In digital design, controlling the flow of logic is essential. Verilog, a hardware description language, provides several control blocks to manage how hardware components behave under different conditions. These blocks include conditional statements like if-else and loops such as forever, repeat, while, and for. Let’s explore these control blocks in Verilog.


1. If-Else-If Statements in Verilog

In Verilog, the if-else-if statement is used to execute specific statements based on conditions, similar to C programming. When a condition is true, the corresponding statement executes. If not, Verilog checks the next condition in the else if part, or runs the else statement if no conditions are met.

Syntax

// Simple if statement
if (condition) 
    [statement]

// If-else statement
if (condition) 
    [statement] 
else 
    [statement]

// If-else for multiple statements
if (condition) begin
    [multiple statements]
end else begin
    [multiple statements]
end

// If-else-if for multiple conditions
if (condition1) 
    [statement]
else if (condition2) 
    [statement]
else 
    [statement]

Example:

Here’s a basic if-else-if example to help you understand better:

if (a > b) 
    $display("a is greater than b");
else if (a < b) 
    $display("a is less than b");
else 
    $display("a is equal to b");

2. Loops in Verilog

Loops are used to repeat statements multiple times. There are four main types of loops in Verilog: forever, repeat, while, and for. Each serves different purposes, and we’ll go through them in detail.

2.1 Forever Loop

The forever loop repeats the enclosed statements indefinitely until the simulation stops.

Syntax:

forever 
    [statement]

// Or with multiple statements
forever begin
    [multiple statements]
end

Example:

module my_design;
    initial begin
        forever begin
            $display("This will print forever!");
        end
    end
endmodule

Simulation Output:

This will print forever!
This will print forever!
...

Note: This loop can cause the simulation to run indefinitely.

2.2 Repeat Loop

The repeat loop executes a set number of times. If the expression evaluates to an X or Z, it will be treated as zero and not executed.

Syntax:

repeat (num_of_times) begin
    [statements]
end

Example:

module my_design;
    initial begin
        repeat(4) begin
            $display("This is iteration number ...");
        end
    end
endmodule

Simulation Output:

This is iteration number ...
This is iteration number ...
This is iteration number ...
This is iteration number ...

2.3 While Loop

The while loop executes as long as the given condition is true. It will exit once the condition is false. If the condition is false initially, the loop will not run.

Syntax:

while (condition) begin
    [statements]
end

Example:

module my_design;
    integer i = 5;

    initial begin
        while (i > 0) begin
            $display("Iteration #%0d", i);
            i = i - 1;
        end
    end
endmodule

Simulation Output:

Iteration #5
Iteration #4
Iteration #3
Iteration #2
Iteration #1

2.4 For Loop

The for loop is used to iterate a set number of times. It is one of the most popular loops in programming and Verilog, especially when the number of iterations is known in advance.

Syntax:

for (initial_condition; condition; increment_variable) begin
    [statements]
end

Example:

module my_design;
    integer i;

    initial begin
        for (i = 0; i < 5; i = i + 1) begin
            $display("Current loop #%0d", i);
        end
    end
endmodule

Simulation Output:

Current loop #0
Current loop #1
Current loop #2
Current loop #3
Current loop #4

3. Using For Loops for Hardware Design

In hardware design, loops help in replicating repetitive tasks, making the code more scalable and easier to modify. For instance, let’s look at how we can implement an 8-bit left shift register in Verilog using a for loop.

Without For Loop

Here’s how we could write an 8-bit left shift register without using a for loop. Each shift operation is written explicitly:

module lshift_reg (
    input clk,        // Clock input
    input rstn,       // Active-low reset input
    input [7:0] load_val,  // Load value
    input load_en,    // Load enable
    output reg [7:0] op  // Output register value
);

    always @ (posedge clk) begin
        if (!rstn) begin
            op <= 0;
        end else begin
            if (load_en) begin
                op <= load_val;
            end else begin
                op[0] <= op[7];
                op[1] <= op[0];
                op[2] <= op[1];
                op[3] <= op[2];
                op[4] <= op[3];
                op[5] <= op[4];
                op[6] <= op[5];
                op[7] <= op[6];
            end
        end
    end
endmodule

With For Loop

Now, using the for loop, we can rewrite the same shift register code more efficiently. This reduces redundancy and makes it scalable.

module lshift_reg (
    input clk,        // Clock input
    input rstn,       // Active-low reset input
    input [7:0] load_val,  // Load value
    input load_en,    // Load enable
    output reg [7:0] op  // Output register value
);

    integer i;

    always @ (posedge clk) begin
        if (!rstn) begin
            op <= 0;
        end else begin
            if (load_en) begin
                op <= load_val;
            end else begin
                for (i = 0; i < 7; i = i + 1) begin
                    op[i] <= op[i+1];
                end
                op[7] <= op[0];
            end
        end
    end
endmodule

Key Benefits of Using For Loop:

  • Reduces Redundancy: A single for loop can replace multiple assignments.
  • Scalable: The code is easily adjustable for registers of different sizes by changing the loop conditions.
  • Clear and Concise: It makes the design easier to read and maintain.

4. Testbench for Verilog Design

A testbench is used to simulate and verify the functionality of your Verilog code. Below is an example of a simple testbench to test the shift register design.

module tb;
    reg clk;
    reg rstn;
    reg [7:0] load_val;
    reg load_en;
    wire [7:0] op;

    // Clock generation
    always #10 clk = ~clk;

    // Instantiate the design
    lshift_reg u0 (
        .clk(clk),
        .rstn(rstn),
        .load_val(load_val),
        .load_en(load_en),
        .op(op)
    );

    initial begin
        // 1. Initialize variables
        clk <= 0;
        rstn <= 0;
        load_val <= 8'h01;
        load_en <= 0;

        // 2. Apply reset
        repeat (2) @ (posedge clk);
        rstn <= 1;
        repeat (5) @ (posedge clk);

        // 3. Set load_en to 1 to load value
        load_en <= 1;
        repeat(1) @ (posedge clk);
        load_en <= 0;

        // 4. Let design run for 20 clocks
        repeat (20) @ (posedge clk);
        $finish;
    end
endmodule

Comparison Table: Verilog Control Blocks

Control BlockDescriptionExample
If-Else-IfConditional statements to execute code based on conditionsif (a > b) $display("a is greater than b");
ForeverExecutes statements infinitely until stoppedforever begin $display("Infinite loop!"); end
RepeatExecutes statements a fixed number of timesrepeat (5) begin $display("Iteration"); end
WhileExecutes statements as long as a condition is truewhile (i > 0) begin i = i - 1; end
ForLoops with initial condition, condition check, and incrementfor (i = 0; i < 5; i = i + 1) $display(i);

This approach will help you understand the various control blocks in Verilog and how to use them efficiently in your hardware designs.

Conclusion

Verilog provides various control blocks like if-else-if and loops to manage hardware behavior efficiently. Using loops such as for, while, and repeat can significantly simplify the code and make it more scalable. The examples above demonstrate how control blocks work and how you can leverage them in your Verilog designs.


Scroll to Top