That is the correct and only way; a procedural concurrent assertion (e.f. always @(posedge clk) ) is not more efficient. However, you mention that signal should remain ‘1’ for next five clocks, meaning for 5 more clock cycles. You would need the |=> instead of the |-> since *$rose[a) |-> a[1] is valid for the cycle in which $rose(a) occurred.
one addition to above; the signal which i check want to be HIGH for all remaining clk cycles & it should not go unknown(X).
assert_check: assert property(@(posedge clk) disable iff (rst) $rose (signal) |=> !($isunknown (signal)) & stable(signal)[*]) else $error();[/quote]
Change the above assertion to:
// [*$] is illegal, use the always(property)
// 1800
// property_expr ::= ....
// always property_expr
// | always [ cycle_delay_const_range_expression ] property_expr
// | s_always [ constant_range] property_expr
// Do you need the $error? Ok if you want it.
assert_check: assert property(@(posedge clk) disable iff(rst)
$rose (signal) |=> always(
!$isunknown(signal) && $stable(signal)); // else $error();
// To avoid multiple threads, you could do the following:
initial begin
wait(rst==1'b0); // use whatever variation you need)
assert_check: assert property(@(posedge clk) disable iff(rst)
$rose (signal)[->1] |=> always(
!$isunknown(signal) && $stable(signal)); // else $error();
end
// To avoid multiple threads, you could do the following:
initial begin
wait(rst==1’b0); // use whatever variation you need)
assert_check: assert property(@(posedge clk) disable iff(rst)
$rose (signal)[->1] |=> always(
!$isunknown(signal) && $stable(signal)); // else $error();
end
I tried your suggestion like below; as i want to check this for few sets of signals; when i compile hit with syntax error: "token is ‘always’. (using synopsys)
tried
$rose(a)[->1] |=> ##30 (!$isunknown(q) && $stable(q)); // this works, but it checks once and not till simulation end.
me requirement is to check HIGH for all remaining clk cycles.
SVA legal but not supported:
property_expr ::= …
always property_expr // Is legal syntax
Tools may not support this feature because it is not often used
Alternative solution
See my alternative approach in the paper below. I address your model further down. PAPER: Understanding the SVA Engine + Simple alternate solutions | Verification Academy
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 uses computational variables within threads; those variables can cause, in some cases, errors in SVA. The strictly emulation model with tasks solves this issue.
A new version of that paper entitled "SVA Alternative for Complex Assertions" will be on the February 2018 Issue of the Verification Horizons.
Below is code that simulates OK. I used an always block to fire the task, and also an assertion where in the consequent I fire the task in the sequence_match_item.
Read my paper, as it explains the concepts. The code is self-explanatory, I believe.
import uvm_pkg::*; `include "uvm_macros.svh"
module top;
timeunit 1ns; timeprecision 100ps;
logic clk=0, a, rst=-0;
default clocking @(posedge clk); endclocking
initial forever #10 clk=!clk;
/*initial begin
wait(rst==1'b0); // use whatever variation you need)
assert_check: assert property(@(posedge clk) disable iff(rst)
$rose (a)[->1] |=> always(
!$isunknown(a) && $stable(a)); // else $error();
end*/
task automatic t_stays();
forever begin : fevr
@(posedge clk);
if(rst) return;
if($isunknown(a) || $changed(a)) begin : err
`uvm_error("my_module", "a changed or is unkonwn")
return;
end : err
end : fevr
endtask
always @(posedge clk) begin // possible new thread at every rose(a)
// use initial to fire task once (see below)
if($rose(a)) t_stays();
end
initial begin // FIring task once, an option
wait(rst==1'b0); // use whatever variation you need)
assert_check: assert property(@(posedge clk) disable iff(rst)
$rose(a)][->1] |=> (1, t_stays())); // the [->1] needed because
// it can occur anyime after rst==0, an it is in the initial.
end
initial begin
repeat(10) @(posedge clk) ;
a <= 1'b0;
repeat(200) begin
@(posedge clk);
if (!randomize(a) with
{ a dist {1'b1:=1, 1'b0:=3};
}) `uvm_error("MYERR", "This is a randomize error")
end
$stop;
end
endmodule
I want to check a signal “a” which should not remain high for more than 5 clock cycles otherwise throw an error. What should be the assertion for that.
In reply to prashantk:
You need supporting logic.
Write a counter that increments if a==1, and resets to 0 if a==0.
assert property(@(posedge clk) counter <6);
I’m implementing clock DCC checker using SVA. I want to only check the duty cycle in the first 2 clock cycles after id goes to 4’h2. When I use the repetition operator, compiler is throwing an error saying ‘repetition operator not allowed in multi-clocking sequence’
property positive_duty_cycle_chk(clk, real tolerance, real half_duty_cycle, id);
real v_t1, v_t2, v_hi, v_lo, v_diff, v_total;
real ratio;
@(id) id== 4'h2 |=> (@(posedge clk) (1, v_t1=$time) ##0 @(negedge clk) (1, v_t2=$time, v_hi=v_t2-v_t1) ##0 @(posedge clk) (1, v_lo=$time-v_t2) ##0
(1, v_total = (v_lo+v_hi)) ##0 (1, ratio = (v_lo* (1/v_total))) ##0 ratio >= half_duty_cycle - tolerance && ratio <= half_duty_cycle + tolerance) [*2];
endproperty
In reply to nimitz_class:
You’re saying compiler is throwing an error saying ‘repetition operator not allowed in multi-clocking sequence’
I don’t see that with 2 simulators. Edit code - EDA Playground // some modified code here
It looks like you may have a tool issue.
From a language point of view, ‘repetition operator is allowed in multi-clocking sequence’.
You’ll need to contact your vendor.
Ben
**Warning-[LCA_FEATURES_ENABLED] Usage warning
LCA features enabled by ‘-lca’ argument on the command line. For more
information regarding list of LCA features please refer to Chapter “LCA
features” in the VCS Release Notes
Parsing design file ‘design.sv’
Parsing design file ‘testbench.sv’
Top Level Modules:
duty_cycle
TimeScale is 1 ns / 1 ns
To me, it does not look like an 1800 issue. It could be a tool restriction, and we don’t address tools in this forum. Am consulting with one of the other 1800 SVA member.
More to come.
Did a search on LCA feature
NOTE: Adding the “-lca” switch to a VCS/VCS-MX command line enables a suite of “limited customer availability” features.The exact set of features differs from release to release, but is documented in the “LCA Features” portion of “vcs -doc”.
Without the switch I cannot compile, tool suggested me to add -lca and then re-reun. Anyway, I’m not sure how to fix this issue with the tool. So, I will go with your suggestion of computing duty cycle again after one cycle.