What 'cycle-accurate' actually means (and why you almost never need it)

Post a virtual-board run and count how many replies it takes before someone shows up with: "sure, but is it cycle-accurate?"
It's not usually a question. It's a dismissal wearing a question mark. The implication is that if the simulator isn't cycle-accurate, whatever it just caught doesn't count.
Cycle-accurate simulation is real. It has a precise definition. Almost everybody demanding it in your replies isn't actually asking for it. And "just flash the real board" isn't free either — HIL benches don't scale to how fast agents can now generate test runs.
The same move already happened with the word "simulation" itself. A well-known embedded consultant posted recently that most engineers get simulation wrong: real simulation means decoupling your business logic from the hardware and running it on your host machine. Firing up QEMU or Renode to model a whole microcontroller is "emulation," not simulation, and therefore beside the point.1 That's a real distinction and a fine argument for testable architecture. It's also a category reshuffle that lets you dismiss a whole class of tooling without engaging with what it actually catches.
"Is it cycle-accurate" is the same move with a scarier-sounding word. Let's define the word properly, because it has a real definition, and then figure out how often you actually need what it names.
The three tiers of embedded simulator accuracy
Embedded simulator accuracy isn't one dial. It's three different claims:
Behavioral / functional accuracy. Does the program produce the right outputs for the right inputs? No timing claim at all — gem5's own tutorial material describes functional simulation as executing programs correctly, "usually no timing information," used to check that a compiler or an instruction implementation is correct in the first place.2 This is what you want when you're asking "did my firmware do the thing." It's also where real divergence shows up before anyone's talking about clocks: the same STM32 firmware booted clean on Renode and crashed instantly on QEMU, no cycle count needed to catch that.
Instruction accuracy. Same as above, plus a rough notion of how long things took — usually derived from instruction count, not from modeling a pipeline. Renode's time framework is a clean example: it advances virtual time in units tied to a configured MIPS rate, so a CPU rated at 1 MIPS executes exactly one instruction per virtual microsecond.3 That gets you relative ordering and ballpark timing. It does not get you the exact cycle a bus stall added.
Cycle accuracy. This is where instruction-accurate vs. cycle-accurate actually splits: the simulator's internal state changes in lockstep with the real hardware's clock, cycle for cycle — pipeline stages, cache fills, bus arbitration, wait states, all of it. This is the tier people are actually invoking when they use the word, whether they know it or not.
Here's the part that makes the objection funnier than it thinks it is: gem5, the tool the computer-architecture research world treats as the serious cycle-level simulator, doesn't claim to be cycle-accurate either. Its own maintainers draw the line explicitly — gem5 is "cycle-level," which "models the system cycle-by-cycle" and can be "quite accurate," but is "not the exact same cycle-by-cycle as the ASIC." True cycle accuracy, in their own slide, means RTL: register-transfer-level, the actual hardware description, "the same in the model and in an ASIC."2 A UC Davis architecture-lab write-up says the quiet part out loud: "gem5 is only cycle-level, not cycle-accurate."4 If the field's reference simulator for cycle-level work isn't cycle-accurate by the term's own definition, the guy in your replies almost certainly isn't asking for cycle accuracy either. He's asking for you to be embarrassed.
There's a reason RTL sits at the top. A SiFive forum thread on RISC-V simulators puts the practical requirement plainly: for actual cycle accuracy you need the RTL for the specific design, run through a hardware simulator like Verilator, because different implementations of the same ISA take different numbers of cycles for the same instruction — an instruction-set simulator can't know that without a hardware model to match.5 Arm's own materials frame it as a deliberate trade-off, not a free upgrade: cycle-accurate models buy 100% confidence in timing but cost you RTL availability, execution speed, and validation effort — which is exactly why Arm sells both "Fast Models" (fast, not cycle-accurate) and RTL-derived "Cycle Accurate" models as separate products for separate jobs.6

What bug classes actually need which tier
This is the part that matters. Most firmware bugs don't live in the cycle-accurate tier. Some genuinely do.
| Bug class | Example | Accuracy tier actually needed |
|---|---|---|
| Missing/wrong init sequence | Peripheral clock never enabled before the register write | Behavioral |
| State machine logic | Handshake never reaches its exit state, firmware hangs forever | Behavioral |
| Protocol sequencing | I²C start/stop/ack issued out of order | Behavioral |
| Peripheral mode misconfiguration | DMA channel pointed at the wrong buffer | Behavioral |
| RTOS scheduling / priority bugs | Low-priority task starves a higher one | Behavioral / instruction-accurate (ordering matters, exact cycles don't) |
| Soft real-time budgets | "Is this ISR roughly within budget" | Instruction-accurate |
| Bit-banged protocol timing | Software SPI/I²C/1-Wire timed by delay loops and NOP counts | Cycle-accurate |
| Cache/DMA memory-ordering races | Stale cache line read after a DMA write lands | Cycle-accurate |
| Hard real-time WCET sign-off | Certifying worst-case execution time against a safety deadline | Cycle-accurate (RTL) |
When do you actually need cycle-accurate simulation?
Concede the real cases.
Bit-banging is the textbook one. When there's no UART peripheral and the protocol timing comes entirely from counting instruction cycles in a delay loop, the cycle count is the correctness criterion — Microchip's own app note on software one-wire framing describes bit-banged timing as built from delay routines that count "a predefined number of CPU clock cycles," where the loop itself defines the bus protocol.7 A behavioral model that just executes the loop and moves on has thrown away the only thing that mattered.
Cache and DMA interaction is the other one that's genuinely a cycle problem, not a logic problem. When a DMA engine writes to memory a cached core hasn't invalidated yet, the bug isn't in your code's logic — the code is fine — it's in the exact interleaving of a cache fill, a bus transaction, and an invalidate that only shows up if the timing model knows about cache lines and bus arbitration at all. Arm's own coherency material calls out systems where "50% of debug time is spent on SW coherency issues" for exactly this reason: the bug is invisible to anything that treats memory as instantaneous and uniform.8
And if you're certifying worst-case execution time for a hard deadline — not "usually fine," but a number a safety case depends on — you're back to needing RTL, for the reason the SiFive thread gave: different silicon implementations of the same instruction set take different numbers of cycles for the same instruction, and no ISA-level model can know that without the actual hardware description.5
None of that is a strawman. All of it is real, and all of it is a small fraction of what a normal firmware verification loop spends its time on.

What most firmware verification is actually asking
Look back at that table. Driver init order, state machine logic, protocol sequencing, peripheral mode selection — that's most of what breaks in a firmware review, and none of it needs a clock tick to be modeled correctly. It needs the behavior modeled correctly: did the write happen, did the state advance, did the sequence come out in the right order.
That's the layer a byte-level UART model or an instruction-stepped CPU is built for. We've written before about what Renode and QEMU each actually model at that layer — Renode's UART peripheral, for instance, hands over bytes when firmware writes them and doesn't pretend to know about baud rate or clock gating, which is a real gap if you're validating electrical behavior and completely irrelevant if you're checking whether your driver enabled the clock before writing the baud register.9 That's not a cycle-accuracy gap. It's a scope, and it's the right scope for the bug class that dominates a normal review.
So the next time "is it cycle-accurate" shows up in your replies, ask back what specific bug they think that objection is going to catch. If the answer is a missing register write, a state machine that never advances, or a driver that enables the wrong mode — that's not a cycle-accuracy problem. It's a behavior problem, and a behavioral model already caught it, in seconds, without anyone waiting for a board.
If the answer is a bit-banged delay loop or a cache/DMA race, they're right, and you should go get RTL. That case exists. It's just not the one showing up in most replies.
Sources
Footnotes
-
Beningo, Jacob. "Most embedded engineers misunderstand simulation." LinkedIn, 2025. https://www.linkedin.com/posts/jacobbeningo_most-embedded-engineers-misunderstand-simulation-activity-7373325093281779712-D-Ml ↩
-
gem5 Tutorial, ISCA 2024, "Introduction to Simulation and gem5." Slides on functional vs. cycle-level vs. cycle-accurate RTL simulation. https://www.gem5.org/assets/files/isca2024-tutorial/01-intro.pdf ↩ ↩2
-
Renode Time Framework documentation. https://renode.readthedocs.io/en/latest/advanced/time_framework.html ↩
-
Ganjehloo, Lowe-Power, and Akella. "Integrating Cycle Accurate Chisel Models with gem5's System Simulation." UC Davis Computer Architecture, 2018. https://arch.cs.ucdavis.edu/simulation/2018/11/14/CycleAccurateChiselGem5.html ↩
-
SiFive Community Forums. "Which one is timing/cycle accurate RISC-V software simulator?" https://forums.sifive.com/t/which-one-is-timing-cycle-accurate-risc-v-software-simulator/2842 ↩ ↩2
-
Arm. "High Performance or Cycle Accuracy?" White paper. https://developer.arm.com/-/media/Arm%20Developer%20Community/PDF/Cycle%20Models/White%20Papers/High%20Performance%20or%20Cycle%20Accuracy.pdf ↩
-
Microchip Technology. "USART in One-Wire Mode," AN2658, §3.2 Bit Banging. https://onlinedocs.microchip.com/oxy/GUID-CF2C0DBC-087A-4CE7-B9C1-5E08A928CFD9-en-US-6/GUID-52ED8983-65D6-4CC9-8A08-F6384F009DDB.html ↩
-
Arm Developer Community. "Extended System Coherency: Part 1 — Cache Coherency Fundamentals." https://developer.arm.com/community/arm-community-blogs/b/architectures-and-processors-blog/posts/extended-system-coherency---part-1---cache-coherency-fundamentals ↩
-
Baldassari, François. "Cortex-M MCU Emulation with Renode." Interrupt by Memfault, March 23, 2020. https://interrupt.memfault.com/blog/intro-to-renode — see also our own Renode vs. QEMU comparison. ↩
