Commit 9ce986ab authored by Andrey Filippov's avatar Andrey Filippov
Browse files

adding code for top of the hispi decoder

parent 1b4f3f2c
Loading
Loading
Loading
Loading
+144 −1
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ module sens_hispi12l4#(
    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

    parameter HISPI_MSB_FIRST =            0,
    parameter HISPI_NUMLANES =             4,
    parameter HISPI_CAPACITANCE =         "DONT_CARE",
    parameter HISPI_DIFF_TERM =           "TRUE",
@@ -76,6 +77,7 @@ module sens_hispi12l4#(
    input                           ld_idelay,       // mclk synchronous set idealy value
    input                           set_clk_phase,   // mclk synchronous set idealy value
    input                           rst_mmcm,
//    input                           wait_all_lanes,  // when 0 allow some lanes missing sync (for easier phase adjustment)
    // MMCP output status
    output       ps_rdy,          // output
    output [7:0] ps_out,          // output[7:0] reg 
@@ -154,7 +156,148 @@ module sens_hispi12l4#(
        .dout         (sns_d) // output[15:0] 
    );
    
    localparam WAIT_ALL_LANES = 8; // number of output pixel cycles to wait after the earliest lane
    localparam FIFO_DEPTH = 4;

    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
    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;

    assign hact_out = hact_r;
    
    always @(posedge ipclk) begin
       if (irst || (|hispi_eof[i])) vact_ipclk <= 0; // extend output if hact active
       else if (|hispi_sof)         vact_ipclk <= 1;
    
    end
    
    always @(posedge pclk) begin
        vact_pclk_strt <= {vact_pclk_strt[0],vact_ipclk};

        rd_run_d <= rd_run;
       
        sof_pclk <= vact_pclk_strt[0] && ! vact_pclk_strt[1];
       
        if      (prst || sof_pclk) rd_line <= 0;
        else if (sol_pclk)         rd_line <= 1;
        else                       rd_line <= rd_line & (&(~good_lanes | rd_run)); // Off when first of the good lanes goes off      
       
        rd_line_r <= rd_line;
        
        if (sol_pclk && !rd_line) good_lanes <= ~rd_run;             // should be off before start
        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
        pxd_out <= ({12 {fifo_re_r[0]}} & fifo_out[0 * 12 +:12]) |
                   ({12 {fifo_re_r[1]}} & fifo_out[1 * 12 +:12]) |
                   ({12 {fifo_re_r[2]}} & fifo_out[2 * 12 +:12]) |
                   ({12 {fifo_re_r[3]}} & fifo_out[3 * 12 +:12]);
       
       if      (prst)                                                 fifo_re <= 0;
       else if (sol_pclk || (rd_line && fifo_re[HISPI_NUMLANES - 1])) fifo_re <= 1;
       else                                                           fifo_re <= fifo_re << 1;
       
       if (prst || hact_off) hact_r <= 0;
       else if (hact_on)     hact_r <= 1;
       
       vact_out <= vact_pclk_strt [0] || hact_r;
    end

    dly_16 #(
        .WIDTH(1)
    ) dly_16_start_line_i (
        .clk  (pclk),                  // input
        .rst  (1'b0),                  // input
        .dly  (WAIT_ALL_LANES),        // input[3:0] 
        .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
        .dly  (2),                           // input[3:0] 
        .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
        .dly  (2),                           // input[3:0] 
        .din  (fifo_re[HISPI_NUMLANES - 1]), // input[0:0] 
        .dout (hact_off)                     // output[0:0] 
    );

   
    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
                .din      (sns_d[4*i +: 4]),           // input[3:0] 
                .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 #(
                .COUNT_START  (7),
                .DATA_WIDTH  (12),
                .DATA_DEPTH  (FIFO_DEPTH)
            ) sens_hispi_fifo_i (
                .ipclk    (ipclk),                     // input
                .irst     (irst),                      // input
                .we       (hispi_dv[i]),               // input
                .sol      (hispi_sol[i]),              // input
                .eol      (hispi_eol[i]),              // input
                .din      (hispi_aligned[12*i +: 12]), // input[11:0] 
                .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        

endmodule
+36 −27
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ module sens_hispi_lane#(
    input             ipclk,   // half HiSPi recovered clock (165 MHz for 660 bps of MT9F002)
    input             irst,    // reset sync to ipclk 
    input       [3:0] din,     // @posedge ipclk, din[3] came first
    output reg [3:0] dout,  // data output, aligned (decide about bit order)
    output reg [11:0] dout,    // 12-bit data output
    output reg        dv,      // data valid - continuous marks line
    output reg        embed,   // valid @sol and up through all dv
    output reg        sof,     // always before first sol - not instead of
@@ -40,7 +40,10 @@ module sens_hispi_lane#(
//    localparam  [3:0] SYNC_EOL = 6;
    
    localparam  [3:0] SYNC_EMBED  = HISPI_MSB_FIRST ? 4'h1 : 4'h8; // other nibble (bit 4)
    localparam        SYNC_NIBBLE = HISPI_MSB_FIRST ? 2 : 0; // decode which nibble of the last sync word

    localparam        LSB_INDEX =   HISPI_MSB_FIRST ? 2 : 0; // nibble number in 12-bit word
    localparam        MSB_INDEX =   HISPI_MSB_FIRST ? 0 : 2; // nibble number in 12-bit word
    
    
    reg   [3:0] d_r; // rehistered input data
    wire   [2:0] num_trail_0_w; // number of trailing 0-s in the last nibble
@@ -64,7 +67,7 @@ module sens_hispi_lane#(
//    reg          got_eol;
    reg          got_embed;
    
    reg          pre_dv;
    reg    [2:0] pre_dv;
    wire   [3:0] dout_w;
    wire   [4:0] num_running_zeros_w = num_running_zeros + {1'b0, num_lead_0_w};
    wire         start_line =  sync_decode[3] && (got_sol || got_sof);
@@ -120,34 +123,41 @@ module sens_hispi_lane#(
        else               sync_decode <= sync_decode << 1;
        
        if      (got_sync)                                       got_sof <= 0;
        else if (sync_decode[SYNC_NIBBLE] && (barrel == SYNC_SOF)) got_sof <= 1;
        else if (sync_decode[LSB_INDEX] && (barrel == SYNC_SOF)) got_sof <= 1;
        
        if      (got_sync)                                       got_eof <= 0;
        else if (sync_decode[SYNC_NIBBLE] && (barrel == SYNC_EOF)) got_eof <= 1;
        else if (sync_decode[LSB_INDEX] && (barrel == SYNC_EOF)) got_eof <= 1;
        
        if      (got_sync)                                       got_sol <= 0;
        else if (sync_decode[SYNC_NIBBLE] && (barrel == SYNC_SOL)) got_sol <= 1;
        else if (sync_decode[LSB_INDEX] && (barrel == SYNC_SOL)) got_sol <= 1;
        
//        if      (got_sync)                                       got_eol <= 0;
//        else if (sync_decode[SYNC_NIBBLE] && (barrel == SYNC_EOL)) got_eol <= 1;
//        else if (sync_decode[LSB_INDEX] && (barrel == SYNC_EOL)) got_eol <= 1;

        if      (got_sync)                                       got_embed <= 0;
        else if (sync_decode[1] && (barrel == SYNC_EMBED))       got_embed <= 1;
        
        if (irst) dout <= 0; 
        else      dout <= dout_w;
        if      (irst)              dout[ 3:0] <= 0; 
        else if (pre_dv[LSB_INDEX]) dout[ 3:0] <= dout_w;

        if      (irst)              dout[ 7:4] <= 0; 
        else if (pre_dv[1])         dout[ 7:4] <= dout_w;
        
        if      (irst)              dout[11:8] <= 0; 
        else if (pre_dv[MSB_INDEX]) dout[11:8] <= dout_w;

        if  (irst || got_sync) pre_dv <= 0;
        else if (start_line_d) pre_dv <= 1;
        else                   pre_dv <= {pre_dv[1:0],pre_dv[2]};
        
        if (irst) dv <= 0;
        else      dv <= pre_dv;
        else      dv <= pre_dv[2];

        if (irst) sol <= 0;
        else      sol <= start_line_d;

        if (irst) eol <= 0;
        else      eol <= got_sync && pre_dv;
        else      eol <= got_sync && (|pre_dv);
        
        if (irst) sof <= 0;
        else      sof <= sync_decode[3] && got_sof;
@@ -180,4 +190,3 @@ module sens_hispi_lane#(


endmodule
+6 −5
Original line number Diff line number Diff line
@@ -82,12 +82,13 @@ module fifo_cross_clocks
    end
    
    always @ (posedge  rclk or posedge rst) begin
        if (rst)       raddr <= 0;
        else if (rrst) raddr <= 0;
// making rrst set FIFO to empty regardless of current  waddr (write should be stopped)        
        if (rst)       raddr <= waddr; // 0;
        else if (rrst) raddr <= waddr; // 0;
        else if (re)   raddr <= raddr_plus1;

        if (rst)       raddr_gray_top3 <= 0;
        else if (rrst) raddr_gray_top3 <= 0;
        if (rst)       raddr_gray_top3 <= waddr[DATA_DEPTH-1 -: 3] ^ {1'b0,waddr[DATA_DEPTH-1 -: 2]}; // 0;
        else if (rrst) raddr_gray_top3 <= waddr[DATA_DEPTH-1 -: 3] ^ {1'b0,waddr[DATA_DEPTH-1 -: 2]}; // 0;
        else if (re)   raddr_gray_top3 <= raddr_plus1_gray_top3;
    end