Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • Start Here6
  • SystemVerilog Language Foundations28
  • Object-Oriented SystemVerilog for Verification30
  • Constraint Randomization — Interview-Critical Deep Dive36
  • SystemVerilog Assertions — Interview-Critical Deep Dive40
    • SVA Fundamentals
    • Sequences: Temporal Building Blocks
    • Implication and Property Operators
      • |-> vs |=>
      • Vacuous Success
      • Property Operators: not, and, or, if/else, implies
      • nexttime, always, s_eventually, until
      • Designing Good Antecedents
    • Sampled Value Functions
    • Protocol Assertion Cookbook
    • Advanced SVA: Local Variables, Multiclock & More
    • Assertion Debug & Methodology
    • SVA Interview Drills
  • Functional Coverage in SystemVerilog22
  • Testbench Architecture in SystemVerilog23
  • Advanced Language & Integration25
  • Senior & Interview Preparation21
  • Principal-Level Verification28
Loading lesson

‹Implication and Property Operators
  1. Topics
  2. SystemVerilog
  3. SystemVerilog Assertions — Interview-Critical Deep Dive
  4. Implication and Property Operators
  5. |-> vs |=>

Part 4 · Assertions (SVA) · Intermediate

|-> vs |=>

Overlapped and nonoverlapped implication, one stimulus with opposite verdicts, and the desugared delay form.

On this page

    Why this matters

    A one-cycle-latency handshake check failed on every transfer. It was written with |-> where the spec said the response comes the next cycle, which is |=>.

    After this lesson you can: choose between overlapped and non-overlapped implication and convert one into the other.

    Where the consequent starts

    An implication has two halves. The antecedent is a sequence that triggers, and the consequent states the obligation.

    Every clock tick starts one attempt. If the antecedent matches, the consequent must hold from each match endpoint.

    |-> starts the consequent on the antecedent end tick. |=> starts it one tick later, which is exactly |-> ##1.

    design.sv
    1
    2
    3
    4
    5
    6
    7
    // snippet
    property p_ovl;
      @(posedge clk) req |-> gnt;
    endproperty
    property p_novl;
      @(posedge clk) req |=> gnt;
    endproperty

    For a sequence consequent, a |=> s equals a |-> ##1 s. In general, a |=> p equals a ##1 1 |-> p, which also covers a property consequent. Windows need |-> ##[M:N], since no ranged |=> exists. The reverse has no clean form, so |-> is the primitive and |=> is sugar for the one-cycle case.

    One stimulus, opposite verdicts

    The diagram drives req for one cycle and answers with gnt in the next cycle.

    • Slot 0: req 0, gnt 0. The antecedent is low, so the attempt is vacuous.

    • Slot 1: req 1. Overlapped samples gnt now (0) and fails, while nonoverlapped waits one tick.

    • Slot 2: gnt 1. Nonoverlapped samples 1 and passes.

    • Slot 3: both 0. Idle attempt.

    • Slot 4: both 0. Idle attempt.

    Attempt and failure ticks shift by one with the consequent start. On this stimulus the two forms give opposite verdicts, though with gnt held high both would pass.

    Choosing the operator

    Spec wording

    Operator

    Reading

    Same cycle

    |->

    Consequent overlaps the antecedent end tick

    Next cycle

    |=>

    Consequent starts one tick after the end tick

    Within M to N cycles

    |-> ##[M:N]

    Explicit ranged window

    Multi-cycle antecedent

    Either

    Timing measured from the end tick, never the first

    With (req ##1 ack) |-> done, done is checked on the ack cycle. With |=> it is checked one tick after ack.

    Common pitfall

    Writing |=> for a same-cycle rule lands one cycle late and passes broken logic. Writing |-> for a registered grant fails correct hardware. Measure every delay from the antecedent endpoint.

    Interview

    Likely tasks: rewrite a |=> b without |=>, extend it to a 2-to-4 window, and place the consequent start for a multi-cycle antecedent. Answers: a |-> ##1 b, a |-> ##[2:4] b, from the end tick.

    Check yourself What does req |=> gnt expand to, and how is a 1-to-3 window written?

    req |=> gnt is exactly req |-> ##1 gnt. A 1-to-3 window is req |-> ##[1:3] gnt, since |=> has no ranged form.

    Check yourself The antecedent (req ##1 ack) matches. On which tick is done checked under |->?

    On the ack cycle, the antecedent end tick. Under |=> it would be one tick after ack.

    Testbench

    A registered grant plus the testbench that proves both forms agree on it.

    design.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    module tb_impl_ovl;
      timeunit 1ns; timeprecision 1ps;
      logic clk = 0;
      always #5 clk = ~clk;
      logic rst_n = 0;
      logic req = 0;
      logic gnt = 0;
      logic req_q = 0;
      int checks = 0;
      int errors = 0;
    
      always @(posedge clk) begin
        if (!rst_n) gnt <= 1'b0;
        else gnt <= req;
      end
    
      a_novl: assert property (@(posedge clk) disable iff (!rst_n) req |=> gnt);
      a_desugar: assert property (@(posedge clk) disable iff (!rst_n) req |-> ##1 gnt);
    
      always @(posedge clk) begin
        req_q <= req;
        if (rst_n && req_q) begin
          checks <= checks + 1;
          if (gnt !== 1'b1) errors <= errors + 1;
        end
      end
    
      initial begin
        rst_n = 0;
        req = 0;
        repeat (2) @(negedge clk);
        rst_n = 1;
        @(negedge clk);
        req = 1;
        @(negedge clk);
        req = 0;
        repeat (4) @(negedge clk);
        if (checks == 1 && errors == 0)
          $display("PASS: grant sampled high one cycle after req; both implication forms agreed");
        else
          $fatal(1, "FAIL: grant timing off");
        $finish;
      end
    endmodule
    Terminal
    PASS: grant sampled high one cycle after req; both implication forms agreed

    Remember

    • |-> starts the consequent on the antecedent's last tick.

    • |=> starts it one tick later; a |=> b equals a |-> ##1 b.

    • Read the spec's latency before choosing the arrow.

    Rule of thumb: write the latency the spec states, then pick the arrow that says it.

    How this was checked

    Run with Verilator 5.048 (--binary --timing --assert, plus --coverage when a listing has a cover property) on 2026-10-18; every bench printed the PASS line shown. Verilator stops at the first $error or failing assertion without an action block, so the benches count failures in the action block. Icarus 13 has no concurrent assertions.

    Related topics

    • Vacuous Success

    • Sequences

    Previous

    110 / 259

    Next: Vacuous Success

    Up next

    Up nextVacuous Success

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Property Operators: not, and, or, if/else, implies
    • nexttime, always, s_eventually, until
    • Designing Good Antecedents
    clkreqgnt
    A request answered one cycle later: overlapped fails, nonoverlapped passes.