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

📄 cpu.vhd

📁 16位元浮点数CPU,可作运算,以VHDL编写
💻 VHD
字号:
package commonConstants is	constant wordSize: integer := 16;	constant adrLength: integer := 16;end package commonConstants;library IEEE;use IEEE.std_logic_1164.all;use IEEE.std_logic_arith.all;use work.commonConstants.all;entity ram is port (        reset, en, r_w: in STD_LOGIC;        aBus: in STD_LOGIC_VECTOR(adrLength-1 downto 0);        dBus: inout STD_LOGIC_VECTOR(wordSize-1 downto 0));end ram;architecture ramArch of ram isconstant resAdrLength: integer := 6; -- address length restricted within architectureconstant memSize: integer := 2**resAdrLength;type ram_typ is array(0 to memSize-1) of STD_LOGIC_VECTOR(wordSize-1 downto 0);signal ram: ram_typ;begin	process(reset, en, r_w, aBus, dBus) begin	  	if reset = '1' then		      	-- basic instruction check	        	  ram(0)  <= x"2005"; -- direct load			     ram(1)  <= x"a006"; -- negate		        ram(2)  <= x"4004"; -- direct store		        ram(3)  <= x"0000"; -- halt		        ram(5)  <= x"999A"; -- X = 999A(1001100110011010)		        ram(6)  <= x"100F"; -- X = 100F(001000000001111)		elsif en = '1' and r_w = '0' then	  		ram(conv_integer(unsigned(aBus(resAdrLength-1 downto 0)))) <= dBus;		end if;	end process;	dBus <= ram(conv_integer(unsigned(aBus(resAdrLength-1 downto 0))))  			when reset = '0' and en = '1' and r_w = '1' else			(dbus'range => 'Z');end ramArch;---------------------------------------------------------library IEEE;use IEEE.std_logic_1164.all;use IEEE.std_logic_arith.all;use IEEE.std_logic_unsigned.all;use work.commonConstants.all;entity cpu is port (    	clk, reset 	: in  std_logic;    	m_en, m_rw	: out std_logic;    		aBus		: out std_logic_vector(adrLength-1 downto 0);	dBus		: inout std_logic_vector(wordSize-1 downto 0);	-- these signals "exported" so they can be monitored in post-P&R simulation	pcX, iarX	: out std_logic_vector(adrLength-1 downto 0);	iregX, accX, aluX	: out std_logic_vector(wordSize-1 downto 0));end cpu;architecture cpuArch of cpu istype state_type is (	reset_state, fetch, halt, negate, mload, dload, iload,	dstore, istore, branch, brZero, brPos, brNeg, add);signal state: state_type;type tick_type is (t0, t1, t2, t3, t4, t5, t6, t7);signal tick: tick_type;signal pc: 	std_logic_vector(adrLength-1 downto 0); -- program countersignal iReg: 	std_logic_vector(wordSize-1 downto 0); -- instruction registersignal iar: 	std_logic_vector(adrLength-1 downto 0); -- indirect address registersignal acc: 	std_logic_vector(wordSize-1 downto 0); -- accumulatorsignal alu: 	std_logic_vector(wordSize-1 downto 0); -- alu outputbegin	alu <= 	(not acc) + x"0001" when state = negate else				acc + dbus when state = add else				(alu'range => '0');	pcX <= pc; iregX <= ireg; iarX <= iar; accX <= acc; aluX <= alu;	process(clk) -- perform actions that occur on rising clock edges	function nextTick(tick: tick_type) return tick_type is begin		-- return next logical value for tick		case tick is		when t0 => return t1; when t1 => return t2; when t2 => return t3;		when t3 => return t4; when t4 => return t5; when t5 => return t6;		when t6 => return t7; when others => return t0;		end case;	end function nextTick;	procedure decode is begin		-- Instruction decoding.		case iReg(15 downto 12) is		when x"0" =>			if iReg(11 downto 0) = x"000" then 				state <= halt;			elsif iReg(11 downto 0) = x"001" then 				state <= negate;			end if;		when x"1" => 	state <= mload;		when x"2" => 	state <= dload;		when x"3" => 	state <= iload;		when x"4" => 	state <= dstore;		when x"5" => 	state <= istore;		when x"6" => 	state <= branch;		when x"7" => 	state <= brZero;			when x"8" => 	state <= brPos;		when x"9" => 	state <= brNeg;		when x"a" => 	state <= add;		when others => state <= halt;		end case;	end procedure decode;  	procedure wrapup is begin		-- Do this at end of every instruction		state <= fetch; tick <= t0;	end procedure wrapup;	begin	  	if clk'event and clk = '1' then	  		if reset = '1' then 				state <= reset_state; tick <= t0;				pc <= (pc'range => '0'); iReg <= (iReg'range => '0');				acc <= (acc'range => '0'); iar <= (iar'range => '0');    			else				tick <= nextTick(tick) ; -- advance time by default				case state is				when reset_state => state <= fetch; tick <= t0; m_rw <= '1';				when fetch => 	if tick = t1 then iReg <= dBus; end if;									if tick = t2 then 										decode; pc <= pc + '1'; tick <= t0;									end if;				when halt => tick <= t0; -- do nothing				when negate => if tick = t0 then alu <= 	(not acc) + x"0001"; end if;				               if tick = t1 then acc <= alu;	wrapup;                           end if;                                             				-- load instructions				when mload => 					if iReg(11) = '0' then -- sign extension						acc <= x"0" & ireg(11 downto 0); 					else						acc <= x"f" & ireg(11 downto 0);					end if;					wrapup;				when dload =>					if tick = t1 then acc <= dBus; end if;					if tick = t2 then wrapup; end if;				when iload =>					if tick = t1 then iar <= dBus; end if;					if tick = t4 then acc <= dBus; end if;					if tick = t5 then wrapup; end if;				-- store instructions			  					when dstore =>					if tick = t4 then wrapup; end if;				when istore =>					if tick = t1 then iar <= dBus; end if;					if tick = t7 then wrapup; end if;				-- branch instructions				when branch => 					pc <= x"0" & iReg(11 downto 0);					wrapup;				when brZero => 					if acc = x"0000" then pc <= x"0" & iReg(11 downto 0);	end if;					wrapup;				when brPos => 					if acc(15) = '0' and acc /= x"0000" then 						pc <= x"0" & iReg(11 downto 0);					end if;					wrapup;				when brNeg => 					if acc(15) = '1' then pc <= x"0" & iReg(11 downto 0);	end if;					wrapup;				-- arithmetic instructions				when add =>					if tick = t1 then alu <= acc + dbus; end if;					if tick = t2 then acc <= alu; end if;					if tick = t3 then wrapup; end if;				when others => state <= halt;				end case;			end if;  		end if;	end process;	process(clk) begin -- perform actions that occur on falling clock edges		if clk'event and clk ='0' then			if reset = '1' then				m_en <= '0'; m_rw <= '1';				aBus <= (aBus'range => '0'); dBus <= (dBus'range => 'Z');			else				case state is				when fetch =>					if tick = t0 then m_en <= '1'; aBus <= pc; end if;					if tick = t2 then m_en <= '0'; aBus <= "ZZZZZZZZZZZZZZZZ"; end if;			  	when dload =>					if tick = t0 then m_en <= '1'; aBus <= x"0" & iReg(11 downto 0); end if;					if tick = t2 then m_en <= '0'; aBus <= "ZZZZZZZZZZZZZZZZ"; end if;			  	when iload =>					if tick = t0 then m_en <= '1'; aBus <= x"0" & iReg(11 downto 0); end if;					if tick = t2 then m_en <= '0'; aBus <= "ZZZZZZZZZZZZZZZZ"; end if;					if tick = t3 then m_en <= '1'; aBus <= iar; end if;					if tick = t5 then m_en <= '0'; aBus <= "ZZZZZZZZZZZZZZZZ"; end if;								  	when dstore =>					if tick = t0 then m_en <= '1'; aBus <= x"0" & iReg(11 downto 0); end if;					if tick = t1 then m_rw <= '0'; dBus <= acc; end if;					if tick = t3 then m_rw <= '1'; end if;					if tick = t4 then 						m_en <= '0'; aBus <= "ZZZZZZZZZZZZZZZZ"; dBus <= "ZZZZZZZZZZZZZZZZ"; 					end if;				when istore =>					if tick = t0 then m_en <= '1'; aBus <= x"0" & iReg(11 downto 0); end if;					if tick = t2 then m_en <= '0'; aBus <= "ZZZZZZZZZZZZZZZZ"; end if;					if tick = t3 then m_en <= '1'; aBus <= iar; end if;					if tick = t4 then m_rw <= '0'; dBus <= acc; end if;					if tick = t6 then m_rw <= '1'; end if;					if tick = t7 then 						m_en <= '0'; aBus <= "ZZZZZZZZZZZZZZZZ"; dBus <= "ZZZZZZZZZZZZZZZZ"; 					end if;				when add =>					if tick = t0 then m_en <= '1'; aBus <= x"0" & iReg(11 downto 0); end if;					if tick = t3 then m_en <= '0'; aBus <= "ZZZZZZZZZZZZZZZZ"; end if;				when others => -- do nothing				end case;			end if;			end if;						end process;end cpuArch;-------------------------------library IEEE;use IEEE.std_logic_1164.all;use IEEE.std_logic_arith.all;use work.commonConstants.all;entity top is port(	clk, reset: in STD_LOGIC;	mem_enX, mem_rwX : out std_logic;	aBusX : out std_logic_vector(adrLength-1 downto 0);	dBusX : out std_logic_vector(wordSize-1 downto 0);	pcX, iarX : out std_logic_vector(adrLength-1 downto 0);	iregX, accX, aluX : out std_logic_vector(wordSize-1 downto 0));end top;architecture topArch of top iscomponent ram port (        reset, en, r_w: in STD_LOGIC;        aBus: in STD_LOGIC_VECTOR(adrLength-1 downto 0);        dBus: inout STD_LOGIC_VECTOR(wordSize-1 downto 0));end component;component cpu port (    	clk, reset:	in  STD_LOGIC;    	m_en, m_rw: out STD_LOGIC;    		aBus:	out STD_LOGIC_VECTOR(adrLength-1 downto 0);	dBus:	inout STD_LOGIC_VECTOR(wordSize-1 downto 0);	pcX, iarX : out std_logic_vector(wordSize-1 downto 0);	iregX, accX, aluX : out std_logic_vector(wordSize-1 downto 0));end component;signal mem_en, mem_rw: STD_LOGIC;signal aBus, dBus: STD_LOGIC_VECTOR(15 downto 0);signal pc, ireg, iar, acc, alu: std_logic_vector(15 downto 0);begin	ramC: ram port map(reset, mem_en, mem_rw, aBus, dBus);	cpuC: cpu port map(clk, reset, mem_en, mem_rw, aBus, dBus,			pc, iar, ireg, acc, alu);	mem_enX <= mem_en; mem_rwX <= mem_rw;	aBusX <= aBus; dBusX <= dBus;	pcX <= pc; iregX <= ireg; iarX <= iar; accX <= acc; aluX <= alu;end topArch;

⌨️ 快捷键说明

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