Is there a way to use SVA property's local variable value to be used outside property

Below is the assertion I have written


property scl_clk_per;
    realtime start_time,start_time_temp;
    realtime period;
     disable iff(!reset)
     @(posedge scl_in) (1,start_time = $time) ##0 @(negedge scl_in) ##0 (1,start_time_temp = start_time) ##0 @(posedge scl_in) (1,period = ($time - start_time_temp)) ##0 (period >= 1us)
 endproperty

clock_freq_prop : assert property (scl_clk_per) else $display("Assertion Error");


Now I want to use the value that I captured in local variable period in the $display statement.

Thanks in Advance

In reply to Monarch Dave:
SVA does not allow the access of local variables from the action block.
Some simulators do report the value of the variables upon a failure. However, if you absolutely want to have access you can do what I have in the example below. In this example,
the property is


(a, v=b, t=$realtime) |=> (b==v); // where b and v are int.

import uvm_pkg::*; `include "uvm_macros.svh" 
module top; 
	bit clk, a;  
	int b, temp;
	string tID="My project"; 
	realtime tr; 
	default clocking @(posedge clk); endclocking
	initial forever #10 clk=!clk;   
	
	function void report_fail(int v, b, realtime t); 
	   if (b!=v) 
  `uvm_info(tID,$sformatf("Fail for @attempt time=%t v=%d, b=%d", t, v, b), UVM_LOW);
	endfunction

	property p_test; 
		int v; 
		realtime t;
		(a, v=b, t=$realtime) |=> (1, report_fail(v, b, t)) ##0 (b==v);
	endproperty 
	ap_test: assert property(p_test);  
	

 initial begin 
     repeat(200) begin 
       @(posedge clk);   
       #2 if (!randomize(a, b)  with 
           { a dist {1'b1:=2, 1'b0:=1};
             b inside {[2:5]}; 
           }) `uvm_error("MYERR", "This is a randomize error")
       end 
       $finish; 
    end 
endmodule  

you can change the UVM verbosity with th ewneeded verbosity with:
simulation_command +UVM_VERBOSITY=UVM_HIGH filename.sv
Code file: http://systemverilog.us/vdispvar2.sv
Results

Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us

  • SVA Handbook 4th Edition, 2016 ISBN 978-1518681448
    // For 10% discount, use code 45KJT5GN @ https://www.createspace.com/5810350
  • A Pragmatic Approach to VMM Adoption 2006 ISBN 0-9705394-9-5
  • Using PSL/SUGAR for Formal and Dynamic Verification 2nd Edition, 2004, ISBN 0-9705394-6-0
  • Real Chip Design and Verification Using Verilog and VHDL, 2002 isbn 0-9705394-2-8
  • Component Design by Example ", 2001 ISBN 0-9705394-0-1
  • VHDL Coding Styles and Methodologies, 2nd Edition, 1999 ISBN 0-7923-8474-1
  • VHDL Answers to Frequently Asked Questions, 2nd Edition ISBN 0-7923-8115

In reply to ben@SystemVerilog.us:

Thanks Ben,

Thanks for solution.

I did actually thought to use verbosity feature, but used it like this


property scl_clk_per;
    realtime start_time,start_time_temp;
    realtime period;
     disable iff(!reset)
     @(posedge scl_in) (1,start_time = $time) ##0 @(negedge scl_in) ##0 (1,start_time_temp = start_time) ##0 @(posedge scl_in) (1,period = ($time - start_time_temp),`uvm_info("CLK_PERIOD",$psprintf("Actual Period =%0d",period),UVM_MEDIUM)) ##0 (period >= 1us)
 endproperty
 
clock_freq_prop : assert property (scl_clk_per) else $display("Assertion Error");

But it gives compilation error like below.

** Error: (vlog-13069) ** while parsing macro expansion: ‘uvm_info’ starting at
** at I2cIf.sv(823): near “begin”: syntax error, unexpected begin.

In reply to Monarch Dave:

The macro `uvm_info expands to begin…end hence your issue. Use uvm_report_info () function instead.

Srini
www.go2uvm.org

In reply to Srini @ CVCblr.com:

Thanks Srini.

Hello Everyone,

I have a similar situation where I need to use the local variable of my property inside the sequence which it calls. But this is not allowed by SVA.
Below is my requirement :

  sequence seq_timer_irq_to_fccu;
    ($rose(Ctrl[16])) ##1 (1,timer=timer-1'b1) [*0:$] ##1 timer==0 ##0 ($rose(timer_irq) && $rose(TmrIrq_status[0]));
  endsequence
  sequence seq_timer_irq_internal;
    (!(Ctrl[16])) ##1 (1,timer=timer-1'b1) [*0:$] ##1 timer==0 ##0 (!(timer_irq) && $rose(TmrIrq_status[0]));
  endsequence
  property ASSERT_TIMER_IRQ;
    int timer = 0;
    @(posedge ipg_clk) disable iff (async_reset_b == 1'b0)
    (($rose(Ctrl[0])) && !timer_irq, timer=TmrReLd+1'b1) |-> (seq_timer_irq_to_fccu or seq_timer_irq_internal); // TmrReLd is local signal inside my interface which is connected to the RTL top.
  endproperty

The above code is giving syntax error which I expect here. Could anyone please suggest me how can I achieve my goal here.

In reply to birenkumar:
Your issue is your improper use of Local variables in formal arguments and in sequence and property declarations. Below is an expalanation from my SVA Handbook 4th Edition on the use of passing property local variables into sequences.

Please take note that on complex assertions with local variables, I prefer the use of tasks
as explained in my recent paper:
https://verificationacademy.com/forums/systemverilog/paper-understanding-sva-engine-simple-alternate-solutions
Abstract: Understanding the engine behind SVA provides not only a better appreciation and limitations of SVA, but in some situations provide features that cannot be simply implemented with the current definition of SVA. This paper first explains, by example, how a relatively simple assertion example can be written without SVA with the use of SystemVerilog tasks; this provides the basis for understanding the concepts of multithreading and exit of threads upon a condition, such as an error in the assertion. The paper then provides examples that use computational variables within threads; those variables can cause, in some cases, errors in SVA. The strict emulation model with tasks solves this issue.
I’ll work on the testimonial.
Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us
For training, consulting, services: contact Home - My cvcblr


In reply to ben@SystemVerilog.us:

Thanks a lot Ben. I went through your documents. It has clarified few of my concepts on SVA. Thanks again.

One time I used a function with static variable to enable communication between assertion threads. Worked well in that case. Maybe someone will use this concept, and I’m also wondering what you will think of it. Here is the code extract:


function void count_sync(output int o_counter, input bit reset);
    static int counter = 0; 
    begin
    counter = reset ? 0 : counter+1;
    o_counter = counter;
end
endfunction

property sync_processed;
    int counter = 0;
    ( seq_single(k28_5, k30_7, d0_6) , count_sync(counter, 0)) |->
        (counter == 3) |-> ##1 ($rose(asic_rst) ##1 $fell(asic_rst), count_sync(counter, 1));
endproperty

In reply to ocmob:

used a function with static variable to enable communication between assertion threads.

  • What’s the difference between static variables declared in a function and a module variable, which is static? None.
  • The issue in using static variables to communicate between threads is that it is very confusing and is error prone; that’s my belief.
  • I used static variables that are modified from a thread to lock-out other threads from starting or to achieve exclusivity for termination. See
  • A SVA question - SystemVerilog - Verification Academy

Ben Cohen http://www.systemverilog.us/

The difference is it is encapsulated inside a function so only a call to this function can modify it. The use I cited was exactly what you mentioned - to achieve exclusivity for termination for every third thread (when and only when a sequence repeated 3 times there should be a viable result). Now I see it could probably be dealt with using first_match(). Thanks for your opinion. I will try to avoid static variables for communication between threads in any other circumstances than mentioned.

In reply to M_Dave:

Another example using the idea of Ben. Thanks
In this case i do not use the uvm macros and the property is measuring the time a signal (SHIFT_LATCH) is being zero.




function void report_fail(time cur_time, time neglatch_leading, time min_latch_time_ps);
        //error condition BAD CASE
        if ((cur_time-neglatch_leading)<=min_latch_time_ps) begin
            $display("DEBUG_ERROR property_latch_too_short  at %t with  measured latch_time:%t and MIN_LATCH_TIME_PS:%t negedge latch time:%t \n", cur_time, cur_time-neglatch_leading ,min_latch_time_ps, neglatch_leading);
        end
endfunction

 property property_latch_too_short;
        time leading;
        disable iff(!SHIFT_RESETn)
            @(negedge SHIFT_LATCH)
            (1, leading = $time) |->
            @(posedge SHIFT_LATCH)
            (1, report_fail($time,leading,MIN_LATCH_TIME_PS)) ##0    //adding this to the last good case condition allows you print ONLY IN CASE OF ASSERTION CONDITION failure
            ((($time-leading)>MIN_LATCH_TIME_PS),  $display("property_latch_too_short  at %t with MIN_LATCH_TIME_PS:%t and measured latch_time:%t \n", $time, MIN_LATCH_TIME_PS, $time-leading));//GOOD CASE
endproperty
// FUNCTIONAL COVERAGE
c_property_latch_too_short: cover property(property_latch_too_short);
//ASSERTION OF PROPERTY
a_property_latch_too_short : assert property (property_latch_too_short)       else $error($sformatf("UVM_ERROR  Width of LATCH less than %t ps. Min Latch time violation at time %t",MIN_LATCH_TIME_PS,$time) );


In reply to JA:
Use realtime, $realtime instead of time, $time
Otherwise, looks OK.