x393  1.0
FPGAcodeforElphelNC393camera
cmprs_afi_mux.v
Go to the documentation of this file.
1 
39 `timescale 1ns/1ps
40 
41 module cmprs_afi_mux#(
42  parameter CMPRS_AFIMUX_ADDR= 'h140, //TODO: assign valid address
43  parameter CMPRS_AFIMUX_MASK= 'h7f0,
44  parameter CMPRS_AFIMUX_EN= 'h0, // enables (global and per-channel)
45 /*
46 used 10 bits, in each pair [0] - value, [1] - set (0 - nop). [7:0] - per-channel control, [9:8] - common enable/disable (independent)
47 */
48  parameter CMPRS_AFIMUX_RST= 'h1, // per-channel resets
49 /*
50 bits [3:0] - persistent per-channel reset (0 - run, 1 - reset)
51  */
52  parameter CMPRS_AFIMUX_MODE= 'h2, // per-channel select - which register to return as status
53 /*
54 mode == 0 - show EOF pointer, internal
55 mode == 1 - show EOF pointer, confirmed
56 mode == 2 - show current pointer, internal
57 mode == 3 - show current pointer, confirmed
58 each group of 4 bits per channel : bits [1:0] - select, bit[2] - sset (0 - nop), bit[3] - not used
59  */
60  parameter CMPRS_AFIMUX_STATUS_CNTRL= 'h4, // .. 'h7
61 /*
62  4 consecutive locations, per-channel status control
63 */
64  parameter CMPRS_AFIMUX_SA_LEN= 'h8, // .. 'hf
65 /*
66  27-bit "chunk" addresses and lengths. 1 chunk = 32 bytes, so 27 bit covers all 2^32 address range
67  8 .. 11 - per-channel start adddresses,
68  12 .. 15 - per-channel buffer lengths (will roll over to start address)
69 (0..3 - start addresses, 4..7 - lengths)
70 */
71 
72  parameter CMPRS_AFIMUX_STATUS_REG_ADDR= 'h20, //Uses 4 locations TODO: assign valid address
73  parameter CMPRS_AFIMUX_WIDTH = 26, // maximal for status: currently only works with 26)
74  parameter CMPRS_AFIMUX_CYCBITS = 3,
75  parameter AFI_MUX_BUF_LATENCY = 4'd2 // buffers read latency from fifo_ren* to fifo_rdata* valid : 2 if no register layers are used
76 `ifdef DEBUG_RING
77  ,parameter DEBUG_CMD_LATENCY = 2
78 `endif
79 
80 )(
81 // input rst,
82  input mclk, // for command/status
83  input hclk, // global clock to run axi_hp @ 150MHz, shared by all compressor channels
84  input mrst, // @posedge mclk, sync reset
85  input hrst, // @posedge xclk, sync reset
86  // programming interface
87  input [7:0] cmd_ad, // byte-serial command address/data (up to 6 bytes: AL-AH-D0-D1-D2-D3
88  input cmd_stb, // strobe (with first byte) for the command a/d
89  output [7:0] status_ad, // status address/data - up to 5 bytes: A - {seq,status[1:0]} - status[2:9] - status[10:17] - status[18:25]
90  output status_rq, // input request to send status downstream
91  input status_start, // Acknowledge of the first status packet byte (address)
92 
93  // compressor channel 0
94  output fifo_rst0, // reset FIFO (set read address to write, reset count)
95  output fifo_ren0,
96  input [63:0] fifo_rdata0,
97 // input fifo_eof0, // single rclk pulse signalling EOF
98  output eof_written0, // confirm frame written over AFI to the system memory (single hclk pulse)
99  input pre_flush0, // before last data chunk was written to FIFO
100  input fifo_flush0, // EOF, need to output all what is in FIFO (Stays active until enough data chunks are read)
101  input [7:0] fifo_count0, // number of 32-byte chunks in FIFO
102 
103  // compressor channel 1
104  output fifo_rst1, // reset FIFO (set read address to write, reset count)
105  output fifo_ren1,
106  input [63:0] fifo_rdata1,
107 // input fifo_eof1, // single rclk pulse signalling EOF
108  output eof_written1, // confirm frame written over AFI to the system memory (single hclk pulse)
109  input pre_flush1, // before last data chunk was written to FIFO
110  input fifo_flush1, // EOF, need to output all what is in FIFO (Stays active until enough data chunks are read)
111  input [7:0] fifo_count1, // number of 32-byte chunks in FIFO
112 
113  // compressor channel 2
114  output fifo_rst2, // reset FIFO (set read address to write, reset count)
115  output fifo_ren2,
116  input [63:0] fifo_rdata2,
117 // input fifo_eof2, // single rclk pulse signalling EOF
118  output eof_written2, // confirm frame written over AFI to the system memory (single hclk pulse)
119  input pre_flush2, // before last data chunk was written to FIFO
120  input fifo_flush2, // EOF, need to output all what is in FIFO (Stays active until enough data chunks are read)
121  input [7:0] fifo_count2, // number of 32-byte chunks in FIFO
122 
123  // compressor channel 3
124  output fifo_rst3, // reset FIFO (set read address to write, reset count)
125  output fifo_ren3,
126  input [63:0] fifo_rdata3,
127 // input fifo_eof3, // single rclk pulse signalling EOF
128  output eof_written3, // confirm frame written over AFI to the system memory (single hclk pulse)
129  input pre_flush3, // before last data chunk was written to FIFO
130  input fifo_flush3, // EOF, need to output all what is in FIFO (Stays active until enough data chunks are read)
131  input [7:0] fifo_count3, // number of 32-byte chunks in FIFO
132 
133  // axi_hp signals write channel
134  // write address
135  output [31:0] afi_awaddr,
136  output afi_awvalid,
137  input afi_awready, // @SuppressThisWarning VEditor unused - used FIF0 level
138  output [ 5:0] afi_awid,
139  output [ 1:0] afi_awlock,
140  output [ 3:0] afi_awcache,
141  output [ 2:0] afi_awprot,
142  output reg [ 3:0] afi_awlen,
143  output [ 1:0] afi_awsize,
144  output [ 1:0] afi_awburst,
145  output [ 3:0] afi_awqos,
146  // write data
147  output [63:0] afi_wdata,
148  output afi_wvalid,
149  input afi_wready, // @SuppressThisWarning VEditor unused - used FIF0 level
150  output [ 5:0] afi_wid,
151  output afi_wlast,
152  output [ 7:0] afi_wstrb,
153  // write response
154  input afi_bvalid,
155  output afi_bready,
156  input [ 5:0] afi_bid,
157  input [ 1:0] afi_bresp, // @SuppressThisWarning VEditor unused
158  // PL extra (non-AXI) signals
159  input [ 7:0] afi_wcount,
160  input [ 5:0] afi_wacount,
162 `ifdef DEBUG_RING
163  ,output debug_do, // output to the debug ring
164  input debug_sl, // 0 - idle, (1,0) - shift, (1,1) - load // SuppressThisWarning VEditor - not used
165  input debug_di // input from the debug ring
166 `endif
167 );
168 //`ifdef DEBUG_RING
169 // assign debug_do = debug_di; // just temporarily to short-circuit the ring
170 //`endif
171  reg en; // enable mux
172  reg en_d; // or use it to reset all channels?
173  wire en_nrst = en && ! hrst; // when hclk is not yet available
174  reg [3:0] en_chn; // per-channel enable
175 
176  wire [31:0] cmd_data;
177  wire [ 3:0] cmd_a;
178  wire cmd_we;
181 
183  wire cmd_we_en_w;
185 
186  reg [26:0] sa_len_d;
187  reg [2:0] sa_len_wa;
188  reg [3:0] rst_mclk;
189  reg [9:0] en_mclk;
190 
191  // hclk domain
192 // reg [26:0] sa_len_d;
193 // reg [2:0] sa_len_wa;
194  wire sa_len_we;
195  wire en_we;
196  wire en_rst;
197 
200  reg [3:0] ren_suspend_flush; // suspend buffer read until flush is finished
201 
202 // reg [2:0] cur_chn; // 'b0xx - none, 'b1** - ** - channel number (should match fifo_ren*)
203  reg [1:0] cur_chn; // 'b0xx - none, 'b1** - ** - channel number (should match fifo_ren*)
204  reg [31:0] left_to_eof; // number of chunks left to end of frame (one less: 3 means 4 left)
205  reg [3:0] fifo_flush_d; // fifo_flush* delayed by 1 clk (to detect rising edge
206  reg [3:0] eof_stb; // single-cycle pulse after fifo_flush is asserted
207 // reg [1:0] w64_cnt; // count 64-bit words in a chunk
208 // adjusted counters used for channel arbitration
209 // pessimistic FIFO content counter - decrements (form FIFO counter) on FIFO reads, knows nothing of writes
210  reg [35:0] counts_corr0; // registers to hold corrected (decremented currently processed ones if any) fifo count values, MSB - needs flush
211  reg [17:0] counts_corr1; // first arbitration level winning values
212  reg [8:0] counts_corr2; // second arbitration level winning values
213 
214  reg [1:0] winner1; // 2 first level arbitration winners
215  reg [1:0] winner2; // 2-bit second level arbitration winner
216  wire [1:0] pre_winner2_w; // 1 cycle ahead of winner2
217 
218 // reg [1:0] cur_chn; // Can it be the same as cur_chn?
219  wire [7:0] fifo_count0_m1 = fifo_count0 - 1;
220  wire [7:0] fifo_count1_m1 = fifo_count1 - 1;
221  wire [7:0] fifo_count2_m1 = fifo_count2 - 1;
222  wire [7:0] fifo_count3_m1 = fifo_count3 - 1;
223  // See if we need to bother - any channel needs flushing or has >= 4 of 32-byte chunks to transfer in a single AXI 16-burst 64 bit wide (latency = 4)
225  reg ready_to_start; // TBD: either idle or soon will finish the previous burst (include AFI FIFO level here too?)
226 // wire [3:0] last_chunk_w;
227  reg [3:0] busy; // TODO: adjust number of bits. During continuous run busy is deasseted for 1 clock cycle
228  wire done_burst_w; // de-asset busy
230  reg first_busy; // cycle after pre_busy_w
231  reg [3:0] pend_last; // waiting for last chunk
233 // reg [1:0] wlen32; // 2 high bits of burst len (LSB are always 2'b11)
234 
235  reg [3:0] wleft; // number of 64-bit words left to be sent - also used as awlen (valid @ awvalid)
236 // reg [2:0] chunk_inc; // how much to increment chunk pointer (1..4)
237 
238 // wire [2:0] pre_chunk_inc = (|counts_corr2[7:2])? // Would like to increment, if not roll-over
239 // 3'h4 :
240 // ({1'b0,left_to_eof[winner2 * 8 +: 2]} + 3'h1);
241 
242  // Why it has priority for |counts_corr2[7:2] ? If next frame started, it may skip EOF? Or not?
243  // it is just to pass to a channel, actual transfer size will be decided here (depending on EOF)
244  wire [1:0] pre_chunk_inc_m1 = (|counts_corr2[7:2])? // Would like to increment, if not roll-over
245  2'h3 :
246  left_to_eof[winner2 * 8 +: 2];
247 
248 
249  reg [ 3:0] reset_pointers; // per-channel - after chunk_start_hclk or chunk_len_hclk were written or explicit fifo_rst*
250 
251  wire ptr_resetting; // pointers are being reset in cmprs_afi_mux_ptr module
252 
253 
254  wire [26:0] chunk_addr;
255  reg [1:0] awvalid;
256  reg wvalid;
257  reg wlast;
258  reg [63:0] wdata; // registered data from one of the 4 buffers
259  wire wdata_en; // register enable for wdata
260  wire [1:0] wdata_sel; // source select for wdata
261  reg [3:0] fifo_ren;
262 
263  wire [26:0] chunk_ptr_rd;
264  wire [ 3:0] chunk_ptr_ra;
265 
266  // If flushing - whatever is left to EOF, otherwise corrected FIFO contents of the winner
267  wire [ 7:0] items_left = counts_corr2[8] ? left_to_eof[(winner2 * 8) +: 8] : counts_corr2[7:0];
268 
269  reg [5:0] afi_awid_r;
270  // "rollover" - roll over destination memory range
271  wire [2:0] max_wlen; // 0,1,2,3,7 (7 - not limited by rollover) - calculated by cmprs_afi_mux_ptr
272  // wants to write (want_wleft32+1) 32-byte chunks (4,3,2,1)
273  wire [1:0] want_wleft32 = (|items_left[7:2])? 2'b11 : items_left[1:0]; // want to set wleft[3:2] if not roll-over (actually "3" means 2)
274 
277 
278 
279  assign cmd_we_status_w = cmd_we && ((cmd_a & 'hc) == CMPRS_AFIMUX_STATUS_CNTRL);
280  assign cmd_we_mode_w = cmd_we && (cmd_a == CMPRS_AFIMUX_MODE);
281 
282  assign cmd_we_sa_len_w = cmd_we && ((cmd_a & 'h8) == CMPRS_AFIMUX_SA_LEN);
283  assign cmd_we_en_w = cmd_we && (cmd_a == CMPRS_AFIMUX_EN);
284  assign cmd_we_rst_w = cmd_we && (cmd_a == CMPRS_AFIMUX_RST);
285  assign afi_wvalid = afi_wvalid_w && !hrst;
286 
287 
288  // use last_chunk_w to apply a special id to waddr and wdata and watch for it during readout
289  // compose ID of channel number, frame bumber LSBs and last/not last chunk
290 /*
291  assign last_chunk_w[3:0] = {(left_to_eof[3 * 8 +: 8]==1),
292  (left_to_eof[2 * 8 +: 8]==1),
293  (left_to_eof[1 * 8 +: 8]==1),
294  (left_to_eof[0 * 8 +: 8]==1)};
295 */
297  assign done_burst_w = busy[0] && !(|wleft[3:1]); // when wleft[3:0] == 0, busy is 0
300 
301  assign pre_winner2_w = (counts_corr1[1 * 9 +: 9] > counts_corr1[0 * 9 +: 9]) ? {1'b1,winner1[1]} : {1'b0,winner1[0]};
302 
303  assign afi_awaddr = {chunk_addr,5'b0};
304  assign afi_awid = afi_awid_r; // {1'b0,wleft[3:2],last_burst_in_frame,cur_chn};
305  assign afi_awvalid = awvalid[1] && !hrst;
306 // assign afi_awlen = {wleft[3:2],2'b11};
307  assign afi_wdata = wdata;
308 // assign afi_bready = 1'b1; // always ready
309 
310 // other fixed-value AFI signals
311  assign afi_awlock = 2'h0;
312  assign afi_awcache = 4'h3;
313  assign afi_awprot = 3'h0;
314  assign afi_awsize = 2'h3;
315  assign afi_awburst = 2'h1;
316  assign afi_awqos = 4'h0;
317  assign afi_wstrb = 8'hff;
318  assign afi_wrissuecap1en = 1'b0;
319 
320 
321 
322 `ifdef DEBUG_RING
324  .SHIFT_WIDTH (64),
325  .READ_WIDTH (64),
326  .WRITE_WIDTH (32),
327  .DEBUG_CMD_LATENCY (DEBUG_CMD_LATENCY)
328  ) debug_slave_i (
329  .mclk (mclk), // input
330  .mrst (mrst), // input
331  .debug_di (debug_di), // input
332  .debug_sl (debug_sl), // input
333  .debug_do (debug_do), // output
334  .rd_data ({
335  left_to_eof[31:0],
336  24'b0,
337  fifo_count0[7:0]
338  }), // input[31:0]
339  .wr_data (), // output[31:0] - not used
340  .stb () // output - not used
341  );
342 `endif
343  always @ (posedge mclk) begin
344  if (cmd_we_sa_len_w) begin
345  sa_len_d <= cmd_data[26:0];
346  sa_len_wa <= cmd_a[2:0];
347  end
348  if (mrst) en_mclk <= 0;
349  else if (cmd_we_en_w) en_mclk <= cmd_data[9:0];
350 
351  if (mrst) rst_mclk <= ~0;
352  else if (cmd_we_rst_w) rst_mclk <= cmd_data[3:0];
353  end
354 
355  always @ (posedge hclk) begin
356  reset_pointers <= ((en && !en_d) || hrst)? 4'hf : (en_rst ? rst_mclk : 4'h0);
357  if (hrst) en_chn[0] <= 0;
358  else if (en_we && en_mclk[1]) en_chn[0] <= en_mclk[0];
359 
360  if (hrst) en_chn[1] <= 0;
361  else if (en_we && en_mclk[3]) en_chn[1] <= en_mclk[2];
362 
363  if (hrst) en_chn[2] <= 0;
364  else if (en_we && en_mclk[5]) en_chn[2] <= en_mclk[4];
365 
366  if (hrst) en_chn[3] <= 0;
367  else if (en_we && en_mclk[7]) en_chn[3] <= en_mclk[6];
368 
369  if (hrst) en <= 0;
370  else if (en_we && en_mclk[9]) en <= en_mclk[8];
371 
372  end
373 
374 
375  always @ (posedge hclk) begin
376  en_d <= en && !hrst;
377 
378  ready_to_start <= en && // ready to strta a burst
379  !afi_wacount[5] && !(&afi_wacount[4:1]) && // >=2 free
380  !afi_wcount[7] && !(&afi_wcount[6:3]); // >=8 free (4 would be enough too)
381 
383  eof_stb <= {fifo_flush3 & ~fifo_flush_d[3],
386  fifo_flush0 & ~fifo_flush_d[0]};
387 
388  // TODO: change &w64_cnt[1:0] so left_to_eof[*] will be updated earlier and valid at pre_busy_w
389  // Done, updating at the first (not last) word of 4
390  // Now seems that eof_stb[i] & fifo_ren{i} == 0
391  // Seems needs to decrement fifo_count0_m1 regardless of &wleft[1:0] - if started, will eventually decrement
392  // How to make sure that decremented value always >0?
393 // if (eof_stb[0]) left_to_eof[0 * 8 +: 8] <= fifo_count0_m1 - (fifo_ren0 & (&wleft[1:0]));
394  if (eof_stb[0]) left_to_eof[0 * 8 +: 8] <= fifo_count0_m1 - fifo_ren0;
395  else if (fifo_ren0 & (&wleft[1:0])) left_to_eof[0 * 8 +: 8] <= left_to_eof[0 * 8 +: 8] - 1;
396 
397 // if (eof_stb[1]) left_to_eof[1 * 8 +: 8] <= fifo_count1_m1 - (fifo_ren1 & (&wleft[1:0]));
398  if (eof_stb[1]) left_to_eof[1 * 8 +: 8] <= fifo_count1_m1 - fifo_ren1;
399  else if (fifo_ren1 & (&wleft[1:0])) left_to_eof[1 * 8 +: 8] <= left_to_eof[1 * 8 +: 8] - 1;
400 
401 // if (eof_stb[2]) left_to_eof[2 * 8 +: 8] <= fifo_count2_m1 - (fifo_ren2 & (&wleft[1:0]));
402  if (eof_stb[2]) left_to_eof[2 * 8 +: 8] <= fifo_count2_m1 - fifo_ren2;
403  else if (fifo_ren2 & (&wleft[1:0])) left_to_eof[2 * 8 +: 8] <= left_to_eof[2 * 8 +: 8] - 1;
404 
405 // if (eof_stb[3]) left_to_eof[3 * 8 +: 8] <= fifo_count3_m1 - (fifo_ren3 & (&wleft[1:0]));
406  if (eof_stb[3]) left_to_eof[3 * 8 +: 8] <= fifo_count3_m1 - fifo_ren3;
407  else if (fifo_ren3 & (&wleft[1:0])) left_to_eof[3 * 8 +: 8] <= left_to_eof[3 * 8 +: 8] - 1;
408 
409  // Calculate corrected values decrementing currently served channel (if any) values by 1 (latency 1 clk)
410  // During ren_suspend_flush (from pre_flush to flush) 0 - effectively disable, after flush - highest priority
411 
412  if ((fifo_count0 == 0) || !en_chn[0] ||ren_suspend_flush[0]) counts_corr0[0 * 9 +: 9] <= 0;
413  else if (fifo_ren[0]) counts_corr0[0 * 9 +: 9] <= (fifo_count0_m1 == 0)? 0 : {fifo_flush0,fifo_count0_m1};
414  else counts_corr0[0 * 9 +: 9] <= {fifo_flush0,fifo_count0};
415 
416  if ((fifo_count1 == 0) || !en_chn[1] ||ren_suspend_flush[1]) counts_corr0[1 * 9 +: 9] <= 0;
417  else if (fifo_ren[1]) counts_corr0[1 * 9 +: 9] <= (fifo_count1_m1 == 0)? 0 : {fifo_flush1,fifo_count1_m1};
418  else counts_corr0[1 * 9 +: 9] <= {fifo_flush1,fifo_count1};
419 
420  if ((fifo_count2 == 0) || !en_chn[2] ||ren_suspend_flush[2]) counts_corr0[2 * 9 +: 9] <= 0;
421  else if (fifo_ren[2]) counts_corr0[2 * 9 +: 9] <= (fifo_count2_m1 == 0)? 0 : {fifo_flush2,fifo_count2_m1};
422  else counts_corr0[2 * 9 +: 9] <= {fifo_flush2,fifo_count2};
423 
424  if ((fifo_count3 == 0) || !en_chn[3] ||ren_suspend_flush[3]) counts_corr0[3 * 9 +: 9] <= 0;
425  else if (fifo_ren[3]) counts_corr0[3 * 9 +: 9] <= (fifo_count3_m1 == 0)? 0 : {fifo_flush3,fifo_count3_m1};
426  else counts_corr0[3 * 9 +: 9] <= {fifo_flush3,fifo_count3};
427 
428  // 2-level arbitration
429  // first arbitration level (latency 2 clk)
430  if (counts_corr0[1 * 9 +: 9] > counts_corr0[0 * 9 +: 9]) begin
431  counts_corr1[0 * 9 +: 9] <= counts_corr0[1 * 9 +: 9];
432  winner1[0] <= 1;
433  end else begin
434  counts_corr1[0 * 9 +: 9] <= counts_corr0[0 * 9 +: 9];
435  winner1[0] <= 0;
436  end
437 
438  if (counts_corr0[3 * 9 +: 9] > counts_corr0[2 * 9 +: 9]) begin
439  counts_corr1[1 * 9 +: 9] <= counts_corr0[3 * 9 +: 9];
440  winner1[1] <= 1;
441  end else begin
442  counts_corr1[1 * 9 +: 9] <= counts_corr0[2 * 9 +: 9];
443  winner1[1] <= 0;
444  end
445 
446  // second arbitration level (latency 3 clk)
447  if (counts_corr1[1 * 9 +: 9] > counts_corr1[0 * 9 +: 9]) begin
448  counts_corr2 <= counts_corr1[1 * 9 +: 9];
449 // winner2 <= {1'b1,winner1[1]};
450  end else begin
451  counts_corr2 <= counts_corr1[0 * 9 +: 9];
452 // winner2 <= {1'b0,winner1[0]};
453  end
454 
456 
457  //ready_to_start need_to_bother
458  //done_burst
459  if (!en) busy <= 0;
460  else busy <= {busy[2:0], pre_busy_w | (busy[0] & ~done_burst_w)};
461 
462  if (!en) first_busy <= 0;
463  else first_busy <= pre_busy_w;
464 
465  if (!en) pend_last <= 0;
467 
468 //pend_last
469 
470  if (!en) wleft <= 0;
471 // else if (pre_busy_w) wleft <= {(max_wlen[1:0] > want_wleft32) ? want_wleft32 : max_wlen[1:0], 2'b11};
472 // wire rollover_limited_w = max_wlen[1:0] < want_wleft32;
473  else if (pre_busy_w) wleft <= {rollover_limited_w ? max_wlen[1:0]: want_wleft32, 2'b11}; // same for ==
474 
475  else if (wleft != 0) wleft <= wleft - 1;
476 
477  // if (!en) wvalid <= 0;
478  if (!en_nrst) wvalid <= 0;
479  else if (pre_busy_w) wvalid <= 1;
480  else if (wlast) wvalid <= 0; // should be after pre_busy_w as both can happen simultaneously
481 
482  if (!en) fifo_ren <= 0;
483  else if (pre_busy_w) fifo_ren <= {(winner2 == 3) ?1'b1:1'b0,
484  (winner2 == 2) ?1'b1:1'b0,
485  (winner2 == 1) ?1'b1:1'b0,
486  (winner2 == 0) ?1'b1:1'b0};
487  else if (wlast) fifo_ren <= 0;
488 
489 // new mods
490  if (!en) ren_suspend_flush <= 0;
492 
493 
494 
495  if (hrst) awvalid <= 0;
496  else awvalid <= {awvalid[0],pre_busy_w}; // no need to wait for afi_awready, will use fifo levels to enable pre_busy_w
497 
498  if (pre_busy_w) begin
499  cur_chn <= winner2;
500 // wire rollover_limited_w = max_wlen[1:0] < want_wleft32;
501 // last_burst_in_frame <= counts_corr2[8] && (left_to_eof[winner2 * 8 + 2 +: 6] == 0) && pend_last[winner2];
503  end
504 
505  wlast <= done_burst_w; // when wleft==4'h1
506 
507  // wdata register mux
509 
510 // if (pre_busy_w) chunk_inc <= (|counts_corr2[7:2])? // Would like to increment, if not roll-over
511 // 3'h4 :
512 // ({1'b0,left_to_eof[winner2 * 8 +: 2]} + 3'h1);
513 
514  if (awvalid[0]) afi_awid_r <={1'b0,wleft[3:2],last_burst_in_frame,cur_chn};
515 
516  if (awvalid[0]) afi_awlen <= {wleft[3:2],2'b11};
517 
518 
519  end
520 
521  // delay write channel controls signal to match data latency. wid bits will be optimized (6 -> 3)
523  .WIDTH(2) // 8)
524  ) afi_wx_i (
525  .clk (hclk), // input
526  .rst (!en), // input
527  .dly (AFI_MUX_BUF_LATENCY), // input[3:0] will delay by AFI_MUX_BUF_LATENCY+1 (normally 3)
528  .din ({ wvalid, wlast}), // , afi_awid_r}), // afi_awid}), // input[0:0]
529  .dout ({afi_wvalid_w, afi_wlast}) //, afi_wid}) // output[0:0]
530  );
531  localparam [3:0] AFI_MUX_BUF_LATENCYM1 = AFI_MUX_BUF_LATENCY - 1;
533  .WIDTH(9) // 3)
534  ) afi_wdata_i (
535  .clk (hclk), // input
536  .rst (!en), // input
537  .dly (AFI_MUX_BUF_LATENCYM1), // input[3:0] will delay by AFI_MUX_BUF_LATENCY+1 (normally 3)
538  .din ({wvalid, cur_chn, afi_awid_r}), //}), // input[0:0]
539  .dout ({wdata_en, wdata_sel, afi_wid}) // }) // output[0:0]
540  );
541 
543  .ADDR (CMPRS_AFIMUX_ADDR),
544  .ADDR_MASK (CMPRS_AFIMUX_MASK),
545  .NUM_CYCLES (6),
546  .ADDR_WIDTH (4),
547  .DATA_WIDTH (32)
548  ) cmd_deser_32bit_i (
549  .rst (1'b0), // rst), // input
550  .clk (mclk), // input
551  .srst (mrst), // input
552  .ad (cmd_ad), // input[7:0]
553  .stb (cmd_stb), // input
554  .addr (cmd_a), // output[3:0]
555  .data (cmd_data), // output[31:0]
556  .we (cmd_we) // output
557  );
558 
559  wire [53:0] chunk_ptr_rd01; // [0:1]; // combines 2 pointers - write one and write response one
560 
561  cmprs_afi_mux_ptr cmprs_afi_mux_ptr_i (
562  .hclk (hclk), // input
563  .sa_len_di (sa_len_d[26:0]), // input[26:0]
564  .sa_len_wa (sa_len_wa[2:0]), // input[2:0]
565  .sa_len_we (sa_len_we), // input
566  .en (en), // input
567  .reset_pointers (reset_pointers), // input[3:0]
568  .pre_busy_w (pre_busy_w), // input
569  .pre_winner_channel (pre_winner2_w), // input[1:0]
570 // .winner_channel (winner2), // input[1:0]
571  .need_to_bother (need_to_bother), // input
572 // .chunk_inc (chunk_inc), // input[2:0]
573  .chunk_inc_want_m1 (pre_chunk_inc_m1), // input[1:0] Want to increment by this (0..3) + 1, if not roll over
575  .busy (busy), // input[3:0]
576  .ptr_resetting (ptr_resetting), // output
577  .chunk_addr (chunk_addr), // output[26:0] reg
578  .chunk_ptr_ra (chunk_ptr_ra[2:0]), // input[2:0]
579  .chunk_ptr_rd (chunk_ptr_rd01[0 * 27 +: 27]), // output[26:0]
580  .max_wlen (max_wlen) // output[2:0]: msb - no rollover (>3)
581  );
582  assign chunk_ptr_rd=chunk_ptr_ra[3]?chunk_ptr_rd01[1 * 27 +: 27]:chunk_ptr_rd01[0 * 27 +: 27];
583  cmprs_afi_mux_ptr_wresp cmprs_afi_mux_ptr_wresp_i (
584  .hclk (hclk), // input
585  .length_di (sa_len_d[26:0]), // input[26:0]
586  .length_wa (sa_len_wa[1:0]), // input[1:0]
587  .length_we (sa_len_we & sa_len_wa[2]), // input
588  .en (en), // input
589  .reset_pointers (reset_pointers), // input[3:0]
590  .chunk_ptr_ra (chunk_ptr_ra[2:0]), // input[2:0]
591  .chunk_ptr_rd (chunk_ptr_rd01[1* 27 +: 27]), // output[26:0]
593  .afi_bvalid (afi_bvalid), // input
594  .afi_bready (afi_bready), // output
595  .afi_bid (afi_bid) // input[5:0]
596  );
597 
602  ) cmprs_afi_mux_status_i (
603 // .rst (rst), // input
604  .hclk (hclk), // input
605  .mclk (mclk), // input
606  .mrst (mrst), // input
607  .hrst (hrst), // input
608  .cmd_data (cmd_data[15:0]), // input[15:0]
609  .cmd_a (cmd_a[1:0]), // input[1:0]
610  .status_we (cmd_we_status_w), // input
611  .mode_we (cmd_we_mode_w), // input
612  .status_ad (status_ad), // output[7:0]
613  .status_rq (status_rq), // output
614  .status_start (status_start), // input
615  .en (en), // input
616  .chunk_ptr_ra (chunk_ptr_ra), // output[3:0] reg
617  .chunk_ptr_rd (chunk_ptr_rd[CMPRS_AFIMUX_WIDTH-1:0]) // input[25:0]
618  );
622 
623 endmodule
624 
[7:0] 147fifo_count1
114CMPRS_AFIMUX_MASK'h7f0
Definition: cmprs_afi_mux.v:43
196cmd_we_status_wwire
[ 1:0] 262pre_winner_channel
10332clk
Definition: dly_16.v:44
[ 7:0] 178afi_wstrb
247items_leftwire[7:0]
234pre_chunk_inc_m1wire[1:0]
251rollover_limited_wwire
220pre_winner2_wwire[1:0]
[WRITE_WIDTH - 1 : 0] 10318wr_data
Definition: debug_slave.v:56
219winner2reg[1:0]
209pre_flushwire[3:0]
213fifo_flush_dreg[3:0]
249max_wlenwire[2:0]
227busyreg[3:0]
217counts_corr2reg[8:0]
235reset_pointersreg[3:0]
231pend_lastreg[3:0]
113CMPRS_AFIMUX_ADDR'h140
Definition: cmprs_afi_mux.v:42
212left_to_eofreg[31:0]
117CMPRS_AFIMUX_MODE'h2
Definition: cmprs_afi_mux.v:52
215counts_corr0reg[35:0]
201sa_len_dreg[26:0]
en_rst_i pulse_cross_clock
194cmd_awire[3:0]
[CMPRS_AFIMUX_WIDTH-1:0] 352chunk_ptr_rd
210ren_suspend_flushreg[3:0]
[63:0] 150fifo_rdata2
248afi_awid_rreg[5:0]
214eof_stbreg[3:0]
[31:0] 162afi_awaddr
[ 1:0] 170afi_awsize
[ADDR_MASK2!=0?2:ADDR_MASK1!=0?1:0:0] 9935we
Definition: cmd_deser.v:60
233wleftreg[3:0]
204en_mclkreg[9:0]
[63:0] 136fifo_rdata0
Definition: cmprs_afi_mux.v:96
cmprs_afi_mux_ptr_i cmprs_afi_mux_ptr
[7:0] 131status_ad
Definition: cmprs_afi_mux.v:89
[WIDTH-1:0] 10336dout
Definition: dly_16.v:48
244fifo_renreg[3:0]
208fifo_flushwire[3:0]
221fifo_count0_m1wire[7:0]
243wdata_selwire[1:0]
[ 1:0] 171afi_awburst
192en_chnreg[3:0]
cmd_deser_32bit_i cmd_deser
afi_wdata_i dly_16
[READ_WIDTH - 1 : 0] 10317rd_data
Definition: debug_slave.v:55
223fifo_count2_m1wire[7:0]
193cmd_datawire[31:0]
[ 1:0] 182afi_bresp
[WIDTH-1:0] 10335din
Definition: dly_16.v:47
[ 2:0] 168afi_awprot
[DATA_WIDTH-1:0] 9934data
Definition: cmd_deser.v:59
198cmd_we_sa_len_wwire
[63:0] 173afi_wdata
241wdatareg[63:0]
216counts_corr1reg[17:0]
[ 5:0] 176afi_wid
218winner1reg[1:0]
[3:0] 253AFI_MUX_BUF_LATENCYM1AFI_MUX_BUF_LATENCY - 1
202sa_len_wareg[2:0]
[7:0] 154fifo_count2
[ 5:0] 181afi_bid
[7:0] 9931ad
Definition: cmd_deser.v:56
250want_wleft32wire[1:0]
245chunk_ptr_rdwire[26:0]
[ 5:0] 165afi_awid
[ADDR_WIDTH-1:0] 9933addr
Definition: cmd_deser.v:58
cmprs_afi_mux_ptr_wresp_i cmprs_afi_mux_ptr_wresp
222fifo_count1_m1wire[7:0]
cmprs_afi_mux_status_i cmprs_afi_mux_status
[7:0] 161fifo_count3
[ 3:0] 167afi_awcache
[ 7:0] 183afi_wcount
254chunk_ptr_rd01wire[53:0]
237chunk_addrwire[26:0]
[7:0] 129cmd_ad
Definition: cmprs_afi_mux.v:87
[ 3:0] 172afi_awqos
[7:0] 140fifo_count0
debug_slave_i debug_slave
119CMPRS_AFIMUX_SA_LEN'h8
Definition: cmprs_afi_mux.v:64
[63:0] 143fifo_rdata1
118CMPRS_AFIMUX_STATUS_CNTRL'h4
Definition: cmprs_afi_mux.v:60
[63:0] 157fifo_rdata3
[ 5:0] 184afi_wacount
120CMPRS_AFIMUX_STATUS_REG_ADDR'h20
Definition: cmprs_afi_mux.v:72
116CMPRS_AFIMUX_RST'h1
Definition: cmprs_afi_mux.v:48
224fifo_count3_m1wire[7:0]
211cur_chnreg[1:0]
reg [ 3:0] 169afi_awlen
[ 1:0] 166afi_awlock
reg [26:0] 268chunk_addr
232last_burst_in_framereg
10333rst
Definition: dly_16.v:45
238awvalidreg[1:0]
203rst_mclkreg[3:0]
246chunk_ptr_rawire[3:0]
[3:0] 10334dly
Definition: dly_16.v:46