Commit cfdcac60 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

modifying histograms module to avoid use of the double pixel frequency clock

parent 59774283
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -61,7 +61,7 @@

    parameter HISTOGRAM_LEFT =           0,   // 2;   // left   
    parameter HISTOGRAM_TOP =            8,   // 2,   // top
    parameter HISTOGRAM_WIDTH =          6,   // width
    parameter HISTOGRAM_WIDTH =         22,  // 6,  // width
    parameter HISTOGRAM_HEIGHT =         6,   // height
    parameter HISTOGRAM_START_PAGE =    20'h12345,
    parameter FRAME_WIDTH_ROUND_BITS =   9,  // multiple of 512 pixels (32 16-byte bursts) (11 - ful SDRAM page)
+6 −56
Original line number Diff line number Diff line
@@ -35,7 +35,6 @@ module sens_histogram #(
`endif        
    
)(
//    input         rst,
    input         mrst,      // @posedge mclk, sync reset
    input         prst,      // @posedge pclk, sync reset
    input         pclk,   // global clock input, pixel rate (96MHz for MT9P006)
@@ -55,16 +54,12 @@ module sens_histogram #(
    input   [7:0] cmd_ad,      // byte-serial command address/data (up to 6 bytes: AL-AH-D0-D1-D2-D3 
    input         cmd_stb,      // strobe (with first byte) for the command a/d
    input         monochrome    // tie to 0 to reduce hardware
//    ,output debug_mclk
`ifdef DEBUG_RING       
    ,output                       debug_do, // output to the debug ring
     input                        debug_sl, // 0 - idle, (1,0) - shift, (1,1) - load // SuppressThisWarning VEditor - not used
     input                        debug_di  // input from the debug ring
`endif         
);
`ifdef DEBUG_RING
//     assign  debug_do = debug_di;
`endif        

    localparam PXD_2X_LATENCY = 2;
    reg         hist_bank_pclk;
@@ -140,11 +135,10 @@ module sens_histogram #(
    reg           hist_xfer_busy; // @pclk, during histogram readout , immediately after woi (no gaps)
    reg           wait_readout;   // only used in NOBUF mode, in outher modes readout is expected to be always finished in time
    
//    reg           debug_vert_woi_r;
    
`ifdef DEBUG_RING
    reg    [15:0] debug_line_cntr;
    reg    [15:0] debug_lines;
    
`endif    
    
    assign set_left_top_w =     pio_stb && (pio_addr == HISTOGRAM_LEFT_TOP );
    assign set_width_height_w = pio_stb && (pio_addr == HISTOGRAM_WIDTH_HEIGHT );
@@ -179,16 +173,14 @@ module sens_histogram #(
    reg        monochrome_pclk;
    reg        monochrome_2x;
    
//    assign debug_mclk = hist_done_mclk;
//    assign debug_mclk = set_width_height_w;

`ifdef DEBUG_RING
    always @ (posedge pclk) begin
        if      (sof)          debug_line_cntr <= 0;
        else if (line_start_w) debug_line_cntr <= debug_line_cntr + 1;
        
        if      (sof)          debug_lines <= debug_line_cntr;
    end
    
`endif    
    
    always @ (posedge pclk) begin
        if (!hact) pxd_wa <= 0;
@@ -215,7 +207,6 @@ module sens_histogram #(
    end
    
    // process WOI
//    wire  eol = !hact && hact_d[0];
    always @ (posedge pclk) begin
        hact_d <= {hact_d[0],hact};
        if      (!en)           pre_first_line <= 0;
@@ -229,9 +220,6 @@ module sens_histogram #(
        if (!en ||(pre_first_line && !hact))  vert_woi <= 0;
        else if (vcntr_zero_w & line_start_w) vert_woi <= top_margin;
        
//        debug_vert_woi_r <= vcntr_zero_w && vert_woi; // vert_woi;
        
//        hist_done <= vcntr_zero_w && vert_woi && line_start_w; // hist done never asserted, line_start_w - active
        hist_done <= vert_woi && (eof || (vcntr_zero_w && line_start_w)); // hist done never asserted, line_start_w - active
        
        if   (!en || hist_done)               frame_active <= 0;
@@ -253,8 +241,6 @@ module sens_histogram #(
        else if (hcntr_zero_w && left_margin) hcntr <= width_m1;
        else if (left_margin || hor_woi)      hcntr <= hcntr - 1;
        
//        if (hor_woi) hist_d <= hist_di;
        
        if      (!en)                                          hist_bank_pclk <= 0;
        else if (hist_done && (HISTOGRAM_RAM_MODE != "NOBUF")) hist_bank_pclk <= !hist_bank_pclk;
        // hist_xfer_busy to extend en
@@ -279,13 +265,11 @@ module sens_histogram #(
        else if (!hact)                   bayer_pclk[0] <= XOR_HIST_BAYER[0];
        else                              bayer_pclk[0] <= ~bayer_pclk[0]; 

//line_start_w        
    end

    always @(posedge pclk2x) begin
        monochrome_2x <= monochrome;
        hist_en_pclk2x <= hist_en;
//        hist_rst_pclk2x <= hist_rst;
        pxd_ra_start <= left[3:0];
        
        if (!hist_en_pclk2x || hlstart || !(hor_woi_2x || (|woi)))  pclk_sync <= 0;
@@ -306,8 +290,6 @@ module sens_histogram #(
            hist_addr_d2 <= hist_addr_d;
            same_addr1 <= monochrome_2x && woi[0] && woi[1] && (hist_addr_d  == hist_addr); // reduce hardware if hard-wire to gnd
            same_addr2 <=                  woi[0] && woi[2] && (hist_addr_d2 == hist_addr);
//            if (same_addr) to_inc <= inc_r;
//            else           to_inc <= hist_new;
            if      (same_addr1) to_inc <= inc_r; // only used in monochrome mode
            else if (same_addr2) to_inc <= inc_sat;
            else                 to_inc <= hist_new;
@@ -317,7 +299,6 @@ module sens_histogram #(
            else                                     inc_sat <= {14'b0,inc_r[17:0]};
        end
        hist_rwen <= (woi[0] & ~pclk_sync) || (woi[2] & pclk_sync);
//        hist_regen <= {hist_regen[1:0], woi[0] & ~pclk_sync};
        hist_regen <= {hist_regen[0], woi[0] & ~pclk_sync};
        hist_we <= woi[2] & pclk_sync;
        
@@ -326,35 +307,25 @@ module sens_histogram #(
        
        inc_r <= to_inc + 1;
        
//        if      (HISTOGRAM_RAM_MODE != "BUF18")  inc_r <= inc_w;
//        else if (inc_w[18])                      inc_r <= 32'h3fff; // maximal value
//        else                                     inc_r <= {14'b0,inc_w[17:0]};
        
    end
    // after hist_out was off, require inactive grant before sending rq
    reg en_rq_start;
    
    always @ (posedge mclk) begin
        en_mclk <= en;
        monochrome_pclk <= monochrome;
//        monochrome_pclk <= monochrome;
        if      (!en_mclk)       hist_out <= 0;
        else if (hist_done_mclk) hist_out <= 1;
        else if (&hist_raddr)    hist_out <= 0;
        
        hist_out_d <= hist_out;
        // reset address each time new transfer is started
//        if      (!en_mclk || (hist_out && !hist_out_d)) hist_raddr <= 0;
        if      (!hist_out)  hist_raddr <= 0;
        else if (hist_re[0]) hist_raddr <= hist_raddr + 1;
        
//        if      (!en_mclk)             hist_rq_r <= 0;
//        else if (hist_out && !hist_re) hist_rq_r <= 1;

//        hist_rq_r <= en_mclk && hist_out && !(&hist_raddr);
// prevent starting rq if grant is still on (back-to-back)
        if      (!hist_out)   en_rq_start <= 0;
        else if (!hist_grant) en_rq_start <= 1;
//        hist_rq_r <= en_mclk && hist_out && !(&hist_raddr) && ((|hist_raddr[9:0]) || !hist_grant);
        hist_rq_r <= en_mclk && hist_out && !(&hist_raddr) && en_rq_start;
        
        if      (!hist_out || (&hist_raddr[7:0])) hist_re[0] <= 0;
@@ -372,6 +343,7 @@ module sens_histogram #(
        else if ((HISTOGRAM_RAM_MODE == "NOBUF") && hist_done) wait_readout <= 1;
        else if (hist_xfer_done)                               wait_readout <= 0;
    
        monochrome_pclk <= monochrome;
    end

`ifdef DEBUG_RING
@@ -386,27 +358,12 @@ module sens_histogram #(
        .debug_di   (debug_di), // input
        .debug_sl   (debug_sl), // input
        .debug_do   (debug_do), // output
//        .rd_data   ({height_m1[15:0], vcntr[15:0], width_m1[15:0],  hcntr[15:0]}), // input[31:0] 
        .rd_data   ({debug_lines[15:0], debug_line_cntr[15:0], width_m1[15:0],  hcntr[15:0]}), // input[31:0] 
//debug_lines <= debug_line_cntr        
        .wr_data    (), // output[31:0]  - not used
        .stb        () // output  - not used
    );
`endif
    
/*
    pulse_cross_clock pulse_cross_clock_debug_mclk_i (
        .rst         (prst), // input
        .src_clk     (pclk), // input
        .dst_clk     (mclk), // input
//        .in_pulse    (vert_woi && !debug_vert_woi_r), // line_start_w), // input vcntr_zero_w
//        .in_pulse    (vcntr_zero_w && !debug_vert_woi_r), // line_start_w), // input 
        .in_pulse    (vcntr_zero_w && vert_woi && !debug_vert_woi_r), // line_start_w), // input 
        .out_pulse   (debug_mclk),    // output
        .busy() // output
    );
*/
    
    cmd_deser #(
        .ADDR        (HISTOGRAM_ADDR),
        .ADDR_MASK   (HISTOGRAM_ADDR_MASK),
@@ -474,13 +431,6 @@ module sens_histogram #(
        .out_pulse   (hist_xfer_done),    // output
        .busy() // output
    );
/*   
    clk_to_clk2x clk_to_clk2x_i (
        .clk         (pclk), // input
        .clk2x       (pclk2x), // input
        .clk_sync    (pclk_sync) // output
    );
*/    
    //TODO:  make it double cycle in timing

    // select between 18-bit wide histogram data using a single BRAM or 2 BRAMs having full 32 bits    
+716 −0

File added.

Preview size limit exceeded, changes collapsed.

+34 −0
Original line number Diff line number Diff line
@@ -993,6 +993,40 @@ module sensor_channel#(
        .bayer_out   (gamma_bayer)     // output [1:0]
    );

// Debugging - adding a parallel to 0:0 module
        wire        hist_rq_debug;
        wire [31:0] hist_do_debug; 
        wire        hist_dv_debug; 

    sens_histogram_snglclk #(
                .HISTOGRAM_RAM_MODE     ("BUF32"),
//                .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)
`ifdef DEBUG_RING
                ,.DEBUG_CMD_LATENCY     (DEBUG_CMD_LATENCY) 
`endif        
    ) sens_histogram_snglclk_chn0_0_i (
                .mrst       (mrst), // input
                .prst       (prsts), // input
                .pclk       (pclk), // input
                .sof        (gamma_sof_out), // input
                .eof        (gamma_eof_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[0]), // input
                .hist_rq    (hist_rq_debug), // output
                .hist_grant (hist_gr[0]), // input
                .hist_do    (hist_do_debug), // output[31:0] 
                .hist_dv    (hist_dv_debug), // output reg 
                .cmd_ad     (cmd_ad), // input[7:0] 
                .cmd_stb    (cmd_stb) // input
    );

    // TODO: Use generate to generate 1-4 histogram modules
    generate
        if (HISTOGRAM_ADDR0 >=0)
+178 −0
Original line number Diff line number Diff line
/*******************************************************************************
 * Module: ram18t_var_w_var_r
 * Date:2015-05-29  
 * Author: Andrey Filippov     
 * Description:  Dual port memory wrapper, with variable width write and variable
 * width read,  using "TDP" mode of RAMB36E1. Same R/W widths in each port.
 * Does not use parity bits to increase total data width, width down to 1 are valid.
 *
 * Copyright (c) 2015 Elphel, Inc.
 * ram18t_var_w_var_r.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.
 *
 *  ram18t_var_w_var_r.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
`include "system_defines.vh" 
/*
   Address/data widths
   Connect unused data to 1b0, unused addresses - to 1'b1
   
   RAMB18E1 in True Dual Port (TDP) Mode - each port individually
   +-----------+---------+---------+---------+
   |Data Width | Address |   Data  | Parity  |
   +-----------+---------+---------+---------+
   |     1     | A[13:0] | D[0]    |  ---    |
   |     2     | A[13:1] | D[1:0]  |  ---    |
   |     4     | A[13:2] | D[3:0[  |  ---    |
   |     9     | A[13:3] | D[7:0]  | DP[0]   |
   |    18     | A[13:4] | D[15:0] | DP[1:0] |
   +-----------+---------+---------+---------+

   RAMB18E1 in Simple Dual Port (SDP) Mode
   one of the ports (r or w) - 32/36 bits, other - variable 
   +------------+---------+---------+---------+
   |Data Widths | Address |   Data  | Parity  |
   +------------+---------+---------+---------+
   |   32/  1   | A[13:0] | D[0]    |  ---    |
   |   32/  2   | A[13:1] | D[1:0]  |  ---    |
   |   32/  4   | A[13:2] | D[3:0[  |  ---    |
   |   36/  9   | A[13:3] | D[7:0]  | DP[0]   |
   |   36/ 18   | A[13:4] | D[15:0] | DP[1:0] |
   |   36/ 36   | A[13:5] | D[31:0] | DP[3:0] |
   +------------+---------+---------+---------+
   
   RAMB36E1 in True Dual Port (TDP) Mode - each port individually
   +-----------+---------+---------+---------+
   |Data Width | Address |   Data  | Parity  |
   +-----------+---------+---------+---------+
   |     1     | A[14:0] | D[0]    |  ---    |
   |     2     | A[14:1] | D[1:0]  |  ---    |
   |     4     | A[14:2] | D[3:0[  |  ---    |
   |     9     | A[14:3] | D[7:0]  | DP[0]   |
   |    18     | A[14:4] | D[15:0] | DP[1:0] |
   |    36     | A[14:5] | D[31:0] | DP[3:0] |
   |1(Cascade) | A[15:0] | D[0]    |  ---    |
   +-----------+---------+---------+---------+

   RAMB36E1 in Simple Dual Port (SDP) Mode
   one of the ports (r or w) - 64/72 bits, other - variable 
   +------------+---------+---------+---------+
   |Data Widths | Address |   Data  | Parity  |
   +------------+---------+---------+---------+
   |   64/  1   | A[14:0] | D[0]    |  ---    |
   |   64/  2   | A[14:1] | D[1:0]  |  ---    |
   |   64/  4   | A[14:2] | D[3:0[  |  ---    |
   |   64/  9   | A[14:3] | D[7:0]  | DP[0]   |
   |   64/ 18   | A[14:4] | D[15:0] | DP[1:0] |
   |   64/ 36   | A[14:5] | D[31:0] | DP[3:0] |
   |   64/ 72   | A[14:6] | D[63:0] | DP[7:0] |
   +------------+---------+---------+---------+
*/

module  ram18t_var_w_var_r
#(
  parameter integer REGISTERS_A = 0, // 1 - registered output
  parameter integer REGISTERS_B = 0, // 1 - registered output
  parameter integer LOG2WIDTH_A = 4,  // WIDTH= 9  << (LOG2WIDTH - 3)
  parameter integer LOG2WIDTH_B = 4,  // WIDTH= 9  << (LOG2WIDTH - 3)
  parameter WRITE_MODE_A =        "NO_CHANGE", //Valid: "WRITE_FIRST", "READ_FIRST", "NO_CHANGE"
  parameter WRITE_MODE_B =        "NO_CHANGE"  //Valid: "WRITE_FIRST", "READ_FIRST", "NO_CHANGE"
`ifdef PRELOAD_BRAMS
    ,
    `include "includes/ram36_declare_init.vh"
`endif
 )(
      input                               clk_a,     // clock for port A
      input            [13-LOG2WIDTH_A:0] addr_a,    // address port A
      input                               en_a,      // enable port A (read and write)
      input                               regen_a,   // output register enable port A
      input                               we_a,      // write port enable port A
      output     [(1 << LOG2WIDTH_A)-1:0] data_out_a,// data out port A
      input      [(1 << LOG2WIDTH_A)-1:0] data_in_a, // data in port A
      
      input                               clk_b,     // clock for port BA
      input            [13-LOG2WIDTH_B:0] addr_b,    // address port B
      input                               en_b,      // read enable port B
      input                               regen_b,   // output register enable port B
      input                               we_b,      // write port enable port B
      output     [(1 << LOG2WIDTH_B)-1:0] data_out_b,// data out port B
      input      [(1 << LOG2WIDTH_B)-1:0] data_in_b  // data in port B
);
    localparam  PWIDTH_A = (LOG2WIDTH_A > 2)? (9 << (LOG2WIDTH_A - 3)): (1 << LOG2WIDTH_A);
    localparam  PWIDTH_B = (LOG2WIDTH_B > 2)? (9 << (LOG2WIDTH_B - 3)): (1 << LOG2WIDTH_B);
    localparam  WIDTH_A  = 1 << LOG2WIDTH_A;
    localparam  WIDTH_B  = 1 << LOG2WIDTH_B;
    
    wire          [15:0] data_out16_a;
    assign data_out_a=data_out16_a[WIDTH_A-1:0];

    wire          [15:0] data_out16_b;
    assign data_out_b=data_out16_b[WIDTH_B-1:0];


    wire [WIDTH_A+15:0] data_in_ext_a =  {16'b0,data_in_a[WIDTH_A-1:0]};
    wire         [15:0] data_in16_a =    data_in_ext_a[15:0];

    wire [WIDTH_B+15:0] data_in_ext_b =  {16'b0,data_in_b[WIDTH_B-1:0]};
    wire         [15:0] data_in16_b =    data_in_ext_b[15:0];

    RAMB18E1
    #(
    .RSTREG_PRIORITY_A         ("RSTREG"),       // Valid: "RSTREG" or "REGCE"
    .RSTREG_PRIORITY_B         ("RSTREG"),       // Valid: "RSTREG" or "REGCE"
    .DOA_REG                   (REGISTERS_A),    // Valid: 0 (no output registers) and 1 - one output register (in SDP - to lower 18)
    .DOB_REG                   (REGISTERS_B),    // Valid: 0 (no output registers) and 1 - one output register (in SDP - to lower 18)
    .READ_WIDTH_A              (PWIDTH_A),       // Valid: 0,1,2,4,9,18 and in SDP mode - 36 (should be 0 if port is not used)
    .READ_WIDTH_B              (PWIDTH_B),       // Valid: 0,1,2,4,9,18 and in SDP mode - 36 (should be 0 if port is not used)
    .WRITE_WIDTH_A             (PWIDTH_A),       // Valid: 0,1,2,4,9,18 and in SDP mode - 36 (should be 0 if port is not used)
    .WRITE_WIDTH_B             (PWIDTH_B),       // Valid: 0,1,2,4,9,18 and in SDP mode - 36 (should be 0 if port is not used)
    .RAM_MODE                  ("TDP"),          // Valid "TDP" (true dual-port) and "SDP" - simple dual-port
    .WRITE_MODE_A              (WRITE_MODE_A),   // Valid: "WRITE_FIRST", "READ_FIRST", "NO_CHANGE"
    .WRITE_MODE_B              (WRITE_MODE_B),   // Valid: "WRITE_FIRST", "READ_FIRST", "NO_CHANGE"
    .RDADDR_COLLISION_HWCONFIG ("DELAYED_WRITE"),// Valid: "DELAYED_WRITE","PERFORMANCE" (no access to the same page)
    .SIM_COLLISION_CHECK       ("ALL"),          // Valid: "ALL", "GENERATE_X_ONLY", "NONE", and "WARNING_ONLY"
    .INIT_FILE                 ("NONE"),         // "NONE" or filename with initialization data
    .SIM_DEVICE                ("7SERIES")      // Simulation device family - "VIRTEX6", "VIRTEX5" and "7_SERIES" // "7SERIES"
`ifdef PRELOAD_BRAMS
    `include "includes/ram18_pass_init.vh"
`endif
    
    ) RAMB18E1_i
    (
        // Port A (Read port in SDP mode):
        .DOADO           (data_out16_a),    // Port A data/LSB data[15:0], output
        .DOPADOP         (),                // Port A parity/LSB parity[1:0], output
        .DIADI           (data_in16_a),     // Port A data/LSB data[15:0], input
        .DIPADIP         (2'b0),            // Port A parity/LSB parity[1:0], input
        .ADDRARDADDR     ({addr_a,{LOG2WIDTH_A{1'b1}}}),  // Port A (read port in SDP) address [13:0], unused should be high, input
        .CLKARDCLK       (clk_a),           // Port A (read port in SDP) clock, input
        .ENARDEN         (en_a),            // Port A (read port in SDP) Enable, input
        .REGCEAREGCE     (regen_a),         // Port A (read port in SDP) register enable, input
        .RSTRAMARSTRAM   (1'b0),            // Port A (read port in SDP) set/reset, input
        .RSTREGARSTREG   (1'b0),            // Port A (read port in SDP) register set/reset, input
        .WEA             ({2{we_a}}),       // Port A (read port in SDP) Write Enable[1:0], input
        // Port B
        .DOBDO           (data_out16_b),    // Port B data/MSB data[31:0], output
        .DOPBDOP         (),                // Port B parity/MSB parity[3:0], output
        .DIBDI           (data_in16_b),     // Port B data/MSB data[31:0], input
        .DIPBDIP         (2'b0),            // Port B parity/MSB parity[3:0], input
        .ADDRBWRADDR     ({addr_b,{LOG2WIDTH_B{1'b1}}}), // Port B (read port in SDP) address [13:0], unused should be high, input
        .CLKBWRCLK       (clk_b),           // Port B (write port in SDP) clock, input
        .ENBWREN         (en_b),            // Port B (write port in SDP) Enable, input
        .REGCEB          (regen_b),         // Port B (write port in SDP) register enable, input
        .RSTRAMB         (1'b0),            // Port B (write port in SDP) set/reset, input
        .RSTREGB         (1'b0),            // Port B (write port in SDP) register set/reset, input
        .WEBWE           ({4{we_b}})        // Port B (write port in SDP) Write Enable[3:0], input
    );

endmodule
Loading