0

我正在尝试编写一个断言,该断言仅在信号在“clk”的上升沿转换时才会触发。我写了下面的代码来测试我的想法

module test();

bit clk, clkb;
int d;

assign clkb = ~clk;

initial begin
   clk = 0;
   forever #100 clk = ~clk;
end

initial begin
   d = 10;
   #150 d = 20;
end

sva_d_chgd: assert property (@(posedge clk) $stable(d,@(clkb))) 
   else $error($psprintf("err: time = %0d, clk = %b, d = %0d", $time, clk, d));

always @ (d or clk) begin
   $display("time = %0d, clk = %b, d = %0d", $time, clk, d);
   if ($time > 200) $finish;
end
endmodule

上面的代码在 VCS 中返回以下输出:

time = 0, clk = 0, d = 10
time = 100, clk = 1, d = 10
"test.vs", 18: test.sva_d_chgd: started at 100s failed at 100s
        Offending '$stable(d, @(clkb))'
Error: "test.vs", 18: test.sva_d_chgd: at time 100
err: time = 100, clk = 1, d = 10
time = 150, clk = 1, d = 20
time = 200, clk = 0, d = 20
time = 300, clk = 1, d = 20
$finish called from file "test.vs", line 23.
$finish at simulation time                  300

为什么断言在时间 100 时触发,而“d”在时间 150 之前保持稳定?

4

1 回答 1

0

在您的代码中,stable 检查 clk 的每个 posedge 以查看“d”的值是否在 clkb 的前两个边缘之间发生了变化。由于在 clk 的第一个 posedge 没有先前的 clkb 边缘值“d”,stable 返回“unknown”而不是“true”或“false”,这会导致您的断言失败。

我已在您的代码中添加了一个复位信号并禁用了断言,直到 clk 的第一个 posedge 之后。当“d”改变时,我也搬家了。

module test();

bit clk, clkb, rst;
int d;

assign clkb = ~clk;

initial begin
   clk = 0;
   forever #100 clk = ~clk;
end

initial begin
   rst = 1;
   #150 rst = 0;
end

initial begin
   d = 10;
   #250 d = 20;
end

sva_d_chgd: assert property (@(posedge clk)
                            disable iff (rst)
                            $stable(d,@(clkb))) 
   else $error($psprintf("err: time = %0d, clk = %b, d = %0d", $time, clk, d));

always @ (d or clk) begin
   $display("time = %0d, clk = %b, d = %0d", $time, clk, d);
   if ($time > 400) $finish;
end
endmodule

这是输出:

# time = 0, clk = 0, d = 10
# time = 100, clk = 1, d = 10
# time = 200, clk = 0, d = 10
# time = 250, clk = 0, d = 20
# time = 300, clk = 1, d = 20
# ** Error: err: time = 300, clk = 1, d = 20
#    Time: 300 ns Started: 300 ns  Scope: test.sva_d_chgd File: assert_test.sv Line: 26
# time = 400, clk = 0, d = 20
# time = 500, clk = 1, d = 20
# ** Note: $finish    : assert_test.sv(30)
#    Time: 500 ns  Iteration: 1  Instance: /test

这解决了您的断言的第一次不必要的失败,但我认为您编写断言的方式仍然没有真正捕获您正在寻找的条件。

于 2014-05-05T00:58:16.090 回答