jp_channel.v 81 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
/*!
 * <b>Module:</b>jp_channel
 * @file jp_channel.v
 * @date 2015-06-10  
 * @author Andrey Filippov     
 *
 * @brief Top module of JPEG/JP4 compressor channel
 *
 * @copyright Copyright (c) 2015 Elphel, Inc.
 *
 * <b>License:</b>
12 13 14 15 16 17 18 19 20 21 22 23 24
 *
 * jp_channel.v is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 *  jp_channel.v is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/> .
25 26 27 28 29 30
 *
 * Additional permission under GNU GPL version 3 section 7:
 * If you modify this Program, or any covered work, by linking or combining it
 * with independent modules provided by the FPGA vendor only (this permission
 * does not extend to any 3-rd party modules, "soft cores" or macros) under
 * different license terms solely for the purpose of generating binary "bitstream"
31
 * files and/or simulating the code, the copyright holders of this Program give
32 33
 * you the right to distribute the covered work without those independent modules
 * as long as the source code for them is available from the FPGA vendor free of
Andrey Filippov's avatar
Andrey Filippov committed
34
 * charge, and there is no dependence on any encrypted modules for simulating of
35 36 37
 * the combined code. This permission applies to you if the distributed code
 * contains all the components and scripts required to completely simulate it
 * with at least one of the Free Software programs.
38
 */
39 40 41
`timescale 1ns/1ps

module  jp_channel#(
42 43 44 45 46 47 48
        parameter CMPRS_NUMBER =             0,
        parameter CMPRS_GROUP_ADDR =         'h600,
        parameter CMPRS_BASE_INC =           'h10,
        parameter CMPRS_STATUS_REG_BASE=     'h10,
        parameter CMPRS_HIFREQ_REG_BASE=     'h14, 
        parameter CMPRS_STATUS_REG_INC=       1,
        parameter CMPRS_HIFREQ_REG_INC=       1,
49
        parameter CMPRS_MASK=                'h7f8,
50 51 52 53 54
        parameter CMPRS_CONTROL_REG=          0,
        parameter CMPRS_STATUS_CNTRL=         1,
        parameter CMPRS_FORMAT=               2,
        parameter CMPRS_COLOR_SATURATION=     3,
        parameter CMPRS_CORING_MODE=          4,
55
        parameter CMPRS_INTERRUPTS=           5,        
Andrey Filippov's avatar
Andrey Filippov committed
56
        parameter CMPRS_TABLES=               6, // 6(data)..7(address)
57 58 59 60
        parameter TABLE_QUANTIZATION_INDEX =  0,
        parameter TABLE_CORING_INDEX =        1,
        parameter TABLE_FOCUS_INDEX =         2,
        parameter TABLE_HUFFMAN_INDEX =       3,
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98

        parameter FRAME_HEIGHT_BITS=          16, // Maximal frame height 
        parameter LAST_FRAME_BITS=            16, // number of bits in frame counter (before rolls over)
        // Bit-fields in compressor control word
        parameter CMPRS_CBIT_RUN =            2, // bit # to control compressor run modes
        parameter CMPRS_CBIT_RUN_BITS =       2, // number of bits to control compressor run modes
        parameter CMPRS_CBIT_QBANK =          6, // bit # to control quantization table page
        parameter CMPRS_CBIT_QBANK_BITS =     3, // number of bits to control quantization table page
        parameter CMPRS_CBIT_DCSUB =          8, // bit # to control extracting DC components bypassing DCT
        parameter CMPRS_CBIT_DCSUB_BITS =     1, // bit # to control extracting DC components bypassing DCT
        parameter CMPRS_CBIT_CMODE =         13, // bit # to control compressor color modes
        parameter CMPRS_CBIT_CMODE_BITS =     4, // number of bits to control compressor color modes
        parameter CMPRS_CBIT_FRAMES =        15, // bit # to control compressor multi/single frame buffer modes
        parameter CMPRS_CBIT_FRAMES_BITS =    1, // number of bits to control compressor multi/single frame buffer modes
        parameter CMPRS_CBIT_BAYER =         20, // bit # to control compressor Bayer shift mode
        parameter CMPRS_CBIT_BAYER_BITS =     2, // number of bits to control compressor Bayer shift mode
        parameter CMPRS_CBIT_FOCUS =         23, // bit # to control compressor focus display mode
        parameter CMPRS_CBIT_FOCUS_BITS =     2, // number of bits to control compressor focus display mode
        // compressor bit-fields decode
        parameter CMPRS_CBIT_RUN_RST =        2'h0, // reset compressor, stop immediately
//      parameter CMPRS_CBIT_RUN_DISABLE =    2'h1, // disable compression of the new frames, finish any already started
        parameter CMPRS_CBIT_RUN_STANDALONE = 2'h2, // enable compressor, compress single frame from memory (async)
        parameter CMPRS_CBIT_RUN_ENABLE =     2'h3, // enable compressor, enable synchronous compression mode
        parameter CMPRS_CBIT_CMODE_JPEG18 =   4'h0, // color 4:2:0
        parameter CMPRS_CBIT_CMODE_MONO6 =    4'h1, // mono 4:2:0 (6 blocks)
        parameter CMPRS_CBIT_CMODE_JP46 =     4'h2, // jp4, 6 blocks, original
        parameter CMPRS_CBIT_CMODE_JP46DC =   4'h3, // jp4, 6 blocks, dc -improved
        parameter CMPRS_CBIT_CMODE_JPEG20 =   4'h4, // mono, 4 blocks (but still not actual monochrome JPEG as the blocks are scanned in 2x2 macroblocks)
        parameter CMPRS_CBIT_CMODE_JP4 =      4'h5, // jp4,  4 blocks, dc-improved
        parameter CMPRS_CBIT_CMODE_JP4DC =    4'h6, // jp4,  4 blocks, dc-improved
        parameter CMPRS_CBIT_CMODE_JP4DIFF =  4'h7, // jp4,  4 blocks, differential
        parameter CMPRS_CBIT_CMODE_JP4DIFFHDR =  4'h8, // jp4,  4 blocks, differential, hdr
        parameter CMPRS_CBIT_CMODE_JP4DIFFDIV2 = 4'h9, // jp4,  4 blocks, differential, divide by 2
        parameter CMPRS_CBIT_CMODE_JP4DIFFHDRDIV2 = 4'ha, // jp4,  4 blocks, differential, hdr,divide by 2
        parameter CMPRS_CBIT_CMODE_MONO1 =    4'hb, // mono JPEG (not yet implemented)
        parameter CMPRS_CBIT_CMODE_MONO4 =    4'he, // mono 4 blocks
        parameter CMPRS_CBIT_FRAMES_SINGLE =  0, //1, // use a single-frame buffer for images

99 100 101 102 103
        parameter CMPRS_COLOR18 =           0, // JPEG 4:2:0 with 18x18 overlapping tiles for de-bayer
        parameter CMPRS_COLOR20 =           1, // JPEG 4:2:0 with 18x18 overlapping tiles for de-bayer (not implemented)
        parameter CMPRS_MONO16 =            2, // JPEG 4:2:0 with 16x16 non-overlapping tiles, color components zeroed
        parameter CMPRS_JP4 =               3, // JP4 mode with 16x16 macroblocks
        parameter CMPRS_JP4DIFF =           4, // JP4DIFF mode TODO: see if correct
104 105 106 107 108 109 110 111 112 113 114 115
        parameter CMPRS_MONO8 =             7,  // Regular JPEG monochrome with 8x8 macroblocks (not yet implemented)
        
        parameter CMPRS_FRMT_MBCM1 =           0, // bit # of number of macroblock columns minus 1 field in format word
        parameter CMPRS_FRMT_MBCM1_BITS =     13, // number of bits in number of macroblock columns minus 1 field in format word
        parameter CMPRS_FRMT_MBRM1 =          13, // bit # of number of macroblock rows minus 1 field in format word
        parameter CMPRS_FRMT_MBRM1_BITS =     13, // number of bits in number of macroblock rows minus 1 field in format word
        parameter CMPRS_FRMT_LMARG =          26, // bit # of left margin field in format word
        parameter CMPRS_FRMT_LMARG_BITS =      5, // number of bits in left margin field in format word
        parameter CMPRS_CSAT_CB =              0, // bit # of number of blue scale field in color saturation word
        parameter CMPRS_CSAT_CB_BITS =        10, // number of bits in blue scale field in color saturation word
        parameter CMPRS_CSAT_CR =             12, // bit # of number of red scale field in color saturation word
        parameter CMPRS_CSAT_CR_BITS =        10, // number of bits in red scale field in color saturation word
116 117
        parameter CMPRS_CORING_BITS =          3,  // number of bits in coring mode
        
118 119 120 121
        parameter CMPRS_TIMEOUT_BITS=         12,
        parameter CMPRS_TIMEOUT=            1000,   // mclk cycles
        parameter NUM_FRAME_BITS =             4 // number of bits use for frame number 
        
122 123 124
`ifdef DEBUG_RING
        ,parameter DEBUG_CMD_LATENCY = 2 //SuppressThisWarning VEditor - not used
`endif        
125
        
126
)(
127
    input                         xclk,          // global clock input, compressor single clock rate
128
`ifdef  USE_XCLK2X    
129
    input                         xclk2x,        // global clock input, compressor double clock rate, nominally rising edge aligned
130
`endif    
131 132 133
    input                         mrst,          // @posedge mclk, sync reset
    input                         xrst,          // @posedge xclk, sync reset
    input                         hrst,          // @posedge xclk, sync reset
Andrey Filippov's avatar
Andrey Filippov committed
134
    
135
    // programming interface
136 137 138 139 140 141 142
    input                         mclk,          // global system/memory clock
    input                   [7:0] cmd_ad,        // byte-serial command address/data (up to 6 bytes: AL-AH-D0-D1-D2-D3 
    input                         cmd_stb,       // strobe (with first byte) for the command a/d
    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]
    output                        status_rq,     // input request to send status downstream
    input                         status_start,  // Acknowledge of the first status packet byte (address)
    output                        irq,           // processor interrupt
143
    
144
    // Buffer interface (buffer to be a part of the memory controller - it is connected there by a 64-bit data, here - by an 9-bit one
145
    input                         xfer_reset_page_rd, // from mcntrl_tiled_rw (
146 147

    input                         buf_wpage_nxt, // advance to next page memory interface writes to
148 149
    input                         buf_we,        // @!mclk write buffer from memory, increment write
    input                  [63:0] buf_din,       // data out 
150

151
    
152 153
    input                         page_ready_chn,     // single mclk (posedge)
    output                        next_page_chn,      // single mclk (posedge): Done with the page in the  buffer, memory controller may read more data 
154 155
// Master(sensor)/slave(compressor) synchronization signals
    output                        frame_start_dst,    // @mclk - trigger receive (tiledc) memory channel (it will take care of single/repetitive
156
                                                      // this output either follows vsync_late (reclocks it) or generated in non-bonded mode
157
                                                      // (compress from memory)
158 159 160
    input                         frame_start_conf,   // memory controller confirmed frame_start_dst - normally delayed by 1 clock,
                                                        // or more if there were outstanding memory transactions.                                                           
                                                      
161 162 163 164 165 166 167 168
    input [FRAME_HEIGHT_BITS-1:0] line_unfinished_src,// number of the current (unfinished ) line, in the source (sensor) channel (RELATIVE TO FRAME, NOT WINDOW?)
    input   [LAST_FRAME_BITS-1:0] frame_number_src,   // current frame number (for multi-frame ranges) in the source (sensor) channel
    input                         frame_done_src,     // single-cycle pulse when the full frame (window) was transferred to/from DDR3 memory 
                                                      // frame_done_src is later than line_unfinished_src/ frame_number_src changes
                                                      // Used withe a single-frame buffers
     
    input [FRAME_HEIGHT_BITS-1:0] line_unfinished_dst,// number of the current (unfinished ) line in this (compressor) channel
    input   [LAST_FRAME_BITS-1:0] frame_number_dst,   // current frame number (for multi-frame ranges) in this (compressor channel
169
    input                         frames_in_sync,     // frame number in destination memory channel is valid for bonded mode
170 171 172
    input                         frame_done_dst,     // single-cycle pulse when the full frame (window) was transferred to/from DDR3 memory
                                                      // use as 'eot_real' in 353 
    output                        suspend,            // suspend reading data for this channel - waiting for the source data
173 174
//    output                        master_follow,      // compressor is following sensor, copy sesnor frame number instead of reset. 
    
175 176
    output reg [LAST_FRAME_BITS-1:0] frame_number_finished,   // valid after stuffer done
    
177

178
// statistics data was not used in late nc353    
179 180 181 182
    input                         dccout,         //enable output of DC and HF components for brightness/color/focus adjustments
    input                   [2:0] hfc_sel,        // [2:0] (for autofocus) only components with both spacial frequencies higher than specified will be added
    output                        statistics_dv,
    output                 [15:0] statistics_do,
183 184 185 186 187

// Timestamp messages (@mclk)    
    input                         ts_pre_stb,  // @mclk - 1 cycle before receiving 8 bytes of timestamp data
    input                   [7:0] ts_data,     // timestamp data (s0,s1,s2,s3,us0,us1,us2,us3==0)
    
188 189
    output                        eof_written_mclk,
    output                        stuffer_done_mclk,
Andrey Filippov's avatar
Andrey Filippov committed
190
    
191
//    output                 [31:0] hifreq,             //  accumulated high frequency components in a frame sub-window
192
    input                         vsync_late,         // delayed start of frame, @mclk. In 353 it was 16 lines after VACT active
193 194
                                                      // source channel should already start, some delay give time for sequencer commands
                                                      // that should arrive before it
195
    input  [NUM_FRAME_BITS-1:0] frame_num_compressed,
196 197 198
    
    // Output interface to the AFI mux
    input                         hclk,
199
    input                         fifo_rst,      // reset FIFO (set read address to write, reset count)
200 201
    input                         fifo_ren,
    output                 [63:0] fifo_rdata,
202 203
    output                        fifo_eof,      // single rclk pulse signaling EOF
    input                         eof_written,   // confirm frame written over AFI to the system memory (single rclk pulse)
204
    output                        fifo_flush,    // EOF, need to output all what is in FIFO (Stays active until enough data chunks are read)
205 206
    output                        flush_hclk,    // output before writing last chunk - use it to suspend AFI to have
                                                 // last burst marked as the last one (otherwise last may be empty if frame had %4==0 chunks) 
207
    output                 [7:0]  fifo_count     // number of 32-byte chunks in FIFO
208 209 210 211 212
`ifdef DEBUG_RING       
    ,output                       debug_do, // output to the debug ring
     input                        debug_sl, // 0 - idle, (1,0) - shift, (1,1) - load // SuppressThisWarning VEditor - not used
     input                        debug_di  // input from the debug ring
`endif         
213
);
214 215 216
//`ifdef DEBUG_RING
//     assign  debug_do = debug_di; // just temporarily to short-circuit the ring
//`endif        
217

218 219 220 221 222
    localparam CMPRS_ADDR = CMPRS_GROUP_ADDR + CMPRS_NUMBER * CMPRS_BASE_INC;
    localparam CMPRS_STATUS_REG_ADDR = CMPRS_STATUS_REG_BASE + CMPRS_NUMBER *  CMPRS_STATUS_REG_INC;
    localparam CMPRS_HIFREQ_REG_ADDR = CMPRS_HIFREQ_REG_BASE + CMPRS_NUMBER *  CMPRS_HIFREQ_REG_INC;
    wire                      [31:0] hifreq;   //  accumulated high frequency components in a frame sub-window was output, now - with status
    
223
    // Control signals to be defined
224
    wire                             frame_en;           // if 0 - will reset logic immediately (but not page number)
225 226
    wire                             frame_start_xclk;   // re-clocked, parameters are copied at this pulse
    wire                             stuffer_en;         //  extended enable to allow stuffer to gracefully finish 
227
    
228
    wire                             frame_go=frame_en;  // start frame: if idle, will start reading data (if available),
229
                                      // if running - will not restart a new frame if 0.
230 231 232 233 234
    wire [CMPRS_FRMT_LMARG_BITS-1:0] left_marg;          // left margin (for not-yet-implemented) mono JPEG (8 lines tile row) can need 7 bits (mod 32 - tile)
    wire [CMPRS_FRMT_MBCM1_BITS-1:0] n_blocks_in_row_m1; // number of macroblocks in a macroblock row minus 1
    wire [CMPRS_FRMT_MBRM1_BITS-1:0] n_block_rows_m1;    // number of macroblock rows in a frame minus 1
    wire                             ignore_color;       // zero Cb/Cr components (TODO: maybe include into converter_type?)
    wire                      [ 1:0] bayer_phase;        // [1:0])  bayer color filter phase 0:(GR/BG), 1:(RG/GB), 2: (BG/GR), 3: (GB/RG)
235
//    wire                             four_blocks;        // use only 6 blocks for the output, not 6
236 237 238 239 240 241 242 243 244 245 246
    wire                             jp4_dc_improved;    // in JP4 mode, compare DC coefficients to the same color ones
//    wire   [ 1:0] tile_margin;        // margins around 16x16 tiles (0/1/2)
//    wire   [ 2:0] tile_shift;         // tile shift from top left corner
    wire                      [ 2:0] converter_type;     // 0 - color18, 1 - color20, 2 - mono, 3 - jp4, 4 - jp4-diff, 7 - mono8 (not yet implemented)
    wire                             scale_diff;         // divide differences by 2 (to fit in 8-bit range)
    wire                             hdr;                // second green absolute, not difference
    wire                             subtract_dc;        // subtract/restore DC components
    wire    [CMPRS_CSAT_CB_BITS-1:0] m_cb;               // [9:0] scale for CB - default 0.564 (10'h90)
    wire    [CMPRS_CSAT_CR_BITS-1:0] m_cr;               // [9:0] scale for CR - default 0.713 (10'hb6)

    wire   [ 1:0] cmprs_fmode;        // focusing/overlay mode
247

248
    //TODO: assign next 5 values from converter_type[2:0]
249 250 251
    wire   [ 5:0] mb_w_m1;            // macroblock width minus 1
    wire   [ 5:0] mb_h_m1;            // macroblock height -1
    wire   [ 4:0] mb_hper;            // macroblock horizontal period (8/16) // 3 LSB not used
252 253
    wire   [ 1:0] tile_width;         // memory tile width (can be 128 for monochrome JPEG)   Can be 32/64/128: 0 - 16, 1 - 32, 2 - 64, 3 - 128
    wire          tile_col_width;     // 0 - 16 pixels,  1 -32 pixels
254 255 256 257 258 259 260 261
    
    
    // signals connecting modules: cmprs_macroblock_buf_iface_i and cmprs_pixel_buf_iface_i:
    wire          mb_pre_end;         // from cmprs_pixel_buf_iface - just in time to start a new macroblock w/o gaps
    wire          mb_release_buf;     // send required "next_page" pulses to buffer. Having rather long minimal latency in the memory
                                      // controller this can just be the same as mb_pre_end_in        
    wire          mb_pre_start;       // 1 clock cycle before stream of addresses to the buffer
    wire   [ 1:0] start_page;         // page to read next tile from (or first of several pages)
262 263 264 265 266 267
    wire   [ 6:0] macroblock_x;       // macroblock left pixel x relative to a tile (page) Maximal page - 128 bytes wide
    
    // signals connecting modules: cmprs_macroblock_buf_iface_i and cmprs_buf_average:
    
     wire         first_mb;           // output reg 
     wire         last_mb;            // output
268 269
    
    // signals connecting modules: cmprs_pixel_buf_iface_i and chn_rd_buf_i:
270 271
//    wire   [ 7:0] buf_di;             // data from the buffer
//    wire   [11:0] buf_ra;             // buffer read address (2 MSB - page number)
272
    wire   [ 1:0] buf_rd;             // buf {regen, re}
273
    wire   [ 7:0] buf_pxd;            // 8-bit pixel data from the memory buffer
274
    wire   [11:0] buf_ra;             // Memory buffer read address
275 276 277
    // signals connecting modules: chn_rd_buf_i and ???:
    wire   [ 7:0] mb_data_out;       // Macroblock data out in scanline order 
    wire          mb_pre_first_out;  // Macroblock data out strobe - 1 cycle just before data valid
278
    wire          mb_pre2_first_out;  // Macroblock data out strobe - 2 cycles just before data valid
279
//    wire          mb_data_valid;     // Macroblock data out valid
280
    
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
    wire           limit_diff     = 1'b1;  // as in the prototype - just a constant 1
    
    // signals connecting modules: csconvert and cmprs_buf_average:
    
 
    wire   [8:0]  signed_y; // was y_in
    wire   [8:0]  signed_c; // was c_in
    wire   [7:0]  yaddrw; 
    wire          ywe; 
    wire   [7:0]  caddrw; 
    wire          cwe; 
    wire          yc_pre_first_out; // pre first output from color converter (was  pre_first_out) - last cycle of writing (may inc wpage
    // How they are used? Can it be average instead?  
    wire   [7:0]  n000;  // number of all 0 in macroblock (255 for 256), valid only for color JPEG 
    wire   [7:0]  n255;  // number of all 255 in macroblock (255 for 256), valid only for color JPEG 
    
    // signals connecting modules: cmprs_buf_average and ???:

    wire   [ 9:0] yc_nodc;         // [9:0] data out (4:2:0) (signed, average=0)
    wire   [ 8:0] yc_avr;          // [8:0]    DC (average value) - RAM output, no register. For Y components 9'h080..9'h07f, for C - 9'h100..9'h0ff!
301
//    wire          yc_nodc_dv;         // out data valid (will go high for at least 64 cycles)
302 303 304 305
    wire          dct_start;         // single-cycle mark of the first_r pixel in a 64 (8x8) - pixel block
    wire   [ 2:0] color_tn;   // [2:0] tile number 0..3 - Y, 4 - Cb, 5 - Cr (valid with start)
    wire          color_first;      // sending first_r MCU (valid @ ds)
    wire          color_last;       // sending last_r MCU (valid @ ds)
306
// below signals valid at ds ( 1 later than tn, first_r, last_r)
307 308 309 310 311
    wire    [2:0] component_num;    //[2:0] - component number (YCbCr: 0 - Y, 1 - Cb, 2 - Cr, JP4: 0-1-2-3 in sequence (depends on shift) 4 - don't use
    wire          component_color;  // use color quantization table (YCbCR, jp4diff)
    wire          component_first;  // first this component in a frame (DC absolute, otherwise - difference to previous)
    
    wire          component_lastinmb; // last_r component in a macroblock;
312 313


314 315 316 317 318 319
// control signals valid @ mclk
    wire          cmprs_en_extend;  // extend cmprs_en_xclk to include flushing
    wire          cmprs_en_mclk;    // resets immediately
    wire          cmprs_run_mclk;   // enable propagation of vsync_late to frame_start_dst in bonded(sync to src) mode
    wire          cmprs_standalone; // single-cycle: generate a single frame_start_dst in unbonded (not synchronized) mode. cmprs_run should be off
    wire          sigle_frame_buf;  // input - memory controller uses a single frame buffer (frame_number_* == 0), use other sync
320

Andrey Filippov's avatar
Andrey Filippov committed
321 322


323
    wire          force_flush_long; 
Andrey Filippov's avatar
Andrey Filippov committed
324 325 326 327 328
///    wire          enc_last; not used
    wire   [15:0] enc_do; 
    wire          enc_dv;

//TODO: use next signals for status
329 330
    wire          stuffer_running_mclk;
    wire          reading_frame;
331
// SuppressWarnings VEditor unused 
332 333 334 335 336 337 338 339 340 341 342
    wire          frame_started_mclk;// store frame number ? Wrong, frame number should come from the sensor channel
    reg           stuffer_running_mclk_d;          
    reg [LAST_FRAME_BITS-1:0] frame_number_started;   // valid when stuffer started
    
//    output reg [LAST_FRAME_BITS-1:0] frame_number_finished,   // valid after stuffer done
    always @ (posedge mclk) begin
        stuffer_running_mclk_d <=stuffer_running_mclk;
        if ( stuffer_running_mclk && !stuffer_running_mclk_d) frame_number_started <= frame_number_dst;
        if (!stuffer_running_mclk &&  stuffer_running_mclk_d) frame_number_finished <= frame_number_started;
        
    end
343
    
344
`ifdef   USE_XCLK2X
345 346 347 348
    wire   [15:0] huff_do;     // output[15:0] reg 
    wire    [3:0] huff_dl;     // output[3:0] reg 
    wire          huff_dv;     // output reg 
    wire          flush;       // output reg @ negedge xclk2x
349
    wire          last_block;  // @negedge xxlk2x - used to copy timestamp in stuffer
350 351 352
    wire          stuffer_rdy; // receiver (bit stuffer) is ready to accept data;
`endif
    
353 354 355 356 357 358 359 360 361 362

    wire   [31:0] cmd_data;       // 32-bit data to write to tables and registers(LSB first) - from cmd_deser
    wire          cmd_we;         // control register write enable
    wire   [2:0]  cmd_a;          // control register write enable
    
    wire          set_ctrl_reg_w;
    wire          set_status_w;
    wire          set_format_w;
    wire          set_color_saturation_w;
    wire          set_coring_w;
363
    wire          set_interrupts_w;
364 365
    wire          set_tables_w;
    
366 367 368 369 370 371 372 373
    wire          stuffer_running;   // @negedge xclk2x from registering timestamp until done
    
    wire   [12:0] quant_do; 
    wire          quant_ds;
    wire   [15:0] quant_dc_tdo;// MSB aligned coefficient for the DC component (used in focus module)
    wire   [ 2:0] cmprs_qpage;
    wire   [ 2:0] coring_num;
    reg           dcc_en;
374
    
375 376 377 378

    wire   [15:0] dccdata; // was not used in late nc353
    wire          dccvld;  // was not used in late nc353
    
379 380 381 382 383
    assign set_ctrl_reg_w =          cmd_we && (cmd_a==       CMPRS_CONTROL_REG);
    assign set_status_w =            cmd_we && (cmd_a==       CMPRS_STATUS_CNTRL);
    assign set_format_w =            cmd_we && (cmd_a==       CMPRS_FORMAT);
    assign set_color_saturation_w =  cmd_we && (cmd_a==       CMPRS_COLOR_SATURATION);
    assign set_coring_w =            cmd_we && (cmd_a==       CMPRS_CORING_MODE);
384
    assign set_interrupts_w =        cmd_we && (cmd_a==       CMPRS_INTERRUPTS);
385
    assign set_tables_w =            cmd_we && ((cmd_a & 6)== CMPRS_TABLES);
386
    
387
    
388 389 390 391 392
`ifdef  USE_XCLK2X
      // re-sync to posedge xclk2x
    reg           xrst2xn;
    always @ (negedge xclk2x) xrst2xn <= xrst;
`endif    
393

394
`ifdef DEBUG_RING
395 396 397 398 399 400 401
    `ifndef   USE_XCLK2X
//        wire   [15:0] huff_do;     // output[15:0] reg 
//        wire    [3:0] huff_dl;     // output[3:0] reg 
//        wire          huff_dv;     // output reg 
//        wire          flush;       // output reg @ negedge xclk2x
        wire          last_block =  0;  // @negedge xxlk2x - used to copy timestamp in stuffer
        wire          stuffer_rdy = 1; // receiver (bit stuffer) is ready to accept data;
402
        wire          xrst2xn =     xrst;
403 404 405 406
    `endif



407 408 409 410 411 412 413 414 415 416 417 418 419 420
    reg [31:0] debug_fifo_in;
    reg [31:0] debug_fifo_out;
    reg [15:0] pre_start_cntr;
    reg [15:0] pre_end_cntr;
    reg        debug_frame_done;
    reg [15:0] pages_requested;
    reg [15:0] pages_got;
    wire [1:0] dbg_add_invalid;
    wire       dbg_mb_release_buf;
    reg [15:0] pages_needed;  // count number requested
    reg [15:0] page_requests; // count regardless of how many requested
    reg        dbg_stuffer_ext_running;
    reg        dbg_reset_fifo;
    wire [3:0] etrax_dma;
421 422 423 424 425
    wire       dbg_ts_rstb; // output
    wire [7:0] dbg_ts_dout; //output [7:0]
    wire [31:0] dbg_sec;
    wire [31:0] dbg_usec;
    
426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444
    wire       dbg_flushing;
    reg        dbg_flush_hclk;
    reg        dbg_en_hclk;
    
    reg        dbg_en_n2x;
    reg        dbg_last_block_persist;
    wire       dbg_test_lbw;
    wire       dbg_gotLastBlock;
    wire       dbg_frame_start_hclk;
    wire       dbg_last_DCAC;
    reg        dbg_gotLastBlock_persist;
    reg        dbg_lastBlock_sent;
    wire       dbg_fifo_or_full;
    wire       dbg_comp_lastinmbo;
    wire [2:0] dbg_block_mem_ra;
    reg [15:0] dbg_stb_cntr;
    reg [15:0] dbg_zds_cntr;
    wire [2:0] dbg_block_mem_wa;
    wire [2:0] dbg_block_mem_wa_save;
445 446
  `ifndef  USE_XCLK2X
        // temporarily assigning unused debug signals to 0
447 448 449 450 451 452 453 454 455
//        assign dbg_add_invalid =    0;
//        assign dbg_mb_release_buf = 0;
//        assign etrax_dma =          0;
//        assign dbg_ts_rstb =        0; // output
//        assign dbg_ts_dout =        0; //output [7:0]
        assign dbg_flushing =       0; // still not used in huffman_stuffer_meta 
//        assign dbg_test_lbw =       0;
//        assign dbg_gotLastBlock =   0;
        assign dbg_fifo_or_full =   0; // still not used in huffman_stuffer_meta
456 457
       
  `endif    
458
    timestamp_to_parallel dbg_timestamp_to_parallel_i (
459 460 461 462 463
  `ifdef  USE_XCLK2X     
        .clk      (~xclk2x),     // input
  `else
        .clk      (xclk),        // input
  `endif        
464 465
        .pre_stb  (dbg_ts_rstb), // input
        .tdata    (dbg_ts_dout), // input[7:0] 
466
        .sec      (dbg_sec),     // output[31:0] reg 
467
        .usec     (dbg_usec[19:0]),    // output[19:0] reg 
468
        .done()                  // output
469
    );
470 471 472
    
    
// cmprs_standalone - use to reset flush     
473
  `ifdef  USE_XCLK2X
474
    always @ (posedge ~xclk2x) begin
475 476 477
  `else  
    always @ (posedge xclk) begin
  `endif  
478 479 480 481 482 483
        dbg_reset_fifo <= fifo_rst;
        if (xrst2xn || dbg_reset_fifo) debug_fifo_in <= 0;
        else if (stuffer_dv)           debug_fifo_in <= debug_fifo_in + 1;
        
        dbg_en_n2x <= stuffer_en;
        
484 485
        if      (!dbg_en_n2x) dbg_last_block_persist <= 0;
        else if (last_block)  dbg_last_block_persist <= 1;
486 487 488 489 490

        if      (!dbg_en_n2x)      dbg_gotLastBlock_persist <= 0;
        else if (dbg_gotLastBlock) dbg_gotLastBlock_persist <= 1;
        
//dbg_last_block_persist        
491 492 493
    end
    always @ (posedge hclk) begin
        if      (hrst)     debug_fifo_out <= 0;
494
        else if (fifo_rst) debug_fifo_out <= 0; // debug_fifo_in >> 2;
495
        else if (fifo_ren) debug_fifo_out <= debug_fifo_out + 1;
496 497 498 499 500
        
        dbg_en_hclk <= cmprs_en_mclk;
        
        if (!dbg_en_hclk || dbg_frame_start_hclk) dbg_flush_hclk <= 0;
        else if (flush_hclk)                      dbg_flush_hclk <= 1;
501
    end
502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539
    
    always @ (posedge mclk) begin
        if      (!cmprs_en_mclk) pages_requested <= 0;
        else if  (next_page_chn) pages_requested <= pages_requested + 1;
        
        if      (!cmprs_en_mclk) pages_got <= 0;
        else if (page_ready_chn) pages_got <= pages_got + 1;
        
        if      (!cmprs_en_mclk) debug_frame_done <= 0;
        else if (frame_done_dst) debug_frame_done <= 1;
        
        if      (!cmprs_en_mclk || stuffer_done_mclk) dbg_stuffer_ext_running <= 0;
        else if (stuffer_running_mclk)                dbg_stuffer_ext_running <= 1;
        
    end
    
    always @ (posedge xclk) begin
        if         (!frame_en) pre_start_cntr <= 0;
        else if (mb_pre_start) pre_start_cntr <= pre_start_cntr + 1;

        if       (!frame_en) pre_end_cntr <= 0;
        else if (mb_pre_end) pre_end_cntr <= pre_end_cntr + 1;
        
        if      (!frame_en)          pages_needed <= 0;
        else if (dbg_mb_release_buf) pages_needed <= pages_needed + {14'b0,dbg_add_invalid};
        
        if      (!frame_en)          page_requests <= 0;
        else if (dbg_mb_release_buf) page_requests <= page_requests + 1;
        
        if (!frame_en)                                              dbg_lastBlock_sent <= 0;
        else if (enc_dv && enc_do[15] && enc_do[14] && enc_do[12] ) dbg_lastBlock_sent <= 1;
//        else if enc_do[15:0]
        
        if      (!frame_en) dbg_stb_cntr <= 0;
        else if (dct_start) dbg_stb_cntr <= dbg_stb_cntr + 1;
        
        if      (!frame_en) dbg_zds_cntr <= 0;
        else if  (focus_ds) dbg_zds_cntr <= dbg_zds_cntr + 1;
540

541 542 543
    end
//frame_start_dst
    
544
    debug_slave #(
545 546
        .SHIFT_WIDTH       (384),
        .READ_WIDTH        (384),
547 548 549 550 551 552 553 554 555
        .WRITE_WIDTH       (32),
        .DEBUG_CMD_LATENCY (DEBUG_CMD_LATENCY)
    ) debug_slave_i (
        .mclk       (mclk),          // input
        .mrst       (mrst),          // input
        .debug_di   (debug_di), // input
        .debug_sl   (debug_sl),      // input
        .debug_do   (debug_do), // output
        .rd_data   ({
556 557
        dbg_usec,
        dbg_sec,
558 559 560 561 562 563 564 565 566 567 568
        26'h0, dbg_block_mem_wa_save[2:0],dbg_block_mem_wa[2:0],
        dbg_zds_cntr[15:0],
        dbg_stb_cntr[15:0],
        pages_needed[15:0],
        page_requests[15:0],
        pre_end_cntr[15:0],
        pre_start_cntr[15:0],
        pages_got[15:0],
        pages_requested[15:0],
        dbg_comp_lastinmbo, dbg_block_mem_ra[2:0], debug_fifo_out[27:0],
        debug_fifo_in[31:0],
569
        color_last, dbg_last_block_persist, dbg_gotLastBlock, dbg_test_lbw, last_block,
570
         dbg_flush_hclk, dbg_flushing, stuffer_rdy, etrax_dma[3:0], dbg_stuffer_ext_running, stuffer_running_mclk, debug_frame_done, reading_frame,
571
        fifo_count[7:0],
572
        2'b0, dbg_fifo_or_full, dbg_gotLastBlock_persist, dbg_lastBlock_sent, dbg_last_DCAC, sigle_frame_buf, suspend,
573 574 575 576
        frame_number_dst[15:0],
        line_unfinished_dst[15:0],
        frame_number_src[15:0],
        line_unfinished_src[15:0]
577 578 579 580
        }), // input[31:0]
        .wr_data    (), // output[31:0]  - not used
        .stb        () // output  - not used
    );
581 582 583 584 585 586 587
//    wire [2:0] dbg_block_mem_wa;
//    wire [2:0] dbg_block_mem_wa_save;
    
    pulse_cross_clock dbg_fs_hclk_i (
        .rst       (!cmprs_en_mclk),
        .src_clk   (mclk),
        .dst_clk   (hclk),
588 589
//        .in_pulse  (frame_start_dst),
        .in_pulse  (frame_start_conf),
590 591 592 593
        .out_pulse (dbg_frame_start_hclk),
        .busy      ());
    
    
594 595
`endif    

596 597 598 599 600 601 602
    cmd_deser #(
        .ADDR       (CMPRS_ADDR),
        .ADDR_MASK  (CMPRS_MASK),
        .NUM_CYCLES (6),
        .ADDR_WIDTH (3),
        .DATA_WIDTH (32)
    ) cmd_deser_32bit_i (
Andrey Filippov's avatar
Andrey Filippov committed
603
        .rst        (1'b0), //rst),      // input
604
        .clk        (mclk),     // input
Andrey Filippov's avatar
Andrey Filippov committed
605
        .srst       (mrst),      // input
606 607 608 609 610 611
        .ad         (cmd_ad),   // input[7:0] 
        .stb        (cmd_stb),  // input
        .addr       (cmd_a),    // output[3:0] 
        .data       (cmd_data), // output[31:0] 
        .we         (cmd_we)    // output
    );
612
    
613 614 615 616 617 618 619 620 621 622 623 624 625
    wire [11:0] status_data; 
    cmprs_status  #(
        .NUM_FRAME_BITS(4)
    ) cmprs_status_i (
        .mrst                 (mrst),                  // input
        .mclk                 (mclk),                  // input
        .eof_written          (eof_written_mclk),      // input
        .stuffer_running      (stuffer_running_mclk),  // input
        .reading_frame        (reading_frame),         // input
        .frame_num_compressed (frame_num_compressed),  // input[3:0]
        .set_interrupts       (set_interrupts_w),      // input
        .data_in              (cmd_data[1:0]),         // input[1:0] 
        .status               (status_data),           // output[9:0] 
Andrey Filippov's avatar
Andrey Filippov committed
626
        .irq                  (irq)                    // output
627
    );
Andrey Filippov's avatar
Andrey Filippov committed
628

629 630
    status_generate #(
        .STATUS_REG_ADDR  (CMPRS_STATUS_REG_ADDR),
631
        .PAYLOAD_BITS     (14),
632 633 634
        .EXTRA_WORDS      (1),
        .EXTRA_REG_ADDR   (CMPRS_HIFREQ_REG_ADDR)
        
635
    ) status_generate_i (
Andrey Filippov's avatar
Andrey Filippov committed
636
        .rst              (1'b0),                      // input
637 638 639 640
        .clk              (mclk),                      // input
        .srst             (mrst),                      // input
        .we               (set_status_w),              // input
        .wd               (cmd_data[7:0]),             // input[7:0] 
Andrey Filippov's avatar
Andrey Filippov committed
641
        .status           ({hifreq,status_data,2'b0}), // input[45:0] 
642 643 644
        .ad               (status_ad),                 // output[7:0] 
        .rq               (status_rq),                 // output
        .start            (status_start)               // input
645
    );
Andrey Filippov's avatar
Andrey Filippov committed
646
    
647
//hifreq
648 649 650 651 652 653 654
// Not needed?
//    reg   emul64;
//    always @ (negedge mclk) begin
//        emul64 <= tile_width[1]; // will not work for monochrome (128 pixel wide) - chnge to 64?
//    end
    

655 656 657
    mcntrl_buf_rd #(
        .LOG2WIDTH_RD(3) // 64 bit external interface
    ) chn_rd_buf_i (
658 659 660 661 662 663 664 665
        .ext_clk      (xclk),               // input
        .ext_raddr    (buf_ra),             // input[11:0] 
        .ext_rd       (buf_rd[0]),          // input
        .ext_regen    (buf_rd[1]),          // input
        .ext_data_out (buf_pxd),            // output[7:0]
//        .emul64       (1'b0), //emul64),             // input Modify buffer addresses (used for JP4 until a 64-wide mode is implemented)
        .wclk         (!mclk),              // input
        .wpage_in     (2'b0),               // input[1:0] 
666
        .wpage_set    (xfer_reset_page_rd), // input  TODO: Generate @ negedge mclk on frame start
667 668 669 670
        .page_next    (buf_wpage_nxt),      // input
        .page         (),                   // output[1:0]
        .we           (buf_we),             // input
        .data_in      (buf_din)             // input[63:0] 
671
    );
Andrey Filippov's avatar
Andrey Filippov committed
672
    
673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722
    cmprs_cmd_decode #(
        .CMPRS_CBIT_RUN                  (CMPRS_CBIT_RUN),
        .CMPRS_CBIT_RUN_BITS             (CMPRS_CBIT_RUN_BITS),
        .CMPRS_CBIT_QBANK                (CMPRS_CBIT_QBANK),
        .CMPRS_CBIT_QBANK_BITS           (CMPRS_CBIT_QBANK_BITS),
        .CMPRS_CBIT_DCSUB                (CMPRS_CBIT_DCSUB),
        .CMPRS_CBIT_DCSUB_BITS           (CMPRS_CBIT_DCSUB_BITS),
        .CMPRS_CBIT_CMODE                (CMPRS_CBIT_CMODE),
        .CMPRS_CBIT_CMODE_BITS           (CMPRS_CBIT_CMODE_BITS),
        .CMPRS_CBIT_FRAMES               (CMPRS_CBIT_FRAMES),
        .CMPRS_CBIT_FRAMES_BITS          (CMPRS_CBIT_FRAMES_BITS),
        .CMPRS_CBIT_BAYER                (CMPRS_CBIT_BAYER),
        .CMPRS_CBIT_BAYER_BITS           (CMPRS_CBIT_BAYER_BITS),
        .CMPRS_CBIT_FOCUS                (CMPRS_CBIT_FOCUS),
        .CMPRS_CBIT_FOCUS_BITS           (CMPRS_CBIT_FOCUS_BITS),
        .CMPRS_CBIT_RUN_RST              (CMPRS_CBIT_RUN_RST),
        .CMPRS_CBIT_RUN_STANDALONE       (CMPRS_CBIT_RUN_STANDALONE),
        .CMPRS_CBIT_RUN_ENABLE           (CMPRS_CBIT_RUN_ENABLE),
        .CMPRS_CBIT_CMODE_JPEG18         (CMPRS_CBIT_CMODE_JPEG18),
        .CMPRS_CBIT_CMODE_MONO6          (CMPRS_CBIT_CMODE_MONO6),
        .CMPRS_CBIT_CMODE_JP46           (CMPRS_CBIT_CMODE_JP46),
        .CMPRS_CBIT_CMODE_JP46DC         (CMPRS_CBIT_CMODE_JP46DC),
        .CMPRS_CBIT_CMODE_JPEG20         (CMPRS_CBIT_CMODE_JPEG20),
        .CMPRS_CBIT_CMODE_JP4            (CMPRS_CBIT_CMODE_JP4),
        .CMPRS_CBIT_CMODE_JP4DC          (CMPRS_CBIT_CMODE_JP4DC),
        .CMPRS_CBIT_CMODE_JP4DIFF        (CMPRS_CBIT_CMODE_JP4DIFF),
        .CMPRS_CBIT_CMODE_JP4DIFFHDR     (CMPRS_CBIT_CMODE_JP4DIFFHDR),
        .CMPRS_CBIT_CMODE_JP4DIFFDIV2    (CMPRS_CBIT_CMODE_JP4DIFFDIV2),
        .CMPRS_CBIT_CMODE_JP4DIFFHDRDIV2 (CMPRS_CBIT_CMODE_JP4DIFFHDRDIV2),
        .CMPRS_CBIT_CMODE_MONO1          (CMPRS_CBIT_CMODE_MONO1),
        .CMPRS_CBIT_CMODE_MONO4          (CMPRS_CBIT_CMODE_MONO4),
        .CMPRS_CBIT_FRAMES_SINGLE        (CMPRS_CBIT_FRAMES_SINGLE),
        .CMPRS_COLOR18                   (CMPRS_COLOR18),
        .CMPRS_COLOR20                   (CMPRS_COLOR20),
        .CMPRS_MONO16                    (CMPRS_MONO16),
        .CMPRS_JP4                       (CMPRS_JP4),
        .CMPRS_JP4DIFF                   (CMPRS_JP4DIFF),
        .CMPRS_MONO8                     (CMPRS_MONO8),
        .CMPRS_FRMT_MBCM1                (CMPRS_FRMT_MBCM1),
        .CMPRS_FRMT_MBCM1_BITS           (CMPRS_FRMT_MBCM1_BITS),
        .CMPRS_FRMT_MBRM1                (CMPRS_FRMT_MBRM1),
        .CMPRS_FRMT_MBRM1_BITS           (CMPRS_FRMT_MBRM1_BITS),
        .CMPRS_FRMT_LMARG                (CMPRS_FRMT_LMARG),
        .CMPRS_FRMT_LMARG_BITS           (CMPRS_FRMT_LMARG_BITS),
        .CMPRS_CSAT_CB                   (CMPRS_CSAT_CB),
        .CMPRS_CSAT_CB_BITS              (CMPRS_CSAT_CB_BITS),
        .CMPRS_CSAT_CR                   (CMPRS_CSAT_CR),
        .CMPRS_CSAT_CR_BITS              (CMPRS_CSAT_CR_BITS),
        .CMPRS_CORING_BITS               (CMPRS_CORING_BITS)
    ) cmprs_cmd_decode_i (
Andrey Filippov's avatar
Andrey Filippov committed
723
//        .rst                (rst),                 // input
724 725
        .xclk               (xclk),                // input - global clock input, compressor single clock rate
        .mclk               (mclk),                // input - global system/memory clock
Andrey Filippov's avatar
Andrey Filippov committed
726
        .mrst               (mrst),                // input
727 728 729 730 731
        .ctrl_we            (set_ctrl_reg_w),      // input - control register write enable
        .format_we          (set_format_w),        // input - write number of tiles and left margin
        .color_sat_we       (set_color_saturation_w), // input - write color saturation values
        .coring_we          (set_coring_w),        // input - write color saturation values
        .di                 (cmd_data),            // input[31:0] - 32-bit data to write to control register (24LSB are used)
732 733
//        .frame_start        (frame_start_dst),     // input @mclk
        .frame_start        (frame_start_conf),     // input @mclk
734
        .frame_start_xclk   (frame_start_xclk),    // output re-clocked, parameters are copied during this pulse
735 736 737 738 739
        .cmprs_en_mclk      (cmprs_en_mclk),       // output
        .cmprs_en_extend    (cmprs_en_extend),     // input
        .cmprs_run_mclk     (cmprs_run_mclk),      // output reg 
        .cmprs_standalone   (cmprs_standalone),    // output reg 
        .sigle_frame_buf    (sigle_frame_buf),     // output reg 
740 741
        .cmprs_en_xclk      (frame_en),            // output reg
        .cmprs_en_late_xclk (stuffer_en),          // output reg - extended enable to allow stuffer to gracefully finish 
742 743 744 745 746
        .cmprs_qpage        (cmprs_qpage),         // output[2:0] reg 
        .cmprs_dcsub        (subtract_dc),         // output reg 
        .cmprs_fmode        (cmprs_fmode),         // output[1:0] reg 
        .bayer_shift        (bayer_phase),         // output[1:0] reg 
        .ignore_color       (ignore_color),        // output reg 
747 748
//      .four_blocks        (four_blocks),         // output reg Not used?
        .four_blocks        (),                    // output reg Not used?
749 750 751 752 753 754 755 756 757
        .jp4_dc_improved    (jp4_dc_improved),     // output reg 
        .converter_type     (converter_type),      // output[2:0] reg 
        .scale_diff         (scale_diff),          // output reg 
        .hdr                (hdr),                 // output reg 
        .left_marg          (left_marg),           // output[4:0] reg 
        .n_blocks_in_row_m1 (n_blocks_in_row_m1),  // output[12:0] reg 
        .n_block_rows_m1    (n_block_rows_m1),     // output[12:0] reg 
        .color_sat_cb       (m_cb),                // output[9:0] reg 
        .color_sat_cr       (m_cr),                // output[9:0] reg 
758
        .coring             (coring_num)           // output[2:0] reg 
759 760
    );

761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777
// set derived parameters from converter_type
//    wire   [ 2:0] converter_type;    // 0 - color18, 1 - color20, 2 - mono, 3 - jp4, 4 - jp4-diff, 7 - mono8 (not yet implemented)
    cmprs_tile_mode_decode #( // fully combinatorial
        .CMPRS_COLOR18   (CMPRS_COLOR18),
        .CMPRS_COLOR20   (CMPRS_COLOR20),
        .CMPRS_MONO16    (CMPRS_MONO16),
        .CMPRS_JP4       (CMPRS_JP4),
        .CMPRS_JP4DIFF   (CMPRS_JP4DIFF),
        .CMPRS_MONO8     (CMPRS_MONO8)
    ) cmprs_tile_mode_decode_i (
        .converter_type  (converter_type), // input[2:0] 
        .mb_w_m1         (mb_w_m1),        // output[5:0] reg 
        .mb_h_m1         (mb_h_m1),        // output[5:0] reg 
        .mb_hper         (mb_hper),        // output[4:0] reg 
        .tile_width      (tile_width),     // output[1:0] reg 
        .tile_col_width  (tile_col_width)  // output reg 
    );
778 779 780 781


    cmprs_frame_sync #(
        .FRAME_HEIGHT_BITS  (FRAME_HEIGHT_BITS),
782 783 784
        .LAST_FRAME_BITS    (LAST_FRAME_BITS),
        .CMPRS_TIMEOUT_BITS (CMPRS_TIMEOUT_BITS),
        .CMPRS_TIMEOUT      (CMPRS_TIMEOUT)
785
    ) cmprs_frame_sync_i (
Andrey Filippov's avatar
Andrey Filippov committed
786
//        .rst                (rst),                 // input
787 788
        .xclk               (xclk),                // input - global clock input, compressor single clock rate
        .mclk               (mclk),                // input - global system/memory clock
Andrey Filippov's avatar
Andrey Filippov committed
789 790
        .mrst               (mrst),                // input
        .xrst               (xrst),                // input
791
        .cmprs_en           (cmprs_en_mclk),       // input - @mclk 0 resets immediately
792
        .cmprs_en_extend    (cmprs_en_extend),     // output
793 794 795 796
        .cmprs_run          (cmprs_run_mclk),      // input - @mclk enable propagation of vsync_late to frame_start_dst in bonded(sync to src) mode
        .cmprs_standalone   (cmprs_standalone),    // input - @mclk single-cycle: generate a single frame_start_dst in unbonded (not synchronized) mode.
                                                   // cmprs_run should be off
        .sigle_frame_buf    (sigle_frame_buf),     // input - memory controller uses a single frame buffer (frame_number_* == 0), use other sync
797
        .vsync_late         (vsync_late),          // input - @mclk delayed start of frame, @xclk. In 353 it was 16 lines after VACT active
798
                                                   // source channel should already start, some delay give time for sequencer commands
799
                                                   // that should arrive before it, in NC393 it is programmable
800
        .frame_started      (first_mb && mb_pre_start), // @xclk started first macroblock (checking for broken frames)
801 802 803
        .frame_start_dst    (frame_start_dst),     // output reg @mclk - trigger receive (tiled) memory channel (it will take care of
                                                   // single/repetitive modes itself this output either follows vsync_late (reclocks it)
                                                   // or generated in non-bonded mode (compress from memory once)
804 805
        .frame_start_conf   (frame_start_conf),    // input: memory controller confirmed cmprs_frame_start_dst - normally delayed by 1 clock,
                                                   // or more if there were outstanding memory transactions.                                                           
806 807 808 809 810 811 812
        .line_unfinished_src(line_unfinished_src), // input[15:0] - number of the current (unfinished ) line, in the source (sensor) channel
        .frame_number_src   (frame_number_src),    // input[15:0] - current frame number (for multi-frame ranges) in the source (sensor) channel
        .frame_done_src     (frame_done_src),      // input - single-cycle pulse when the full frame (window) was transferred to/from DDR3 memory 
                                                   // frame_done_src is later than line_unfinished_src/ frame_number_src changes
                                                   // Used withe a single-frame buffers
        .line_unfinished    (line_unfinished_dst), // input[15:0] - number of the current (unfinished ) line in this (compressor) channel
        .frame_number       (frame_number_dst),    // input[15:0] - current frame number (for multi-frame ranges) in this (compressor channel
813
        .frames_in_sync     (frames_in_sync),      // frame number in destination memory channel is valid for bonded mode
814 815
        .frame_done         (frame_done_dst),      // input - single-cycle pulse when the full frame (window) was transferred to/from DDR3 memory
        .last_mb_started    (last_mb && mb_pre2_first_out), // input 
816
        .suspend            (suspend),             // output reg - suspend reading data for this channel - waiting for the source data
817
        .stuffer_running    (stuffer_running), // input
818 819
        .force_flush_long   (force_flush_long),         // output reg - @ mclk tried to start frame compression before the previous one was finished
        .stuffer_running_mclk(stuffer_running_mclk), // output
820 821
        .reading_frame      (reading_frame), // output
        .frame_started_mclk (frame_started_mclk)
822 823
    );

824
    cmprs_macroblock_buf_iface cmprs_macroblock_buf_iface_i (
Andrey Filippov's avatar
Andrey Filippov committed
825 826 827 828 829
//        .rst                (rst), // input
        .xclk               (xclk),               // input
        .mclk               (mclk),               // input
        .mrst               (mrst),               // input
        .xrst               (xrst),               // input
830
        .xfer_reset_page_rd (xfer_reset_page_rd), // input
Andrey Filippov's avatar
Andrey Filippov committed
831 832 833
        .page_ready_chn     (page_ready_chn),     // input
        .next_page_chn      (next_page_chn),      // output
        .frame_en           (frame_en),           // input
834
        .frame_start_xclk   (frame_start_xclk),   // input@posedge xclk - parameters are copied @ this pulse
Andrey Filippov's avatar
Andrey Filippov committed
835
        .frame_go           (frame_go),           // input - do not use - assign to frame_en? Running frames can be controlled by other means
836
        .cmprs_run_mclk     (cmprs_run_mclk),     // input used to reset frame_pre_run (enable vsync_late for the new frame after stop)
Andrey Filippov's avatar
Andrey Filippov committed
837
        .left_marg          (left_marg),          // input[4:0] 
838
        .n_blocks_in_row_m1 (n_blocks_in_row_m1), // input[12:0] 
Andrey Filippov's avatar
Andrey Filippov committed
839
        .n_block_rows_m1    (n_block_rows_m1),    // input[12:0] 
840
        .mb_w_m1            (mb_w_m1),            // input[5:0]   // macroblock width minus 1 // 3 LSB not used here
Andrey Filippov's avatar
Andrey Filippov committed
841 842 843 844 845 846 847 848 849
        .mb_hper            (mb_hper),            // input[4:0]   // macroblock horizontal period (8/16) // 3 LSB not used (set them 0)
        .tile_width         (tile_width),         // input[1:0]   // memory tile width. Can be 32/64/128: 0 - 16, 1 - 32, 2 - 64, 3 - 128
        .mb_pre_end_in      (mb_pre_end),         // input
        .mb_release_buf     (mb_release_buf),     // input
        .mb_pre_start_out   (mb_pre_start),       // output
        .start_page         (start_page),         // output[1:0] 
        .macroblock_x       (macroblock_x),       // output[6:0] 
        .first_mb           (first_mb),           // output reg 
        .last_mb            (last_mb)             // output
850 851 852 853
`ifdef DEBUG_RING
        ,.dbg_add_invalid   (dbg_add_invalid),
        .dbg_mb_release_buf (dbg_mb_release_buf)
`endif        
854 855 856 857 858 859 860 861 862 863 864 865 866 867
    );

    cmprs_pixel_buf_iface #(
        .CMPRS_PREEND_EARLY      (6), // TODO:Check / Adjust
        .CMPRS_RELEASE_EARLY     (16),
        .CMPRS_BUF_EXTRA_LATENCY (0),
        .CMPRS_COLOR18           (CMPRS_COLOR18),
        .CMPRS_COLOR20           (CMPRS_COLOR20),
        .CMPRS_MONO16            (CMPRS_MONO16),
        .CMPRS_JP4               (CMPRS_JP4),
        .CMPRS_JP4DIFF           (CMPRS_JP4DIFF),
        .CMPRS_MONO8             (CMPRS_MONO8)
         
    ) cmprs_pixel_buf_iface_i (
Andrey Filippov's avatar
Andrey Filippov committed
868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883
        .xclk               (xclk),             // input
        .frame_en           (frame_en),         // input
        .buf_di             (buf_pxd),          // input[7:0] 
        .buf_ra             (buf_ra),           // output[11:0] 
        .buf_rd             (buf_rd),           // output[1:0] 
        .converter_type     (converter_type),   // input[2:0] 
        .mb_w_m1            (mb_w_m1),          // input[5:0] 
        .mb_h_m1            (mb_h_m1),          // input[5:0] 
        .tile_width         (tile_width),       // input[1:0] 
        .tile_col_width     (tile_col_width),   // input
        .mb_pre_end         (mb_pre_end),       // output
        .mb_release_buf     (mb_release_buf),   // output
        .mb_pre_start       (mb_pre_start),     // input
        .start_page         (start_page),       // input[1:0] 
        .macroblock_x       (macroblock_x),     // input[6:0] 
        .data_out           (mb_data_out),      // output[7:0] // Macroblock data out in scanline order
884
        .pre_first_out      (mb_pre_first_out), // output // Macroblock data out strobe - 1 cycle just before data valid  == old pre_first_pixel?
885
//        .data_valid         (mb_data_valid) // output     // Macroblock data out valid
886 887
        .pre2_first_out     (mb_pre2_first_out), // output reg  
        .data_valid         () // output reg     // Macroblock data out valid Unused
888 889
    );

890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908
    csconvert #(
        .CMPRS_COLOR18   (CMPRS_COLOR18),
        .CMPRS_COLOR20   (CMPRS_COLOR20),
        .CMPRS_MONO16    (CMPRS_MONO16),
        .CMPRS_JP4       (CMPRS_JP4),
        .CMPRS_JP4DIFF   (CMPRS_JP4DIFF),
        .CMPRS_MONO8     (CMPRS_MONO8)
    ) csconvert_i (
        .xclk           (xclk),             // input
        .frame_en       (frame_en),         // input
        .converter_type (converter_type),   // input[2:0] 
        .ignore_color   (ignore_color),     // input
        .scale_diff     (scale_diff),       // input
        .hdr            (hdr),              // input
        .limit_diff     (limit_diff),       // input
        .m_cb           (m_cb),             // input[9:0] 
        .m_cr           (m_cr),             // input[9:0] 
        .mb_din         (mb_data_out),      // input[7:0] 
        .bayer_phase    (bayer_phase),      // input[1:0] 
909
        .pre2_first_in  (mb_pre2_first_out),// input
910 911 912 913 914 915 916 917 918 919
        .signed_y       (signed_y),         // output[8:0] reg 
        .signed_c       (signed_c),         // output[8:0] reg 
        .yaddrw         (yaddrw),           // output[7:0] reg 
        .ywe            (ywe),              // output reg 
        .caddrw         (caddrw),           // output[7:0] reg 
        .cwe            (cwe),              // output reg 
        .pre_first_out  (yc_pre_first_out), // output reg 
        .n000           (n000),             // output[7:0] reg 
        .n255           (n255)              // output[7:0] reg 
    );
920 921


922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937
    cmprs_buf_average #(
        .CMPRS_COLOR18   (CMPRS_COLOR18),
        .CMPRS_COLOR20   (CMPRS_COLOR20),
        .CMPRS_MONO16    (CMPRS_MONO16),
        .CMPRS_JP4       (CMPRS_JP4),
        .CMPRS_JP4DIFF   (CMPRS_JP4DIFF),
        .CMPRS_MONO8     (CMPRS_MONO8)
    ) cmprs_buf_average_i (
        .xclk               (xclk),             // input
        .frame_en           (frame_en),         // input
        .converter_type     (converter_type),   // input[2:0] 
        .pre_first_in       (mb_pre_first_out), // input
        .yc_pre_first_out   (yc_pre_first_out), // input
        .bayer_phase        (bayer_phase),      // input[1:0] 
        .jp4_dc_improved    (jp4_dc_improved),  // input
        .hdr                (hdr),              // input
938
        .subtract_dc_in     (subtract_dc),      // input
939 940 941 942 943 944 945 946
        .first_mb_in        (first_mb),         // input - calculate in cmprs_macroblock_buf_iface 
        .last_mb_in         (last_mb),          // input - calculate in cmprs_macroblock_buf_iface
        .yaddrw             (yaddrw),           // input[7:0] 
        .ywe                (ywe),              // input
        .signed_y           (signed_y),         // input[8:0] 
        .caddrw             (caddrw),           // input[7:0] 
        .cwe                (cwe),              // input
        .signed_c           (signed_c),         // input[8:0] 
947
        .dout               (yc_nodc),          // output[9:0] 
948
        .avr                (yc_avr),           // output[8:0] 
949 950
//        .dv                 (yc_nodc_dv),       // output
        .dv                 (),                 // output unused?
951 952 953 954 955 956 957 958
        .ds                 (dct_start),        // output
        .tn                 (color_tn),         // output[2:0] 
        .first              (color_first),      // output reg 
        .last               (color_last),       // output reg 
        .component_num      (component_num),    // output[2:0] 
        .component_color    (component_color),  // output
        .component_first    (component_first),  // output
        .component_lastinmb (component_lastinmb)// output reg 
959
    );
960 961
//  wire   [ 9:0] yc_nodc;         // [9:0] data out (4:2:0) (signed, average=0)

Andrey Filippov's avatar
Andrey Filippov committed
962 963 964

///TODO: Replace always@ with a module?

965 966
    wire          dct_last_in;
    wire          dct_pre_first_out;
967
//    wire          dct_dv;
968 969
    wire   [12:0] dct_out;
    
970 971 972 973 974
    
 //propagation of first block through compressor pipeline
 
    wire          first_block_color=(color_tn[2:0]==3'h0) && color_first;        // while color conversion,
    reg           first_block_color_after;  // after color conversion,
Andrey Filippov's avatar
Andrey Filippov committed
975 976
    reg           first_block_dct;          // after DCT
    wire          first_block_quant;        // after quantizer
977
    always @ (posedge xclk) begin
978 979 980 981
        if (dct_start)   first_block_color_after <= first_block_color;
        if (dct_last_in) first_block_dct   <= first_block_color_after;
    end
    
982 983 984 985
    // 8x8 DCT implementing Chen algorithm and 2 passes
    // Each pass (1d) uses 5 DSP48E1 modules (2 - multipliers and 3 SIMD (2x24) adder/subracters
    // Needs a small (<48, but did not calculate yet) pause between block if they did not come
    // immediately after each other. This pause is needed to restart pipeline
986 987 988 989 990 991 992 993 994 995 996 997
`ifdef DEBUG_COMPRESSOR_SCRAMBLE
    wire DBG_DCT_DV;
    wire [31:0] DBG_DCT_SCRAMBLED;
    scrambler #(
        .DATA_BYTE_WIDTH(4)
    ) scrambler_i (
        .clk      (xclk),                                                 // input wire 
        .rst      (first_block_dct && !DBG_DCT_DV && !dct_pre_first_out), // input wire 
        .val_in   (DBG_DCT_DV),                                           // input wire 
        .data_in  ({19'b0, dct_out}),                                     // input[31:0] wire 
        .data_out (DBG_DCT_SCRAMBLED)                                     // output[31:0] wire 
    );
998
    
999
`endif    
1000 1001 1002 1003 1004 1005
    dct2d8x8_chen #(
        .INPUT_WIDTH      (10),
        .OUTPUT_WIDTH     (13),
        .STAGE1_SAFE_BITS (3),
        .STAGE2_SAFE_BITS (3),
        .TRANSPOSE_WIDTH  (16),
1006 1007
        .TRIM_STAGE_1     (1),
        .TRIM_STAGE_2     (0),
1008 1009 1010
        .DSP_WIDTH        (24),
        .DSP_B_WIDTH      (18),
        .DSP_A_WIDTH      (25),
1011
        .DSP_P_WIDTH      (48)
1012
    ) dct2d8x8_chen_i (
1013 1014 1015 1016 1017 1018
        .clk           (xclk),              // input
        .rst           (!frame_en),         // input
        .start         (dct_start),         // input
        .xin           (yc_nodc),           // input[9:0] signed 
        .last_in       (dct_last_in),       // output reg 
        .pre_first_out (dct_pre_first_out), // output
1019 1020 1021
`ifdef DEBUG_COMPRESSOR_SCRAMBLE
        .dv            (DBG_DCT_DV),        // output
`else
1022
        .dv            (),                  // output
1023 1024
`endif        
        .d_out         (dct_out)            // output[12:0] signed 
1025 1026
    );
    
1027
    wire          quant_start;
1028
    dly_16 #(.WIDTH(1)) i_quant_start (.clk(xclk),.rst(1'b0), .dly(4'd0), .din(dct_pre_first_out), .dout(quant_start));    // dly=0+1
1029
 
1030 1031
    
    always @ (posedge xclk) begin
1032 1033 1034 1035
        if (!dccout) dcc_en <=1'b0;
        else if (dct_start && color_first && (color_tn[2:0]==3'b001)) dcc_en <=1'b1; // 3'b001 - closer to the first "start" in quantizator
    end
    
1036
    
1037 1038
//    wire          table_a_not_d; // writing table address /not data (a[0] from cmd_deser)
//  wire          table_we;      // writing to tables               (decoded stb from cmd_deser)
1039 1040
    wire          tser_a_not_d;  // address/not data distributed to submodules
    wire   [ 7:0] tser_d;        // byte-wide serialized tables address/data to submodules
1041 1042 1043 1044 1045 1046 1047
    wire   [ 3:0] tser_sel;      // vector of individual table selects (decoded from the 8 MSBs of the table address)
    wire          tser_qe = tser_sel[TABLE_QUANTIZATION_INDEX];  // write serialized table data to quantizer
    wire          tser_ce = tser_sel[TABLE_CORING_INDEX];        // write serialized table data to coring
    wire          tser_fe = tser_sel[TABLE_FOCUS_INDEX];         // write serialized table data to focusing
    wire          tser_he = tser_sel[TABLE_HUFFMAN_INDEX];       // write serialized table data to Huffman
//{tser_he,tser_fe,tser_ce,tser_qe}
// As all commands are 32-bit data, all 4 bytes will be written to a designated table (usually 2 of 16-bit writes)    
1048 1049 1050 1051 1052
    table_ad_transmit #(
        .NUM_CHANNELS(4),
        .ADDR_BITS(3)
    ) table_ad_transmit_i (
        .clk             (mclk),                  // input @posedge
1053
        .srst             (mrst),                  // @posedge mclk
Andrey Filippov's avatar
Andrey Filippov committed
1054
        .a_not_d_in      (cmd_a[0]),              // input writing table address /not data (a[0] from cmd_deser)
1055 1056
        .we              (set_tables_w),          // input writing to tables               (decoded stb from cmd_deser)
        .din             (cmd_data),              // input[31:0] 32-bit data to serialize/write to tables (LSB first) - from cmd_deser
1057 1058
        .ser_d           (tser_d),                // output[7:0] byte-wide serialized tables address/data to submodules
        .a_not_d         (tser_a_not_d),          // output reg address/not data distributed to submodules
1059 1060
//        .chn_en          ({tser_he,tser_fe,tser_ce,tser_qe}) // output[0:0] reg - table 1-hot select outputs
        .chn_en          (tser_sel) // output[0:0] reg - table 1-hot select outputs
1061 1062 1063 1064
    );
    
    
    
1065 1066 1067
    quantizer393 quantizer393_i (
        .clk                (xclk),                   // input
        .en                 (frame_en),               // input 
1068 1069 1070 1071 1072
        .mclk               (mclk),                   // input system clock, twqe, twce, ta,tdi - valid @posedge (ra, tdi - 2 cycles ahead (was negedge)
        .tser_qe            (tser_qe),                // input - write to a quantization table
        .tser_ce            (tser_ce),                // input - write to a coring table
        .tser_a_not_d       (tser_a_not_d),           // input - address/not data to tables
        .tser_d             (tser_d),                 // input[7:0] - byte-wide data to tables
1073
        .ctypei             (component_color),        // input component type input (Y/C)
1074 1075 1076
        .dci                (yc_avr),                 // input[8:0] - average value in a block - subtracted before DCT. now normal signed number
        .first_stb          (first_block_color),      // input - this is first stb pulse in a frame
        .stb                (dct_start),              // input - strobe that writes ctypei, dci
1077
        .tsi                (cmprs_qpage[2:0]),       // input[2:0] - table (quality) select [2:0]
1078 1079 1080 1081
        .pre_start          (dct_pre_first_out),      // input - marks first input pixel (one before)
        .first_in           (first_block_dct),        // input - first block in (valid @ start)
        .first_out          (first_block_quant),      // output reg - valid @ ds
        .di                 (dct_out[12:0]),          // input[12:0] -  pixel data in (signed)
1082
        .dout               (quant_do[12:0]),         // output[12:0] - pixel data out (AC is only 9 bits long?) - changed to 10
1083 1084 1085 1086 1087 1088 1089 1090
        .dv                 (),                       // output reg - data out valid
        .ds                 (quant_ds),               // output reg - data out strobe (one ahead of the start of dv)
        .dc_tdo             (quant_dc_tdo[15:0]),     // output[15:0] reg -  MSB aligned coefficient for the DC component (used in focus module)
        .dcc_en             (dcc_en),                 // input - enable dcc (sync to beginning of a new frame)
        .hfc_sel            (hfc_sel),                // input[2:0] - hight frequency components select [2:0] (includes components with both numbers >=hfc_sel
        .color_first        (color_first),            // input - first MCU in a frame
        .coring_num         (coring_num),             // input[2:0] - coring table pair number (0..7)
        .dcc_vld            (dccvld),                 // output reg  - single cycle when dcc_data is valid
1091 1092 1093 1094 1095 1096 1097 1098
        .dcc_data           (dccdata[15:0]),          // output[15:0] - dc component data out (for reading by software) 
        .n000               (n000),                   // input[7:0] - number of zero pixels (255 if 256) - to be multiplexed with dcc
        .n255               (n255)                    // input[7:0] - number of 0xff pixels (255 if 256) - to be multiplexed with dcc
    );

    // focus sharp module calculates amount of high-frequency components and optioanlly overlays/replaces actual image
    wire   [12:0] focus_do;     // output[12:0] reg  pixel data out, make timing ignore (valid 1.5 clk earlier that Quantizer output)
    wire          focus_ds;     // output reg data out strobe (one ahead of the start of dv)
1099
    // TODO: Verify focus_sharp393: quantizer output (with strobes) is now 2 cycles later than in 353 (relative to xdct out). Seems to be OK.
1100
    focus_sharp393 focus_sharp393_i (
1101
        .clk                (xclk),                   // input - pixel clock
1102
`ifdef  USE_XCLK2X        
1103
        .clk2x              (xclk2x),                 // input 2x pixel clock
1104 1105 1106
`else
        .clk2x              (xclk),                   // FIXME: fix the module not to use xclk2x
`endif        
1107
        .en                 (frame_en),               // input 
1108

1109
        .mclk               (mclk),                   // input system clock to write tables
1110
        .tser_we            (tser_fe),                // input - write to a focus sharpness table
1111 1112 1113
        .tser_a_not_d       (tser_a_not_d),           // input - address/not data to tables
        .tser_d             (tser_d),                 // input[7:0] - byte-wide data to tables
        
1114
        .mode               (cmprs_fmode[1:0]),  // input[1:0] focus mode (combine image with focus info) - 0 - none, 1 - replace, 2 - combine all,  3 - combine woi
1115 1116 1117 1118 1119 1120 1121 1122 1123
        .firsti             (color_first),            // input first macroblock
        .lasti              (color_last),             // input last macroblock
        .tni                (color_tn[2:0]),          // input[2:0] block number in a macronblock - 0..3 - Y, >=4 - color (sync to stb)
        .stb                (dct_start),              // input strobe that writes ctypei, dci
        .start              (quant_start),            // input marks first input pixel (needs 1 cycle delay from previous DCT stage)
        .di                 (dct_out),                // input[12:0] pixel data in (signed)
        .quant_ds           (quant_ds),               // input quantizator ds
        .quant_d            (quant_do[12:0]),         // input[12:0] quantizator data output
        .quant_dc_tdo       (quant_dc_tdo),           // input[15:0] MSB aligned coefficient for the DC component (used in focus module)
1124
        .dout               (focus_do[12:0]),         // output[12:0] reg  pixel data out, make timing ignore (valid 1.5 clk earlier that Quantizer output)
1125 1126 1127 1128
        .ds                 (focus_ds),               // output reg data out strobe (one ahead of the start of dv)
        .hifreq             (hifreq[31:0])            // output[31:0] reg accumulated high frequency components in a frame sub-window
    );

1129
    // Format DC components to be output as a mini-frame. Was not used in the late NC353 as the dma1 channel was used for IMU instead of dcc
Andrey Filippov's avatar
Andrey Filippov committed
1130
    wire          finish_dcc;
1131
`ifdef  USE_XCLK2X    
1132
    wire   [15:0] stuffer_do;
1133 1134 1135
`else
    wire   [31:0] stuffer_do;
`endif    
1136 1137
    wire          stuffer_dv;
    wire          stuffer_done;
Andrey Filippov's avatar
Andrey Filippov committed
1138
    
1139
`ifdef  USE_XCLK2X    
Andrey Filippov's avatar
Andrey Filippov committed
1140
    pulse_cross_clock finish_dcc_i (.rst(xrst2xn), .src_clk(~xclk2x), .dst_clk(xclk2x), .in_pulse(stuffer_done), .out_pulse(finish_dcc),.busy());
1141 1142 1143 1144
`else
    assign finish_dcc = stuffer_done;
`endif    

1145
    dcc_sync393 dcc_sync393_i (
1146
`ifdef  USE_XCLK2X    
1147
        .sclk               (xclk2x),                // input
1148 1149 1150
`else
        .sclk               (xclk),                  // input
`endif        
1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174
        .dcc_en             (dcc_en),                // input xclk rising, sync with start of the frame
        .finish_dcc         (finish_dcc),            // input @ sclk rising
        .dcc_vld            (dccvld),                // input xclk rising
        .dcc_data           (dccdata[15:0]),         // input[15:0] @clk rising
        .statistics_dv      (statistics_dv),         // output reg 
        .statistics_do      (statistics_do[15:0])    // output[15:0] reg @ sclk
    );
    

// generate DC data/strobe for the direct output (re) using sdram channel3 buffering
// encoderDCAC is updated to handle 13-bit signed data instead of the 12-bit. It will limit the values on ot's own
    encoderDCAC393 encoderDCAC393_i (
        .clk                (xclk),                   // input
        .en                 (frame_en),               // input 
        .lasti              (color_last),             // input - was "last MCU in a frame" (@ stb)
        .first_blocki       (first_block_color),      // input - first block in frame - save fifo write address (@ stb)
        .comp_numberi       (component_num[2:0]),     // input[2:0] - component number 0..2 in color, 0..3 - in jp4diff, >= 4 - don't use (@ stb)
        .comp_firsti        (component_first),        // input - first this component in a frame (reset DC) (@ stb)
        .comp_colori        (component_color),        // input - use color - huffman? (@ stb)
        .comp_lastinmbi     (component_lastinmb),     // input - last component in a macroblock (@ stb) is it needed?
        .stb                (dct_start),              // input - strobe that writes firsti, lasti, tni,average
        .zdi                (focus_do[12:0]),         // input[12:0] - zigzag-reordered data input
        .first_blockz       (first_block_quant),      // input - first block input (@zds)
        .zds                (focus_ds),               // input - strobe - one ahead of the DC component output
1175 1176 1177
`ifdef DEBUG_RING
        .last               (dbg_last_DCAC),                       // output reg - not used
`else
Andrey Filippov's avatar
Andrey Filippov committed
1178
        .last               (),                       // output reg - not used
1179
`endif
1180
        .dout               (enc_do[15:0]),           // output[15:0] reg 
1181
        .dv                 (enc_dv)                  // output reg 
1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192
`ifdef DEBUG_RING
        ,.comp_lastinmbo               (dbg_comp_lastinmbo)
        ,.dbg_block_mem_ra             (dbg_block_mem_ra)
        ,.dbg_block_mem_wa             (dbg_block_mem_wa)
        ,.dbg_block_mem_wa_save        (dbg_block_mem_wa_save)
`else
        ,.comp_lastinmbo               ()
        ,.dbg_block_mem_ra             ()
       ,.dbg_block_mem_wa              ()
        ,.dbg_block_mem_wa_save        ()
`endif
1193 1194
    );

1195 1196
//    wire [2:0] dbg_block_mem_wa;
//    wire [2:0] dbg_block_mem_wa_save;
1197

1198
`ifdef  USE_XCLK2X
1199 1200 1201 1202
    huffman393 i_huffman (
        .xclk               (xclk),                   // input
        .xclk2x             (xclk2x),                 // input
        .en                 (frame_en),               // input
1203 1204 1205 1206
        .mclk               (mclk),                   // input system clock to write tables
        .tser_we            (tser_he),                // input - write to a quantization table
        .tser_a_not_d       (tser_a_not_d),           // input - address/not data to tables
        .tser_d             (tser_d),                 // input[7:0] - byte-wide data to tables
1207 1208 1209
        .di                 (enc_do[15:0]),           // input[15:0] - specially RLL prepared 16-bit data (to FIFO)
        .ds                 (enc_dv),                 // input -  di valid strobe
        .rdy                (stuffer_rdy),            // input - receiver (bit stuffer) is ready to accept data
1210 1211 1212
        .do                 (huff_do[15:0]),          // output[15:0] reg 
        .dl                 (huff_dl[3:0]),           // output[3:0] reg 
        .dv                 (huff_dv),                // output reg 
1213 1214
        .flush              (flush),                  // output reg
        .last_block         (last_block),             // output reg
1215 1216 1217 1218
`ifdef DEBUG_RING
        .test_lbw           (dbg_test_lbw), // output reg ??
        .gotLastBlock       (dbg_gotLastBlock), // output ?? - unused (was for debug)
`else
1219 1220
        .test_lbw           (), // output reg ??
        .gotLastBlock       (), // output ?? - unused (was for debug)
1221
`endif        
1222
        .clk_flush          (hclk), // input
1223 1224 1225 1226 1227 1228
        .flush_clk          (flush_hclk), // output
`ifdef DEBUG_RING
        .fifo_or_full       (dbg_fifo_or_full)     // FIFO output register full - just for debuging
`else        
        .fifo_or_full       ()     // FIFO output register full - just for debuging
`endif        
1229 1230 1231 1232
    );
    

    stuffer393 stuffer393_i (
1233
//        .rst                 (rst),                  // input
1234
        .mclk                (mclk),                   // input
1235 1236 1237
        .mrst                (mrst),                   // input
        .xrst                (xrst),                   // input
        .last_block          (last_block),             // input @negedge xclk2x - use it to copy timestamp from fifo 
1238 1239 1240 1241
        .ts_pre_stb          (ts_pre_stb),             // input      1 cycle before timestamp data, @mclk
        .ts_data             (ts_data),                // input[7:0] 8-byte timestamp data (s0,s1,s2,s3,us0,us1,us2,us3==0)
        .color_first         (color_first),            // input valid @xclk - only for sec/usec
        .fradv_clk           (xclk),                   // input
1242
        .clk                 (xclk2x),                 // input clock - uses negedge inside
1243 1244 1245
        .en_in               (stuffer_en),             // 
        .flush               (flush),                  // input - flush output data (fill byte with 0, long word with FFs)
        .abort               (force_flush_long),       // @ any, extracts 0->1 and flushes
1246 1247 1248
        .stb                 (huff_dv),                // input
        .dl                  (huff_dl),                // input[3:0] number of bits to send (0 - 16) (0-16??)
        .d                   (huff_do),                // input[15:0] data to shift (only lower huff_dl bits are valid)
1249
        // outputs valid @negedge xclk2x 
1250 1251 1252 1253
        .rdy                 (stuffer_rdy),            // output - enable huffman encoder to proceed. Used as CE for many huffman encoder registers
        .q                   (stuffer_do),             // output[15:0] reg - output data
        .qv                  (stuffer_dv),             // output reg - output data valid
        .done                (stuffer_done),           // output 
1254 1255 1256
`ifdef DEBUG_RING
        .flushing            (dbg_flushing),                       // output reg Not used?
`else
1257
        .flushing            (),                       // output reg Not used?
1258
`endif        
1259
        .running             (stuffer_running)         // from registering timestamp until done
1260
`ifdef DEBUG_RING
1261 1262 1263 1264
   ,    .dbg_etrax_dma     (etrax_dma)
   ,.dbg_ts_rstb           (dbg_ts_rstb) // output
   ,.dbg_ts_dout           (dbg_ts_dout) //output [7:0]

1265
`endif        
1266 1267 1268 1269 1270
`ifdef debug_stuffer
       ,.etrax_dma_r(tst_stuf_etrax[3:0]) // [3:0] just for testing
       ,.test_cntr(test_cntr[3:0])
       ,.test_cntr1(test_cntr1[7:0])
`endif
1271
    );
1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297
    
//cat x393_testbench03-latest.log | grep "COMPRESSOR[32 ]*CHN" > compressors_out32.log    
    wire          eof_written_xclk2xn;
    pulse_cross_clock stuffer_done_mclk_i (.rst(xrst2xn), .src_clk(~xclk2x), .dst_clk(mclk), .in_pulse(stuffer_done), .out_pulse(stuffer_done_mclk),.busy());
    cmprs_out_fifo cmprs_out_fifo_i (
        // source (stuffer) clock domain
        .wclk                (~xclk2x),        // input source clock (2x pixel clock, inverted) - same as stuffer out
        .wrst                (xrst2xn),         // input mostly for simulation
        
        .we                  (stuffer_dv),     // @ posedge(~xclk2x) input write data from stuffer
        .wdata               ({stuffer_do[7:0],stuffer_do[15:8]}),     // input[15:0] data from stuffer module;
        .wa_rst              (!stuffer_en),    // input reset low address bits when stuffer is disabled (to make sure it is multiple of 32 bytes
        .wlast               (stuffer_done),   // input - written last 32 bytes of a frame (flush FIFO) - stuffer_done (has to be later than we)
        .eof_written_wclk    (eof_written_xclk2xn),    // output - AFI had transferred frame data to the system memory
        // AFI clock domain
        .rclk                (hclk),           // @posedge(hclk) input - AFI clock
        .rrst                (hrst),           // input - AFI clock
        .rst_fifo            (fifo_rst),       // input - reset FIFO (set read address to write, reset count)
        .ren                 (fifo_ren),       // input - fifo read from AFI channel mux
        .rdata               (fifo_rdata),     // output[63:0] - data to AFI channel mux (latency == 2 from fifo_ren)
        .eof                 (fifo_eof),       // output single hclk pulse signalling EOF
        .eof_written         (eof_written),    // input single hclk pulse confirming frame data is written to the system memory
        .flush_fifo          (fifo_flush),     // output level signalling that FIFO has data from the current frame (use short AXI burst if needed)
        .fifo_count          (fifo_count)      // output[7:0] - number of 32-byte chunks available in FIFO
    );
    pulse_cross_clock eof_written_mclk_i (.rst(xrst2xn), .src_clk(~xclk2x), .dst_clk(mclk), .in_pulse(eof_written_xclk2xn), .out_pulse(eof_written_mclk),.busy());
1298 1299 1300
//    pulse_cross_clock eof_written_mclk_i (.rst(xrst2xn), .src_clk(~xclk2x), .dst_clk(mclk), .in_pulse(eof_written_xclk2xn), .out_pulse(eof_written_mclk),.busy());
    
    
1301
  `ifdef DISPLAY_COMPRESSED_DATA
1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324
    integer dbg_stuffer_word_number;
    reg         dbg_odd_stuffer_dv;
    reg  [15:0] dbg_even_stuffer_do;
    wire [31:0] dbg_stuffer_do32 = {dbg_even_stuffer_do, stuffer_do};
    always @ (negedge xclk2x) begin

        if (stuffer_dv && dbg_odd_stuffer_dv) begin
            $display ("COMPRESSOR CHN%d 0x%x -> 0x%x", CMPRS_NUMBER, dbg_stuffer_word_number, dbg_stuffer_do32);
        end
        
        if (stuffer_done) begin
            $display ("COMPRESSOR CHN%d ***** DONE *****",CMPRS_NUMBER);
        end

        if (stuffer_dv && !dbg_odd_stuffer_dv)     dbg_even_stuffer_do = stuffer_do;

        if      (!stuffer_en || stuffer_done)      dbg_stuffer_word_number = 0;
        else if (stuffer_dv && dbg_odd_stuffer_dv) dbg_stuffer_word_number = dbg_stuffer_word_number + 1;

        if     (!stuffer_en)                       dbg_odd_stuffer_dv = 0;
        else if (stuffer_dv)                       dbg_odd_stuffer_dv = ~dbg_odd_stuffer_dv;

    end
1325
  `endif
1326
    
1327
`else
1328
    huffman_stuffer_meta huffman_stuffer_meta_i (
1329 1330 1331 1332 1333
        .mclk              (mclk),             // input
        .mrst              (mrst),             // input
        .xclk              (xclk),             // input
        .en_huffman        (frame_en),         // input
        .en_stuffer        (stuffer_en),       // input
1334
        .abort_stuffer     (force_flush_long), // input
1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356
        .tser_we           (tser_he),          // input
        .tser_a_not_d      (tser_a_not_d),     // input
        .tser_d            (tser_d),           // input[7:0] 
        .di                (enc_do[15:0]),     // input[15:0] 
        .ds                (enc_dv),           // input
        .ts_pre_stb        (ts_pre_stb),       // input
        .ts_data           (ts_data),          // input[7:0] 
        .color_first       (color_first),      // input valid @xclk - only for sec/usec
        .data_out          (stuffer_do),       // output[31:0] 
        .data_out_valid    (stuffer_dv),       // output
        .done              (stuffer_done),     // output
        .running           (stuffer_running),  // output
        .clk_flush          (hclk),            // input
        .flush_clk          (flush_hclk)       // output
        
    `ifdef DEBUG_RING
       ,.test_lbw          (dbg_test_lbw),     // output reg ??
        .gotLastBlock      (dbg_gotLastBlock), // output ?? - unused (was for debug)
        .dbg_etrax_dma     (etrax_dma),        // output[3:0]
        .dbg_ts_rstb       (dbg_ts_rstb),      // output             
        .dbg_ts_dout       (dbg_ts_dout)       //output[7:0]
    `endif        
1357
    );
1358 1359 1360
    wire          eof_written_xclk;
    pulse_cross_clock stuffer_done_mclk_i (.rst(xrst), .src_clk(xclk), .dst_clk(mclk), .in_pulse(stuffer_done), .out_pulse(stuffer_done_mclk),.busy());
    cmprs_out_fifo32 cmprs_out_fifo_i (
1361
        // source (stuffer) clock domain
1362 1363
        .wclk                (xclk),        // input source clock (1x pixel clock, inverted) - same as stuffer out
        .wrst                (xrst),         // input mostly for simulation
Andrey Filippov's avatar
Andrey Filippov committed
1364
        
1365
        .we                  (stuffer_dv),     // @ posedge(~xclk2x) input write data from stuffer
1366
        .wdata               ({stuffer_do[7:0],stuffer_do[15:8],stuffer_do[23:16],stuffer_do[31:24]}),     // input[15:0] data from stuffer module;
1367 1368
        .wa_rst              (!stuffer_en),    // input reset low address bits when stuffer is disabled (to make sure it is multiple of 32 bytes
        .wlast               (stuffer_done),   // input - written last 32 bytes of a frame (flush FIFO) - stuffer_done (has to be later than we)
1369
        .eof_written_wclk    (eof_written_xclk),    // output - AFI had transferred frame data to the system memory
1370
        // AFI clock domain
1371
        .rclk                (hclk),           // @posedge(hclk) input - AFI clock
Andrey Filippov's avatar
Andrey Filippov committed
1372
        .rrst                (hrst),           // input - AFI clock
1373
        .rst_fifo            (fifo_rst),       // input - reset FIFO (set read address to write, reset count)
1374 1375 1376 1377 1378 1379 1380
        .ren                 (fifo_ren),       // input - fifo read from AFI channel mux
        .rdata               (fifo_rdata),     // output[63:0] - data to AFI channel mux (latency == 2 from fifo_ren)
        .eof                 (fifo_eof),       // output single hclk pulse signalling EOF
        .eof_written         (eof_written),    // input single hclk pulse confirming frame data is written to the system memory
        .flush_fifo          (fifo_flush),     // output level signalling that FIFO has data from the current frame (use short AXI burst if needed)
        .fifo_count          (fifo_count)      // output[7:0] - number of 32-byte chunks available in FIFO
    );
1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397
    pulse_cross_clock eof_written_mclk_i (.rst(xrst), .src_clk(xclk), .dst_clk(mclk), .in_pulse(eof_written_xclk), .out_pulse(eof_written_mclk),.busy());
    
  `ifdef DISPLAY_COMPRESSED_DATA
    integer stuffer_word_number;
    always @ (posedge xclk) begin
        if (stuffer_dv) begin
            $display ("COMPRESSOR CHN%d 0x%x -> 0x%x", CMPRS_NUMBER, stuffer_word_number, stuffer_do);
        end
        if (stuffer_done) begin
            $display ("COMPRESSOR CHN%d ***** DONE *****",CMPRS_NUMBER);
        end
        if (!stuffer_en || stuffer_done) stuffer_word_number = 0;
        else if (stuffer_dv)             stuffer_word_number =  stuffer_word_number + 1;
    end
  `endif
    
`endif
Andrey Filippov's avatar
Andrey Filippov committed
1398 1399

// TODO: Add status module to combine/FF, re-clock status signals
1400

1401

1402 1403
endmodule