Arithmetic & logical Unit – Verilog

Making a arithmetic and logical unit (ALU) using Verilog Programming

Here we are going to make a clock driven => synchronous ALU.

Content to be covered

  • ALU (Arithmetic & Logical Unit )
  • Data Bus & Instruction Bus
  • Introduction to clock concept => Synchronous design
  • Arithmetic unit
  • Logical unit
  • Combining the ALU
  • RTL View
  • Testbench for ALU
  • Stimulation

1. ALU (Arithmetic & Logical Unit)

A 4-bit ALU

An ALU is the most basic part of any computer processor. This unit, as the name suggest, helps in any arithmetic and logical operations that come across the processor. Also, a N-bit processor has a N-bit ALU.

Many times the Logical and Arithmetic part is divided into two different parts. This practice helps to keep the logic concise and easy to understand.

In this tutorial, we will build a 4-bit synchronous ALU using our very own Verilog HDL. We will also use the parametric approach so that this design could be scaled up to the requirement of the designer.

2. Data & Instruction Bus

In order to understand the working of the ALU, we need to understand how do we talk to the ALU.

First there is the data bus, through which we provide the data to be processed to the ALU. Thus in the given figure the A and B inputs are the 4-bit inputs, which work as the data supply for the ALU.

And secondly, we have Instructions that are necessary to tell the ALU which operation is to be performed with the operands. Here, we have 16 instructions(8 arithmetic and 8 logical), so a 4-bit instruction bus is used.

We also have a flag register which holds the different types of flags such as carry flag, zero flag, etc. but to keep things simple we will not introduce it in this tutorial. (There will be a separate tutorial including the flag output in the ALU so stay tuned.)

3. Introduction to clock concept => Synchronous design

Clock in FPGA (Field Programmable Gate Array) design is rather easy concept, since each flipflop is driven by a clock and FPGA is made up of many of such flipflops.

This simply implies that any change in other signals will occur either at rising edge of the clock or falling edge of the clock ( as per what is mentioned in the design ). Thus faster the clock the faster changes can occur and the more faster would be the design. Also, the design become synchronous as the changes occur at either of the edge.

4. Arithmetic unit

The arithmetic unit comprises of the Arithmetic instructions as mentioned below:

Hex inputInstructionAU_out
0AdditionA + B
1SubtractionA – B
2MultiplicationA * B
3DivisionA / B
4Left Shift register A A << 1
5Right Shift register AA >> 1
6Rotate Left register A
7Rotate Right register A
Arithmetic Operations

Verilog Code :

// the tech social
// Verilog Programming
// the arithmetic block or module
module Arithematic 
#(parameter N = 4, M = 4)
(
    input wire clk,
    input wire [N-1:0] A, B,
    input wire [M-2:0] instruction,
    output reg [N-1:0] AU_out
);
    
    always @ (posedge clk) begin
        
        case (instruction)
            3'h0: AU_out = A + B;
            3'h1: AU_out = A - B;
            3'h2: AU_out = A * B;
            3'h3: AU_out = A / B;
            3'h4: AU_out = A << 1;
            3'h5: AU_out = A >> 1;
            3'h6: AU_out = {A[N-2:0], A[N-1]};
            3'h7: AU_out = {A[0], A[N-1:1]};
            default: AU_out = A;
        endcase
    end

endmodule

5. Logical unit

The Logical unit comprises of the Logical instructions as mentioned below:

Hex inputInstructionLU_out
0ANDA & B
1ORA | B
2XORA ^ B
3NOR~(A|B)
4NAND~(A&B)
5XNOR~(A^B)
6A > B1 IF TRUE
7A == B1 IF TRUE
Logical Operations

Verilog Code :

// the tech social
// Verilog Programming
// the logical block or module
module Logical 
#(parameter N = 4, M = 4)
(
    input wire clk,
    input wire [N-1:0] A, B,
    input wire [M-2:0] instruction,
    output reg [N-1:0] LU_out
);
    always @(posedge clk) begin

        case (instruction)
            3'h0: LU_out = A & B; 
            3'h1: LU_out = A | B; 
            3'h2: LU_out = A ^ B; 
            3'h3: LU_out = ~(A | B); 
            3'h4: LU_out = ~(A & B); 
            3'h5: LU_out = ~(A ^ B); 
            3'h6: LU_out = (A>B) ? 4'h1: 4'h0;
            3'h7: LU_out = (A==B) ? 4'h1: 4'h0; 
            default: LU_out = A;
        endcase

    end
endmodule

6. Combining the ALU

You can see that none of the blocks above have ALU_out as their output. But the main ALU has the ALU_out as output. So, we used the MSB of the instruction set for choosing between the Arithmetic and Logical blocks and thus combine the AU with LU to provide the ALU.

// the tech social
// Verilog Programming
// the top level module -> ALU 
// sub modules -> AU, LU
module ALU 
#(parameter N = 4, M = 4)
(
    input clk,
    input [N-1:0] A, B,
    input [M-1:0] instruction,
    output reg [N-1:0] ALU_out
);
    wire [N-1:0] LU, AU;

    // initialize the sub blocks
    Logical Logic(.clk(clk), 
                  .A(A), .B(B), 
                  .instruction(instruction[M-2:0]), 
                  .LU_out(LU));
    Arithematic arith(.clk(clk), 
                      .A(A), .B(B), 
                      .instruction(instruction[M-2:0]), 
                      .AU_out(AU));
    
    always @*
        ALU_out <= (instruction[M-1]==1) ? LU : AU;

endmodule

Therefore, if we select the MSB to be ‘1’ we can access one of the Logical instructions and if we take it to be ‘0’ we can access Arithmetic instructions.

Here is my git repo for the ALU_unit -> https://github.com/nirbhay12345/chipDesign/Alu_unit

7. RTL View

Our logic can be seen reflected in the the RTL view itself.

RTL generated using Xilinx ISE

8. Testbench for ALU

Writing a testbench for the functional checking of ALU is also a creative thing to do.

// the tech social
// Verilog Programming
// ALU test bench 
module ALU_tb;
    reg clk;
    reg [3:0] a, b;
    reg [3:0] in;
    wire [3:0] out;

	integer i;
    // design block instatiantion
    ALU alu(.clk(clk), .A(a), .B(b), .instruction(in), .ALU_out(out));

    initial clk = 1'b0; //initialize the clk

    // clk of (T = 20ns) given
    always #10 clk = ~clk;

    // control signals that drive the design block
    initial begin
        a = 4'h7;
        b = 4'ha;
        in = 4'h0;
        // for signal generation for the instruction in ALU
        for (i=0;i<=15;i=i+1) begin
            in = in + 8'h01;
            #20;
        end
    end
endmodule

You can see the above code is just an example of how one can write a testbench to a ALU design and not aimed at the complete functional check of the ALU design.

9. Stimulation

In accordance to our test bench following stimulation of the design is achieved :

Stimulation using ISIM

Great going!!! 🤩🤩😎😎🤗

2 thoughts on “Arithmetic & logical Unit – Verilog

Leave a comment