Ferrite is a CPU microarchitectural simulator written in Rust: components
communicate only through typed, backpressured ports over links with declared
latency, systems are assembled at runtime from a pure-data ConfigGraph (no
recompilation), and every run is deterministic and testable. This repository
currently implements Milestones 0.1 ("First Light") and 0.2 (trace
fidelity + RISC-V ingestion): a deterministic single-shard event kernel
with smart ticking, a component registry, a trace frontend reading ChampSim,
STF (plain .stf and zstd-compressed .zstf — the RISC-V tooling standard),
and synthetic streams, a trace-fidelity verifier (ferrite trace-verify)
with a 100%-detection corruption-corpus gate, a one-IPC trace-driven core, a
set-associative LRU cache with MSHRs, a fixed-latency DRAM model, and a CLI
that runs a config end-to-end and dumps stats. The full architecture and
multi-year roadmap are in PLAN.md; the market rationale is in
MARKET.md; the normative engineering specs are
docs/milestone-0.md and
docs/milestone-0.2.md.
Requires Rust (edition 2021+ toolchain via rustup).
# Build everything
cargo build --release
# Run the demo: 1M synthetic instructions through core -> L1D -> DRAM
./target/release/ferrite run configs/demo-1core.jsonExpected output (stats on stdout, deterministic and byte-stable across runs; timing summary on stderr):
core0.insts 1000000
core0.loads 300083
...
l1d.hits 25088
l1d.misses 374873
...
derived.ipc 0.015887
derived.ticks 31472739500
ferrite: 1000000 insts, 62945479 cycles (31472739500 ticks) in 0.42s wall = 2.4 MIPS; ...
(The demo's 512 KiB footprint deliberately thrashes the 32 KiB L1D, so IPC is low — it exists to exercise the miss path.)
Other commands:
# List registered component models and their ports
./target/release/ferrite info # or: ferrite info mem.cache
# Generate a ChampSim-format synthetic trace file
./target/release/ferrite gen-trace --insts 100000 --seed 7 --footprint-kb 64 -o my.trace
# Run with JSON stats, also written to a file
./target/release/ferrite run configs/demo-1core.json --json --stats-out stats.json
# Verify a trace's fidelity: fingerprint + invariant checks, optionally
# compared field-by-field against a reference (exit 0 clean / 1 errors / 2 diverged)
./target/release/ferrite trace-verify my.trace --against converted.stfTraces: "trace" params (and trace-verify arguments) accept a file path —
ChampSim input_instr binary (64-byte records; decompress .xz externally
via xz -dc), STF .stf, or zstd-compressed .zstf, detected by extension
or magic — or a
synthetic:insts=N,seed=S,footprint_kb=K[,load_pct=..,store_pct=..,branch_pct=..,taken_pct=..]
spec.
The wiki at docs/wiki/ is the reference for how the
simulator works: start at the Home page for the system
overview and crate map, follow the per-crate pages for internals, use the
reference pages for the config schema, CLI,
determinism contract, and trace formats, and work through the
tutorial to make your first modification end to end.
API-level documentation is rustdoc: cargo doc --workspace --no-deps --open.
The wiki describes the current state of the simulator only — it is not a changelog or history — and it is updated in the same change as the code it describes, never bulk-updated later. The policy is normative in CONTRIBUTING.
configs/ example configs (demo-1core.json)
docs/milestone-0.md normative spec for this milestone
crates/
ferrite-time Tick (1 ps) and ClockPeriod types
ferrite-if-cpu instruction IR (TraceInst) + TraceSource trait
ferrite-if-mem memory messages (MemReq/MemResp) + line_addr
ferrite-kernel deterministic event engine: Component trait, ports/links,
credit backpressure, smart ticking, seeds (SplitMix64)
ferrite-stats flat counters behind handles; text/JSON dumps
ferrite-config ConfigGraph serde model + validation with near-miss hints
ferrite-comp model registry (linkme) + ConfigGraph -> Engine instantiation
ferrite-trace ChampSim reader/writer, STF/.zstf reader, synthetic
generator, and the fidelity module (fingerprints,
invariant checks, corruption-corpus gate)
core-1ipc `cpu.1ipc` one-IPC trace-driven core (blocking loads)
mem-cache `mem.cache` set-associative, true-LRU, MSHR cache
mem-dram `mem.dram` fixed-latency, bounded-inflight memory
ferrite-models registration hub (link_all keeps model crates linked)
ferrite-cli the `ferrite` binary: run / info / trace-verify / gen-trace
Model crates never depend on each other; only ferrite-models and
ferrite-cli link the world.
cargo test --workspace # all unit + integration + e2e testsEnd-to-end tests live in crates/ferrite-cli/tests/e2e.rs: a frozen golden
stats dump for configs/demo-1core.json and a determinism gate (two runs must
be byte-identical). The perf smoke (5M-instruction run, prints wall time and
MIPS) is ignored by default:
cargo test -p ferrite-cli --test e2e --release -- --ignored --nocaptureReference numbers (4-core host, release): ~2.4 MIPS / ~12M events/s on the miss-heavy demo topology.
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.