jp_channel.v 78.5 KB
Newer Older
1 2 3
/*******************************************************************************
 * Module: jp_channel
 * Date:2015-06-10  
4
 * Author: Andrey Filippov     
5 6
 * Description: Top module of JPEG/JP4 compressor channel
 *
7
 * Copyright (c) 2015 Elphel, Inc.
8 9 10 11 12 13 14 15 16 17 18 19
 * 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/> .
20 21 22 23 24 25
 *
 * 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"
26
 * files and/or simulating the code, the copyright holders of this Program give
27 28
 * 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
29
 * charge, and there is no dependence on any encrypted modules for simulating of
30 31 32
 * 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.
33 34 35 36
 *******************************************************************************/
`timescale 1ns/1ps

module  jp_channel#(
37 38 39 40 41 42 43
        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,
44
        parameter CMPRS_MASK=                'h7f8,
45 46 47 48 49
        parameter CMPRS_CONTROL_REG=          0,
        parameter CMPRS_STATUS_CNTRL=         1,
        parameter CMPRS_FORMAT=               2,
        parameter CMPRS_COLOR_SATURATION=     3,
        parameter CMPRS_CORING_MODE=          4,
50
        parameter CMPRS_INTERRUPTS=           5,        
Andrey Filippov's avatar
Andrey Filippov committed
51
        parameter CMPRS_TABLES=               6, // 6(data)..7(address)
52 53 54 55
        parameter TABLE_QUANTIZATION_INDEX =  0,
        parameter TABLE_CORING_INDEX =        1,
        parameter TABLE_FOCUS_INDEX =         2,
        parameter TABLE_HUFFMAN_INDEX =       3,
56 57 58 59 60 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

        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

94 95 96 97 98
        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
99 100 101 102 103 104 105 106 107 108 109 110
        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
111 112 113 114
        parameter CMPRS_CORING_BITS =          3,  // number of bits in coring mode
        
        parameter CMPRS_TIMEOUT_BITS=              12,
        parameter CMPRS_TIMEOUT=                   1000   // mclk cycles
115 116 117
`ifdef DEBUG_RING
        ,parameter DEBUG_CMD_LATENCY = 2 //SuppressThisWarning VEditor - not used
`endif        
118
        
119
)(
120
    input                         xclk,          // global clock input, compressor single clock rate
121
`ifdef  USE_XCLK2X    
122
    input                         xclk2x,        // global clock input, compressor double clock rate, nominally rising edge aligned
123
`endif    
124 125 126
    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
127
    
128
    // programming interface
129 130 131 132 133 134 135
    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
136
    
137
    // 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
138
    input                         xfer_reset_page_rd, // from mcntrl_tiled_rw (
139 140

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

144
    
145 146
    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 
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
// Master(sensor)/slave(compressor) synchronization signals
    output                        frame_start_dst,    // @mclk - trigger receive (tiledc) memory channel (it will take care of single/repetitive
                                                      // these output either follows vsync_late (reclocks it) or generated in non-bonded mode
                                                      // (compress from memory)
    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
    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

163
// statistics data was not used in late nc353    
164 165 166 167
    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,
168 169 170 171 172

// 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)
    
173 174
    output                        eof_written_mclk,
    output                        stuffer_done_mclk,
Andrey Filippov's avatar
Andrey Filippov committed
175
    
176
//    output                 [31:0] hifreq,             //  accumulated high frequency components in a frame sub-window
177
    input                         vsync_late,         // delayed start of frame, @mclk. In 353 it was 16 lines after VACT active
178 179
                                                      // source channel should already start, some delay give time for sequencer commands
                                                      // that should arrive before it
180 181 182
    
    // Output interface to the AFI mux
    input                         hclk,
183
    input                         fifo_rst,      // reset FIFO (set read address to write, reset count)
184 185
    input                         fifo_ren,
    output                 [63:0] fifo_rdata,
186 187
    output                        fifo_eof,      // single rclk pulse signaling EOF
    input                         eof_written,   // confirm frame written over AFI to the system memory (single rclk pulse)
188
    output                        fifo_flush,    // EOF, need to output all what is in FIFO (Stays active until enough data chunks are read)
189 190
    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) 
191
    output                 [7:0]  fifo_count     // number of 32-byte chunks in FIFO
192 193 194 195 196
`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         
197
);
198 199 200
//`ifdef DEBUG_RING
//     assign  debug_do = debug_di; // just temporarily to short-circuit the ring
//`endif        
201

202 203 204 205 206
    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
    
207
    // Control signals to be defined
208
    wire                             frame_en;           // if 0 - will reset logic immediately (but not page number)
209 210
    wire                             frame_start_xclk;   // re-clocked, parameters are copied at this pulse
    wire                             stuffer_en;         //  extended enable to allow stuffer to gracefully finish 
211
    
212
    wire                             frame_go=frame_en;  // start frame: if idle, will start reading data (if available),
213
                                      // if running - will not restart a new frame if 0.
214 215 216 217 218
    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)
219
//    wire                             four_blocks;        // use only 6 blocks for the output, not 6
220 221 222 223 224 225 226 227 228 229 230
    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
231

232
    //TODO: assign next 5 values from converter_type[2:0]
233 234 235
    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
236 237
    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
238 239 240 241 242 243 244 245
    
    
    // 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)
246 247 248 249 250 251
    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
252 253
    
    // signals connecting modules: cmprs_pixel_buf_iface_i and chn_rd_buf_i:
254 255
//    wire   [ 7:0] buf_di;             // data from the buffer
//    wire   [11:0] buf_ra;             // buffer read address (2 MSB - page number)
256
    wire   [ 1:0] buf_rd;             // buf {regen, re}
257
    wire   [ 7:0] buf_pxd;            // 8-bit pixel data from the memory buffer
258
    wire   [11:0] buf_ra;             // Memory buffer read address
259 260 261
    // 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
262
    wire          mb_pre2_first_out;  // Macroblock data out strobe - 2 cycles just before data valid
263
//    wire          mb_data_valid;     // Macroblock data out valid
264
    
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
    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!
285
//    wire          yc_nodc_dv;         // out data valid (will go high for at least 64 cycles)
286 287 288 289
    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)
290
// below signals valid at ds ( 1 later than tn, first_r, last_r)
291 292 293 294 295
    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;
296 297


298 299 300 301 302 303
// 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
304

Andrey Filippov's avatar
Andrey Filippov committed
305 306


307
    wire          force_flush_long; 
Andrey Filippov's avatar
Andrey Filippov committed
308 309 310 311 312
///    wire          enc_last; not used
    wire   [15:0] enc_do; 
    wire          enc_dv;

//TODO: use next signals for status
313 314 315
    wire          stuffer_running_mclk;
    wire          reading_frame;
    
316
`ifdef   USE_XCLK2X
317 318 319 320
    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
321
    wire          last_block;  // @negedge xxlk2x - used to copy timestamp in stuffer
322 323 324
    wire          stuffer_rdy; // receiver (bit stuffer) is ready to accept data;
`endif
    
325 326 327 328 329 330 331 332 333 334

    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;
335
    wire          set_interrupts_w;
336 337
    wire          set_tables_w;
    
338 339 340 341 342 343 344 345
    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;
346
    
347 348 349 350

    wire   [15:0] dccdata; // was not used in late nc353
    wire          dccvld;  // was not used in late nc353
    
351 352 353 354 355
    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);
356
    assign set_interrupts_w =        cmd_we && (cmd_a==       CMPRS_INTERRUPTS);
357
    assign set_tables_w =            cmd_we && ((cmd_a & 6)== CMPRS_TABLES);
358
    
359
    
360 361 362 363 364
`ifdef  USE_XCLK2X
      // re-sync to posedge xclk2x
    reg           xrst2xn;
    always @ (negedge xclk2x) xrst2xn <= xrst;
`endif    
365

366
`ifdef DEBUG_RING
367 368 369 370 371 372 373
    `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;
374
        wire          xrst2xn =     xrst;
375 376 377 378
    `endif



379 380 381 382 383 384 385 386 387 388 389 390 391 392
    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;
393 394 395 396 397
    wire       dbg_ts_rstb; // output
    wire [7:0] dbg_ts_dout; //output [7:0]
    wire [31:0] dbg_sec;
    wire [31:0] dbg_usec;
    
398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416
    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;
417 418
  `ifndef  USE_XCLK2X
        // temporarily assigning unused debug signals to 0
419 420 421 422 423 424 425 426 427
//        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
428 429
       
  `endif    
430
    timestamp_to_parallel dbg_timestamp_to_parallel_i (
431 432 433 434 435
  `ifdef  USE_XCLK2X     
        .clk      (~xclk2x),     // input
  `else
        .clk      (xclk),        // input
  `endif        
436 437
        .pre_stb  (dbg_ts_rstb), // input
        .tdata    (dbg_ts_dout), // input[7:0] 
438
        .sec      (dbg_sec),     // output[31:0] reg 
439
        .usec     (dbg_usec[19:0]),    // output[19:0] reg 
440
        .done()                  // output
441
    );
442 443 444
    
    
// cmprs_standalone - use to reset flush     
445
  `ifdef  USE_XCLK2X
446
    always @ (posedge ~xclk2x) begin
447 448 449
  `else  
    always @ (posedge xclk) begin
  `endif  
450 451 452 453 454 455
        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;
        
456 457
        if      (!dbg_en_n2x) dbg_last_block_persist <= 0;
        else if (last_block)  dbg_last_block_persist <= 1;
458 459 460 461 462

        if      (!dbg_en_n2x)      dbg_gotLastBlock_persist <= 0;
        else if (dbg_gotLastBlock) dbg_gotLastBlock_persist <= 1;
        
//dbg_last_block_persist        
463 464 465
    end
    always @ (posedge hclk) begin
        if      (hrst)     debug_fifo_out <= 0;
466
        else if (fifo_rst) debug_fifo_out <= 0; // debug_fifo_in >> 2;
467
        else if (fifo_ren) debug_fifo_out <= debug_fifo_out + 1;
468 469 470 471 472
        
        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;
473
    end
474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511
    
    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;
512

513 514 515
    end
//frame_start_dst
    
516
    debug_slave #(
517 518
        .SHIFT_WIDTH       (384),
        .READ_WIDTH        (384),
519 520 521 522 523 524 525 526 527
        .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   ({
528 529
        dbg_usec,
        dbg_sec,
530 531 532 533 534 535 536 537 538 539 540
        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],
541
        color_last, dbg_last_block_persist, dbg_gotLastBlock, dbg_test_lbw, last_block,
542
         dbg_flush_hclk, dbg_flushing, stuffer_rdy, etrax_dma[3:0], dbg_stuffer_ext_running, stuffer_running_mclk, debug_frame_done, reading_frame,
543
        fifo_count[7:0],
544
        2'b0, dbg_fifo_or_full, dbg_gotLastBlock_persist, dbg_lastBlock_sent, dbg_last_DCAC, sigle_frame_buf, suspend,
545 546 547 548
        frame_number_dst[15:0],
        line_unfinished_dst[15:0],
        frame_number_src[15:0],
        line_unfinished_src[15:0]
549 550 551 552
        }), // input[31:0]
        .wr_data    (), // output[31:0]  - not used
        .stb        () // output  - not used
    );
553 554 555 556 557 558 559 560 561 562 563 564
//    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),
        .in_pulse  (frame_start_dst),
        .out_pulse (dbg_frame_start_hclk),
        .busy      ());
    
    
565 566
`endif    

567 568 569 570 571 572 573
    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
574
        .rst        (1'b0), //rst),      // input
575
        .clk        (mclk),     // input
Andrey Filippov's avatar
Andrey Filippov committed
576
        .srst       (mrst),      // input
577 578 579 580 581 582
        .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
    );
583 584
    
    wire [4:0] status_data; 
585
    cmprs_status cmprs_status_i (
586 587 588 589 590 591 592 593 594
        .mrst            (mrst),                  // input
        .mclk            (mclk),                  // input
        .eof_written     (eof_written_mclk),      // input
        .stuffer_running (stuffer_running_mclk),  // input
        .reading_frame   (reading_frame),         // input
        .set_interrupts  (set_interrupts_w),      // input
        .data_in         (cmd_data[1:0]),         // input[1:0] 
        .status          (status_data),           // output[2:0] 
        .irq             (irq) // output
595
    );
Andrey Filippov's avatar
Andrey Filippov committed
596

597 598
    status_generate #(
        .STATUS_REG_ADDR  (CMPRS_STATUS_REG_ADDR),
599
        .PAYLOAD_BITS     (7),
600 601 602
        .EXTRA_WORDS      (1),
        .EXTRA_REG_ADDR   (CMPRS_HIFREQ_REG_ADDR)
        
603
    ) status_generate_i (
604 605 606 607 608 609 610 611 612
        .rst              (1'b0),                      //rst),      // input
        .clk              (mclk),                      // input
        .srst             (mrst),                      // input
        .we               (set_status_w),              // input
        .wd               (cmd_data[7:0]),             // input[7:0] 
        .status           ({hifreq,status_data,2'b0}), // input[2:0] 
        .ad               (status_ad),                 // output[7:0] 
        .rq               (status_rq),                 // output
        .start            (status_start)               // input
613
    );
614
//hifreq
615 616 617 618 619 620 621
// Not needed?
//    reg   emul64;
//    always @ (negedge mclk) begin
//        emul64 <= tile_width[1]; // will not work for monochrome (128 pixel wide) - chnge to 64?
//    end
    

622 623 624
    mcntrl_buf_rd #(
        .LOG2WIDTH_RD(3) // 64 bit external interface
    ) chn_rd_buf_i (
625 626 627 628 629 630 631 632
        .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] 
633
        .wpage_set    (xfer_reset_page_rd), // input  TODO: Generate @ negedge mclk on frame start
634 635 636 637
        .page_next    (buf_wpage_nxt),      // input
        .page         (),                   // output[1:0]
        .we           (buf_we),             // input
        .data_in      (buf_din)             // input[63:0] 
638
    );
Andrey Filippov's avatar
Andrey Filippov committed
639
    
640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689
    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
690
//        .rst                (rst),                 // input
691 692
        .xclk               (xclk),                // input - global clock input, compressor single clock rate
        .mclk               (mclk),                // input - global system/memory clock
Andrey Filippov's avatar
Andrey Filippov committed
693
        .mrst               (mrst),                // input
694 695 696 697 698 699
        .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)
        .frame_start        (frame_start_dst),     // input @mclk
700
        .frame_start_xclk   (frame_start_xclk),    // re-clocked, parameters are copied during this pulse
701 702 703 704 705
        .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 
706 707
        .cmprs_en_xclk      (frame_en),            // output reg
        .cmprs_en_late_xclk (stuffer_en),          // output reg - extended enable to allow stuffer to gracefully finish 
708 709 710 711 712
        .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 
713 714
//      .four_blocks        (four_blocks),         // output reg Not used?
        .four_blocks        (),                    // output reg Not used?
715 716 717 718 719 720 721 722 723
        .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 
724
        .coring             (coring_num)           // output[2:0] reg 
725 726
    );

727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743
// 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 
    );
744 745 746 747


    cmprs_frame_sync #(
        .FRAME_HEIGHT_BITS  (FRAME_HEIGHT_BITS),
748 749 750
        .LAST_FRAME_BITS    (LAST_FRAME_BITS),
        .CMPRS_TIMEOUT_BITS (CMPRS_TIMEOUT_BITS),
        .CMPRS_TIMEOUT      (CMPRS_TIMEOUT)
751
    ) cmprs_frame_sync_i (
Andrey Filippov's avatar
Andrey Filippov committed
752
//        .rst                (rst),                 // input
753 754
        .xclk               (xclk),                // input - global clock input, compressor single clock rate
        .mclk               (mclk),                // input - global system/memory clock
Andrey Filippov's avatar
Andrey Filippov committed
755 756
        .mrst               (mrst),                // input
        .xrst               (xrst),                // input
757 758 759 760 761 762
        .cmprs_en           (cmprs_en_mclk),       // input - @mclk 0 resets immediately
        .cmprs_en_extend    (cmprs_en_extend), // output
        .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
763
        .vsync_late         (vsync_late),          // input - @mclk delayed start of frame, @xclk. In 353 it was 16 lines after VACT active
764 765
                                                   // source channel should already start, some delay give time for sequencer commands
                                                   // that should arrive before it
766
        .frame_started      (first_mb && mb_pre_start), // @xclk started first macroblock (checking for broken frames)
767 768 769 770 771 772 773 774 775 776 777 778
        .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)
        .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
        .frame_done         (frame_done_dst),      // input - single-cycle pulse when the full frame (window) was transferred to/from DDR3 memory 
        .suspend            (suspend),             // output reg - suspend reading data for this channel - waiting for the source data
779
        .stuffer_running    (stuffer_running), // input
780 781 782 783
        .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
        .reading_frame      (reading_frame) // output
        
784 785
    );

786
    cmprs_macroblock_buf_iface cmprs_macroblock_buf_iface_i (
Andrey Filippov's avatar
Andrey Filippov committed
787 788 789 790 791
//        .rst                (rst), // input
        .xclk               (xclk),               // input
        .mclk               (mclk),               // input
        .mrst               (mrst),               // input
        .xrst               (xrst),               // input
792
        .xfer_reset_page_rd (xfer_reset_page_rd), // input
Andrey Filippov's avatar
Andrey Filippov committed
793 794 795
        .page_ready_chn     (page_ready_chn),     // input
        .next_page_chn      (next_page_chn),      // output
        .frame_en           (frame_en),           // input
796
        .frame_start_xclk   (frame_start_xclk),   // input@posedge xclk - parameters are copied @ this pulse
Andrey Filippov's avatar
Andrey Filippov committed
797 798
        .frame_go           (frame_go),           // input - do not use - assign to frame_en? Running frames can be controlled by other means
        .left_marg          (left_marg),          // input[4:0] 
799
        .n_blocks_in_row_m1 (n_blocks_in_row_m1), // input[12:0] 
Andrey Filippov's avatar
Andrey Filippov committed
800
        .n_block_rows_m1    (n_block_rows_m1),    // input[12:0] 
801
        .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
802 803 804 805 806 807 808 809 810
        .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
811 812 813 814
`ifdef DEBUG_RING
        ,.dbg_add_invalid   (dbg_add_invalid),
        .dbg_mb_release_buf (dbg_mb_release_buf)
`endif        
815 816 817 818 819 820 821 822 823 824 825 826 827 828
    );

    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
829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844
        .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
845
        .pre_first_out      (mb_pre_first_out), // output // Macroblock data out strobe - 1 cycle just before data valid  == old pre_first_pixel?
846
//        .data_valid         (mb_data_valid) // output     // Macroblock data out valid
847 848
        .pre2_first_out     (mb_pre2_first_out), // output reg  
        .data_valid         () // output reg     // Macroblock data out valid Unused
849 850
    );

851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869
    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] 
870
        .pre2_first_in  (mb_pre2_first_out),// input
871 872 873 874 875 876 877 878 879 880
        .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 
    );
881 882


883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898
    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
899
        .subtract_dc_in     (subtract_dc),      // input
900 901 902 903 904 905 906 907
        .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] 
908 909
        .do                 (yc_nodc),          // output[9:0] 
        .avr                (yc_avr),           // output[8:0] 
910 911
//        .dv                 (yc_nodc_dv),       // output
        .dv                 (),                 // output unused?
912 913 914 915 916 917 918 919
        .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 
920
    );
921 922
//  wire   [ 9:0] yc_nodc;         // [9:0] data out (4:2:0) (signed, average=0)

Andrey Filippov's avatar
Andrey Filippov committed
923 924 925

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

926 927
    wire          dct_last_in;
    wire          dct_pre_first_out;
928
//    wire          dct_dv;
929 930
    wire   [12:0] dct_out;
    
931 932 933 934 935
    
 //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
936 937
    reg           first_block_dct;          // after DCT
    wire          first_block_quant;        // after quantizer
938
    always @ (posedge xclk) begin
939 940 941 942 943
        if (dct_start)   first_block_color_after <= first_block_color;
        if (dct_last_in) first_block_dct   <= first_block_color_after;
    end
    
    
944
`ifdef USE_OLD_XDCT393    
945
    
946
    xdct393 xdct393_i (
Andrey Filippov's avatar
Andrey Filippov committed
947 948 949 950 951 952 953
        .clk                (xclk),                // input
        .en                 (frame_en),            // input  if zero will reset transpose memory page numbers
        .start              (dct_start),           // input  single-cycle start pulse that goes with the first pixel data. Other 63 should follow
        .xin                (yc_nodc),             // input[9:0] 
        .last_in            (dct_last_in),         // output reg  output high during input of the last of 64 pixels in a 8x8 block //
        .pre_first_out      (dct_pre_first_out),   // outpu 1 cycle ahead of the first output in a 64 block
///        .dv                 (dct_dv),           // output data output valid. Will go high on the 94-th cycle after the start (now - on 95-th?)
954
        .dv                 (),  // not used: output data output valid. Will go high on the 94-th cycle after the start (now - on 95-th?)
Andrey Filippov's avatar
Andrey Filippov committed
955
        .d_out              (dct_out)              // output[12:0] 
956
    );
957 958 959 960 961 962 963 964 965 966 967 968 969 970
`else
    xdct393r xdct393_i (
        .clk                (xclk),                // input
        .en                 (frame_en),            // input  if zero will reset transpose memory page numbers
        .start              (dct_start),           // input  single-cycle start pulse that goes with the first pixel data. Other 63 should follow
        .xin                (yc_nodc),             // input[9:0] 
        .last_in            (dct_last_in),         // output reg  output high during input of the last of 64 pixels in a 8x8 block //
        .pre_first_out      (dct_pre_first_out),   // outpu 1 cycle ahead of the first output in a 64 block
///        .dv                 (dct_dv),           // output data output valid. Will go high on the 94-th cycle after the start (now - on 95-th?)
        .dv                 (),  // not used: output data output valid. Will go high on the 94-th cycle after the start (now - on 95-th?)
        .d_out              (dct_out)              // output[12:0] 
    );
`endif    
    
971
    wire          quant_start;
972
    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
973
 
974 975
    
    always @ (posedge xclk) begin
976 977 978 979
        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
    
980
    
981 982
//    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)
983 984
    wire          tser_a_not_d;  // address/not data distributed to submodules
    wire   [ 7:0] tser_d;        // byte-wide serialized tables address/data to submodules
985 986 987 988 989 990 991
    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)    
992 993 994 995 996
    table_ad_transmit #(
        .NUM_CHANNELS(4),
        .ADDR_BITS(3)
    ) table_ad_transmit_i (
        .clk             (mclk),                  // input @posedge
997
        .srst             (mrst),                  // @posedge mclk
Andrey Filippov's avatar
Andrey Filippov committed
998
        .a_not_d_in      (cmd_a[0]),              // input writing table address /not data (a[0] from cmd_deser)
999 1000
        .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
1001 1002
        .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
1003 1004
//        .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
1005 1006 1007 1008
    );
    
    
    
1009 1010 1011
    quantizer393 quantizer393_i (
        .clk                (xclk),                   // input
        .en                 (frame_en),               // input 
1012 1013 1014 1015 1016
        .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
1017
        .ctypei             (component_color),        // input component type input (Y/C)
1018 1019 1020
        .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
1021
        .tsi                (cmprs_qpage[2:0]),       // input[2:0] - table (quality) select [2:0]
1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034
        .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)
        .do                 (quant_do[12:0]),         // output[12:0] - pixel data out (AC is only 9 bits long?) - changed to 10
        .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
1035 1036 1037 1038 1039 1040 1041 1042
        .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)
1043
    // TODO: Verify focus_sharp393: quantizer output (with strobes) is now 2 cycles later than in 353 (relative to xdct out). Seems to be OK.
1044
    focus_sharp393 focus_sharp393_i (
1045
        .clk                (xclk),                   // input - pixel clock
1046
`ifdef  USE_XCLK2X        
1047
        .clk2x              (xclk2x),                 // input 2x pixel clock
1048 1049 1050
`else
        .clk2x              (xclk),                   // FIXME: fix the module not to use xclk2x
`endif        
1051
        .en                 (frame_en),               // input 
1052

1053
        .mclk               (mclk),                   // input system clock to write tables
1054
        .tser_we            (tser_fe),                // input - write to a focus sharpness table
1055 1056 1057
        .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
        
1058
        .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
1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072
        .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)
        .do                 (focus_do[12:0]),         // output[12:0] reg  pixel data out, make timing ignore (valid 1.5 clk earlier that Quantizer output)
        .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
    );

1073
    // 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
1074
    wire          finish_dcc;
1075
`ifdef  USE_XCLK2X    
1076
    wire   [15:0] stuffer_do;
1077 1078 1079
`else
    wire   [31:0] stuffer_do;
`endif    
1080 1081
    wire          stuffer_dv;
    wire          stuffer_done;
Andrey Filippov's avatar
Andrey Filippov committed
1082
    
1083
`ifdef  USE_XCLK2X    
Andrey Filippov's avatar
Andrey Filippov committed
1084
    pulse_cross_clock finish_dcc_i (.rst(xrst2xn), .src_clk(~xclk2x), .dst_clk(xclk2x), .in_pulse(stuffer_done), .out_pulse(finish_dcc),.busy());
1085 1086 1087 1088
`else
    assign finish_dcc = stuffer_done;
`endif    

1089
    dcc_sync393 dcc_sync393_i (
1090
`ifdef  USE_XCLK2X    
1091
        .sclk               (xclk2x),                // input
1092 1093 1094
`else
        .sclk               (xclk),                  // input
`endif        
1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118
        .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
1119 1120 1121
`ifdef DEBUG_RING
        .last               (dbg_last_DCAC),                       // output reg - not used
`else
Andrey Filippov's avatar
Andrey Filippov committed
1122
        .last               (),                       // output reg - not used
1123
`endif
1124 1125
        .do                 (enc_do[15:0]),           // output[15:0] reg 
        .dv                 (enc_dv)                  // output reg 
1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136
`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
1137 1138
    );

1139 1140
//    wire [2:0] dbg_block_mem_wa;
//    wire [2:0] dbg_block_mem_wa_save;
1141

1142
`ifdef  USE_XCLK2X
1143 1144 1145 1146
    huffman393 i_huffman (
        .xclk               (xclk),                   // input
        .xclk2x             (xclk2x),                 // input
        .en                 (frame_en),               // input
1147 1148 1149 1150
        .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
1151 1152 1153
        .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
1154 1155 1156
        .do                 (huff_do[15:0]),          // output[15:0] reg 
        .dl                 (huff_dl[3:0]),           // output[3:0] reg 
        .dv                 (huff_dv),                // output reg 
1157 1158
        .flush              (flush),                  // output reg
        .last_block         (last_block),             // output reg
1159 1160 1161 1162
`ifdef DEBUG_RING
        .test_lbw           (dbg_test_lbw), // output reg ??
        .gotLastBlock       (dbg_gotLastBlock), // output ?? - unused (was for debug)
`else
1163 1164
        .test_lbw           (), // output reg ??
        .gotLastBlock       (), // output ?? - unused (was for debug)
1165
`endif        
1166
        .clk_flush          (hclk), // input
1167 1168 1169 1170 1171 1172
        .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        
1173 1174 1175 1176
    );
    

    stuffer393 stuffer393_i (
1177
//        .rst                 (rst),                  // input
1178
        .mclk                (mclk),                   // input
1179 1180 1181
        .mrst                (mrst),                   // input
        .xrst                (xrst),                   // input
        .last_block          (last_block),             // input @negedge xclk2x - use it to copy timestamp from fifo 
1182 1183 1184 1185
        .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
1186
        .clk                 (xclk2x),                 // input clock - uses negedge inside
1187 1188 1189
        .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
1190 1191 1192
        .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)
1193
        // outputs valid @negedge xclk2x 
1194 1195 1196 1197
        .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 
1198 1199 1200
`ifdef DEBUG_RING
        .flushing            (dbg_flushing),                       // output reg Not used?
`else
1201
        .flushing            (),                       // output reg Not used?
1202
`endif        
1203
        .running             (stuffer_running)         // from registering timestamp until done
1204
`ifdef DEBUG_RING
1205 1206 1207 1208
   ,    .dbg_etrax_dma     (etrax_dma)
   ,.dbg_ts_rstb           (dbg_ts_rstb) // output
   ,.dbg_ts_dout           (dbg_ts_dout) //output [7:0]

1209
`endif        
1210 1211 1212 1213 1214
`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
1215
    );
1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242
    
//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());
  `ifdef DISPLAY_COMPRESSED_DATA
1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265
    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
1266
  `endif
1267
    
1268
`else
1269
    huffman_stuffer_meta huffman_stuffer_meta_i (
1270 1271 1272 1273 1274
        .mclk              (mclk),             // input
        .mrst              (mrst),             // input
        .xclk              (xclk),             // input
        .en_huffman        (frame_en),         // input
        .en_stuffer        (stuffer_en),       // input
1275
        .abort_stuffer     (force_flush_long), // input
1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297
        .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        
1298
    );
1299 1300 1301
    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 (
1302
        // source (stuffer) clock domain
1303 1304
        .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
1305
        
1306
        .we                  (stuffer_dv),     // @ posedge(~xclk2x) input write data from stuffer
1307
        .wdata               ({stuffer_do[7:0],stuffer_do[15:8],stuffer_do[23:16],stuffer_do[31:24]}),     // input[15:0] data from stuffer module;
1308 1309
        .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)
1310
        .eof_written_wclk    (eof_written_xclk),    // output - AFI had transferred frame data to the system memory
1311
        // AFI clock domain
1312
        .rclk                (hclk),           // @posedge(hclk) input - AFI clock
Andrey Filippov's avatar
Andrey Filippov committed
1313
        .rrst                (hrst),           // input - AFI clock
1314
        .rst_fifo            (fifo_rst),       // input - reset FIFO (set read address to write, reset count)
1315 1316 1317 1318 1319 1320 1321
        .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
    );
1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338
    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
1339 1340

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

1342

1343 1344
endmodule