In reply to MayurKubavat:
Looks like your issue is that the path to the assertion label is not complete.
// CHANGE FROM
$assertkill(0, uvm_test_top.env.scoreboard.assertion_name);
// TO the fix
$assertkill(0, uvm_test_top.env.scoreboard.task_name.assertion_name);
Below is an example that ran OK
import uvm_pkg::*; `include "uvm_macros.svh"
module top;
bit clk, a, b;
default clocking @(posedge clk); endclocking
initial forever #10 clk=!clk;
class C;
bit d=1;
task t();
a_intask: assert(d);
endtask
endclass : C
C c;
initial c=new();
always @(posedge clk) begin : alw1
c.d=b;
c.t();
a_intop: assert(b);
if(a) $assertkill(0, top.alw1.a_intop);
if(a) $assertkill(0, top.c.t.a_intask);
end : alw1
initial begin
repeat(200) begin
@(posedge clk);
if (!randomize(a, b) with
{ a dist {1'b1:=1, 1'b0:=3};
b dist {1'b1:=1, 1'b0:=2};
}) `uvm_error("MYERR", "This is a randomize error")
end
$stop;
end
endmodule
I have tried this in different simulators. But it does not work :(
My Code:
module test();
class A;
bit a = 0;
task checkA;
begin
#10ns;
CHECK: assert(a == 1)
$display($time, "Check on A passed");
else
$display($time, "Check on A failed");
end
endtask
endclass
initial
begin
A Ah = new();
$assertoff(0, test.Ah.checkA.CHECK);
Ah.checkA();
#10 $finish;
end
endmodule //test
One can add some glue logic to disable the assertion instead of depending on hierarchy of assertions. One can make use of a guarding criteria for assertion to fire. Here is a sample code that works for all the simulators.
Note that you can modify the assert_guard to static or a function. Or you can pass it to the macro input argument, depending on the requirement.
`define ASSERT(VAL,ERR) \
assert(!assert_guard || (VAL)) else begin \
$error(ERR); \
end \
class A;
bit assert_guard = 1; // assertion ON by default
bit a = 0;
task checkA;
#10ns;
CHECK: `ASSERT(a == 1,"Check on A failed")
endtask
endclass
initial begin
A Ah = new();
//$assertoff(0, test.Ah.checkA.CHECK);
Ah.assert_guard = 0;
Ah.checkA();
end
endmodule //test
Moreover, one can use disable statement as for deffered assertions, but that would need exact time for assertion to fire.
# KERNEL: Warning: test.Ah.checkA.CHECK is not a valid $assertoff task parameter.
# KERNEL: Warning: test.checkB.CHECKB is not a valid $assertoff task parameter.
// Use this instead
$assertoff(0, test.A.CHECK);
$assertoff(0, test.CHECKB);
// Code your testbench here
// or browse Examples
module test();
bit b=0;
class A;
bit a = 0;
task checkA;
begin
#10ns;
CHECK: assert(a == 1)
$display($time, "Check on A passed");
else
$display($time, "Check on A failed");
end
endtask
endclass
task checkB;
begin : BB
#10ns;
CHECKB: assert(b == 1)
$display($time, "CheckB on A passed");
else
$display($time, "CheckB on A failed");
end
endtask
initial
begin : init0
A Ah = new();
$assertoff(0, test.A.CHECK);
$assertoff(0, test.CHECKB);
Ah.checkA();
checkB();
#10 $finish;
end
endmodule //test
In reply to MayurKubavat:
You’re correct, I don’t know why this is tool dependent.
The following worked on another tool
$assertoff(0, test.checkB.BB.CHECKB); // 34
On the immediate assertion in a class, I believe that the $assertcontrol $assertoff) is not supported, and that makes sense for the following reasons:
Concurrent assertions are not allowed in classes
The simulator creates a database for each assertion to manage its status and state; that includes things like started, pass/fail, success/fail count, strong/weak, etc.
That database is done at elaboration time.
Adding to that database the immediate assertions that are created dynamically (i.e., from class instances) is complicated.
Adding a switch seem to be only possible solution for this.
correct.
class A;
bit a = 0, assertion_enb;
task checkA;
//begin : cc // not needed
#10ns;
if (assertion_enb && !a) // CHECK: assert(a == 1)
// $display($time, "Check on A passed");
// else
$display($time, "Check on A failed");
//end
endtask
endclass
The argument to $asserton/off needs to be a statically scoped identifier.
$assertoff(0, test.checkB.BB.CHECKB);
Should work on any tool, and I’ve tested it on 3 different tools.
The problem with the assertion inside
checkA is that the task has an automatic lifetime, and you cannot access any identifiers declared inside the task from the outside.
I think your best options is to prevent the immediate assertion from executing by overrides or setting conditional flags.
Hi @dave_59,
What is the meaning of “statically scoped identifier”?
Could you please give an example of what is statically scoped and what is not-statically scoped?