Logo

Procedural blocks in system verilog

16 Jul 2022
4 mins

In Verilog, there are initial and always procedural blocks as we have seen. In system Verilog, these procedural blocks were improved, and a few more procedural blocks were added. Some of these added procedural blocks are synthesizable and some are non-synthesizable. In this article we will see these blocks in detail.

Combinational logic

In Verilog, always block was used to define both combinational and sequential circuits. But in always block if we forget to add the else part it may be considered as latch during synthesis. Also, the sensitivity list needs to be provided correctly for the simulation to match the actual circuit. To account for these problem System Verilog introduced a new always block construct known as always_comb.

Syntax

always_comb begin
    ...
end

Advantage over normal always construct

  1. always_comb automatically executes once at time-zero apart from normal execution whereas always executes only when there is change in the signal defined in the sensitivity list. This is helpful as in always block the value of signal is normally x until the block is triggered.
  2. always_comb automatically infers the sensitivity list whereas in always block sensitivity list needs to be given manually. Sometimes some signal may be missed out in the always block leading to different result in simulation and actual hardware.
  3. always_comb ensures that the variable on the left-hand side of the assignment is not written by another process. Whereas in always multiple process can write to the same variable.

Latch logic

System Verilog introduces always_latch to write the latch logic. In always_latch the sensitivity list is also automatically inferred from the signals used inside the block.

The only difference in always_latch is that we need to have a if statement to support the enable signal for the latch

Syntax

always_latch begin
    if(enable_cond) begin
        ...
    end
end

Sequential Logic

System Verilog introduces always_ff to write sequential logics which can be synthesized. Always_ff also ensures that the left side of the assignment is not written by any other process.

In always_ff we can have a iff keyword to control the triggering of the block.

Syntax

always_ff @(event_control) begin
end

Example

module proc_mod(input wire clk, rst, a, b, c, en,
                output reg op1, op2, op3);
    always_comb begin
        op1 = a + b;
    end

    always_latch begin
        if(en) begin
            op2 = c;
        end
    end

    always_ff @(posedge clk or negedge rst) begin
        if(!rst)
            op3 = 0;
        else begin
            op3 = a + b + c;
        end
    end
endmodule

The test bench for the above code is not given. It is recommended to implement a test bench using the concepts discussed so far. In this scenario there is no specific requirement for the design to match. Thus, the test bench can be implemented in various ways.

Try this code in EDA Playground

Final

Final is a new procedural block introduced in system Verilog. It is non synthesizable and is called at the end of the simulation. This block is basically used to carry out last moment house keeping activites. As it is non-synthesizable it is mainly used in test bench codes. One use could be to print the report of a test in the final block.

Syntax

final begin
end

Example

module final_block;
    initial begin
        $display("[%0t] Printing from intitial block", $time);
        #30;
        $finish();
    end

    final begin
        $display("[%0t] Printing from final block", $time);
    end

endmodule

Named blocks

In Verilog, we have seen that we can name procedural blocks using a :. In System Verilog this has been extended and we can write the block name at the end of the block as well. This helps to improve the readability of the code as we can easily identify the opening and closing of a block.

Example

module abc;
    initial begin:init_block
        $display("Initial block");
    end:init_block
endmodule
Simulators may give errors or warnings if the name at the end is different than the name of the block at the beginning.