x393  1.0
FPGAcodeforElphelNC393camera
membridge.v
Go to the documentation of this file.
1 
39 `timescale 1ns/1ps
40 //`define MEMBRIDGE_DEBUG_READ 1
41 module membridge#(
42  parameter MEMBRIDGE_ADDR= 'h200,
43  parameter MEMBRIDGE_MASK= 'h7f0,
44  parameter MEMBRIDGE_CTRL= 'h0, // bit 0 - enable, bits[2:1]: 11 - start(continue), 01 - start and reset address
45  parameter MEMBRIDGE_STATUS_CNTRL= 'h1,
46  parameter MEMBRIDGE_LO_ADDR64= 'h2, // low address of the system memory, in 64-bit words (<<3 to get byte address)
47  parameter MEMBRIDGE_SIZE64= 'h3, // size of the system memory range (access will roll over to lo_addr
48  parameter MEMBRIDGE_START64= 'h4, // start address relative to lo_addr
49  parameter MEMBRIDGE_LEN64= 'h5, // full length of transfer in 64-bit words
50  parameter MEMBRIDGE_WIDTH64= 'h6, // frame width in 64-bit words (partial last page in each line)
51  parameter MEMBRIDGE_MODE= 'h7, // bits [3:0] - *_cache, bit [4] - cache debug
52  parameter MEMBRIDGE_STATUS_REG= 'h3b,
53  parameter FRAME_HEIGHT_BITS= 16, // Maximal frame height bits
54  parameter FRAME_WIDTH_BITS= 13
55 // ,parameter MCNTRL_SCANLINE_FRAME_PAGE_RESET= 1'b0 // reset internal page number to zero at the frame start (false - only when hard/soft reset)
56 `ifdef DEBUG_RING
57  ,parameter DEBUG_CMD_LATENCY = 2
58 `endif
59 
60 )(
61 // input rst,
62  input mrst, // @posedge mclk - sync reset
63  input hrst, // @posedge hclk - sync reset
64 
65  input mclk, // for command/status
66  input hclk, // global clock to run axi_hp @ 150MHz
67  // programming interface
68  input [7:0] cmd_ad, // byte-serial command address/data (up to 6 bytes: AL-AH-D0-D1-D2-D3
69  input cmd_stb, // strobe (with first byte) for the command a/d
70  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]
71  output status_rq, // input request to send status downstream
72  input status_start, // Acknowledge of the first status packet byte (address)
73  // mcntrl_linear_rw.v interface
74  output frame_start_chn, // input
75  output next_page_chn, // input
76  input cmd_wrmem, // @mclk - writing to DDR3 mode (0 - reading from DDR3)
77  input page_ready_chn, // output single mclk
78  input frame_done_chn, // output single mclk
79  input [FRAME_HEIGHT_BITS-1:0] line_unfinished_chn1, // output[15:0] @SuppressThisWarning VEditor unused (yet)
80  output suspend_chn1, //
81  // buffer interface, DDR3 memory read
82  input xfer_reset_page_rd, // input
83  input buf_wpage_nxt, // input
84  input buf_wr, // input
85  input [63:0] buf_wdata,
86  // buffer interface, DDR3 memory write
87  input xfer_reset_page_wr, // input @ posedge mclk
89  input buf_rd,
90  output [63:0] buf_rdata,
91  // axi_hp signals write channel
92  // write address
93  output [31:0] afi_awaddr,
94  output afi_awvalid,
95  input afi_awready, // @SuppressThisWarning VEditor unused - used FIF0 level
96  output [ 5:0] afi_awid,
97  output [ 1:0] afi_awlock,
98  output [ 3:0] afi_awcache,
99  output [ 2:0] afi_awprot,
100  output [ 3:0] afi_awlen,
101  output [ 1:0] afi_awsize,
102  output [ 1:0] afi_awburst,
103  output [ 3:0] afi_awqos,
104  // write data
105  output [63:0] afi_wdata,
106  output afi_wvalid,
107  input afi_wready, // @SuppressThisWarning VEditor unused - used FIF0 level
108  output [ 5:0] afi_wid,
109  output afi_wlast,
110  output [ 7:0] afi_wstrb,
111  // write response
112  input afi_bvalid,
113  output afi_bready,
114  input [ 5:0] afi_bid, // @SuppressThisWarning VEditor unused
115  input [ 1:0] afi_bresp, // @SuppressThisWarning VEditor unused
116  // PL extra (non-AXI) signals
117  input [ 7:0] afi_wcount,
118  input [ 5:0] afi_wacount,
120  // AXI_HP signals - read channel
121  // read address
122  output [31:0] afi_araddr,
123  output afi_arvalid,
124  input afi_arready, // @SuppressThisWarning VEditor unused - used FIF0 level
125  output [ 5:0] afi_arid,
126  output [ 1:0] afi_arlock,
127  output [ 3:0] afi_arcache,
128  output [ 2:0] afi_arprot,
129  output [ 3:0] afi_arlen,
130  output [ 1:0] afi_arsize,
131  output [ 1:0] afi_arburst,
132  output [ 3:0] afi_arqos,
133  // read data
134  input [63:0] afi_rdata,
135  input afi_rvalid,
136  output afi_rready,
137  input [ 5:0] afi_rid, // @SuppressThisWarning VEditor unused
138  input afi_rlast, // @SuppressThisWarning VEditor unused
139  input [ 1:0] afi_rresp, // @SuppressThisWarning VEditor unused
140  // PL extra (non-AXI) signals
141  input [ 7:0] afi_rcount,
142  input [ 2:0] afi_racount,
144 `ifdef DEBUG_RING
145  ,output debug_do, // output to the debug ring
146  input debug_sl, // 0 - idle, (1,0) - shift, (1,1) - load // SuppressThisWarning VEditor - not used
147  input debug_di // input from the debug ring
148 `endif
149 
150 );
151  localparam BUFWR_WE_WIDTH = 4; //2; // 4;
152  localparam SAFE_RD_BITS = 3; //2; // 3;
153  // Some constant signals:
154 
155  assign afi_awlock = 2'h0;
156 // assign afi_awcache = 4'h3;
157  assign afi_awprot = 3'h0;
158  assign afi_awsize = 2'h3;
159  assign afi_awburst = 2'h1;
160  assign afi_awqos = 4'h0;
161  assign afi_wstrb = 8'hff;
162  assign afi_wrissuecap1en = 1'b0;
163 
164  assign afi_arlock = 2'h0;
165 // assign afi_arcache = 4'h3;
166  assign afi_arprot = 3'h0;
167  assign afi_arsize = 2'h3;
168  assign afi_arburst = 2'h1;
169  assign afi_arqos = 4'h0;
170  assign afi_rdissuecap1en = 1'b0;
171 
172 
173  assign frame_start_chn = start_mclk;
174  assign suspend_chn1 = 1'b0;
175  wire [ 3:0] cmd_a; // control register address
176  wire [31:0] cmd_data; // register data
177  wire cmd_we; // register write
178 
187  reg [4:0] mode_reg_mclk;
188  reg [4:0] mode_reg;
190  assign cache_debug=mode_reg[4];
191  assign afi_awcache = mode_reg[3:0]; // 4'h3;
192  assign afi_arcache = mode_reg[3:0]; // 4'h3;
193  assign set_ctrl_w = cmd_we && (cmd_a== MEMBRIDGE_CTRL);
195  assign set_size64_w = cmd_we && (cmd_a== MEMBRIDGE_SIZE64);
197  assign set_len64_w = cmd_we && (cmd_a== MEMBRIDGE_LEN64);
200  assign set_mode_w = cmd_we && (cmd_a== MEMBRIDGE_MODE);
201  reg [28:0] lo_addr64_mclk;
202  reg [28:0] size64_mclk;
203  reg [28:0] start64_mclk;
204  reg [28:0] len64_mclk;
205 // reg [FRAME_WIDTH_BITS+1:0] width64_mclk; // FRAME_WIDTH_BITS in 128 bit bursts
206  reg [FRAME_WIDTH_BITS:0] width64_mclk; // FRAME_WIDTH_BITS in 128 bit bursts
207  reg [FRAME_WIDTH_BITS:0] width64_minus1_mclk; // FRAME_WIDTH_BITS in 128 bit bursts
209  reg rdwr_reset_addr_mclk; // resets system memory address
211 `ifdef MEMBRIDGE_DEBUG_READ
212  reg debug_aw_mclk; // enable sending next address over AFI
213  reg debug_w_mclk; // enable sending next data burst over AFI
214  wire debug_aw; // enable sending next address over AFI, sync to hclk
215  wire debug_w; // enable sending next data burst over AFI, sync to hclk
216  reg [6:0] debug_aw_allowed;
217  reg [8:0] debug_w_allowed;
218  reg [4:0] debug_bufrd_rd;
219  reg debug_disable_set_mclk; // disable debug slowdown
220  wire debug_disable_set; // disable debug slowdown
221  reg debug_disable; // disable debug slowdown
222  wire debug_aw_ready;
223  wire debug_w_ready;
224  assign debug_aw_ready = (!debug_aw_allowed[6] && (|debug_aw_allowed[5:0])) || debug_disable; // > 0
225  assign debug_w_ready = (!debug_w_allowed[8] && (|debug_w_allowed [7:0]) &&((|debug_w_allowed [7:1]) || !(|debug_bufrd_rd))) || debug_disable; // > 0
226 `endif
227 //cmd_wrmem
228  always @ (posedge mclk) begin
229  if (set_lo_addr64_w) lo_addr64_mclk <= {cmd_data[28:4],4'b0}; // align to 16-bursts
230  if (set_size64_w) size64_mclk <= {cmd_data[28:4],4'b0}; // align to 16-bursts
231  if (set_lo_addr64_w) start64_mclk <= 0;
232  else if (set_start64_w) start64_mclk <= {cmd_data[28:4],4'b0}; // align to 16-bursts
233  if (set_len64_w) len64_mclk <= cmd_data[28:0]; // OK not to be aligned
234 // if (set_width64_w) width64_mclk <= {~(|cmd_data[FRAME_WIDTH_BITS:0]),cmd_data[FRAME_WIDTH_BITS:0]}; // OK not to be aligned
235  if (set_width64_w) width64_mclk <= cmd_data[FRAME_WIDTH_BITS:0]; // OK not to be aligned
238  end
239 
240  always @ (posedge mclk) begin
241  if (mrst) rdwr_en_mclk <= 0;
242  else if (set_ctrl_w) rdwr_en_mclk <= cmd_data[0];
243 
244  if (mrst) start_mclk <= 0;
245  else start_mclk <= set_ctrl_w & cmd_data[1];
247  if (mrst) mode_reg_mclk <= 5'h03;
248  else if (set_mode_w) mode_reg_mclk <= cmd_data[4:0];
250 `ifdef MEMBRIDGE_DEBUG_READ
251  if (mrst) debug_aw_mclk <= 0;
252  else debug_aw_mclk <= set_ctrl_w & cmd_data[2];
254  if (mrst) debug_w_mclk <= 0;
255  else debug_w_mclk <= set_ctrl_w & cmd_data[3];
257  if (mrst) debug_disable_set_mclk <= 0;
258  else debug_disable_set_mclk <= set_ctrl_w & cmd_data[4];
259 
260 
261 `endif
263  end
264 
265  // syncronize mclk ->hclk
266 
267  reg [28:0] lo_addr64;
268  reg [28:0] size64;
269  reg [28:0] start64;
270  reg [28:0] len64;
271  reg [FRAME_WIDTH_BITS:0] last_in_line64;
272  reg [24:0] last_addr1k; // last adress before rollover w/o 4 LSB
273  reg rdwr_en; // TODO: Use it?
274  reg rdwr_reset_addr; // resets system memory address
276  reg rd_start;
277  reg wr_start;
278  reg [2:0] rdwr_start;
279  reg wr_mode;
280  wire page_ready; // @ posedge hclk
281  wire frame_done; // @ posedge hclk
282 //next_page_chn
283  wire reset_page_wr; // @ posedge hclk (from @ posedge mclk)
284  wire reset_page_rd; // @ posedge hclk (from @ negedge mclk)
285  reg page_ready_rd;
286  reg page_ready_wr;
288  reg next_page_wr;
289 
290  wire next_page; // @ posedge hclk - source
291 // wire busy_next_page; // do not send next_page -previous is crossing clock boundaries
292 
294 
295  // incrementing IDs for read (MSB==0) and write (MSB==1)
296  reg [4:0] rd_id;
297  reg [4:0] wr_id;
298 
299  reg read_no_more; // after frame_done - no more requests for new pages to read
300 
301  assign afi_arid={1'b1,rd_id};
302  assign afi_awid={1'b1,wr_id};
303  assign afi_wid= {1'b1,wr_id};
304 
305 
306 
307 
308  always @ (posedge hclk) begin
310  size64 <= size64_mclk;
312  len64 <= len64_mclk;
315  wr_mode <= cmd_wrmem;
317  last_addr1k <= size64[28:4] - 1;
318  end
319 
320  always @ (posedge hclk) begin
321  if (hrst) rdwr_en <= 0;
322  else rdwr_en <= rdwr_en_mclk;
323 
324 
325  if (hrst) rdwr_start <= 0;
328  if (hrst) rd_start <= 0;
329  else rd_start <= rdwr_start[2] && !wr_mode; // later to enable adders+ to propagate
330 
331  if (hrst) wr_start <= 0;
332  else wr_start <= rdwr_start[2] && wr_mode;
333 
334 // page_ready_rd <= page_ready && !wr_mode && !read_no_more;
335 
336  if (hrst) rd_id <= 0;
337  else if (rd_start) rd_id <= rd_id +1;
338 
339  if (hrst) wr_id <= 0;
340  else if (wr_start) wr_id <= wr_id +1;
341 
342 
343 
344  end
345  // mclk -> hclk
350 
351 `ifdef MEMBRIDGE_DEBUG_READ
352  // mclk -> hclk, debug-only
353  pulse_cross_clock debug_aw_i (.rst(hrst), .src_clk(mclk), .dst_clk(hclk), .in_pulse(debug_aw_mclk), .out_pulse(debug_aw),.busy());
354  pulse_cross_clock debug_w_i (.rst(hrst), .src_clk(mclk), .dst_clk(hclk), .in_pulse(debug_w_mclk), .out_pulse(debug_w), .busy());
355  pulse_cross_clock debug_disable_set_i(.rst(hrst),.src_clk(mclk),.dst_clk(hclk), .in_pulse(debug_disable_set_mclk),.out_pulse(debug_disable_set), .busy());
356 `endif
357  // negedge mclk -> hclk (verify clock inversion is absorbed)
358  reg mrstn = 1;
359  always @ (negedge mclk) mrstn <= mrst;
361 
362  // hclk -> mclk
363 // pulse_cross_clock next_page_i (.rst(hrst), .src_clk(hclk), .dst_clk(mclk), .in_pulse(next_page), .out_pulse(next_page_chn),.busy(busy_next_page));
364 
366  .WIDTH(2),
367  .EXTRA_DLY(0)
368  ) elastic_cross_clock_i (
369  .rst (hrst), // input
370  .src_clk (hclk), // input
371  .dst_clk (mclk), // input
372  .in_pulses (next_page), // input
373  .out_pulse (next_page_chn), // output
374  .busy () // output
375  );
376 
377 
378  // Common to both directions
379  localparam DELAY_ADVANCE_ADDR=3;
380  reg [28:0] rel_addr64; // realtive (to lo_addr) address
381  wire advance_rel_addr_w;
383  wire advance_rel_addr_rd;
384 
385  reg advance_rel_addr;
386 
388  reg [28:0] left64;
390  reg rollover;
391  reg [ 3:0] afi_len;
392  reg [ 4:0] afi_len_plus1;
394 
395  reg [28:0] buf_left64; // number of 64-bit words yet to be read from the DDR3 (or written to it)
396  reg [FRAME_WIDTH_BITS:0] buf_in_line64; // number of last 64-bit words in line
397 
398  //last_addr1k
399  assign afi_awlen = afi_len;
400  assign afi_arlen = afi_len;
401  reg [28:0] axi_addr64;
402  wire left_zero;
403 
404  assign afi_awaddr={axi_addr64,3'b0};
405  assign afi_araddr={axi_addr64,3'b0};
406 
407  assign left_zero = low4_zero && last_burst;
408  always @ (posedge hclk) begin
409  if (hrst) advance_rel_addr_d <= 0;
411 
412  end
413 
414  reg read_started;
415  reg write_busy;
416  wire rw_in_progress;
417  reg busy;
418  reg done;
419  reg pre_done;
420 
422 
423  always @ (posedge hclk) begin
424  advance_rel_addr <= advance_rel_addr_w && !advance_rel_addr && !(|advance_rel_addr_d); // make sure advance_rel_addr_w is recalculated after address change
425  last_burst <= ! (|left64[28:4]);
426  rollover <= rel_addr64[28:4] == last_addr1k;
427  low4_zero <= ! (|left64[3:0]);
429  else if (advance_rel_addr) rel_addr64 <= last_burst?(rel_addr64 + {25'h0,left64[3:0]}) : (rollover?29'h0:(rel_addr64 + 29'h10));
430 
432 
434  else if (advance_rel_addr) left64 <= last_burst? 0: (left64 - 29'h10);
435 
436  afi_len <= (|left64[28:4])?4'hf : (left64[3:0]-1);
437  afi_len_plus1 <= (|left64[28:4]) ? 5'h10 : {1'b0,left64[3:0]};
438 
441 
443  else if (buf_rdwr) buf_left64 <= buf_left64 - 1;
444 
446  else if (buf_rdwr) buf_in_line64 <= is_last_in_line? {(FRAME_WIDTH_BITS+1){1'b0}} : (buf_in_line64 +1);
447 
448  if (hrst) next_page_rd <= 0;
450 
451  if (hrst) next_page_wr <= 0;
453 
454  end
455 
456  // DDR3 read - AFI write
457  //rdwr_en
458  reg [7:0] axi_arw_requested; // 64-bit words to be read/written over axi queued to AR/AW channels
459  reg [7:0] axi_bursts_requested; // number of bursts requested
460  reg [7:0] wresp_conf; // number of 64-bit words confirmed through axi b channel (wrong confirmed only bursts)!
461  wire [7:0] axi_wr_pending; // Number of bursts queued to AW but not yet confirmed through B-channel;
462  reg [7:0] axi_wr_left; // Number of bursts queued through AW but not sent over W;
463  wire [7:0] axi_rd_pending;
464 
465  reg [7:0] axi_rd_received;
466  assign axi_rd_pending= axi_arw_requested - axi_rd_received; // WRONG! - use bursts, not words!
467 // assign axi_wr_pending= axi_arw_requested - wresp_conf;
469 
470  reg read_busy;
471  reg read_over;
472  reg afi_bvalid_r;
473  reg [1:0] read_page;
474 // reg [6:0] read_addr;
475  reg [2:0] read_pages_ready;
476 
477  assign afi_bready = 1'b1; // always ready to receive confirmation
478 
481 
483 // assign advance_rel_addr_wr = read_started && afi_wa_safe_not_full && (|left64); // left 64 is decremented by 16, except possibly the last (partial)
484 `ifdef MEMBRIDGE_DEBUG_READ
485  assign advance_rel_addr_wr = read_started && afi_wa_safe_not_full && (|left64) && debug_aw_ready; // debugging ddr3 -> system
486 `else
488 `endif
490 
491  always @ (posedge hclk) begin
492  if (hrst) read_busy <= 0;
493  else if (rd_start) read_busy <= 1;
494  else if (read_over) read_busy <= 0;
495 
496 
497 
498  if (hrst) read_started <= 0;
499  else if (!read_busy) read_started <= 0;
500  else if (wr_mode) read_started <= 0; // just debugging, making sure read is disabled in write mode
501  else if (page_ready) read_started <= 1; // first page is in the buffer - use it to mask page number comparison
502 
503 `ifdef MEMBRIDGE_DEBUG_READ
504  if (hrst) debug_aw_allowed <= 0;
505  else if (!read_busy) debug_aw_allowed <= 0;
506  else if ( debug_aw && !afi_awvalid) debug_aw_allowed <= debug_aw_allowed + 1;
507  else if (!debug_aw && afi_awvalid) debug_aw_allowed <= debug_aw_allowed - 1;
508 
509 
510  if (hrst) debug_w_allowed <= 0;
511  else if (!read_busy) debug_w_allowed <= 0;
512  else if ( debug_w && !(afi_wvalid && afi_wlast)) debug_w_allowed <= debug_w_allowed + 1;
513  else if (!debug_w && (afi_wvalid && afi_wlast)) debug_w_allowed <= debug_w_allowed - 1;
514 
515  if (hrst) debug_disable <= 0;
516  else if (!read_busy) debug_disable <= 0;
517  else if (debug_disable_set) debug_disable <= 1;
518 `endif
519 
520 
522 
523  if (hrst) wresp_conf <= 0;
524  else if (!read_busy) wresp_conf <= 0;
526 
528 
529  if (hrst) read_page <= 0;
530  else if (reset_page_rd) read_page <= 0;
534  else if (!read_busy) read_pages_ready <= 0;
537 
538  if (hrst) afi_wd_safe_not_full <= 0;
539  else afi_wd_safe_not_full <= rdwr_en && (!afi_wcount[7] && !(&afi_wcount[6:3]));
540 
541  if (hrst) afi_wa_safe_not_full <= 0;
542  else afi_wa_safe_not_full <= rdwr_en && (!afi_wacount[5] && !(&afi_wacount[4:2]));
543 
544  if (hrst) busy <= 0;
545  else busy <= read_busy || write_busy;
546 
547  if (hrst) pre_done <= 0; // delay done to turn on same time busy is off
548  else pre_done <= (write_busy && frame_done) || (read_busy && read_over);
549 
550  if (hrst) done <= 0;
551  else if (!rdwr_en) done <= 0; // disabling when idle will reset done
552  else if (pre_done) done <= 1;
553  else if (rdwr_start) done <= 0;
554 
555  if (hrst ) read_no_more <= 0;
556  else if (!read_busy) read_no_more <= 0;
557  else if (frame_done) read_no_more <= 1;
558 
559 
560 
561  end
562 
563  // handle interaction with the buffer, advance addresses, keep track of partial (last) pages in each line
564  wire bufrd_rd_w;
565  wire bufwr_we_w; // TODO: assign
566 
567  reg [2:0] bufrd_rd;
568  reg [BUFWR_WE_WIDTH-1:0] bufwr_we;
569  reg buf_rdwr; // equiv to bufrd_rd[0] || bufwr_we)
570  wire is_last_in_line;
571  wire is_last_in_page;
572  wire next_page_rd_w;
573  wire next_page_wr_w;
574  wire done_page_rd_w;
575  wire safe_some_left_rd_w;
576  reg left_was_1; // was <=1 (0 does not matter) valid next after buffer address
577  reg left_many;
578 
579 
580 // assign next_page_rd_w = read_started && !busy_next_page && is_last_in_page && bufrd_rd[0];
584  assign is_last_in_page = is_last_in_line || (&buf_in_line64[6:0]);
585 // assign safe_some_left_rd_w = (axi_wr_left[7:1]!=0) || (axi_wr_left[0] && !bufrd_rd[0]);
586  assign safe_some_left_rd_w = left_many || (|buf_left64[1:0] && !(|bufrd_rd)); // Fine tune
587 `ifdef MEMBRIDGE_DEBUG_READ
588  assign bufrd_rd_w = safe_some_left_rd_w && !read_over && afi_wd_safe_not_full &&
589  (|read_pages_ready[2:1] || (read_pages_ready[0] && (!is_last_in_page || read_no_more))) && debug_w_ready;
590 `else
591 // assign bufrd_rd_w = afi_wd_safe_not_full && (|read_pages_ready[2:1] || (read_pages_ready[0] && !is_last_in_page));
592 
595 `endif
596 //last_in_line64 - last word number in scan line
597  reg [3:0] src_wcntr;
598 // reg [2:0] wlast_in_burst;
599  reg wlast; // valid 2 after buffer address, same as wvalid
600 
601  reg src_was_f; // valid next after buffer address
602 
603 // assign afi_wlast = wlast_in_burst[2];
604  assign afi_wlast = wlast;
605 
606  always @ (posedge hclk) begin
607  if (!rw_in_progress) left_was_1 <= 0;
608  else if (buf_rdwr) left_was_1 <= !(|buf_left64[28:1]);
609 
610 /* if (!rw_in_progress) left_many <= 0;
611  else if (buf_rdwr) **/
612 
613  left_many <= |buf_left64[28:2];
614 
616  if (!read_started) src_wcntr <= 0;
617  else if (bufrd_rd[0]) src_wcntr <= src_wcntr+1;
618 
619  if (!read_started) src_was_f <= 0;
620  else if (bufrd_rd[0]) src_was_f <= &src_wcntr; // valid with buffer address
621 
622 // if (!read_started) wlast_in_burst <= 0;
623 // else if (bufrd_rd[0]) wlast_in_burst <= {wlast_in_burst[1:0],left_was_1 | (&src_wcntr)};
624 
625  if (!read_started) wlast <= 0;
626  else if (bufrd_rd[1]) wlast <= left_was_1 || src_was_f;
627 
628 
629  bufrd_rd <= {bufrd_rd[1:0], bufrd_rd_w };
630 `ifdef MEMBRIDGE_DEBUG_READ
631  debug_bufrd_rd<= {debug_bufrd_rd[3:0], bufrd_rd_w };
632 `endif
635 
636  end
637  assign afi_wvalid=bufrd_rd[2];
638 
639  // write to ddr3 from afi
643  // assign advance_rel_addr_wr = read_started && afi_wa_safe_not_full && (|left64); // left 64 is decremented by 16, except possibly the last (partial)
646 
647 // assign next_page_wr_w = write_busy && !busy_next_page && is_last_in_page && bufwr_we[0];
649 
651 
652  // handle buffer address, page
653  reg [1:0] write_page; // current number of buffer page
654  reg [2:0] write_pages_ready; // number of pages in the buffer
655  reg [1:0] write_page_r; // 1-cycle delayed page address
656  reg [6:0] buf_in_line64_r; // 1-cycle delayed buffer address
657 
658  assign afi_rready = bufwr_we[0];
659 
660  always @ (posedge hclk) begin
661  if (hrst) write_busy <= 0;
662  else if (wr_start) write_busy <= 1;
663  else if (!wr_mode) write_busy <= 0; // Just debugging, making sure write mode is disabled in read mode
664  else if (frame_done) write_busy <= 0;
665 
666  if (hrst) axi_arw_requested <= 0;
667  else if (!write_busy && !read_started) axi_arw_requested <= 0;
669 
673 
674  if (hrst) axi_rd_received <= 0;
675  else if (!write_busy) axi_rd_received <= 0;
676  else if (bufwr_we[0]) axi_rd_received <= axi_rd_received + 1;
677 
678  if (hrst) axi_wr_left <= 0;
679  else if (!read_started) axi_wr_left <= 0;
680  else if ( advance_rel_addr && !(wlast && afi_wvalid)) axi_wr_left <= axi_wr_left + 1;
682 
683 
684  if (hrst) afi_rd_safe_not_empty <= 0;
685  // allow 1 cycle latency, no continuous reads when FIFO is low (like in the very end of the transfer)
686  // Adjust '2' in afi_rcount[6:2] ?
688 
689  if (hrst) afi_ra_safe_not_full <= 0;
690  else afi_ra_safe_not_full <= rdwr_en && ( !afi_racount[2] && !(&afi_racount[1:0]));
691 
692  if (hrst) afi_safe_rd_pending <= 0;
693  else if (!write_busy) afi_safe_rd_pending <= 0;
694  else afi_safe_rd_pending <= rdwr_en && ( !axi_rd_pending[7] && !(&axi_rd_pending[6:4]));
695 
696  // handle buffer address, page
697  if (hrst) write_page <= 0;
698  else if (reset_page_wr) write_page <= 0;
699  else if (next_page_wr_w) write_page <= write_page + 1;
700 
701  if (hrst) write_pages_ready <= 0;
702  else if (!write_busy) write_pages_ready <= 0;
705 
706  end
707 `ifdef MEMBRIDGE_DEBUG_WRITE
708  reg [30:0] dbg_read_counter;
709  always @ (posedge hclk) begin
710  if (!write_busy ) dbg_read_counter <= 0;
711  else if (bufwr_we[0]) dbg_read_counter <= dbg_read_counter + 1;
712  end
713 `endif
714 
715  reg [63:0] rdata_r;
716  always @ (posedge hclk) begin
719 // rdata_r <= afi_rdata;
720 `ifdef MEMBRIDGE_DEBUG_WRITE
721  rdata_r <= cache_debug?{dbg_read_counter,1'h1,dbg_read_counter,1'h0}:afi_rdata[63:0]; // debugging
722 `else
723  rdata_r <= cache_debug?{wr_id[3:0],2'b0,write_page_r[1:0],afi_rcount[7:0],afi_rdata[47:0]}:afi_rdata[63:0]; // debugging
724 `endif
725  end
726 
727  cmd_deser #(
728  .ADDR (MEMBRIDGE_ADDR),
729  .ADDR_MASK (MEMBRIDGE_MASK),
730  .NUM_CYCLES (6),
731  .ADDR_WIDTH (4),
732  .DATA_WIDTH (32)
733  ) cmd_deser_32bit_i (
734  .rst (1'b0), // rst), // input
735  .clk (mclk), // input
736  .srst (mrst), // input
737  .ad (cmd_ad), // input[7:0]
738  .stb (cmd_stb), // input
739  .addr (cmd_a), // output[3:0]
740  .data (cmd_data), // output[31:0]
741  .we (cmd_we) // output
742  );
743 
744  status_generate #(
745  .STATUS_REG_ADDR (MEMBRIDGE_STATUS_REG),
746 `ifdef MEMBRIDGE_DEBUG_READ
747  .PAYLOAD_BITS (18) // 2) // With debug
748 `else
749  .PAYLOAD_BITS (18) //2)
750 `endif
751  ) status_generate_i (
752  .rst (1'b0), // rst), // input
753  .clk (mclk), // input
754  .srst (mrst), // input
755  .we (set_status_w), // input
756  .wd (cmd_data[7:0]), // input[7:0]
757 `ifdef MEMBRIDGE_DEBUG_READ
758  .status ({debug_aw_allowed, debug_w_allowed, done, busy}), // input[25:0]
759 `else
760  .status ({axi_arw_requested, wresp_conf, done, busy}), // input[25:0]
761 `endif
762  .ad (status_ad), // output[7:0]
763  .rq (status_rq), // output
764  .start (status_start) // input
765  );
766 
767 // Port 1rd (read DDR to AFI) buffer, linear
768 wire [63:0] afi_wdata0;
769 `ifdef MEMBRIDGE_DEBUG_WRITE
770  reg [15:0] dbg_write_counter;
771  always @ (posedge hclk) begin
772  if (!read_busy || !cache_debug) dbg_write_counter <= 0;
773  else if (bufrd_rd[1]) dbg_write_counter <= dbg_write_counter + 1;
774  end
775  assign afi_wdata = {afi_wdata0[63:16], dbg_write_counter[0]? dbg_write_counter[15:0]: afi_wdata0[15:0]};
776 `else
777  assign afi_wdata = afi_wdata0;
778 `endif
779 
780 
781  mcntrl_buf_rd #(
782  .LOG2WIDTH_RD(6) // 64 bit external interface
783  ) chn1rd_buf_i (
784  .ext_clk (hclk), // input
785  .ext_raddr ({read_page,buf_in_line64[6:0]}), // input[8:0]
786  .ext_rd (bufrd_rd[0]), // input
787  .ext_regen (bufrd_rd[1]), // input
788  .ext_data_out (afi_wdata0), // output[63:0]
789 // .emul64 (1'b0), // input Modify buffer addresses (used for JP4 until a 64-wide mode is implemented)
790  .wclk (!mclk), // input
791  .wpage_in (2'b0), // input[1:0]
792  .wpage_set (xfer_reset_page_rd), // input TODO: Generate @ negedge mclk on frame start
793  .page_next (buf_wpage_nxt), // input
794  .page (), // output[1:0]
795  .we (buf_wr), // input
796  .data_in (buf_wdata) // input[63:0]
797  );
798 
799 // Port 1wr (write DDR from AFI) buffer, linear
800  mcntrl_buf_wr #(
801  .LOG2WIDTH_WR(6) // 64 bit external interface
802  ) chn1wr_buf_i (
803  .ext_clk (hclk), // input
804  .ext_waddr ({write_page_r, buf_in_line64_r[6:0]}), // input[8:0]
805  .ext_we (bufwr_we[1]), // input
806  .ext_data_in (rdata_r), //afi_rdata), // input[63:0] buf_wdata - from AXI
807  .rclk (mclk), // input
808  .rpage_in (2'b0), // input[1:0]
809  .rpage_set (xfer_reset_page_wr), // input @ posedge mclk
810  .page_next (buf_rpage_nxt), // input
811  .page (), // output[1:0]
812  .rd (buf_rd), // input
813  .data_out (buf_rdata) // output[63:0]
814  );
815 
816 `ifdef DEBUG_RING
817  debug_slave #(
818  .SHIFT_WIDTH (32),
819  .READ_WIDTH (32),
820  .WRITE_WIDTH (32),
821  .DEBUG_CMD_LATENCY (DEBUG_CMD_LATENCY)
822  ) debug_slave_i (
823  .mclk (mclk), // input
824  .mrst (mrst), // input
825  .debug_di (debug_di), // input
826  .debug_sl (debug_sl), // input
827  .debug_do (debug_do), // output
828  .rd_data ({
829  5'b0, afi_racount[2:0],
830  afi_rcount[7:0],
831  2'b0, afi_wacount[5:0],
832  afi_wcount[7:0]
833  }), // input[31:0]
834  .wr_data (), // output[31:0] - not used
835  .stb () // output - not used
836  );
837 `endif
838 
839 endmodule
840 
841 
617rdwr_en_mclkreg
Definition: membridge.v:208
[ 7:0] 564afi_wstrb
Definition: membridge.v:110
655rolloverreg
Definition: membridge.v:364
638page_ready_wrreg
Definition: membridge.v:265
698src_was_freg
Definition: membridge.v:558
701afi_safe_rd_pendingreg
Definition: membridge.v:597
641next_pagewire
Definition: membridge.v:269
685bufrd_rdreg[2:0]
Definition: membridge.v:527
cmd_deser_32bit_i cmd_deser
Definition: membridge.v:681
619start_mclkreg
Definition: membridge.v:210
693safe_some_left_rd_wwire
Definition: membridge.v:535
[1:0] 5204rpage_in
Definition: mcntrl_buf_wr.v:51
533frame_start_chn
Definition: membridge.v:74
574afi_arready
Definition: membridge.v:124
629rd_startreg
Definition: membridge.v:255
704write_page_rreg[1:0]
Definition: membridge.v:610
[WRITE_WIDTH - 1 : 0] 10318wr_data
Definition: debug_slave.v:56
[ 1:0] 568afi_bresp
Definition: membridge.v:115
654last_burstreg
Definition: membridge.v:363
chn1rd_buf_i mcntrl_buf_rd
Definition: membridge.v:729
[ 7:0] 569afi_wcount
Definition: membridge.v:117
663read_startedreg
Definition: membridge.v:388
[63:0] 543buf_wdata
Definition: membridge.v:85
544xfer_reset_page_wr
Definition: membridge.v:87
531status_rq
Definition: membridge.v:71
515MEMBRIDGE_SIZE64'h3
Definition: membridge.v:47
630wr_startreg
Definition: membridge.v:256
682afi_wa_safe_not_fullreg
Definition: membridge.v:454
[ 5:0] 551afi_awid
Definition: membridge.v:96
600set_ctrl_wwire
Definition: membridge.v:179
647rel_addr64reg[28:0]
Definition: membridge.v:354
reset_page_rd_i pulse_cross_clock
Definition: membridge.v:334
[ 3:0] 558afi_awqos
Definition: membridge.v:103
702write_pagereg[1:0]
Definition: membridge.v:608
598cmd_datawire[31:0]
Definition: membridge.v:176
[ 1:0] 588afi_rresp
Definition: membridge.v:139
703write_pages_readyreg[2:0]
Definition: membridge.v:609
518MEMBRIDGE_WIDTH64'h6
Definition: membridge.v:50
608mode_reg_mclkreg[4:0]
Definition: membridge.v:187
690next_page_rd_wwire
Definition: membridge.v:532
[ 1:0] 580afi_arsize
Definition: membridge.v:130
602set_lo_addr64_wwire
Definition: membridge.v:181
609mode_regreg[4:0]
Definition: membridge.v:188
650advance_rel_addr_rdwire
Definition: membridge.v:357
[63:0] 547buf_rdata
Definition: membridge.v:90
645mrstnreg
Definition: membridge.v:332
595BUFWR_WE_WIDTH4
Definition: membridge.v:151
659buf_left64reg[28:0]
Definition: membridge.v:369
[63:0] 5209data_out
Definition: mcntrl_buf_wr.v:56
679read_pagereg[1:0]
Definition: membridge.v:447
666busyreg
Definition: membridge.v:391
642rd_idreg[4:0]
Definition: membridge.v:275
[ 5:0] 567afi_bid
Definition: membridge.v:114
689is_last_in_pagewire
Definition: membridge.v:531
708afi_wdata0wire[63:0]
Definition: membridge.v:718
684bufwr_we_wwire
Definition: membridge.v:525
675axi_rd_receivedreg[7:0]
Definition: membridge.v:439
521FRAME_HEIGHT_BITS16
Definition: membridge.v:53
[ 5:0] 570afi_wacount
Definition: membridge.v:118
[ADDR_MASK2!=0?2:ADDR_MASK1!=0?1:0:0] 9935we
Definition: cmd_deser.v:60
633page_readywire
Definition: membridge.v:259
683bufrd_rd_wwire
Definition: membridge.v:524
656afi_lenreg[3:0]
Definition: membridge.v:365
631rdwr_startreg[2:0]
Definition: membridge.v:257
636reset_page_rdwire
Definition: membridge.v:263
[ 1:0] 576afi_arlock
Definition: membridge.v:126
[ 3:0] 553afi_awcache
Definition: membridge.v:98
669axi_arw_requestedreg[7:0]
Definition: membridge.v:432
623len64reg[28:0]
Definition: membridge.v:249
618rdwr_reset_addr_mclkreg
Definition: membridge.v:209
664write_busyreg
Definition: membridge.v:389
549afi_awvalid
Definition: membridge.v:94
640next_page_wrreg
Definition: membridge.v:267
661axi_addr64reg[28:0]
Definition: membridge.v:375
637page_ready_rdreg
Definition: membridge.v:264
[63:0] 5195data_in
Definition: mcntrl_buf_rd.v:59
624last_in_line64reg[FRAME_WIDTH_BITS:0]
Definition: membridge.v:250
653left64reg[28:0]
Definition: membridge.v:362
550afi_awready
Definition: membridge.v:95
571afi_wrissuecap1en
Definition: membridge.v:119
[63:0] 583afi_rdata
Definition: membridge.v:134
692done_page_rd_wwire
Definition: membridge.v:534
651advance_rel_addrreg
Definition: membridge.v:359
662left_zerowire
Definition: membridge.v:376
678afi_bvalid_rreg
Definition: membridge.v:446
597cmd_awire[3:0]
Definition: membridge.v:175
debug_slave_i debug_slave
Definition: membridge.v:765
545buf_rpage_nxt
Definition: membridge.v:88
646DELAY_ADVANCE_ADDR3
Definition: membridge.v:353
628start_hclkwire
Definition: membridge.v:254
[READ_WIDTH - 1 : 0] 10317rd_data
Definition: debug_slave.v:55
649advance_rel_addr_wrwire
Definition: membridge.v:356
639next_page_rdreg
Definition: membridge.v:266
621size64reg[28:0]
Definition: membridge.v:247
625last_addr1kreg[24:0]
Definition: membridge.v:251
674axi_rd_pendingwire[7:0]
Definition: membridge.v:437
686bufwr_wereg[BUFWR_WE_WIDTH-1:0]
Definition: membridge.v:528
511MEMBRIDGE_MASK'h7f0
Definition: membridge.v:43
614len64_mclkreg[28:0]
Definition: membridge.v:204
610cache_debugwire
Definition: membridge.v:189
673axi_wr_leftreg[7:0]
Definition: membridge.v:436
[ 3:0] 579afi_arlen
Definition: membridge.v:129
573afi_arvalid
Definition: membridge.v:123
591afi_rdissuecap1en
Definition: membridge.v:143
620lo_addr64reg[28:0]
Definition: membridge.v:246
635reset_page_wrwire
Definition: membridge.v:262
612size64_mclkreg[28:0]
Definition: membridge.v:202
691next_page_wr_wwire
Definition: membridge.v:533
700afi_ra_safe_not_fullreg
Definition: membridge.v:596
532status_start
Definition: membridge.v:72
[ 1:0] 556afi_awsize
Definition: membridge.v:101
634frame_donewire
Definition: membridge.v:260
627rdwr_reset_addrreg
Definition: membridge.v:253
632wr_modereg
Definition: membridge.v:258
510MEMBRIDGE_ADDR'h200
Definition: membridge.v:42
536page_ready_chn
Definition: membridge.v:77
[DATA_WIDTH-1:0] 9934data
Definition: cmd_deser.v:59
643wr_idreg[4:0]
Definition: membridge.v:276
603set_size64_wwire
Definition: membridge.v:182
[1:0] 5193page
Definition: mcntrl_buf_rd.v:57
613start64_mclkreg[28:0]
Definition: membridge.v:203
535cmd_wrmem
Definition: membridge.v:76
517MEMBRIDGE_LEN64'h5
Definition: membridge.v:49
[ 7:0] 589afi_rcount
Definition: membridge.v:141
644read_no_morereg
Definition: membridge.v:278
680read_pages_readyreg[2:0]
Definition: membridge.v:449
616width64_minus1_mclkreg[FRAME_WIDTH_BITS:0]
Definition: membridge.v:207
[ 1:0] 581afi_arburst
Definition: membridge.v:131
[7:0] 530status_ad
Definition: membridge.v:70
709dbg_write_counterreg[15:0]
Definition: membridge.v:720
667donereg
Definition: membridge.v:392
[ 5:0] 562afi_wid
Definition: membridge.v:108
671wresp_confreg[7:0]
Definition: membridge.v:434
513MEMBRIDGE_STATUS_CNTRL'h1
Definition: membridge.v:45
[FRAME_HEIGHT_BITS-1:0] 538line_unfinished_chn1
Definition: membridge.v:79
660buf_in_line64reg[FRAME_WIDTH_BITS:0]
Definition: membridge.v:370
[ 5:0] 575afi_arid
Definition: membridge.v:125
677read_overreg
Definition: membridge.v:445
615width64_mclkreg[FRAME_WIDTH_BITS:0]
Definition: membridge.v:206
601set_status_wwire
Definition: membridge.v:180
[7:0] 9931ad
Definition: cmd_deser.v:56
514MEMBRIDGE_LO_ADDR64'h2
Definition: membridge.v:46
695left_manyreg
Definition: membridge.v:537
[1:0] 5190wpage_in
Definition: mcntrl_buf_rd.v:54
707rdata_rreg[63:0]
Definition: membridge.v:670
[ADDR_WIDTH-1:0] 9933addr
Definition: cmd_deser.v:58
670axi_bursts_requestedreg[7:0]
Definition: membridge.v:433
694left_was_1reg
Definition: membridge.v:536
706dbg_read_counterreg[30:0]
Definition: membridge.v:663
596SAFE_RD_BITS3
Definition: membridge.v:152
626rdwr_enreg
Definition: membridge.v:252
657afi_len_plus1reg[4:0]
Definition: membridge.v:366
696src_wcntrreg[3:0]
Definition: membridge.v:554
[63:0] 559afi_wdata
Definition: membridge.v:105
540xfer_reset_page_rd
Definition: membridge.v:82
539suspend_chn1
Definition: membridge.v:80
606set_mode_wwire
Definition: membridge.v:185
699afi_rd_safe_not_emptyreg
Definition: membridge.v:595
[1:0] 5207page
Definition: mcntrl_buf_wr.v:54
[ 2:0] 554afi_awprot
Definition: membridge.v:99
[ 2:0] 590afi_racount
Definition: membridge.v:142
607set_width64_wwire
Definition: membridge.v:186
541buf_wpage_nxt
Definition: membridge.v:83
537frame_done_chn
Definition: membridge.v:78
[1 << LOG2WIDTH_WR-1:0] 5202ext_data_in
Definition: mcntrl_buf_wr.v:48
519MEMBRIDGE_MODE'h7
Definition: membridge.v:51
[1 << LOG2WIDTH_RD-1:0] 5188ext_data_out
Definition: mcntrl_buf_rd.v:49
687buf_rdwrreg
Definition: membridge.v:529
[ 3:0] 577afi_arcache
Definition: membridge.v:127
elastic_cross_clock_i elastic_cross_clock
Definition: membridge.v:339
658low4_zeroreg
Definition: membridge.v:367
[31:0] 548afi_awaddr
Definition: membridge.v:93
676read_busyreg
Definition: membridge.v:444
665rw_in_progresswire
Definition: membridge.v:390
668pre_donereg
Definition: membridge.v:393
648advance_rel_addr_wwire
Definition: membridge.v:355
705buf_in_line64_rreg[6:0]
Definition: membridge.v:611
512MEMBRIDGE_CTRL'h0
Definition: membridge.v:44
[ 1:0] 557afi_awburst
Definition: membridge.v:102
[ 2:0] 578afi_arprot
Definition: membridge.v:128
520MEMBRIDGE_STATUS_REG'h3b
Definition: membridge.v:52
688is_last_in_linewire
Definition: membridge.v:530
chn1wr_buf_i mcntrl_buf_wr
Definition: membridge.v:748
672axi_wr_pendingwire[7:0]
Definition: membridge.v:435
516MEMBRIDGE_START64'h4
Definition: membridge.v:48
[7:0] 528cmd_ad
Definition: membridge.v:68
status_generate_i status_generate
Definition: membridge.v:698
[ 3:0] 582afi_arqos
Definition: membridge.v:132
599cmd_wewire
Definition: membridge.v:177
622start64reg[28:0]
Definition: membridge.v:248
681afi_wd_safe_not_fullreg
Definition: membridge.v:453
[ 1:0] 552afi_awlock
Definition: membridge.v:97
[ALL_BITS-1:0] 10777status
652advance_rel_addr_dreg[DELAY_ADVANCE_ADDR-1:0]
Definition: membridge.v:361
697wlastreg
Definition: membridge.v:556
[ 5:0] 586afi_rid
Definition: membridge.v:137
[14-LOG2WIDTH_RD:0] 5185ext_raddr
Definition: mcntrl_buf_rd.v:46
[ 3:0] 555afi_awlen
Definition: membridge.v:100
534next_page_chn
Definition: membridge.v:75
604set_start64_wwire
Definition: membridge.v:183
[31:0] 572afi_araddr
Definition: membridge.v:122
605set_len64_wwire
Definition: membridge.v:184
[14-LOG2WIDTH_WR:0] 5200ext_waddr
Definition: mcntrl_buf_wr.v:46
611lo_addr64_mclkreg[28:0]
Definition: membridge.v:201