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 cratevcd_to_svg;
use embed_doc_image;
///
/// ## Blinky!
///
///The definitive example in FPGA firmware land is a simple LED blinker. This typically
///involves a clock that is fed to the FPGA with a pre-defined frequency, and an output
///signal that can control an LED. Because we don't know what FPGA we are using, we will
///do this in simulation first. We want a blink that is 250 msec long every second, and
/// our clock speed is (a comically slow) 10kHz. Here is a minimal working Blinky! example:
///
///```rust
///use std::time::Duration;
///use rust_hdl::core::prelude::*;
///use rust_hdl::docs::vcd2svg::vcd_to_svg;
///use rust_hdl::widgets::prelude::*;
///
///const CLOCK_SPEED_HZ : u64 = 10_000;
///
///
///#[derive(LogicBlock)]
///struct Blinky {
/// pub clock: Signal<In, Clock>,
/// pulser: Pulser,
/// pub led: Signal<Out, Bit>,
///}
///
///impl Default for Blinky {
/// fn default() -> Self {
/// Self {
/// clock: Default::default(),
/// pulser: Pulser::new(CLOCK_SPEED_HZ, 1.0, Duration::from_millis(250)),
/// led: Default::default(),
/// }
/// }
///}
///
///impl Logic for Blinky {
/// #[hdl_gen]
/// fn update(&mut self) {
/// self.pulser.clock.next = self.clock.val();
/// self.pulser.enable.next = true.into();
/// self.led.next = self.pulser.pulse.val();
/// }
///}
///
///let mut sim = simple_sim!(Blinky, clock, CLOCK_SPEED_HZ, ep, {
/// let mut x = ep.init()?;
/// wait_clock_cycles!(ep, clock, x, 4*CLOCK_SPEED_HZ);
/// ep.done(x)
///});
///
///let mut uut = Blinky::default();
///uut.connect_all();
///sim.run_to_file(Box::new(uut), 5*SIMULATION_TIME_ONE_SECOND, "/tmp/blinky.vcd").unwrap();
///vcd_to_svg("/tmp/blinky.vcd","images/blinky_all.svg",&["uut.clock", "uut.led"], 0, 4_000_000_000_000).unwrap();
///vcd_to_svg("/tmp/blinky.vcd","images/blinky_pulse.svg",&["uut.clock", "uut.led"], 900_000_000_000, 1_500_000_000_000).unwrap();
///```
///Running the above (a release run is highly recommended) will generate a `vcd` file (which is
/// a trace file for FPGAs and hardware in general). You can open this using e.g., `gtkwave`.
/// Here you will see (with some manipulation of the UI)
///
/// ![Full Simulation Time][full_sim_time]
///
/// And a zoom in shows the 250 msec pulse.
///
/// ![Pulse detail][pulse_detail]
///
;