⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pm_fetch_dec.vhd

📁 一个FPGA的AVR_Core 仅供测试~
💻 VHD
📖 第 1 页 / 共 5 页
字号:
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 + -