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
use super::ddr_fifo::DDRFIFO;
use super::mcb_if::MCBInterface1GDDR2;
use crate::bsp::ok_core::prelude::*;
use crate::core::prelude::*;
use crate::widgets::prelude::*;
#[derive(LogicBlock)]
pub struct OpalKellyDDRBackedDownloadFIFO {
pub mcb: MCBInterface1GDDR2,
pub raw_sys_clock: Signal<In, Clock>,
pub reset: Signal<In, Bit>,
pub data_in: Signal<In, Bits<32>>,
pub write: Signal<In, Bit>,
pub full: Signal<Out, Bit>,
pub almost_full: Signal<Out, Bit>,
pub write_clock: Signal<In, Clock>,
pub ti_clk: Signal<In, Clock>,
pub ok1: Signal<In, Bits<31>>,
pub ok2: Signal<Out, Bits<17>>,
pub did_read: Signal<Out, Bit>,
ddr_fifo: DDRFIFO,
reducer: FIFOReducer<32, 16, false>,
fifo_out: SynchronousFIFO<Bits<16>, 13, 14, 512>,
o_pipe: BTPipeOut,
read_delay: DFF<Bit>,
}
impl OpalKellyDDRBackedDownloadFIFO {
pub fn new(n: u8) -> Self {
Self {
mcb: Default::default(),
raw_sys_clock: Default::default(),
reset: Default::default(),
data_in: Default::default(),
write: Default::default(),
full: Default::default(),
almost_full: Default::default(),
write_clock: Default::default(),
ti_clk: Default::default(),
ok1: Default::default(),
ok2: Default::default(),
did_read: Default::default(),
ddr_fifo: Default::default(),
reducer: Default::default(),
fifo_out: Default::default(),
o_pipe: BTPipeOut::new(n),
read_delay: Default::default(),
}
}
}
impl Logic for OpalKellyDDRBackedDownloadFIFO {
#[hdl_gen]
fn update(&mut self) {
MCBInterface1GDDR2::link(&mut self.mcb, &mut self.ddr_fifo.mcb);
self.ddr_fifo.reset.next = self.reset.val();
self.ddr_fifo.raw_sys_clock.next = self.raw_sys_clock.val();
self.fifo_out.clock.next = self.ti_clk.val();
self.reducer.clock.next = self.ti_clk.val();
self.read_delay.clk.next = self.ti_clk.val();
self.ddr_fifo.write_clock.next = self.write_clock.val();
self.ddr_fifo.read_clock.next = self.ti_clk.val();
self.ddr_fifo.data_in.next = self.data_in.val();
self.ddr_fifo.write.next = self.write.val();
self.full.next = self.ddr_fifo.full.val();
self.almost_full.next = self.ddr_fifo.almost_full.val();
self.reducer.empty.next = self.ddr_fifo.empty.val();
self.reducer.data_in.next = self.ddr_fifo.data_out.val();
self.ddr_fifo.read.next = self.reducer.read.val();
self.fifo_out.data_in.next = self.reducer.data_out.val();
self.fifo_out.write.next = self.reducer.write.val();
self.reducer.full.next = self.fifo_out.full.val();
self.fifo_out.read.next = self.read_delay.q.val();
self.read_delay.d.next = self.o_pipe.read.val();
self.did_read.next = self.o_pipe.read.val();
self.o_pipe.ready.next = !self.fifo_out.almost_empty.val();
self.o_pipe.datain.next = self.fifo_out.data_out.val();
self.o_pipe.ok1.next = self.ok1.val();
self.ok2.next = self.o_pipe.ok2.val();
}
}
#[test]
fn test_ddr_download_fifo_gen() {
let ddr = OpalKellyDDRBackedDownloadFIFO::new(0xA0);
let vlog = generate_verilog_unchecked(&ddr);
println!("{}", vlog);
}