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

📄 cpu.vhd

📁 这是接上面程序
💻 VHD
字号:
--实验12 微程序控制器实验 
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);       
	  mem_addr   : IN 	UNSIGNED(word_w-op_w-1 DOWNTO 0);	  
	  output     : OUT  STD_LOGIC_VECTOR(word_w-1 DOWNTO 0); 	
	  data_r_out : OUT  STD_LOGIC_VECTOR(19 DOWNTO 0);
	  op_out     : OUT  STD_LOGIC_VECTOR(op_w-1 DOWNTO 0);
	  add_r_out  : OUT  UNSIGNED(4 DOWNTO 0)  	  
	);	         
END ENTITY;

ARCHITECTURE rtl OF CPU IS	
	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'));	
	TYPE microcode_array IS ARRAY (0 TO 14) OF STD_LOGIC_VECTOR(19 DOWNTO 0);
	CONSTANT code      : microcode_array:=(
				0=> "00010100010000000001",
				1=> "00000000000110000010",
				2=> "00001010000000000011",
				3=> "00000100001000001111",	
				4=> "00100010000000000000",
				5=> "00000000000100000000",
				6=> "00000010100001000000",
				7=> "00000010100000100000",
				8=> "00000000000110000100",
				9=> "01000001000000000101",
			   10=> "00000000000110000110",	
			   11=> "00000000000110000111",
			   12=> "00000000000110010000",
       		   13=> "10000010000000000000",
		       14=> "00000000000000000000");	
	
	SIGNAL count    :  UNSIGNED(word_w-op_w-1 DOWNTO 0);
	SIGNAL op       :  STD_LOGIC_VECTOR(op_w-1 DOWNTO 0);		
	SIGNAL z_flag   :  STD_LOGIC;                          
	SIGNAL mdr_out  :  STD_LOGIC_VECTOR(word_w-1 DOWNTO 0);   
	SIGNAL mar_out  :  UNSIGNED(word_w-op_w-1 DOWNTO 0);       
	SIGNAL IR_out   :  STD_LOGIC_VECTOR(word_w-1 DOWNTO 0);    	
	SIGNAL acc_out  :  UNSIGNED(word_w-1 DOWNTO 0);            	
	SIGNAL sysbus_out : STD_LOGIC_VECTOR(word_w-1 DOWNTO 0);  
	
BEGIN	
		
	PROCESS(reset,clock)
		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);			
		VARIABLE microcode : microcode_array;
		VARIABLE add_r     : UNSIGNED(4 DOWNTO 0);	
    	VARIABLE data_r    : STD_LOGIC_VECTOR(19 DOWNTO 0);
		VARIABLE temp      : STD_LOGIC_VECTOR(4 DOWNTO 0);
	BEGIN		
	
		IF reset='0' THEN
			add_r:=(OTHERS =>'0');			         
			count     <= (OTHERS =>'0');
			instr_reg := (OTHERS =>'0');
			acc       := (OTHERS =>'0');
			mdr       := (OTHERS =>'0');
			mar       := (OTHERS =>'0');
			z_flag    <='0';
			mem       <= prog;
			sysbus    :=(OTHERS =>'0');	
			
		ELSIF RISING_EDGE(clock) THEN			
			--microprogram controller	
			data_r  := code(TO_INTEGER(add_r));				
			IF data_r(4 DOWNTO 0)="01111" THEN --判断下地址
			    temp:="01" & op(2 DOWNTO 0);
				add_r := UNSIGNED(temp);
			ELSIF data_r(4 DOWNTO 0)="10000"  THEN
				IF z_flag='1' THEN
					add_r:="01110";
				ELSE
					add_r :="01101";
				END IF;
			ELSE
				add_r   := UNSIGNED(data_r(4 DOWNTO 0));
			END IF;			
			data_r_out <=data_r;
			add_r_out <= add_r;
			
		    --PC
			IF data_r(16)='1' THEN     --PC_bus='1'
				sysbus := rfill & STD_LOGIC_VECTOR(count);
			END IF;		
			IF data_r(19)='1' THEN     --load_PC='1'
				count <= UNSIGNED(mdr(word_w-op_w-1 DOWNTO 0));
			ELSIF data_r(10)='1' THEN    --INC_PC='1'
				count <= count+1;					
			ELSE 
				count <= count;
			END IF;				
			
			--IR
			IF data_r(15)='1' THEN   --load_IR
				instr_reg := mdr;				
			END IF;
			IF data_r(9)='1' THEN    --Addr_bus='1'
				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;
			op_out <=op;
			
			--ALU
			IF data_r(17)='1' THEN    --load_ACC='1'				
				acc:=UNSIGNED(mdr);
			END IF;
			IF data_r(11)='1' THEN  --ALU_ACC='1'
				IF data_r(6)='1' THEN   --ALU_add='1'
					acc := acc + UNSIGNED(mdr);
				ELSIF data_r(5)='1' THEN   --ALU_sub='1'
			 		acc := acc - UNSIGNED(mdr);
				END IF;
			END IF;
			IF data_r(18)='1' THEN  --ACC_bus='1'
				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 data_r(14)='1' THEN  --load_MAR='1'
				mar := UNSIGNED(sysbus(word_w-op_w-1 DOWNTO 0));
			ELSIF data_r(12)='1' THEN   --load_MDR='1'
				mdr := sysbus;
			ELSIF data_r(8)='1' THEN   --CS='1'
				IF data_r(7)='1' THEN      --R_NW='1'
					mdr := mem(TO_INTEGER(mar));					
				ELSE
					mem(TO_INTEGER(mar))<=mdr;
				END IF;
			END IF;			
			IF data_r(13)='1' THEN   --MDR_bus='1'
				sysbus:=mdr;
			END IF;
			mdr_out <= mdr;
			mar_out <= mar;	
		END IF;	
		
		sysbus_out <=sysbus;	
		
		 
	END PROCESS;
	
	PROCESS(mode,mem_addr)                            
	BEGIN    
		--mode=0 -> sysbus  
		--mode=1 -> PC
		--mode=2 -> result of ALU
		--mode=3 -> IR
		--mode=4 -> MAR
		--mode=5 -> MDR
		--mode=6 -> mem                                         		
		output <= (OTHERS =>'0');		
		CASE mode is                    
		WHEN "000" =>  
			output<=sysbus_out;
		WHEN "001" =>                   
			output(word_w-op_w-1 DOWNTO 0)<= STD_LOGIC_VECTOR(count);	
		WHEN "010" =>
			output <= STD_LOGIC_VECTOR(acc_out);
		WHEN "011" =>
			output <= IR_out;	
		WHEN "100" =>
			output(word_w-op_w-1 DOWNTO 0) <= STD_LOGIC_VECTOR(mar_out);
		WHEN "101" =>
			output <= mdr_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 + -