SystemVerilog Immediate Assertions
Immediate Assertions基于模拟事件语义执行,并且需要在过程块中指定。在模拟过程中,它的处理方式与语句中的表达式相同。if
如果表达式在执行语句时为true,则Immediate Assertions将通过,如果表达式的计算结果为false(X、Z或0),则Immediate Assertions将失败。这些Assertions旨在用于仿真,不适合进行形式验证。它可以在RTL代码和测试平台中使用,以标记仿真中的错误。
Syntax
// Simple assert statement
assert(<expression>);
// Assert statement with statements to be executed for pass/fail conditions
assert(<expression>) begin
// If condition is true, execute these statements
end else begin
// If condition is false, execute these statements
end
// Optionally give name for the assertion
[assert_name] : assert(<expression>);
Immediate Assertion in Design
下面是一个示例,其中设计具有Immediate Assertion,用于检查在FIFO已满时是否未向FIFO发出推送请求。如果语句中的表达式的计算结果为true,则将执行第一个块,如果表达式的计算结果为false,则计算该部分。这与构造非常相似,不同之处在于用户不需要放置display语句来标记错误。assert
begin end
else if
module my_des (my_if _if);
always @(posedge _if.clk) begin
if (_if.push) begin
// Immediate assertion and ensures that fifo is not full when push is 1
a_push: assert (!_if.full) begin
$display ("push when fifo not full !");
end else begin
$display ("[FAIL] push when fifo full !");
end
end
if (_if.pop) begin
// Immediate assertion and ensures that fifo is not empty when pop is 1
a_pop: assert (!_if.empty) begin
$display ("[PASS] pop when fifo not empty !");
end else begin
$display ("[FAIL] pop when fifo empty !");
end
end
end
endmodule
如果没有这种Immediate Assertions,就需要使用concurrent assertions来复制导致该特定点的逻辑,这可能需要额外的努力和资源。
interface my_if(input bit clk);
logic pop;
logic push;
logic empty;
logic full;
endinterface
module tb;
bit clk;
always #10 clk <= ~clk;
my_if _if(clk);
my_des u0 (.*);
initial begin
for (int i = 0; i < 5; i++) begin
_if.push <= $random;
_if.pop <= $random;
_if.empty <= $random;
_if.full <= $random;
$strobe ("[%0t] push=%0b full=%0b pop=%0b empty=%0b",
$time, _if.push, _if.full, _if.pop, _if.empty)
@(posedge clk);
end
#10 $finish;
end
endmodule
看到assertion失败的时间和行显示为*E
。
模拟日志
ncsim> run
[0] push=0 full=1 pop=1 empty=1
ncsim: *E,ASRTST (./design.sv,13): (time 10 NS) Assertion tb.u0.a_pop has failed
[FAIL] pop when fifo empty !
[10] push=1 full=0 pop=1 empty=1
[PASS] push when fifo not full !
ncsim: *E,ASRTST (./design.sv,13): (time 30 NS) Assertion tb.u0.a_pop has failed
[FAIL] pop when fifo empty !
[30] push=1 full=1 pop=1 empty=0
ncsim: *E,ASRTST (./design.sv,5): (time 50 NS) Assertion tb.u0.a_push has failed
[FAIL] push when fifo full !
[PASS] pop when fifo not empty !
[50] push=1 full=0 pop=0 empty=1
[PASS] push when fifo not full !
[70] push=1 full=1 pop=0 empty=1
ncsim: *E,ASRTST (./design.sv,5): (time 90 NS) Assertion tb.u0.a_push has failed
Simulation complete via $finish(1) at time 100 NS + 0
./testbench.sv:25 #10 $finish;
ncsim> exit
Immediate Assertion in Testbench
假设创建了一个名为Packet
的类并随机化。但是,此示例存在约束错误,随机化将失败。但是,失败将显示为警告消息,如果用户不够小心,测试可能会显示不正确的行为,甚至可能看起来通过。
class Packet;
rand bit [7:0] addr;
constraint c_addr {addr > 5; addr < 3;};
endclass
module tb;
initial begin
Packet m_pkt = new();
m_pkt.randomize();
end
endmodule
模拟日志
ncsim> run
m_pkt.randomize();
ncsim: *W,SVRNDF (); The randomize method call failed. The unique id of the failed randomize call is 0.
Observed simulation time : O FS + 0
ncsim: *W,RNDOCS: These constraints contribute to the set of conflicting constraints:
rand variables:
addr [./testbench.sv, 2]
ncsim: *W,RNQUIE: Simulation is complete.
相反,可以在随机化方法调用上放置一个Immediate Assertion,以确保返回值始终为1,表示随机化成功。如果Assertion失败,它会提供用户首先查看失败,从而减少调试工作。
class Packet;
rand bit [7:0] addr;
constraint c_addr {addr > 5; addr < 3;}
endclass
module tb;
initial begin
Packet m_pkt = new();
assert(m_pkt.randomize());
end
endmodule
Simulator assigns a generated name for the assertion if the user has not specified one. |
模拟日志
ncsim> run
assert(m_pkt.randomize());
ncsim: *W,SVRNDF (./testbench.sv,11|25); The randomize method call failed. The unique id of the failed randomize call is 0.
Observed simulation time : O FS + 0
ncsim: *W,RNDOCS: These constraints contribute to the set of conflicting constraints:
constraint c_addr {addr > 5; addr < 3} (./testbench.sv,4)
ncsim: *W,RNDOCS:These varibles contribute to the set of conflicting constraints:
rand variables:
addr [./testbench.sv, 2]
ncsim: **E,ASRTST (./testbench.sv,11): (time 0 FS) Assertion tb.unmblk1._assert_1 has failed
ncsim: *W,RNQUIE: Simulation is complete.
ncsim> exit
以类似的方式,可以与过程快中计算结果为true或false的任何表达式一起使用。assert