Cycle-based simulation evaluates a synchronous digital design once per clock cycle, computing the values that registers will capture at the clock edge and ignoring everything that happens in between. It skips gate delays, glitches and intermediate events, so it runs much faster than event-driven simulation, at the cost of requiring a clean synchronous design and leaving timing to separate static timing analysis. It is one of the main answers to the growing gap between design size and the simulation time needed to verify it.
Key takeaways
- Cycle-based simulators compute register inputs once per clock period, not every time a signal toggles.
- They rely on the design being synchronous, and on rank-ordering (levelisation) so each logic element is evaluated exactly once per cycle.
- Circuit delays are ignored and the value set is small, usually two to four states such as {0, 1, X, Z}.
- Timing is checked by a separate static timing analysis tool, not by the simulator.
- Modern open-source and commercial tools that compile RTL into cycle-based models, such as Verilator, follow the same principles.
Why simulation speed keeps getting harder
New design starts continue to grow in gate count, and the amount of CPU time required to simulate these designs tends to grow faster than the gate count itself, which implies a growing need for simulation speed. A simple example helps to shed light on this.
Suppose a circuit has n functions and that, in the worst case, each function interacts with all of the others. Ignoring for the moment the complexity of the interactions, there are n × (n − 1)/2 potential interactions between the n functions. In the worst case, the number of interactions therefore grows in proportion to the square of the number of functions. Handshaking protocols between functions also become more complex, and internal status and mode control registers act as extensions of the device I/O pins.
| Functions (n) | Potential interactions n(n − 1)/2 |
|---|---|
| 10 | 45 |
| 100 | 4,950 |
| 1,000 | 499,500 |
Verifying the growing number of interactions needs more stimuli. At the same time, the growing number of gates and functions generates more events that must be evaluated in each clock cycle. More functionality multiplied by more stimuli means CPU time grows far faster than the design, a growth often described as exponential, although the worst-case interaction count above is quadratic. The consequence is that it becomes harder to create and simulate enough stimuli to verify design correctness, and design errors are more likely to escape detection until after tape-out, when finding them forces another expensive pass through the design cycle.
How cycle-based simulation works
Cycle simulation evaluates logic elements and functions across clock cycle boundaries without regard to intermediate values. Its purpose is to evaluate input stimuli as rapidly as possible. The main ideas are:
- Synchronous design is required. Every register is clocked by a known clock, so the simulator knows exactly when values can change, and every possible speed-up technique can be applied.
- Rank-ordering (levelisation). The combinational logic between registers is sorted so that every element is evaluated after all of its inputs. Each element then needs to be evaluated only once per clock period.
- No circuit delays. The simulator does not model gate or wire delays, so there are no glitches or races to track inside a cycle.
- A small value set. The number of logic values is usually limited to three or four, {0, 1, X, Z}, and many tools run purely two-state (0 and 1) for speed.
- Compact internal form. The circuit may be represented internally in forms such as binary decision diagrams (BDDs) or compiled machine code, so intermediate values are not visible at all.
To ensure that a circuit operates at its intended speed when fabricated, circuit delays are measured by timing analysis programs written specifically for that purpose, which run independently of simulation.
Event-driven versus cycle-based
| Aspect | Event-driven simulation | Cycle-based simulation |
|---|---|---|
| When logic is evaluated | Every time an input changes (an event) | Once per clock cycle, in rank order |
| Delays | Gate and wire delays can be modelled | Ignored |
| Glitches and races | Visible | Not visible |
| Value set | Usually four-state or more (strengths) | Two to four states |
| Design style supported | Any, including asynchronous logic and #delays | Synchronous designs only |
| Speed | Slower, proportional to activity | Faster, often by a large factor |
| Timing sign-off | Possible with back-annotated delays | Needs separate static timing analysis |
A small worked example
Consider an 8-bit register fed by an adder. In one clock cycle the adder's inputs may change several times as different bits settle, and an event-driven simulator evaluates the adder each time. Illustratively, if the inputs produce five events in a cycle, the adder is evaluated five times. A cycle-based simulator evaluates it once, at the point in rank order where all its inputs are final, and then updates the register at the clock edge. Across millions of gates and cycles, that difference in work is where the speed comes from.
Writing RTL that suits cycle-based tools
The designer plays a role in this simulation mode by modelling circuits at the highest possible level of abstraction without losing essential details. In practice that means synchronous logic, no delays in the design, and non-blocking assignments for registers. The Verilog below is a simple accumulator written in that style.
// Synchronous, delay-free design: friendly to cycle-based simulation
module acc4 (
input wire clk,
input wire rst_n,
input wire en,
input wire [3:0] d,
output reg [7:0] sum
);
wire [7:0] next_sum = sum + {4'd0, d}; // one combinational rank
always @(posedge clk or negedge rst_n)
if (!rst_n) sum <= 8'd0;
else if (en) sum <= next_sum;
endmodule
With a testbench applying d = 1, 2, 3, 4, 5 on successive cycles, sum reads 1, 3, 6, 10 and 15. Everything the simulator needs is the value of next_sum at each rising edge; how the adder output ripples in between does not matter.
A number of methods have been developed to speed up simulation while reducing the amount of workstation memory required. Common ones are compiling the RTL into native code, two-state evaluation, removing logic whose outputs are never observed, and evaluating many test vectors in parallel using the bits of a machine word.
Where cycle-based simulation fits today
- RTL regression. Long functional regressions, booting software on a processor model, or running large random test suites.
- Open-source tools. Verilator compiles synthesisable Verilog and SystemVerilog into a cycle-based C++ or SystemC model and is widely used for fast RTL simulation.
- Hardware acceleration. Emulators and FPGA prototypes take the same synchronous, cycle-based view further by running the design in hardware.
- Not for gate-level timing simulation, asynchronous interfaces, or debugging glitches and races; event-driven simulators remain the tool for those.
Common mistakes
- Using #delays inside RTL that must also run on a cycle-based tool; the delays are ignored or rejected.
- Relying on simulation to catch timing problems; cycle-based tools cannot see them, so static timing analysis is essential.
- Combinational loops or latches, which break rank-ordering.
- Expecting X-propagation behaviour to match a four-state event-driven simulator when the cycle-based tool runs two-state.
FAQ
Is cycle-based simulation cycle-accurate?
Yes, at the register boundaries. Register values at every clock edge match what a correct synchronous design would produce; what is lost is the detail within the cycle.
Can a cycle-based simulator handle multiple clocks?
Most can, if the clocks are known and the domains are synchronous to defined edges. Asynchronous crossings need care and are usually checked with separate CDC tools.
Why are only three or four logic values used?
Fewer values mean simpler, faster evaluation. Signal strengths and many-valued logic are only needed to model detailed transistor or bus behaviour, which cycle-based tools do not attempt.
How do I check timing if the simulator ignores delays?
Use static timing analysis, which checks every path against setup and hold requirements without needing stimulus.
Contribute to this Article: onenanometer[at]gmail.com
Please leave a comment.


Your comments will be moderated before it appears here.