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

📄 alu.vhd

📁 alu算术逻辑运算单元 主要代码 运行环境为QU6.0
💻 VHD
字号:
--实验8 ALU
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;

LIBRARY LPM;
USE LPM.LPM_COMPONENTS.ALL;

ENTITY ALU IS
	GENERIC (width:NATURAL:=7; op_w:NATURAL:=3);
	PORT ( 
	      a, b    : IN std_logic_vector(width DOWNTO 0);
	      op      : IN std_logic_vector(op_w DOWNTO 0);
	      result  : OUT std_logic_vector(width DOWNTO 0);
	      c       : OUT std_logic ;
          z       : OUT std_logic ;
          v       : OUT std_logic ;
	      n       : OUT std_logic
         );
END ALU;

ARCHITECTURE struct OF ALU IS

	CONSTANT ALU_ADD  : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "0000";
	CONSTANT ALU_SUB  : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "0001";
	CONSTANT ALU_ADDU : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "0010";
	CONSTANT ALU_SUBU : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "0011";
	CONSTANT ALU_AND  : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "0100";		
	CONSTANT ALU_OR   : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "0101";		
	CONSTANT ALU_XOR  : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "0110";		
	CONSTANT ALU_NOTA : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "0111";
	CONSTANT ALU_SLL  : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "1000";			
	CONSTANT ALU_SRL  : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "1001";		
	CONSTANT ALU_SLA  : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "1010";	
	CONSTANT ALU_SRA  : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "1011";
	CONSTANT ALU_ROL  : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "1100";
	CONSTANT ALU_ROR  : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "1101";
	CONSTANT ALU_SET  : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "1110";
	CONSTANT ALU_CLR  : STD_LOGIC_VECTOR(op_w DOWNTO 0) := "1111";
	CONSTANT NC8      : STD_LOGIC_VECTOR(width DOWNTO 0):= "--------";
	CONSTANT ZR8      : STD_LOGIC_VECTOR(width DOWNTO 0):= "00000000";	
	
	COMPONENT lpm_add_sub
	GENERIC (
		lpm_width		: NATURAL;
		lpm_direction	: STRING;
		lpm_type		: STRING;
		lpm_hint		: STRING
	);
	PORT (
		dataa	: IN STD_LOGIC_VECTOR (width DOWNTO 0);
		datab	: IN STD_LOGIC_VECTOR (width DOWNTO 0);
		cin	    : IN STD_LOGIC ;
		cout, overflow : OUT STD_LOGIC;
		result	: OUT STD_LOGIC_VECTOR (width DOWNTO 0)
	);
	END COMPONENT;
	
	SIGNAL ADDER_out_overflow  : STD_LOGIC;
	SIGNAL ADDER_out_cout      : STD_LOGIC;
	SIGNAL ADDER_out_result    : STD_LOGIC_VECTOR(width DOWNTO 0);
	SIGNAL ADDER_in_dataa      : STD_LOGIC_VECTOR(width DOWNTO 0);
	SIGNAL ADDER_in_datab      : STD_LOGIC_VECTOR(width DOWNTO 0);
	SIGNAL ADDER_in_cin        : STD_LOGIC;
	SIGNAL r                   : STD_LOGIC_VECTOR(width DOWNTO 0);
	SIGNAL sll_r               : STD_LOGIC_VECTOR(width DOWNTO 0);
	SIGNAL srl_r               : STD_LOGIC_VECTOR(width DOWNTO 0);
	SIGNAL sla_r               : STD_LOGIC_VECTOR(width DOWNTO 0);
	SIGNAL sra_r               : STD_LOGIC_VECTOR(width DOWNTO 0);
	SIGNAL rol_r               : STD_LOGIC_VECTOR(width DOWNTO 0);
	SIGNAL ror_r               : STD_LOGIC_VECTOR(width DOWNTO 0);
	
BEGIN
	
	ADDER_in_dataa <= a;
	ADDER_in_datab <= NOT b WHEN op=ALU_SUB  ELSE
	                  NOT b WHEN op=ALU_SUBU ELSE 
	                  b;
	ADDER_in_cin   <= '1' WHEN op=ALU_SUB  ELSE
	                  '1' WHEN op=ALU_SUBU ELSE 
	                  '0';	
	
	ALU_ADDER : lpm_add_sub
	GENERIC MAP (
		lpm_width => (width+1),
		lpm_direction => "ADD",
		lpm_type => "LPM_ADD_SUB",
		lpm_hint => "ONE_INPUT_IS_CONSTANT=NO,CIN_USED=YES"
	)
	PORT MAP (
		dataa => ADDER_in_dataa,
		datab => ADDER_in_datab,
		cin => ADDER_in_cin,
		overflow => ADDER_out_overflow,
		cout => ADDER_out_cout,
		result => ADDER_out_result
	);
	
    --SLL
    PROCESS (a, b) IS
    	VARIABLE x,y : STD_LOGIC_VECTOR (width DOWNTO 0);
    BEGIN
    	CASE b(0) IS
		WHEN '0' => x :=  a;
		WHEN '1' => x := a((width-1) DOWNTO 0) & '0'; 
		WHEN OTHERS => NULL;
		END CASE;
		CASE b(1) IS
		WHEN '0' => y := x;
		WHEN '1' => y := x((width-2) DOWNTO 0) & "00"; 
        WHEN OTHERS => NULL;
		END CASE;  
		CASE b(2) IS
		WHEN '0' => sll_r <= y;
		WHEN '1' => sll_r <= y((width-4) DOWNTO 0) & "0000"; 
        WHEN OTHERS => NULL;
		END CASE;		
	END PROCESS;	
	
    --SRL
    PROCESS (a, b) IS
    	VARIABLE x,y : STD_LOGIC_VECTOR (width DOWNTO 0);
    BEGIN
    	CASE b(0) IS
		WHEN '0' => x := a;
		WHEN '1' => x := '0' & a(width DOWNTO 1); 
        WHEN OTHERS => NULL;
		END CASE;
		CASE b(1) IS
		WHEN '0' => y := x;
		WHEN '1' => y := "00" & x(width DOWNTO 2); 
        WHEN OTHERS => NULL;
		END CASE;  
		CASE b(2) IS
		WHEN '0' => srl_r <= y;
		WHEN '1' => srl_r <= "0000" & y(width DOWNTO 4); 
        WHEN OTHERS => NULL;
		END CASE;
	END PROCESS;
	
    --SLA
    PROCESS (a, b) IS
    	VARIABLE x,y : STD_LOGIC_VECTOR (width DOWNTO 0);
    BEGIN
    	CASE b(0) IS
		WHEN '0' => x := a;
		WHEN '1' => x := a((width-1) DOWNTO 0) & a(0); 
		WHEN OTHERS => NULL;
		END CASE;
		CASE b(1) IS
		WHEN '0' => y := x;
		WHEN '1' => y := x((width-2) DOWNTO 0) & x(0) & x(0); 
		WHEN OTHERS => NULL;
		END CASE;  
		CASE b(2) IS
		WHEN '0' => sla_r <= y;
		WHEN '1' => sla_r <= y((width-4) DOWNTO 0) & y(0) & y(0) & y(0) & y(0); 
		WHEN OTHERS => NULL;
		END CASE;
	END PROCESS;
	
	--SRA
	PROCESS (a, b) IS
    	VARIABLE x,y : STD_LOGIC_VECTOR (width DOWNTO 0);
    BEGIN
		CASE b(0) IS
		WHEN '0' => x := a;
		WHEN '1' => x := a(width) & a(width DOWNTO 1); 
		WHEN OTHERS => NULL;
		END CASE;
		CASE b(1) IS
		WHEN '0' => y := x;
		WHEN '1' => y := x(width) & x(width) & x(width DOWNTO 2); 
		WHEN OTHERS => NULL;
		END CASE;  
		CASE b(2) IS
		WHEN '0' => sra_r <= y;
		WHEN '1' => sra_r <= y(width) & y(width) & y(width) & y(width) & y(width DOWNTO 4); 
		WHEN OTHERS => NULL;
		END CASE;		
	END PROCESS;
	
	--ROL
	PROCESS (a, b) IS
    	VARIABLE x,y : STD_LOGIC_VECTOR (width DOWNTO 0);
    BEGIN
		CASE b(0) IS
		WHEN '0' => x := a;
		WHEN '1' => x := a((width-1) DOWNTO 0) & a(width); 
		WHEN OTHERS => NULL;
		END CASE;
		CASE b(1) IS
		WHEN '0' => y := x;
		WHEN '1' => y := x((width-2) DOWNTO 0) & x(width DOWNTO (width-1)); 
		WHEN OTHERS => NULL;
		END CASE;  
		CASE b(2) IS
		WHEN '0' => rol_r <= y;
		WHEN '1' => rol_r <= y((width-4) DOWNTO 0) & y(width DOWNTO (width-3)); 
		WHEN OTHERS => NULL;
		END CASE;
	END PROCESS;
	
	--ROR
	PROCESS (a, b) IS
    	VARIABLE x,y : STD_LOGIC_VECTOR (width DOWNTO 0);
    BEGIN
		CASE b(0) IS
		WHEN '0' => x := a;
		WHEN '1' => x := a(0) & a(width DOWNTO 1); 
		WHEN OTHERS => NULL;
		END CASE;
		CASE b(1) IS
		WHEN '0' => y := x;
		WHEN '1' => y := x(1 DOWNTO 0) & x(width DOWNTO 2); 
		WHEN OTHERS => NULL;
		END CASE;  
		CASE b(2) IS
		WHEN '0' => ror_r <= y;
		WHEN '1' => ror_r <= y(3 DOWNTO 0) & y(width DOWNTO 4); 
		WHEN OTHERS => NULL;
		END CASE;
	END PROCESS;
	
	RESULT_MUX : PROCESS (a, b, ADDER_out_result, sll_r, srl_r,
	                      sla_r, sra_r, rol_r, ror_r, op) IS
	BEGIN
		CASE op IS
		WHEN ALU_ADD | ALU_SUB | ALU_ADDU | ALU_SUBU =>
			r <= ADDER_out_result;
		WHEN ALU_AND =>
			r <= a AND b;
		WHEN ALU_OR =>
			r <= a OR b;
		WHEN ALU_XOR => 
			r <= a XOR b;
		WHEN ALU_NOTA =>
			r <= NOT a;
		WHEN ALU_SLL =>
			r <= sll_r;
		WHEN ALU_SRL =>
	        r <= srl_r; 	
		WHEN ALU_SLA =>
			r <= sla_r;
		WHEN ALU_SRA =>
		    r <= sra_r;
		WHEN ALU_ROL =>
			r <= rol_r;
		WHEN ALU_ROR =>  
			r <= ror_r;
		WHEN ALU_SET =>  
            r <= "11111111";
		WHEN ALU_CLR =>	
		    r <= "00000000";
		WHEN OTHERS =>
			r <= NC8;
		END CASE;
	END PROCESS;
		
	v <= ADDER_out_overflow WHEN op=ALU_ADD ELSE
	     ADDER_out_overflow WHEN op=ALU_SUB ELSE 
	     '0';
	z <= '1' WHEN r=ZR8 ELSE '0';
	c <= ADDER_out_cout WHEN op=ALU_ADD ELSE
	     ADDER_out_cout;
	n <= '0' WHEN op=ALU_ADDU ELSE
	     NOT ADDER_out_cout WHEN op=ALU_SUBU ELSE
	     r(width);
	result <= r;
END struct;

⌨️ 快捷键说明

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