Skip to content
code0.HDL

Design and verification

From a requirement to a design under test and its testbench; what compile, elaborate, simulate and synthesize each do; normal, boundary and reset cases; and how to reason from a first mismatch to a likely cause.

In this chapter

  • Separate the requirement, the design under test and the testbench
  • Say what compile, elaborate, simulate and synthesize each do, and which this site runs
  • Turn a requirement into normal, boundary and reset test cases and reason from a first mismatch to a likely cause
Concepts in this chapter
  • Requirements, DUT, testbench
  • Compile, elaborate, simulate, synthesize
  • Normal, boundary and reset cases
Prerequisite concepts

1. The requirement comes first; the design implements it and the testbench checks it

Hardware design and verification connect three things: requirements that specify the behavior, design code that implements it as a circuit, and a testbench that drives inputs and compares outputs with expected values. The circuit being checked is the DUT, the design under test.

RoleWhat it doesThe question it answers
Requirementfixes the inputs, the outputs and the cycle-by-cycle behaviour in wordswhat has to be built
DUTdescribes the requirement as a circuithow it is built
Testbenchgenerates clock and reset, drives the inputs, observes the outputs against expected values, and stops the simulation when donewhether it behaves as required

The testbench's expected values are computed from the requirement, never from the DUT's code. Write both from the same misunderstanding and the test passes while the design is wrong.

Note. How a testbench is written differs by language, and each language path writes the real code. In Verilog it is a module of initial blocks and system tasks; in BSV, testbench rules that drive inputs and print results; in Chisel, a Scala test that sets inputs with poke, advances an edge with step and reads outputs with peek or expect. This unit covers the roles only, without syntax.

2. Distinguish compilation, elaboration, simulation and synthesis

These four tasks expose different kinds of problems. Tools may combine compilation and elaboration, and synthesis is a separate path to a hardware implementation, not a mandatory step after simulation.

StageWhat it doesWhat surfaces here
Compilechecks syntax and types and builds an internal representationsyntax errors, type errors, undeclared names
Elaborate (generate)expands module instances and fixes parameters and widthsunconnected ports, mismatched widths
Simulateadvances time in the order the testbench dictates and computes valuesoutputs that differ from the requirement, runs that never end
Synthesizemaps the circuit onto gates or FPGA resourcesconstructs that cannot be synthesized, timing

This site runs simulation and nothing beyond it: Verilog with Icarus Verilog 11, BSV with bsc 2026.01, Chisel with Chisel 6.7.0, chiseltest 6.0.0 and firtool 1.154.0. Gate-level or FPGA technology mapping is not run. A successful execution means that the requested command completed; it does not prove that every requirement was checked. Read the assertions and observations to see what was tested. Whether the design can be synthesized is a separate question.

When an execution does not give the expected result, distinguish these four kinds of problem.

OutcomeMeaningWhere to look first
Compile errorthe compile or elaborate stage stopped; no simulation startedthe file and line in the message
Run-time errorthe simulation started but did not finish normallythe simulator's last output
Test mismatchthe simulation finished and an output differs from the expectationthe first differing cycle
Result not receivedthe request failed or the response could not be receivedcheck the displayed service or connection error before retrying

Check

A Bool value is assigned to a 4-bit signal and the tool reports a type error. Which stage reports it?

Your answer

3. Cases come in three kinds: normal, boundary and reset

A requirement is turned into test cases. One case is an input sequence, the output expected for it, and the sentence of the requirement that expectation comes from. Sorting cases into three kinds shows where the gaps are.

KindMeaning
Normalthe everyday behaviour the body of the requirement describes
Boundarywhere the rule changes shape: the maximum, the wrap, two inputs at 1 in the same edge
Resetthe starting value and the return to it

The requirement for counter4 reads: "A 4-bit counter. At an edge where clear is 1, q becomes 0. With clear at 0 and enable at 1, q increases by 1, and 0 follows 15. With both at 0, q holds. The starting value is 0." Those sentences give this table.

CaseKindInputsExpected qWhy
Starting valueresetbefore the first edge0"the starting value is 0"
Count oncenormalclear 0, enable 1 for one cycle1"increases by 1"
Holdnormalfrom q = 1, enable 0 for two cycles1"with both at 0, holds"
Wrapboundaryenable 1 for sixteen cycles0"0 follows 15"
Clear while countingresetfrom q = 5, clear 1 for one cycle0"where clear is 1, 0"
Clear and enable togetherboundaryboth 1 for one cycle0the clear sentence applies before the enable sentence
Count again after clearnormalclear 0, enable 1 for one cycle1"increases by 1", from 0

The table below packs the wrap and a clear during counting into one input sequence. In cycles 0 to 15 only enable is 1, so q climbs by one and the edge of cycle 15 produces the value after 15. Cycle 17 is an edge, in the middle of counting, where clear and enable are both 1. Write q after every edge.

Predict, then compare · counter4

Fill in each cell before comparing. Empty cells count as a mismatch.

State table
Cycleclearinputs sampled at the edgeenableinputs sampled at the edgeqafter the edge
001
101
201
301
401
501
601
701
801
901
1001
1101
1201
1301
1401
1501
1601
1711
1800

4. A weak test is strengthened by adding boundary cases

Here is the sequence of a testbench for counter4.

clear = 1, enable = 0 for one cycle     → check q == 0
clear = 0, enable = 1 for three cycles  → check q == 3
enable = 0 for one cycle                → check q == 3
finish

A design can pass all three checks and still violate the requirement. This test never takes q past 3 and never has an edge with clear and enable both 1, so a counter that stops at 15 passes, and so does one that lets enable win over clear. Strengthening the test means putting the boundary cases from the table into the sequence: clear to 0, then apply sixteen cycles with clear = 0 and enable = 1 before checking q == 0. Also add an edge with both inputs at 1 followed by a check for q == 0.

Play the testbench yourself on the model below. First press the five edges of the weak test exactly as written and confirm that q is 3. Then leave only enable at 1 and press sixteen more edges to find the row where q returns to 0, and finally set clear and enable both to 1 and press one edge to see the row where q is 0. The rows after the weak test ends are the cases it was missing.

Concept experiment · counter4

A browser model of the circuit, not a compiled design. The real toolchain runs in the examples.

Inputs

Outputs

q
0

No edge has happened yet. Set the inputs, then apply a clock edge.

Check

Which case does the test above not check?

Your answer

5. From the first mismatch to a likely cause

When the simulation finishes and an output differs from the expectation, work in this order.

StepWhat to do
1find the first cycle that differs
2confirm, in the waveform or the printed output, what inputs the DUT saw at that edge
3write down which sentence of the requirement should have applied to those inputs
4list the causes that could produce the observed value, and cross out those the input check rules out

Caution. What the testbench sent and what arrived at the DUT's port can differ. With a wrong port connection the testbench believes it drove enable = 1 while the DUT saw 0. Step 2 checks the value at the DUT's port.

Check

From the starting value 0, the testbench drove clear = 0 and enable = 1 for three cycles, yet q is still 0. In the waveform the DUT's clear port was 0 at all three edges. Which is the likely cause?

Your answer

6. Variation: cases from the requirement of a rising-edge detector

The same method applies to the cycle-based rise-detect model from the previous chapter, with inputs held constant during each cycle. Its requirement: "Each time in goes from 0 to 1, rise is 1 for exactly one cycle, and otherwise 0."

CaseKindInputsExpected rise
One risenormalin 0, 0, 1, 01 in cycle 2 only
Held highboundaryin 1 for five cycles1 in the first of them only
1 from the first cycleresetin 1 in cycle 01 in cycle 0 (prev starts at 0)
Two risesnormalin 1, 0, 11 in cycles 0 and 2

A test without the "held high" case passes a design that wires rise straight to in.

Check

in goes from 0 to 1 and then stays 1 for five cycles. In how many of those five cycles is rise 1?

7. Summary

  • The requirement comes first. The DUT implements it, and the testbench checks the DUT against expectations computed from the requirement.
  • Compilation, elaboration, simulation and synthesis have different purposes. This site runs compile and simulation commands, not gate-level or FPGA technology mapping.
  • When a result is wrong or missing, distinguish compile errors, run-time errors, test mismatches and service or connection failures. Normal completion alone does not prove correctness.
  • Cases are sorted into normal, boundary and reset, and a weak test gains boundary cases.
  • A mismatch is traced from the first differing cycle: confirm the inputs at the DUT's port, then cross out causes.

This ends the fundamentals. Choose BSV, Verilog or Chisel and start the first chapter of that course. Each course introduces the DUT and testbench with executable code.

Checkpoint

Answer the checks in this chapter