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