rust_hdl_widgets/
pulser.rs

1use crate::shot::Shot;
2use crate::strobe::Strobe;
3use rust_hdl_core::prelude::*;
4use std::time::Duration;
5
6#[derive(LogicBlock)]
7pub struct Pulser {
8    pub clock: Signal<In, Clock>,
9    pub enable: Signal<In, Bit>,
10    pub pulse: Signal<Out, Bit>,
11    strobe: Strobe<32>,
12    shot: Shot<32>,
13}
14
15impl Pulser {
16    pub fn new(clock_rate_hz: u64, pulse_rate_hz: f64, pulse_duration: Duration) -> Self {
17        let strobe = Strobe::new(clock_rate_hz, pulse_rate_hz);
18        let shot = Shot::new(clock_rate_hz, pulse_duration);
19        Self {
20            clock: Signal::default(),
21            enable: Signal::default(),
22            pulse: Signal::new_with_default(false),
23            strobe,
24            shot,
25        }
26    }
27}
28
29impl Logic for Pulser {
30    #[hdl_gen]
31    fn update(&mut self) {
32        clock!(self, clock, strobe, shot);
33        self.strobe.enable.next = self.enable.val();
34        self.shot.trigger.next = self.strobe.strobe.val();
35        self.pulse.next = self.shot.active.val();
36    }
37}
38
39#[test]
40fn test_pulser_synthesis() {
41    let mut uut = Pulser::new(1_000_000, 1.0, Duration::from_millis(100));
42    uut.connect_all();
43    let vlog = generate_verilog(&uut);
44    yosys_validate("pulser", &vlog).unwrap();
45}
46
47#[test]
48fn test_pulser() {
49    let mut sim = Simulation::new();
50    const KHZ10: u64 = 10_000;
51    sim.add_clock(5, |x: &mut Box<Pulser>| x.clock.next = !x.clock.val());
52    sim.add_testbench(|mut sim: Sim<Pulser>| {
53        let mut x = sim.init()?;
54        x.enable.next = true;
55        x = sim.wait(100_000, x)?;
56        sim.done(x)?;
57        Ok(())
58    });
59    sim.add_testbench(|mut sim: Sim<Pulser>| {
60        let mut x = sim.init()?;
61        for _j in 0..20 {
62            x = sim.watch(|x| x.pulse.val(), x)?;
63            for _i in 0..10 {
64                wait_clock_cycle!(sim, clock, x);
65                sim_assert!(sim, x.pulse.val(), x);
66            }
67            wait_clock_cycle!(sim, clock, x);
68            sim_assert!(sim, !x.pulse.val(), x);
69        }
70        sim.done(x)?;
71        Ok(())
72    });
73    let mut uut = Pulser::new(KHZ10, 100.0, Duration::from_millis(1));
74    uut.connect_all();
75    sim.run(Box::new(uut), 1_000_000).unwrap();
76}