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

module  sens_hispi12l4#(
    parameter IODELAY_GRP =               "IODELAY_SENSOR",
    parameter integer IDELAY_VALUE =       0,
    parameter real REFCLK_FREQUENCY =      200.0,
    parameter HIGH_PERFORMANCE_MODE =     "FALSE",
    parameter SENS_PHASE_WIDTH=            8,      // number of bits for te phase counter (depends on divisors)
Andrey Filippov's avatar
Andrey Filippov committed
47
//    parameter SENS_PCLK_PERIOD =           3.000,  // input period in ns, 0..100.000 - MANDATORY, resolution down to 1 ps
48 49
    parameter SENS_BANDWIDTH =             "OPTIMIZED",  //"OPTIMIZED", "HIGH","LOW"

Andrey Filippov's avatar
Andrey Filippov committed
50 51
    parameter CLKIN_PERIOD_SENSOR =        3.000, // input period in ns, 0..100.000 - MANDATORY, resolution down to 1 ps
    parameter CLKFBOUT_MULT_SENSOR =       3,      // 330 MHz --> 990 MHz
52 53 54 55 56 57 58
    parameter CLKFBOUT_PHASE_SENSOR =      0.000,  // CLOCK FEEDBACK phase in degrees (3 significant digits, -360.000...+360.000)
    parameter IPCLK_PHASE =                0.000,
    parameter IPCLK2X_PHASE =              0.000,
    parameter BUF_IPCLK =                 "BUFR",
    parameter BUF_IPCLK2X =               "BUFR",  

    parameter SENS_DIVCLK_DIVIDE =         1,            // Integer 1..106. Divides all outputs with respect to CLKIN
Andrey Filippov's avatar
Andrey Filippov committed
59
    parameter SENS_REF_JITTER1   =         0.010,        // Expected jitter on CLKIN1 (0.000..0.999)
60 61 62 63 64
    parameter SENS_REF_JITTER2   =         0.010,
    parameter SENS_SS_EN         =        "FALSE",      // Enables Spread Spectrum mode
    parameter SENS_SS_MODE       =        "CENTER_HIGH",//"CENTER_HIGH","CENTER_LOW","DOWN_HIGH","DOWN_LOW"
    parameter SENS_SS_MOD_PERIOD =         10000,        // integer 4000-40000 - SS modulation period in ns

65
    parameter DEFAULT_LANE_MAP =           8'b11100100, // one-to-one map (or make it 8'b00111001 ?)
66
    parameter HISPI_MSB_FIRST =            0,
67
    parameter HISPI_NUMLANES =             4,
68 69
    parameter HISPI_DELAY_CLK =           "FALSE",      
    parameter HISPI_MMCM =                "TRUE",
70 71 72 73
    parameter HISPI_KEEP_IRST =           5,   // number of cycles to keep irst on after release of prst (small number - use 1 hot)
    parameter HISPI_WAIT_ALL_LANES =      4'h8, // number of output pixel cycles to wait after the earliest lane
    parameter HISPI_FIFO_DEPTH =          4,
    parameter HISPI_FIFO_START =          7,
74 75
    parameter HISPI_CAPACITANCE =         "DONT_CARE",
    parameter HISPI_DIFF_TERM =           "TRUE",
76
    parameter HISPI_UNTUNED_SPLIT =       "FALSE", // Very power-hungry
77 78 79 80
    parameter HISPI_DQS_BIAS =            "TRUE",
    parameter HISPI_IBUF_DELAY_VALUE =    "0",
    parameter HISPI_IBUF_LOW_PWR =        "TRUE",
    parameter HISPI_IFD_DELAY_VALUE =     "AUTO",
81
    parameter HISPI_IOSTANDARD =          "DIFF_SSTL18_I" //"DIFF_SSTL18_II" for high current (13.4mA vs 8mA),
82 83
)(
    input             pclk,   // global clock input, pixel rate (220MHz for MT9F002)
Andrey Filippov's avatar
Andrey Filippov committed
84
    input             prst,   // reset @pclk (add sensor reset here)
85 86 87 88 89 90
    // I/O pads
    input [HISPI_NUMLANES-1:0] sns_dp,
    input [HISPI_NUMLANES-1:0] sns_dn,
    input                      sns_clkp,
    input                      sns_clkn,
    // output
Andrey Filippov's avatar
Andrey Filippov committed
91 92 93
//    output reg          [11:0] pxd_out,
    output              [11:0] pxd_out,
//    output reg                 vact_out, 
94
    output                     hact_out,
Andrey Filippov's avatar
Andrey Filippov committed
95 96
    output                     sof, // @pclk
    output reg                 eof, // @pclk
97 98 99 100 101
    
    // delay control inputs
    input                           mclk,
    input                           mrst,
    input  [HISPI_NUMLANES * 8-1:0] dly_data,        // delay value (3 LSB - fine delay) - @posedge mclk
102
    input                           set_lanes_map,   // set number of physical lane for each logical one
103
    input                           set_fifo_dly,
104 105
    input      [HISPI_NUMLANES-1:0] set_idelay,      // mclk synchronous load idelay value
    input                           ld_idelay,       // mclk synchronous set idealy value
106
    input                           set_clk_phase,   // mclk synchronous set idealy value
107
    input                           rst_mmcm,
Andrey Filippov's avatar
Andrey Filippov committed
108
    input                           ignore_embedded, // ignore lines with embedded data
109
//    input                           wait_all_lanes,  // when 0 allow some lanes missing sync (for easier phase adjustment)
110
    // MMCP output status
Andrey Filippov's avatar
Andrey Filippov committed
111 112 113 114 115
    output                         ps_rdy,          // output
    output                   [7:0] ps_out,          // output[7:0] reg 
    output                         locked_pxd_mmcm,
    output                         clkin_pxd_stopped_mmcm, // output
    output                         clkfb_pxd_stopped_mmcm // output
116 117 118 119 120
    
);
    wire                          ipclk;  // re-generated half HiSPi clock (165 MHz) 
    wire                          ipclk2x;// re-generated HiSPi clock (330 MHz)
    wire [HISPI_NUMLANES * 4-1:0] sns_d;
121 122
//    localparam WAIT_ALL_LANES = 4'h8; // number of output pixel cycles to wait after the earliest lane
//    localparam FIFO_DEPTH = 4;
Andrey Filippov's avatar
Andrey Filippov committed
123
    reg      [HISPI_KEEP_IRST-1:0] irst_r;
124 125
    wire                          irst = irst_r[0];
    reg  [HISPI_NUMLANES * 2-1:0] lanes_map;
126 127 128
    reg  [HISPI_NUMLANES * 4-1:0] logical_lanes4;
    reg    [HISPI_FIFO_DEPTH-1:0] fifo_out_dly_mclk;                  
    reg    [HISPI_FIFO_DEPTH-1:0] fifo_out_dly;                  
129 130 131
    always @ (posedge mclk) begin
        if      (mrst)          lanes_map <= DEFAULT_LANE_MAP; //{2'h3,2'h2,2'h1,2'h0}; // 1-to-1 default map
        else if (set_lanes_map) lanes_map <= dly_data[HISPI_NUMLANES * 2-1:0];
132 133 134

        if      (mrst)          fifo_out_dly_mclk <= HISPI_FIFO_START;
        else if (set_fifo_dly)  fifo_out_dly_mclk <= dly_data[HISPI_FIFO_DEPTH-1:0];
135 136 137 138 139 140 141 142 143 144
    end
    
//non-parametrized lane switch (4x4)
    always  @(posedge ipclk) begin
        logical_lanes4[ 3: 0] <= sns_d[{lanes_map[1:0],2'b0} +:4];
        logical_lanes4[ 7: 4] <= sns_d[{lanes_map[3:2],2'b0} +:4];
        logical_lanes4[11: 8] <= sns_d[{lanes_map[5:4],2'b0} +:4];
        logical_lanes4[15:12] <= sns_d[{lanes_map[7:6],2'b0} +:4];
    end   
    
145 146 147
    always  @(posedge ipclk) begin
        fifo_out_dly <= fifo_out_dly_mclk;
    end
Andrey Filippov's avatar
Andrey Filippov committed
148
    
149 150 151
    sens_hispi_clock #(
        .SENS_PHASE_WIDTH       (SENS_PHASE_WIDTH),
        .SENS_BANDWIDTH         (SENS_BANDWIDTH),
Andrey Filippov's avatar
Andrey Filippov committed
152
        .CLKIN_PERIOD_SENSOR    (CLKIN_PERIOD_SENSOR),
153 154 155 156 157 158 159 160 161 162 163 164
        .CLKFBOUT_MULT_SENSOR   (CLKFBOUT_MULT_SENSOR),
        .CLKFBOUT_PHASE_SENSOR  (CLKFBOUT_PHASE_SENSOR),
        .IPCLK_PHASE            (IPCLK_PHASE),
        .IPCLK2X_PHASE          (IPCLK2X_PHASE),
        .BUF_IPCLK              (BUF_IPCLK),
        .BUF_IPCLK2X            (BUF_IPCLK2X),
        .SENS_DIVCLK_DIVIDE     (SENS_DIVCLK_DIVIDE),
        .SENS_REF_JITTER1       (SENS_REF_JITTER1),
        .SENS_REF_JITTER2       (SENS_REF_JITTER2),
        .SENS_SS_EN             (SENS_SS_EN),
        .SENS_SS_MODE           (SENS_SS_MODE),
        .SENS_SS_MOD_PERIOD     (SENS_SS_MOD_PERIOD),
165 166 167 168 169 170 171 172
        .IODELAY_GRP            (IODELAY_GRP),
        .IDELAY_VALUE           (IDELAY_VALUE),
        .REFCLK_FREQUENCY       (REFCLK_FREQUENCY),
        .HIGH_PERFORMANCE_MODE  (HIGH_PERFORMANCE_MODE),

        .HISPI_DELAY_CLK        (HISPI_DELAY_CLK),
        .HISPI_MMCM             (HISPI_MMCM),
        
173 174 175 176 177 178 179 180 181 182 183 184
        .HISPI_CAPACITANCE      (HISPI_CAPACITANCE),
        .HISPI_DIFF_TERM        (HISPI_DIFF_TERM),
        .HISPI_DQS_BIAS         (HISPI_DQS_BIAS),
        .HISPI_IBUF_DELAY_VALUE (HISPI_IBUF_DELAY_VALUE),
        .HISPI_IBUF_LOW_PWR     (HISPI_IBUF_LOW_PWR),
        .HISPI_IFD_DELAY_VALUE  (HISPI_IFD_DELAY_VALUE),
        .HISPI_IOSTANDARD       (HISPI_IOSTANDARD)
    ) sens_hispi_clock_i (
        .mclk                   (mclk),                   // input
        .mrst                   (mrst),                   // input
        .phase                  (dly_data[7:0]),          // input[7:0] 
        .set_phase              (set_clk_phase),          // input
185
        .load                   (ld_idelay),              // input
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
        .rst_mmcm               (rst_mmcm),               // input
        .clp_p                  (sns_clkp),               // input
        .clk_n                  (sns_clkn),               // input
        .ipclk                  (ipclk),                  // output
        .ipclk2x                (ipclk2x),                // output
        .ps_rdy                 (ps_rdy),                 // output
        .ps_out                 (ps_out),                 // output[7:0] 
        .locked_pxd_mmcm        (locked_pxd_mmcm),        // output
        .clkin_pxd_stopped_mmcm (clkin_pxd_stopped_mmcm), // output
        .clkfb_pxd_stopped_mmcm (clkfb_pxd_stopped_mmcm)  // output
    );

    sens_hispi_din #(
        .IODELAY_GRP            (IODELAY_GRP),
        .IDELAY_VALUE           (IDELAY_VALUE),
        .REFCLK_FREQUENCY       (REFCLK_FREQUENCY),
        .HIGH_PERFORMANCE_MODE  (HIGH_PERFORMANCE_MODE),
        .HISPI_NUMLANES         (HISPI_NUMLANES),
        .HISPI_CAPACITANCE      (HISPI_CAPACITANCE),
        .HISPI_DIFF_TERM        (HISPI_DIFF_TERM),
206
        .HISPI_UNTUNED_SPLIT    (HISPI_UNTUNED_SPLIT),        
207 208 209 210 211 212 213 214 215 216 217 218 219 220
        .HISPI_DQS_BIAS         (HISPI_DQS_BIAS),
        .HISPI_IBUF_DELAY_VALUE (HISPI_IBUF_DELAY_VALUE),
        .HISPI_IBUF_LOW_PWR     (HISPI_IBUF_LOW_PWR),
        .HISPI_IFD_DELAY_VALUE  (HISPI_IFD_DELAY_VALUE),
        .HISPI_IOSTANDARD       (HISPI_IOSTANDARD)
    ) sens_hispi_din_i (
        .mclk         (mclk), // input
        .mrst         (mrst), // input
        .dly_data     (dly_data), // input[31:0] 
        .set_idelay   (set_idelay), // input[3:0] 
        .ld_idelay    (ld_idelay), // input
        .ipclk        (ipclk), // input
        .ipclk2x      (ipclk2x), // input
        .irst         (irst), // input
221 222 223 224
//`ifdef REVERSE_LANES
//        .din_p        ({sns_dp[0],sns_dp[1],sns_dp[2],sns_dp[3]}), // input[3:0] 
//        .din_n        ({sns_dn[0],sns_dn[1],sns_dn[2],sns_dn[3]}), // input[3:0] 
//`else
225 226
        .din_p        (sns_dp), // input[3:0] 
        .din_n        (sns_dn), // input[3:0] 
227
//`endif        
228 229
        .dout         (sns_d) // output[15:0] 
    );
230
    
Andrey Filippov's avatar
Andrey Filippov committed
231 232
    

233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252
    wire [HISPI_NUMLANES * 12-1:0] hispi_aligned;
    wire      [HISPI_NUMLANES-1:0] hispi_dv;
    wire      [HISPI_NUMLANES-1:0] hispi_embed;
    wire      [HISPI_NUMLANES-1:0] hispi_sof;
    wire      [HISPI_NUMLANES-1:0] hispi_eof;
    wire      [HISPI_NUMLANES-1:0] hispi_sol;
    wire      [HISPI_NUMLANES-1:0] hispi_eol;
   // TODO - try to make that something will be recorded even if some lanes are bad (to simplify phase adjust
   // possibly - extra control bit (wait_all_lanes)
   //    use earliest SOF
    reg                             vact_ipclk;
    reg                       [1:0] vact_pclk_strt;
    wire       [HISPI_NUMLANES-1:0] rd_run;
    reg                             rd_line; // combine all lanes
    reg                             rd_line_r;
    wire                            sol_all_dly;
    reg        [HISPI_NUMLANES-1:0] rd_run_d;
    reg                             sof_pclk;
//    wire       [HISPI_NUMLANES-1:0] sol_pclk = rd_run & ~rd_run_d;
    wire                            sol_pclk = |(rd_run & ~rd_run_d); // possibly multi-cycle
253
    reg                             start_fifo_re; // start reading FIFO - single-cycle
254 255 256 257 258 259 260
    reg        [HISPI_NUMLANES-1:0] good_lanes; // lanes that started active line OK   
    reg        [HISPI_NUMLANES-1:0] fifo_re;
    reg        [HISPI_NUMLANES-1:0] fifo_re_r;
    reg                             hact_r;
    wire  [HISPI_NUMLANES * 12-1:0] fifo_out;
    wire                            hact_on;
    wire                            hact_off;
Andrey Filippov's avatar
Andrey Filippov committed
261
    reg                             ignore_embedded_ipclk;
Andrey Filippov's avatar
Andrey Filippov committed
262 263 264 265 266
    reg                       [1:0] vact_pclk;
    wire                     [11:0] pxd_out_pre = ({12 {fifo_re_r[0] & rd_run[0]}} & fifo_out[0 * 12 +:12]) |
                                                  ({12 {fifo_re_r[1] & rd_run[1]}} & fifo_out[1 * 12 +:12]) |
                                                  ({12 {fifo_re_r[2] & rd_run[2]}} & fifo_out[2 * 12 +:12]) |
                                                  ({12 {fifo_re_r[3] & rd_run[3]}} & fifo_out[3 * 12 +:12]);
267
    reg                             start_only; // time window at the beginning of each line, can not end here                                              
Andrey Filippov's avatar
Andrey Filippov committed
268 269 270
       
    
    
271
    assign hact_out = hact_r;
Andrey Filippov's avatar
Andrey Filippov committed
272 273 274 275 276 277 278 279 280
    assign sof =      sof_pclk;
    
    // async reset
    always @ (posedge ipclk or posedge prst) begin
        if (prst) irst_r <= {HISPI_KEEP_IRST{1'b1}}; // HISPI_KEEP_IRST-1
        else      irst_r <= irst_r >> 1; 
    end
    
    
281 282
    
    always @(posedge ipclk) begin
Andrey Filippov's avatar
Andrey Filippov committed
283
//        irst_r <= {irst_r[1:0], prst};
Andrey Filippov's avatar
Andrey Filippov committed
284
    
Andrey Filippov's avatar
Andrey Filippov committed
285 286
        if (irst || (|hispi_eof)) vact_ipclk <= 0; // extend output if hact active
        else if (|hispi_sof)      vact_ipclk <= 1;
287
    
Andrey Filippov's avatar
Andrey Filippov committed
288
        ignore_embedded_ipclk <= ignore_embedded;
289 290 291
    end
    
    always @(posedge pclk) begin
292 293
        if (prst || !vact_ipclk) vact_pclk_strt <= 0;
        else                     vact_pclk_strt <= {vact_pclk_strt[0], 1'b1};
294

295
        rd_run_d <= rd_run;
296 297
        
        start_fifo_re <= sol_pclk && !rd_line; // sol_pclk may be multi-cycle
298 299
       
        sof_pclk <= vact_pclk_strt[0] && ! vact_pclk_strt[1];
300 301 302 303
        
        if (prst || sof_pclk || sol_all_dly) start_only <= 0;
        else if (sol_pclk)                   start_only <= 1;
        
304 305 306
       
        if      (prst || sof_pclk) rd_line <= 0;
        else if (sol_pclk)         rd_line <= 1;
307
        else                       rd_line <= rd_line & (start_only || (&(~good_lanes | rd_run))); // Off when first of the good lanes goes off      
308 309 310
       
        rd_line_r <= rd_line;
        
Andrey Filippov's avatar
Andrey Filippov committed
311
        if (sol_pclk && !rd_line) good_lanes <= ~rd_run_d;             // should be off before start
312 313 314 315 316
        else if (sol_all_dly)     good_lanes <= good_lanes & rd_run; // and now they should be on
        
        fifo_re_r <= fifo_re & rd_run; // when data out is ready, mask if not running
        
        // not using HISPI_NUMLANES here - fix? Will be 0 (not possible in hispi) when no data
Andrey Filippov's avatar
Andrey Filippov committed
317 318 319 320
/*        pxd_out <= ({12 {fifo_re_r[0] & rd_run[0]}} & fifo_out[0 * 12 +:12]) |
                   ({12 {fifo_re_r[1] & rd_run[1]}} & fifo_out[1 * 12 +:12]) |
                   ({12 {fifo_re_r[2] & rd_run[2]}} & fifo_out[2 * 12 +:12]) |
                   ({12 {fifo_re_r[3] & rd_run[3]}} & fifo_out[3 * 12 +:12]); */
321
       
322 323 324 325
       if      (prst)                                                      fifo_re <= 0;
//       else if (sol_pclk || (rd_line && fifo_re[HISPI_NUMLANES - 1])) fifo_re <= 1;
       else if (start_fifo_re || (rd_line && fifo_re[HISPI_NUMLANES - 1])) fifo_re <= 1;
       else                                                                fifo_re <= fifo_re << 1;
326
       
Andrey Filippov's avatar
Andrey Filippov committed
327 328 329
//       if (prst || (hact_off && (|(good_lanes & ~rd_run)))) hact_r <= 0;
       if (prst || (hact_off && (!rd_line || (good_lanes[3] & ~rd_run[3])))) hact_r <= 0;
       else if (hact_on)                                    hact_r <= 1;
330
       
Andrey Filippov's avatar
Andrey Filippov committed
331 332 333
       vact_pclk <= {vact_pclk[0],vact_pclk_strt [0] || hact_r};
       eof <= vact_pclk[1] && !vact_pclk[0]; 
//       vact_out <= vact_pclk_strt [0] || hact_r;
334 335 336 337 338 339 340
    end

    dly_16 #(
        .WIDTH(1)
    ) dly_16_start_line_i (
        .clk  (pclk),                  // input
        .rst  (1'b0),                  // input
341
        .dly  (HISPI_WAIT_ALL_LANES),  // input[3:0] 
342 343 344 345 346 347 348 349 350
        .din  (rd_line && !rd_line_r), // input[0:0] 
        .dout (sol_all_dly)            // output[0:0] 
    );

    dly_16 #(
        .WIDTH(1)
    ) dly_16_hact_on_i (
        .clk  (pclk),                        // input
        .rst  (1'b0),                        // input
351 352
//        .dly  (4'h2),                      // input[3:0] 
//        .dly  (4'h3),                      // input[3:0] 
353
        .dly  (4'h1),                        // input[3:0] 
354
//        .dly  (4'h2),                      // input[3:0] 
355 356 357 358 359 360 361 362 363
        .din  (sol_pclk),                    // input[0:0] 
        .dout (hact_on)                      // output[0:0] 
    );

    dly_16 #(
        .WIDTH(1)
    ) dly_16_hact_off_i (
        .clk  (pclk),                        // input
        .rst  (1'b0),                        // input
Andrey Filippov's avatar
Andrey Filippov committed
364 365
//        .dly  (4'h2),                        // input[3:0] 
//        .dly  (4'h0),                        // input[3:0] 
366 367
        .dly  (4'h1),                        // input[3:0] 
//        .dly  (4'h2),                        // input[3:0] 
368 369 370
        .din  (fifo_re[HISPI_NUMLANES - 1]), // input[0:0] 
        .dout (hact_off)                     // output[0:0] 
    );
371

Andrey Filippov's avatar
Andrey Filippov committed
372 373 374 375 376 377
    dly_16 #(
        .WIDTH(12)
    ) dly_16_pxd_out_i (
        .clk  (pclk),                        // input
        .rst  (1'b0),                        // input
//        .dly  (4'h2),                        // input[3:0] 
378 379
        .dly  (4'h0),                        // input[3:0] 
//        .dly  (4'h1),                        // input[3:0] 
Andrey Filippov's avatar
Andrey Filippov committed
380 381 382
        .din  (pxd_out_pre),                 // input[0:0] 
        .dout (pxd_out)                      // output[0:0] 
    );
383 384 385 386 387 388 389 390 391
   
    generate
        genvar i;
        for (i=0; i < 4; i=i+1) begin: hispi_lane
            sens_hispi_lane #(
                .HISPI_MSB_FIRST(HISPI_MSB_FIRST)
            ) sens_hispi_lane_i (
                .ipclk    (ipclk),                     // input
                .irst     (irst),                      // input
392
                .din      (logical_lanes4[4*i +: 4]),           // input[3:0] 
393 394 395 396 397 398 399 400 401
                .dout     (hispi_aligned[12*i +: 12]), // output[3:0] reg 
                .dv       (hispi_dv[i]),               // output reg 
                .embed    (hispi_embed[i]),            // output reg 
                .sof      (hispi_sof[i]),              // output reg 
                .eof      (hispi_eof[i]),              // output reg 
                .sol      (hispi_sol[i]),              // output reg 
                .eol      (hispi_eol[i])               // output reg 
            );
            sens_hispi_fifo #(
402
//                .COUNT_START  (HISPI_FIFO_START),
403
                .DATA_WIDTH  (12),
404
                .DATA_DEPTH  (HISPI_FIFO_DEPTH)
405 406 407 408
            ) sens_hispi_fifo_i (
                .ipclk    (ipclk),                     // input
                .irst     (irst),                      // input
                .we       (hispi_dv[i]),               // input
Andrey Filippov's avatar
Andrey Filippov committed
409
                .sol      (hispi_sol[i] && !(hispi_embed[i] && ignore_embedded_ipclk)), // input
410
                .eol      (hispi_eol[i]),              // input
411 412
                .din      (hispi_aligned[12*i +: 12]), // input[11:0]
                .out_dly  (fifo_out_dly),              // input[3:0] 
413 414 415 416 417 418 419 420 421
                .pclk     (pclk),                      // input
                .prst     (prst),                      // input
                .re       (fifo_re[i]),                // input
                .dout     (fifo_out[12*i +: 12]),      // output[11:0] reg 
                .run      (rd_run[i])                  // output
            );
        
        end
    endgenerate        
422 423 424

endmodule