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
77
78
79
80
81
82
83
84
85
86
87
88
use std::fmt::Debug;

/// Fundamentally a Clock signal in RustHDL is simply a transparent wrapper around a boolean
/// valued signal.  So it could be thought of as a simple 1-bit wide signal.  However, semantically,
/// clocks are rarely treated like other signals, and typically connect only to dedicated clock
/// ports on synchronous logic (like [DFF] or [RAM]).
#[repr(transparent)]
#[derive(Clone, Copy, Default, PartialEq, Eq, Hash, Debug)]
pub struct Clock {
    /// The clock signal itself.  Available using this field of the struct.
    pub clk: bool,
}

/// The number of nanoseconds per femtosecond.
pub const NANOS_PER_FEMTO: f64 = 1_000_000.0;

/// Convert a frequency in Hz to a period in femtoseconds.
pub fn freq_hz_to_period_femto(freq: f64) -> f64 {
    (1.0e15 / freq).round()
}

#[test]
fn test_freq_to_period_mapping() {
    assert_eq!(freq_hz_to_period_femto(1.0), 1.0e15)
}

impl std::ops::Not for Clock {
    type Output = Clock;

    fn not(self) -> Self::Output {
        Clock { clk: !self.clk }
    }
}

impl From<bool> for Clock {
    fn from(x: bool) -> Clock {
        Clock { clk: x }
    }
}

/// The [clock!] macro is used to connect a set of devices to a common clock.
/// The macro takes a variable number of arguments:
///  * `self` - the struct containing the items to connect, normally just `self`
///  * `clock` - the name of the field of the struct that holds the clock source
///  * `subs` - the set of fields that should be clocked with `clock`.
/// Note that the macro assumes that the sub-circuits being clocked all have clock inputs
/// named `clock`.
///
/// For example:
/// ```
/// use rust_hdl_core::prelude::*;
///
/// #[derive(LogicBlock)]
/// pub struct SubWidget {
///    pub clock: Signal<In, Clock>,
/// }
///
/// # impl Logic for SubWidget {
/// #   #[hdl_gen]
/// #   fn update(&mut self) {}
/// # }
///
/// #[derive(LogicBlock)]
/// pub struct Widget {
///    pub clock: Signal<In, Clock>,
///    pub dff_1: SubWidget,
///    pub dff_2: SubWidget,
/// }
///
/// impl Logic for Widget {
///    #[hdl_gen]
///    fn update(&mut self) {
///        // This is equivalent to:
///        // self.dff_1.clock.next = self.clock.val();
///        // self.dff_2.clock.next = self.clock.val();
///        clock!(self, clock, dff_1, dff_2);
///    }
/// }
/// ```
///
/// When you have many [DFF]s or several complex sub-circuits, the `clock!` macro can make it
/// easier to read the source code.
#[macro_export]
macro_rules! clock {
    ($self: ident, $clock: ident, $($subs: ident), +) => {
        $($self.$subs.clock.next = $self.$clock.val());+;
    }
}