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).

1. Project Files

2. Program Files

3. Program Compilation


4. RTL Diagram

5. Testbench

6. Simulation Diagram



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
