You are on page 1of 4

VHDL code for a simple ALU

ALU(Arithmetic Logic Unit) is a digital circuit which does arithmetic and logical operations. Its a basic block in any processor. In this article I have shared vhdl code for a simple ALU. Note that this is one of the simplest architecture of an ALU. Most of the ALU's used in practical designs are far more complicated and requires good design experience. The block diagram of the ALU is given below. As you can see, it receives two input operands 'A' and 'B' which are 8 bits long. The result is denoted by 'R' which is also 8 bit long. The input signal 'Op' is a 3 bit value which tells the ALU what operation to be performed by the ALU. Since 'Op' is 3 bits long we can have 2^3=8 operations.

Our ALU is capable of doing the following operations:

ALU Operation Description Add Signed R = A + B : Treating A, B, and R as signed two's complement integers. Subtract Signed R = A - B : Treating A, B, and R as signed two's complement integers. Bitwise AND Bitwise NOR Bitwise OR Bitwise XOR Biwise NOT R(i) = A(i) AND B(i). R(i) = A(i) NOR B(i). R(i) = A(i) OR B(i). R(i) = A(i) XOR B(i). R(i) = NOT A(i).

Bitwise NAND R(i) = A(i) NAND B(i).

These functions are implemented using a case statement. The ALU calculates the outputs at every positive edge of clock cycle. As soon as the outputs are calculated it is available at the port signal 'R'. See the code below, to know how it is done:

library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity simple_alu is port( Clk : in std_logic; --clock signal A,B : in signed(7 downto 0); --input operands Op : in unsigned(2 downto 0); --Operation to be performed R : out signed(7 downto 0) --output of ALU ); end simple_alu; architecture Behavioral of simple_alu is --temporary signal declaration. signal Reg1,Reg2,Reg3 : signed(7 downto 0) := (others => '0'); begin Reg1 <= A; Reg2 <= B; R <= Reg3; process(Clk) begin if(rising_edge(Clk)) then --Do the calculation at the positive edge of clock cycle. case Op is when "000" => Reg3 <= Reg1 + Reg2; --addition when "001" => Reg3 <= Reg1 - Reg2; --subtraction when "010" => Reg3 <= not Reg1; --NOT gate when "011" => Reg3 <= Reg1 nand Reg2; --NAND gate when "100" => Reg3 <= Reg1 nor Reg2; --NOR gate when "101" => Reg3 <= Reg1 and Reg2; --AND gate when "110" => Reg3 <= Reg1 or Reg2; --OR gate when "111" => Reg3 <= Reg1 xor Reg2; --XOR gate when others => NULL; end case;

end if; end process; end Behavioral;


The testbench code used for testing the ALU code is given below:

LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY tb IS END tb; ARCHITECTURE behavior OF tb IS signal Clk : std_logic := '0'; signal A,B,R : signed(7 downto 0) := (others => '0'); signal Op : unsigned(2 downto 0) := (others => '0'); constant Clk_period : time := 10 ns; BEGIN -- Instantiate the Unit Under Test (UUT) uut: entity work.simple_alu PORT MAP ( Clk => Clk, A => A, B => B, Op => Op, R => R ); -- Clock process definitions Clk_process :process begin Clk <= '0'; wait for Clk_period/2; Clk <= '1'; wait for Clk_period/2; end process; -- Stimulus process stim_proc: process begin wait for Clk_period*1; A <= "00010010"; --18 in decimal B <= "00001010"; --10 in decimal Op <= "000"; wait for Clk_period; --add A and B Op <= "001"; wait for Clk_period; --subtract B from A.

Op <= "010"; Op <= "011"; B Op <= "100"; Op <= "101"; Op <= "110"; Op <= "111"; wait; end process; END;

wait for Clk_period; --Bitwise NOT of A wait for Clk_period; --Bitwise NAND of A and wait wait wait wait for for for for Clk_period; Clk_period; Clk_period; Clk_period; --Bitwise --Bitwise --Bitwise --Bitwise NOR of A and B AND of A and B OR of A and B XOR of A and B

You might also like