我完全新的Verilog,所以忍耐一下。
我不知道是否有Verilog内的断言语句。 在我的测试平台,我希望能够断言模块的输出等于一定值。
例如,
mymodule m(in, out);
assert(out == 1'b1);
谷歌搜索给了我几个环节 ,但他们要么过于复杂或没有似乎是我想要的东西。
我完全新的Verilog,所以忍耐一下。
我不知道是否有Verilog内的断言语句。 在我的测试平台,我希望能够断言模块的输出等于一定值。
例如,
mymodule m(in, out);
assert(out == 1'b1);
谷歌搜索给了我几个环节 ,但他们要么过于复杂或没有似乎是我想要的东西。
有断言的开源库称为OVL 。 然而,这是相当沉重的。 一招我从那里缺口正在创建一个模块做断言。
module assert(input clk, input test);
always @(posedge clk)
begin
if (test !== 1)
begin
$display("ASSERTION FAILED in %m");
$finish;
end
end
endmodule
现在,任何时候你要检查的信号,所有你需要做的就是你的模块中实例化一个断言,这样的:
module my_cool_module(input clk, ...);
...
assert a0(.clk(clk), .test(some_signal && some_other_signal));
...
endmodule
当断言失败,你会得到这样的消息:
ASSERTION FAILED in my_cool_module.a0
在显示语句%M将显示整个层次结构有问题的说法,当你有一个较大的项目不少,这些是得心应手。
你可能想知道,为什么我检查在时钟的边缘。 这是微妙的,但很重要。 如果some_signal和some_other_signal在上面的表达式中总是不同的块被分配,这是可能的表达可以为根据订单的一段短暂的时间,你的Verilog仿真调度块(尽管逻辑是完全有效的)是假的。 这会给你一个假阴性。
另一件事上面要注意的是我使用!==,这会导致如果测试值是X或Z如果使用正常的断言失败!=,它可以悄悄给假阳性的情况。
你可以这样写
if(!(out==1'b1)) $finish;
如果您的仿真器支持SystemVerilog的语法,有一个assert
关键字这你想要做什么。
与我的宏的作品放在一起上面:
`define assert(signal, value) \
if (signal !== value) begin \
$display("ASSERTION FAILED in %m: signal != value"); \
$finish; \
end
再后来在我的测试模块:
initial begin // assertions
#32 `assert(q, 16'hF0CB)
end
作为一个示例性测试失败的情况下:
ASSERTION FAILED in test_shift_register: q != 16'hF0CB
Verilog的不支持的断言。 有些工具支持PSL,这使断言在评论,但这是非标准的。 你应该考虑使用从测试平台层次的引用来,否则你必须每个断言放置在一个过程,这将导致混乱。
模仿类似C的断言最简单的方法可能是一个`因为这样定义将使他们全球性的。
`define assert(condition) if(condition) begin $finish(1); end
为了检查信号在非程序性背景下,如你的榜样,您将需要一个不同的宏,构建了一个状态信号,然后触发该信号的测试活动。
`define assert_always(condition) generate if(1) begin wire test = condition; always @(test) `assert(condition) end endgenerate
上面的生成将创建变量测试,以便多个实例应该工作一个新的范围。
在一个程序一个更好的办法可能是建立在一个单独的文件中的任务,然后包括在任何模块声明。
task assert(input condition);
if(!condition)
$finish(2);
endtask
对于非程序性背景下,您需要创建一个包含进程和实例该模块的模块。 这将需要一个唯一的名称为每个实例,除非你把它放在一个生成块。