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

📄 control_mem_rtl.vhd

📁 mc8051源码
💻 VHD
📖 第 1 页 / 共 4 页
字号:
------------------------------------------------------------------------------ -- purpose: check the interupt-sources and start an interupt if necessary-- inputs:  ie,ip,scon,tcon,s_inthigh,s_intlow,s_ti,s_ri,s_ie0,--          s_ie1,s_tf0,s_tf1-- 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 "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------------------------------------------------------------------------------    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_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 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         pc_comb <= conv_unsigned(pc_plus1 + signed(rom_data_i),16);        when "0011" =>                  -- load interrupt vectoradress

⌨️ 快捷键说明

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