VHDL · Chapter 1.10 · Foundation
Simulation vs Synthesis
Your VHDL source has two readers, and they do not agree on what every line means. A simulator runs the code as a behavioural model and shows you waveforms, while a synthesizer keeps only the synthesizable subset and turns it into gates. Most of the expensive surprises in RTL come from forgetting this, because code that simulates beautifully can synthesize differently, or not at all. Delays, file reads, and printed messages have no gate equivalent, so the synthesizer ignores or rejects them. This lesson draws the line between the two views: what is RTL, what is testbench-only, and why the claim that something simulates correctly is not the same as the claim that it will become correct hardware. That gap is exactly where the most costly bugs hide.
Foundation13 min readVHDLSimulationSynthesisRTLSynthesizable Subset
1. Intuition — one source, two readers
A single .vhd file is handed to two tools with completely different jobs:
- a simulator pretends to be the hardware and runs your design over simulated time, so you can watch signals change and check behaviour;
- a synthesizer builds hardware, mapping your description to a netlist of real gates and flip-flops.
The catch is that they do not interpret the language identically. The simulator will
faithfully run things that have no hardware meaning at all — a wait for 10 ns, a
read from a text file, a printed message. The synthesizer ignores or rejects those,
because there is no gate for "wait ten nanoseconds." So a line can be perfectly valid to
simulate and meaningless to build.
2. The synthesizable subset
Think of the language as two nested sets: all of VHDL, and inside it the synthesizable subset that maps to hardware. Simulation runs everything; synthesis runs only the inner subset:
3. RTL vs testbench-only, side by side
Here is the same idea in code. The register is synthesizable — it maps to flip-flops.
The clock generator beside it is testbench-only — after describes a delay no gate
can implement:
process (clk)
begin
if rising_edge(clk) then
q <= d; -- a register: real hardware
end if;
end process;-- generate a clock for SIMULATION only
clk <= not clk after 5 ns; -- `after` = a timed delay, not hardware
stim : process
begin
rst <= '1'; wait for 20 ns; -- `wait for` = simulation time
rst <= '0'; wait; -- unbounded wait: stop this process
end process;The first block belongs in your design; the second belongs only in a testbench. Mixing
them up — putting after or wait for in RTL — is one of the most common beginner
mistakes, and it produces code that simulates yet will not synthesize.
What does not synthesize (and why)
afterdelays (q <= d after 3 ns;) — there is no gate for "in 3 ns"; synthesis ignores the delay, so the hardware behaves differently from the simulation.wait for <time>— simulation time has no hardware meaning; clocked logic must be driven by a clock edge, not a timed wait.- File I/O (
textio, reading/writing files) — for loading stimulus or logging in a testbench, never something a chip does. - Unbounded / unconstrained waits and other simulation control — they orchestrate the testbench, not the design.
4. The synthesizable part, over time
The register above is real hardware, and simulation shows its behaviour: q captures d
only at the rising clock edge — exactly what the flip-flop will do in silicon.
A flip-flop: q captures d on the rising edge of clk (synthesizable behaviour)
8 cyclesThis waveform is trustworthy because the code is RTL. Had we relied on an after delay
to get the timing, the simulation would still draw a tidy waveform — but the synthesized
hardware would ignore the delay and behave differently. That divergence is the whole risk.
5. Common mistakes & what to watch for
- Believing the waveform proves the hardware. A green simulation only proves the model behaves; if the code leans on non-synthesizable constructs, the gates may not.
- Putting
after/wait forin RTL. They simulate and then vanish (or error) at synthesis — keep all timing in the testbench and drive design logic from clock edges. - Relying on initial values for behaviour. A signal's
:= '0'initialiser may hold in simulation but is not a reset in hardware; use an explicit reset. - Ignoring synthesis warnings. "Inferred latch", "signal has no driver", "delay ignored" are the synthesizer telling you the two views have diverged. Read them.
6. Summary & next step
The same VHDL is read two ways: a simulator runs all of it over time to check behaviour, and a synthesizer maps only the synthesizable subset to gates. Delays, file I/O, and unbounded waits are testbench-only — they make simulation convenient but have no hardware. So "it simulates correctly" is a claim about the model, and "it synthesizes to correct hardware" is a separate claim about the gates; disciplined RTL keeps the two aligned by staying inside the subset.
With the foundations' mental model complete, the next lesson puts it all together into a single, complete first design — interface, implementation, the hardware it becomes, and how a testbench would exercise it.