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)
......
......@@ -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
......
This diff is collapsed.
......@@ -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)
......
/*******************************************************************************
* 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
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment