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
use crate::core::prelude::*;
use crate::widgets::shot::Shot;
use crate::widgets::strobe::Strobe;
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) {
self.strobe.clock.next = self.clock.val();
self.shot.clock.next = self.clock.val();
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.clock.connect();
uut.enable.connect();
uut.connect_all();
let vlog = generate_verilog(&uut);
println!("{}", vlog);
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(())
});
let mut uut = Pulser::new(KHZ10, 100.0, Duration::from_millis(100));
uut.clock.connect();
uut.enable.connect();
uut.connect_all();
sim.run_traced(
Box::new(uut),
1_000_000,
std::fs::File::create(("/tmp/pulser.vcd")).unwrap(),
)
.unwrap();
}