Commit cfdcac60 authored by Andrey Filippov's avatar Andrey Filippov

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

parent 59774283
......@@ -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)
......
......@@ -390,7 +390,7 @@ module mcntrl_linear_rw #(
if (mrst) xfer_skipped <= 0;
else xfer_skipped <= start_not_partial && skip_run;
// if (mrst || frame_start_delayed) frame_start_pending <= 0;
if (mrst) frame_start_pending <= 0;
// else frame_start_pending <= {frame_start_pending[0], busy_r && (frame_start_pending[0] | frame_start)};
......
......@@ -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;
......@@ -325,10 +306,6 @@ module sens_histogram #(
else if (woi[2] & pclk_sync) hist_rwaddr <= hist_addr_d2;
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
......@@ -336,25 +313,19 @@ module sens_histogram #(
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,26 +358,11 @@ 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),
......@@ -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
......
/*******************************************************************************
* Module: sens_histogram_snglclk
* Date:2015-10-21
* Author: Andrey Filippov
* Description: Calculates per-color histogram over the specified rectangular region.
* Modified from the original sens_histogram to avoid using double
* frequency clock
*
* Copyright (c) 2015 Elphel, Inc.
* sens_histogram_snglclk.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_snglclk.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_snglclk #(
parameter HISTOGRAM_RAM_MODE = "BUF32", // valid: "NOBUF" (32-bits, no buffering - now is replaced by BUF32), "BUF18", "BUF32"
parameter HISTOGRAM_ADDR = 'h33c,
parameter HISTOGRAM_ADDR_MASK = 'h7fe,
parameter HISTOGRAM_LEFT_TOP = 'h0,
parameter HISTOGRAM_WIDTH_HEIGHT = 'h1, // 1.. 2^16, 0 - use HACT
parameter [1:0] XOR_HIST_BAYER = 2'b00// 11 // invert bayer setting
`ifdef DEBUG_RING
,parameter DEBUG_CMD_LATENCY = 2 // SuppressThisWarning VEditor - not used
`endif
)(
input mrst, // @posedge mclk, sync reset
input prst, // @posedge pclk, sync reset
input pclk, // global clock input, pixel rate (96MHz for MT9P006)
// input pclk2x,
input sof,
input eof,
input hact,
input [7:0] hist_di, // 8-bit pixel data
input mclk,
input hist_en, // @mclk - gracefully enable/disable histogram
input hist_rst, // @mclk - immediately disable if true
output hist_rq,
input hist_grant,
output [31:0] hist_do,
output reg hist_dv,
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 // NOT supported in this implementation - use software to sum
`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
);
localparam HIST_WIDTH = (HISTOGRAM_RAM_MODE == "BUF18") ? 18 : 32;
reg hist_bank_pclk;
reg [8:0] hist_rwaddr_even; // {bayer[1], pixel}
reg [8:0] hist_rwaddr_odd; // {bayer[1], pixel}
reg hist_bank_mclk;
wire set_left_top_w;
wire set_width_height_w;
wire [1:0] pio_addr;
wire [31:0] pio_data;
wire pio_stb;
reg [31:0] lt_mclk; // left+top @ posedge mclk
reg [31:0] wh_mclk; // width+height @ posedge mclk
reg [15:0] width_m1; // @posedge pclk
reg [15:0] height_m1; // @posedge pclk
reg [15:0] left; // @posedge pclk
reg [15:0] top; // @posedge pclk
reg hist_en_pclk; // @pclk - gracefully enable/disable histogram
reg hist_rst_pclk; // @pclk - immediately disable if true
reg en;
reg en_new; // @ pclk - enable new frame
reg en_mclk;
wire set_left_top_pclk;
wire set_width_height_pclk;
// reg pclk_sync; // CE for pclk2x, ~=pclk
reg odd_pix;
reg [1:0] bayer_pclk;
reg [1:0] hact_d;
reg top_margin; // above (before) active window
reg hist_done; // @pclk single cycle
wire hist_done_mclk;
reg vert_woi; // vertically in window TESTED ACTIVE
reg left_margin; // left of (before) active window
// reg [2:0] woi; // @ pclk2x - inside WOI (and delayed
reg [6:0] hor_woi; // vertically in window and delayed
reg [15:0] vcntr; // vertical (line) counter
reg [15:0] hcntr; // horizontal (pixel) counter
wire vcntr_zero_w; // vertical counter is zero
wire hcntr_zero_w; // horizontal counter is zero
reg hist_out; // some data yet to be sent out
reg hist_out_d;
reg [2:0] hist_re;
reg [1:0] hist_re_even_odd;
reg [9:0] hist_raddr;
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)
reg wait_readout; // only used in NOBUF mode, in outher modes readout is expected to be always finished in time
`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 );
assign vcntr_zero_w = !(|vcntr);
assign hcntr_zero_w = !(|hcntr);
assign hist_rq = hist_rq_r;
assign hist_xfer_done_mclk = hist_out_d && !hist_out && hist_en;
wire line_start_w = hact && !hact_d[0]; // // tested active
reg pre_first_line;
reg frame_active; // until done
`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;
else pxd_wa <= pxd_wa + 1;
if (!hact) pxd_wa_woi <= -PXD_2X_LATENCY;
else pxd_wa_woi <= pxd_wa_woi + 1;
if (hist_en_pclk && hact) pxd_ram[pxd_wa] <= hist_di;
if (hist_en_pclk && hact) bayer_ram[pxd_wa] <= bayer_pclk;
if (hist_en_pclk && hact_d[1]) woi_ram[pxd_wa_woi] <= hor_woi; // PXD_2X_LATENCY;
end
*/
always @ (posedge mclk) begin
if (set_left_top_w) lt_mclk <= pio_data;
if (set_width_height_w) wh_mclk <= pio_data;
end
always @ (posedge pclk) begin
if (set_left_top_pclk) {top,left} <= lt_mclk[31:0];
if (set_width_height_pclk) {height_m1,width_m1} <= wh_mclk[31:0];
end
// process WOI
always @ (posedge pclk) begin
hact_d <= {hact_d[0],hact};
if (!en) pre_first_line <= 0;
else if (sof && en_new) pre_first_line <= 1;
else if (hact) pre_first_line <= 0;
if (!en) top_margin <= 0;
else if (sof && en_new) top_margin <= 1;
else if (vcntr_zero_w & line_start_w) top_margin <= 0;
if (!en ||(pre_first_line && !hact)) vert_woi <= 0;
else if (vcntr_zero_w & line_start_w) vert_woi <= top_margin;
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;
else if (sof && en_new) frame_active <= 1;
if ((pre_first_line && !hact) || !frame_active) vcntr <= top;
else if (line_start_w) vcntr <= vcntr_zero_w ? height_m1 : (vcntr - 1);
if (!frame_active) left_margin <= 0;
else if (!hact_d[0]) left_margin <= 1;
else if (hcntr_zero_w) left_margin <= 0;
// !hact_d[0] to limit by right margin if window is set wrong
if (!vert_woi || wait_readout || !hact_d[0]) hor_woi[0] <= 0; // postpone WOI if reading out/erasing histogram (no-buffer mode)
else if (hcntr_zero_w) hor_woi[0] <= left_margin && vert_woi;
hor_woi[6:1] <= hor_woi[5:0];
if (!hact_d[0]) hcntr <= left;
else if (hcntr_zero_w && left_margin) hcntr <= width_m1;
else if (left_margin || hor_woi[0]) hcntr <= hcntr - 1;
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
if (!en) hist_xfer_busy <= 0;
else if (hist_xfer_done) hist_xfer_busy <= 0;
else if (vcntr_zero_w && vert_woi) hist_xfer_busy <= 1;
hist_en_pclk <= hist_en;
hist_rst_pclk <= hist_rst;
if (hist_rst_pclk) en <= 0;
else if (hist_en_pclk) en <= 1;
else if (!top_margin && !vert_woi && !hist_xfer_busy) en <= 0;
en_new <= !hist_rst_pclk && hist_en_pclk;
if (!hact && hact_d[0]) bayer_pclk[1] <= !bayer_pclk[1];
else if (pre_first_line && !hact) bayer_pclk[1] <= XOR_HIST_BAYER[1];
if (!hact) bayer_pclk[0] <= XOR_HIST_BAYER[0];
else bayer_pclk[0] <= ~bayer_pclk[0];
end
// assign hlstart = hcntr_zero_w && left_margin && hact_d[0];
reg [6:0] memen_even;
reg [6:0] memen_odd;
wire set_ra_even = memen_even[0];
wire regen_even = memen_even[2];
wire set_wa_even = memen_even[5];
wire we_even = memen_even[6];
wire set_ra_odd = memen_odd[0];
wire regen_odd = memen_odd[2];
wire set_wa_odd = memen_odd[5];
wire we_odd = memen_odd[6];
reg rwen_even; // re or we
reg rwen_odd; // re or we
wire [7:0] px_d0; // px delayed to match hor_woi (2 cycles)
wire [7:0] px_d2; // px delayed by 2 cycles from px_d0
wire [7:0] px_d4; // px delayed by 2 cycles from px_d2
wire [7:0] px_d5; // px delayed by 1 cycle from px_d4
reg [HIST_WIDTH -1 :0] r0;
reg [HIST_WIDTH -1 :0] r1;
reg r1_sat; // only used in 18-bit mode
reg [HIST_WIDTH -1 :0] r2;
reg [HIST_WIDTH -1 :0] r3;
wire [HIST_WIDTH -1 :0] hist_new_even; // data (to increment) read from the histogram memory, even pixels
wire [HIST_WIDTH -1 :0] hist_new_odd; // data (to increment) read from the histogram memory, odd pixels
reg [3:0] r_load; // load r0-r1-r2-r3 registers
reg r0_sel; // select odd/even for r0 (other option possible)
reg eq_prev_prev; // pixel equals one before previous of the same color
wire eq_prev_prev_d2; // eq_prev_prev delayed by 2 clocks to select r1 source
reg eq_prev; // pixel equals previous of the same color
wire eq_prev_d3; // eq_prev delayed by 3 clocks to select r1 source
wire start_hor_woi = hcntr_zero_w && left_margin && vert_woi;
// hist_di is 2 cycles ahead of hor_woi
always @(posedge pclk) begin
if (!hist_en_pclk || !(|hor_woi)) odd_pix <= 0;
else odd_pix <= ~odd_pix;
if (!hist_en_pclk || !((XOR_HIST_BAYER[0] ^ left[0])? hor_woi[1] : hor_woi[0])) memen_even[0] <= 0;
else memen_even[0] <= ~memen_even[0];
memen_even[6:1] <= memen_even[5:0];
if (!hist_en_pclk || !((XOR_HIST_BAYER[0] ^ left[0])? hor_woi[0] : hor_woi[1])) memen_odd[0] <= 0;
else memen_odd[0] <= ~memen_odd[0];
memen_odd[6:1] <= memen_odd[5:0];
if (hor_woi[1:0] == 2'b01) hist_rwaddr_even[8] <= bayer_pclk[1];
if (hor_woi[1:0] == 2'b01) hist_rwaddr_odd[8] <= bayer_pclk[1];
if (set_ra_even) hist_rwaddr_even[7:0] <= px_d0;
else if (set_wa_even) hist_rwaddr_even[7:0] <= px_d5;
if (set_ra_odd) hist_rwaddr_odd[7:0] <= px_d0;
else if (set_wa_odd) hist_rwaddr_odd[7:0] <= px_d5;
rwen_even <= memen_even[0] || memen_even[5];
rwen_odd <= memen_odd[0] || memen_odd[5];
r_load <= {r_load[2:0], regen_even | regen_odd};
r0_sel <= regen_odd;
eq_prev_prev <= hor_woi[4] && (px_d4 == px_d0);
eq_prev <= hor_woi[2] && (px_d2 == px_d0);
if (r_load[0]) r0 <= eq_prev_prev_d2 ? r3 : (r0_sel ? hist_new_odd : hist_new_even);
if (r_load[1]) r1 <= eq_prev_d3 ? r2 : r0;
if (r_load[1]) r1_sat <= eq_prev_d3 ? (&r2) : (&r0);
if (r_load[2]) r2 <= ((HISTOGRAM_RAM_MODE != "BUF18") || !r1_sat) ? (r1 + 1) : r1;
if (r_load[3]) r3 <= r2;
end
// after hist_out was off, require inactive grant before sending rq
reg en_rq_start;
always @ (posedge mclk) begin
en_mclk <= en;
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 (!hist_out) hist_raddr <= 0;
else if (hist_re[0]) hist_raddr <= hist_raddr + 1;
// 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) && en_rq_start;
if (!hist_out || (&hist_raddr[7:0])) hist_re[0] <= 0;
else if (hist_grant) hist_re[0] <= 1;
hist_re[2:1] <= hist_re[1:0];
// reg [2:0] hist_re_even_odd;
if (!hist_out || (&hist_raddr[7:1])) hist_re_even_odd[0] <= 0;
else if (hist_re[0]) hist_re_even_odd[0] <= ~hist_re_even_odd[0];
else if (hist_grant) hist_re_even_odd[0] <= 1; // hist_re[0] == 0 here
if (!en_mclk) hist_bank_mclk <= 0;
else if (hist_xfer_done_mclk && (HISTOGRAM_RAM_MODE != "NOBUF")) hist_bank_mclk <= !hist_bank_mclk;
hist_dv <= hist_re[2];
end
always @ (posedge pclk) begin
if (!en) wait_readout <= 0;
else if ((HISTOGRAM_RAM_MODE == "NOBUF") && hist_done) wait_readout <= 1;
else if (hist_xfer_done) wait_readout <= 0;
end
`ifdef DEBUG_RING
debug_slave #(
.SHIFT_WIDTH (64),
.READ_WIDTH (64),
.WRITE_WIDTH (32),
.DEBUG_CMD_LATENCY (DEBUG_CMD_LATENCY)
) debug_slave_i (
.mclk (mclk), // input
.mrst (mrst), // input
.debug_di (debug_di), // input
.debug_sl (debug_sl), // input
.debug_do (debug_do), // output
.rd_data ({debug_lines[15:0], debug_line_cntr[15:0], width_m1[15:0], hcntr[15:0]}), // input[31:0]
.wr_data (), // output[31:0] - not used
.stb () // output - not used
);
`endif
cmd_deser #(
.ADDR (HISTOGRAM_ADDR),
.ADDR_MASK (HISTOGRAM_ADDR_MASK),
.NUM_CYCLES (6),
.ADDR_WIDTH (2),
.DATA_WIDTH (32),
.ADDR1 (0),
.ADDR_MASK1 (0),
.ADDR2 (0),
.ADDR_MASK2 (0)
) cmd_deser_sens_histogram_i (
.rst (1'b0), // input
.clk (mclk), // input
.srst (mrst), // input
.ad (cmd_ad), // input[7:0]
.stb (cmd_stb), // input
.addr (pio_addr), // output[15:0]
.data (pio_data), // output[31:0]
.we (pio_stb) // output
);
dly_16 #(
.WIDTH(8)
) dly_16_px_dly0_i (
.clk (pclk), // input
.rst (prst), // input
.dly (4'h2), // input[3:0]
.din (hist_di), // input[0:0]
.dout (px_d0) // output[0:0]
);
dly_16 #(
.WIDTH(8)
) dly_16_px_dly2_i (
.clk (pclk), // input
.rst (prst), // input
.dly (4'h1), // input[3:0]
.din (px_d0), // input[0:0]
.dout (px_d2) // output[0:0]
);
dly_16 #(
.WIDTH(8)
) dly_16_px_dly4_i (
.clk (pclk), // input
.rst (prst), // input
.dly (4'h1), // input[3:0]
.din (px_d2), // input[0:0]
.dout (px_d4) // output[0:0]
);
dly_16 #(
.WIDTH(8)
) dly_16_px_dly5_i (
.clk (pclk), // input
.rst (prst), // input
.dly (4'h0), // input[3:0]
.din (px_d4), // input[0:0]
.dout (px_d5) // output[0:0]
);
dly_16 #(
.WIDTH(1)
) dly_16_eq_prev_prev_d2_i (
.clk (pclk), // input
.rst (prst), // input
.dly (4'h1), // input[3:0]
.din (eq_prev_prev), // input[0:0]
.dout (eq_prev_prev_d2) // output[0:0]
);
dly_16 #(
.WIDTH(1)
) dly_16_eq_prev_d3_i (
.clk (pclk), // input
.rst (prst), // input
.dly (4'h2), // input[3:0]
.din (eq_prev), // input[0:0]
.dout (eq_prev_d3) // output[0:0]
);
pulse_cross_clock pulse_cross_clock_lt_i (
.rst (mrst), // input
.src_clk (mclk), // input
.dst_clk (pclk), // input
.in_pulse (set_left_top_w), // input
.out_pulse (set_left_top_pclk), // output
.busy() // output
);
pulse_cross_clock pulse_cross_clock_wh_i (
.rst (mrst), // input
.src_clk (mclk), // input
.dst_clk (pclk), // input
.in_pulse (set_width_height_w), // input
.out_pulse (set_width_height_pclk), // output
.busy() // output
);
pulse_cross_clock pulse_cross_clock_hist_done_i (
.rst (prst), // input
.src_clk (pclk), // input
.dst_clk (mclk), // input
.in_pulse (hist_done), // input
.out_pulse (hist_done_mclk), // output
.busy() // output
);
pulse_cross_clock pulse_cross_clock_hist_xfer_done_i (
.rst (mrst), // input
.src_clk (mclk), // input
.dst_clk (pclk), // input
.in_pulse (hist_xfer_done_mclk), // input
.out_pulse (hist_xfer_done), // output
.busy() // 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
generate
if ((HISTOGRAM_RAM_MODE=="BUF32") || (HISTOGRAM_RAM_MODE=="NOBUF"))// impossible to use a two RAMB18E1 32-bit wide
sens_hist_ram_snglclk_32 sens_hist_ram_snglclk_32_i (
.pclk (pclk), // input
.addr_a_even ({hist_bank_pclk, hist_rwaddr_even}), // input[9:0]
.addr_a_odd ({hist_bank_pclk, hist_rwaddr_odd}), // input[9:0]