📄 pm_fetch_dec.vhd
字号:
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 + -