Verilog Coding Tips and Tricks: Verilog code for a simple ALU

Friday, October 23, 2015

Verilog 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 Verilog 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 has to be performed by the ALU. Since 'Op' is 3 bits long we can have a maximum of 2^3=8 operations.




Our ALU is capable of doing the following operations:


ALU OperationDescription
Add SignedR = A + B : Treating A, B, and R as signed two's complement integers.
Subtract SignedR = A - B : Treating A, B, and R as signed  two's complement integers.
Bitwise ANDR(i) = A(i) AND B(i).
Bitwise NORR(i) = A(i) NOR B(i).
Bitwise ORR(i) = A(i) OR B(i).
Bitwise NANDR(i) = A(i) NAND B(i).
Bitwise XORR(i) = A(i) XOR B(i).
Biwise NOTR(i) = NOT A(i).

These functions are implemented using a case statement. The ALU calculates the outputs, whenever there is a change in the input operands A or B or in the operation to be performed Op . As soon as the outputs are calculated it is available at the port signal 'R'. 

8 bit ALU:

//Verilog module for an ALU
module ALU(
    A,
    B,
    Op,
    R   );
    
    //inputs,outputs and internal variables declared here
    input [7:0] A,B;
    input [2:0] Op;
    output [7:0] R;
    wire [7:0] Reg1,Reg2;
    reg [7:0] Reg3;
    
    //Assign A and B to internal variables for doing operations
    assign Reg1 = A;
    assign Reg2 = B;
    //Assign the output 
    assign R = Reg3;

    //Always block with inputs in the sensitivity list.
    always @(Op or Reg1 or Reg2)
    begin
        case (Op)
            0 : Reg3 = Reg1 + Reg2;  //addition
         1 : Reg3 = Reg1 - Reg2; //subtraction
         2 : Reg3 = ~Reg1;  //NOT gate
         3 : Reg3 = ~(Reg1 & Reg2); //NAND gate 
         4 : Reg3 = ~(Reg1 | Reg2); //NOR gate               
         5 : Reg3 = Reg1 & Reg2;  //AND gate
         6 : Reg3 = Reg1 | Reg2;  //OR gate    
         7 : Reg3 = Reg1 ^ Reg2; //XOR gate  
        endcase 
    end
    
endmodule

Testbench for ALU:

module tb_alu;

    // Inputs
    reg [7:0] A;
    reg [7:0] B;
    reg [2:0] Op;

    // Outputs
    wire [7:0] R;

    // Instantiate the Unit Under Test (UUT)
    ALU uut ( 
        .A(A), 
        .B(B), 
        .Op(Op), 
        .R(R)
    );
    
    initial begin
        // Apply inputs.
        A = 8'b01101010;
        B = 8'b00111011;
        Op = 0; #100;
        Op = 1; #100;
        Op = 2; #100;
        Op = 3; #100;
        Op = 4; #100;
        Op = 5; #100;
        Op = 6; #100;
        Op = 7; #100;
    end
      
endmodule

Simulation waveform:

The codes are simulated in Xilinx ISE 13.1 to get the following waveform:



Few years back, I have implemented the same ALU design using VHDL. You can check out that code here.

1 comment:

  1. Hello Sir
    Here you declare input as reg and used them in case statement.
    But without reg can we also use simple as input ?

    and what is purpose of define input as reg ?

    ReplyDelete