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

📄 cpu.vhd

📁 说明:cpuyuanma1是硬布线控制器源代码
💻 VHD
字号:
--实验11 组合逻辑控制器实验
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL,IEEE.NUMERIC_STD.ALL;
USE WORK.CPU_DEFS.ALL;

ENTITY CPU IS
PORT( clock    : IN     STD_LOGIC;
      reset    : IN     STD_LOGIC;
	  mode     : IN     STD_LOGIC_VECTOR(2 DOWNTO 0);       --used to select the content of output
	  mem_addr : IN 	UNSIGNED(word_w-op_w-1 DOWNTO 0);
	
	  PC_bus   : INOUT  STD_LOGIC;                          -- signal of PC
	  load_PC  : INOUT  STD_LOGIC;                          -- signal of PC
	  INC_PC   : INOUT  STD_LOGIC;                          -- signal of PC	
	
	  Addr_bus : INOUT  STD_LOGIC;                          -- signal of IR
	  load_IR  : INOUT  STD_LOGIC;                          -- signal of IR	  
	  
	  ACC_bus  : INOUT  STD_LOGIC;                          -- signal of ALU
	  load_ACC : INOUT  STD_LOGIC;                          -- signal of ALU
	  ALU_ACC  : INOUT  STD_LOGIC;                          -- signal of ALU
	  ALU_add  : INOUT  STD_LOGIC;                          -- signal of ALU
	  ALU_sub  : INOUT  STD_LOGIC;                          -- signal of ALU
	  z_flag   : INOUT  STD_LOGIC;                          -- signal of ALU 
	  
	  MDR_bus  : INOUT  STD_LOGIC;                          -- signal of RAM	
	  load_MDR : INOUT  STD_LOGIC;                          -- signal of RAM	
	  load_MAR : INOUT  STD_LOGIC;                          -- signal of RAM	
	  CS       : INOUT  STD_LOGIC;                          -- signal of RAM	
	  R_NW     : INOUT  STD_LOGIC;                          -- signal of RAM		  
	  
	  sysbus_out : OUT  STD_LOGIC_VECTOR(word_w-1 DOWNTO 0);     --output of bus	
	  present_out: OUT  STD_LOGIC_VECTOR(3 DOWNTO 0);			 --the output of C,Z,V,S	
	  output     : OUT  STD_LOGIC_VECTOR(word_w-1 DOWNTO 0)      --output of PC,opcode,mdr,mar,IR,acc,mem	 
	);	         
END ENTITY;

ARCHITECTURE rtl OF CPU IS
	TYPE   state IS (s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10);
	TYPE mem_array IS ARRAY (0 TO 2**(word_w-op_w)-1) OF STD_LOGIC_VECTOR(word_w-1 DOWNTO 0);
	SIGNAL   mem       : mem_array;
	CONSTANT prog      : mem_array:=(
				0=> op2slv(load)  & STD_LOGIC_VECTOR(TO_UNSIGNED(4,word_w-op_w)),
				1=> op2slv(add)   & STD_LOGIC_VECTOR(TO_UNSIGNED(5,word_w-op_w)),
				2=> op2slv(store) & STD_LOGIC_VECTOR(TO_UNSIGNED(6,word_w-op_w)),
				3=> op2slv(bne)   & STD_LOGIC_VECTOR(TO_UNSIGNED(7,word_w-op_w)),	
				4=> STD_LOGIC_VECTOR(TO_UNSIGNED(2,word_w)),
				5=> STD_LOGIC_VECTOR(TO_UNSIGNED(3,word_w)),
				OTHERS => (OTHERS =>'0'));
	SIGNAL present_state,next_state:state;
	SIGNAL mdr_out    :  STD_LOGIC_VECTOR(word_w-1 DOWNTO 0);    --output of mdr
	SIGNAL mar_out    :  UNSIGNED(word_w-op_w-1 DOWNTO 0);       --output of mar
	SIGNAL IR_out     :  STD_LOGIC_VECTOR(word_w-1 DOWNTO 0);    --output of Instruction Register
	--SIGNAL present_out:  STD_LOGIC_VECTOR(3 DOWNTO 0);	         --output of current state
	SIGNAL acc_out    :  UNSIGNED(word_w-1 DOWNTO 0);            --output of acc	
	SIGNAL count      :  UNSIGNED(word_w-op_w-1 DOWNTO 0);	
	SIGNAL op         :  STD_LOGIC_VECTOR(op_w-1 DOWNTO 0);
BEGIN	

	PROCESS(clock,reset) 		
		VARIABLE instr_reg : STD_LOGIC_VECTOR(word_w-1 DOWNTO 0);	
		VARIABLE acc       : UNSIGNED(word_w-1 DOWNTO 0);
		CONSTANT zero      : UNSIGNED(word_w-1 DOWNTO 0):=(others =>'0');		
		VARIABLE mdr       : STD_LOGIC_VECTOR(word_w-1 DOWNTO 0);
		VARIABLE mar       : UNSIGNED(word_w-op_w-1 DOWNTO 0);
		VARIABLE sysbus    : STD_LOGIC_VECTOR(word_w-1 DOWNTO 0);
	BEGIN			
		IF reset='0' THEN
			count     <= (OTHERS =>'0');
			instr_reg := (OTHERS =>'0');
			acc       := (OTHERS =>'0');
			mdr       := (OTHERS =>'0');
			mar       := (OTHERS =>'0');
			z_flag    <='0';
			mem       <= prog;
			sysbus    :=(OTHERS =>'0');
			present_state <=s0;				
					
		ELSIF RISING_EDGE(clock) THEN
			--PC
			IF PC_bus='1' THEN
				sysbus := rfill & STD_LOGIC_VECTOR(count);
			END IF;		
			IF load_PC='1' THEN 
				--count <= UNSIGNED(sysbus(word_w-op_w-1 DOWNTO 0));
				count <= UNSIGNED(mdr(word_w-op_w-1 DOWNTO 0));
			ELSIF INC_PC='1' THEN 
				count <= count+1;					
			ELSE 
				count <= count;
			END IF;				
			
			--IR
			IF load_IR='1' THEN
				instr_reg := mdr;				
			END IF;
			IF Addr_bus='1' THEN
				sysbus := rfill & instr_reg(word_w-op_w-1 DOWNTO 0);
			END IF;	
			op     <= instr_reg(word_w-1 DOWNTO word_w-op_w);			
			IR_out <= instr_reg;
			
			--ALU
			IF load_ACC='1' THEN				
				acc:=UNSIGNED(mdr);
			END IF;
			IF ALU_ACC='1' THEN
				IF ALU_add='1' THEN
					acc := acc + UNSIGNED(mdr);
				ELSIF ALU_sub='1' THEN
			 		acc := acc - UNSIGNED(mdr);
				END IF;
			END IF;
			IF ACC_bus='1' THEN
				sysbus := STD_LOGIC_VECTOR(acc);
			END IF;
			IF acc=zero THEN
				z_flag <='1';
			ELSE
				z_flag <='0';
			END IF;
			acc_out<= acc;
			
			--RAM
			IF load_MAR='1' THEN
				mar := UNSIGNED(sysbus(word_w-op_w-1 DOWNTO 0));
			ELSIF load_MDR='1' THEN
				mdr := sysbus;
			ELSIF CS='1' THEN
				IF R_NW='1' THEN
					mdr := mem(TO_INTEGER(mar));					
				ELSE
					mem(TO_INTEGER(mar))<=mdr;
				END IF;
			END IF;
			
			IF MDR_bus='1' THEN
				sysbus:=mdr;
			END IF;
			mdr_out <= mdr;
			mar_out <= mar;
			
			--sequencer
			present_state <= next_state;	
		END IF;	
		
		sysbus_out <=sysbus;	
	   
	END PROCESS;
	
	
	PROCESS(present_state,op,z_flag)	
		
	BEGIN
		ACC_bus  <= '0';
		load_ACC <= '0';
		PC_bus   <= '0';
		load_PC  <= '0';
		load_IR  <= '0';
		load_MAR <= '0';
		MDR_bus  <= '0';
		load_MDR <= '0';
		ALU_ACC  <= '0';
		ALU_add  <= '0';
		ALU_sub  <= '0';
		INC_PC   <= '0';
		Addr_bus <= '0';
		CS       <= '0';
		R_NW     <= '0';
		CASE present_state IS
		WHEN s0 =>
			PC_bus     <= '1';
			load_MAR   <= '1';
	  		INC_PC     <= '1';
			next_state <= s1;
			present_out<= "0000";
			
		WHEN s1 =>
			CS         <= '1';
			R_NW       <= '1';
			next_state <= s2;
			present_out<= "0001";
			
		WHEN s2 =>
			MDR_bus    <= '1';
			load_IR    <= '1';
			next_state <= s3;
			present_out<= "0010";
			
		WHEN s3 =>
			Addr_bus   <= '1';
			load_MAR   <= '1';
			present_out<= "0011";
			IF op="001" THEN   --op=store 
				next_state <=s4;				
			ELSE
				next_state <=s6;				
			END IF;
		WHEN s4 =>
			ACC_bus    <= '1';
			load_MDR   <= '1';
			next_state <= s5;
			present_out<= "0100";
			
		WHEN s5 =>
			CS         <= '1';
			r_NW       <= '0';
			next_state <= s0;
			present_out<= "0101";
			
		WHEN s6 =>
			CS         <= '1';
			R_NW       <= '1';
			present_out<= "0110";
			IF op="000" THEN   --op=load
				next_state <=s7;				
			ELSIF op="100" THEN  --op=bne
				IF z_flag='0' THEN
					next_state <=s9;				    
				ELSE 
					next_state <=s10;				    
				END IF;
			ELSE 
				next_state <=s8;				
			END IF;
		WHEN s7=>
			MDR_bus    <= '1';
			load_ACC   <= '1';
			next_state <= s0;
			present_out<= "0111";			
		WHEN s8 =>
			MDR_bus    <= '1';
			ALU_ACC    <= '1';				
			present_out<= "1000";
			IF op="010" THEN   --op=add
				ALU_add <='1';
			ELSIF op="011" THEN  --op=sub
				ALU_sub <='1';
			END IF;
			next_state <=s0;
			
		WHEN s9=>
			MDR_bus    <= '1';
			load_PC    <= '1';
			next_state <= s0;
			present_out<= "1001";
			
		WHEN s10=>
			next_state <= s0;
			present_out<= "1010";
		END CASE;
		
		
	END PROCESS;
	
	
	PROCESS(mode,mem_addr)                            
	BEGIN    
		--mode=0 -> PC  
		--mode=1 -> opcode
		--mode=2 -> mdr
		--mode=3 -> mar
		--mode=4 -> IR
		--mode=5 -> result of ALU
		--mode=6 -> mem                                         		
		output <= (OTHERS =>'0');		
		CASE mode is                    
		WHEN "000" =>                   
			output(word_w-op_w-1 downto 0)<= STD_LOGIC_VECTOR(count);		 							
		WHEN "001" =>					
			output(op_w-1 downto 0) <= op;
		WHEN "010" =>
			output <= mdr_out;
		WHEN "011" =>
			output(word_w-op_w-1 downto 0) <= STD_LOGIC_VECTOR(mar_out);
		WHEN "100" =>
			output <= IR_out;
		WHEN "101" =>
			output <= STD_LOGIC_VECTOR(acc_out);
		WHEN "110" =>
			output <= mem(TO_INTEGER(mem_addr));	
		WHEN others =>
			output <= (others =>'Z');	
		END CASE;
	END PROCESS;		
			
								
END ARCHITECTURE;						
										
										

⌨️ 快捷键说明

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