Question regarding the sampling values

I have a question regarding the sampling values.

logic a;
$rose(a);
 meaning a can go from 0/x/z to 1

now my question is ,

$(posedge a);
 what does this mean? is it only from 0 to 1 or same as above.

Further,
2)
If “a” is x/z on the previous cycle and existing cycle, what will

$stable(a)

return?
Will it still return 1?

If “a” is x on the previous cycle and 1 on existing cycle, what will

$changed(a)

return?
Will it still return 1/0?

If “a” is x/z on the previous cycle , what will

$past(a)

return?
Will is still return x?

If a needs to toggle every clock cycle - i.e.

1 0 1 0 1 0 1 0

Which one is correct assertion to check? from below two options?

a_toggle : assert property (@(posedge clk) ##1 $changed(a));
a_toggle : assert property (@(posedge clk) 1 -> ##1 $changed(a));

Thank you,
Mega

In reply to megamind:

  1. 1800’21017 states: $rose returns true (1’b1) if the LSB of the expression changed __to 1. Otherwise, it returns false (1’b0).
    Thus, X to 1 is a rose.
  2. @(posedge a); 1800’2017 9.4.2 Event control
  3. A negedge shall be detected on the transition from 1 to x, z, or 0, and from x or z to 0
    — A posedge shall be detected on the transition from 0 to x, z, or 1, and from x or z to 1
  4. $stable(a) 1800’2017
    $stable returns true (1’b1) if the value of the expression did not change. Otherwise, it returns false (1’b0). Thus, X to X is a no change
  5. $past returns the sampled value of expression1 in a particular time step strictly prior to the one in which $past is evaluated (see 16.5.1 for the definition of sampling in past clock ticks).
    Thus, if past was X, $past returns XX.
    If 1st clock (i.e., no past exists). it is the default sampled value of a static variable is the value assigned in its declaration, or, in the eabsence of such an assignment, it is the default (or uninitialized) value of the corresponding type

Sample code


 module m; 
    logic a, b;
    bit clk; 
    initial forever #10 clk = !clk;
    default clocking @(posedge clk); endclocking
    initial begin  
      $display("1  %t  $sampled(a} = %b", $realtime, $sampled(a));
      $display("1  %t a= %b", $realtime, a);
      $display("1  %t $rose(a)= %b", $realtime, $rose(a));
      $display("1  %t $stable(a)= %b", $realtime, $stable(a));
  
      @(posedge clk) a <= 1'b1; 
      $display("2  %t  $sampled(a} = %b", $realtime, $sampled(a));
      $display("2  %t a= %b", $realtime, a);     
      $display("2  %t $rose(a)= %b", $realtime, $rose(a));
      $display("2  %t $stable(a)= %b", $realtime, $stable(a));
      #1 $display("2 #1  %t a= %b", $realtime, a);

  
      @(posedge clk) a <= 1'b0;
      $display("3  %t  $sampled(a} = %b", $realtime, $sampled(a));
      $display("3  %t a= %b", $realtime, a);
      $display("3  %t $rose(a)= %b", $realtime, $rose(a));
      $display("%t $stable(a)= %b", $realtime, $stable(a));
  
      @(posedge clk) a <= 1'b1;
      $display("4  %t a= %b", $realtime, a);
      $display("4  %t  $sampled(a} = %b", $realtime, $sampled(a));
      $display("4  %t $rose(a)= %b", $realtime, $rose(a));
      $display("4  %t $stable(a)= %b", $realtime, $stable(a));
  
      @(posedge clk) a <= 1'b1; 
      $display("5  %t a= %b", $realtime, a);
      $display("5  %t  $sampled(a} = %b", $realtime, $sampled(a));
      $display("5  %t $rose(a)= %b", $realtime, $rose(a));
      $display("5  %t $stable(a)= %b", $realtime, $stable(a));

      @(posedge clk) a <= 1'b1; 
      $display("6  %t a= %b", $realtime, a);
      $display("6  %t  $sampled(a} = %b", $realtime, $sampled(a));
      $display("6  %t $rose(a)= %b", $realtime, $rose(a));
      $display("6  %t $stable(a)= %b", $realtime, $stable(a));

      @(posedge clk) a <= 1'b0;
      $finish;
    end
  endmodule
  
  # KERNEL: 1                     0  $sampled(a} = x
# KERNEL: 1                     0 a= x
# KERNEL: 1                     0 $rose(a)= 0
# KERNEL: 1                     0 $stable(a)= 1
# KERNEL: 2                    10  $sampled(a} = x
# KERNEL: 2                    10 a= x
# KERNEL: 2                    10 $rose(a)= 0
# KERNEL: 2                    10 $stable(a)= 1
# KERNEL: 2 #1                    11 a= 1
# KERNEL: 3                    30  $sampled(a} = 1
# KERNEL: 3                    30 a= 1
# KERNEL: 3                    30 $rose(a)= 1
# KERNEL:                   30 $stable(a)= 0
# KERNEL: 4                    50 a= 0
# KERNEL: 4                    50  $sampled(a} = 0
# KERNEL: 4                    50 $rose(a)= 0
# KERNEL: 4                    50 $stable(a)= 0
# KERNEL: 5                    70 a= 1
# KERNEL: 5                    70  $sampled(a} = 1
# KERNEL: 5                    70 $rose(a)= 1
# KERNEL: 5                    70 $stable(a)= 0
# KERNEL: 6                    90 a= 1
# KERNEL: 6                    90  $sampled(a} = 1
# KERNEL: 6                    90 $rose(a)= 0
# KERNEL: 6                    90 $stable(a)= 1

Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us
For training, consulting, services: contact http://cvcblr.com/home.html
** SVA Handbook 4th Edition, 2016 ISBN 978-1518681448

  1. SVA Package: Dynamic and range delays and repeats SVA: Package for dynamic and range delays and repeats - SystemVerilog - Verification Academy
  2. Free books: Component Design by Example https://rb.gy/9tcbhl
    Real Chip Design and Verification Using Verilog and VHDL($3) https://rb.gy/cwy7nb
  3. Papers:

In reply to ben@SystemVerilog.us:

Thank you Ben.
I am still little confused on $rose(a); and @(posedge a);
Like you said, both will detect if value changes from “0/x/z” to “1”
I was wondering if it is possible to use’m interchangeably ?

always @(posedge a)
always $(rose a)

property @(posedge a)
property $(rose a)

Or it is the rule to use only events while using always and properties, and why is that rule?

Also can you please throw your inputs on this.

logic a;
If “a” needs to toggle every clock cycle - i.e.

1 0 1 0 1 0 1 0

Which one is correct assertion to check? from below two options?

a_toggle : assert property (@(posedge clk) ##1 $changed(a));
a_toggle : assert property (@(posedge clk) 1 -> ##1 $changed(a));

Thank you,
Mega

In reply to megamind:

Hi @Megamind,

I am not sure always$rose(a) is a good coding style. But let me answer your first question:

Difference between always@(posedge a) v/s always $rose(a):

always@(posedge a) is an event which is checked instantly. It will activate in the same cycle if a is high.

While always$rose(a) is checked in different way. It checks whether a was low in the previous cycle and high in current cycle. If a is high in this cycle, procedural block always$rose(a) will get executed in the next cycle as mentioned above.

In reply to sa5691:
Before answering the specific questions, let me review important related points that can clarify some of your concerns:

  1. What is an event? 1800’2017: Every change in state of a net or variable in the system description being simulated is considered an update event.
  2. Processes are sensitive to update events. Examples of processes include, but are not limited to, primitives; initial, always, always_comb, always_latch, and always_ff procedures; continuous assignments; asynchronous tasks; and procedural assignment
    statements
  3. **sensitivity:**Processes are sensitive to update events. When an update event is executed, all the processes that are sensitive to that event are considered for evaluation in an arbitrary order. The evaluation of a process is also an event, known as an evaluation event.
  4. 1800’2017 9.4: Procedural timing controls: Time control statements are the # expression and @ expression constructs.
    …The first type is a delay control, in which an expression specifies the time duration between initially encountering the statement and when the statement actually executes.
    …The second type of timing control is the event expression, which allows statement execution to be delayed until the occurrence of some simulation event occurring in a procedure executing concurrently with this procedure.
    …Simulation
    time can advance by one of the following three methods:
    — A delay control, which is introduced by the symbol #
    — An event control, which is introduced by the symbol @
    — The wait statement, which operates like a combination of the event control and the while loop.

delay_control ::=
# delay_value
| # ( mintypmax_expression )
event_control ::=
@ hierarchical_event_identifier
| @ ( event_expression )
| @*
| @ (*)
| @ ps_or_hierarchical_sequence_identifier
event_expression31 ::=
[ edge_identifier ] expression [ iff expression ]
| sequence_instance [ iff expression ]
| event_expression or event_expression
| event_expression , event_expression
| ( event_expression )
procedural_timing_control ::=
delay_control
| event_control
| cycle_delay
...
wait_statement ::=
wait ( expression ) statement_or_null
| wait fork ;
| wait_order ( hierarchical_identifier { , hierarchical_identifier } ) action_block
edge_identifier ::= posedge | negedge | edge

Back to your questions:
There is a big difference between “what you can possibly do” and what you can safely do. You can drive a car on the wrong side of the road, but that there may be severe consequences in doing so. Keeping this in mind.


$rose:  Syntax: $rose(expr [,clk_evnt])
// You can write 
always @($rose(a, @(posedge clk)) ... // the rose of a is an event 
// The process will wake up at every rose.  Ok to do if this is what you want. 
// Definitely NOT OK for RTL designs, but OK for testbenches. 
// I don't believe that this type of structure is used often, and I personally prefer to 
// stick to traditional approaches, like 
always @(posedge clk) begin 
   if($rose(a) ... // the clock is inferred here. 

// 1800'2017 9.2.2.1 General purpose always procedure
/* If an always procedure has no control for simulation time to
advance, it will create a simulation deadlock condition.
The following code, for example, creates a zero-delay infinite loop: */ 
always areg = ~areg;

always $rose(a) // Illegal because of no clocks
always $rose(a, @(posedge clk)) // creates a zero-delay infinite loop
// the result of the $rose is a value, true or false. 
//-------------------
a_toggle : assert property (@(posedge clk) ##1 $changed(a));
a_toggle : assert property (@(posedge clk) 1 -> ##1 $changed(a)); // BAD practice
// The use of true as antecedent is meaningless and adds nothing, unless 
// you are in a debugging mode and just want to examine the consequent 

Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us
For training, consulting, services: contact http://cvcblr.com/home.html
** SVA Handbook 4th Edition, 2016 ISBN 978-1518681448

  1. SVA Package: Dynamic and range delays and repeats SVA: Package for dynamic and range delays and repeats | Verification Academy
  2. Free books: Component Design by Example FREE BOOK: Component Design by Example … A Step-by-Step Process Using VHDL with UART as Vehicle | Verification Academy
    Real Chip Design and Verification Using Verilog and VHDL($3) Amazon.com
  3. Papers:

In reply to ben@SystemVerilog.us:

Thank you. This discussion clarified confusion.