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

AboutRoadmapCareersInternshipsFAQContactPrivacyTerms
Skip to lesson

Course contents

  • RTL Foundations36
    • Digital Logic for RTL Engineers
    • Number Systems for RTL Engineers
    • Verilog Fundamentals
    • Verilog Operators and Types
    • SystemVerilog for RTL
    • Simulation and Testbenches
      • Minimal but Robust Testbench Structure
      • Clock and Reset Best Practices
      • Self-Checking and Observability
      • Useful Runtime Instrumentation
      • Verification Quality Gates
      • First Project: a 4-bit ALU
  • Combinational Design25
  • Sequential Design27
  • FSM & Control27
  • Timing & Clocking39
  • Reset & CDC34
  • Memory & Buses57
  • Advanced RTL28
  • Senior & Interview76
  • Glossary and Notation
Loading lesson

←Simulation and Testbenches
  1. Topics
  2. RTL Design
  3. RTL Foundations
  4. Simulation and Testbenches
  5. Verification Quality Gates
On this page

    Part 1 of 9, lesson 35 of 36Part 1 of 9/Foundations/Lesson 35 of 36Beginner

    Verification Quality Gates

    Nine gates from lint to review that decide when an RTL block is finished.

    One passing simulation does not finish a block. A test suite that never reaches a state cannot detect a bug in it, so coverage is a gate: it measures what the tests saw, not whether they passed.

    After this lesson you can: list the gates that define a block as verified, in the order they start, and say what each one catches.

    Done is a checklist, not a feeling

    One passing simulation does not finish a block. A defined set of gates does, with each gate catching a different kind of mistake.

    Gate

    Question it answers

    Typical tool

    1. Lint

    Is the code free of width, latch, multiple-driver and style problems?

    Verilator -Wall, signoff lint

    2. Clean compile

    Does it compile in every target simulator with no warnings?

    Your simulators

    3. Directed tests

    Do the known corner cases pass (reset, full, empty, back-to-back, limits)?

    Self-checking testbench

    4. Randomized tests

    Does it survive millions of unplanned input patterns?

    Seeded constrained-random

    5. Assertions

    Do protocol and invariant rules hold every cycle?

    SVA in design or testbench

    6. Coverage

    Did the tests actually exercise every state, branch and interesting combination?

    Code and functional coverage

    7. Equivalence / formal

    Does the synthesized netlist match RTL, and do key properties hold?

    Formal tools

    8. CDC / reset review

    Are clock-domain crossings and resets safe?

    CDC and RDC tools

    9. Review

    Can a second engineer explain every always block?

    Code review

    Gate order

    All gates must be clean before sign-off. Cheap gates (lint, compile, directed tests) run on every change; the others run continuously and are closed together. The order below is roughly the order in which each gate first starts.

    The gates in the order they usually start. They overlap and iterate, and all must be clean before sign-off.

    Cheap gates to run today

    Diagram
    # 1) lint everything with warnings on
    verilator --lint-only -Wall -Wno-DECLFILENAME top.sv
    
    # 2) compile with a second tool to catch dialect differences
    iverilog -g2012 -o sim.out top.sv tb_top.sv
    
    # 3) run the self-checking test as a real gate: keep the simulator status, then require no FAIL and exactly one PASS
    set -o pipefail
    vvp sim.out | tee run.log || exit 1
    ! grep -q FAIL run.log && test "$(grep -c '^PASS:' run.log)" -eq 1
    # vvp sim.out | grep -E "PASS|FAIL"  # log filtering, not a gate: matches even a FAIL line

    Passing tests is not the same as being verified. A test suite that never reaches a state cannot detect a bug in it. That is why coverage is a gate: it measures what the tests saw, not whether they passed.

    Automate the gates in a single script and run it before every commit. A gate that is easy to run is a gate that is run.

    “When do you consider a block verified?” A complete answer lists the gates above and mentions coverage closure, not just “the tests pass”.

    Check yourself All 500 tests pass, but code coverage shows an FSM state was never entered. Is the block verified?

    No. The untested state could contain a bug that no test can reveal. Add a directed test (or constraint) that reaches the state, or justify and document why it is unreachable.

    • Each gate catches a different kind of mistake: lint, compile, directed tests, assertions, coverage, and more.

    • Cheap gates run on every change. The others run continuously and close together.

    • Passing tests are not verification. An unreached state needs a directed test or a documented reason.

    Rule of thumb: automate the gates in one script and run it before every commit.

    • Practice: FSM verification: coverage and assertions for corner cases

    • Interview: run a mock interview on this topic

    Related topics

    • Coding style and lint

    • Assertions for RTL

    • First project: a 4-bit ALU

    Previous

    35 / 350

    Next: First Project: a 4-bit ALU

    Up next

    Up nextFirst Project: a 4-bit ALU

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error

    See also

    • Minimal but Robust Testbench Structure
    • Clock and Reset Best Practices
    • Self-Checking and Observability