Skip to main content

rustdv_sim/
clock.rs

1//! Clock generator (port of cocotb `Clock`, mapping row 24).
2
3use crate::executor::{TaskHandle, spawn_named};
4use crate::handle::{HandleBase, 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!(
17            period.steps >= 2,
18            "clock period must be at least 2 precision steps"
19        );
20        Clock { sig: *sig, period }
21    }
22
23    /// Spawn the free-running clock task (starts high, like cocotb's
24    /// default). Cancel the returned handle to stop the clock.
25    pub fn start(&self) -> TaskHandle<()> {
26        let sig = self.sig;
27        let high = self.period.steps / 2;
28        let low = self.period.steps - high;
29        spawn_named(
30            async move {
31                loop {
32                    sig.set_u64_now(1);
33                    Timer::steps(high).await;
34                    sig.set_u64_now(0);
35                    Timer::steps(low).await;
36                }
37            },
38            &format!("clock({})", sig.name()),
39        )
40    }
41}