FPGA-Based 16-Bit ALU Design VHDL Code Simulation

Name: FPGA-Based 16-Bit ALU Design VHDL Code Simulation

Software: Quartus

Language: VHDL

Code Function:

1. Implement a simple 16-bit ALU using VHDL.

1) The main function of the Arithmetic Logic Unit (ALU) is to perform fixed-point arithmetic operations, logical operations, and various shift operations on binary data. Arithmetic operations include fixed-point addition, subtraction, multiplication, and division; logical operations mainly include logical AND, logical OR, logical XOR, and logical NOT. The ALU typically has two data inputs A and B for the operands, one data output Y, and flag outputs for the results. The operation to be performed is determined by the input operation code (op). This experiment implements a state machine that inputs operands and operation codes based on the state changes of the state machine, ultimately performing different calculations and presenting the results and flag outputs.

2) The ALU is required to implement basic arithmetic operations, logical operations, and shift operations, as detailed in the table below. Properly set the flag bits for each instruction, including Carry Flag (CF), Overflow Flag (OF), Sign Flag (SF), and Zero Flag (ZF).

FPGA-Based 16-Bit ALU Design VHDL Code Simulation

1. Project Files

FPGA-Based 16-Bit ALU Design VHDL Code Simulation

2. Program Files

FPGA-Based 16-Bit ALU Design VHDL Code Simulation

3. Program Compilation

FPGA-Based 16-Bit ALU Design VHDL Code Simulation

FPGA-Based 16-Bit ALU Design VHDL Code Simulation

4. RTL Diagram

FPGA-Based 16-Bit ALU Design VHDL Code Simulation

5. Testbench

FPGA-Based 16-Bit ALU Design VHDL Code Simulation

6. Simulation Diagram

FPGA-Based 16-Bit ALU Design VHDL Code Simulation

FPGA-Based 16-Bit ALU Design VHDL Code Simulation

FPGA-Based 16-Bit ALU Design VHDL Code Simulation

Partial code display:

-- Libraries used
LIBRARY ieee;
   USE ieee.std_logic_1164.all;
   USE ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
   USE ieee.std_logic_arith.all;
-- ALU entity declaration
ENTITY ALU IS
   PORT (
      A         : IN STD_LOGIC_VECTOR(15 DOWNTO 0);-- 16-bit input A
      B         : IN STD_LOGIC_VECTOR(15 DOWNTO 0);-- 16-bit input B
      op        : IN STD_LOGIC_VECTOR(3 DOWNTO 0);-- 4-bit operation code
      CF        : OUT STD_LOGIC;-- CF, Carry Flag
      O_F       : OUT STD_LOGIC;-- OF, Overflow Flag
      SF        : OUT STD_LOGIC;-- SF, Sign Flag
      ZF        : OUT STD_LOGIC;-- ZF, Zero Flag
      result    : OUT STD_LOGIC_VECTOR(15 DOWNTO 0)-- Output ALU calculation result
   );
END ALU;
-- End of entity declaration
ARCHITECTURE behave OF ALU IS
-- Define intermediate signals
   SIGNAL A_ext           : STD_LOGIC_VECTOR(16 DOWNTO 0):= (others => '0');-- 16-bit input A extended to 17 bits
   SIGNAL B_ext           : STD_LOGIC_VECTOR(16 DOWNTO 0):= (others => '0');-- 16-bit input B extended to 17 bits
   SIGNAL B_bu            : STD_LOGIC_VECTOR(16 DOWNTO 0):= (others => '0');-- B's complement, for subtraction calculation
   SIGNAL result_temp_add : STD_LOGIC_VECTOR(16 DOWNTO 0):= (others => '0');-- Sum of A+B
   SIGNAL result_temp_sub : STD_LOGIC_VECTOR(16 DOWNTO 0):= (others => '0');-- A-B difference
   SIGNAL result_temp    : STD_LOGIC_VECTOR(15 DOWNTO 0):= (others => '0');-- Cache output ALU calculation result
   SIGNAL B_int  : INTEGER := 0; -- B converted to int type
BEGIN
B_int <= Conv_Integer(B);-- Conv_Integer function converts B to int
   result <= result_temp;-- Output ALU calculation result
   A_ext <= ('0' & A);-- 16-bit input A extended to 17 bits
   B_ext <= ('0' & B);-- 16-bit input B extended to 17 bits
   B_bu <= NOT((B_ext)) + "00000000000000001";-- B's complement, negate and add 1, for subtraction calculation
   result_temp_add <= A_ext + B_ext;-- A+B sum
   result_temp_sub <= A_ext + B_bu;-- A+B's complement, i.e., A-B difference

-- Perform different operations based on operation code
   PROCESS (op, result_temp_add, result_temp_sub, A, B)
   BEGIN
      CASE op IS
         WHEN "0000" =>-- Addition
            result_temp <= result_temp_add(15 DOWNTO 0);-- 16-bit A+B sum
         WHEN "0001" =>-- Subtraction
            result_temp <= result_temp_sub(15 DOWNTO 0);-- 16-bit A-B difference
         WHEN "0010" =>-- AND
            result_temp <= A AND B;
         WHEN "0011" =>-- OR
            result_temp <= A OR B;
         WHEN "0100" =>-- XOR
            result_temp <= A XOR B;
         WHEN "0101" =>-- NOT
            result_temp <= NOT(A);
         WHEN "0110" =>-- Logical left shift B bits, B_int is the int value of B
            result_temp <= to_stdlogicvector( to_bitvector(A) SLL B_int );-- SLL operation requires conversion to bitvector type, convert back to stdlogicvector type after calculation
         WHEN "0111" =>-- Logical right shift B bits
            result_temp <= to_stdlogicvector( to_bitvector(A) SRL B_int );-- SRL operation requires conversion to bitvector type, convert back to stdlogicvector type after calculation
         WHEN "1000" =>-- Arithmetic left shift B bits
            result_temp <= to_stdlogicvector( to_bitvector(A) SLA B_int );-- SLA operation requires conversion to bitvector type, convert back to stdlogicvector type after calculation
         WHEN "1001" =>-- Arithmetic right shift B bits
            result_temp <= to_stdlogicvector( to_bitvector(A) SRA B_int );-- SRA operation requires conversion to bitvector type, convert back to stdlogicvector type after calculation
         WHEN "1010" =>-- Rotate left B bits
            result_temp <= to_stdlogicvector( to_bitvector(A) ROL B_int );-- ROL operation requires conversion to bitvector type, convert back to stdlogicvector type after calculation
         WHEN "1011" =>-- Rotate right B bits
            result_temp <= to_stdlogicvector( to_bitvector(A) ROR B_int );-- ROR operation requires conversion to bitvector type, convert back to stdlogicvector type after calculation
         WHEN OTHERS =>-- Other outputs 0
result_temp <= "0000000000000000";
      END CASE;
   END PROCESS;
   
   -- Output carry
   CF <= result_temp_add(16) WHEN (op = "0000") ELSE-- Output highest bit of result_temp_add during addition
         result_temp_sub(16) WHEN (op = "0001") ELSE-- Output highest bit of result_temp_sub during subtraction
         '0';
-- Output overflow flag
   PROCESS (op, A_ext, B_ext, result_temp_add, B_bu, result_temp_sub)
   BEGIN

FPGA-Based 16-Bit ALU Design VHDL Code Simulation

Leave a Comment