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

working on sensor channel: histograms

parent 05baee9d
......@@ -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
/*******************************************************************************
* 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
......@@ -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,
......@@ -102,25 +112,33 @@ module sensor_channel#(
parameter SS_MOD_PERIOD = 10000 // integer 4000-40000 - SS modulation period in ns
) (
input rst,
input pclk, // global clock input, pixel rate (96MHz for MT9P006)
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,
inout sns_clkp,
inout sns_clkn,
inout sns_scl,
inout sns_sda,
inout sns_ctl,
inout sns_pg,
inout [7:0] sns_dp,
inout [7:0] sns_dn,
inout sns_clkp,
inout sns_clkn,
inout sns_scl,
inout sns_sda,
inout sns_ctl,
inout sns_pg,
// programming interface
input mclk, // global clock, half DDR3 clock, synchronizes all I/O through the command port
input [7:0] cmd_ad_in, // byte-serial command address/data (up to 6 bytes: AL-AH-D0-D1-D2-D3
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)
// (much) more will be added later
input mclk, // global clock, half DDR3 clock, synchronizes all I/O through the command port
input [7:0] cmd_ad_in, // byte-serial command address/data (up to 6 bytes: AL-AH-D0-D1-D2-D3
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)
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
......@@ -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
......
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