x393  1.0
FPGAcodeforElphelNC393camera
mcntrl_tiled_rw.v
Go to the documentation of this file.
1 
42 `timescale 1ns/1ps
43 
45  parameter ADDRESS_NUMBER= 15,
46  parameter COLADDR_NUMBER= 10,
47  parameter FRAME_WIDTH_BITS= 13, // Maximal frame width - 8-word (16 bytes) bursts
48  parameter FRAME_HEIGHT_BITS= 16, // Maximal frame height
49  parameter MAX_TILE_WIDTH= 6, // number of bits to specify maximal tile (width-1) (6 -> 64)
50  parameter MAX_TILE_HEIGHT= 6, // number of bits to specify maximal tile (height-1) (6 -> 64)
51  parameter LAST_FRAME_BITS= 16, // number of bits in frame counter (before rolls over)
52  parameter MCNTRL_TILED_ADDR= 'h120,
53  parameter MCNTRL_TILED_MASK= 'h7f0, // both channels 0 and 1
54  parameter MCNTRL_TILED_MODE= 'h0, // set mode register: {byte32,keep_open,extra_pages[1:0],write_mode,enable,!reset}
55  parameter MCNTRL_TILED_STATUS_CNTRL= 'h1, // control status reporting
56  parameter MCNTRL_TILED_STARTADDR= 'h2, // 22-bit frame start address (3 CA LSBs==0. BA==0)
57  parameter MCNTRL_TILED_FRAME_SIZE= 'h3, // 22-bit frame start address increment (3 CA LSBs==0. BA==0)
58  parameter MCNTRL_TILED_FRAME_LAST= 'h4, // 16-bit last frame number in the buffer
59  parameter MCNTRL_TILED_FRAME_FULL_WIDTH='h5, // Padded line length (8-row increment), in 8-bursts (16 bytes)
60  parameter MCNTRL_TILED_WINDOW_WH= 'h6, // low word - 13-bit window width (0->'h4000), high word - 16-bit frame height (0->'h10000)
61  parameter MCNTRL_TILED_WINDOW_X0Y0= 'h7, // low word - 13-bit window left, high word - 16-bit window top
62  parameter MCNTRL_TILED_WINDOW_STARTXY= 'h8, // low word - 13-bit start X (relative to window), high word - 16-bit start y
63  // Start XY can be used when read command to start from the middle
64  // TODO: Add number of blocks to R/W? (blocks can be different) - total length?
65  // Read back current address (for debugging)?
66  parameter MCNTRL_TILED_TILE_WHS= 'h9, // low byte - 6-bit tile width in 8-bursts, second byte - tile height (0 - > 64),
67  // 3-rd byte - vertical step (to control tile vertical overlap)
69  parameter MCNTRL_TILED_PENDING_CNTR_BITS=2, // Number of bits to count pending trasfers, currently 2 is enough, but may increase
70  // if memory controller will allow programming several sequences in advance to
71  // spread long-programming (tiled) over fast-programming (linear) requests.
72  // But that should not be too big to maintain 2-level priorities
73  parameter MCNTRL_TILED_FRAME_PAGE_RESET =1'b0, // reset internal page number to zero at the frame start (false - only when hard/soft reset)
74  // bits in mode control word
75  parameter MCONTR_LINTILE_NRESET = 0, // reset if 0
76  parameter MCONTR_LINTILE_EN = 1, // enable requests
77  parameter MCONTR_LINTILE_WRITE = 2, // write to memory mode
78  parameter MCONTR_LINTILE_EXTRAPG = 3, // extra pages (over 1) needed by the client simultaneously
79  parameter MCONTR_LINTILE_EXTRAPG_BITS = 2, // number of bits to use for extra pages
80  parameter MCONTR_LINTILE_KEEP_OPEN = 5, // keep banks open (will be used only if number of rows <= 8)
81  parameter MCONTR_LINTILE_BYTE32 = 6, // use 32-byte wide columns in each tile (false - 16-byte)
82  parameter MCONTR_LINTILE_RST_FRAME = 8, // reset frame number
83  parameter MCONTR_LINTILE_SINGLE = 9, // read/write a single page
84  parameter MCONTR_LINTILE_REPEAT = 10, // read/write pages until disabled
85  parameter MCONTR_LINTILE_DIS_NEED = 11 // disable 'need' request
86 
87 )(
88  input mrst,
89  input mclk,
90 // programming interface
91  input [7:0] cmd_ad, // byte-serial command address/data (up to 6 bytes: AL-AH-D0-D1-D2-D3
92  input cmd_stb, // strobe (with first byte) for the command a/d
93 
94  output [7:0] status_ad, // byte-wide address/data
95  output status_rq, // request to send downstream (last byte with rq==0)
96  input status_start, // acknowledge of address (first byte) from downsteram
97 
98  input frame_start, // resets page, x,y, and initiates transfer requests (in write mode will wait for next_page)
99  input next_page, // page was read/written from/to 4*1kB on-chip buffer
100 // output page_ready, // == xfer_done, connect externally | Single-cycle pulse indicating that a page was read/written from/to DDR3 memory
101  output frame_done, // single-cycle pulse when the full frame (window) was transferred to/from DDR3 memory
102  output frame_finished,// turns on and stays on after frame_done
103 // optional I/O for channel synchronization
104 // after the last tile in a frame, before starting a new frame line_unfinished will point to non-existent (too high) line in the same frame
105  output [FRAME_HEIGHT_BITS-1:0] line_unfinished, // number of the current (unfinished ) line, RELATIVE TO FRAME, NOT WINDOW.
106  input suspend, // suspend transfers (from external line number comparator)
107  output [LAST_FRAME_BITS-1:0] frame_number, // current frame number (for multi-frame ranges)
108  output xfer_want, // "want" data transfer
109  output xfer_need, // "need" - really need a transfer (only 1 page/ room for 1 page left in a buffer), want should still be set.
110  input xfer_grant, // sequencer programming access granted, deassert wait/need
111 // output xfer_start, // initiate a transfer (next cycle after xfer_grant), following signals (up to xfer_partial) are valid
112  output xfer_start_rd, // initiate a transfer (next cycle after xfer_grant), following signals (up to xfer_partial) are valid
113  output xfer_start_wr, // initiate a transfer (next cycle after xfer_grant), following signals (up to xfer_partial) are valid
114  output xfer_start32_rd, // initiate a transfer to 32-byte wide colums scanning in each tile
115  output xfer_start32_wr, // initiate a transfer to 32-byte wide colums scanning in each tile
116  output [2:0] xfer_bank, // start bank address
117  output [ADDRESS_NUMBER-1:0] xfer_row, // memory row
118  output [COLADDR_NUMBER-4:0] xfer_col, // start memory column in 8-bursts
119  output [FRAME_WIDTH_BITS:0] rowcol_inc, // increment row+col (after bank) for the new scan line in 8-bursts (externally pad with 0)
120  output [MAX_TILE_WIDTH-1:0] num_rows_m1, // number of rows to read minus 1
121  output [MAX_TILE_HEIGHT-1:0] num_cols_m1, // number of 16-pixel columns to read (rows first, then columns) - 1
122  output keep_open, // (programmable bit)keep banks open (for <=8 banks only
123  output xfer_partial, // partial tile (first of 2) , sequencer will not generate page_next at the end of block
124  input xfer_page_done, // transfer to/from the buffer finished (partial transfers should not generate), use rpage_nxt_chn@mclk
125  output xfer_page_rst_wr, // reset buffer internal page - at each frame start or when specifically reset (write to memory channel), @posedge
126  output xfer_page_rst_rd // reset buffer internal page - at each frame start or when specifically reset (read memory channel), @negedge
127 );
128 // FIXME: not all tile heights are valid (because of the banks)
129 
130 //MAX_TILE_WIDTH
131  localparam NUM_RC_BURST_BITS=ADDRESS_NUMBER+COLADDR_NUMBER-3; //to spcify row and col8 == 22
132  localparam MPY_WIDTH= NUM_RC_BURST_BITS; // 22
133  localparam PAR_MOD_LATENCY= 9; // TODO: Find actual worst-case latency for:
134  reg [FRAME_WIDTH_BITS-1:0] curr_x; // (calculated) start of transfer x (relative to window left)
135  reg [FRAME_HEIGHT_BITS-1:0] curr_y; // (calculated) start of transfer y (relative to window top)
136  reg [FRAME_HEIGHT_BITS:0] next_y; // (calculated) next row number
137  reg [NUM_RC_BURST_BITS-1:0] line_start_addr;// (calculated) Line start (in {row,col8} in burst8
138  reg [COLADDR_NUMBER-4:0] line_start_page_left; // number of 8-burst left in the memory page from the start of the frame line
139  // calculating full width from the frame width
140 //WARNING: [Synth 8-3936] Found unconnected internal register 'frame_y_reg' and it is trimmed from '16' to '3' bits. [memctrl/mcntrl_tiled_rw.v:307]
141 // Throblem seems to be that frame_y8_r_reg (load of trimmed bits of the frame_y_reg) is (as intended) absorbed into DSP48. The lower 3 bits are used
142 // outside of the DSP 48. "dont_touch" seems to work here
143 `ifndef IGNORE_ATTR
144  (* keep = "true" *)
145 `endif
146  reg [FRAME_HEIGHT_BITS-1:0] frame_y; // current line number referenced to the frame top
147  reg [FRAME_WIDTH_BITS-1:0] frame_x; // current column number referenced to the frame left
148  reg [FRAME_HEIGHT_BITS-4:0] frame_y8_r; // (13 bits) current row with bank removed, latency2 (to be absorbed when inferred DSP multipler)
149  reg [FRAME_WIDTH_BITS:0] frame_full_width_r; // (14 bit) register to be absorbed by MPY
150  reg [MPY_WIDTH-1:0] mul_rslt;
151  reg [NUM_RC_BURST_BITS-1:0] start_addr_r; // 22 bit - to be absorbed by DSP
152 // reg [2:0] bank_reg [2:0];
153  reg [3 * 3 - 1:0] bank_reg;
155  // wire [2:0] cur_bank;
156  reg [FRAME_WIDTH_BITS:0] row_left; // number of 8-bursts left in the current row
158  reg [COLADDR_NUMBER-3:0] mem_page_left; // number of 8-bursts left in the pointed memory page
159  reg [MAX_TILE_WIDTH:0] lim_by_tile_width; // number of bursts left limited by the longest transfer (currently 64)
160  wire [COLADDR_NUMBER-3:0] remainder_tile_width; // number of bursts postponed to the next partial tile (because of the page crossing) MSB-sign
161  reg continued_tile; // this is a continued tile (caused by page crossing) - only once
162  reg [MAX_TILE_WIDTH-1:0] leftover_cols; // valid with continued_tile, number of columns left
163  wire pgm_param_w; // program one of the parameters, invalidate calculated results for PAR_MOD_LATENCY
164  reg [2:0] xfer_start_r;
170  reg [PAR_MOD_LATENCY-1:0] recalc_r; // 1-hot CE for re-calculating registers
171  wire calc_valid; // calculated registers have valid values
172  wire chn_en; // enable requests by channel (continue ones in progress), enable frame_start inputs
173  wire chn_rst; // resets command, including fifo;
174  reg chn_rst_d; // delayed by 1 cycle do detect turning off
178  reg [2:0] page_cntr; // to maintain requests - difference between client requests and generated requests
179  // partial (truncated by memory page) generated requests should not count
180 
181  wire cmd_wrmem; //= MCNTRL_TILED_WRITE_MODE; // 0: read from memory, 1:write to memory (change to parameter?)
182  wire [1:0] cmd_extra_pages; // external module needs more than 1 page
183  wire byte32; // use 32-byte wide colums in each tile (0 - use 16-byte ones)
184  wire disable_need; // do not assert need, only want
185  wire repeat_frames; // mode bit
186  wire single_frame_w; // pulse
188  reg single_frame_r; // pulse
189  reg [1:0] rst_frame_num_r; // reset frame number/next start address
190  reg frame_en; // enable next frame
191 
192  reg busy_r;
193  reg want_r;
194  reg need_r;
200  reg [MCNTRL_TILED_PENDING_CNTR_BITS-1:0] pending_xfers; // number of requested,. but not finished block transfers (to genearate frame done)
202 // reg [FRAME_HEIGHT_BITS-1:0] line_unfinished_r0;
203 // reg [FRAME_HEIGHT_BITS-1:0] line_unfinished_r1;
204 // reg [2*FRAME_HEIGHT_BITS-1:0] line_unfinished_r;
207 
208  wire pre_want;
209  wire [1:0] status_data;
210  wire [3:0] cmd_a;
211  wire [31:0] cmd_data;
212  wire cmd_we;
213 
219 
225  wire lsw13_zero=!(|cmd_data[FRAME_WIDTH_BITS-1:0]); // LSW 13 (FRAME_WIDTH_BITS) low bits are all 0 - set carry bit
226 // wire msw13_zero=!(|cmd_data[FRAME_WIDTH_BITS+15:16]); // MSW 13 (FRAME_WIDTH_BITS) low bits are all 0 - set carry bit
227  wire msw_zero= !(|cmd_data[31:16]); // MSW all bits are 0 - set carry bit
231 
232 // reg [5:0] mode_reg;//mode register: {write_mode,keep_open,extra_pages[1:0],enable,!reset}
233 // reg [6:0] mode_reg;//mode register: {byte32,keep_open,extra_pages[1:0],write_mode,enable,!reset}
234  reg [11:0] mode_reg;//mode register: {dis_need,repet,single,rst_frame,na,byte32,keep_open,extra_pages[1:0],write_mode,enable,!reset}
235  reg [NUM_RC_BURST_BITS-1:0] start_range_addr; // (programmed) First frame in range start (in {row,col8} in burst8, bank ==0
236  reg [NUM_RC_BURST_BITS-1:0] frame_size; // (programmed) First frame in range start (in {row,col8} in burst8, bank ==0
238  reg [NUM_RC_BURST_BITS-1:0] start_addr; // (programmed) Frame start (in {row,col8} in burst8, bank ==0
243 // reg [2:0] frame_start_r;
244  reg [4:0] frame_start_r; // increased length to have time from line_unfinished to suspend (external)
245 // reg rst_frame_num_d;
246 
247  reg [MAX_TILE_WIDTH:0] tile_cols; // full number of columns in a tile
248 // reg [MAX_TILE_HEIGHT:0] tile_rows; // full number of rows in a tile
249 // reg [MAX_TILE_HEIGHT-1:0] tile_rows; // full number of rows in a tile
250  reg [MAX_TILE_HEIGHT:0] tile_rows; // full number of rows in a tile
251  reg [MAX_TILE_HEIGHT:0] tile_vstep; // vertical step between rows of tiles
252 
253  reg [MAX_TILE_WIDTH:0] num_cols_r; // full number of columns to transfer (not minus 1)
254  wire [MAX_TILE_WIDTH:0] num_cols_m1_w; // full number of columns to transfer minus 1 with extra bit
255  wire [MAX_TILE_HEIGHT:0] num_rows_m1_w; // full number of columns to transfer minus 1 with extra bit
256  reg [FRAME_WIDTH_BITS:0] frame_full_width; // (programmed) increment combined row/col when moving to the next line
257  // frame_width rounded up to max transfer (half page) if frame_width> max transfer/2,
258  // otherwise (smaller widths) round up to the nearest power of 2
259  reg [FRAME_WIDTH_BITS:0] window_width; // (programmed) 0- max
260  reg [FRAME_HEIGHT_BITS:0] window_height; // (programmed) 0- max
261 // reg [FRAME_HEIGHT_BITS:0] window_m_tile_height; // (window height-tile height
262  reg [FRAME_WIDTH_BITS-1:0] window_x0; // (programmed) window left
263  reg [FRAME_HEIGHT_BITS-1:0] window_y0; // (programmed) window top
264  reg [FRAME_WIDTH_BITS-1:0] start_x; // (programmed) normally 0, copied to curr_x on frame_start
265  reg [FRAME_HEIGHT_BITS-1:0] start_y; // (programmed) normally 0, copied to curr_y on frame_start
266  reg xfer_page_done_d; // next cycle after xfer_page_done
267 
269 
270  assign set_mode_w = cmd_we && (cmd_a== MCNTRL_TILED_MODE);
280 
283 
284 
285  //
286  // Set parameter registers
287  always @(posedge mclk) begin
288  if (mrst) mode_reg <= 0;
289  else if (set_mode_w) mode_reg <= cmd_data[11:0]; // [5:0];
290 
291  if (mrst) single_frame_r <= 0;
293 
294  if (mrst) rst_frame_num_r <= 0;
295  else rst_frame_num_r <= {rst_frame_num_r[0],
300 
301  if (mrst) start_range_addr <= 0;
303 
304  if (mrst) frame_size <= 0;
305  else if (set_start_addr_w) frame_size <= 1; // default number of frames - just one
307 
308  if (mrst) last_frame_number <= 0;
310 
311  if (mrst) frame_full_width <= 0;
313 
314  if (mrst) is_last_frame <= 0;
316 
317  if (mrst) frame_start_r <= 0;
319 
320  if (mrst) frame_en <= 0;
321  else if (single_frame_r || repeat_frames) frame_en <= 1;
322  else if (frame_start) frame_en <= 0;
323 
324  if (mrst) frame_number_cntr <= 0;
325  else if (rst_frame_num_r[0]) frame_number_cntr <= 0;
327 
328  if (mrst) frame_number_current <= 0;
329  else if (rst_frame_num_r[0]) frame_number_current <= 0;
331 
332  if (mrst) next_frame_start_addr <= start_range_addr; // just to use rst
335 
336  if (mrst) start_addr <= start_range_addr; // just to use rst
338 
339 
340  if (mrst) begin
341  window_width <= 0;
342  window_height <= 0;
343  end else if (set_window_wh_w) begin
346  end
347 
348  if (mrst) begin
349  tile_cols <= 0;
350  tile_rows <= 0;
351  tile_vstep <= 0;
352  end else if (set_tile_whs_w) begin
356  end
357 
358  if (mrst) begin
359  window_x0 <= 0;
360  window_y0 <= 0;
361  end else if (set_window_x0y0_w) begin
364  end
365 
366  if (mrst) begin
367  start_x <= 0;
368  start_y <= 0;
369  end else if (set_window_start_w) begin
372  end
373 
374  end
375  assign mul_rslt_w= frame_y8_r * frame_full_width_r; // 5 MSBs will be discarded
376 // assign xfer_start= xfer_start_r[0];
381  assign calc_valid= par_mod_r[PAR_MOD_LATENCY-1]; // MSB, longest 0
382  assign frame_done= frame_done_r;
384  assign pre_want= chn_en && busy_r && !want_r && !xfer_start_r[0] && calc_valid && !last_block && !suspend && !(|frame_start_r);
385  assign last_in_row_w=(row_left=={{(FRAME_WIDTH_BITS-MAX_TILE_WIDTH){1'b0}},num_cols_r}); // what if it crosses page? OK, num_cols_r & row_left know that
386 // tiles must completely fit window
387 // all window should be covered (tiles may extend):
389  //window_m_tile_height
390  assign xfer_want= want_r;
391  assign xfer_need= need_r;
392  assign xfer_bank= bank_reg[2*3 +: 3]; // TODO: just a single reg layer
393  assign xfer_row= row_col_r[NUM_RC_BURST_BITS-1:COLADDR_NUMBER-3] ; // memory row
394  assign xfer_col= row_col_r[COLADDR_NUMBER-4:0]; // start memory column in 8-bursts
395 // assign line_unfinished = line_unfinished_r[FRAME_HEIGHT_BITS +: FRAME_HEIGHT_BITS];
397 
398  assign chn_en = mode_reg[MCONTR_LINTILE_NRESET] & mode_reg[MCONTR_LINTILE_EN]; // enable requests by channel (continue ones in progress)
399  assign chn_rst = ~mode_reg[MCONTR_LINTILE_NRESET]; // resets command, including fifo;
400  assign cmd_wrmem = mode_reg[MCONTR_LINTILE_WRITE];// 0: read from memory, 1:write to memory
401  assign cmd_extra_pages = mode_reg[MCONTR_LINTILE_EXTRAPG+:MCONTR_LINTILE_EXTRAPG_BITS]; // external module needs more than 1 page
402  assign keep_open= mode_reg[MCONTR_LINTILE_KEEP_OPEN]; // keep banks open (will be used only if number of rows <= 8
403  assign byte32= mode_reg[MCONTR_LINTILE_BYTE32]; // use 32-byte wide columns in each tile (false - 16-byte)
406  assign status_data= {frame_finished_r, busy_r};
407  assign pgm_param_w= cmd_we;
409  assign num_cols_m1_w= num_cols_r-1;
410  assign num_rows_m1_w= tile_rows-1; // now number of rows == tile height
411  assign num_cols_m1= num_cols_m1_w[MAX_TILE_WIDTH-1:0]; // remove MSB
412  assign num_rows_m1= num_rows_m1_w[MAX_TILE_HEIGHT-1:0]; // remove MSB
414 
417 
419 
420  integer i;
424  assign xfer_limited_by_mem_page= keep_open && (mem_page_left < {EXTRA_BITS,lim_by_tile_width}); // if not keep_open - no need to break
425  always @(posedge mclk) begin // TODO: Match latencies (is it needed?) Reduce consumption by CE?
426  // cycle 1
427  if (recalc_r[0]) begin
428  frame_x <= curr_x + window_x0;
429  frame_y <= curr_y + window_y0;
430  next_y <= curr_y + tile_vstep;
431  row_left <= window_width - curr_x; // 14 bits - 13 bits
432  end
433 // registers to be absorbed in DSP block
434  frame_y8_r <= frame_y[FRAME_HEIGHT_BITS-1:3]; // lat=2 // if (recalc_r[2]) begin
435  frame_full_width_r <= frame_full_width; //(cycle 2) // if (recalc_r[2]) begin
436  start_addr_r <= start_addr; // // if (recalc_r[2]) begin
437  mul_rslt <= mul_rslt_w[MPY_WIDTH-1:0]; // frame_y8_r * frame_width_r; // 7 bits will be discarded lat=3; if (recalc_r[3]) begin
438  line_start_addr <= start_addr_r+mul_rslt; // lat=4 if (recalc_r[4]) begin
439 // TODO: Verify MPY/register timing above
440  if (recalc_r[5]) begin // cycle 6
443  end
444  bank_reg[0 +: 3] <= frame_y[2:0]; //TODO: is it needed - a pipeline for the bank? - remove!
445  for (i=0; i<2; i = i+1)
446  bank_reg[(i+1)*3 +: 3] <= bank_reg[i*3 +: 3];
447 
448  if (recalc_r[6]) begin // cycle 7
451  tile_cols:
452  row_left[MAX_TILE_WIDTH:0]; // 7 bits, max 'h40
453  end
454 
455  if (recalc_r[7]) begin // cycle 8
461  end
462  if (recalc_r[8]) begin // cycle 9
464  end
465  end
466 
467 // now have row start address, bank and row_left ;
468 // calculate number to read (min of row_left, maximal xfer and what is left in the DDR3 page
470  always @(posedge mclk) begin
471  if (mrst) par_mod_r<=0;
472  else if (pgm_param_w ||
473  xfer_start_r[0] ||
474  chn_rst ||
475  frame_start_r[0]) par_mod_r<=0;
476  else par_mod_r <= {par_mod_r[PAR_MOD_LATENCY-2:0], 1'b1};
477 
478  if (mrst) chn_rst_d <= 0;
479  else chn_rst_d <= chn_rst;
480 
481  if (mrst) recalc_r<=0;
482  else if (chn_rst) recalc_r<=0;
483 // else recalc_r <= {recalc_r[PAR_MOD_LATENCY-2:0], (xfer_grant & ~chn_rst) | pgm_param_w | (chn_rst_d & ~chn_rst)};
484  else recalc_r <= {recalc_r[PAR_MOD_LATENCY-2:0],
486 
487  if (mrst) busy_r <= 0;
488  else if (chn_rst) busy_r <= 0;
489  else if (frame_start_r[0]) busy_r <= 1;
490  else if (frame_done_r) busy_r <= 0;
491 
492  if (mrst) xfer_page_done_d <= 0;
494 
495  if (mrst) xfer_start_r <= 0;
496  else xfer_start_r <= {xfer_start_r[1:0],xfer_grant && !chn_rst};
497 
498  if (mrst) xfer_start_rd_r <= 0;
499  else xfer_start_rd_r <= xfer_grant && !chn_rst && !cmd_wrmem && !byte32;
500 
501  if (mrst) xfer_start_wr_r <= 0;
503 
504  if (mrst) xfer_start32_rd_r <= 0;
506 
507  if (mrst) xfer_start32_wr_r <= 0;
509 
510  if (mrst) continued_tile <= 1'b0;
511  else if (chn_rst) continued_tile <= 1'b0;
512  else if (frame_start_r[0]) continued_tile <= 1'b0;
513  else if (xfer_start_r[0]) continued_tile <= xfer_limited_by_mem_page_r; // only set after actual start if it was partial, not after parameter change
514 
515  if (mrst || disable_need) need_r <= 0;
516  else if (chn_rst || xfer_grant) need_r <= 0;
517  else if ((pre_want || want_r) && (page_cntr>=3)) need_r <= 1; // may raise need if want was already set
518 
519  if (mrst) want_r <= 0;
520  else if (chn_rst || xfer_grant) want_r <= 0;
521  else if (pre_want && (page_cntr>{1'b0,cmd_extra_pages})) want_r <= 1;
522 
523  if (mrst) page_cntr <= 0;
524  else if (frame_start_r[0]) page_cntr <= cmd_wrmem?0:4;
525  else if ( start_not_partial && !next_page) page_cntr <= page_cntr - 1;
526  else if (!start_not_partial && next_page) page_cntr <= page_cntr + 1;
527 
528  if (mrst) xfer_page_rst_r <= 1;
530 
531  if (mrst) xfer_page_rst_pos <= 1;
533 
534 // increment x,y (two cycles)
535  if (mrst) curr_x <= 0;
536  else if (chn_rst || frame_start_r[0]) curr_x <= start_x;
537  else if (xfer_start_r[0]) curr_x <= last_in_row?0: curr_x + num_cols_r;
538 
539  if (mrst) curr_y <= 0;
540  else if (chn_rst || frame_start_r[0]) curr_y <= start_y;
541  else if (xfer_start_r[0] && last_in_row) curr_y <= next_y[FRAME_HEIGHT_BITS-1:0];
542 
543  if (mrst) last_block <= 0;
544  else if (chn_rst || !busy_r) last_block <= 0;
545  else if (xfer_start_r[0]) last_block <= last_row_w && last_in_row_w;
546 
547  // start_not_partial is not generated when partial (first of 2, caused by a tile crossing memory page) transfer is requested
548  // here we need to cout all requests - partial or not
549  if (mrst) pending_xfers <= 0;
550  else if (chn_rst || !busy_r) pending_xfers <= 0;
551  else if ( xfer_start_r[0] && !xfer_page_done) pending_xfers <= pending_xfers + 1;
552  else if (!xfer_start_r[0] && xfer_page_done) pending_xfers <= pending_xfers - 1; // page done is not generated on partial (first) pages
553 
554  // single cycle (sent out)
555  if (mrst) frame_done_r <= 0;
557 
558  // turns and stays on (used in status)
559  if (mrst) frame_finished_r <= 0;
560  else if (chn_rst || frame_start_r[0]) frame_finished_r <= 0;
561  else if (frame_done_r) frame_finished_r <= 1;
562  //line_unfinished_r cmd_wrmem
563 /*
564  if (mrst) line_unfinished_r[0 +: FRAME_HEIGHT_BITS] <= 0; //{FRAME_HEIGHT_BITS{1'b0}};
565  else if (chn_rst || frame_start_r[0]) line_unfinished_r[0 +: FRAME_HEIGHT_BITS] <= window_y0+start_y;
566  else if (xfer_start_r[2]) line_unfinished_r[0 +: FRAME_HEIGHT_BITS] <= window_y0+next_y[FRAME_HEIGHT_BITS-1:0]; // latency 2 from xfer_start
567 
568  if (mrst) line_unfinished_r[FRAME_HEIGHT_BITS +: FRAME_HEIGHT_BITS] <= 0; //{FRAME_HEIGHT_BITS{1'b0}};
569  else if (chn_rst || frame_start_r[2]) line_unfinished_r[FRAME_HEIGHT_BITS +: FRAME_HEIGHT_BITS] <= window_y0+start_y; // _r[0] -> _r[2] to make it simultaneous with frame_number
570 
571  // in read mode advance line number ASAP
572  else if (xfer_start_r[2] && !cmd_wrmem) line_unfinished_r[FRAME_HEIGHT_BITS +: FRAME_HEIGHT_BITS] <= window_y0+next_y[FRAME_HEIGHT_BITS-1:0]; // latency 2 from xfer_start
573  // in write mode advance line number only when it is guaranteed it will be the first to actually access memory
574  else if (xfer_grant && cmd_wrmem) line_unfinished_r[FRAME_HEIGHT_BITS +: FRAME_HEIGHT_BITS] <= line_unfinished_r[0 +: FRAME_HEIGHT_BITS];
575 */
576 /*
577  if (mrst) line_unfinished_relw_r <= 0;
578  else if (cmd_wrmem && (frame_start_r[1] || !chn_en)) line_unfinished_relw_r <= start_y;
579  else if ((!cmd_wrmem && recalc_r[1]) || xfer_start_r[2]) line_unfinished_relw_r <= next_y[FRAME_HEIGHT_BITS-1:0];
580  // xfer_start_r[2] and recalc_r[1] are at the same time
581 
582  if (mrst || (frame_start || !chn_en)) line_unfinished_r <= {FRAME_HEIGHT_BITS{~cmd_wrmem}}; // lowest/highest value until valid
583  else if (recalc_r[2]) line_unfinished_r <= line_unfinished_relw_r + window_y0;
584 */
586 
587  if (mrst || (frame_start || !chn_en)) line_unfinished_r <= {FRAME_HEIGHT_BITS{~cmd_wrmem}}; // lowest/highest value until valid
589 
590  end
591  always @ (negedge mclk) begin
593  end
595  .ADDR (MCNTRL_TILED_ADDR),
596  .ADDR_MASK (MCNTRL_TILED_MASK),
597  .NUM_CYCLES (6),
598  .ADDR_WIDTH (4),
599  .DATA_WIDTH (32)
600  ) cmd_deser_32bit_i (
601  .rst (1'b0), // input
602  .clk (mclk), // input
603  .srst (mrst), // input
604  .ad (cmd_ad), // input[7:0]
605  .stb (cmd_stb), // input
606  .addr (cmd_a), // output[15:0]
607  .data (cmd_data), // output[31:0]
608  .we (cmd_we) // output
609  );
610 
612  .STATUS_REG_ADDR (MCNTRL_TILED_STATUS_REG_ADDR),
613  .PAYLOAD_BITS (2)
614  ) status_generate_i (
615  .rst (1'b0), // input
616  .clk (mclk), // input
617  .srst (mrst), // input
618  .we (set_status_w), // input
619  .wd (cmd_data[7:0]), // input[7:0]
620  .status (status_data), // input[25:0]
621  .ad (status_ad), // output[7:0]
622  .rq (status_rq), // output
623  .start (status_start) // input
624  );
625 endmodule
626 
627 
5530line_start_page_leftreg[COLADDR_NUMBER-4:0]
5474MCNTRL_TILED_WINDOW_X0Y0'h7
[FRAME_WIDTH_BITS:0] 5515rowcol_inc
5580pending_xfersreg[MCNTRL_TILED_PENDING_CNTR_BITS-1:0]
5479MCNTRL_TILED_FRAME_PAGE_RESET1'b0
5470MCNTRL_TILED_FRAME_SIZE'h3
5526curr_xreg[FRAME_WIDTH_BITS-1:0]
[MAX_TILE_HEIGHT-1:0] 5517num_cols_m1
5535mul_rsltreg[MPY_WIDTH-1:0]
5533frame_y8_rreg[FRAME_HEIGHT_BITS-4:0]
5609next_frame_start_addrreg[NUM_RC_BURST_BITS-1:0]
[COLADDR_NUMBER-3-MAX_TILE_WIDTH-1:0] 5629EXTRA_BITS0
5610frame_number_cntrreg[LAST_FRAME_BITS-1:0]
5570rst_frame_num_rreg[1:0]
5537bank_regreg[3*3-1:0]
5552par_mod_rreg[PAR_MOD_LATENCY-1:0]
5615tile_rowsreg[MAX_TILE_HEIGHT:0]
5626start_yreg[FRAME_HEIGHT_BITS-1:0]
status_generate_i status_generate
5472MCNTRL_TILED_FRAME_FULL_WIDTH'h5
[LAST_FRAME_BITS-1:0] 5504frame_number
5531frame_yreg[FRAME_HEIGHT_BITS-1:0]
5605start_range_addrreg[NUM_RC_BURST_BITS-1:0]
5553recalc_rreg[PAR_MOD_LATENCY-1:0]
5630xfer_limited_by_mem_pagewire
5465MCNTRL_TILED_ADDR'h120
5581row_col_rreg[NUM_RC_BURST_BITS-1:0]
5541mem_page_leftreg[COLADDR_NUMBER-3:0]
5529line_start_addrreg[NUM_RC_BURST_BITS-1:0]
5587cmd_datawire[31:0]
5621window_widthreg[FRAME_WIDTH_BITS:0]
5631xfer_limited_by_mem_page_rreg
5611frame_number_currentreg[LAST_FRAME_BITS-1:0]
5625start_xreg[FRAME_WIDTH_BITS-1:0]
[ADDR_MASK2!=0?2:ADDR_MASK1!=0?1:0:0] 9935we
Definition: cmd_deser.v:60
5523NUM_RC_BURST_BITSADDRESS_NUMBER+COLADDR_NUMBER-3
5478MCNTRL_TILED_PENDING_CNTR_BITS2
5543remainder_tile_widthwire[COLADDR_NUMBER-3:0]
5545leftover_colsreg[MAX_TILE_WIDTH-1:0]
5468MCNTRL_TILED_STATUS_CNTRL'h1
5604mode_regreg[11:0]
5620frame_full_widthreg[FRAME_WIDTH_BITS:0]
5532frame_xreg[FRAME_WIDTH_BITS-1:0]
5547xfer_start_rreg[2:0]
5524MPY_WIDTHNUM_RC_BURST_BITS
[MAX_TILE_WIDTH-1:0] 5516num_rows_m1
5618num_cols_m1_wwire[MAX_TILE_WIDTH:0]
5527curr_yreg[FRAME_HEIGHT_BITS-1:0]
5583line_unfinished_rreg[FRAME_HEIGHT_BITS-1:0]
5466MCNTRL_TILED_MASK'h7f0
5536start_addr_rreg[NUM_RC_BURST_BITS-1:0]
5563cmd_extra_pageswire[1:0]
5613frame_start_rreg[4:0]
[DATA_WIDTH-1:0] 9934data
Definition: cmd_deser.v:59
5608start_addrreg[NUM_RC_BURST_BITS-1:0]
5622window_heightreg[FRAME_HEIGHT_BITS:0]
5490MCONTR_LINTILE_DIS_NEED11
5477MCNTRL_TILED_STATUS_REG_ADDR'h5
5528next_yreg[FRAME_HEIGHT_BITS:0]
5585status_datawire[1:0]
5617num_cols_rreg[MAX_TILE_WIDTH:0]
5539row_leftreg[FRAME_WIDTH_BITS:0]
[7:0] 9931ad
Definition: cmd_deser.v:56
[ADDR_WIDTH-1:0] 9933addr
Definition: cmd_deser.v:58
[COLADDR_NUMBER-4:0] 5514xfer_col
[ADDRESS_NUMBER-1:0] 5513xfer_row
cmd_deser_32bit_i cmd_deser
5624window_y0reg[FRAME_HEIGHT_BITS-1:0]
5471MCNTRL_TILED_FRAME_LAST'h4
[FRAME_HEIGHT_BITS-1:0] 5502line_unfinished
5607last_frame_numberreg[LAST_FRAME_BITS-1:0]
5614tile_colsreg[MAX_TILE_WIDTH:0]
5542lim_by_tile_widthreg[MAX_TILE_WIDTH:0]
5582line_unfinished_relw_rreg[FRAME_HEIGHT_BITS-1:0]
5606frame_sizereg[NUM_RC_BURST_BITS-1:0]
[ALL_BITS-1:0] 10777status
5619num_rows_m1_wwire[MAX_TILE_HEIGHT:0]
5534frame_full_width_rreg[FRAME_WIDTH_BITS:0]
5475MCNTRL_TILED_WINDOW_STARTXY'h8
5616tile_vstepreg[MAX_TILE_HEIGHT:0]
5538mul_rslt_wwire[FRAME_WIDTH_BITS+FRAME_HEIGHT_BITS-3:0]
5623window_x0reg[FRAME_WIDTH_BITS-1:0]