📄 controlunit.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 + -