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

📄 coreofcpu.vhd

📁 几个VHDL的源代码和和一个本人编写的5级流水线RISC CPU的代码
💻 VHD
字号:
--core_design
--cpu
--all right reserved

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;

entity cpu is
  generic(delay:time:=3 ns);
  port(clk:in std_logic;
       reset:in std_logic;--high
       over_flow:out std_logic;
       data_ex:in std_logic_vector(31 downto 0)
      );
end cpu;

architecture core of cpu is

subtype ram_range is integer range 0 to 31;
subtype ram_lenth is std_logic_vector(31 downto 0);
type ram is array (ram_range) of ram_lenth;
signal ram_array:ram;

function logic2int(din:std_logic_vector(4 downto 0)) return ram_range is
    variable result:ram_range:=0;
  begin
    for i in 0 to 4 loop 
      if din(i)='1' then
        result:=result+2**i;
      end if;
    end loop;
    return result;
end logic2int;

------------------
--IF/ID stage
------------------
        type ifid_struct is record
		iword     : std_logic_vector(31 downto 0);  --instruction word
		pc        : std_logic_vector(31 downto 0);  --pc for this instruction
		
		cm_hw_int : std_logic;                      --hw interupt
	end record;
	signal ifid_in:ifid_struct;
	signal ifid_out:ifid_struct;

------------------
--ID/EX stage
------------------
        type idex_struct is record
                read_data1:std_logic_vector(31 downto 0);
                read_data2:std_logic_vector(31 downto 0);
                after_sign:std_logic_vector(31 downto 0);
        	       wb:std_logic_vector(1 downto 0);
        		m:std_logic_vector(1 downto 0);  					  --read & write
 		ex:std_logic_vector(9 downto 0);          --ALUsrcB & ALUsrcA & inv_in2 & ALUop
        		ins1:std_logic_vector(4 downto 0);
        		ins2:std_logic_vector(4 downto 0);
        end record;
        signal idex_in:idex_struct;
        signal idex_out:idex_struct;
 	
------------------
--EX/MEM stage
------------------
	type exmem_structure is record
	        ALU_result:std_logic_vector(31 downto 0);
		data:std_logic_vector(31 downto 0);
		wb:std_logic_vector(1 downto 0);
        		m:std_logic_vector(1 downto 0);
        		ins:std_logic_vector(4 downto 0);
	end record;
	signal exmem_in:exmem_structure;
	signal exmem_out:exmem_structure;
	
------------------
--MEM/WB stage
------------------
	type memwb_struct is record
	        ALU_result:std_logic_vector(31 downto 0);
	        memdata:std_logic_vector(31 downto 0);
	        wb:std_logic_vector(1 downto 0);
	        ins:std_logic_vector(4 downto 0);
	end record;
	signal memwb_in:memwb_struct;
	signal memwb_out:memwb_struct;
	
component ALU
  port(op: in std_logic_vector(2 downto 0);        -- ALU operation
       inv_in2 : in std_logic;                     -- Invert operator in2
       in1, in2: in std_logic_vector(31 downto 0); -- ALU input
       ovf: out std_logic;                         -- ALU overflow
       alu_out: out std_logic_vector(31 downto 0)
      );
end component;
signal read1:std_logic_vector(31 downto 0);
signal read2:std_logic_vector(31 downto 0);
signal ovf_sig:std_logic;

component control
  port (reset:in std_logic;
  	op : in std_logic_vector (5 downto 0);         	-- The op code
	memread:out std_logic;
	memwrite:out std_logic;
	memtoreg:out std_logic;
	pcsource:out std_logic;
	ALUop:out std_logic_vector(2 downto 0);
	ALUsrcB:out std_logic_vector(1 downto 0);
	ALUsrcA:out std_logic_vector(1 downto 0);
	ALUsrc:out std_logic;
	inv_in2:out std_logic;
	regdst:out std_logic;
	regwrite:out std_logic
       );
  end component;

component ins_rom
  port(clk:in std_logic;
       a:in std_logic_vector(31 downto 0);
        readdata:out std_logic_vector(31 downto 0)
       );
end component;

component dram
  port (clk:in std_logic;
	addr:in std_logic_vector(31 downto 0);
        data_in:in std_logic_vector(31 downto 0);
        data_out:out std_logic_vector(31 downto 0);
	ras:in std_logic;
	we:in std_logic
       );
end component;

component mux2_1
  port (en:in std_logic;
  	in1:in std_logic_vector(31 downto 0);
  	in2:in std_logic_vector(31 downto 0);
  	out1:out std_logic_vector(31 downto 0)
       );
end component;

component mux4_1
  port (en:in std_logic_vector(1 downto 0);
  	in1:in std_logic_vector(31 downto 0);
  	in2:in std_logic_vector(31 downto 0);
  	in3:in std_logic_vector(31 downto 0);
  	in4:in std_logic_vector(31 downto 0);
  	out1:out std_logic_vector(31 downto 0)
       );
end component;

component opt
  port (reset:in std_logic;
  	in1:in std_logic_vector(15 downto 0);
  	in2:in std_Logic_vector(31 downto 0);
  	out1:out std_Logic_vector(31 downto 0);
  	out2:out std_Logic_vector(31 downto 0)
       );
end component;

-------------------
--some signal
-------------------
signal PC_reg:std_logic:='0';  --tell PC instruction rom to read
signal PC_source:std_logic;
signal PC_in:std_logic_vector(31 downto 0);
signal PC_out:std_logic_vector(31 downto 0);
signal PC_out1:std_logic_vector(31 downto 0);
signal after_opt:std_logic_vector(31 downto 0);
signal reg_write:std_logic_vector(4 downto 0);
signal reg_data:std_logic_vector(31 downto 0);
signal memtoreg_out:std_logic_vector(31 downto 0);
signal nodata:std_logic_vector(31 downto 0);
signal read21:std_logic_vector(31 downto 0);
signal eaquel:std_logic;
signal jump:std_logic_vector(31 downto 0);
signal PC_en:std_logic_vector(1 downto 0);

begin
ifid_in.iword<=pc_out1;
over_flow<=ovf_sig;
PC_en<=eaquel & PC_source; 
exmem_in.data<=read21;
reg_data<=memtoreg_out;
memwb_in.ALU_result<=exmem_out.ALU_result;
reg_write<=MEMwb_out.ins;
memwb_in.ins<=exmem_out.ins;

U1:ins_rom port map (clk,PC_out,ifid_in.pc(31 downto 0));
U2:ALU port map (idex_out.ex(2 downto 0),idex_out.ex(3),read1,read2,ovf_sig,exmem_in.ALU_result);
U3:control port map (reset,ifid_out.pc(31 downto 26),idex_in.m(1),idex_in.m(0),idex_in.wb(0),
		     PC_source,idex_in.ex(2 downto 0),idex_in.ex(8 downto 7),idex_in.ex(6 downto 5),
		     idex_in.ex(4),idex_in.ex(3),idex_in.ex(9),idex_in.wb(1));
U4:mux4_1 port map (PC_en,after_opt,PC_out1,exmem_out.ALU_result,jump,PC_in);
U5:opt port map (reset,ifid_out.pc(15 downto 0),ifid_out.iword,idex_in.after_sign,after_opt);
U7:mux4_1 port map (idex_out.ex(8 downto 7),idex_out.read_data1,memtoreg_out,exmem_out.ALU_result,
			nodata,read1);
U8:mux4_1 port map (idex_out.ex(6 downto 5),idex_out.read_data2,memtoreg_out,exmem_out.ALU_result,
			nodata,read21);
U9:mux2_1 port map (idex_out.ex(4),read21,idex_out.after_sign,read2);
U10:dram port map (clk,exmem_out.ALU_result,exmem_out.data,memwb_in.memdata,exmem_out.m(1),exmem_out.m(0));
U11:mux2_1 port map (memwb_out.wb(0),memwb_out.memdata,memwb_out.ALU_result,memtoreg_out);

PC_updata:process(clk)  --PC update every rising clock
	   begin
	    if clk'event and clk='1' then 
	     if reset='1' then
		  PC_out<=(others=>'0');
		 elsif reset='0' then
	       PC_out<=PC_in;
	     end if;
	    end if;
	  end process;

self_increase:process(PC_out,clk)--you ifid_in chufa jincheng
 		begin 
 		 pc_out1<=pc_out + "100";
 	      end process self_increase;

ifid_stage:process(clk)
   	    begin
   	      if clk'event and clk='1' then
   	        if reset='1' then
   	          ifid_out<=((others=>'0'),(others=>'0'),'0');
   	        else 
   	        ifid_out<=ifid_in;
   	        end if;
		  end if;
   	    end process ifid_stage;
   	   
idex_in.read_data1<=(others=>'0') when ifid_out.pc(25 downto 21) = "00000" else
            		    (others=>'0') when ifid_out.pc(31 downto 26) = "101101" else
		    reg_data when ifid_in.pc(25 downto 21) = reg_write else
		    ram_array(conv_integer(ifid_out.pc(25 downto 21)));
idex_in.read_data2<=data_ex when (ifid_out.pc(20 downto 16) = "00000" and ifid_out.pc(31 downto 26) = "101100") else 
		    reg_data when ifid_in.pc(20 downto 16) = reg_write else
		    ram_array(conv_integer(ifid_out.pc(20 downto 16)));
		    
process(clk)
begin
if clk'event and clk='1' then
 if memwb_out.wb(1)='1' then
  if reg_write/="00000" then 
   ram_array(conv_integer(reg_write))<=reg_data;
  elsif reg_write="00000" then
   ram_array(0)<=reg_data;
  end if;
 end if;
end if;
end process;

branch:eaquel<='0' when idex_in.read_data1=idex_in.read_data2 else
                '0' when idex_in.read_data1=idex_in.read_data2 and idex_in.read_data1="UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU" and  idex_in.read_data2="UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU" else  
	        '0';
      
idex_stage:process(clk)
	    begin 
	     if clk'event and clk='1' then
	       if reset='1' then
	         idex_out<=((others=>'0'),(others=>'0'),(others=>'0'),(others=>'0'),
	                   (others=>'0'),(others=>'0'),(others=>'0'),(others=>'0'));
	       else 
	         idex_out<=idex_in;
	       end if;
	     end if;
 	    end process idex_stage;
 	    
exmem_stage:process(clk)
  	     begin
  	      if clk'event and clk='1' then
	       if reset='1' then
	         exmem_out<=((others=>'0'),(others=>'0'),(others=>'0'),(others=>'0'),(others=>'0'));
	       else 
	         exmem_out<=exmem_in;
	       end if;
	      end if;
	    end process exmem_stage;

memwb_stage:process(clk)
  	     begin 
  	      if clk'event and clk='1' then
	       if reset='1' then
	         memwb_out<=((others=>'0'),(others=>'0'),(others=>'0'),(others=>'0'));
	       else 
	         memwb_out<=memwb_in;
	       end if;
	      end if;
	    end process memwb_stage;

data_buffer:process(clk)
	     begin
	      if clk'event and clk='0' then
	       exmem_in.wb<=idex_out.wb after 1 ns;
	       exmem_in.m<=idex_out.m after 1 ns;
	       memwb_in.wb<=exmem_out.wb after 1 ns;
	       idex_in.ins1<=ifid_out.pc(20 downto 16) after 1 ns;
	       idex_in.ins2<=ifid_out.pc(15 downto 11) after 1 ns;
	      end if;
	      end process;
	      
mux:process(idex_out.ex(9),idex_out.ins1,idex_out.ins2)
	begin
	 if reset='0' then
	   case idex_out.ex(9) is
	    when '0' => exmem_in.ins<=idex_out.ins1;
	    when '1' => exmem_in.ins<=idex_out.ins2;
	    when others=>null;
	   end case;
	 else
	   exmem_in.ins<=(others=>'Z');
	 end if;
	end process;
end core;

⌨️ 快捷键说明

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