📄 cu.vhd
字号:
------------------------------------------------------------------------------------ Company: -- Engineer: -- -- Create Date: 18:58:53 12/16/2007 -- Design Name: -- Module Name: cu - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: ---- Dependencies: ---- Revision: -- Revision 0.01 - File Created-- Additional Comments: ------------------------------------------------------------------------------------library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.numeric_std.ALL;use IEEE.std_logic_signed.ALL;---- Uncomment the following library declaration if instantiating---- any Xilinx primitives in this code.--library UNISIM;--use UNISIM.VComponents.all;entity cu is Port ( clk : in STD_LOGIC; rst : in STD_LOGIC; compout : in signed (1 downto 0); --比较器输出到CU r : out STD_LOGIC; --读信号 wb : out STD_LOGIC; --写字节信号 ww : out STD_LOGIC; --写双字信号 en_r1 : out STD_LOGIC; --寄存器组一号数据口读使能信号
en_r2 : out STD_LOGIC; --寄存器组二号数据口读使能信号 en_wr : out STD_LOGIC; --写寄存器组使能信号 en_comp : out STD_LOGIC; --比较器使能信号 en_ir : out STD_LOGIC; --指令寄存器写使能信号 muxalu1_c : out STD_LOGIC; --ALU1号数据口前的数据选择器控制信号 muxalu2_c : out STD_LOGIC;--ALU2号数据口前的数据选择器控制信号 muxa_c : out STD_LOGIC; --地址线前的数据选择器控制信号 rra1 : out signed (4 downto 0); --寄存器组1号地址口
rra2 : out signed (4 downto 0); --寄存器组2号地址口 wra : out signed (4 downto 0); --写寄存器组地址 imm : out signed (31 downto 0); --经过符号扩展后的32位立即数 alu_c : out signed (1 downto 0); --ALU控制信号 pcalu_c : out signed (2 downto 0); --PCALU控制信号 muxpcalu_c : out signed (1 downto 0); --PCALU前数据选择器的控制信号 muxwrd_c : out signed (2 downto 0); --寄存器组写入口数据选择器控制信号 instr : in signed (31 downto 0); --来自指令寄存器的输入信号 instr_out : out signed (31 downto 0)); --instr经过转换的结果end cu;architecture Behavioral of cu is subtype state_type is std_logic_vector(1 downto 0); constant FETCH : state_type:="00"; constant DECODE : state_type:="01"; constant EXECUTE : state_type:="10"; constant alunop : signed(1 downto 0):="00"; constant aluadd_addu_addi_addiu:signed(1 downto 0):="01"; constant alusll : signed(1 downto 0):="11"; constant alusubu : signed(1 downto 0):="10"; constant pcalunop : signed(2 downto 0):="000"; constant pcalubne : signed(2 downto 0):="001"; constant pcaluj : signed(2 downto 0):="010"; constant pcalujr : signed(2 downto 0):="011"; constant pcalubeq : signed(2 downto 0):="100"; constant pcalu4 : signed(2 downto 0):="101"; constant pcalujal : signed(2 downto 0):="110"; -- state signals signal cur_state:state_type; signal nxt_state:state_type; signal lb,lw :std_logic; signal sf :std_logic; signal lreg :signed(4 downto 0); signal r_dummy :std_logic; begin -- choose next state state_comb: process(cur_state,rst) begin if (rst='1') then nxt_state <= FETCH; else case cur_state is when FETCH => nxt_state <= DECODE; when DECODE => nxt_state <= EXECUTE; when others => nxt_state <= FETCH; end case; end if; end process state_comb; -- 2bit state translate state_sync:process(rst,clk) begin if (rst='1') then cur_state<=FETCH; elsif (rising_edge(clk)) then cur_state<=nxt_state; end if; end process state_sync; main: process(cur_state,instr,rst) variable rs,rt,rd,sa:signed(4 downto 0); variable off:signed(15 downto 0); variable imm16:signed(15 downto 0); variable imm26:signed(25 downto 0); begin rs := instr(25 downto 21); rt := instr(20 downto 16); rd := instr(15 downto 11); imm16 := signed(instr(15 downto 0)); imm26 := signed(instr(25 downto 0)); off := instr(15 downto 0); sa := instr(10 downto 6); -- default control signals alu_c <= alunop; pcalu_c <= pcalunop; en_comp <='0'; en_r1 <='0'; en_r2 <='0'; en_wr <='0'; if (rst='1') then lb <='0'; lw <='0'; r <='1'; r_dummy <='1'; sf <='0'; muxa_c <='0'; wb <='0'; ww <='0'; en_ir <='1'; else r <='0'; en_ir <='0'; case cur_state is when FETCH => r<=r_dummy; en_ir<='1'; when DECODE => if ((lb or lw or sf)='0') then if ((instr(31 downto 26)& instr(5 downto 0)="000000100011") or (instr(31 downto 26)& instr(5 downto 0)="000000100001") or (instr(31 downto 26)& instr(5 downto 0)="000000100000")) then --subu,add_addu rra1 <= rs; --将addr送入寄存器 en_r1 <= '1'; rra2 <= rt; en_r2 <= '1'; muxalu1_c <= '0'; --选择muxalu1的rs端口 muxalu2_c <= '0'; --选择muxalu1的rt端口 pcalu_c <= pcalu4; --pc+4 muxpcalu_c <= "00"; end if; if ((instr(31 downto 26)="001000") or (instr(31 downto 26)="001001")) then --addi_addiu rra1 <= rs; en_r1 <= '1'; muxalu1_c <='0'; imm <= resize(imm16,32); muxalu2_c <= '0'; pcalu_c <= pcalu4; muxpcalu_c <="00"; end if; if (instr(31 downto 26)& instr(5 downto 0)="000000000000") then --sll rra2 <= rt; en_r2 <='1'; muxalu1_c <='1'; imm <= resize(sa,32); muxalu2_c <='0'; pcalu_c <= pcalu4; muxpcalu_c <= "00"; end if; if ((instr(31 downto 26)="000101") or (instr(31 downto 26)="000100")) then --bne & beq en_comp <='1'; rra1 <= rs; en_r1 <= '1'; rra2 <= rt; en_r2 <= '1'; imm <= resize(imm16,32); pcalu_c <= pcalu4; muxpcalu_c <= "00"; end if; if (instr(31 downto 26)="000010") then --j imm <= resize(imm26,32); muxpcalu_c <= "01"; end if; if (instr(31 downto 26)="000011") then --jal pcalu_c <= pcalu4; muxpcalu_c <= "00"; end if; if (instr(31 downto 26) & instr(5 downto 0)="000000001000") then --jr muxpcalu_c <= "10"; rra1 <= rs; en_r1 <= '1'; end if ; if ((instr(31 downto 26)="101011") or (instr(31 downto 26)="101000")) then --sw & sb rra1 <= rs; en_r1 <= '1'; muxalu1_c <='0'; muxalu2_c <='0'; imm <= resize(off,32); pcalu_c <= pcalu4; muxpcalu_c <= "00"; end if ; if ((instr(31 downto 26)="100011") or (instr(31 downto 26)="100100")) then --lw & lbu rra1 <= rs; en_r1 <= '1'; muxalu1_c <='0'; muxalu2_c <='0'; imm <= resize(off,32); pcalu_c <= pcalu4; muxpcalu_c <= "00"; end if; if (instr(31 downto 26) & instr(5 downto 0)="000000101010") then --slt en_comp <= '1'; rra1 <= rs; en_r1 <= '1'; rra2 <= rt; en_r2 <= '1'; pcalu_c <= pcalu4; muxpcalu_c <= "00"; end if; if (instr(31 downto 26)="001111") then --lui imm(31 downto 16) <= imm16; imm(15 downto 0) <= (others => '0'); pcalu_c <= pcalu4; muxpcalu_c <= "00"; end if; end if; when EXECUTE => r_dummy <= '1'; wb <='0'; ww <='0'; muxa_c <='0'; if ((lb or lw)='0') then --receive compout,then do operation and write register if (instr(31 downto 26) & instr(5 downto 0)="000000100011") then --subu alu_c <= alusubu; wra <= rd; muxwrd_c <= "001"; en_wr <= '1'; end if; if ((instr(31 downto 26)& instr(5 downto 0)="000000100001") or (instr(31 downto 26)& instr(5 downto 0)="000000100000")) then --add&add_addu alu_c <= aluadd_addu_addi_addiu; wra <= rd; muxwrd_c <= "001"; en_wr <= '1'; end if; if ((instr(31 downto 26)="001000") or (instr(31 downto 26)="001001")) then --addi &addiu alu_c <= aluadd_addu_addi_addiu; wra <= rt; muxwrd_c <= "001"; en_wr <= '1'; end if; if (instr(31 downto 26)& instr(5 downto 0)="000000000000") then --sll alu_c <= alusll; wra <= rd; muxwrd_c <= "001"; en_wr <= '1'; end if; if (instr(31 downto 26)="000101") then --bne pcalu_c <= pcalubne; muxpcalu_c <= "01"; end if; if (instr(31 downto 26)="000100") then --beq pcalu_c <= pcalubeq; muxpcalu_c <= "01"; end if; if (instr(31 downto 26)="000010") then --j pcalu_c <= pcaluj; end if; if (instr(31 downto 26)="000011") then --jal imm <= resize(imm26,32); muxpcalu_c <= "01"; pcalu_c <= pcalujal; wra <= "11111"; en_wr <= '1'; muxwrd_c <= "010"; end if; if (instr(31 downto 26)& instr(5 downto 0)="000000001000") then --jr pcalu_c <= pcalujr; end if; if (instr(31 downto 26) = "101011") then --sw if (sf='0') then r_dummy <= '0'; sf <= '1'; alu_c <= aluadd_addu_addi_addiu; ww <= '1'; muxa_c <= '1'; rra2 <= rt; en_r2 <= '1'; end if; end if; if (instr(31 downto 26)="100011") then --lw muxa_c <= '1'; lw <= '1'; lreg <= rt; alu_c <= aluadd_addu_addi_addiu; end if; if (instr(31 downto 26)="100100") then --lbu muxa_c <= '1'; lb <= '1'; lreg <= rt; alu_c <= aluadd_addu_addi_addiu; end if; if (instr(31 downto 26)="101000") then --sb if (sf='0') then r_dummy <= '0'; sf <= '1'; alu_c <= aluadd_addu_addi_addiu; wb <= '1'; muxa_c <= '1'; rra2 <= rt; en_r2 <= '1'; end if ; end if; if (instr(31 downto 26)& instr(5 downto 0)="000000101010") then --slt if (compout = "10") then wra <= rd; en_wr <= '1'; muxwrd_c <= "101"; else wra <= rd; en_wr <= '1'; muxwrd_c <= "110"; end if; end if; if (instr(31 downto 26)="001111") then --lui wra <= rt; en_wr <= '1'; muxwrd_c <= "011"; end if; if (sf='1') then sf <= '0'; end if; elsif (lb='1') then wra <= lreg; muxwrd_c <= "100"; en_wr <= '1'; instr_out <=signed(resize(unsigned(instr(31 downto 24)),32)); lb <= '0'; elsif (lw='1') then wra <= lreg; muxwrd_c <="100"; en_wr <= '1'; instr_out <= instr; lw <= '0'; end if; when others => null; end case; end if; end process main; end Behavioral;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -