📄 control_mem_rtl.vhd
字号:
-- outputs: s_intpre------------------------------------------------------------------------------ intpre : process (ie,ip,scon,tcon,s_inthigh,s_intlow,s_ti,s_ri,s_ie0, s_ie1,s_tf0,s_tf1) begin if (EA='1' and (EX0='1' or ET0='1' or EX1='1' or ET1='1' or ES='1')) then if s_inthigh='1' then -- interrupt with high priority is running s_intpre <= '0'; elsif s_intlow='1' then -- interrupt with low priority is running if ((PX0 and EX0 and s_ie0) or (PT0 and ET0 and s_tf0) or (PX1 and EX1 and s_ie1) or (PT1 and ET1 and s_tf1) or (PS0 and ES and (s_ri or s_ti)))='1' then s_intpre <= '1'; -- a second interrupt must start else s_intpre <= '0'; end if; else -- no interrupt is running if ((EX0 and s_ie0) or (ET0 and s_tf0) or (EX1 and s_ie1) or (ET1 and s_tf1) or (ES and (s_ri or s_ti)))='1' then s_intpre <= '1'; -- an interrupt must start else s_intpre <= '0'; end if; end if; else -- no interrupt must be carry out s_intpre <= '0'; end if; end process intpre; ------------------------------------------------------------------------------ -- purpose: this are the main-multiplexer for reading and writing regs-- inputs: s_data_mux,pc,aludata_i,s_reg_data,rom_data_i,acc,-- s_bdata_mux,s_bit_data,psw,new_cy_i,s_helpb,sp,s_rr_adr,-- s_ri_data,s_help,s_adr_mux,s_adr,s_regs_wr_en,pc_plus2,-- s_help16,s_ri_adr,s_r0_b0,s_r1_b0,s_r0_b1,s_r1_b1,-- s_r0_b2,s_r1_b2,s_r0_b3,s_r1_b3-- outputs: s_data,s_bdata,s_adr,s_ri_data,ram_wr_o------------------------------------------------------------------------------ p_multiplexer : process (s_data_mux,pc,aludata_i,s_reg_data,rom_data_i,acc, s_bdata_mux,s_bit_data,psw,new_cy_i,s_helpb,sp,s_rr_adr, s_ri_data,s_help,s_adr_mux,s_adr,s_regs_wr_en,pc_plus2, s_help16,s_ri_adr,s_r0_b0,s_r1_b0,s_r0_b1,s_r1_b1, s_r0_b2,s_r1_b2,s_r0_b3,s_r1_b3,s_adrx_mux,dph,dpl, datax_i) begin case s_data_mux is when "0000" => s_data <= conv_unsigned(0,8); when "0001" => s_data <= pc(7 downto 0); when "0010" => s_data <= pc(15 downto 8); when "0011" => s_data <= unsigned(aludata_i); when "0100" => s_data <= s_reg_data; when "0101" => s_data <= unsigned(rom_data_i); when "0110" => s_data <= acc; when "0111" => s_data(7 downto 4) <= acc(3 downto 0); s_data(3 downto 0) <= acc(7 downto 4); when "1000" => s_data <= s_help; when "1001" => s_data(7 downto 4) <= s_reg_data(7 downto 4); s_data(3 downto 0) <= s_help(3 downto 0); when "1010" => s_data(7 downto 4) <= acc(7 downto 4); s_data(3 downto 0) <= s_reg_data(3 downto 0); when "1100" => s_data <= s_help16(7 downto 0); when "1101" => s_data <= s_help16(15 downto 8); when "1110" => s_data <= pc_plus2(7 downto 0); when "1111" => s_data <= unsigned(datax_i); when others => s_data <= conv_unsigned(0,8); end case; case s_bdata_mux is when "0000" => s_bdata <= '0'; when "0001" => s_bdata <= s_bit_data and cy; when "0010" => s_bdata <= not(s_bit_data) and cy; when "0011" => s_bdata <= new_cy_i(1); when "0100" => s_bdata <= s_helpb; when "0101" => s_bdata <= not cy; when "0110" => s_bdata <= not s_bit_data; when "0111" => s_bdata <= s_bit_data; when "1000" => s_bdata <= cy; when "1001" => s_bdata <= s_bit_data or cy; when "1010" => s_bdata <= not(s_bit_data) or cy; when "1011" => s_bdata <= '1'; when others => s_bdata <= '0'; end case; case s_adr_mux is when "0000" => s_adr <= conv_unsigned(0,8); when "0001" => s_adr <= conv_unsigned(16#89#,8); when "0010" => s_adr <= conv_unsigned(16#8D#,8); when "0011" => s_adr <= conv_unsigned(16#8B#,8); when "0100" => s_adr <= conv_unsigned(16#8F#,8); when "0101" => s_adr <= sp; when "0110" => s_adr <= s_rr_adr; when "0111" => s_adr <= s_ri_data; when "1000" => s_adr <= unsigned(rom_data_i); when "1001" => s_adr <= s_reg_data; when "1010" => s_adr <= s_help ; when "1011" => s_adr <= conv_unsigned(16#D7#,8); when "1100" => s_adr <= conv_unsigned(16#F0#,8); when "1101" => s_adr <= conv_unsigned(16#82#,8); when "1110" => s_adr <= conv_unsigned(16#83#,8); when "1111" => s_adr <= sp + conv_unsigned(1,1); when others => s_adr <= conv_unsigned(0,8); end case; case s_adrx_mux is when "00" => adrx_o <= (others => '0'); when "01" => adrx_o(15 downto 8) <= std_logic_vector(dph); adrx_o(7 downto 0) <= std_logic_vector(dpl); when "10" => adrx_o(15 downto 8) <= (others => '0'); adrx_o(7 downto 0) <= std_logic_vector(s_ri_data); when others => adrx_o <= (others => '0'); end case; case s_ri_adr is when "00000000" => s_ri_data <= s_r0_b0; when "00000001" => s_ri_data <= s_r1_b0; when "00001000" => s_ri_data <= s_r0_b1; when "00001001" => s_ri_data <= s_r1_b1; when "00010000" => s_ri_data <= s_r0_b2; when "00010001" => s_ri_data <= s_r1_b2; when "00011000" => s_ri_data <= s_r0_b3; when "00011001" => s_ri_data <= s_r1_b3; when others => s_ri_data <= conv_unsigned(0,8); end case; if ((s_regs_wr_en="100") or (s_regs_wr_en="101")) then -- write one byte if ((s_adr(7)='1') or -- SFR (conv_std_logic_vector(s_adr(7 downto 4),4)="0010") -- bitadressable or ((std_logic_vector(s_adr) AND "11100110") = "00000000")) -- R0,R1 then ram_wr_o <= '0'; else ram_wr_o <= '1'; -- to RAM-block end if; else ram_wr_o <= '0'; end if; end process p_multiplexer; ------------------------------------------------------------------------------ -- purpose: writes internal registers, on which the user have no -- direct access-- inputs: reset,clk,s_nextstate,state,s_help_en,-- rom_data_i,aludata_i,s_reg_data,s_rr_adr,new_cy_i-- outputs: state,s_ir,s_help,s_help16,s_helpb,s_intpre2,s_intlow,-- s_inthigh,s_preadr,s_intblock -- ***------------------------------------------------------------------------------ p_wr_internal_reg : process (reset,clk) begin if reset='1' then state <= STARTUP; s_ir <= conv_unsigned(0,8); s_help <= conv_unsigned(0,8); s_help16 <= conv_unsigned(0,16); s_helpb <= '0'; s_intpre2 <= '0'; s_intblock <= '0'; -- *** s_intlow <= '0'; s_inthigh <= '0'; s_preadr <= conv_unsigned(0,8); pc <= conv_unsigned(0,16); s_p0 <= "11111111"; s_p1 <= "11111111"; s_p2 <= "11111111"; s_p3 <= "11111111"; else if Rising_Edge(clk) then state <= s_nextstate; -- update current state if (s_intblock='0') then -- set s_intblock with s_intdelay everyclock *** s_intblock <= s_intdelay; -- *** else -- *** if (state=FETCH) then -- reset only at fetch *** s_intblock <= s_intdelay; -- *** end if; -- *** end if; -- *** if state=FETCH then s_ir <= unsigned(rom_data_i); -- save OP-Code in IR end if; case s_help_en is when "0000" => NULL; when "0001" => s_help <= unsigned(rom_data_i); when "0010" => s_help <= unsigned(aludata_i); when "0011" => s_help <= s_reg_data; when "0100" => s_help <= s_rr_adr; when "0101" => s_help <= conv_unsigned(16#03#,8); when "0110" => s_help <= conv_unsigned(16#0B#,8); when "0111" => s_help <= conv_unsigned(16#13#,8); when "1000" => s_help <= conv_unsigned(16#1B#,8); when "1001" => s_help <= conv_unsigned(16#23#,8); when "1010" => s_help <= acc; when others => NULL; end case; case s_help16_en is when "00" => NULL; when "01" => s_help16 <= pc + conv_unsigned(3,2); when "10" => s_help16 <= pc_plus2; when "11" => s_help16 <= pc_plus1; when others => NULL; end case; case s_helpb_en is when '0' => NULL; when '1' => s_helpb <= new_cy_i(1); when others => NULL; end case; if s_intpre2_en='1' then -- help-reg for s_intpre s_intpre2 <= s_intpre2_d; else NULL; end if; if s_intlow_en='1' then s_intlow <= s_intlow_d; else NULL; end if; if s_inthigh_en='1' then s_inthigh <= s_inthigh_d; else NULL; end if; s_preadr <= s_adr; pc <= pc_comb; -- write pc-register s_p0 <= p0_i; s_p1 <= p1_i; s_p2 <= p2_i; s_p3 <= p3_i; end if; end if; end process p_wr_internal_reg; ------------------------------------------------------------------------------ -- purpose: calculate the next PC-adress -- inputs: s_pc_inc_en,pc_plus1,rom_data_i,s_intpre2,s_help,s_command,-- s_help16,s_ir,dph,dpl,acc,s_reg_data,pc-- outputs: pc_comb------------------------------------------------------------------------------ p_pc : process (s_pc_inc_en,pc_plus1,rom_data_i,s_help, s_help16,s_ir,dph,dpl,acc,s_reg_data,pc) variable v_dptr: unsigned(15 downto 0); begin v_dptr(15 downto 8) := dph; v_dptr(7 downto 0) := dpl; case s_pc_inc_en is when "0001" => -- increment PC pc_comb <= pc_plus1; when "0010" => -- for relativ jumps and calls
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -