📄 pm_fetch_dec.vhd
字号:
lds_st1 <= '0';
lds_st2 <= '0';
elsif (clk='1' and clk'event) then -- CLOCK
nlds_st0 <= (not nlds_st0 and idc_lds) or (nlds_st0 and not (lds_st2 and not cpuwait));
lds_st1 <= not lds_st1 and not nlds_st0 and idc_lds;
lds_st2 <= (not lds_st2 and lds_st1) or (lds_st2 and cpuwait);
end if;
end process;
sts_state_machine:process(clk,nrst)
begin
if nrst='0' then -- RESET
nsts_st0 <= '0';
sts_st1 <= '0';
sts_st2 <= '0';
elsif (clk='1' and clk'event) then -- CLOCK
nsts_st0 <= (not nsts_st0 and idc_sts) or (nsts_st0 and not (sts_st2 and not cpuwait));
sts_st1 <= not sts_st1 and not nsts_st0 and idc_sts;
sts_st2 <= (not sts_st2 and sts_st1) or (sts_st2 and cpuwait);
end if;
end process;
jmp_state_machine:process(clk,nrst)
begin
if nrst='0' then -- RESET
njmp_st0 <= '0';
jmp_st1 <= '0';
jmp_st2 <= '0';
elsif (clk='1' and clk'event) then -- CLOCK
njmp_st0 <= (not njmp_st0 and idc_jmp) or (njmp_st0 and not jmp_st2);
jmp_st1 <= not jmp_st1 and not njmp_st0 and idc_jmp; -- ??
jmp_st2 <= not jmp_st2 and jmp_st1;
end if;
end process;
rcall_state_machine:process(clk,nrst)
begin
if nrst='0' then -- RESET
nrcall_st0 <= '0';
rcall_st1 <= '0';
rcall_st2 <= '0';
elsif (clk='1' and clk'event) then -- CLOCK
nrcall_st0 <= (not nrcall_st0 and idc_rcall) or (nrcall_st0 and not (rcall_st2 and not cpuwait));
rcall_st1 <= (not rcall_st1 and not nrcall_st0 and idc_rcall) or (rcall_st1 and cpuwait);
rcall_st2 <= (not rcall_st2 and rcall_st1 and not cpuwait) or (rcall_st2 and cpuwait);
end if;
end process;
icall_state_machine:process(clk,nrst)
begin
if nrst='0' then -- RESET
nicall_st0 <= '0';
icall_st1 <= '0';
icall_st2 <= '0';
elsif (clk='1' and clk'event) then -- CLOCK
nicall_st0 <= (not nicall_st0 and idc_icall) or (nicall_st0 and not (icall_st2 and not cpuwait));
icall_st1 <= (not icall_st1 and not nicall_st0 and idc_icall) or (icall_st1 and cpuwait);
icall_st2 <= (not icall_st2 and icall_st1 and not cpuwait) or (icall_st2 and cpuwait);
end if;
end process;
call_state_machine:process(clk,nrst)
begin
if nrst='0' then -- RESET
ncall_st0 <= '0';
call_st1 <= '0';
call_st2 <= '0';
call_st3 <= '0';
elsif (clk='1' and clk'event) then -- CLOCK
ncall_st0 <= (not ncall_st0 and idc_call) or (ncall_st0 and not( call_st3 and not cpuwait));
call_st1 <= not call_st1 and not ncall_st0 and idc_call;
call_st2 <= (not call_st2 and call_st1) or (call_st2 and cpuwait);
call_st3 <= (not call_st3 and call_st2 and not cpuwait) or (call_st3 and cpuwait);
end if;
end process;
ret_state_machine:process(clk,nrst)
begin
if nrst='0' then -- RESET
nret_st0 <= '0';
ret_st1 <= '0';
ret_st2 <= '0';
ret_st3 <= '0';
elsif (clk='1' and clk'event) then -- CLOCK
nret_st0 <= (not nret_st0 and idc_ret) or (nret_st0 and not ret_st3);
ret_st1 <= (not ret_st1 and not nret_st0 and idc_ret) or (ret_st1 and cpuwait);
ret_st2 <= (not ret_st2 and ret_st1 and not cpuwait) or (ret_st2 and cpuwait) ;
ret_st3 <= not ret_st3 and ret_st2 and not cpuwait;
end if;
end process;
reti_state_machine:process(clk,nrst)
begin
if nrst='0' then -- RESET
nreti_st0 <= '0';
reti_st1 <= '0';
reti_st2 <= '0';
reti_st3 <= '0';
elsif (clk='1' and clk'event) then -- CLOCK
nreti_st0 <= (not nreti_st0 and idc_reti) or (nreti_st0 and not reti_st3);
reti_st1 <= (not reti_st1 and not nreti_st0 and idc_reti) or (reti_st1 and cpuwait);
reti_st2 <= (not reti_st2 and reti_st1 and not cpuwait) or (reti_st2 and cpuwait) ;
reti_st3 <= not reti_st3 and reti_st2 and not cpuwait;
end if;
end process;
-- INTERRUPT LOGIC AND STATE MACHINE
irq_int <= '0' when irqlines="00000000000000000000000" else '1';
irq_vector_adr(15 downto 6)<=(others => '0');
irq_vector_adr(0) <= '0';
-- PRIORITY ENCODER
irq_vector_adr(5 downto 1) <= "00001" when irqlines(0)='1' else -- 0x0002
"00010" when irqlines(1)='1' else -- 0x0004
"00011" when irqlines(2)='1' else -- 0x0006
"00100" when irqlines(3)='1' else -- 0x0008
"00101" when irqlines(4)='1' else -- 0x000A
"00110" when irqlines(5)='1' else -- 0x000C
"00111" when irqlines(6)='1' else -- 0x000E
"01000" when irqlines(7)='1' else -- 0x0010
"01001" when irqlines(8)='1' else -- 0x0012
"01010" when irqlines(9)='1' else -- 0x0014
"01011" when irqlines(10)='1' else -- 0x0016
"01100" when irqlines(11)='1' else -- 0x0018
"01101" when irqlines(12)='1' else -- 0x001A
"01110" when irqlines(13)='1' else -- 0x001C
"01111" when irqlines(14)='1' else -- 0x001E
"10000" when irqlines(15)='1' else -- 0x0020
"10001" when irqlines(16)='1' else -- 0x0022
"10010" when irqlines(17)='1' else -- 0x0024
"10011" when irqlines(18)='1' else -- 0x0026
"10100" when irqlines(19)='1' else -- 0x0028
"10101" when irqlines(20)='1' else -- 0x002A
"10110" when irqlines(21)='1' else -- 0x002C
"10111" when irqlines(22)='1' else -- 0x002E
"00000";
-- MULTI CYCLE INSTRUCTION FLAG FOR IRQ
cpu_busy <= idc_adiw or idc_sbiw or idc_cbi or idc_sbi or
idc_rjmp or idc_ijmp or
idc_jmp or jmp_st1 or
idc_brbs or idc_brbc or
idc_lpm or lpm_st1 or
skip_inst_start or (skip_inst_st1 and two_word_inst) or
idc_ld_x or idc_ld_y or idc_ldd_y or idc_ld_z or idc_ldd_z or (ld_st and cpuwait) or
idc_st_x or idc_st_y or idc_std_y or idc_st_z or idc_std_z or (st_st and cpuwait) or
idc_lds or lds_st1 or (lds_st2 and cpuwait) or
idc_sts or sts_st1 or (sts_st2 and cpuwait) or
idc_rcall or rcall_st1 or (rcall_st2 and cpuwait) or -- RCALL
idc_icall or icall_st1 or (icall_st2 and cpuwait) or -- ICALL
idc_call or call_st1 or call_st2 or (call_st3 and cpuwait) or -- CALL
(idc_bclr and sreg_bop_wr_en(7)) or -- ??? CLI
(iowe_int and sreg_adr_eq and not dbusout_int(7))or -- ??? Writing '0' to I flag (OUT/STD/ST/STD)
nirq_st0 or
-- idc_ret or nret_st0 or -- Old variant
idc_ret or ret_st1 or ret_st2 or
-- idc_reti or nreti_st0; -- At least one instruction must be executed after RETI and before the new interrupt.
idc_reti or reti_st1 or reti_st2;
sreg_adr_eq <= '1' when adr_int=SREG_Address else '0';
irq_start <= irq_int and not cpu_busy and sreg_out(7);
irq_state_machine:process(clk,nrst)
begin
if nrst='0' then -- RESET
nirq_st0 <= '0';
irq_st1 <= '0';
irq_st2 <= '0';
irq_st3 <= '0';
elsif (clk='1' and clk'event) then -- CLOCK
nirq_st0 <= (not nirq_st0 and irq_start) or (nirq_st0 and not (irq_st3 and not cpuwait));
irq_st1 <= (not irq_st1 and not nirq_st0 and irq_start);
irq_st2 <= (not irq_st2 and irq_st1) or (irq_st2 and cpuwait);
irq_st3 <= (not irq_st3 and irq_st2 and not cpuwait) or (irq_st3 and cpuwait);
end if;
end process;
irqack_reg:process(clk,nrst)
begin
if nrst='0' then -- RESET
irqack_int<='0';
elsif (clk='1' and clk'event) then -- CLOCK
irqack_int<= not irqack_int and irq_start;
end if;
end process;
irqack <= irqack_int;
irqackad_reg:process(clk,nrst)
begin
if nrst='0' then -- RESET
irqackad_int<=(others=>'0');
elsif (clk='1' and clk'event) then -- CLOCK
irqackad_int<=irq_vector_adr(5 downto 1);
end if;
end process;
irqackad <= irqackad_int;
-- *******************************************************************************************
rjmp_push_pop_ijmp_state_brxx_machine:process(clk,nrst)
begin
if nrst='0' then -- RESET
rjmp_st <= '0';
ijmp_st <= '0';
push_st <= '0';
pop_st <= '0';
brxx_st <= '0';
elsif (clk='1' and clk'event) then -- CLOCK
rjmp_st <= idc_rjmp; -- ??
ijmp_st <= idc_ijmp;
push_st <= (not push_st and idc_push) or (push_st and cpuwait);
pop_st <= (not pop_st and idc_pop) or (pop_st and cpuwait);
brxx_st <= not brxx_st and (idc_brbc or idc_brbs) and bit_test_op_out;
end if;
end process;
-- LD/LDD/ST/STD
ld_st_state_machine:process(clk,nrst)
begin
if nrst='0' then -- RESET
ld_st <= '0';
st_st <= '0';
elsif (clk='1' and clk'event) then -- CLOCK
ld_st <= (not ld_st and (idc_ld_x or idc_ld_y or idc_ldd_y or idc_ld_z or idc_ldd_z)) or (ld_st and cpuwait);
st_st <= (not st_st and (idc_st_x or idc_st_y or idc_std_y or idc_st_z or idc_std_z)) or (st_st and cpuwait);
end if;
end process;
-- SBI/CBI
sbi_cbi_machine:process(clk,nrst)
begin
if nrst='0' then -- RESET
sbi_st <= '0';
cbi_st <= '0';
cbi_sbi_io_adr_tmp <= (others => '0');
cbi_sbi_bit_num_tmp <= (others => '0');
elsif (clk='1' and clk'event) then -- CLOCK
sbi_st <= not sbi_st and idc_sbi;
cbi_st <= not cbi_st and idc_cbi;
cbi_sbi_io_adr_tmp <= dex_adr5port;
cbi_sbi_bit_num_tmp <= dex_bitop_bitnum;
end if;
end process;
-- ########################################################################################
-- SREG FLAGS WRITE ENABLE LOGIC
bclr_bset_op_en_logic:for i in sreg_bop_wr_en'range generate
sreg_bop_wr_en(i) <= '1' when (dex_bitnum_sreg=i and (idc_bclr or idc_bset)='1') else '0';
end generate;
sreg_c_wr_en <= idc_add or idc_adc or (idc_adiw or adiw_st) or idc_sub or idc_subi or
idc_sbc or idc_sbci or (idc_sbiw or sbiw_st) or idc_com or idc_neg or
idc_cp or idc_cpc or idc_cpi or
idc_lsr or idc_ror or idc_asr or sreg_bop_wr_en(0);
sreg_z_wr_en <= idc_add or idc_adc or (idc_adiw or adiw_st) or idc_sub or idc_subi or
idc_sbc or idc_sbci or (idc_sbiw or sbiw_st) or
idc_cp or idc_cpc or idc_cpi or
idc_and or idc_andi or idc_or or idc_ori or idc_eor or idc_com or idc_neg or
idc_inc or idc_dec or idc_lsr or idc_ror or idc_asr or sreg_bop_wr_en(1);
sreg_n_wr_en <= idc_add or idc_adc or adiw_st or idc_sub or idc_subi or
idc_sbc or idc_sbci or sbiw_st or
idc_cp or idc_cpc or idc_cpi or
idc_and or idc_andi or idc_or or idc_ori or idc_eor or idc_com or idc_neg or
idc_inc or idc_dec or idc_lsr or idc_ror or idc_asr or sreg_bop_wr_en(2);
sreg_v_wr_en <= idc_add or idc_adc or idc_adiw or idc_sub or idc_subi or
idc_sbc or idc_sbci or idc_sbiw or idc_neg or idc_inc or idc_dec or
idc_cp or idc_cpc or idc_cpi or
idc_lsr or idc_ror or idc_asr or sreg_bop_wr_en(3);
sreg_s_wr_en <= idc_add or idc_adc or adiw_st or idc_sub or idc_subi or
idc_sbc or idc_sbci or sbiw_st or
idc_cp or idc_cpc or idc_cpi or
idc_and or idc_andi or idc_or or idc_ori or idc_eor or idc_com or idc_neg or
idc_inc or idc_dec or idc_lsr or idc_ror or idc_asr or sreg_bop_wr_en(4);
sreg_h_wr_en <= idc_add or idc_adc or idc_sub
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -