我对Verilog完全不熟悉,所以请耐心等待.
我想知道Verilog中是否有断言声明.在我的测试平台中,我希望能够断言模块的输出等于某些值.
例如,
mymodule m(in, out);
assert(out == 1'b1);
Run Code Online (Sandbox Code Playgroud)
谷歌搜索给了我一些链接,但它们要么太复杂,要么似乎不是我想要的.
Jef*_*ffB 14
有一个名为OVL的断言的开源库.但是,它非常沉重.我从那里得到的一个技巧是创建一个模块来做断言.
module assert(input clk, input test);
always @(posedge clk)
begin
if (test !== 1)
begin
$display("ASSERTION FAILED in %m");
$finish;
end
end
endmodule
Run Code Online (Sandbox Code Playgroud)
现在,只要你想检查一个信号,你所要做的就是在你的模块中实例化一个断言,如下所示:
module my_cool_module(input clk, ...);
...
assert a0(.clk(clk), .test(some_signal && some_other_signal));
...
endmodule
Run Code Online (Sandbox Code Playgroud)
当断言失败时,您将收到如下消息:
ASSERTION FAILED in my_cool_module.a0
Run Code Online (Sandbox Code Playgroud)
display语句中的%m将显示违规断言的整个层次结构,当您在较大的项目中拥有大量这些时,这很方便.
你可能想知道我为什么要检查时钟的边缘.这很微妙,但很重要.如果上面表达式中的some_signal和some_other_signal在不同的always块中分配,则表达式可能在短时间内为false,具体取决于Verilog模拟器调度块的顺序(即使逻辑完全有效).这会给你一个假阴性.
上面要注意的另一件事是我使用!==,如果测试值是X或Z,这将导致断言失败.如果它使用了正常!=,它可能在某些情况下默默地给出误报.
小智 8
将上面的内容与宏一起使用对我来说:
`define assert(signal, value) \
if (signal !== value) begin \
$display("ASSERTION FAILED in %m: signal != value"); \
$finish; \
end
Run Code Online (Sandbox Code Playgroud)
然后在我的测试模块中:
initial begin // assertions
#32 `assert(q, 16'hF0CB)
end
Run Code Online (Sandbox Code Playgroud)
作为示例测试失败案例:
ASSERTION FAILED in test_shift_register: q != 16'hF0CB
Run Code Online (Sandbox Code Playgroud)