reg[FRAME_WIDTH_BITS:0]row_left;// number of 8-bursts left in the current row
reglast_in_row;
reg[COLADDR_NUMBER-3:0]mem_page_left;// number of 8-bursts left in the pointed memory page
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
reg[NUM_XFER_BITS:0]lim_by_xfer;// number of bursts left limited by the longest transfer (currently 64)
// reg [MAX_TILE_WIDTH:0] lim_by_tile_width; // number of bursts left limited by the longest transfer (currently 64)
wire[COLADDR_NUMBER-3:0]remainder_in_xfer;//remainder_tile_width; // number of bursts postponed to the next partial tile (because of the page crossing) MSB-sign
regcontinued_xfer;//continued_tile; // this is a continued tile (caused by page crossing) - only once
reg[NUM_XFER_BITS-1:0]leftover;//[MAX_TILE_WIDTH-1:0] leftover_cols; // valid with continued_tile, number of columns left
reg[NUM_XFER_BITS:0]xfer_num128_r;// number of 128-bit words to transfer (8*16 bits) - full bursts of 8
// reg [NUM_XFER_BITS-1:0] xfer_num128_m1_r; // number of 128-bit words to transfer minus 1 (8*16 bits) - full bursts of 8
wirepgm_param_w;// program one of the parameters, invalidate calculated results for PAR_MOD_LATENCY
reg[2:0]xfer_start_r;// 1 hot started by xfer start only (not by parameter change)
regxfer_start_rd_r;
regxfer_start_wr_r;
reg[PAR_MOD_LATENCY-1:0]par_mod_r;
reg[PAR_MOD_LATENCY-1:0]recalc_r;// 1-hot CE for re-calculating registers
// SuppressWarnings VEditor unused
...
...
@@ -210,7 +209,6 @@ module mcntrl_linear_rw #(
regframe_finished_r;
wirelast_in_row_w;
wirelast_row_w;
// wire last_block_w;
reglast_block;
reg[MCNTRL_SCANLINE_PENDING_CNTR_BITS-1:0]pending_xfers;// number of requested,. but not finished block transfers
reg[NUM_RC_BURST_BITS-1:0]row_col_r;
...
...
@@ -258,7 +256,6 @@ module mcntrl_linear_rw #(
reg[LAST_FRAME_BITS-1:0]frame_number_current;
regis_last_frame;
// reg [2:0] frame_start_r;
reg[4:0]frame_start_r;// increased length to have time from line_unfinished to suspend (external)
reg[FRAME_WIDTH_BITS:0]frame_full_width;// (programmed) increment combined row/col when moving to the next line
...
...
@@ -270,6 +267,7 @@ module mcntrl_linear_rw #(
reg[FRAME_HEIGHT_BITS-1:0]window_y0;// (programmed) window top
reg[FRAME_WIDTH_BITS-1:0]start_x;// (programmed) normally 0, copied to curr_x on frame_start_late
reg[FRAME_HEIGHT_BITS-1:0]start_y;// (programmed) normally 0, copied to curr_y on frame_start_late
regxfer_done_d;// xfer_done delayed by 1 cycle (also includes xfer_skipped)
reg[MCNTRL_SCANLINE_DLY_WIDTH-1:0]start_delay;// how much to delay frame start
// parameter MCONTR_LINTILE_SKIP_LATE = 12, // skip actual R/W operation when it is too late, advance pointers NEW: Copied from LINEAR
parameterMCONTR_LINTILE_COPY_FRAME=13,// copy frame number from the master channel (single event, not a persistent mode)
parameterMCONTR_LINTILE_ABORT_LATE=14// abort frame if not finished by the new frame sync (wait pending memory)
)(
inputmrst,
inputmclk,
// programming interface
input[7:0]cmd_ad,// byte-serial command address/data (up to 6 bytes: AL-AH-D0-D1-D2-D3
inputcmd_stb,// strobe (with first byte) for the command a/d
output[7:0]status_ad,// byte-wide address/data
outputstatus_rq,// request to send downstream (last byte with rq==0)
inputstatus_start,// acknowledge of address (first byte) from downsteram
inputframe_start,// resets page, x,y, and initiates transfer requests (in write mode will wait for next_page)
outputframe_start_conf,// frame start modified by memory controller. Normally delayed by 1 cycle,
// or more if memory transactions are to be finished
inputnext_page,// page was read/written from/to 4*1kB on-chip buffer
outputframe_done,// single-cycle pulse when the full frame (window) was transferred to/from DDR3 memory
outputframe_finished,// turns on and stays on after frame_done
// optional I/O for channel synchronization
// 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
output[FRAME_HEIGHT_BITS-1:0]line_unfinished,// number of the current (unfinished ) line, RELATIVE TO FRAME, NOT WINDOW.
inputsuspend,// suspend transfers (from external line number comparator)
output[LAST_FRAME_BITS-1:0]frame_number,// current frame number (for multi-frame ranges)
outputframes_in_sync,// frame number valid for bonded mode //LINEAR: frame_set, // frame number is just set to a new value (can be used by slave to sync)
input[LAST_FRAME_BITS-1:0]master_frame,// current frame number of a master channel // LINEAR: nothing
inputmaster_set,// master frame number set (1-st cycle when new value is valid) // LINEAR: nothing
outputxfer_want,// "want" data transfer
outputxfer_need,// "need" - really need a transfer (only 1 page/ room for 1 page left in a buffer), want should still be set.
// LINEAR: output xfer_reject, // reject granted access (when skipping) (not used for compressor)
//
outputxfer_start_lin_rd,// LINEAR: initiate a transfer (next cycle after xfer_grant), following signals (up to xfer_partial) are valid
outputxfer_start_lin_wr,// LINEAR: initiate a transfer (next cycle after xfer_grant), following signals (up to xfer_partial) are valid
outputxfer_start_rd,// initiate a transfer (next cycle after xfer_grant), following signals (up to xfer_partial) are valid // LINEAR: DNU
outputxfer_start_wr,// initiate a transfer (next cycle after xfer_grant), following signals (up to xfer_partial) are valid // LINEAR: DNU
outputxfer_start32_rd,// initiate a transfer to 32-byte wide colums scanning in each tile // LINEAR: DNU
outputxfer_start32_wr,// initiate a transfer to 32-byte wide colums scanning in each tile // LINEAR: DNU
output[2:0]xfer_bank,// start bank address
output[ADDRESS_NUMBER-1:0]xfer_row,// memory row
output[COLADDR_NUMBER-4:0]xfer_col,// start memory column in 8-bursts
output[FRAME_WIDTH_BITS:0]rowcol_inc,// increment row+col (after bank) for the new scan line in 8-bursts (externally pad with 0)
output[MAX_TILE_WIDTH-1:0]num_rows_m1,// number of rows to read minus 1
output[MAX_TILE_HEIGHT-1:0]num_cols_m1,// number of 16-pixel columns to read (rows first, then columns) - 1
outputkeep_open,// (programmable bit)keep banks open (for <=8 banks only // LINEAR: DNU
// LINEAR: [NUM_XFER_BITS-1:0] xfer_num128, // number of 128-bit words to transfer (8*16 bits) - full bursts of 8 ( 0 - maximal length, 64)
output[MAX_TILE_WIDTH-1:0]xfer_num128,// number of 128-bit words to transfer (8*16 bits) - full bursts of 8 ( 0 - maximal length, 64)
// assign xfer_num128= num_cols_r[NUM_XFER_BITS-1:0]; // One bit less!
outputxfer_partial,// partial tile (first of 2) , sequencer will not generate page_next at the end of block
inputxfer_page_done,// transfer to/from the buffer finished (partial transfers should not generate), use rpage_nxt_chn@mclk
outputxfer_page_rst_wr,// reset buffer internal page - at each frame start or when specifically reset (write to memory channel), @posedge
outputxfer_page_rst_rd// reset buffer internal page - at each frame start or when specifically reset (read memory channel), @negedge
);
// FIXME: not all tile heights are valid (because of the banks)
//MAX_TILE_WIDTH
localparamNUM_RC_BURST_BITS=ADDRESS_NUMBER+COLADDR_NUMBER-3;//to spcify row and col8 == 22
localparamMPY_WIDTH=NUM_RC_BURST_BITS;// 22
localparamPAR_MOD_LATENCY=9;// TODO: Find actual worst-case latency for:
reg[FRAME_WIDTH_BITS-1:0]curr_x;// (calculated) start of transfer x (relative to window left)
reg[FRAME_HEIGHT_BITS-1:0]curr_y;// (calculated) start of transfer y (relative to window top)
reg[FRAME_HEIGHT_BITS:0]next_y;// (calculated) next row number
reg[NUM_RC_BURST_BITS-1:0]line_start_addr;// (calculated) Line start (in {row,col8} in burst8
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 (LINEAR: DNU)
// calculating full width from the frame width
//WARNING: [Synth 8-3936] Found unconnected internal register 'frame_y_reg' and it is trimmed from '16' to '3' bits. [memctrl/mcntrl_tiled_linear_rw.v:307]
// 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
// outside of the DSP 48. "dont_touch" seems to work here
`ifndefIGNORE_ATTR
(*keep="true"*)
`endif
reg[FRAME_HEIGHT_BITS-1:0]frame_y;// current line number referenced to the frame top
reg[FRAME_WIDTH_BITS-1:0]frame_x;// current column number referenced to the frame left
reg[FRAME_HEIGHT_BITS-4:0]frame_y8_r;// (13 bits) current row with bank removed, latency2 (to be absorbed when inferred DSP multipler)
reg[FRAME_WIDTH_BITS:0]frame_full_width_r;// (14 bit) register to be absorbed by MPY
reg[MPY_WIDTH-1:0]mul_rslt;
reg[NUM_RC_BURST_BITS-1:0]start_addr_r;// 22 bit - to be absorbed by DSP
reg[FRAME_WIDTH_BITS:0]row_left;// number of 8-bursts left in the current row
reglast_in_row;
reg[COLADDR_NUMBER-3:0]mem_page_left;// number of 8-bursts left in the pointed memory page
// (LINEAR: DNU)
reg[MAX_TILE_WIDTH:0]lim_by_tile_width;// number of bursts left limited by the longest transfer (currently 64) (LINEAR: DNU)
wire[COLADDR_NUMBER-3:0]remainder_tile_width;// number of bursts postponed to the next partial tile (because of the page crossing) MSB-sign
regcontinued_tile;// this is a continued tile (caused by page crossing) - only once
reg[MAX_TILE_WIDTH-1:0]leftover_cols;// valid with continued_tile, number of columns left
// (TILED: DNU)
// reg [NUM_XFER_BITS:0] lim_by_xfer; // number of bursts left limited by the longest transfer (currently 64) - using lim_by_tile_width for lim_by_xfer
// reg [MAX_TILE_WIDTH:0] lim_by_tile_width; // number of bursts left limited by the longest transfer (currently 64)
// wire [COLADDR_NUMBER-3:0] remainder_in_xfer ;// Use remainder_tile_width; // number of bursts postponed to the next partial tile (because of the page crossing) MSB-sign
// TODO: in linear mode use continued_tile instead of continued_xfer !
/// reg continued_xfer; //continued_tile; // this is a continued tile (caused by page crossing) - only once
// reg [NUM_XFER_BITS-1:0] leftover; //[MAX_TILE_WIDTH-1:0] leftover_cols; // valid with continued_tile, number of columns left
// LINEAR using leftover_cols instead of leftover
// TODO: LINEAR: use num_cols_r instead of xfer_num128_r
// reg [NUM_XFER_BITS:0] xfer_num128_r; // number of 128-bit words to transfer (8*16 bits) - full bursts of 8
// end of (TILED: DNU)
wirepgm_param_w;// program one of the parameters, invalidate calculated results for PAR_MOD_LATENCY
reg[2:0]xfer_start_r;
// (LINEAR: DNU)
regxfer_start_rd_r;
regxfer_start_wr_r;
regxfer_start32_rd_r;
regxfer_start32_wr_r;
// (TILED: DNU)
regxfer_start_lin_rd_r;
regxfer_start_lin_wr_r;
// end of (TILED: DNU)
reg[PAR_MOD_LATENCY-1:0]par_mod_r;
reg[PAR_MOD_LATENCY-1:0]recalc_r;// 1-hot CE for re-calculating registers
// SuppressWarnings VEditor unused
wirecalc_valid;// calculated registers have valid values - just for simulation
wirechn_en;// enable requests by channel (continue ones in progress), enable frame_start inputs
wirechn_rst;// resets command, including fifo;
regchn_rst_d;// delayed by 1 cycle do detect turning off
regaborting_r;// waiting pending memory transactions at if the frame was not finished at frame sync
regaborting_d;// aborting_r delayed by 1 cycle // (LINEAR: DNU)
// LINEAR: wire with the same name wire frame_start_mod = (frame_start_late && !busy_r) || frame_start_delayed; // when frame_start_delayed it will completely miss a frame_start_late
regframe_start_mod;// either original frame start pulse or delayed during abort (delayed by 1 cycle)
regxfer_page_rst_r=1;
regxfer_page_rst_pos=1;
regxfer_page_rst_neg=1;
reg[2:0]page_cntr;// to maintain requests - difference between client requests and generated requests
// partial (truncated by memory page) generated requests should not count
wirecmd_wrmem;//= MCNTRL_TILED_WRITE_MODE; // 0: read from memory, 1:write to memory (change to parameter?) // (LINEAR: DNU)
wire[1:0]cmd_extra_pages;// external module needs more than 1 page
// wire skip_too_late; // from LINEAR
wirelinear_mode;// use linear mode instead of tiles // (LINEAR: DNU)
wirebyte32;// use 32-byte wide colums in each tile (0 - use 16-byte ones) // (LINEAR: DNU)
reg[MCNTRL_TILED_PENDING_CNTR_BITS-1:0]pending_xfers;// number of requested,. but not finished block transfers (to genearate frame done) // LINEAR:MCNTRL_SCANLINE_PENDING_CNTR_BITS
reg[NUM_RC_BURST_BITS-1:0]row_col_r;
reg[FRAME_HEIGHT_BITS-1:0]line_unfinished_relw_r;
reg[FRAME_HEIGHT_BITS-1:0]line_unfinished_r;
wirepre_want;
regpre_want_r1;// LINEAR (equivalent)
`ifdefDEBUG_MCNTRL_TILED_EXTRA_STATUS
wire[13:0]status_data;
`else
`ifdefREPORT_FRAME_NUMBER
wire[LAST_FRAME_BITS+1:0]status_data;
`else
wire[1:0]status_data;
`endif
`endif
wire[3:0]cmd_a;
wire[31:0]cmd_data;
wirecmd_we;
wireset_mode_w;
wireset_status_w;
wireset_start_addr_w;
wireset_frame_size_w;
wireset_last_frame_w;
wireset_frame_width_w;
wireset_window_wh_w;
wireset_window_x0y0_w;
wireset_window_start_w;
wireset_tile_whs_w;
wirelsw13_zero=!(|cmd_data[FRAME_WIDTH_BITS-1:0]);// LSW 13 (FRAME_WIDTH_BITS) low bits are all 0 - set carry bit
wiremsw_zero=!(|cmd_data[31:16]);// MSW all bits are 0 - set carry bit
// start_not_partial is not generated when partial (first of 2, caused by a tile crossing memory page) transfer is requested
// here we need to cout all requests - partial or not
if(mrst)pending_xfers<=0;
elseif(chn_rst||!busy_r)pending_xfers<=0;
elseif(xfer_start_r[0]&&!xfer_page_done)pending_xfers<=pending_xfers+1;// LINEAR use xfer_done_skipped
elseif(!xfer_start_r[0]&&xfer_page_done)pending_xfers<=pending_xfers-1;// page done is not generated on partial (first) pages // LINEAR use xfer_done_skipped
if(mrst)frame_done_r<=0;
elseframe_done_r<=busy_r&&(pending_xfers==0)&&
((last_block&&xfer_page_done_d)||(aborting_r&&!want_r&&!want_d));// LINEAR use xfer_done_d instead of xfer_page_done_d (same)