Procedural Blocks
delays
- delays are only allowed in procedural blocks (
initialandalways)
Inter assignment delays
- execution of entire statement is delayed by specified time (
#5 a = b;delays assignment ofbtoaby 5 time units)
Intra assignment delays
- delays within an assignment statement (
a = #5 b;assigns value ofbtoaafter 5 time units, but right-hand side is evaluated immediately)
example of delays
module clock (
output logic clk
);
initial begin
clk = 0;
forever #5 clk = ~clk; // toggle clk every 5 time units
// OR:
// #5 ns;
// clk = ~clk;
end
endmodule
example questions of delays
suppose clk has a rising edge at time 10, what are the values of a and b at time 20?
module delay_question1(input logic clk);
logic[31:0] a = 0;
logic[31:0] b = 0;
always @(posedge clk) begin
#5 a = a + 2;
end
always @(posedge clk) begin
#5 b = a + 3;
end
endmodule
unpredictable RESULT, because the new value of b maybe evaluated before or after a is updated.
suppose clk has a rising edge at time 10, what are the values of a and b at time 36 ?
module delay_question1(input logic clk);
logic[31:0] a = 0;
logic[31:0] b = 0;
always @(posedge clk) begin
#5 a <= a + 2;
end
always @(posedge clk) begin
#5 b <= a + 3;
end
endmodule
10ns: a = 0, b = 0 (initial values)
15ns: a = 2, b = 3 (both assignments executed, b uses old value of a (non-blocking))
20ns: a = 2, b = 3
30ns: a = 2, b = 3 (this is the negative edge of clk, no change)
35ns: a = 4, b = 5 (both assignments executed, b uses old value of a (non-blocking))
Sensitivity List
always_comb
- require purely combinational logic (
=)- if there is any storage element (flip-flop, latch), it will cause an sv RTL coding error
- for example, incomplete case
- automatically infers sensitivity list, including functions
- forbids ambigious netlist
- for example, multiple drivers to the same net
- executes at time 0, so the output has valid value at time 0
always_ff
- require purely sequential logic (
<=)- if there is any combinational logic, it will cause an sv RTL coding error
- for example, missing else branch in if statement
- gives warning if there is latch inferred
always_latch
- when intended to infer latch
always@(*)
- similar to
always_comb, but may NOT infer complete sensitivity list when contains functions - and it does not automatically execute at time 0, but waits for an event in the sensitivity list
- warning when latches are inferred (incomplete assignments in some branches
if/case)
always block sensitivity list
- single edge:
always @(posedge clk)oralways @(negedge rst_n) - multiple signals:
always @(a or b or c)oralways @(a, b, c) -
all signals:
always @(*)oralways_comb(preferred for combinational logic)always_combautomatically executes at time 0, and infer complete sensitivity list including functionsalways@(*)may not infer a complete sensitivity list when contains functions.
-
CANNOT mix edge and level sensitivity in the same always block
always_ff @(posedge clk or posedge rst_n)for sequential logic with asynchronous reset- it stores values on clock edges
example of sensitivity list
module sensitivity_list (
input logic clk,
input logic rst_n,
input logic a,
input logic b,
output logic y
);
// correct: single edge sensitivity
always@(posedge clk) begin
// sequential logic
end
// correct: multiple level sensitivity
always@(a or b) begin
// combinational logic
end
// correct: all signals sensitivity
always@(*) begin
// combinational logic
end
// incorrect: mixing edge and level sensitivity
always @(posedge clk or a) begin
// ERROR: cannot mix edge and level sensitivity
end
endmodule
what this the synthesized hardware for q1 and q2?
module bad_FF_coding(
input logic clk, d, reset_n,
output logic q2);
logic q1;
always_ff@(posedge clk) begin
if(!reset_n) // Reset only explicitly applied here
q1<=1'b0;
else begin
q1<=d;
q2<=q1; // q2 is inferred here without explicit reset logic
end
end
endmodule: bad_FF_coding
q1 is a flip-flop with asynchronous reset. q2 is a clock enable, not a simple flip-flop, because it does not have reset logic.

to fix this issue, we need to add reset logic for q2:
module good_FF_coding(
input logic clk, d, reset_n,
output logic q2);
logic q1;
always_ff@(posedge clk) begin
if(!reset_n) begin // Reset applied to both q1 and q2
q1<=1'b0;
q2<=1'b0;
end
else begin
q1<=d;
q2<=q1;
end
end
endmodule: good_FF_coding
or use two separate always_ff blocks:
module example3(
input logic clk,
input logic a,b,c,
output logic f
);
logic t; // the intermediate signal
always_ff @(posedge clk) begin
t <= a & b; // t is registered
f <= t & c;
end
endmodule: example3
for <= assignment, we use D-FF
the clk signal for both D-FF is the clk
a & b is combinational logic before the first D-FF, enters into the D input of the t D-ff
t & c is combinational logic before the second D-FF, enters into the D input of the f D-ff

non-synthesizable constructs
- used for simulation only, not synthesizable
initial block
- executes once at time 0, then terminates. not synthesizable in RTL
- multiple
initialblocks allowed in a module, executed in parallel