Modeling ALUs

Arithmetic Logic Unit implementation.

Darshan N
Updated: 19 March 2026
10 min read

The Arithmetic Logic Unit (ALU) is the computational core of every processor, responsible for performing arithmetic and logical operations on binary operands. Modeling an ALU in Verilog requires understanding how to use a selection signal to multiplex between different operations within a single combinational always block. This is one of the most exam-relevant Verilog design exercises.

4-bit ALU: Inputs, Operation Select, and OutputOperandsA[3:0]B[3:0]4-bitoperandsOp Selectsel[2:0]8 operationsALU Coresel=000: ADD (A+B)sel=001: SUB (A-B)sel=010: AND (A and B)sel=011: OR (A or B)sel=100: XOR (A xor B)sel=101: NOT Asel=110: Left Shift Asel=111: Right Shift AOutputsresult[4:0]zero flagcarry flagoutBehavioral model: case(sel) inside always@(*) block
Figure 1: 4-bit ALU structure showing 8 selectable operations controlled by 3-bit select input

Core Concept: ALU Architecture and Operation Selection

An ALU accepts two operands and a function select input. The select input chooses which of several operations is performed and whose result is passed to the output. In a 3-bit select ALU, up to 8 distinct operations can be supported. The design philosophy in Verilog is to evaluate all operations implicitly through the case statement and route the correct result to the output based on sel.

The output width must be planned carefully. For addition and subtraction of two 4-bit numbers, the result can be 5 bits due to carry or borrow. The carry flag is extracted as the most significant bit of the extended result. The zero flag is asserted when the result equals zero, which is critical in processor branch instructions like BEQ (branch if equal) in MIPS and RISC-V architectures.

The behavioral modeling approach uses a single always@(*) block with a case statement on the sel input. Each case branch assigns the result. Because this is purely combinational logic, the sensitivity list must include all inputs (using the wildcard * is the safe practice). The case statement should include a default branch to avoid latch inference for undefined select values.

Mathematical Expression

For a 4-bit ALU with operands A and B and 3-bit select sel, the output function is defined as a piecewise expression: result = f(A, B) where f is determined by sel. For arithmetic operations, the result is represented in (n+1) bits to accommodate carry. The carry out Cout = result[n] where n is the operand width. The zero flag Z = NOR of all result bits = ~|result[n-1:0]. The overflow flag for signed addition is V = A[n-1] XOR B[n-1] XOR result[n-1] XOR Cout.

Practical Understanding

In processor datapaths, the ALU is controlled by the control unit which decodes the instruction opcode and drives the ALU select lines accordingly. For a simple RISC processor, an ADD instruction maps to sel=000, a SUB maps to sel=001, and logical operations map to their respective codes. The ALU output feeds the register file write-back path and the branch condition logic simultaneously.

Shift operations in the ALU are particularly important. Left shift by 1 bit is equivalent to multiplication by 2 and is implemented in hardware without an actual multiplier. Similarly, right shift implements integer division by powers of 2. These operations execute in a single clock cycle in most RISC processors, making them far more efficient than full multiplication.

Example
Given:
A = 4b1010 (decimal 10), B = 4b0011 (decimal 3), sel = 3b000 (ADD)

Why this formula applies:
sel = 000 selects the ADD operation in the ALU case statement.
Result must be 5 bits to capture carry.

Formula:
result[4:0] = {1b0, A} + {1b0, B}
carry = result[4]
zero = ~|result[3:0]

Substitution:
{1b0, 4b1010} + {1b0, 4b0011}
= 5b01010 + 5b00011

Calculation:
  01010
+ 00011
-------
  01101

Final Answer:
result[4:0] = 5b01101 (decimal 13)
carry flag = 0 (no overflow beyond 4 bits)
zero flag = 0 (result is non-zero)
Exam Tip: In GATE questions on Verilog ALU modeling, watch for the result bit-width. Declaring result as a 4-bit reg when adding two 4-bit numbers silently truncates the carry bit. Always declare result as (n+1) bits or use a separate carry output. Also, missing the default in a case statement causes latch inference in synthesis, which is a common synthesis-related MCQ.
ALU Datapath: Case Statement Execution FlowA=1010, B=0011sel = 3b000case(sel)000: ADD selected001: SUB010: AND011: OR100: XOR101: NOT Adefault: 0active pathADD OperationA + B = 011015-bit resultout=01101Z=0C=0Key Synthesis NoteMissing default → latch inferred. Always include default branch.Zero Flag Logiczero = ~|result[3:0] (reduction NOR)
Figure 2: ALU behavioral model execution flow showing case branch selection, result computation, and flag generation
  • The ALU uses always@(*) with a case(sel) block; each branch computes one operation and assigns to the result register.
  • Result must be declared (n+1) bits for n-bit operands to correctly capture the carry out from addition and subtraction.
  • The zero flag is computed as the bitwise NOR reduction of the result: zero = ~|result.
  • The carry flag is simply the MSB of the extended result: carry = result[n].
  • A default branch in the case statement is mandatory to prevent latch inference during synthesis.
  • Shift operations (left and right) implement multiply/divide by powers of 2 without a hardware multiplier.

Quick Revision

  • ALU selects one of multiple operations using a case(sel) in always@(*); this is purely combinational.
  • Result bit-width: for n-bit operands, declare result as (n+1) bits to capture carry.
  • Zero flag: zero = ~|result[n-1:0] (reduction NOR).
  • Carry flag: carry = result[n].
  • Default branch in case is mandatory to avoid latch inference.
  • Left shift by k = multiply by 2^k; right shift by k = divide by 2^k.
  • Exam trap: 4-bit result reg for 4-bit ADD silently discards carry; always size result correctly.

ALU Modeling Quiz

Test functional knowledge of Arithmetic Logic Unit design.

Question 1 of 3

Q1.What parameter primarily controls the specific operation executed by an ALU during a given clock cycle?