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

📄 pm_fetch_dec.vhd

📁 avr core porocesssor vhdl source code
💻 VHD
📖 第 1 页 / 共 5 页
字号:

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 <= '1'; -- FOR TEST
	
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 and cpuwait) or 
			idc_sts or (sts_st1 and cpuwait) or 
			idc_rcall or (rcall_st1 and cpuwait) or
			idc_icall or (icall_st1 and cpuwait) or
			idc_call or call_st1 or (call_st2 and cpuwait) or
			idc_ret or ret_st1 or (ret_st2 and cpuwait);
		
	
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  or idc_subi or
				idc_cp or idc_cpc or idc_cpi or
                idc_sbc or idc_sbci or idc_neg or sreg_bop_wr_en(5);

sreg_t_wr_en <=  idc_bst or sreg_bop_wr_en(6);

sreg_i_wr_en <= irq_start or reti_st3 or sreg_bop_wr_en(7); -- idc_reti !!!???


sreg_fl_wr_en(0) <= sreg_c_wr_en;
sreg_fl_wr_en(1) <= sreg_z_wr_en;
sreg_fl_wr_en(2) <= sreg_n_wr_en;
sreg_fl_wr_en(3) <= sreg_v_wr_en;
sreg_fl_wr_en(4) <= sreg_s_wr_en;
sreg_fl_wr_en(5) <= sreg_h_wr_en;
sreg_fl_wr_en(6) <= sreg_t_wr_en;
sreg_fl_wr_en(7) <= sreg_i_wr_en;



sreg_fl_in <=  bit_pr_sreg_out when (idc_bst or idc_bclr or idc_bset)='1' else		           -- TO THE SREG
reti_st3&'0'&alu_h_flag_out&alu_s_flag_out&alu_v_flag_out&alu_n_flag_out&alu_z_flag_out&alu_c_flag_out;      
               
-- #################################################################################################################

-- *********************************************************************************************
-- ************** INSTRUCTION DECODER OUTPUTS FOR THE OTHER BLOCKS  ****************************
-- *********************************************************************************************

-- FOR ALU

idc_add_out   <= idc_add;
idc_adc_out   <= idc_adc;
idc_adiw_out  <= idc_adiw;
idc_sub_out   <= idc_sub;
idc_subi_out  <= idc_subi;
idc_sbc_out   <= idc_sbc;
idc_sbci_out  <= idc_sbci;
idc_sbiw_out  <= idc_sbiw;
adiw_st_out   <= adiw_st;
sbiw_st_out   <= sbiw_st;
idc_and_out   <= idc_and;
idc_andi_out  <= idc_andi;
idc_or_out    <= idc_or;
idc_ori_out   <= idc_ori;
idc_eor_out   <= idc_eor;              
idc_com_out   <= idc_com;              
idc_neg_out   <= idc_neg;
idc_inc_out   <= idc_inc;
idc_dec_out   <= idc_dec;
idc_cp_out    <= idc_cp;              
idc_cpc_out   <= idc_cpc;
idc_cpi_out   <= idc_cpi;
idc_cpse_out  <= idc_cpse;                            
idc_lsr_out   <= idc_lsr;
idc_ror_out   <= idc_ror;
idc_asr_out   <= idc_asr;
idc_swap_out  <= idc_swap;

-- FOR THE BIT PROCESSOR

idc_sbi_out  <= idc_sbi;
sbi_st_out   <= sbi_st;
idc_cbi_out  <= idc_cbi;
cbi_st_out   <= cbi_st;
idc_bld_out  <= idc_bld;
idc_bst_out  <= idc_bst;
idc_bset_out <= idc_bset;
idc_bclr_out <= idc_bclr;
idc_sbic_out <= idc_sbic;
idc_sbis_out <= idc_sbis;
idc_sbrs_out <= idc_sbrs;
idc_sbrc_out <= idc_sbrc;
idc_brbs_out <= idc_brbs;
idc_brbc_out <= idc_brbc;
idc_reti_out <= idc_reti;

-- POST INCREMENT/PRE DECREMENT FOR THE X,Y,Z REGISTERS
post_inc <= idc_psinc;
pre_dec  <= idc_prdec;
reg_h_wr <= (idc_st_x or idc_st_y or idc_st_z or idc_ld_x or idc_ld_y or idc_ld_z) and (idc_psinc or idc_prdec);

reg_h_adr(0)<= idc_st_x or idc_ld_x;
reg_h_adr(1)<= idc_st_y or 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -