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

📄 cu.vhd

📁 32位微处理器的设计
💻 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 + -