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
      • Immediate vs Concurrent Assertions
      • The Four Layers of SVA
      • Clocks & the Sampling Model
      • Evaluation Attempts & Threads
      • assert, assume, cover, restrict & Action Blocks
    • Sequences: Temporal Building Blocks
    • Implication and Property Operators
    • 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

‹SVA Fundamentals
  1. Topics
  2. SystemVerilog
  3. SystemVerilog Assertions — Interview-Critical Deep Dive
  4. SVA Fundamentals
  5. The Four Layers of SVA

Part 4 · Assertions (SVA) · Intermediate

The Four Layers of SVA

Booleans, sequences, properties and directives: the four-layer model with parameterized reuse.

On this page

    Why this matters

    A team copied one handshake check into twenty channels by hand, and one copy kept a stale latency. A parameterized property would have been one line per channel.

    After this lesson you can: name the four layers of an assertion, know which operators belong to which, and reuse one property across many signals.

    Why a layered model

    SVA is a stack of four small languages, each consuming the one below. Booleans say what is true at an instant, sequences arrange booleans across cycles, properties add obligation with a clock and reset, and directives tell the tool what to do.

    Four layers, each consuming the one below.

    The same property feeds every directive. The table below is the one-line version; the Directives and Severity lesson gives the full simulation-versus-formal semantics.

    Directive

    Job

    assert

    Check: report a violation

    assume

    Constrain formal, checked in simulation

    cover

    Count matches, never report

    restrict

    Constrain formal only, ignored in simulation

    One assertion dissected

    req_gnt_props.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
    module req_gnt_props (
      input logic clk,
      input logic rst_n,
      input logic req,
      input logic busy,
      input logic gnt
    );
      // LAYER 1: booleans, named in comments for readability
      // req && !busy   "a request the DUT can accept"
      // gnt            "grant asserted"
    
      // LAYER 2: sequence, the temporal shape "grant within 1 to 4 cycles"
      sequence s_gnt_window;
        ##[1:4] gnt;
      endsequence
    
      // LAYER 3: property, clock plus reset plus obligation
      property p_req_gets_gnt;
        @(posedge clk) disable iff (!rst_n)
        (req && !busy) |-> s_gnt_window;
      endproperty
    
      // LAYER 4: directive, check it in simulation
      ap_req_gets_gnt: assert property (p_req_gets_gnt)
        else $error("request not granted within 4 cycles");
    
      // LAYER 4 again: same property, different directive, count matches
      cp_req_gets_gnt: cover property (p_req_gets_gnt);
    endmodule

    The same property feeds two directives: one checks, one measures. The clock and disable iff live in the property. disable iff must, because it is property-only. A clock could also be attached to the sequence, but keeping it in the property leaves the sequence a reusable shape.

    Reusable libraries

    Sequences and properties take arguments, which turns one-off checks into a library. One handshake property with formal signal and latency arguments can check every channel in the design.

    The library below runs. Its first version had a reusable sequence s_held(sig, n) written as sig [*n], which Verilator 5.048 rejects (a formal used as a repetition count); a formal used as a delay bound, ##[1:max_lat], works. The checks count failures so the bench can plant one.

    handshake_lib.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    module handshake_lib (
      input logic clk,
      input logic rst_n,
      input logic awvalid, awready,
      input logic wvalid,  wready,
      input logic bvalid,  bready,
      output int  aw_fails, w_fails, b_fails
    );
      // Reusable property: fixed clock and reset, signals and latency as arguments.
      property p_handshake(req_s, ack_s, int max_lat);
        @(posedge clk) disable iff (!rst_n)
        req_s |-> ##[1:max_lat] ack_s;
      endproperty
    
      // One definition, three checks with different budgets.
      ap_axi_aw: assert property (p_handshake(awvalid, awready, 2)) else aw_fails++;
      ap_axi_w:  assert property (p_handshake(wvalid,  wready,  4)) else w_fails++;
      ap_axi_b:  assert property (p_handshake(bvalid,  bready,  4)) else b_fails++;
      initial begin aw_fails = 0; w_fails = 0; b_fails = 0; end
    endmodule
    
    Terminal
    answered after 2 cycles: AW 0, W 0, B 0 failures
    answered after 3 cycles: AW 1, W 0, B 0 failures
    PASS: the 2-cycle AW instance caught the 3-cycle answer, and the 4-cycle W and B instances accepted both

    Memorize the composition rules. A sequence instantiates other sequences, and a property instantiates sequences and other properties. Implication, not and disable iff are property-only, while and and or exist at both layers. A clock may be attached to a sequence or to a property. A boolean is a degenerate one-cycle sequence, so it fits anywhere a sequence is required.

    The bench pulses all three channels together, answered after 2 cycles and then after 3. Only the AW instance, with a 2-cycle budget, may fail, and only on the second pulse.

    Common mistakes

    Common pitfall

    Implication and disable iff inside a sequence do not compile. They are property-layer operators, and the sequence / property boundary is exactly where they stop being legal.

    Interview

    Walk through the structure of a concurrent assertion: booleans, composed into sequences by temporal operators, wrapped in properties that add clock, reset and implication, consumed by a directive. The one-property feeding assert and cover pair reads as real-project experience.

    • Trap: disable iff inside a sequence is illegal. It lives at the property layer, like implication.

    • Trap: a sequence describes a pattern that matches or not. A property adds obligation and context. Directives take properties, and a sequence is a degenerate property; cover sequence counts every match of a sequence.

    Check yourself Where do |-> and disable iff belong, and what about not?

    At the property layer, and so does not: negating a sequence yields a property, never a sequence. Only and and or exist at both layers.

    Check yourself Why feed one property to both assert and cover?

    The assert checks the rule while the cover proves the antecedent can fire. Without the cover, a passing assert may never have checked anything.

    Remember

    • Boolean, sequence, property, directive: each consumes the one below.

    • Implication, not and disable iff are property-only.

    • Properties take arguments; one definition can check every channel.

    Rule of thumb: write a property once and instantiate it with arguments.

    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.

    Verilator 5.048 rejected a sequence formal used as a repetition count (sig [*n]) and accepted one used as a delay bound (##[1:max_lat]).

    Related topics

    • Protocol assertions

    • Sequences

    Previous

    102 / 259

    Next: Clocks & the Sampling Model

    Up next

    Up nextClocks & the Sampling Model

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Evaluation Attempts & Threads
    • assert, assume, cover, restrict & Action Blocks