stuffer393.v 21.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
/*
** -----------------------------------------------------------------------------**
** stuffer393.v
**etrax_dma
** Bit stuffer for JPEG encoder
**
** Copyright (C) 2002-2015 Elphel, Inc
**
** -----------------------------------------------------------------------------**
**  stuffer393.v is free software - hardware description language (HDL) code.
** 
**  This program 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.
**
**  This program 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/>.
** -----------------------------------------------------------------------------**
**
*/
`define debug_compressor
// 08.27.2005 - modified "rdy" - moved register to make it faster.
// 01.22.2004 - fixed bug if flush comes with !rdy (required mod of huffman.v to extend "flush" until ready)
// 02.05.2004 - modified data length output. It is 24 it ow, in bytes and is output as last 4 bytes in the
//              data block that is 32-byte DMA page aligned

// running on v8.2i - does not meet constraints with enabled global USE_SYNC_SET yes/auto because set input is slower. Trying to selectively disable it

// s ynthesis attribute use_sync_set of stuffer is no; 
// s ynthesis attribute use_sync_reset of stuffer is no; 
// s ynthesis attribute use_clock_enable of stuffer is no; 
38 39 40 41 42
// TODO:
// 1: Add FIFO buffer - with hclk on the read side
// 2: Get rid of imgptr - read addresses from the AFI module
// 3  Add multi-word status transmitter or just status transmit module for each compressor channel (29 bits are OK to read in multiple of 32-byte blocks
// Or make FIFO outside of the stuffer?
43 44

module stuffer393 (
Andrey Filippov's avatar
Andrey Filippov committed
45
//    input              rst,         // global reset
46
    input              mclk,
Andrey Filippov's avatar
Andrey Filippov committed
47 48 49
    input              mrst,      // @posedge mclk, sync reset
    input              xrst,      // @posedge xclk, sync reset
    
50 51 52 53 54 55 56
// time stamping - will copy time at the end of color_first (later than the first hact after vact in the current frame, but before the next one
// and before the data is needed for output 
    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)
    input              color_first, // @fradv_clk only used for timestamp
    input              fradv_clk,   // clock to synchronize color_first (leading edge to advance timestamp data for the output)
    
57
    input              clk,         // 2x pixel clock
58
    input              en_in,       // enable, 0- reset (other clock domain, needs re-sync)
59
    input              flush,       // flush output data (fill byte with 0, long word with 0
60
    input              abort,       // @ any, extracts 0->1 and flushes
61 62 63
    input              stb,         // input data strobe
    input        [3:0] dl,          // [3:0] number of bits to send (0 - 16) ??
    input       [15:0] d,           // [15:0] input data to shift (only lower bits are valid)
64 65
//    input       [31:0] sec,         // [31:0] number of seconds
//    input       [19:0] usec,        // [19:0] number of microseconds
66 67 68 69 70
    output             rdy,         // enable huffman encoder to proceed. Used as CE for many huffman encoder registers
    // outputs @ negedge clk
    output reg  [15:0] q,           // [15:0] output data
    output reg         qv,          // output data valid
    output             done,        // reset by !en, goes high after some delay after flushing
Andrey Filippov's avatar
Andrey Filippov committed
71
///    output reg  [23:0] imgptr,      // [23:0]image pointer in 32-byte chunks 
72 73
    output reg         flushing,
    output reg         running      // from registering timestamp until done
74 75 76 77 78 79 80 81 82 83
`ifdef debug_stuffer
,      output reg   [3:0] etrax_dma_r, // [3:0] just for testing
       output reg   [3:0] test_cntr,
       output reg   [7:0] test_cntr1
`endif
);

`ifdef debug_stuffer
    reg           en_d;
`endif
84 85 86 87 88 89
    reg           en; // re-clock en_in to match this clock
    reg     [2:0] abort_r;
    reg           force_flush;
    
    
    
90
    reg    [23:1] stage1;         //    stage 1 register (after right-shifting input data by 0..7 - actually left by 7..0)
91
    wire    [2:0] shift1;        // shift amount for stage 1
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
    reg     [4:0] stage1_bits;    // number of topmost invalid bits in stage1 register - 2 MSBs, use lower 3  stage2_bits
    reg     [4:0] stage1_length;  // number of bits (1..16) in stage 1 register

    wire          flush_end;
    reg           stage1_full;
    wire    [7:0] byteMask;
    wire   [31:1] longMask;    
    wire   [31:1] dflt_stage2;
    wire   [ 2:0] sel;
    wire   [ 1:0] st2m;
    wire   [31:1] st2_d;
    reg    [31:1] stage2;
    reg    [ 4:0] stage2_bits;
    wire          send8h;
    wire          send8l;
    wire          send8;
    reg           flush_end_delayed;   // update: fixed delay some delay after flush_end to ensure combining with output FIFO empty
    wire          pre_flush_end_delayed;    // some delay after flush_end to ensure combining with output FIFO empty
    reg    [23:0] size_count; //(now will be byte count)
     
// to make it faster - split in parts
    reg           inc_size_count2316;
    reg    [ 2:0] size_out;
    reg           size_out_over;// only needed with extra 32 bytes of zeroes added.
    reg           busy_eob;     // flushing and sending length
    reg           trailer;      // sending out data length and 32 bytes for ETRAX
    reg           was_trailer;  // sending out data length and 32 bytes for ETRAX

    reg    [ 3:0] etrax_dma;    // count words to make total size multiple of 32 bytes.
                                // Last 4 bytes of data will have actual length in bytes
                                // There will always be at least 4 more bytes (0-es) before length - needed for software
    reg           will_flush;   // next dv will be flushing byte/word
    wire          flush_now;
    wire          start_sizeout; //delay by 2 cycles

    reg           send8h_r;
    reg           send8l_r;

    wire          pre_stage2_bits_3;    // what will be registered to stage2_bits[3];
    wire    [4:3] willbe_stage1_bits;
    wire    [3:0] sum_lengths;
    reg     [1:0] st2m_r;
    
135
//    reg     [2:0] stb_time;
136 137 138 139 140 141 142 143 144
    reg    [31:0] sec_r;
    reg    [19:0] usec_r;
    reg           time_out;
    reg           time_size_out;
    wire          start_time_out;
    
// stb_time[2] - single-cycle pulse after color_first goes low 
    reg    [19:0] imgsz32; // current image size in multiples of 32-bytes
    reg           inc_imgsz32;
145
    // re-clock enable to this clock
146 147 148
    
    wire          ts_rstb; // one cycle before getting timestamp data from FIFO
    wire    [7:0] ts_dout; // timestamp data, byte at a time
149 150
//    reg     [7:0] ts_cycles; // 1-hot we for the portions of the 'old" timestamp registers
    reg     [6:0] ts_cycles; // 1-hot we for the portions of the 'old" timestamp registers
151 152 153 154 155 156 157
    
    reg           color_first_r; // registered with the same clock as color_first to extract leading edge
    wire          stb_start; // re-clocked  color_first
    
    
    assign ts_rstb = trailer && !was_trailer;  // enough time to have timestamp data
    always @ (negedge clk) begin
158 159
//        ts_cycles <= {ts_cycles[6:0],ts_rstb};
        ts_cycles <= {ts_cycles[5:0],ts_rstb};
160 161
        if      (ts_cycles[0])  sec_r[ 7: 0] <= ts_dout;
        else if (start_sizeout) sec_r[ 7: 0] <= size_count[ 7:0];
162
        else if (time_size_out) sec_r[ 7: 0] <= sec_r[23:16];
163 164 165
        
        if      (ts_cycles[1])  sec_r[15: 8] <= ts_dout;
        else if (start_sizeout) sec_r[15: 8] <= size_count[15:8];
166
        else if (time_size_out) sec_r[15: 8] <= sec_r[31:24];
167 168 169
        
        if      (ts_cycles[2])  sec_r[23:16] <= ts_dout;
        else if (start_sizeout) sec_r[23:16] <= size_count[23:16];
170
        else if (time_size_out) sec_r[23:16] <= usec_r[ 7: 0];
171 172 173

        if      (ts_cycles[3])  sec_r[31:24] <= ts_dout;
        else if (start_sizeout) sec_r[31:24] <= 8'hff;
174
        else if (time_size_out) sec_r[31:24] <= usec_r[15: 8];
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
        
        if      (ts_cycles[4]) usec_r[ 7: 0] <= ts_dout;
        else if (time_out)     usec_r[ 7: 0] <= {4'h0, usec_r[19:16]};
        
        if      (ts_cycles[5]) usec_r[15: 8] <= ts_dout;
        else if (time_out)     usec_r[15: 8] <= 8'h0;

        if      (ts_cycles[6]) usec_r[19:16] <= ts_dout[3:0];
        else if (time_out)     usec_r[19:16] <= 4'h0;
        
/*    
        stb_time[2:0] <= {stb_time[1] & ~stb_time[0], stb_time[0],color_first};
        if        (stb_time[2]) sec_r[31:0] <= sec[31:0];
        else if (start_sizeout) sec_r[31:0] <= {8'hff, size_count[23:0]};
        else if (time_size_out) sec_r[31:0] <= {usec_r[15:0],sec_r[31:16]};
        if   (stb_time[2]) usec_r[19:0] <= usec[19:0];
        else if (time_out) usec_r[19:0] <= {16'h0,usec_r[19:16]};
*/        
    end
    
195 196 197 198 199 200 201 202 203
    always @ (negedge clk) begin
        en <= en_in;
        // re-clock abort, extract leading edge
        abort_r <= {abort_r[0] & ~abort_r[1], abort_r[0], abort};
        if      (!en)       force_flush <= 0;
        else if (abort_r)   force_flush <= 1;
        else if (flush_end) force_flush <= 0;
        
        if      (!en)         running <= 0;
204 205
//        else if (stb_time[2]) running <= 1;
        else if (stb_start)   running <= 1;
206 207 208
        else if (flush_end)   running <= 0;
        
    end
209

210 211 212
    always @ (negedge clk)  begin
        flushing <= en && !flush_end && (((flush || force_flush) && rdy) || flushing);
    end
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361
    
    wire    [4:0]    pre_stage1_bits;
    assign pre_stage1_bits[4:0]={2'b00,stage1_bits[2:0]} +  {(dl[3:0]==4'b0),dl[3:0]};
    
    always @ (negedge clk)    begin 
        if (!en || flush_end) stage1_bits[4:0] <= 5'b0;
        else if (stb && rdy) stage1_bits <= {(2'b10-pre_stage1_bits[4:3]),pre_stage1_bits[2:0]};
    end

    assign shift1[2:0]= stage1_bits[2:0] + dl[2:0];
    always @ (negedge clk) if (stb && rdy)    begin
        case (shift1[2:0])
            0: stage1[23:1]    <= {     d[15:0],7'b0};
            1: stage1[23:1]    <= {1'b0,d[15:0],6'b0};
            2: stage1[23:1]    <= {2'b0,d[15:0],5'b0};
            3: stage1[23:1]    <= {3'b0,d[15:0],4'b0};
            4: stage1[23:1]    <= {4'b0,d[15:0],3'b0};
            5: stage1[23:1]    <= {5'b0,d[15:0],2'b0};
            6: stage1[23:1]    <= {6'b0,d[15:0],1'b0};
            7: stage1[23:1]    <= {7'b0,d[15:0]     };
         endcase
        stage1_length[4:0]    <= {(dl[3:0]==4'b0),dl[3:0]};
    end


//*****************************
    always @ (negedge clk) begin
        if (!en) stage2_bits    <= 5'b0;
        else if (send8) stage2_bits[4:0] <= stage2_bits[4:0] - 8;
        else if (flushing && !stage1_full && !stage2_bits[4] && (stage2_bits[3:0]!=4'b0)) stage2_bits[4:0]<=5'h10;    // actual flushing to word size
        else        stage2_bits[4:0]    <= (rdy && stage1_full)? {1'b0,stage2_bits[3:0]}+stage1_length[4:0]:{1'b0,stage2_bits[3:0]};
    end

    assign        sum_lengths=stage2_bits[3:0]+stage1_length[3:0];
    assign pre_stage2_bits_3= en &&
                          (send8? (~stage2_bits[3]): (
                                  !(flushing && !stage1_full && !stage2_bits[4] && (stage2_bits[3:0]!=4'b0)) && // not flushing
                                  ((rdy && stage1_full)?sum_lengths[3]:    stage2_bits[3] )
                                  ));
    assign willbe_stage1_bits[4:3]={2{en && !flush_end}} & ((stb && rdy)?(2'b10-pre_stage1_bits[4:3]):stage1_bits[4:3]);
    

// accelerating rdy calculation - making it a register
    wire       pre_busy_eob=en && !flush_end_delayed && (busy_eob || (flush && rdy));
    wire [4:3] pre_stage2_bits_4_interm1=stage2_bits[4:3]-2'h1;
    wire [4:0] pre_stage2_bits_4_interm2={1'b0,stage2_bits[3:0]}+stage1_length[4:0];
    wire       pre_stage2_bits_4=en && (send8?
                                     (pre_stage2_bits_4_interm1[4]):
                                     ((flushing && !stage1_full && !stage2_bits[4] && (stage2_bits[3:0]!=4'b0))?
                                       (1'b1):
                                       (((rdy && stage1_full))?
                                         (pre_stage2_bits_4_interm2[4]):
                                         (1'b0)
                                       )
                                     )
                              );
    wire pre_send8h_r= (( send8h_r  &&  stage2_bits[4])?
                           (&stage2[23:16]):
                           ((!send8l_r  || !stage2_bits[4])?
                             (&((longMask[31:24] & st2_d[31:24]) | (~longMask[31:24] & dflt_stage2[31:24]))):
                             (send8h_r)
                           )
                         );

    wire pre_send8l_r= ((( send8h_r || send8l_r) &&  stage2_bits[4] )?
                        (&stage2[15:8]):
                        (&((longMask[23:16] & st2_d[23:16]) | (~longMask[23:16] & dflt_stage2[23:16])))
                       );

//Trying to delay rdy to make more room before it
    reg           rdy_rega;
    reg           rdy_regb;
    reg           rdy_regc;
    reg           rdy_regd;
// s ynthesis attribute use_sync_set of {module_name|signal_name|instance_name} [is] no; 
 
   always @ (negedge clk) begin
        rdy_rega <= !pre_stage2_bits_4;
        rdy_regb <= !pre_send8h_r;
        rdy_regc <= !pre_send8l_r;
        rdy_regd <= !pre_busy_eob;
        busy_eob <= pre_busy_eob;
//**********************************
        send8h_r<=pre_send8h_r;
        send8l_r<=pre_send8l_r;
    end
    assign rdy = (rdy_rega || (rdy_regb && rdy_regc)) && rdy_regd;
    
    assign send8h= send8h_r && stage2_bits[4];
    assign send8l= send8l_r && stage2_bits[4];
    assign send8=stage2_bits[4] && (send8h_r || send8l_r);

    always    @ (negedge clk) begin
        if (!en) stage1_full <= 1'b0;
/* TODO: MAke sure it is OK !! 05/12/2010 */
        else if (flushing) stage1_full <= 1'b0; //force flush does not turn off stb, in normal operation flushing is after last stb
        else if (rdy) stage1_full <=stb; //force flush does not turn off stb, in normal operation flushing is after last stb

    end
    assign    sel[2:0]=stage2_bits[2:0];
    assign    byteMask[7:0]=    {!sel[2] && !sel[1] && !sel[0],
                                 !sel[2] && !sel[1],
                                 !sel[2] && (!sel[1] || !sel[0]),
                                 !sel[2],
                                 !sel[2] || (!sel[1] && !sel[0]),
                                 !sel[2] || !sel[1],
                                 !sel[2] || !sel[1] || !sel[0],
                                 1'b1
                                 };

//TODO: Try to move stage1_full up here, this is the time-limiting path 05.26.2010
    assign    longMask[31:1]={{8{(flushing || stage1_full) && !stage2_bits[3]}} & byteMask[7:0],
                              {8{flushing || stage1_full}} & ({8{!stage2_bits[3]}} | byteMask[7:0]),
                              {8{stage1_full}},
                              {7{stage1_full}}};

    always @ (negedge clk) st2m_r[1:0]<=willbe_stage1_bits[4:3]-{1'b0,pre_stage2_bits_3};
    
    assign    st2m[1:0]=st2m_r[1:0];
    assign    st2_d[31:1]=    {{8{!flushing || stage1_full}} & (st2m[1]?{stage1[7:1],1'b0}:(st2m[0]? stage1[15:8]:     stage1[23:16])),
                               {8{!flushing || stage1_full}} & (st2m[1]? stage1[23:16]:    (st2m[0]?{stage1[7:1],1'b0}:stage1[15: 8])),
                               st2m[1]? stage1[15: 8]:    {stage1[7:1],1'b0},
                               {stage1[7:1]}};
    assign    dflt_stage2=stage2_bits[4]?{stage2[15:1],16'b0}:{stage2[31:1]};


always @ (negedge clk) begin
    if          (send8h) stage2[31:24] <= stage2[23:16];
    else if (send8l) stage2[31:24] <= 8'h00;
    else                  stage2[31:24] <= (longMask[31:24] & st2_d[31:24]) | (~longMask[31:24] & dflt_stage2[31:24]);
    if          (send8)  stage2[23:16] <= stage2[15:8];
    else                  stage2[23:16] <= (longMask[23:16] & st2_d[23:16]) | (~longMask[23:16] & dflt_stage2[23:16]);

    if          (send8)  stage2[15: 8] <= {stage2[7:1],1'b0};
    else                  stage2[15: 8] <= (longMask[15: 8] & st2_d[15: 8]) | (~longMask[15: 8] & dflt_stage2[15: 8]);

    if          (send8)  stage2[7:  1] <= 7'b0;
    else                  stage2[7:  1] <= (longMask[7: 1] & st2_d[7: 1]) | (~longMask[7: 1] & dflt_stage2[7: 1]);
end

// output stage
    assign   flush_end= !stage2_bits[4] && flushing && !stage1_full && (stage2_bits[3:0]==4'b0);
    assign flush_now= en && (!send8) && (flushing && !stage1_full && !stage2_bits[4]) && !will_flush;
`ifdef debug_stuffer
    reg [3:0] tst_done_dly;
`endif

    always @ (negedge clk) begin
 //reset_data_counters; // reset data transfer counters (only when DMA and compressor are disabled)
Andrey Filippov's avatar
Andrey Filippov committed
362 363
//        if (reset_data_counters ) etrax_dma[3:0] <= 0; // not needed to be reset after frame, and that was wrong (to early)
        if (!en ) etrax_dma[3:0] <= 0; // Now en here waits for flashing to end, so it should not be too early
364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401
        else if (qv) etrax_dma[3:0] <= etrax_dma[3:0] + 1;

// just for testing
`ifdef debug_stuffer
        en_d<= en;
        if (en) etrax_dma_r[3:0] <= etrax_dma[3:0];
        if    (done) test_cntr1[7:0] <= 0;
        else if (qv) test_cntr1[7:0] <= test_cntr1[7:0] +1 ; // normally should be one (done 1 ahead of end of qv)
        tst_done_dly[3:0] <= {tst_done_dly[2:0],done};
        if (tst_done_dly[1]) test_cntr[3:0] <= 0;
        else if (qv)         test_cntr[3:0] <= test_cntr[3:0] +1 ;
`endif
 

        size_out_over <= en && (size_out_over?(!done):size_out[0]);
  
        size_out[2:0]<={size_out[1:0],start_sizeout};
        time_out <= en && (start_time_out || (time_out && !(etrax_dma[3:2]== 2'h3)));
        time_size_out <= en && (start_time_out || (time_size_out && !(etrax_dma[3:1]== 3'h7)));
  
        trailer <= en && (trailer?(!flush_end_delayed):(flush_end));
        was_trailer<=trailer; 
        will_flush <= en && (will_flush?(!qv):(flush_now && (stage2_bits[3:0]!=4'b0)));
        if (flush_now) size_count[0] <= stage2_bits[3] ^ (|stage2_bits[2:0]); // odd number of bytes
        if (!en || size_out[2]) size_count[15:1] <= 0;
        else if (!trailer && !was_trailer && qv && (!will_flush || !size_count[0]))  size_count[15:1] <= size_count[15:1]+1;
        inc_size_count2316 <= (!trailer && !was_trailer && qv && (!will_flush || !size_count[0])) && (&size_count[15:1]);
//reset_data_counters instead of !en here?
        if      (!en || size_out[2]) size_count[23:16] <= 0;
        else if (inc_size_count2316) size_count[23:16] <= size_count[23:16]+1;

        qv <= en && (stage2_bits[4] || trailer);
// to make it faster (if needed) use a single register as a source for  q[15:0] in two following lines
        if      (time_size_out)  q[15:0] <= {sec_r[7:0],sec_r[15:8]};
        else                     q[15:0] <= {(stage2_bits[4]?stage2[31:24]:8'b0),
                                             ((stage2_bits[4] && !send8h)? stage2[23:16]:8'b0)};
        inc_imgsz32 <= (etrax_dma[3:0]== 4'h0) && qv;
//reset_data_counters instead of !en here?
Andrey Filippov's avatar
Andrey Filippov committed
402 403
//        if (reset_data_counters || done) imgsz32[19:0] <= 0;
        if (!en || done) imgsz32[19:0] <= 0; // now en is just for stuffer, waits for flushing to end
404 405
        else if (inc_imgsz32) imgsz32[19:0]<=imgsz32[19:0]+1;

Andrey Filippov's avatar
Andrey Filippov committed
406 407
///        if (reset_data_counters) imgptr[23:0] <= 0;
///        else if (done) imgptr[23:0] <= imgptr[23:0]+ imgsz32[19:0];
408 409 410 411 412 413 414
        
        flush_end_delayed <= en & pre_flush_end_delayed; // en just to prevent optimizing pre_flush_end_delayed+flush_end_delayed into a single SRL16
    end
//start_sizeout
    assign start_time_out= qv && trailer && (etrax_dma[3:0]== 4'h8) && !size_out_over;
    assign start_sizeout= time_out && (etrax_dma[3:0]== 4'hc);
// SRL16_1 i_pre_flush_end_delayed (.D(size_out[1]),.Q(pre_flush_end_delayed), .A0(1'b0), .A1(1'b1), .A2(1'b1), .A3(1'b1), .CLK(clk)); // dly=3+1    // rather arbitrary?
415
    dly_16 #(.WIDTH(1)) i_pre_flush_end_delayed(.clk(~clk),.rst(1'b0), .dly(4'd14), .din(size_out[1]), .dout(pre_flush_end_delayed));    // dly=14+1 // rather arbitrary?
416 417
    assign done = flush_end_delayed;

418 419
    // extract strart of frame run from different clock, re-clock from the source
    always @ (posedge fradv_clk) color_first_r <= color_first;
Andrey Filippov's avatar
Andrey Filippov committed
420
    pulse_cross_clock stb_start_i    (.rst(xrst), .src_clk(fradv_clk), .dst_clk(~clk), .in_pulse(!color_first && color_first_r), .out_pulse(stb_start),.busy());
421
    
Andrey Filippov's avatar
Andrey Filippov committed
422 423
    reg rst_nclk;
    always @ (negedge clk) rst_nclk <= xrst;
424
    timestamp_fifo timestamp_fifo_i (
Andrey Filippov's avatar
Andrey Filippov committed
425
//        .rst      (rst),       // input
426
        .sclk     (mclk),        // input
Andrey Filippov's avatar
Andrey Filippov committed
427
        .srst     (mrst),        // input
428 429 430 431
        .pre_stb  (ts_pre_stb),  // input
        .din      (ts_data),     // input[7:0] 
         // may use stb_start @ negedge clk
        .aclk     (~clk),        //fradv_clk),   // input
Andrey Filippov's avatar
Andrey Filippov committed
432 433
        .arst     (rst_nclk),        //fradv_clk),   // input
        
434 435
        .advance  (stb_start),   // color_first), // input
        .rclk     (~clk),        // input
Andrey Filippov's avatar
Andrey Filippov committed
436
        .rrst     (rst_nclk),    //fradv_clk),   // input
437 438 439 440
        .rstb     (ts_rstb),     // input
        .dout     (ts_dout)      // output[7:0] reg 
    );

441
endmodule