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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use super::ok_pipe::BTPipeOut;
use super::ok_wire::WireOut;
use crate::core::prelude::*;
use crate::widgets::prelude::*;
declare_sync_fifo!(OKDLFIFO, Bits<16>, 8192, 256);
#[derive(LogicBlock)]
pub struct OpalKellyDownloadFIFO {
pub clock: Signal<In, Clock>,
pub data_in: Signal<In, Bits<16>>,
pub data_write: Signal<In, Bit>,
pub data_full: Signal<Out, Bit>,
pub ok1: Signal<In, Bits<31>>,
pub ok2: Signal<Out, Bits<17>>,
fifo: OKDLFIFO,
o_pipe: BTPipeOut,
delay_read: DFF<Bit>,
status_wire: WireOut,
}
impl Logic for OpalKellyDownloadFIFO {
#[hdl_gen]
fn update(&mut self) {
self.delay_read.clk.next = self.clock.val();
self.fifo.clock.next = self.clock.val();
self.o_pipe.ok1.next = self.ok1.val();
self.status_wire.ok1.next = self.ok1.val();
self.ok2.next = self.o_pipe.ok2.val() | self.status_wire.ok2.val();
self.o_pipe.datain.next = self.fifo.data_out.val();
self.o_pipe.ready.next = !self.fifo.almost_empty.val();
self.delay_read.d.next = self.o_pipe.read.val();
self.fifo.read.next = self.delay_read.q.val();
self.fifo.data_in.next = self.data_in.val();
self.fifo.write.next = self.data_write.val();
self.data_full.next = self.fifo.full.val();
self.status_wire.datain.next = bits::<16>(0xAD00_u128)
| (bit_cast::<16, 1>(self.fifo.overflow.val().into()) << 4_u32)
| (bit_cast::<16, 1>(self.fifo.full.val().into()) << 3_u32)
| (bit_cast::<16, 1>(self.fifo.almost_empty.val().into()) << 2_u32)
| (bit_cast::<16, 1>(self.fifo.empty.val().into()) << 1_u32)
| (bit_cast::<16, 1>(self.fifo.underflow.val().into()) << 0_u32);
}
}
impl OpalKellyDownloadFIFO {
pub fn new(port: u8) -> Self {
Self {
clock: Default::default(),
data_in: Default::default(),
data_write: Default::default(),
data_full: Default::default(),
ok1: Default::default(),
ok2: Default::default(),
fifo: Default::default(),
o_pipe: BTPipeOut::new(port),
delay_read: Default::default(),
status_wire: WireOut::new(0x38),
}
}
}
#[test]
fn test_okdf_synthesizes() {
let uut = OpalKellyDownloadFIFO::new(0xA0);
generate_verilog_unchecked(&uut);
}
declare_sync_fifo!(OKStageFIFO, Bits<32>, 32, 1);
#[derive(LogicBlock)]
pub struct OpalKellyDownload32FIFO {
pub clock: Signal<In, Clock>,
pub data_in: Signal<In, Bits<32>>,
pub write: Signal<In, Bit>,
pub full: Signal<Out, Bit>,
pub ok1: Signal<In, Bits<31>>,
pub ok2: Signal<Out, Bits<17>>,
upstage: OKStageFIFO,
redux: FIFOReducer<32, 16, false>,
dfifo: OpalKellyDownloadFIFO,
}
impl Logic for OpalKellyDownload32FIFO {
#[hdl_gen]
fn update(&mut self) {
self.upstage.clock.next = self.clock.val();
self.redux.clock.next = self.clock.val();
self.dfifo.clock.next = self.clock.val();
self.dfifo.ok1.next = self.ok1.val();
self.ok2.next = self.dfifo.ok2.val();
self.dfifo.data_in.next = self.redux.data_out.val();
self.dfifo.data_write.next = self.redux.write.val();
self.redux.full.next = self.dfifo.data_full.val();
self.redux.data_in.next = self.upstage.data_out.val();
self.redux.empty.next = self.upstage.empty.val();
self.upstage.read.next = self.redux.read.val();
self.upstage.data_in.next = self.data_in.val();
self.upstage.write.next = self.write.val();
self.full.next = self.upstage.full.val();
}
}
impl OpalKellyDownload32FIFO {
pub fn new(port: u8) -> Self {
Self {
clock: Default::default(),
data_in: Default::default(),
write: Default::default(),
full: Default::default(),
ok1: Default::default(),
ok2: Default::default(),
upstage: Default::default(),
redux: Default::default(),
dfifo: OpalKellyDownloadFIFO::new(port),
}
}
}