Commit 08d64701 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

working on sensor channel: histograms

parent 05baee9d
Loading
Loading
Loading
Loading
+18 −7
Original line number Diff line number Diff line
@@ -37,8 +37,8 @@ module sens_histogram #(
    input         mclk,
    input         hist_en,  // @mclk - gracefully enable/disable histogram
    input         hist_rst, // @mclk - immediately disable if true
    output        hist_out_rq,
    input         hist_out_grant,
    output        hist_rq,
    input         hist_grant,
    output [31:0] hist_do,
    output        hist_dv,
    input   [7:0] cmd_ad,      // byte-serial command address/data (up to 6 bytes: AL-AH-D0-D1-D2-D3 
@@ -108,7 +108,7 @@ module sens_histogram #(
    reg           hist_out_d;
    reg     [2:0] hist_re;
    reg     [9:0] hist_raddr;
    reg           hist_rq;
    reg           hist_rq_r;
    wire          hist_xfer_done_mclk; //@ mclk
    wire          hist_xfer_done; // @pclk
    reg           hist_xfer_busy; // @pclk, during histogram readout , immediately after woi (no gaps)
@@ -121,7 +121,7 @@ module sens_histogram #(
    assign hcntr_zero_w =      !(|hcntr);
    assign inc_w =             to_inc+1;

    assign hist_out_rq = hist_rq;
    assign hist_rq = hist_rq_r;
    assign hist_dv = hist_re[2];
    assign hist_xfer_done_mclk = hist_out_d && !hist_out_d;
    
@@ -228,11 +228,11 @@ module sens_histogram #(
        if      (!en_mclk)       hist_raddr <= 0;
        else if (hist_re)        hist_raddr <= hist_raddr + 1;
        
        if      (!en_mclk)             hist_rq <= 0;
        else if (hist_out && !hist_re) hist_rq <= 1;
        if      (!en_mclk)             hist_rq_r <= 0;
        else if (hist_out && !hist_re) hist_rq_r <= 1;
        
        if      (!hist_out)        hist_re[0] <= 0;
        else if (hist_out_grant)   hist_re[0] <= 1;
        else if (hist_grant)   hist_re[0] <= 1;
        else if (&hist_raddr[7:0]) hist_re[0] <= 0;
        
        hist_re[2:1] <= hist_re[1:0];
@@ -519,3 +519,14 @@ module sens_hist_ram_nobuff(
    );
    
endmodule

module  sens_histogram_dummy(
    output        hist_rq,
    output [31:0] hist_do,
    output        hist_dv

);
    assign         hist_rq = 0;
    assign         hist_do = 0;
    assign         hist_dv = 0;
endmodule
 No newline at end of file
+130 −0
Original line number Diff line number Diff line
/*******************************************************************************
 * Module: sens_histogram_mux
 * Date:2015-06-01  
 * Author: andrey     
 * Description: Readout multiplexer for 4 histogram modules
 *
 * Copyright (c) 2015 <set up in Preferences-Verilog/VHDL Editor-Templates> .
 * sens_histogram_mux.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_histogram_mux.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/> .
 *******************************************************************************/
`timescale 1ns/1ps

module  sens_histogram_mux(
    input         mclk,
    input         en,

    input         rq0,
    output        grant0,
    input         dav0,
    input  [31:0] din0,

    input         rq1,
    output        grant1,
    input         dav1,
    input  [31:0] din1,

    input         rq2,
    output        grant2,
    input         dav2,
    input  [31:0] din2,

    input         rq3,
    output        grant3,
    input         dav3,
    input  [31:0] din3,

    output        rq,
    input         grant,
    output  [1:0] chn,
    output        dv,
    output [31:0] dout
);

    reg   [2:0] burst0;
    reg   [2:0] burst1;
    reg   [2:0] burst2;
    reg   [2:0] burst3;
    
    wire  [3:0] pri_rq;
    reg   [2:0] enc_rq;
    wire        busy_w;
    reg         busy_r;
    reg   [1:0] mux_sel;
    wire        start_w;
    reg         started;
    wire        dav_in;
    reg         dav_out;
    wire [31:0] din;
    reg  [31:0] dout_r;
    wire        burst_done_w;
    wire  [3:0] chn_sel;
    wire  [3:0] chn_start;
    wire  [3:0] burst_next;
    reg   [3:0] chn_grant;
    wire        rq_in;
    reg         rq_out;
    
    assign pri_rq = {rq3 & ~rq2 & ~rq1 & ~rq0, rq2 & ~rq1 & ~ rq0, rq1 & ~ rq0, rq0};
    assign busy_w = |burst0 || (|burst1) || (|burst2) || (|burst3);
    assign start_w = enc_rq[2] && !busy_r && !started;
    assign dav_in = mux_sel[1] ? (mux_sel[0] ? dav3 : dav2) : (mux_sel[0] ? dav1 : dav0); 
    assign din =    mux_sel[1] ? (mux_sel[0] ? din3 : din2) : (mux_sel[0] ? din1 : din0);
    assign rq_in =  mux_sel[1] ? (mux_sel[0] ? rq3 :  rq2)  : (mux_sel[0] ? rq1 :  rq0); 
    assign burst_done_w = dav_out && !dav_in;
    assign chn_start =  {4{start_w}} & {enc_rq[1] & enc_rq[0], enc_rq[1] & ~enc_rq[0], ~enc_rq[1] & enc_rq[0], ~enc_rq[1] & ~enc_rq[0]};
    assign chn_sel =    {mux_sel[1] & mux_sel[0], mux_sel[1] & ~mux_sel[0], ~mux_sel[1] & mux_sel[0], ~mux_sel[1] & ~mux_sel[0]};
    assign burst_next = {4{burst_done_w}} & chn_sel;
    
    assign dout =   dout_r;
    assign grant0 = chn_grant[0];
    assign grant1 = chn_grant[1];
    assign grant2 = chn_grant[2];
    assign grant3 = chn_grant[3];
    assign rq =     rq_out;
    assign dv =     dav_out;
    assign chn =    mux_sel;
    
    always @(posedge mclk) begin
        enc_rq <= {|pri_rq, pri_rq[3] | pri_rq[2], pri_rq[3] | pri_rq[1]};
        busy_r <= busy_w;
        if  (!en || busy_r) started <= 0;
        else if (enc_rq[2]) started <= 1;
        if (start_w) mux_sel <= enc_rq[1:0];
        dav_out <= dav_in;
        dout_r <= din;
        
        if      (!en)           burst0 <= 0;
        else if (chn_start[0])  burst0 <= 4;
        else if (burst_next[0]) burst0 <= burst0 + 1;
        
        if      (!en)           burst1 <= 0;
        else if (chn_start[1])  burst1 <= 4;
        else if (burst_next[1]) burst1 <= burst1 + 1;
        
        if      (!en)           burst2 <= 0;
        else if (chn_start[2])  burst2 <= 4;
        else if (burst_next[2]) burst2 <= burst2 + 1;
        
        if      (!en)           burst3 <= 0;
        else if (chn_start[3])  burst3 <= 4;
        else if (burst_next[3]) burst3 <= burst3 + 1;
        
        if (!en) chn_grant <= 0;
        else     chn_grant <= {4{grant}} & chn_sel;
        
        rq_out <= en && rq_in;
    end

endmodule
+205 −17
Original line number Diff line number Diff line
@@ -75,6 +75,16 @@ module sensor_channel#(
    parameter SENS_GAMMA_MODE_REPET =  4,
    parameter SENS_GAMMA_MODE_TRIG =   5,
    
    parameter HISTOGRAM_RAM_MODE =     "NOBUF", // valid: "NOBUF" (32-bits, no buffering), "BUF18", "BUF32"
    parameter HISTOGRAM_ADDR_MASK =    'h3fe,
    parameter HISTOGRAM_LEFT_TOP =     'h0,
    parameter HISTOGRAM_WIDTH_HEIGHT = 'h1, // 1.. 2^16, 0 - use HACT
    parameter HISTOGRAM_ADDR0 =        'h340, // TODO: optimize!
    parameter HISTOGRAM_ADDR1 =        'h342, // TODO: optimize!
    parameter HISTOGRAM_ADDR2 =        'h344, // TODO: optimize!
    parameter HISTOGRAM_ADDR3 =        -1,    // < 0 - not implemented
    
    
    parameter IODELAY_GRP ="IODELAY_SENSOR", // may need different for different channels?
    parameter integer IDELAY_VALUE = 0,
    parameter integer PXD_DRIVE = 12,
@@ -104,6 +114,7 @@ module sensor_channel#(
) (
    input         rst,
    input         pclk,   // global clock input, pixel rate (96MHz for MT9P006)
    input         pclk2x, // global clock input, double pixel rate (192MHz for MT9P006)
    // I/O pads, pin names match circuit diagram
    inout   [7:0] sns_dp,
    inout   [7:0] sns_dn,
@@ -119,9 +130,16 @@ module sensor_channel#(
    input         cmd_stb_in,     // 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)
    input         status_start, // Acknowledge of the first status packet byte (address)

    output        hist_request,
    input         hist_grant,
    output  [1:0] hist_chn,      // output[1:0]
    output        hist_dvalid,   // output
    output [31:0] hist_data     // output[31:0] 
// (much) more will be added later
    
    
);
    reg    [7:0] cmd_ad;      // byte-serial command address/data (up to 6 bytes: AL-AH-D0-D1-D2-D3 
    reg          cmd_stb;     // strobe (with first byte) for the command a/d
@@ -151,6 +169,12 @@ module sensor_channel#(
    wire         gamma_sof_in;
    wire         gamma_eof_in;
    
    wire   [7:0] gamma_pxd_out; 
    wire         gamma_hact_out;
    wire         gamma_sof_out;
    wire         gamma_eof_out;
    
    
    // TODO: insert vignetting and/or flat field, pixel defects before gamma_*_in
    assign gamma_pxd_in = {pxd[11:0],4'b0};
    assign gamma_hact_in = hact;
@@ -316,6 +340,170 @@ module sensor_channel#(
        .cmd_stb     (cmd_stb) // input
    );

    // TODO: Use generate to generate 1-4 histogram modules
    wire  [3:0] hist_en;
    wire        hist_nrst;
    wire  [3:0] hist_rq;
    wire  [3:0] hist_gr;
    wire  [3:0] hist_dv;
    wire [31:0] hist_do0;
    wire [31:0] hist_do1;
    wire [31:0] hist_do2;
    wire [31:0] hist_do3;
    generate
        if (HISTOGRAM_ADDR0 >=0)
            sens_histogram #(
                .HISTOGRAM_RAM_MODE     (HISTOGRAM_RAM_MODE),
                .HISTOGRAM_ADDR         (HISTOGRAM_ADDR0),
                .HISTOGRAM_ADDR_MASK    (HISTOGRAM_ADDR_MASK),
                .HISTOGRAM_LEFT_TOP     (HISTOGRAM_LEFT_TOP),
                .HISTOGRAM_WIDTH_HEIGHT (HISTOGRAM_WIDTH_HEIGHT)
            ) sens_histogram_i (
                .rst        (rst), // input
                .pclk       (pclk), // input
                .pclk2x     (pclk2x), // input
                .sof        (gamma_sof_out), // input
                .hact       (gamma_hact_out), // input
                .hist_di    (gamma_pxd_out), // input[7:0] 
                .mclk       (mclk), // input
                .hist_en    (hist_en[0]), // input
                .hist_rst   (!hist_nrst), // input
                .hist_rq    (hist_rq[0]), // output
                .hist_grant (hist_gr[0]), // input
                .hist_do    (hist_do0), // output[31:0] 
                .hist_dv    (hist_dv[0]), // output
                .cmd_ad     (cmd_ad), // input[7:0] 
                .cmd_stb    (cmd_stb) // input
            );
        else
            sens_histogram_dummy sens_histogram_dummy_i (
                .hist_rq(hist_rq[0]), // output
                .hist_do(hist_do0), // output[31:0] 
                .hist_dv(hist_dv[0]) // output
            );
    endgenerate
    generate
        if (HISTOGRAM_ADDR1 >=0)
            sens_histogram #(
                .HISTOGRAM_RAM_MODE     (HISTOGRAM_RAM_MODE),
                .HISTOGRAM_ADDR         (HISTOGRAM_ADDR1),
                .HISTOGRAM_ADDR_MASK    (HISTOGRAM_ADDR_MASK),
                .HISTOGRAM_LEFT_TOP     (HISTOGRAM_LEFT_TOP),
                .HISTOGRAM_WIDTH_HEIGHT (HISTOGRAM_WIDTH_HEIGHT)
            ) sens_histogram_i (
                .rst        (rst), // input
                .pclk       (pclk), // input
                .pclk2x     (pclk2x), // input
                .sof        (gamma_sof_out), // input
                .hact       (gamma_hact_out), // input
                .hist_di    (gamma_pxd_out), // input[7:0] 
                .mclk       (mclk), // input
                .hist_en    (hist_en[1]), // input
                .hist_rst   (!hist_nrst), // input
                .hist_rq    (hist_rq[1]), // output
                .hist_grant (hist_gr[1]), // input
                .hist_do    (hist_do1), // output[31:0] 
                .hist_dv    (hist_dv[1]), // output
                .cmd_ad     (cmd_ad), // input[7:0] 
                .cmd_stb    (cmd_stb) // input
            );
        else
            sens_histogram_dummy sens_histogram_dummy_i (
                .hist_rq(hist_rq[1]), // output
                .hist_do(hist_do1), // output[31:0] 
                .hist_dv(hist_dv[1]) // output
            );
    endgenerate
    generate
        if (HISTOGRAM_ADDR2 >=0)
            sens_histogram #(
                .HISTOGRAM_RAM_MODE     (HISTOGRAM_RAM_MODE),
                .HISTOGRAM_ADDR         (HISTOGRAM_ADDR2),
                .HISTOGRAM_ADDR_MASK    (HISTOGRAM_ADDR_MASK),
                .HISTOGRAM_LEFT_TOP     (HISTOGRAM_LEFT_TOP),
                .HISTOGRAM_WIDTH_HEIGHT (HISTOGRAM_WIDTH_HEIGHT)
            ) sens_histogram_i (
                .rst        (rst), // input
                .pclk       (pclk), // input
                .pclk2x     (pclk2x), // input
                .sof        (gamma_sof_out), // input
                .hact       (gamma_hact_out), // input
                .hist_di    (gamma_pxd_out), // input[7:0] 
                .mclk       (mclk), // input
                .hist_en    (hist_en[2]), // input
                .hist_rst   (!hist_nrst), // input
                .hist_rq    (hist_rq[2]), // output
                .hist_grant (hist_gr[2]), // input
                .hist_do    (hist_do2), // output[31:0] 
                .hist_dv    (hist_dv[2]), // output
                .cmd_ad     (cmd_ad), // input[7:0] 
                .cmd_stb    (cmd_stb) // input
            );
        else
            sens_histogram_dummy sens_histogram_dummy_i (
                .hist_rq(hist_rq[2]), // output
                .hist_do(hist_do2), // output[31:0] 
                .hist_dv(hist_dv[2]) // output
            );
    endgenerate
    generate
        if (HISTOGRAM_ADDR3 >=0)
            sens_histogram #(
                .HISTOGRAM_RAM_MODE     (HISTOGRAM_RAM_MODE),
                .HISTOGRAM_ADDR         (HISTOGRAM_ADDR3),
                .HISTOGRAM_ADDR_MASK    (HISTOGRAM_ADDR_MASK),
                .HISTOGRAM_LEFT_TOP     (HISTOGRAM_LEFT_TOP),
                .HISTOGRAM_WIDTH_HEIGHT (HISTOGRAM_WIDTH_HEIGHT)
            ) sens_histogram_i (
                .rst        (rst), // input
                .pclk       (pclk), // input
                .pclk2x     (pclk2x), // input
                .sof        (gamma_sof_out), // input
                .hact       (gamma_hact_out), // input
                .hist_di    (gamma_pxd_out), // input[7:0] 
                .mclk       (mclk), // input
                .hist_en    (hist_en[3]), // input
                .hist_rst   (!hist_nrst), // input
                .hist_rq    (hist_rq[3]), // output
                .hist_grant (hist_gr[3]), // input
                .hist_do    (hist_do3), // output[31:0] 
                .hist_dv    (hist_dv[3]), // output
                .cmd_ad     (cmd_ad), // input[7:0] 
                .cmd_stb    (cmd_stb) // input
            );
        else
            sens_histogram_dummy sens_histogram_dummy_i (
                .hist_rq(hist_rq[3]), // output
                .hist_do(hist_do3), // output[31:0] 
                .hist_dv(hist_dv[3]) // output
            );
    endgenerate
    
    sens_histogram_mux sens_histogram_mux_i (
        .mclk   (mclk),          // input
        .en     (!hist_nrst),    // input
        .rq0    (hist_rq[0]),    // input
        .grant0 (hist_gr[0]),    // output
        .dav0   (hist_dv[0]),    // input
        .din0   (hist_do0),      // input[31:0] 
        .rq1    (hist_rq[1]),    // input
        .grant1 (hist_gr[1]),    // output
        .dav1   (hist_dv[1]),    // input
        .din1   (hist_do1),      // input[31:0] 
        .rq2    (hist_rq[2]),    // input
        .grant2 (hist_gr[2]),    // output
        .dav2   (hist_dv[2]),    // input
        .din2   (hist_do2),      // input[31:0] 
        .rq3    (hist_rq[3]),    // input
        .grant3 (hist_gr[3]),    // output
        .dav3   (hist_dv[3]),    // input
        .din3   (hist_do3),      // input[31:0] 
        .rq     (hist_request),  // output
        .grant  (hist_grant),    // input
        .chn    (hist_chn),      // output[1:0]
        .dv     (hist_dvalid),   // output
        .dout   (hist_data)      // output[31:0] 
    );


endmodule