Hi dave_59,
SV code :
module tb;
import "DPI-C" function int register_assertions();
import "DPI-C" function int assertion_errors();
reg clk,rst;
reg a,d11;
wire out;
int acount;
dut dut1 (d11,a,rst,clk,out);
always
#5 clk = ~clk;
initial begin
clk=0;rst=1;
#10 rst=0; d11=0;a=0;
end
initial begin
$display("SVA testcase");
acount = register_assertions();
$display("Note: %0d assertions registered in testbench",acount);
#20;
d11=0;a=0;
#20 d11=1;
#30 d11=0;
#30 d11=1;
#20 a=1;
#30 d11=0;
#300 acount = assertion_errors();
if ( acount > 0 ) $display("Note: %0d assertion errors seen during simulation",acount);
#100 $finish;
end
initial begin
$monitor($time,"in=%0b a=%0b out=%0b rst=%0b",dut1.in,dut1.a,out,rst);
end
//reg source_flop="dut1.src.q1",
// destination_flop="dut1.dst.q2";
property p1;
@(posedge clk) dut1.in != $past(dut1.in,1) |-> (out == $past(out))[*10];
endproperty
a_p1: assert property (p1);
endmodule
C code :
#include "vpi_user.h"
#include "vpi_abv_cds.h"
#include "sv_vpi_user.h"
#define NULL ((void *)(0))
#define DEBUG_ACNT 1
static int assertion_error_count = 0;
static int assertion_error_detected ( int reason, p_vpi_time timeP, vpiHandle assrtH,
p_vpi_attempt_info attemptP, char *user_data)
{
if ( reason == cbAssertionFailure )
{
assertion_error_count ++;
if ( DEBUG_ACNT ) vpi_printf("Assertion error detected\n");
if(vpi_get(vpiType,assrtH) == vpiAssert) {
vpi_printf("%s, It is an assertion\n",vpi_get_str(vpiFullName,assrtH));
///////////////////////////////////////////////////
vpiHandle prptyH;
prptyH = vpi_handle(vpiProperty,assrtH);
//vpi_printf("%s, It is a property\n",vpi_get_str(vpiDefName,prptyH));
if (prptyH == NULL) {
vpi_printf("ERROR: property handle is empty\n");
}
vpiHandle argsH,argH;
argsH = vpi_iterate(vpiArgument,prptyH);
if (argsH == NULL) {
vpi_printf("ERROR: arguments handle is empty\n");
}
//s_vpi_value current_value;
//current_value.format = vpiBinStrVal; /* read value as a string */
while((argH = vpi_scan(argsH)) != NULL) {
vpi_printf("%s, It is an arg\n",vpi_get_str(vpiName,argH));
//vpi_get_value(argH, ¤t_value);
//vpi_printf("%s, It is the arg val\n",current_value.value.str);
}
///////////////////////////////////////////////////
}
}
return assertion_error_count;
}
static int register_assertion_1scope(vpiHandle scopeH)
{
int mtype;
vpiHandle assrtI, assrtH, parentH;
vpiHandle subI, subH;
int acount = 0;
/* Look for assertions inside modules, programs and interface objects. */
if ( DEBUG_ACNT ) vpi_printf("\nProcessing scope %s for assertions\n",vpi_get_str(vpiFullName,scopeH));
mtype = vpi_get(vpiType,scopeH);
if ( mtype == vpiModule || mtype == vpiProgram || mtype == vpiInterface )
{
/* Find any assertion directives in this scope */
if ( (assrtI = vpi_iterate(vpiAssertion,scopeH)) )
while ( (assrtH = vpi_scan(assrtI)) )
{
if ( vpi_get(vpiType,assrtH) == vpiAssert )
{
parentH = vpi_handle(vpiInstance,assrtH);
if ( parentH == scopeH )
{
/* Register the callback function to catch an error transition on this assertion */
vpi_register_assertion_cb ( assrtH, cbAssertionFailure, assertion_error_detected, NULL );
acount++;
if ( DEBUG_ACNT ) vpi_printf(" Registered cb for %s\n",vpi_get_str(vpiFullName,assrtH));
}
}
}
}
/* Finish by processing the subscopes to this scope */
if ( (subI = vpi_iterate(vpiInternalScope,scopeH)) )
while ( (subH = vpi_scan(subI)) ) acount += register_assertion_1scope(subH);
if ( DEBUG_ACNT ) vpi_printf("End scope %s with %d assertions\n\n",
vpi_get_str(vpiFullName,scopeH),acount);
return acount;
}
int register_assertions ( void )
{
vpiHandle topI,topH;
int acount = 0;
if ( DEBUG_ACNT ) vpi_printf("Registering assertions to detect errors during simulation\n");
/* Loop over the top level scopes in the design registering assertions for each */
if ( (topI = vpi_iterate(vpiModule,NULL)) )
while ( (topH = vpi_scan(topI)) ) acount += register_assertion_1scope(topH);
if ( (topI = vpi_iterate(vpiProgram,NULL)) )
while ( (topH = vpi_scan(topI)) ) acount += register_assertion_1scope(topH);
if ( (topI = vpi_iterate(vpiInterface,NULL)) )
while ( (topH = vpi_scan(topI)) ) acount += register_assertion_1scope(topH);
return acount;
}
int assertion_errors(void)
{
return assertion_error_count;
}