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

📄 control_mem.vhd

📁 8051VHDL原代码
💻 VHD
📖 第 1 页 / 共 4 页
字号:
    -- activities triggered by rising edge of clock 
    elsif clk'event and clk = '1' then
      intblock_o <= s_intblock;
      for i in 0 to C_IMPL_N_EXT-1 loop
        s_int0_h1(i) <= int0_i(i);              -- external INT0 
        s_int0_h2(i) <= s_int0_h1(i); 
        s_int0_h3(i) <= s_int0_h2(i); 
        s_int1_h1(i) <= int1_i(i);              -- external INT1 
        s_int1_h2(i) <= s_int1_h1(i);
        s_int1_h3(i) <= s_int1_h2(i);
      end loop; 
      for i in 0 to C_IMPL_N_TMR-1 loop
        s_tf0_h1(i) <= all_tf0_i(i);          -- TF0 flags 
        s_tf0_h2(i) <= s_tf0_h1(i); 
        s_tf1_h1(i) <= all_tf1_i(i);          -- TF1 flags 
        s_tf1_h2(i) <= s_tf1_h1(i);      
        -- all_xxx is a std_logic_vector, s_xxx is a array of std_logic !!!
      end loop;
      for i in 0 to C_IMPL_N_SIU-1 loop
        s_ri_h1(i) <= all_scon_i(i*3);        -- RI flag
        s_ri_h2(i) <= s_ri_h1(i); 
        s_ti_h1(i) <= all_scon_i((i*3)+1);    -- TI flag 
        s_ti_h2(i) <= s_ti_h1(i);      
        -- all_xxx is a std_logic_vector, s_xxx is a array of std_logic !!!
      end loop;
    end if; 
  end process iep; 
 
------------------------------------------------------------------------------ 
-- 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 "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
------------------------------------------------------------------------------ 
 
  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";
      s_ext0isr_d <= '0';
      s_ext0isrh_d <= '0';
      s_ext1isr_d <= '0';
      s_ext1isrh_d <= '0';
    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;

        if ext0isr_en_i = '1' then
          s_ext0isr_d <= ext0isr_d_i;
        end if;
        if ext1isr_en_i = '1' then
          s_ext1isr_d <= ext1isr_d_i;
        end if;
        if ext0isrh_en_i = '1' then
          s_ext0isrh_d <= ext0isrh_d_i;
        end if;
        if ext1isrh_en_i = '1' then
          s_ext1isrh_d <= ext1isrh_d_i;
        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 

⌨️ 快捷键说明

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