Unit3 Part1
Unit3 Part1
Decoder
A decoder that has two inputs, an enable pin and four outputs is implemented in a
CPLD
using VHDL in this part of the VHDL course.
This 2x4 decoder will switch on one of the four active low outputs, depending on
the
binary value of the two inputs and if the enable input
is high.
VHDL
Behavioural
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity decoder_2x4_behavioral is
Port ( A : in STD_LOGIC_VECTOR (1 downto 0); -- 2-bit input
Y : out STD_LOGIC_VECTOR (3 downto 0)); -- 4-bit outp
end decoder_2x4_behavioral;
Unit 3 1
when "10" => Y <= "0100";
when "11" => Y <= "1000";
when others => Y <= "0000";
end case;
end process;
end Behavioral;
Dataflow
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity decoder_2x4_dataflow is
Port ( A : in STD_LOGIC_VECTOR (1 downto 0);
Y : out STD_LOGIC_VECTOR (3 downto 0));
end decoder_2x4_dataflow;
Strcutural
Unit 3 2
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity decoder_2x4_structural is
Port ( A : in STD_LOGIC_VECTOR (1 downto 0);
Y : out STD_LOGIC_VECTOR (3 downto 0));
end decoder_2x4_structural;
Verilog
module decoder_2x4_behavioral (
input [1:0] A, // 2-bit input
output reg [3:0] Y // 4-bit output
);
Unit 3 3
2'b00: Y = 4'b0001;
2'b01: Y = 4'b0010;
2'b10: Y = 4'b0100;
2'b11: Y = 4'b1000;
default: Y = 4'b0000;
endcase
end
endmodule
module decoder_2x4_dataflow (
input [1:0] A,
output [3:0] Y
);
endmodule
module decoder_2x4_structural (
input [1:0] A,
output [3:0] Y
);
// NOT gates
not (notA0, A[0]);
not (notA1, A[1]);
Unit 3 4
// AND gates for each output
and (Y[0], notA1, notA0);
and (Y[1], notA1, A[0]);
and (Y[2], A[1], notA0);
and (Y[3], A[1], A[0]);
endmodule
Encoder
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity encoder_4to2 is
Port (
I : in STD_LOGIC_VECTOR(3 downto 0); -- 4-bit input
Y : out STD_LOGIC_VECTOR(1 downto 0) -- 2-bit output
);
end encoder_4to2;
Unit 3 5
when "0001" => Y <= "00"; -- Input I0 is 1, outputs
when others => Y <= "00"; -- Default case
end case;
end process;
end Behavioral;
module encoder_4to2 (
input wire [3:0] I, // 4-bit input
output reg [1:0] Y // 2-bit output
);
endmodule
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity encoder_4to2 is
Port (
I : in STD_LOGIC_VECTOR(3 downto 0); -- 4-bit input
Y : out STD_LOGIC_VECTOR(1 downto 0) -- 2-bit output
);
end encoder_4to2;
Unit 3 6
architecture Dataflow of encoder_4to2 is
begin
Y(1) <= I(3) or I(2); -- Y1 is 1 if I3 or I2 is 1
Y(0) <= I(3) or (not I(2) and I(1)); -- Y0 is 1 if I3 or (I2
end Dataflow;
module encoder_4to2_dataflow (
input wire [3:0] I, // 4-bit input
output wire [1:0] Y // 2-bit output
);
endmodule
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity encoder_4to2 is
Port (
I : in STD_LOGIC_VECTOR(3 downto 0); -- 4-bit input
Y : out STD_LOGIC_VECTOR(1 downto 0) -- 2-bit output
);
end encoder_4to2;
Unit 3 7
signal not_I2 : STD_LOGIC;
signal I2_and_I1 : STD_LOGIC;
begin
-- Intermediate signals for gate outputs
I3_or_I2 <= I(3) or I(2);
not_I2 <= not I(2);
I2_and_I1 <= not_I2 and I(1);
module encoder_4to2_structural (
input wire [3:0] I, // 4-bit input
output wire [1:0] Y // 2-bit output
);
wire I3_or_I2;
wire not_I2;
wire I2_and_I1;
endmodule
Unit 3 8
Mux 2x1
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity mux_2to1 is
Port (
A : in STD_LOGIC;
B : in STD_LOGIC;
Sel : in STD_LOGIC;
Y : out STD_LOGIC
);
end mux_2to1;
module mux_2to1 (
input wire A,
input wire B,
input wire Sel,
output reg Y
Unit 3 9
);
endmodule
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity mux_2to1 is
Port (
A : in STD_LOGIC;
B : in STD_LOGIC;
Sel : in STD_LOGIC;
Y : out STD_LOGIC
);
end mux_2to1;
Unit 3 10
module mux_2to1 (
input wire A,
input wire B,
input wire Sel,
output wire Y
);
endmodule
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity mux_2to1 is
Port (
A : in STD_LOGIC;
B : in STD_LOGIC;
Sel : in STD_LOGIC;
Y : out STD_LOGIC
);
end mux_2to1;
Unit 3 11
Y <= and1 or and2;
end Structural;
module mux_2to1 (
input wire A,
input wire B,
input wire Sel,
output wire Y
);
endmodule
Mux 4x1
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity mux_4to1 is
Port (
A : in STD_LOGIC_VECTOR(3 downto 0);
Sel : in STD_LOGIC_VECTOR(1 downto 0);
Unit 3 12
Y : out STD_LOGIC
);
end mux_4to1;
module mux_4to1 (
input wire [3:0] A,
input wire [1:0] Sel,
output reg Y
);
Unit 3 13
endmodule
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity mux_4to1 is
Port (
A : in STD_LOGIC_VECTOR(3 downto 0);
Sel : in STD_LOGIC_VECTOR(1 downto 0);
Y : out STD_LOGIC
);
end mux_4to1;
module mux_4to1 (
input wire [3:0] A,
input wire [1:0] Sel,
output wire Y
);
Unit 3 14
endmodule
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity mux_4to1 is
Port (
A : in STD_LOGIC_VECTOR(3 downto 0);
Sel : in STD_LOGIC_VECTOR(1 downto 0);
Y : out STD_LOGIC
);
end mux_4to1;
A 4-to-1 multiplexer (4x1 MUX) is a digital device that selects one of four input
signals and forwards it to a single output line based on a select signal. It
essentially acts as a data selector, routing one of multiple input lines to the output.
Unit 3 15
The number of inputs to the multiplexer is \( 2^n \), where \( n \) is the number of
select lines.
4 input lines: typically labeled as \( I_0 \), \( I_1 \), \( I_2 \), and \( I_3 \).
The select lines control which of the inputs is connected to the output. In a 4-to-1
multiplexer:
0 0 \( I_0 \)
0 1 \( I_1 \)
1 0 \( I_2 \)
1 1 \( I_3 \)
Unit 3 16
For example:
2. Calculate the number of select lines required based on the number of inputs
using \( n = \log_2(N) \).
3. Create the logic to route each input to the output based on the binary values
of the select lines.
Use AND, OR, and NOT gates to design a circuit that implements the function
described in the truth table.
2 bit comparator
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Comparator is
Port (
A : in STD_LOGIC_VECTOR (1 downto 0); -- 2-bit input A
Unit 3 17
B : in STD_LOGIC_VECTOR (1 downto 0); -- 2-bit input B
A_gt_B : out STD_LOGIC; -- Output high if
A_eq_B : out STD_LOGIC; -- Output high if
A_lt_B : out STD_LOGIC -- Output high if
);
end Comparator;
module Comparator (
input [1:0] A, // 2-bit input A
input [1:0] B, // 2-bit input B
output reg A_gt_B, // Output high if A > B
output reg A_eq_B, // Output high if A = B
output reg A_lt_B // Output high if A < B
);
Unit 3 18
always @ (A or B) begin
if (A > B) begin
A_gt_B = 1;
A_eq_B = 0;
A_lt_B = 0;
end
else if (A == B) begin
A_gt_B = 0;
A_eq_B = 1;
A_lt_B = 0;
end
else begin
A_gt_B = 0;
A_eq_B = 0;
A_lt_B = 1;
end
end
endmodule
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Comparator2Bit is
Port (
A : in STD_LOGIC_VECTOR(1 downto 0);
B : in STD_LOGIC_VECTOR(1 downto 0);
A_gt_B : out STD_LOGIC;
A_eq_B : out STD_LOGIC;
A_lt_B : out STD_LOGIC
);
end Comparator2Bit;
Unit 3 19
architecture Dataflow of Comparator2Bit is
begin
-- A > B condition
A_gt_B <= (A(1) and not B(1)) or ((A(1) xnor B(1)) and (A(0)
-- A = B condition
A_eq_B <= (A(1) xnor B(1)) and (A(0) xnor B(0));
-- A < B condition
A_lt_B <= (not A(1) and B(1)) or ((A(1) xnor B(1)) and (not
end Dataflow;
module Comparator2Bit (
input [1:0] A,
input [1:0] B,
output A_gt_B,
output A_eq_B,
output A_lt_B
);
// A > B condition
assign A_gt_B = (A[1] & ~B[1]) | ((A[1] ~^ B[1]) & (A[0] & ~
// A = B condition
assign A_eq_B = (A[1] ~^ B[1]) & (A[0] ~^ B[0]);
// A < B condition
assign A_lt_B = (~A[1] & B[1]) | ((A[1] ~^ B[1]) & (~A[0] &
endmodule
Unit 3 20
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Comparator2Bit is
Port (
A : in STD_LOGIC_VECTOR(1 downto 0);
B : in STD_LOGIC_VECTOR(1 downto 0);
A_gt_B : out STD_LOGIC;
A_eq_B : out STD_LOGIC;
A_lt_B : out STD_LOGIC
);
end Comparator2Bit;
begin
-- NOT gates
notA1 <= not A(1);
notA0 <= not A(0);
notB1 <= not B(1);
notB0 <= not B(0);
-- A > B condition
Unit 3 21
A_gt_B <= A1_and_notB1 or (A1_xnor_B1 and A0_and_notB0);
-- A = B condition
A_eq_B <= A1_xnor_B1 and A0_xnor_B0;
-- A < B condition
A_lt_B <= notA1_and_B1 or (A1_xnor_B1 and notA0 and B(0));
end Structural;
module Comparator2Bit (
input [1:0] A,
input [1:0] B,
output A_gt_B,
output A_eq_B,
output A_lt_B
);
// NOT gates
not (notA1, A[1]);
not (notA0, A[0]);
not (notB1, B[1]);
not (notB0, B[0]);
Unit 3 22
// A > B condition
or (A_gt_B, A1_and_notB1, A1_xnor_B1 & A0_and_notB0);
// A = B condition
and (A_eq_B, A1_xnor_B1, A0_xnor_B0);
// A < B condition
or (A_lt_B, notA1_and_B1, A1_xnor_B1 & notA0 & B[0]);
endmodule
Half Adder
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Half_Adder is
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
Sum : out STD_LOGIC;
Carry : out STD_LOGIC);
end Half_Adder;
Unit 3 23
begin
process(A, B)
begin
Sum <= A XOR B;
Carry <= A AND B;
end process;
end Behavioral;
module Half_Adder(
input A,
input B,
output reg Sum,
output reg Carry
);
endmodule
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Half_Adder is
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
Sum : out STD_LOGIC;
Carry : out STD_LOGIC);
end Half_Adder;
Unit 3 24
architecture Dataflow of Half_Adder is
begin
Sum <= A XOR B;
Carry <= A AND B;
end Dataflow;
module Half_Adder(
input A,
input B,
output Sum,
output Carry
);
assign Sum = A ^ B;
assign Carry = A & B;
endmodule
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Half_Adder is
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
Sum : out STD_LOGIC;
Carry : out STD_LOGIC);
end Half_Adder;
component AND_GATE
Port ( X : in STD_LOGIC;
Unit 3 25
Y : in STD_LOGIC;
Z : out STD_LOGIC);
end component;
component XOR_GATE
Port ( X : in STD_LOGIC;
Y : in STD_LOGIC;
Z : out STD_LOGIC);
end component;
begin
end Structural;
module Half_Adder(
input A,
input B,
output Sum,
output Carry
);
Unit 3 26
assign Sum = xor_out;
assign Carry = and_out;
endmodule
Full Adder
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Full_Adder is
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
Cin : in STD_LOGIC;
Sum : out STD_LOGIC;
Cout : out STD_LOGIC );
end Full_Adder;
module Full_Adder (
input A,
input B,
input Cin,
output Sum,
Unit 3 27
output Cout
);
assign Sum = A ^ B ^ Cin;
assign Cout = (A & B) | (Cin & (A ^ B));
endmodule
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Full_Adder is
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
Cin : in STD_LOGIC;
Sum : out STD_LOGIC;
Cout : out STD_LOGIC );
end Full_Adder;
module Full_Adder (
input A,
input B,
input Cin,
output Sum,
Unit 3 28
output Cout
);
wire AB_XOR;
assign AB_XOR = A ^ B;
assign Sum = AB_XOR ^ Cin;
assign Cout = (A & B) | (Cin & AB_XOR);
endmodule
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Full_Adder is
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
Cin : in STD_LOGIC;
Sum : out STD_LOGIC;
Cout : out STD_LOGIC );
end Full_Adder;
Unit 3 29
Cout <= Carry1 OR Carry2;
end Structural;
module Half_Adder (
input X,
input Y,
output Sum,
output Carry
);
assign Sum = X ^ Y;
assign Carry = X & Y;
endmodule
module Full_Adder (
input A,
input B,
input Cin,
output Sum,
output Cout
);
wire Sum1, Carry1, Carry2;
Unit 3 30
Substractor
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Subtractor is
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
Borrow_in : in STD_LOGIC;
Diff : out STD_LOGIC;
Borrow_out : out STD_LOGIC );
end Subtractor;
module Subtractor(
input A,
input B,
input Borrow_in,
output Diff,
output Borrow_out
);
assign Diff = A ^ B ^ Borrow_in;
assign Borrow_out = (~A & B) | ((~(A ^ B)) & Borrow_in);
endmodule
Unit 3 31
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
component AND_GATE is
Port ( X : in STD_LOGIC;
Y : in STD_LOGIC;
Z : out STD_LOGIC );
end component;
component NOT_GATE is
Port ( A : in STD_LOGIC;
Z : out STD_LOGIC );
end component;
Unit 3 32
-- Signals for internal connections
signal xor1_out, xor2_out, and1_out, and2_out, not_a_out, no
begin
-- XOR1: First XOR for A and B
XOR1: XOR_GATE port map (A, B, xor1_out);
-- AND1: AND gate for the first borrow condition (NOT A AND
AND1: AND_GATE port map (not_a_out, B, and1_out);
end Structural;
Serial Adder
Unit 3 33
A Serial Adder adds two binary numbers one bit at a time, with each bit being
added in sequence. It requires a clock signal to synchronize the addition process.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Serial_Adder is
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
Cin : in STD_LOGIC;
clk : in STD_LOGIC;
Sum : out STD_LOGIC;
Cout : out STD_LOGIC );
end Serial_Adder;
end Behavioral;
module Serial_Adder(
input A,
input B,
Unit 3 34
input Cin,
input clk,
output reg Sum,
output reg Cout
);
reg carry;
endmodule
Parallel Adder
A Parallel Adder adds two binary numbers all at once (i.e., all bits of the two
numbers are added simultaneously). For a 4-bit adder, each bit of the numbers is
added in parallel, and the carry propagates through each bit.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Parallel_Adder is
Port ( A : in STD_LOGIC_VECTOR(3 downto 0);
B : in STD_LOGIC_VECTOR(3 downto 0);
Unit 3 35
Cin : in STD_LOGIC;
Sum : out STD_LOGIC_VECTOR(3 downto 0);
Cout : out STD_LOGIC );
end Parallel_Adder;
end Behavioral;
module Parallel_Adder(
input [3:0] A,
input [3:0] B,
input Cin,
output reg [3:0] Sum,
output reg Cout
);
Unit 3 36
reg [3:0] carry;
Cout = carry[3];
end
endmodule
BCD Adder
A BCD Adder is a type of adder used to add Binary Coded Decimal (BCD)
numbers. In BCD, each decimal digit is represented by a 4-bit binary number,
ranging from 0000 to 1001 (0 to 9). A BCD adder adds two BCD numbers and
ensures that the result is still in valid BCD format. If the sum
exceeds 9 (i.e., 1001 in binary), an additional 6 ( 0110 in binary) is added to
correct the result back to valid BCD.
ere's an explanation of how a BCD Adder works:
The BCD numbers are added just like regular binary numbers.
Unit 3 37
If the sum of two BCD digits is greater than 9 (i.e., 1010 or higher),
then 6 ( 0110 ) is added to correct the result.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity BCD_Adder is
Port ( A : in STD_LOGIC_VECTOR(3 downto 0);
B : in STD_LOGIC_VECTOR(3 downto 0);
Cin : in STD_LOGIC;
Sum : out STD_LOGIC_VECTOR(3 downto 0);
Cout : out STD_LOGIC);
end BCD_Adder;
Unit 3 38
end if;
end process;
end Behavioral;
nput Ports:
Output Ports:
Sum : The 4-bit result after addition and correction (if needed).
Internal Logic:
The two BCD numbers ( A and B ) are added along with the carry-in ( Cin )
to form a temporary 5-bit sum ( temp_sum ).
The Sum is assigned the lower 4 bits of the result, and the Cout (carry-out)
is set if the sum exceeds 9.
module BCD_Adder(
input [3:0] A, // 4-bit BCD input A
input [3:0] B, // 4-bit BCD input B
input Cin, // Carry-in
output reg [3:0] Sum, // 4-bit BCD sum
output reg Cout // Carry-out
);
Unit 3 39
always @(A or B or Cin) begin
temp_sum = A + B + Cin; // Add the inputs and carry
endmodule
Barrel Shifter
A Barrel Shifter is a digital circuit that can shift a data word (usually a multi-bit
binary number) by any number of positions in either direction (left or right), with
the shifted bits wrapping around to the opposite end. This is different from
traditional shift operations, where the bits that "fall off" during a shift are typically
lost. The barrel shifter handles this wrap-around operation and can shift the data
efficiently in parallel.
2. Right Barrel Shifter: Shifts the bits to the right and wraps the rightmost bits
around to the leftmost positions.
Unit 3 40
3. Bidirectional Barrel Shifter: Can shift in both left and right directions based on
the control signal.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Barrel_Shifter is
Port ( A : in STD_LOGIC_VECTOR(3 downto 0);
Shift : in INTEGER range 0 to 3; -- Amount of shif
Direction : in STD_LOGIC; -- '0' for left shift, '1
Y : out STD_LOGIC_VECTOR(3 downto 0)
);
end Barrel_Shifter;
Unit 3 41
end if;
end process;
end Behavioral;
module Barrel_Shifter(
input [3:0] A, // 4-bit input data
input [1:0] Shift, // Amount of shift (2 bits for 0 to 3
input Direction, // Shift direction (0 for left, 1 for
output reg [3:0] Y // 4-bit shifted output
);
endmodule
Unit 3 42
Multiplier
A multiplier is a circuit that takes two numbers as input and produces their product
as
an output. So a binary multiplier takes binary numbers as inputs and produces a
result
in binary. Before moving forward, lets quickly recap binary multiplication first.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Multiplier_2bit_Behavioral is
Port ( A : in STD_LOGIC_VECTOR(1 downto 0); -- 2-bit input
B : in STD_LOGIC_VECTOR(1 downto 0); -- 2-bit input
P : out STD_LOGIC_VECTOR(3 downto 0) -- 4-bit output
);
end Multiplier_2bit_Behavioral;
Unit 3 43
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Multiplier_2bit_Dataflow is
Port ( A : in STD_LOGIC_VECTOR(1 downto 0); -- 2-bit input
B : in STD_LOGIC_VECTOR(1 downto 0); -- 2-bit input
P : out STD_LOGIC_VECTOR(3 downto 0) -- 4-bit output
);
end Multiplier_2bit_Dataflow;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Multiplier_2bit_Structural is
Port ( A : in STD_LOGIC_VECTOR(1 downto 0); -- 2-bit input
B : in STD_LOGIC_VECTOR(1 downto 0); -- 2-bit input
P : out STD_LOGIC_VECTOR(3 downto 0) -- 4-bit output
);
end Multiplier_2bit_Structural;
component AND_GATE
Port ( X : in STD_LOGIC;
Y : in STD_LOGIC;
Z : out STD_LOGIC );
Unit 3 44
end component;
component OR_GATE
Port ( X : in STD_LOGIC;
Y : in STD_LOGIC;
Z : out STD_LOGIC );
end component;
begin
-- First AND Gate for A(0) and B(0)
AND1: AND_GATE port map (A(0), B(0), and1);
end Structural;
Unit 3 45
module Multiplier_2bit_Behavioral (
input [1:0] A, // 2-bit input A
input [1:0] B, // 2-bit input B
output [3:0] P // 4-bit output product
);
assign P = (A[0] & B[0]) | (A[1] & B[0]) | (A[0] & B[1]) | (A[1]
endmodule
module Multiplier_2bit_Dataflow (
input [1:0] A, // 2-bit input A
input [1:0] B, // 2-bit input B
output [3:0] P // 4-bit output product
);
endmodule
module Multiplier_2bit_Structural (
input [1:0] A, // 2-bit input A
input [1:0] B, // 2-bit input B
output [3:0] P // 4-bit output product
);
Unit 3 46
AND_GATE and_gate3 (A[0], B[1], and3);
endmodule
module AND_GATE (
input X,
input Y,
output Z
);
assign Z = X & Y;
endmodule
module OR_GATE (
input X,
input Y,
output Z
);
assign Z = X | Y;
endmodule
ALU
Unit 3 47
ALU or Arithmetic Logical Unit is a digital circuit to do arithmetic operations lie
addition, subtraction, division, multiplication and logical operations like AND, OR,
XOR,
NAND, NOR etc. Arithmetic Logic Unit (ALU) is a critical component of a
microprocessor
and is the core component of central processing unit. ALU can perform all the 16
possible
logic operations or 16 different arithmetic operations on active HIGH or active LOW
operands.
To design a 4-bit Arithmetic Logic Unit (ALU) in VHDL and Verilog, we will create
an ALU that performs basic operations like addition, subtraction, AND, OR, and
XOR based on the control signals provided.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity ALU_4bit is
Port ( A : in STD_LOGIC_VECTOR (3 downto 0);
B : in STD_LOGIC_VECTOR (3 downto 0);
Ctrl : in STD_LOGIC_VECTOR (2 downto 0);
Result : out STD_LOGIC_VECTOR (3 downto 0);
Zero : out STD_LOGIC );
end ALU_4bit;
Unit 3 48
Result <= A + B;
when "001" => -- Subtraction
Result <= A - B;
when "010" => -- AND
Result <= A and B;
when "011" => -- OR
Result <= A or B;
when "100" => -- XOR
Result <= A xor B;
when others => -- Default case for unrecognized
control signals
Result <= (others => '0');
end case;
Unit 3 49
"010" : Perform AND operation between A and B .
Zero Flag: If the result is all zeroes, the Zero flag is set to '1'.
module ALU_4bit (
input [3:0] A, // 4-bit input A
input [3:0] B, // 4-bit input B
input [2:0] Ctrl, // 3-bit control signal
output reg [3:0] Result, // 4-bit result
output reg Zero // Zero flag
);
Unit 3 50
endmodule
3'b000 : Addition ( A + B ).
3'b001 : Subtraction ( A - B ).
3'b011 : OR operation ( A | B ).
Zero Flag: If the Result is 4'b0000 , the Zero flag is set to 1 ; otherwise, it's 0 .
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity ALU_4bit is
Port ( A : in STD_LOGIC_VECTOR (3 downto 0);
Unit 3 51
B : in STD_LOGIC_VECTOR (3 downto 0);
Ctrl : in STD_LOGIC_VECTOR (2 downto 0);
Result : out STD_LOGIC_VECTOR (3 downto 0);
Zero : out STD_LOGIC );
end ALU_4bit;
component AND_Gate
Port ( A : in STD_LOGIC_VECTOR(3 downto 0);
B : in STD_LOGIC_VECTOR(3 downto 0);
Result : out STD_LOGIC_VECTOR(3 downto 0) );
end component;
begin
-- Adders and logic gates instantiation
Adder1: Adder port map (A, B, sum_result, carry_out);
AND1: AND_Gate port map (A, B, and_result);
OR1: OR_Gate port map (A, B, or_result);
XOR1: XOR_Gate port map (A, B, xor_result);
Unit 3 52
case Ctrl is
when "000" => Result <= sum_result;
when "001" => Result <= sum_result; -- Subtractio
n can be implemented using two's complement
when "010" => Result <= and_result;
when "011" => Result <= or_result;
when "100" => Result <= xor_result;
when others => Result <= (others => '0');
end case;
end process;
end Structural;
module ALU_4bit (
input [3:0] A,
input [3:0] B,
input [2:0] Ctrl,
output reg [3:0] Result,
output reg Zero
);
Unit 3 53
// Instantiate components
Adder add1 (.A(A), .B(B), .Sum(sum_result), .Carry(carry_
out));
AND_Gate and1 (.A(A), .B(B), .Result(and_result));
OR_Gate or1 (.A(A), .B(B), .Result(or_result));
XOR_Gate xor1 (.A(A), .B(B), .Result(xor_result));
;
3'b100: Result = xor_result;
default: Result = 4'b0000;
endcase
end
endmodule
Unit 3 54
Component Instantiation: Each operation (Adder, AND gate, OR gate, XOR
gate) is defined as a separate component and instantiated within the ALU.
Result Selection: The appropriate result (sum, and, or, xor) is selected based
on the control signal Ctrl .
This is a basic structural design that can be extended by implementing each logic
operation in a separate module.
Unit 3 55