rust_hdl_lib_hls/
fifo.rs

1use crate::bus::{FIFOReadResponder, FIFOWriteResponder};
2use rust_hdl_lib_core::prelude::*;
3use rust_hdl_lib_widgets::prelude::*;
4
5#[derive(LogicBlock, Default)]
6pub struct SyncFIFO<T: Synth, const N: usize, const NP1: usize, const BLOCK_SIZE: u32> {
7    pub bus_write: FIFOWriteResponder<T>,
8    pub bus_read: FIFOReadResponder<T>,
9    pub clock: Signal<In, Clock>,
10    fifo: SynchronousFIFO<T, N, NP1, BLOCK_SIZE>,
11}
12
13impl<T: Synth, const N: usize, const NP1: usize, const BLOCK_SIZE: u32> Logic
14    for SyncFIFO<T, N, NP1, BLOCK_SIZE>
15{
16    #[hdl_gen]
17    fn update(&mut self) {
18        clock!(self, clock, fifo);
19        // Connect up the write side of the FIFO
20        self.fifo.data_in.next = self.bus_write.data.val();
21        self.fifo.write.next = self.bus_write.write.val();
22        self.bus_write.full.next = self.fifo.full.val();
23        self.bus_write.almost_full.next = self.fifo.almost_full.val();
24        // Connect up the read side of the FIFO
25        self.bus_read.data.next = self.fifo.data_out.val();
26        self.bus_read.empty.next = self.fifo.empty.val();
27        self.bus_read.almost_empty.next = self.fifo.almost_empty.val();
28        self.fifo.read.next = self.bus_read.read.val();
29    }
30}
31
32#[derive(LogicBlock, Default)]
33pub struct AsyncFIFO<T: Synth, const N: usize, const NP1: usize, const BLOCK_SIZE: u32> {
34    pub bus_write: FIFOWriteResponder<T>,
35    pub write_clock: Signal<In, Clock>,
36    pub bus_read: FIFOReadResponder<T>,
37    pub read_clock: Signal<In, Clock>,
38    fifo: AsynchronousFIFO<T, N, NP1, BLOCK_SIZE>,
39}
40
41impl<T: Synth, const N: usize, const NP1: usize, const BLOCK_SIZE: u32> Logic
42    for AsyncFIFO<T, N, NP1, BLOCK_SIZE>
43{
44    #[hdl_gen]
45    fn update(&mut self) {
46        // Connect up the write side of the FIFO
47        self.fifo.data_in.next = self.bus_write.data.val();
48        self.fifo.write.next = self.bus_write.write.val();
49        self.fifo.write_clock.next = self.write_clock.val();
50        self.bus_write.full.next = self.fifo.full.val();
51        self.bus_write.almost_full.next = self.fifo.almost_full.val();
52        // Connect up the read side of the FIFO
53        self.bus_read.data.next = self.fifo.data_out.val();
54        self.bus_read.empty.next = self.fifo.empty.val();
55        self.bus_read.almost_empty.next = self.fifo.almost_empty.val();
56        self.fifo.read.next = self.bus_read.read.val();
57        self.fifo.read_clock.next = self.read_clock.val();
58    }
59}
60
61#[test]
62fn test_hsl_fifo_synthesizes() {
63    let mut uut = AsyncFIFO::<Bits<8>, 6, 7, 1>::default();
64    uut.connect_all();
65    let vlog = generate_verilog(&uut);
66    yosys_validate("hsl_fifo", &vlog).unwrap();
67}
68
69#[test]
70fn test_hsl_sync_fifo_synthesizes() {
71    let mut uut = SyncFIFO::<Bits<8>, 6, 7, 1>::default();
72    uut.connect_all();
73    let vlog = generate_verilog(&uut);
74    yosys_validate("hsl_sync_fifo", &vlog).unwrap();
75}