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
use rust_hdl_core::prelude::*;

use crate::{dff::DFF, dff_setup};

#[derive(LogicBlock)]
pub struct EdgeDetector {
    pub input_signal: Signal<In, Bit>,
    pub edge_signal: Signal<Out, Bit>,
    pub clock: Signal<In, Clock>,
    prev: DFF<Bit>,
    current: DFF<Bit>,
    is_rising: Constant<Bit>,
}

impl EdgeDetector {
    pub fn new(is_rising: bool) -> Self {
        Self {
            input_signal: Default::default(),
            edge_signal: Default::default(),
            clock: Default::default(),
            prev: Default::default(),
            current: Default::default(),
            is_rising: Constant::new(is_rising),
        }
    }
}

impl Logic for EdgeDetector {
    #[hdl_gen]
    fn update(&mut self) {
        dff_setup!(self, clock, prev, current);
        self.prev.d.next = self.current.q.val();
        self.current.d.next = self.is_rising.val() ^ self.input_signal.val();
        self.edge_signal.next = !self.current.q.val() & self.prev.q.val();
    }
}

#[test]
fn test_edge_detector_synthesizes() {
    let mut uut = EdgeDetector::new(false);
    uut.connect_all();
    yosys_validate("edge", &generate_verilog(&uut)).unwrap();
}