Commit 722e3aca authored by Andrey Filippov's avatar Andrey Filippov
Browse files

Added measurement of HISPI cycles between SOF, EOF, SOL, EOL. Version

03930101
parent 17dd79cf
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -36,7 +36,8 @@
 * with at least one of the Free Software programs.
 * with at least one of the Free Software programs.
 */
 */
 
 
        parameter FPGA_VERSION =          32'h03930100;      // serial - 17.4 - disabling SOF when setting interface
        parameter FPGA_VERSION =          32'h03930101;      // serial - 17.4 - disabling SOF when setting interface
//      parameter FPGA_VERSION =          32'h03930100;      // serial - 17.4 - disabling SOF when setting interface timing OK
//      parameter FPGA_VERSION =          32'h039300ff;      // serial - 15.3 - same, suspected bitstream problems
//      parameter FPGA_VERSION =          32'h039300ff;      // serial - 15.3 - same, suspected bitstream problems
//      parameter FPGA_VERSION =          32'h039300fe;      // serial - 17.4 - same, suspected bitstream problems no timing errors
//      parameter FPGA_VERSION =          32'h039300fe;      // serial - 17.4 - same, suspected bitstream problems no timing errors
//      parameter FPGA_VERSION =          32'h039300fd;      // serial - 17.4 - monitor lanes barrel (0..3)
//      parameter FPGA_VERSION =          32'h039300fd;      // serial - 17.4 - monitor lanes barrel (0..3)
+13 −3
Original line number Original line Diff line number Diff line
@@ -356,6 +356,16 @@
    parameter SENSI2C_STATUS_REG_INC =    2,     // increment to the next sensor
    parameter SENSI2C_STATUS_REG_INC =    2,     // increment to the next sensor
    parameter SENSI2C_STATUS_REG_REL =    0,     // 4 locations" 'h20, 'h22, 'h24, 'h26
    parameter SENSI2C_STATUS_REG_REL =    0,     // 4 locations" 'h20, 'h22, 'h24, 'h26
    parameter SENSIO_STATUS_REG_REL =     1,     // 4 locations" 'h21, 'h23, 'h25, 'h27
    parameter SENSIO_STATUS_REG_REL =     1,     // 4 locations" 'h21, 'h23, 'h25, 'h27
    
    // parameters to measure sensor timing from (last){sof,eof,sol, eol} to next{sof,eof,sol, eol}
    parameter SENSOR_TIMING_STATUS_REG_BASE =   'h40,  // 4 locations" x40, x41, x42, x43
    parameter SENSOR_TIMING_STATUS_REG_INC =      1,   // increment to the next sensor
    parameter SENSOR_TIMING_BITS =               24,   // increment to the next sensor
    parameter SENSOR_TIMING_START =              16,   // bit # in JTAB control word to start timing measurement (now f = 660/4 = 165) 
    parameter SENSOR_TIMING_LANE =               14,   // 15:14 - select lane
    parameter SENSOR_TIMING_FROM =               12,   // select from 0 - sof, 1 - eof, 2 - sol, 3 eol
    parameter SENSOR_TIMING_TO =                 10,   // select to   0 - sof, 1 - eof, 2 - sol, 3 eol
    
    parameter SENSOR_NUM_HISTOGRAM=       1, //was 3  trying just one histogram (see utilization) 3,     // number of histogram channels
    parameter SENSOR_NUM_HISTOGRAM=       1, //was 3  trying just one histogram (see utilization) 3,     // number of histogram channels
    parameter HISTOGRAM_RAM_MODE =        "BUF32", // "NOBUF", // valid: "NOBUF" (32-bits, no buffering), "BUF18", "BUF32"
    parameter HISTOGRAM_RAM_MODE =        "BUF32", // "NOBUF", // valid: "NOBUF" (32-bits, no buffering), "BUF18", "BUF32"
    parameter SENS_NUM_SUBCHN =           3,     // number of subchannels for his sensor ports (1..4)
    parameter SENS_NUM_SUBCHN =           3,     // number of subchannels for his sensor ports (1..4)
+25 −0
Original line number Original line Diff line number Diff line
@@ -331,6 +331,11 @@ class X393ExportC(object):
                                 name =      "x393_status_sens_i2c",  typ="ro",
                                 name =      "x393_status_sens_i2c",  typ="ro",
                                 frmt_spcs = frmt_spcs)
                                 frmt_spcs = frmt_spcs)


        stypedefs += self.get_typedef32(comment =   "Sensor measured timing between sof/eof/sol/eol",
                                 data =      self._enc_status_sensor_timing(),
                                 name =      "x393_status_sensor_timing",  typ="ro",
                                 frmt_spcs = frmt_spcs)

        stypedefs += self.get_typedef32(comment =   "Command bits for test01 module (test frame memory accesses)",
        stypedefs += self.get_typedef32(comment =   "Command bits for test01 module (test frame memory accesses)",
                                 data =      self._enc_test01_mode(),
                                 data =      self._enc_test01_mode(),
                                 name =      "x393_test01_mode",  typ="wo",
                                 name =      "x393_test01_mode",  typ="wo",
@@ -940,6 +945,14 @@ class X393ExportC(object):
            (("X393_SENSIO_STATUS",                     c, vrlg.SENSIO_STATUS_REG_REL +       ba, ia, z3, "x393_status_sens_io", "ro",                        "Status of the sensor ports I/O pins")),
            (("X393_SENSIO_STATUS",                     c, vrlg.SENSIO_STATUS_REG_REL +       ba, ia, z3, "x393_status_sens_io", "ro",                        "Status of the sensor ports I/O pins")),
            ]
            ]


        #sensors time measurements (in 1/4 DDR bitrate, now 165MHz)        
        ba = vrlg.STATUS_ADDR + vrlg.SENSOR_TIMING_STATUS_REG_BASE
        ia = vrlg.SENSOR_TIMING_STATUS_REG_INC
        c =  "sens_num"
        sdefines +=[
            (('Read-only addresses for sensors time measurement information',)),
            (("SENSOR_TIMING_STATUS",                   c, 0 +                                ba, ia, z3, "x393_status_sensor_timing", "ro",                  "Measured duration between selected sof/eof/sol/eol")),
            ]
        #Compressor control
        #Compressor control
        sdefines +=[
        sdefines +=[
            (('Compressor bitfields values',)),
            (('Compressor bitfields values',)),
@@ -1857,6 +1870,7 @@ class X393ExportC(object):
        dw.append(("barrel_1",              16, 2,0,  "Lane 1 barrel shift"))
        dw.append(("barrel_1",              16, 2,0,  "Lane 1 barrel shift"))
        dw.append(("barrel_2",              18, 2,0,  "Lane 2 barrel shift"))
        dw.append(("barrel_2",              18, 2,0,  "Lane 2 barrel shift"))
        dw.append(("barrel_3",              20, 2,0,  "Lane 3 barrel shift"))
        dw.append(("barrel_3",              20, 2,0,  "Lane 3 barrel shift"))
        dw.append(("time_busy",             22, 1,0,  "Sensor time measurement in progress"))
#        dw.append(("lanes_alive",           14, 4,0,  "Per-lane HACT toggling (reset by changing DLL delays)"))
#        dw.append(("lanes_alive",           14, 4,0,  "Per-lane HACT toggling (reset by changing DLL delays)"))
#        dw.append(("rel_sol",               18, 3,0,  "When SOL active on the last lane @ipclk, latches all other lanes SOL"))
#        dw.append(("rel_sol",               18, 3,0,  "When SOL active on the last lane @ipclk, latches all other lanes SOL"))
#        dw.append(("vact_alive",            15, 1,0,  "VACT signal from the sensor is toggling (N/A for HiSPI)"))
#        dw.append(("vact_alive",            15, 1,0,  "VACT signal from the sensor is toggling (N/A for HiSPI)"))
@@ -1881,6 +1895,13 @@ class X393ExportC(object):
        dw.append(("seq_num",               26, 6,0,  "Sequence number"))
        dw.append(("seq_num",               26, 6,0,  "Sequence number"))
        return dw
        return dw


    def _enc_status_sensor_timing(self):
        dw=[]
        dw.append(("quad_cycles",            0, vrlg.SENSOR_TIMING_BITS,0,  "Measured time in quad HISPI cycles (now 165 MHz)"))
        return dw





    def _enc_test01_mode(self): # command for test01 module (test frame memory accesses)
    def _enc_test01_mode(self): # command for test01 module (test frame memory accesses)
        dw=[]
        dw=[]
@@ -2097,6 +2118,10 @@ class X393ExportC(object):
        dw.append(("prog_set",     vrlg.SENS_JTAG_PROG + 1,    1,   0,  "Sensor port PROG set to 'prog' field"))
        dw.append(("prog_set",     vrlg.SENS_JTAG_PROG + 1,    1,   0,  "Sensor port PROG set to 'prog' field"))
        dw.append(("pgmen",        vrlg.SENS_JTAG_PGMEN,       1,   0 , "Sensor port PGMEN level"))
        dw.append(("pgmen",        vrlg.SENS_JTAG_PGMEN,       1,   0 , "Sensor port PGMEN level"))
        dw.append(("pgmen_set",    vrlg.SENS_JTAG_PGMEN + 1,   1,   0,  "Sensor port PGMEN set to 'pgmen' field"))
        dw.append(("pgmen_set",    vrlg.SENS_JTAG_PGMEN + 1,   1,   0,  "Sensor port PGMEN set to 'pgmen' field"))
        dw.append(("timing_to",    vrlg.SENSOR_TIMING_TO,      2,   0,  "Measuring sensor time to: 0 - sof, 1 - eof, 2 - sol, 3 eol"))
        dw.append(("timing_from",  vrlg.SENSOR_TIMING_FROM,    2,   0,  "Measuring sensor time from: 0 - sof, 1 - eof, 2 - sol, 3 eol"))
        dw.append(("timing_from",  vrlg.SENSOR_TIMING_LANE,    2,   0,  "Measuring sensor time on lane 0..3"))
        dw.append(("timing_start", vrlg.SENSOR_TIMING_START,   1,   0,  "Start sensor timing measurement"))
        return dw
        return dw
    """    
    """    
    def _enc_sensio_dly_par12(self):
    def _enc_sensio_dly_par12(self):
+62 −47
Original line number Original line Diff line number Diff line
@@ -37,7 +37,7 @@
 * with at least one of the Free Software programs.
 * with at least one of the Free Software programs.
 */
 */
`timescale 1ns/1ps
`timescale 1ns/1ps

//`define MON_HISPI // moved to system_defines
module  sens_10398 #(
module  sens_10398 #(
    parameter SENSIO_ADDR =        'h330,
    parameter SENSIO_ADDR =        'h330,
    parameter SENSIO_ADDR_MASK =   'h7f8,
    parameter SENSIO_ADDR_MASK =   'h7f8,
@@ -48,6 +48,15 @@ module sens_10398 #(
    parameter SENSIO_DELAYS =      'h4, // 'h4..'h7 - each address sets 4 delays through 4 bytes of 32-bit data
    parameter SENSIO_DELAYS =      'h4, // 'h4..'h7 - each address sets 4 delays through 4 bytes of 32-bit data
// 5, swap lanes 6 - delays, 7 - phase
// 5, swap lanes 6 - delays, 7 - phase
    parameter SENSIO_STATUS_REG =  'h21,
    parameter SENSIO_STATUS_REG =  'h21,
`ifdef MON_HISPI    
    parameter SENSOR_TIMING_BITS = 24,     // increment to the next sensor
    parameter TIM_START =         16,
    parameter TIM_LANE  =         14,
    parameter TIM_FROM  =         12,
    parameter TIM_TO  =           10,
    parameter SENSOR_TIMING_STATUS_REG =  'h40,
`endif    
    
    parameter SENS_JTAG_PGMEN =    8,
    parameter SENS_JTAG_PGMEN =    8,
    parameter SENS_JTAG_PROG =     6,
    parameter SENS_JTAG_PROG =     6,
    parameter SENS_JTAG_TCK =      4,
    parameter SENS_JTAG_TCK =      4,
@@ -226,11 +235,18 @@ module sens_10398 #(
    wire           hact_mclk;
    wire           hact_mclk;
    reg            hact_alive;
    reg            hact_alive;
    wire  [HISPI_NUMLANES*2-1:0] mon_barrel;          // @ipclk per-lane monitor barrel shifter  
    wire  [HISPI_NUMLANES*2-1:0] mon_barrel;          // @ipclk per-lane monitor barrel shifter  
//    wire  [HISPI_NUMLANES-1:0] monitor_pclk;

//    wire  [HISPI_NUMLANES-1:0] monitor_mclk;
`ifdef MON_HISPI
//    wire  [HISPI_NUMLANES-2:0] monitor_diff;  
    reg                     [3:0] tim_start;
//    reg   [HISPI_NUMLANES-1:0] lanes_alive;
    reg                     [1:0] tim_lane;
//    assign status = {monitor_diff, lanes_alive,
    reg                     [1:0] tim_from; // 0 - sof, 1 - sol, 2 - eof, 3 eol
    reg                     [1:0] tim_to;   // 0 - sof, 1 - sol, 2 - eof, 3 eol
    wire                          tim_busy;
    wire                   [31:0] tim_cntr;                                       
`endif    



    assign status = {mon_barrel,
    assign status = {mon_barrel,
                     hact_alive, locked_pxd_mmcm, 
                     hact_alive, locked_pxd_mmcm, 
                     clkin_pxd_stopped_mmcm, clkfb_pxd_stopped_mmcm, xfpgadone,
                     clkin_pxd_stopped_mmcm, clkfb_pxd_stopped_mmcm, xfpgadone,
@@ -304,12 +320,6 @@ module sens_10398 #(
        if  (mrst) ld_idelay <= 0;
        if  (mrst) ld_idelay <= 0;
        else       ld_idelay <= set_ctrl_r && data_r[SENS_CTRL_LD_DLY]; 
        else       ld_idelay <= set_ctrl_r && data_r[SENS_CTRL_LD_DLY]; 


///        if      (mrst)                                      gp_r[0] <= 0;
///        else if (set_ctrl_r && data_r[SENS_CTRL_GP0 + 1])   gp_r[0] <= data_r[SENS_CTRL_GP0]; 

///        if      (mrst)                                      gp_r[1] <= 0;
///        else if (set_ctrl_r && data_r[SENS_CTRL_GP1 + 1])   gp_r[1] <= data_r[SENS_CTRL_GP1]; 

        if      (mrst)                                      gp_r[1:0] <= 0;
        if      (mrst)                                      gp_r[1:0] <= 0;
        else if (set_ctrl_r && data_r[SENS_CTRL_GP0 + 2])   gp_r[1:0] <= data_r[SENS_CTRL_GP0+:2]; 
        else if (set_ctrl_r && data_r[SENS_CTRL_GP0 + 2])   gp_r[1:0] <= data_r[SENS_CTRL_GP0+:2]; 


@@ -321,11 +331,17 @@ module sens_10398 #(
        if      (mrst || set_iclk_phase || set_idelays)     hact_alive <= 0;
        if      (mrst || set_iclk_phase || set_idelays)     hact_alive <= 0;
        else if (hact_mclk)                                 hact_alive <= 1;
        else if (hact_mclk)                                 hact_alive <= 1;
        
        
//        if      (mrst || set_iclk_phase || set_idelays)     lanes_alive <= 0;
//        else                                                lanes_alive <= lanes_alive | monitor_mclk;

        if      (mrst)                                      lines_skip <= 0;
        if      (mrst)                                      lines_skip <= 0;
        else if (set_skip_r)                                lines_skip <= data_r[SENSIO_SKIP_BITS-1:0]; 
        else if (set_skip_r)                                lines_skip <= data_r[SENSIO_SKIP_BITS-1:0]; 
        
`ifdef MON_HISPI
        tim_start <= {tim_start[2:0], set_jtag_r & data_r[TIM_START]};
        if (set_jtag_r & data_r[TIM_START]) begin
            tim_lane <= data_r[TIM_LANE +: 2];
            tim_from <= data_r[TIM_FROM +: 2];
            tim_to   <= data_r[TIM_TO   +: 2];
        end
`endif            
    end
    end


    // generate (slow) clock for the sensor - it will be multiplied by the sensor VCO
    // generate (slow) clock for the sensor - it will be multiplied by the sensor VCO
@@ -375,10 +391,26 @@ module sens_10398 #(
        .data        (cmd_data), // output[31:0] 
        .data        (cmd_data), // output[31:0] 
        .we          (cmd_we)    // output
        .we          (cmd_we)    // output
    );
    );

`ifdef MON_HISPI    
    status_generate #(
        .STATUS_REG_ADDR(SENSIO_STATUS_REG),
        .PAYLOAD_BITS(1+15+1+2*HISPI_NUMLANES), // +3) // +STATUS_ALIVE_WIDTH) // STATUS_PAYLOAD_BITS)
        .EXTRA_WORDS(1),
        .EXTRA_REG_ADDR(SENSOR_TIMING_STATUS_REG)
    ) status_generate_sens_io_i (
        .rst        (1'b0),                      // rst), // input
        .clk        (mclk),                      // input
        .srst       (mrst),                      // input
        .we         (set_status_r),              // input
        .wd         (data_r[7:0]),               // input[7:0] 
        .status     ({tim_cntr,tim_busy,status}),// input[22:0] 
        .ad         (status_ad),                 // output[7:0] 
        .rq         (status_rq),                 // output
        .start      (status_start)               // input
    );
`else
    status_generate #(
    status_generate #(
        .STATUS_REG_ADDR(SENSIO_STATUS_REG),
        .STATUS_REG_ADDR(SENSIO_STATUS_REG),
//        .PAYLOAD_BITS(3+15+1+HISPI_NUMLANES) // +3) // +STATUS_ALIVE_WIDTH) // STATUS_PAYLOAD_BITS)
        .PAYLOAD_BITS(15+1+2*HISPI_NUMLANES) // +3) // +STATUS_ALIVE_WIDTH) // STATUS_PAYLOAD_BITS)
        .PAYLOAD_BITS(15+1+2*HISPI_NUMLANES) // +3) // +STATUS_ALIVE_WIDTH) // STATUS_PAYLOAD_BITS)
    ) status_generate_sens_io_i (
    ) status_generate_sens_io_i (
        .rst        (1'b0),                    // rst), // input
        .rst        (1'b0),                    // rst), // input
@@ -386,12 +418,12 @@ module sens_10398 #(
        .srst       (mrst),                    // input
        .srst       (mrst),                    // input
        .we         (set_status_r),            // input
        .we         (set_status_r),            // input
        .wd         (data_r[7:0]),             // input[7:0] 
        .wd         (data_r[7:0]),             // input[7:0] 
//        .status     ({status_alive,status}),   // input[25:0] 
        .status     (status),                  // input[22:0] 
        .status     (status),                  // input[22:0] 
        .ad         (status_ad),               // output[7:0] 
        .ad         (status_ad),               // output[7:0] 
        .rq         (status_rq),               // output
        .rq         (status_rq),               // output
        .start      (status_start)             // input
        .start      (status_start)             // input
    );
    );
`endif


    sens_hispi12l4 #(
    sens_hispi12l4 #(
        .IODELAY_GRP            (IODELAY_GRP),
        .IODELAY_GRP            (IODELAY_GRP),
@@ -429,6 +461,9 @@ module sens_10398 #(
        .HISPI_IBUF_LOW_PWR     (HISPI_IBUF_LOW_PWR),
        .HISPI_IBUF_LOW_PWR     (HISPI_IBUF_LOW_PWR),
        .HISPI_IFD_DELAY_VALUE  (HISPI_IFD_DELAY_VALUE),
        .HISPI_IFD_DELAY_VALUE  (HISPI_IFD_DELAY_VALUE),
        .HISPI_IOSTANDARD       (HISPI_IOSTANDARD)
        .HISPI_IOSTANDARD       (HISPI_IOSTANDARD)
    `ifdef MON_HISPI
        ,.TIM_BITS       (SENSOR_TIMING_BITS)
    `endif
        
        
    ) sens_hispi12l4_i (
    ) sens_hispi12l4_i (
        .pclk                   (pclk),                   // input
        .pclk                   (pclk),                   // input
@@ -459,36 +494,16 @@ module sens_10398 #(
        .monitor_pclk           (), // monitor_pclk),           // output reg[3:0] // for monitoring: each bit contains single cycle @pclk line starts
        .monitor_pclk           (), // monitor_pclk),           // output reg[3:0] // for monitoring: each bit contains single cycle @pclk line starts
        .monitor_diff           (), // monitor_diff),           // when SOL active on the last lane @ipclk, latches all other lanes SOL,
        .monitor_diff           (), // monitor_diff),           // when SOL active on the last lane @ipclk, latches all other lanes SOL,
        .mon_barrel             (mon_barrel)              // output[7:0] // @ipclk per-lane monitor barrel shifter
        .mon_barrel             (mon_barrel)              // output[7:0] // @ipclk per-lane monitor barrel shifter
        
`ifdef MON_HISPI
    );
        ,.tim_start             (tim_start[3]), // input
/*    
        .tim_lane               (tim_lane), // input[1:0] 
    dly_16 #(
        .tim_from               (tim_from), // input[1:0] 
        .WIDTH(HISPI_NUMLANES)
        .tim_to                 (tim_to), // input[1:0] 
    ) dly_16_monitor_i (
        .tim_busy               (tim_busy), // output
        .clk  (pclk),                        // input
        .tim_cntr               (tim_cntr[SENSOR_TIMING_BITS-1:0]) // output[23:0] reg 
        .rst  (1'b0),                        // input

        .dly  (4'h0),                        // input[3:0] 
`endif        
        .din  (monitor_pclk),                // input[3:0] 
        .dout (monitor_mclk)                 // output[3:0] 
    );
    );
*/
/*
    output reg [HISPI_NUMLANES-1:0] monitor_pclk    // for monitoring: each bit contains single cycle @pclk line starts    

    obufds #(
        .CAPACITANCE("DONT_CARE"),
        .IOSTANDARD(PXD_IOSTANDARD), // not diff, just opposite phase signals
        .SLEW("SLOW")
    ) obufds_i (
        .o   (sens_ext_clk_p),                   // output
        .ob  (sens_ext_clk_n),                  // output
        .i   (pxd_clk_cntr[PXD_CLK_DIV_BITS-1]) // input
    );
*/  
//    reg [1:0] ext_clk_r;
//    always @(posedge pclk) begin
//        ext_clk_r <= {pxd_clk_cntr[PXD_CLK_DIV_BITS-1], !pxd_clk_cntr[PXD_CLK_DIV_BITS-1]};
//    end


  
  
    obuf #(
    obuf #(
+68 −1
Original line number Original line Diff line number Diff line
@@ -37,7 +37,7 @@
 * with at least one of the Free Software programs.
 * with at least one of the Free Software programs.
 */
 */
`timescale 1ns/1ps
`timescale 1ns/1ps

//`define MON_HISPI // moved to system_defines
module  sens_hispi12l4#(
module  sens_hispi12l4#(
    parameter IODELAY_GRP =               "IODELAY_SENSOR",
    parameter IODELAY_GRP =               "IODELAY_SENSOR",
    parameter integer IDELAY_VALUE =       0,
    parameter integer IDELAY_VALUE =       0,
@@ -79,6 +79,9 @@ module sens_hispi12l4#(
    parameter HISPI_IBUF_LOW_PWR =        "TRUE",
    parameter HISPI_IBUF_LOW_PWR =        "TRUE",
    parameter HISPI_IFD_DELAY_VALUE =     "AUTO",
    parameter HISPI_IFD_DELAY_VALUE =     "AUTO",
    parameter HISPI_IOSTANDARD =          "DIFF_SSTL18_I" //"DIFF_SSTL18_II" for high current (13.4mA vs 8mA),
    parameter HISPI_IOSTANDARD =          "DIFF_SSTL18_I" //"DIFF_SSTL18_II" for high current (13.4mA vs 8mA),
    `ifdef MON_HISPI
        , parameter TIM_BITS =              24 // number of bits in HISPI timing counter
    `endif
)(
)(
    input             pclk,   // global clock input, pixel rate (220MHz for MT9F002)
    input             pclk,   // global clock input, pixel rate (220MHz for MT9F002)
    input             prst,   // reset @pclk (add sensor reset here)
    input             prst,   // reset @pclk (add sensor reset here)
@@ -117,7 +120,71 @@ module sens_hispi12l4#(
    output reg [HISPI_NUMLANES-2:0] monitor_diff,       // for monitoring: when SOL active on the last lane @ipclk, latches all other lanes SOL,
    output reg [HISPI_NUMLANES-2:0] monitor_diff,       // for monitoring: when SOL active on the last lane @ipclk, latches all other lanes SOL,
    output   [HISPI_NUMLANES*2-1:0] mon_barrel          // @ipclk per-lane monitor barrel shifter
    output   [HISPI_NUMLANES*2-1:0] mon_barrel          // @ipclk per-lane monitor barrel shifter
    
    
`ifdef MON_HISPI
    ,input                          tim_start,
    input                     [1:0] tim_lane,
    input                     [1:0] tim_from, // 0 - sof, 1 - eof, 2 - sol, 3 eol
    input                     [1:0] tim_to,   // 0 - sof, 1 - eof, 2 - sol, 3 eol
    output                          tim_busy,
    output reg       [TIM_BITS-1:0] tim_cntr                                       
`endif    
);

`ifdef MON_HISPI
    reg                      [1:0] tim_busy_r;
    reg             [TIM_BITS-1:0] tim_icntr;
    wire                           tim_istart;
    reg                      [1:0] tim_ilane;
    reg                      [1:0] tim_ifrom; // 0 - sof, 1 - eof, 2 - sol, 3 eol
    reg                      [1:0] tim_ito;   // 0 - sof, 1 - eof, 2 - sol, 3 eol
    reg                      [1:0] tim_ibusy;
    reg                      [3:0] tim_sefl;
    reg                            tim_f;
    reg                            tim_t;
    
    assign tim_busy = |tim_busy_r; 
    pulse_cross_clock #(
        .EXTRA_DLY(0)
    ) pulse_cross_clock_tim_start_i (
        .rst       (mrst),                      // input
        .src_clk   (mclk),                      // input
        .dst_clk   (ipclk),                     // input
        .in_pulse  (tim_start),                 // input
        .out_pulse (tim_istart),                // output
        .busy() // output
    );
    );
    always @(posedge ipclk) begin
        tim_ifrom <= tim_from;
        tim_ilane <= tim_lane;
        tim_ito <=   tim_to;
        tim_sefl <= tim_ilane[1]?
                         (tim_ilane[0]?{hispi_eol[3],hispi_sol[3],hispi_eof[3],hispi_sof[3]}:
                                       {hispi_eol[2],hispi_sol[2],hispi_eof[2],hispi_sof[2]}):
                         (tim_ilane[0]?{hispi_eol[1],hispi_sol[1],hispi_eof[1],hispi_sof[1]}:
                                       {hispi_eol[0],hispi_sol[0],hispi_eof[0],hispi_sof[0]});
        tim_f <= tim_ifrom[1]?
                         (tim_ifrom[0]?tim_sefl[3]:tim_sefl[2]):
                         (tim_ifrom[0]?tim_sefl[1]:tim_sefl[0]);
        
        tim_t <= tim_ito[1]?
                         (tim_ito[0]?tim_sefl[3]:tim_sefl[2]):
                         (tim_ito[0]?tim_sefl[1]:tim_sefl[0]);
        if      (irst)                   tim_ibusy <= 0;
        else if (tim_istart)             tim_ibusy <= 1;
        else if (tim_ibusy[0] && tim_f)  tim_ibusy <= 2;
        else if (tim_ibusy[1] && tim_t)  tim_ibusy <= 0;
        
        if      (tim_ibusy[0] || tim_f)  tim_icntr <= 0; // reset if repeated start (e.g. to measure last sol to eof)
        else if (tim_ibusy[1])           tim_icntr <= tim_icntr + 1;
    end
    always @ (posedge mclk) begin
        tim_busy_r <= {tim_busy_r[0], |tim_ibusy};
        if (!tim_busy_r[0]) tim_cntr <= tim_icntr;
    end
      
`endif


    wire                          ipclk;  // re-generated half HiSPi clock (165 MHz) 
    wire                          ipclk;  // re-generated half HiSPi clock (165 MHz) 
    wire                          ipclk2x;// re-generated HiSPi clock (330 MHz)
    wire                          ipclk2x;// re-generated HiSPi clock (330 MHz)
    wire [HISPI_NUMLANES * 4-1:0] sns_d;
    wire [HISPI_NUMLANES * 4-1:0] sns_d;
Loading