8-bit Arithmetic and Logic Unit

  1. Introduction


    ALU is the fundamental building block of the processor, which is responsible for carrying out the arithmetic and logic functions. ALU comprises of combinatorial logic that implements arithmetic operations such as Addition, Subtraction and Multiplication,and logic operations such as AND, OR, NOT. The ALU gets operands from the register file or memory. The block diagram of a typical ALU is shown in Figure 1. The ALU reads two input operands In A and In B. The operation to perform on these input operands is selected using the control input Opcode. The ALU performs the selected operation on the input operands In A and In B and produces the output, Out. The ALU also updates different flag signals after performing the selected function. Note that the ALU is purely combinatorial logic and contains no registers or latches.

    Figure 1. Block diagram of 8-bit ALU

    The arithmetic functions are much more complex to implement than the logic functions. The performance of the ALU depends upon the architecture of each structural components of the ALU. In this example only some basic ALU functions are implemented. The ALU is divided into an arithmetic section and a logical section.

    The Arithmetic Unit compromises of three functions. They are:
    • Addition
    • Subtraction
    • Multiplication
    The Logical Unit compromises of five functions. They are:
    • Bitwise AND
    • Bitwise OR
    • Bitwise NAND
    • Bitwise NOR
    • Bitwise XOR
    Flags: ALU updates the conditional flags, which are used by the processor to perform other operations like condition checking and branching. In this example two flags are implemented. They are:
    • Zero - If all the bits of the result data are zero then the zero flag is set
    • Carry out - If the addition of the two operands gives the carry out this flag is set

  2. Truth Table


    Figure 2 shows the truth table of the 8-bit ALU. The ALU works on 8-bit operands. It supports 8 instructions which are selected by the 3-bit Opcode.

    Figure 2. Truth table for 8-bit ALU.

  3. Verilog Module


    Figure 3 shows the Verilog module of the 8-bit ALU. The input to the ALU are 3-bit Opcode, and two 8-bit operands Operand1 and Operand2. The result of the operation is presented through the 16-bit Result port. In addition, there are two flags for carry (flagC) and zero (flagZ).

    Figure 3. Verilog module for 8-bit ALU

  4. Verilog Code for the 8-bit ALU (ALU8bit.v)



    1. `timescale 1ns / 1ps
    2. module ALU8bit( Opcode,
    3. Operand1,
    4. Operand2,
    5. Result,
    6. flagC,
    7. flagZ
    8. );
    9. input [2:0] Opcode;
    10. input [7:0] Operand1,
    11. Operand2;
    12. output reg [15:0] Result = 16'b0;
    13. output reg flagC = 1'b0,
    14. flagZ = 1'b0;
    15. parameter [2:0] ADD = 3'b000,
    16. SUB = 3'b001,
    17. MUL = 3'b010,
    18. AND = 3'b011,
    19. OR = 3'b100,
    20. NAND = 3'b101,
    21. NOR = 3'b110,
    22. XOR = 3'b111;
    23. always @ (Opcode or Operand1 or Operand2)
    24. begin
    25. case (Opcode)
    26. ADD: begin
    27. Result = Operand1 + Operand2;
    28. flagC = Result[8];
    29. flagZ = (Result == 16'b0);
    30. end
    31. SUB: begin
    32. Result = Operand1 - Operand2;
    33. flagC = Result[8];
    34. flagZ = (Result == 16'b0);
    35. end
    36. MUL: begin
    37. Result = Operand1 * Operand2;
    38. flagZ = (Result == 16'b0);
    39. end
    40. AND: begin
    41. Result = Operand1 & Operand2;
    42. flagZ = (Result == 16'b0);
    43. end
    44. OR: begin
    45. Result = Operand1 | Operand2;
    46. flagZ = (Result == 16'b0);
    47. end
    48. NAND: begin
    49. Result = ~(Operand1 & Operand2);
    50. flagZ = (Result == 16'b0);
    51. end
    52. NOR: begin
    53. Result = ~(Operand1 | Operand2);
    54. flagZ = (Result == 16'b0);
    55. end
    56. XOR: begin
    57. Result = Operand1 ^ Operand2;
    58. flagZ = (Result == 16'b0);
    59. end
    60. default: begin
    61. Result = 16'b0;
    62. flagC = 1'b0;
    63. flagZ = 1'b0;
    64. end
    65. endcase
    66. end
    67. endmodule
    Figure 4. Verilog code for 8-bit ALU

  5. Verilog Test Bench for 8-bit ALU (ALU8bit_tb.v)



    1. `timescale 1ns / 1ps
    2. module ALU8bit_tb;
    3. // Inputs
    4. reg [2:0] Opcode;
    5. reg [7:0] Operand1;
    6. reg [7:0] Operand2;
    7. // Outputs
    8. wire [15:0] Result;
    9. wire flagC;
    10. wire flagZ;
    11. //Temporary variable
    12. reg [2:0] count = 3'd0;
    13. // Instantiate the Unit Under Test (UUT)
    14. ALU8bit uut (
    15. .Opcode(Opcode),
    16. .Operand1(Operand1),
    17. .Operand2(Operand2),
    18. .Result(Result),
    19. .flagC(flagC),
    20. .flagZ(flagZ)
    21. );
    22. initial begin
    23. // Initialize Inputs
    24. Opcode = 3'b0;
    25. Operand1 = 8'd0;
    26. Operand2 = 8'd0;
    27. // Wait 100 ns for global reset to finish
    28. #100;
    29. // Add stimulus here
    30. Operand1 = 8'hAA;
    31. Operand2 = 8'h55;
    32. for (count = 0; count < 8; count = count + 1'b1)
    33. begin
    34. Opcode = count;
    35. #20;
    36. end
    37. end
    38. endmodule
    Figure 5. Verilog Test-bench for 8-bit ALU

  6. Timing Diagram


    Figure 6. Timing diagram of 8-bit ALU