I'm completely new to Verilog, so bear with me.
I'm wondering if there is an assert statement in Verilog. In my testbench, I want to be able to assert that the outputs of modules are equal to certain values.
For example,
mymodule m(in, out);
assert(out == 1'b1);
Googling gave me a few links, but they were either too complex or didn't seem to be what I wanted.
There is an open source library for assertions called OVL. However, it's pretty heavy. One trick I nicked from there is creating a module to do assertions.
module assert(input clk, input test);
always @(posedge clk)
begin
if (test !== 1)
begin
$display("ASSERTION FAILED in %m");
$finish;
end
end
endmodule
Now, any time you want to check a signal, all you have to do is instantiate an assertion in your module, like this:
module my_cool_module(input clk, ...);
...
assert a0(.clk(clk), .test(some_signal && some_other_signal));
...
endmodule
When the assertion fails, you'll get a message like this:
ASSERTION FAILED in my_cool_module.a0
The %m in the display statement will show the entire hierarchy to the offending assertion, which is handy when you have a lot of these in a larger project.
You may wonder why I check on the edge of the clock. This is subtle, but important. If some_signal and some_other_signal in the expression above were assigned in different always blocks, it's possible the expression could be false for a brief period of time depending on the order that your Verilog simulator schedules the blocks (even though the logic was entirely valid). This would give you a false negative.
The other thing to note above is that I use !==, which will cause the assertion to fail if the test value is X or Z. If it used the normal !=, it could silently give a false positive in some cases.
Putting the above together with a macro works for me:
`define assert(signal, value) \
if (signal !== value) begin \
$display("ASSERTION FAILED in %m: signal != value"); \
$finish; \
end
Then later in my test module:
initial begin // assertions
#32 `assert(q, 16'hF0CB)
end
As an example test fail case:
ASSERTION FAILED in test_shift_register: q != 16'hF0CB
you can write like this
if(!(out==1'b1)) $finish;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With