?? coreofcpu.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 + -