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

📄 controlunit.vhd

📁 modelsim+dc开发的4级流水线结构的MIPS CPU
💻 VHD
字号:
-- cu.vhdl
--
-- Control unit
-- 

library ieee;
use ieee.std_logic_1164.all;
use work.mips_pack.all;


entity cu is
	port (instr_in: in std_ulogic_vector(31 downto 0);
	      pc_next: in std_ulogic_vector(3 downto 0); 
	      branch_in: in std_ulogic;
	      rst: in std_ulogic;
	      clk: in std_ulogic;
	      alu_ctl: out std_ulogic_vector(5 downto 0);
	      alu_shamt: out std_ulogic_vector(4 downto 0);
	      pcalu_ctl: out std_ulogic;
	      branch_ctl:out std_ulogic_vector(2 downto 0);
	      mux1_ctl: out std_ulogic;
	      mux2_ctl: out std_ulogic;
	      mux3_ctl: out std_ulogic_vector(1 downto 0);
	      mux5_ctl_d: out std_ulogic; 
	      instr_re: out std_ulogic;                  
	      reg_we: out std_ulogic;
	      reg_we_d: out std_ulogic;
	      reg_we_dd: out std_ulogic;
	      mem_we: out std_ulogic;
	      mem_we_d: out std_ulogic;
	      mem_re: out std_ulogic;
	      mem_re_d: out std_ulogic;
	      mem_word: out std_ulogic;
	      mem_word_d: out std_ulogic;
	      imm_out: out std_ulogic_vector(31 downto 0);
	      target: out std_ulogic_vector(31 downto 0);
	      pc_rel: out std_ulogic_vector(31 downto 0);
	      wr_addr: out std_ulogic_vector(4 downto 0);
	      wr_addr_d: out std_ulogic_vector(4 downto 0);
	      wr_addr_dd: out std_ulogic_vector(4 downto 0)
	     );
end entity cu;


architecture behavior of cu is

signal bubble:std_ulogic;    
signal mux5_ctl,mux5_ctl_u: std_ulogic; 
signal branch_in_d: std_ulogic;                   
signal	reg_we_u,mem_we_u, mem_re_u, mem_word_u:  std_ulogic;
signal	reg_we_b, reg_we_d_b, mem_we_b, mem_re_b, mem_word_b:  std_ulogic;
signal Op,alu_ctl_u: std_ulogic_vector(5 downto 0);
signal func: std_ulogic_vector(5 downto 0);
signal Rs,Rt,Rd,Shamt,wr_addr_u:std_ulogic_vector(4 downto 0); 
signal wr_addr_b,wr_addr_d_b:std_ulogic_vector(4 downto 0);
signal branch_ctl_u: std_ulogic_vector(2 downto 0);
signal pcalu_ctl_u:  std_ulogic;	

begin
bubble <= branch_in or branch_in_d ;
Op <= instr_in(31 downto 26);
Rs <= instr_in(25 downto 21);
Rt <= instr_in(20 downto 16);
Rd <= instr_in(15 downto 11);
Shamt <= instr_in(10 downto 6);
func <= instr_in(5 downto 0);
target <= pc_next(3 downto 0)&instr_in(25 downto 0)&"00";
pc_rel <=	"00000000000000" & instr_in(15 downto 0) & "00";  
imm_out <= 									--16bit to 32 bit
			X"FFFF" & instr_in(15 downto 0) when instr_in(15)='1'	else			
   		X"0000" & instr_in(15 downto 0);  
mem_we <= mem_we_b ;
mem_re <= mem_re_b ;
mem_word <= mem_word_b;
reg_we <= reg_we_b ;
reg_we_d <= reg_we_d_b ;
wr_addr <= wr_addr_b; 
wr_addr_d <= wr_addr_d_b;
instr_re <= not rst;

LOGIC:process (op,rs,rt,rd,func) is
begin
         --default value
		   alu_ctl_u <= NOP;
		   pcalu_ctl_u <= PC_NOP;
         branch_ctl_u <= BR_NOP;
         mux1_ctl <= '0';
         mux2_ctl <= '0';
         mux3_ctl <= "00";
         mux5_ctl_u <= '0';                   
         reg_we_u <= '0';
         mem_we_u <= '0';
         mem_re_u <= '0';
         mem_word_u <= '1';
         wr_addr_u <= "00000";        
		   case op is 
		      when "000000" =>
		         case func is
		            when "000000" =>
		               if  rt = "00000" then --NOP 
	                      null;
                     else
		                   alu_ctl_u <= SSLL;                   
                         reg_we_u <= '1';
                         mem_word_u <= '1';
                         wr_addr_u <= rd;
                     end if;
		            when "100001" =>
		               alu_ctl_u <=ADDU ;                
                     reg_we_u <= '1';
                     wr_addr_u <= rd;
		            when "100000" =>
		               alu_ctl_u <= ADD;                 
                     reg_we_u <= '1';
                     wr_addr_u <= rd;
		            when "100011" =>
		               alu_ctl_u <= SUBU;                   
                     reg_we_u <= '1';
                     wr_addr_u <= rd ;
		            when "000011" =>
		               alu_ctl_u <= SSRA;                  
                     reg_we_u <= '1';
                     wr_addr_u <= rd ;
		            when "101010" =>
		               alu_ctl_u <= SLT;                   
                     reg_we_u <= '1';
                     wr_addr_u <= rd ;
		            when "001000" =>
		               alu_ctl_u <= JR;
		               pcalu_ctl_u <= PC_JUMP;
                     branch_ctl_u <= BR_JR;
		            when others =>
                     null;
		         end case;
		      when ADDIU => 
		         alu_ctl_u <= op;
               mux2_ctl <= '1';                  
               reg_we_u <= '1';
               wr_addr_u <= rt;
		      when ADDI =>
		         alu_ctl_u <= op;
               mux2_ctl <= '1';                  
               reg_we_u <= '1';
               wr_addr_u <= rt;
		      when LW =>
		         alu_ctl_u <= op;
               mux2_ctl <= '1';
               mux5_ctl_u <= '1';                   
               reg_we_u <= '1';
               mem_re_u <= '1';
               wr_addr_u <= rt;
		      when SW =>
		         alu_ctl_u <= op;
               mux2_ctl <= '1';
               mem_we_u <= '1';
		      when LBU =>
		         alu_ctl_u <= op;
               mux2_ctl <= '1';
               mux5_ctl_u <= '1';                   
               reg_we_u <= '1';
               mem_re_u <= '1';
               mem_word_u <= '0';
               wr_addr_u <= rt;
		      when SB =>
		         alu_ctl_u <= op;
               mux2_ctl <= '1';
               mem_we_u <= '1';
               mem_word_u <= '0';
		      when LUI =>
		         alu_ctl_u <= op;
               mux2_ctl <= '1';                   
               reg_we_u <= '1';
               wr_addr_u <= rt;
		      when BEQ =>
		         alu_ctl_u <= op;
		         pcalu_ctl_u <= PC_BRANCH;
               branch_ctl_u <= BR_BEQ;
               mux3_ctl <= "01";
		      when BNE =>
		         alu_ctl_u <= op;
		         pcalu_ctl_u <= PC_BRANCH;
               branch_ctl_u <= BR_BNE;
               mux3_ctl <= "01";
		      when BGTZ =>
		         alu_ctl_u <= op;
		         pcalu_ctl_u <= PC_BRANCH;
               branch_ctl_u <= BR_BGTZ;
               mux3_ctl <= "01";
		      when BLTZ =>
		         alu_ctl_u <= op;
		         pcalu_ctl_u <= PC_BRANCH;
               branch_ctl_u <= BR_BLTZ;
               mux3_ctl <= "01";
		      when JUMP =>
		         alu_ctl_u <= op;
		         pcalu_ctl_u <= PC_JUMP;
               branch_ctl_u <= BR_JUMP;
               mux3_ctl <= "10";
		      when JAL =>
		         alu_ctl_u <= op;
		         pcalu_ctl_u <= PC_JUMP;
               branch_ctl_u <= BR_JAL;
               mux1_ctl <= '1';
               mux3_ctl <= "10";                   
               reg_we_u <= '1';
               wr_addr_u <= "11111"; 
		      when others =>
               null;
		   end case;
end process;
  
process (rst, clk) is
	begin
		if (rst = '1') then
	      alu_ctl <= NOP;
	      alu_shamt <= "00000";
	      branch_ctl <= BR_NOP;
	      pcalu_ctl <= PC_NOP;
	      mux5_ctl <= '0';
	      mux5_ctl_d <= '0';
	      branch_in_d <= '0';
	      reg_we_b <= '0';                 
	      reg_we_d_b <= '0';
	      reg_we_dd <= '0';
	      wr_addr_b <= "00000";
	      wr_addr_d_b <= "00000";
	      wr_addr_dd <= "00000";
	      mem_we_b <= '0';
	      mem_we_d <= '0';
	      mem_re_b <= '0';
	      mem_re_d <= '0';
	      mem_word_b <= '1';
	      mem_word_d <= '1';
		elsif rising_edge(clk) then
		   branch_in_d <= branch_in;
		   mux5_ctl_d <= mux5_ctl;
		   reg_we_d_b <= reg_we_b;
         reg_we_dd <= reg_we_d_b;
         wr_addr_d_b <= wr_addr_b;
         wr_addr_dd <= wr_addr_d_b;
         mem_we_d <= mem_we_b;
   		   mem_re_d <= mem_re_b;
   		   mem_word_d <= mem_word_b;
   		   --default value
   		   alu_shamt <= "00000";
		   alu_ctl <= NOP;
         branch_ctl <= BR_NOP;
         pcalu_ctl <= PC_NOP;
         mux5_ctl<= '0';                   
         reg_we_b <= '0';
         mem_we_b <= '0';
         mem_re_b <= '0';
         mem_word_b <= '1';
         wr_addr_b <= "00000";
         
   		   if (bubble = '0') then
   		   alu_shamt <= shamt;
   		   alu_ctl <= alu_ctl_u;
   		   branch_ctl <= branch_ctl_u;
   		   pcalu_ctl <= pcalu_ctl_u;
   		   mux5_ctl <= mux5_ctl_u;
   		   reg_we_b <= reg_we_u;
   		   mem_we_b <= mem_we_u;
         mem_re_b <= mem_re_u;
         mem_word_b <= mem_word_u;
         wr_addr_b <= wr_addr_u;  		   
   		   else
		   null;
		   end if;
		     
		end if;
	end process ;

end architecture behavior;

⌨️ 快捷键说明

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