rust_hdl_widgets/
pulser.rs1use 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}