Skip to main content

rustdv_sim/
clock.rs

1//! Clock generator (port of cocotb `Clock`, mapping row 24).
2
3use crate::executor::{spawn_named, TaskHandle};
4use crate::handle::LogicHandle;
5use crate::time::SimDuration;
6use crate::triggers::Timer;
7
8/// `Clock::new(&dut_clk, SimDuration::ns(10)).start()`.
9pub struct Clock {
10    sig: LogicHandle,
11    period: SimDuration,
12}
13
14impl Clock {
15    pub fn new(sig: &LogicHandle, period: SimDuration) -> Clock {
16        assert!(period.steps >= 2, "clock period must be at least 2 precision steps");
17        Clock { sig: *sig, period }
18    }
19
20    /// Spawn the free-running clock task (starts high, like cocotb's
21    /// default). Cancel the returned handle to stop the clock.
22    pub fn start(&self) -> TaskHandle<()> {
23        let sig = self.sig;
24        let high = self.period.steps / 2;
25        let low = self.period.steps - high;
26        spawn_named(
27            async move {
28                loop {
29                    sig.set_u64_now(1);
30                    Timer::steps(high).await;
31                    sig.set_u64_now(0);
32                    Timer::steps(low).await;
33                }
34            },
35            &format!("clock({})", sig.name()),
36        )
37    }
38}