x393  1.0
FPGAcodeforElphelNC393camera
elastic1632.v
Go to the documentation of this file.
1 
26 `timescale 1ns/1ps
27 
28 module elastic1632#(
29  parameter DEPTH_LOG2 = 4, // => 16 total rows x16 is for free in Xilinx, but keep it asymmetrical to reduce
30  // latency
31  parameter OFFSET = 7 // 5 // distance between read and write pointers, = wr_ptr - rd_ptr
32 )(
33  input wclk,
34  input rclk,
35 
36  input isaligned_in,
37  input [1:0] charisk_in,
38  input [1:0] notintable_in,
39  input [1:0] disperror_in,
40  input [15:0] data_in,
41 
42  output isaligned_out,
43  output reg [3:0] charisk_out,
44  output reg [3:0] notintable_out,
45  output reg [3:0] disperror_out,
46  output reg [31:0] data_out,
47 
48 // status outputs, just in case
49  output full,
50  output empty
51 
52 );
53 localparam ALIGN_PRIM = 32'h7B4A4ABC;
54 localparam FIFO_DEPTH = 1 << DEPTH_LOG2;
55 localparam CORR_OFFSET = OFFSET - 0;
56 
57 reg [15:0] data_in_r;
58 reg [1:0] charisk_in_r;
59 reg [1:0] notintable_in_r;
60 reg [1:0] disperror_in_r;
61 reg aligned32_in_r; // input data is word-aligned and got ALIGNp
62 reg msb_in_r; // input contains MSB
64 reg [DEPTH_LOG2:0] waddr;
65 wire [DEPTH_LOG2-1:0] waddr_minus = waddr[DEPTH_LOG2-1:0] - 1;
68 reg [44:0] fifo_ram [0: FIFO_DEPTH -1];
69 reg [0:0] prealign_ram[0: FIFO_DEPTH -1];
70 reg [FIFO_DEPTH-1:0] fill;
71 wire [FIFO_DEPTH-1:0] fill_out;
72 wire [FIFO_DEPTH-1:0] fill_out_more; // "pessimistic"
73 wire [FIFO_DEPTH-1:0] fill_out_less; // "optimistic"
74 wire [FIFO_DEPTH-1:0] fill_1;
75 reg [2:0] aligned_rclk;
76 reg [1:0] dav_rclk; // FIFO has more than level
77 reg [1:0] dav_rclk_more; // FIFO has more than (level + 1)
78 reg [1:0] dav_rclk_less; // FIFO has more than (level - 1)
79 wire skip_rclk; // skip 1 align primitive
80 wire skip_rclk2; // skip 2 align primitives
81 //wire add_rclk; // insert 1 align primitive (to add2 - do this twice)
82 //wire add_rclk2; // skip 2 ALIGNp (just twice using add_rclk || add_rclk2_r
83 reg [1:0] add_rclk_r;
84 reg [44:0] rdata_r;
85 wire align_out = rdata_r[44];
87 // reg align_out_r;
88 reg [2:0] correct_r;
89 //wire correct = align_out && (!align_out_r || (pre_align_out_r && !correct_r[2]));
90 wire correct_stream = align_out && pre_align_out_r && !correct_r[2]; // correct during continuous align steram - by 1 only
91 wire correct_first = pre_align_out_r && !align_out; // next will be ALIGNp, may skip both
92 
94 
95 reg [1:0] full_0; // full at waddr = waddr
96 reg [1:0] full_1; // full at waddr = raddr+1
97 
98 
99 
101  ({charisk_in, charisk_in_r} == 4'h1) &&
102  ({notintable_in, notintable_in_r} == 0) &&
103  ({disperror_in, disperror_in_r} == 0);
104 `ifdef SIMULATION
105  wire [DEPTH_LOG2:0] dbg_diff = waddr-raddr_r; // SuppressThisWarning VEditor Not used, just for viewing in simulator
106  wire dbg_dav1 = dav_rclk[1]; // SuppressThisWarning VEditor Not used, just for viewing in simulator
107  wire dbg_full0 = full_0[1]; // SuppressThisWarning VEditor Not used, just for viewing in simulator
108  wire dbg_full1 = full_1[1]; // SuppressThisWarning VEditor Not used, just for viewing in simulator
109  reg [31:0] dbg_di; // SuppressThisWarning VEditor Not used, just for viewing in simulator
110 
111  always @(posedge wclk) begin
112  if (msb_in_r) dbg_di<= {data_in,data_in_r};
113  end
114 `endif
115 
116 
117 genvar ii;
118 generate
119  for (ii = 0; ii < FIFO_DEPTH; ii = ii + 1)
120  begin: gen_fill_out
121  assign fill_out[ii] = fill[(ii + CORR_OFFSET ) & (FIFO_DEPTH - 1)] ^ ((ii + CORR_OFFSET ) >= FIFO_DEPTH);
122  assign fill_out_more[ii] = fill[(ii + CORR_OFFSET + 1) & (FIFO_DEPTH - 1)] ^ ((ii + CORR_OFFSET + 1) >= FIFO_DEPTH);
123  assign fill_out_less[ii] = fill[(ii + CORR_OFFSET - 1) & (FIFO_DEPTH - 1)] ^ ((ii + CORR_OFFSET - 1) >= FIFO_DEPTH);
124  assign fill_1[ii] = fill[(ii + 1) & (FIFO_DEPTH - 1)] ^ ((ii + 1) >= FIFO_DEPTH);
125  end
126 endgenerate
127 
128 // FIFO write clock domain - read data synchronous, 150MHz for SATA2
129 always @(posedge wclk) begin
130  data_in_r <= data_in;
134 
135  if (!isaligned_in) aligned32_in_r <= 0;
136  else if (is_alignp_w) aligned32_in_r <= 1;
137 
138  if (!aligned32_in_r && !is_alignp_w) msb_in_r <= 1;
139  else msb_in_r <= !msb_in_r;
140 
142 
143  if (!aligned32_in_r) waddr <= 0;
144  else if (inc_waddr) waddr <= waddr + 1;
145 
146  // write will be active before aligned32_in_r too
153 
154  if (!aligned32_in_r) fill <= 0;
155  else if (msb_in_r) fill <={fill[FIFO_DEPTH-2:0],~waddr[DEPTH_LOG2]};
156 
157 end
158 
159 // FIFO read clock domain - system synchronous, 75MHz for SATA2
160  localparam [DEPTH_LOG2:0] SIZED0 = 0;
161  localparam [DEPTH_LOG2:0] SIZED1 = 1;
162  localparam [DEPTH_LOG2:0] SIZED2 = 2;
163  localparam [DEPTH_LOG2:0] SIZED3 = 3;
164  assign raddr_w = aligned_rclk[1]? ( raddr_r + (add_rclk_r[0]? SIZED0 : (skip_rclk ? (skip_rclk2 ? SIZED3 : SIZED2) : SIZED1))) : SIZED0;
165 
166 always @(posedge rclk) begin
167 
168  raddr_r <= raddr_w;
169 
171 
173 
174  if (!aligned32_in_r) aligned_rclk <= 0;
175  else aligned_rclk <= {aligned_rclk[1:0],fill[OFFSET-2] | aligned_rclk[0]};
176 
177  if (!aligned32_in_r) dav_rclk <= 0;
179 
180  if (!aligned32_in_r) dav_rclk_more <= 0;
182 
183  if (!aligned32_in_r) dav_rclk_less <= 0;
185 
186 
187  if (!aligned32_in_r) full_0 <= 1;
188  else full_0 <= {full_0[0], fill[raddr_r[DEPTH_LOG2-1:0]] ^ raddr_r[DEPTH_LOG2]};
189 
190  if (!aligned32_in_r) full_1 <= 1;
191  else full_1 <= {full_1[0], fill_1[raddr_r[DEPTH_LOG2-1:0]] ^ raddr_r[DEPTH_LOG2]};
192 
193  disperror_out <= rdata_r[43:40];
194  notintable_out <= rdata_r[39:36];
195  charisk_out <= rdata_r[35:32];
196  data_out <= rdata_r[31: 0];
197 
198 // align_out_r <= align_out;
199 
200  if (correct || !aligned_rclk) correct_r <= ~0;
201  else correct_r <= correct_r << 1;
202 
203 // add_rclk2_r <=add_rclk2;
204  if (correct_first) add_rclk_r <= {~dav_rclk_less[1], ~dav_rclk[1]};
205  else if (correct_stream) add_rclk_r <= {1'b0, ~dav_rclk[1]};
206  else add_rclk_r <= add_rclk_r >> 1;
207 
208 end
209 
210 //assign skip_rclk = correct && dav_rclk[1];
211 //assign add_rclk = correct && !dav_rclk[1];
212 assign skip_rclk = correct && dav_rclk[1];
213 assign skip_rclk2 = correct_first && dav_rclk_more[1];
214 
215 //assign add_rclk = correct && !dav_rclk[1];
216 //assign add_rclk2 = correct_first && !dav_rclk_less[1];
217 
218 assign isaligned_out = aligned_rclk[2];
219 assign full = aligned_rclk && full_1[1] && !full_0[1];
220 assign empty = aligned_rclk && !full_1[1] && full_0[1];
221 endmodule
222 
223 
14692aligned_rclkreg[2:0]
Definition: elastic1632.v:75
reg [3:0] 14666notintable_out
Definition: elastic1632.v:44
14695dav_rclk_lessreg[1:0]
Definition: elastic1632.v:78
14697skip_rclk2wire
Definition: elastic1632.v:80
[1:0] 14661notintable_in
Definition: elastic1632.v:38
[DEPTH_LOG2:0] 14711SIZED22
Definition: elastic1632.v:153
[0:FIFO_DEPTH-1] 14685fifo_ramreg[44:0]
Definition: elastic1632.v:68
14678aligned32_in_rreg
Definition: elastic1632.v:61
14676notintable_in_rreg[1:0]
Definition: elastic1632.v:59
14679msb_in_rreg
Definition: elastic1632.v:62
[15:0] 14663data_in
Definition: elastic1632.v:40
14703correct_streamwire
Definition: elastic1632.v:90
14698add_rclk_rreg[1:0]
Definition: elastic1632.v:83
14674data_in_rreg[15:0]
Definition: elastic1632.v:57
[DEPTH_LOG2:0] 14709SIZED00
Definition: elastic1632.v:151
14700align_outwire
Definition: elastic1632.v:85
14702correct_rreg[2:0]
Definition: elastic1632.v:88
14681waddrreg[DEPTH_LOG2:0]
Definition: elastic1632.v:64
14704correct_firstwire
Definition: elastic1632.v:91
reg [31:0] 14668data_out
Definition: elastic1632.v:46
14694dav_rclk_morereg[1:0]
Definition: elastic1632.v:77
14696skip_rclkwire
Definition: elastic1632.v:79
14705correctwire
Definition: elastic1632.v:93
14675charisk_in_rreg[1:0]
Definition: elastic1632.v:58
[0:FIFO_DEPTH-1] 14686prealign_ramreg[0:0]
Definition: elastic1632.v:69
14701pre_align_out_rreg
Definition: elastic1632.v:86
14699rdata_rreg[44:0]
Definition: elastic1632.v:84
reg [3:0] 14665charisk_out
Definition: elastic1632.v:43
14693dav_rclkreg[1:0]
Definition: elastic1632.v:76
14706full_0reg[1:0]
Definition: elastic1632.v:95
reg [3:0] 14667disperror_out
Definition: elastic1632.v:45
[DEPTH_LOG2:0] 14712SIZED33
Definition: elastic1632.v:154
14671ALIGN_PRIM32'h7B4A4ABC
Definition: elastic1632.v:53
14689fill_out_morewire[FIFO_DEPTH-1:0]
Definition: elastic1632.v:72
[1:0] 14662disperror_in
Definition: elastic1632.v:39
[DEPTH_LOG2:0] 14710SIZED11
Definition: elastic1632.v:152
14707full_1reg[1:0]
Definition: elastic1632.v:96
14672FIFO_DEPTH1 << DEPTH_LOG2
Definition: elastic1632.v:54
14677disperror_in_rreg[1:0]
Definition: elastic1632.v:60
14688fill_outwire[FIFO_DEPTH-1:0]
Definition: elastic1632.v:71
14673CORR_OFFSETOFFSET - 0
Definition: elastic1632.v:55
14683raddr_wwire[DEPTH_LOG2:0]
Definition: elastic1632.v:66
14691fill_1wire[FIFO_DEPTH-1:0]
Definition: elastic1632.v:74
14690fill_out_lesswire[FIFO_DEPTH-1:0]
Definition: elastic1632.v:73
[1:0] 14660charisk_in
Definition: elastic1632.v:37
14682waddr_minuswire[DEPTH_LOG2-1:0]
Definition: elastic1632.v:65
14708is_alignp_wwire
Definition: elastic1632.v:100
14684raddr_rreg[DEPTH_LOG2:0]
Definition: elastic1632.v:67
14687fillreg[FIFO_DEPTH-1:0]
Definition: elastic1632.v:70
14680inc_waddrreg
Definition: elastic1632.v:63