Skip to main content

rhdl_ed25519_fast_core/
simulation.rs

1//! Host-only, constant-memory cycle simulation without waveform recording.
2//!
3//! RHDL's `run_fn` records trace pages, which is useful for waveforms but costly
4//! for throughput experiments. This driver uses the **same** `Synchronous::sim`
5//! hardware transitions with tracing disabled. It is not a cryptographic model
6//! or a replacement for RTL simulation. One [`CycleSim::tick`] is one rising edge.
7
8use rhdl::prelude::*;
9
10/// A native RHDL simulator with no per-cycle history allocation.
11pub struct CycleSim<C: Synchronous> {
12    circuit: C,
13    state: C::S,
14    cycles: u64,
15}
16
17impl<C: Synchronous> CycleSim<C> {
18    /// Construct a simulator and apply one synchronous reset edge.
19    pub fn new(circuit: C) -> Self {
20        let state = circuit.init();
21        let mut sim = Self {
22            circuit,
23            state,
24            cycles: 0,
25        };
26        sim.edge(C::I::dont_care(), true);
27        sim
28    }
29
30    fn edge(&mut self, input: C::I, reset_high: bool) -> C::O {
31        for level in [false, true] {
32            let cr = rhdl::core::clock_reset(
33                rhdl::core::clock::clock(level),
34                rhdl::core::types::reset::reset(reset_high),
35            );
36            let output = self.circuit.sim(cr, input, &mut self.state);
37            if level {
38                return output;
39            }
40        }
41        unreachable!()
42    }
43
44    /// Advance one clock cycle; inputs must obey the circuit's ready/valid rules.
45    pub fn tick(&mut self, input: C::I) -> C::O {
46        self.cycles += 1;
47        self.edge(input, false)
48    }
49
50    /// Number of non-reset rising edges simulated so far.
51    pub fn cycles(&self) -> u64 {
52        self.cycles
53    }
54}