SystemVerilog New logic specific processes: always_comb, always_latch, and always_ff

4.8/5 - (13 votes)

[wpbread]

In SystemVerilogalways_combalways_latch, and always_ff are procedural blocks that are used for different types of hardware modeling. They provide different timing and sensitivity control to describe the behavior of combinational logic, latches, and flip-flops respectively. All forms of always procedures repeat continuously throughout the duration of the simulation. In this post we will discuss about these always procedures.

Table of Contents

always_comb

always_comb procedure is used for modelling combinational logic.

always_comb

The always_comb procedure provides functionality that is different from the general purpose always procedure, as follows:

1). There is an inferred sensitivity list that includes the expressions defined.

Example code: Here changing value of ‘a’ automatically triggers always_comb block.

module top;
int a, b, c, d;
always_comb begin
b = a;
c = b;
$display("%0t] a=%0d, b=%0d, c=%0d", $time, a, b, c);
end

initial begin
#1 a=1;
#1 a=2;
end
endmodule

Run_on_EdaPlayground

Simulator output:

0] a=0, b=0, c=0
1] a=1, b=1, c=1
2] a=2, b=2, c=2

2). always_comb automatically triggered once at time zero, whereas always @* waits until a change occurs on a signal in the inferred sensitivity list.

Example code:  always_comb automatically triggered once at time zero.

module top;
int a, b, c, d;
always_comb begin
b = a;
$display("%0t] BLK1 a=%0d, b=%0d, c=%0d", $time, a, b);
end

always @* begin
c = d;
$display("%0t] BLK2 c=%0d, d=%0d", $time, c, d);
end

initial begin
#1 a=1; d=1;
#1 a=2; d=2;
end
endmodule

Run_on_EdaPlayground

Simulator output:

0] BLK1 a=0, b=0
1] BLK1 a=1, b=1
1] BLK2 c=1, d=1
2] BLK1 a=2, b=2
2] BLK2 c=2, d=2

There is always_comb print is at time zero but not for always @.

3). The variables written on the left-hand side of assignments shall not be written to by any other process.

Example code: Here “#1 b=1; inside initial block will cause compile time error.

module top;
int a, b, c, d;

always_comb begin
b = a;
c = b;
$display("%0t] a=%0d, b=%0d, c=%0d", $time, a, b, c);
end

initial begin
#1 b=1; //compilation error
#1 a=1;
#1 a=2;
end
endmodule

Run_on_EdaPlayground

Simulator output:

Error-[ICPD] Illegal combination of drivers
testbench.sv, 2
Illegal combination of procedural drivers
Variable “b” is driven by an invalid combination of procedural drivers.
Variables written on left-hand of “always_comb” cannot be written to by any
other processes, including other “always_comb” processes.
This variable is declared at “testbench.sv”, 2: int b;
The first driver is at “testbench.sv”, 11: b = 1;
The second driver is at “testbench.sv”, 4: always_comb begin
b = a;


1 error

4). always_comb is sensitive to changes within the contents of a function, whereas always @* is only sensitive to changes to the arguments of a function.

Example code: 

  • always @* is sensitive to changes in the arguments of the function.
  • always_comb is sensitive to changes within the contents of the function, including any internal variables that may change as a result of the function’s logic.
module top;
int x, y;

function automatic sum(input int X);
int s;
s=X+y;
//$display("[%0t] function - sum=%0d", $time, s);
endfunction

always @* begin
sum(x);
$display("[%0t] alwaya @", $time);
end

always_comb begin
sum(x);
$display("[%0t] alwaya_comb", $time);
end

initial begin
#1 $display("[%0t] x=1", $time);
x = 1;
#1 $display("[%0t] y=1", $time);
y = 1;
end
endmodule

Run_on_EdaPlayground

Simulator Output:

[0] alwaya_comb
[1] x=1
[1] alwaya @
[1] alwaya_comb
[2] y=1
[2] alwaya_comb

When value of ‘x‘ is changed, both always@ and always_comb executed.

For value change of ‘y‘ , only always_comb is triggered.

 

5). Task calls are allowed in an always_comb, but the contents of the tasks do not add anything to the sensitivity list.

Example code: 

  • always @* & always_comb are sensitive to changes in the arguments of the task, but not with any internal variables within task.
module top;
int x, y;

task automatic sum(input int X);
int s;
s=X+y;
//$display("[%0t] task - sum=%0d", $time, s);
endtask

always @* begin
sum(x);
$display("[%0t] alwaya @", $time);
end

always_comb begin
sum(x);
$display("[%0t] alwaya_comb", $time);
end

initial begin
#1 $display("[%0t] x=1", $time);
x = 1;
#1 $display("[%0t] y=1", $time);
y = 1;
end
endmodule

Run_on_EdaPlayground

Simulator Output:

[0] alwaya_comb
[1] x=1
[1] alwaya @
[1] alwaya_comb
[2] y=1

When value of ‘x‘ is changed, both always@ and always_comb executed.

For value change of ‘y‘ , neither always@ or always_comb is triggered.

6). always_comb is sensitive to expressions in immediate assertions within the procedure and within the contents of a function called in the procedure, whereas always @* is sensitive to expressions in immediate assertions within the procedure only.

Example code:

7). Statements in an always_comb shall not include those that block, have blocking timing or event controls, or fork-join statements.

Example code:

always_ff

The always_ff block is used to model flip-flops, which are edge-triggered storage elements. It represents behavior where the output value is updated only on a clock edge (positive, negative, or both) based on the input values at that particular clock edge. The block is sensitive to the specified clock signal and executes on the positive (posedge) or negative (negedge) edge of the clock.

always_ff @(posedge clk)
begin
    // Flip-flop logic statements
    // Assignments, conditional statements, etc.
end

 

always_latch

The always_latch block is used to model latches, which are level-sensitive storage elements. It represents behavior where the output value is determined by the input value only during a specific level of the clock. The block is triggered by changes in the variables used within the block and executes when any of these variables change.

always_latch
begin
   // Latch logic statements
   // Assignments, conditional statements, etc.
end

2 thoughts on “SystemVerilog New logic specific processes: always_comb, always_latch, and always_ff”

Leave a Comment

Your email address will not be published. Required fields are marked *