Commit d4f2714d authored by Andrey Filippov's avatar Andrey Filippov

added sensor trigger/synchronization module (with linescan mode), completed top sensor subsystem

parent 3023d860
...@@ -70,7 +70,7 @@ module event_logger#( ...@@ -70,7 +70,7 @@ module event_logger#(
output [GPIO_N-1:0] ext_en, output [GPIO_N-1:0] ext_en,
// byte-parallel timestamps from 4 sesnors channels (in triggered mode all are the same, different only in free running mode) // byte-parallel timestamps from 4 sensors channels (in triggered mode all are the same, different only in free running mode)
// each may generate logger event, channel number encoded in bits 25:24 of the external microseconds // each may generate logger event, channel number encoded in bits 25:24 of the external microseconds
input ts_stb_chn0, // @mclk 1 clock before ts_rcv_data is valid input ts_stb_chn0, // @mclk 1 clock before ts_rcv_data is valid
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
`timescale 1ns/1ps `timescale 1ns/1ps
/* /*
Logs frame synchronization data from other camera (same as frame sync) Logs frame synchronization data from other camera (same as frame sync)
When sesnors are running in free running mode, each sensor may provide individual timestamp (sampled at vsync) When sensors are running in free running mode, each sensor may provide individual timestamp (sampled at vsync)
*/ */
module imu_exttime393( module imu_exttime393(
...@@ -29,7 +29,7 @@ module imu_exttime393( ...@@ -29,7 +29,7 @@ module imu_exttime393(
input mclk, // system clock, negedge TODO:COnvert to posedge! input mclk, // system clock, negedge TODO:COnvert to posedge!
input xclk, // half frequency (80 MHz nominal) input xclk, // half frequency (80 MHz nominal)
input [3:0] en_chn_mclk, // enable per-channel module operation, if all 0 - reset input [3:0] en_chn_mclk, // enable per-channel module operation, if all 0 - reset
// byte-parallel timestamps from 4 sesnors channels (in triggered mode all are the same, different only in free running mode) // byte-parallel timestamps from 4 sensors channels (in triggered mode all are the same, different only in free running mode)
// each may generate logger event, channel number encoded in bits 25:24 of the external microseconds // each may generate logger event, channel number encoded in bits 25:24 of the external microseconds
input ts_stb_chn0, // @mclk 1 clock before ts_rcv_data is valid input ts_stb_chn0, // @mclk 1 clock before ts_rcv_data is valid
......
...@@ -260,7 +260,7 @@ module sens_histogram #( ...@@ -260,7 +260,7 @@ module sens_histogram #(
.ADDR_MASK1 (0), .ADDR_MASK1 (0),
.ADDR2 (0), .ADDR2 (0),
.ADDR_MASK2 (0) .ADDR_MASK2 (0)
) cmd_deser_sens_i2c_i ( ) cmd_deser_sens_histogram_i (
.rst (rst), // input .rst (rst), // input
.clk (mclk), // input .clk (mclk), // input
.ad (cmd_ad), // input[7:0] .ad (cmd_ad), // input[7:0]
......
...@@ -26,8 +26,8 @@ module sens_parallel12 #( ...@@ -26,8 +26,8 @@ module sens_parallel12 #(
parameter SENSIO_CTRL = 'h0, parameter SENSIO_CTRL = 'h0,
parameter SENSIO_STATUS = 'h1, parameter SENSIO_STATUS = 'h1,
parameter SENSIO_JTAG = 'h2, parameter SENSIO_JTAG = 'h2,
parameter SENSIO_WIDTH = 'h3, // 1.. 2^16, 0 - use HACT parameter SENSIO_WIDTH = 'h3, // set line width (1.. 2^16) if 0 - use HACT
parameter SENSIO_DELAYS = 'h4, // 'h4..'h7 parameter SENSIO_DELAYS = 'h4, // 'h4..'h7 - each address sets 4 delays through 4 bytes of 32-bit data
parameter SENSIO_STATUS_REG = 'h31, parameter SENSIO_STATUS_REG = 'h31,
parameter SENS_JTAG_PGMEN = 8, parameter SENS_JTAG_PGMEN = 8,
...@@ -78,9 +78,11 @@ module sens_parallel12 #( ...@@ -78,9 +78,11 @@ module sens_parallel12 #(
output ipclk, // re-generated sensor output clock (regional clock to drive external fifo) output ipclk, // re-generated sensor output clock (regional clock to drive external fifo)
output ipclk2x,// twice frequency regenerated sensor clock (possibly to run external fifo) output ipclk2x,// twice frequency regenerated sensor clock (possibly to run external fifo)
// input pclk2x, // maybe not needed here // input pclk2x, // maybe not needed here
input trigger_mode, // running in triggered mode (0 - free running mode)
input trig, // per-sensor trigger input
// sensor pads excluding i2c // sensor pads excluding i2c
input vact, inout vact,
input hact, //output in fillfactory mode inout hact, //output in fillfactory mode
inout bpf, // output in fillfactory mode inout bpf, // output in fillfactory mode
inout [11:0] pxd, //actually only 2 LSBs are inouts inout [11:0] pxd, //actually only 2 LSBs are inouts
inout mrst, inout mrst,
...@@ -88,7 +90,7 @@ module sens_parallel12 #( ...@@ -88,7 +90,7 @@ module sens_parallel12 #(
inout arst, inout arst,
inout aro, inout aro,
output dclk, output dclk, // externally connected to inout port
// output // output
output [11:0] pxd_out, output [11:0] pxd_out,
output vact_out, output vact_out,
...@@ -142,13 +144,14 @@ module sens_parallel12 #( ...@@ -142,13 +144,14 @@ module sens_parallel12 #(
wire clkfb_pxd_stopped_mmcm; wire clkfb_pxd_stopped_mmcm;
// programmed resets to the sensor // programmed resets to the sensor
reg iaro = 0; reg iaro_soft = 0;
wire iaro;
reg iarst = 0; reg iarst = 0;
reg imrst = 0; reg imrst = 0;
reg rst_mmcm=1; // rst and command - en/dis reg rst_mmcm=1; // rst and command - en/dis
reg [5:0] quadrants=0; reg [5:0] quadrants=0; //90-degree shifts for data {1:0], hact [3:2] and vact [5:4]
reg ld_idelay=0; reg ld_idelay=0;
reg sel_ext_clk=0; // select clock source from the sensor (0 - use internal clock - to sesnor) reg sel_ext_clk=0; // select clock source from the sensor (0 - use internal clock - to sensor)
...@@ -175,15 +178,16 @@ module sens_parallel12 #( ...@@ -175,15 +178,16 @@ module sens_parallel12 #(
assign set_other_delay = set_idelay[3]; assign set_other_delay = set_idelay[3];
assign status = {locked_pxd_mmcm,clkin_pxd_stopped_mmcm,clkfb_pxd_stopped_mmcm,xfpgadone,ps_rdy, ps_out,xfpgatdo,senspgmin}; assign status = {locked_pxd_mmcm,clkin_pxd_stopped_mmcm,clkfb_pxd_stopped_mmcm,xfpgadone,ps_rdy, ps_out,xfpgatdo,senspgmin};
assign hact_out = hact_r; assign hact_out = hact_r;
assign iaro = trigger_mode? ~trig : iaro_soft;
always @(posedge rst or posedge mclk) begin always @(posedge rst or posedge mclk) begin
if (rst) data_r <= 0; if (rst) data_r <= 0;
else if (cmd_we) data_r <= cmd_data; else if (cmd_we) data_r <= cmd_data;
if (rst) set_idelay <= 0; if (rst) set_idelay <= 0;
else set_idelay <= {4{cmd_we}} & {(cmd_a==(SENSIO_DELAYS+3))?1'b1:1'b0, else set_idelay <= {4{cmd_we}} & {(cmd_a==(SENSIO_DELAYS+3)),
(cmd_a==(SENSIO_DELAYS+2))?1'b1:1'b0, (cmd_a==(SENSIO_DELAYS+2)),
(cmd_a==(SENSIO_DELAYS+1))?1'b1:1'b0, (cmd_a==(SENSIO_DELAYS+1)),
(cmd_a==(SENSIO_DELAYS+0))?1'b1:1'b0}; (cmd_a==(SENSIO_DELAYS+0))};
if (rst) set_status_r <=0; if (rst) set_status_r <=0;
else set_status_r <= cmd_we && (cmd_a== SENSIO_STATUS); else set_status_r <= cmd_we && (cmd_a== SENSIO_STATUS);
if (rst) set_ctrl_r <=0; if (rst) set_ctrl_r <=0;
...@@ -212,8 +216,8 @@ module sens_parallel12 #( ...@@ -212,8 +216,8 @@ module sens_parallel12 #(
if (rst) iarst <= 0; if (rst) iarst <= 0;
else if (set_ctrl_r && data_r[SENS_CTRL_ARST + 1]) iarst <= data_r[SENS_CTRL_ARST]; else if (set_ctrl_r && data_r[SENS_CTRL_ARST + 1]) iarst <= data_r[SENS_CTRL_ARST];
if (rst) iaro <= 0; if (rst) iaro_soft <= 0;
else if (set_ctrl_r && data_r[SENS_CTRL_MRST + 1]) iaro <= data_r[SENS_CTRL_ARO]; else if (set_ctrl_r && data_r[SENS_CTRL_MRST + 1]) iaro_soft <= data_r[SENS_CTRL_ARO];
if (rst) rst_mmcm <= 0; if (rst) rst_mmcm <= 0;
else if (set_ctrl_r && data_r[SENS_CTRL_RST_MMCM + 1]) rst_mmcm <= data_r[SENS_CTRL_RST_MMCM]; else if (set_ctrl_r && data_r[SENS_CTRL_RST_MMCM + 1]) rst_mmcm <= data_r[SENS_CTRL_RST_MMCM];
...@@ -538,7 +542,7 @@ module sens_parallel12 #( ...@@ -538,7 +542,7 @@ module sens_parallel12 #(
.I (xpgmen?(~xfpgaprog):force_senspgm), // input .I (xpgmen?(~xfpgaprog):force_senspgm), // input
.T (~(xpgmen || force_senspgm)) // input - disable when reading DONE .T (~(xpgmen || force_senspgm)) // input - disable when reading DONE
); );
// pullup for mrst (used as input for "DONE") and senspgm (grounded on sesnor boards) // pullup for mrst (used as input for "DONE") and senspgm (grounded on sensor boards)
mpullup i_mrst_pullup(mrst); mpullup i_mrst_pullup(mrst);
mpullup i_senspgm_pullup(senspgm); mpullup i_senspgm_pullup(senspgm);
always @ (posedge mclk or posedge rst) begin always @ (posedge mclk or posedge rst) begin
......
/*******************************************************************************
* Module: sens_sync
* Date:2015-07-13
* Author: andrey
* Description: Handle linescan mode, sensor trigger and late frame sync
*
* Copyright (c) 2015 Elphel, Inc .
* sens_sync.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_sync.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_sync#(
parameter SENS_SYNC_ADDR = 'h404,
parameter SENS_SYNC_MASK = 'h7fc,
// 2 locations reserved for control/status (if they will be needed)
parameter SENS_SYNC_MULT = 'h2, // relative register address to write number of frames to combine in one (minus 1, '0' - each farme)
parameter SENS_SYNC_LATE = 'h3, // number of lines to delay late frame sync
parameter SENS_SYNC_FBITS = 16, // number of bits in a frame counter for linescan mode
parameter SENS_SYNC_LBITS = 16, // number of bits in a line counter for sof_late output (limited by eof)
parameter SENS_SYNC_LATE_DFLT = 15, // number of lines to delay late frame sync
parameter SENS_SYNC_MINBITS = 8, // number of bits to enforce minimal frame period
parameter SENS_SYNC_MINPER = 130 // minimal frame period (in pclk/mclk?)
)(
input rst, // global reset
input pclk, // global clock input, pixel rate (96MHz for MT9P006)
input mclk, // global system clock, synchronizes commands
input en, // enable channel (0 resets counters)
input sof_in, // @pclk start of frame input, single-cycle
input eof_in, // @pclk end of frame input, single-cycle (to limit sof_late
input hact, // @pclk (use to count lines for delayed pulse)
input trigger_mode,// @mclk - 1 - triggered mode, 0 - free running mode
input trig_in, // @mclk - single-cycle trigger input
output trig, // @pclk trigger signal to the sensor - from trig_in until SOF
output reg sof_out_pclk,// @pclk - use in the same sensor_channel module
output sof_out, // @mclk - single-cycle frame sync (no delay)
output sof_late, // @mclk - single-cycle frame sync (delayed)
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
);
localparam DATA_WIDTH = (SENS_SYNC_FBITS > SENS_SYNC_LBITS) ? SENS_SYNC_FBITS : SENS_SYNC_LBITS;
reg [SENS_SYNC_FBITS-1:0] sub_frames_pclk = 0; // sub-frame number ("linescan" mode)
reg [SENS_SYNC_LBITS-1:0] line_dly_pclk = SENS_SYNC_LATE_DFLT; // sub-frame number ("linescan" mode)
reg [SENS_SYNC_FBITS-1:0] sub_frames_left; // sub-frame number ("linescan" mode)
reg [SENS_SYNC_FBITS-1:0] lines_left; //Number of lines left to generate sof_late
reg [DATA_WIDTH-1:0] cmd_data_r;
wire [31:0] cmd_data;
wire [1:0] cmd_a;
wire cmd_we;
reg [1:0] cmd_a_r;
wire set_data_mclk;
wire set_data_pclk;
wire zero_frames_left;
wire trig_in_pclk;
wire pre_sof_out;
reg hact_r;
wire hact_single;
reg sof_dly; // from sof_in to sof_out;
wire last_line;
wire pre_sof_late;
reg trigger_mode_pclk;
reg en_vacts_free=1'b1; // register to allow only one vacts after trigger in triggered mode. Allows first vacts after mode is set
reg overdue; // generated at camsync to bypass filtering out second vact after trigger. Needed to prevent lock-up
// when exposure > triger period (and trigger is operated as divide-by-2)
reg trig_r;
reg [SENS_SYNC_MINBITS-1:0] period_cntr;
reg period_dly; // runnning counter to enforce > min period
assign set_data_mclk = cmd_we && ((cmd_a == SENS_SYNC_MULT) || (cmd_a == SENS_SYNC_LATE));
assign zero_frames_left = !(|sub_frames_left);
assign hact_single = hact && !hact_r;
assign last_line = !(|lines_left);
assign pre_sof_late = sof_dly && (eof_in || (hact_single && last_line));
assign trig = trig_r;
assign pre_sof_out = sof_in && zero_frames_left && !period_dly && (en_vacts_free || trig_r || overdue);
always @ (posedge mclk) begin
if (set_data_mclk) cmd_data_r <= cmd_data[DATA_WIDTH-1:0];
if (set_data_mclk) cmd_a_r <= cmd_a;
end
always @ (posedge pclk) begin
if (set_data_pclk && (cmd_a_r == SENS_SYNC_MULT))
sub_frames_pclk <= cmd_data_r[SENS_SYNC_FBITS-1:0];
if (set_data_pclk && (cmd_a_r == SENS_SYNC_LATE))
line_dly_pclk <= cmd_data_r[SENS_SYNC_LBITS-1:0];
if (!en || (sof_in && zero_frames_left)) sub_frames_left <= sub_frames_pclk ;
else if (sof_in) sub_frames_left <= sub_frames_left - 1;
if (!en) hact_r <= hact;
if (!en) sof_dly <= 0;
else if (pre_sof_out) sof_dly <= 1;
else if (pre_sof_late) sof_dly <= 0;
else if (!sof_dly) lines_left <= line_dly_pclk;
else if (hact_single) lines_left <= lines_left - 1;
trigger_mode_pclk <= trigger_mode;
if (!trigger_mode_pclk || !en) en_vacts_free<= 1'b1;
else if (sof_in) en_vacts_free<= 1'b0;
if (pre_sof_out || !trigger_mode_pclk) overdue <= 1'b0;
else if (trig_in_pclk) overdue <= trig_r;
if (!en || !trigger_mode_pclk) trig_r <=0;
else if (trig_in) trig_r <= ~trig_r;
// enforce minimal frame period (applies to both normal and delayed pulse (Make it only in free-running mode?)
if (!en || !(&period_cntr)) period_dly <= 0;
else if (pre_sof_out) period_dly <= 1;
if (!period_dly) period_cntr <= SENS_SYNC_MINPER;
else period_cntr <= period_cntr - 1;
sof_out_pclk <= pre_sof_out;
end
cmd_deser #(
.ADDR (SENS_SYNC_ADDR),
.ADDR_MASK (SENS_SYNC_MASK),
.NUM_CYCLES (6),
.ADDR_WIDTH (2),
.DATA_WIDTH (32),
.ADDR1 (0),
.ADDR_MASK1 (0),
.ADDR2 (0),
.ADDR_MASK2 (0)
) cmd_deser_sens_sync_i (
.rst (rst), // input
.clk (mclk), // input
.ad (cmd_ad), // input[7:0]
.stb (cmd_stb), // input
.addr (cmd_a), // output[15:0]
.data (cmd_data), // output[31:0]
.we (cmd_we) // output
);
// mclk -> pclk
pulse_cross_clock pulse_cross_clock_set_data_pclk_i (
.rst (rst), // input
.src_clk (mclk), // input
.dst_clk (pclk), // input
.in_pulse (set_data_mclk), // input
.out_pulse (set_data_pclk), // output
.busy() // output
);
pulse_cross_clock pulse_cross_clock_trig_in_pclk_i (
.rst (rst), // input
.src_clk (mclk), // input
.dst_clk (pclk), // input
.in_pulse (trig_in), // input
.out_pulse (trig_in_pclk), // output
.busy() // output
);
// pclk -> mclk
pulse_cross_clock pulse_cross_clock_sof_out_i (
.rst (rst), // input
.src_clk (pclk), // input
.dst_clk (mclk), // input
.in_pulse (pre_sof_out), // input
.out_pulse (sof_out), // output
.busy() // output
);
pulse_cross_clock pulse_cross_clock_sof_late_i (
.rst (rst), // input
.src_clk (pclk), // input
.dst_clk (mclk), // input
.in_pulse (pre_sof_late), // input
.out_pulse (sof_late), // output
.busy() // output
);
endmodule
...@@ -30,16 +30,25 @@ module sensor_channel#( ...@@ -30,16 +30,25 @@ module sensor_channel#(
parameter SENSI2C_STATUS_REG_REL = 0, // 4 locations" 'h30, 'h32, 'h34, 'h36 parameter SENSI2C_STATUS_REG_REL = 0, // 4 locations" 'h30, 'h32, 'h34, 'h36
parameter SENSIO_STATUS_REG_REL = 1, // 4 locations" 'h31, 'h33, 'h35, 'h37 parameter SENSIO_STATUS_REG_REL = 1, // 4 locations" 'h31, 'h33, 'h35, 'h37
// parameter SENSOR_BASE_ADDR = 'h300, // sensor registers base address parameter SENS_SYNC_RADDR = 'h4,
// parameter SENSI2C_STATUS_REG = 'h30, parameter SENS_SYNC_MASK = 'h7fc,
// parameter SENSIO_STATUS_REG = 'h31, // 2 locations reserved for control/status (if they will be needed)
parameter SENS_SYNC_MULT = 'h2, // relative register address to write number of frames to combine in one (minus 1, '0' - each farme)
parameter SENS_SYNC_LATE = 'h3, // number of lines to delay late frame sync
parameter SENS_SYNC_FBITS = 16, // number of bits in a frame counter for linescan mode
parameter SENS_SYNC_LBITS = 16, // number of bits in a line counter for sof_late output (limited by eof)
parameter SENS_SYNC_LATE_DFLT = 15, // number of lines to delay late frame sync
parameter SENS_SYNC_MINBITS = 8, // number of bits to enforce minimal frame period
parameter SENS_SYNC_MINPER = 130, // minimal frame period (in pclk/mclk?)
parameter SENSOR_NUM_HISTOGRAM= 3, // number of histogram channels parameter SENSOR_NUM_HISTOGRAM= 3, // number of histogram channels
parameter HISTOGRAM_RAM_MODE = "NOBUF", // valid: "NOBUF" (32-bits, no buffering), "BUF18", "BUF32" parameter HISTOGRAM_RAM_MODE = "NOBUF", // valid: "NOBUF" (32-bits, no buffering), "BUF18", "BUF32"
parameter SENS_GAMMA_NUM_CHN = 3, // number of subchannels for his sensor ports (1..4) parameter SENS_GAMMA_NUM_CHN = 3, // number of subchannels for his sensor ports (1..4)
parameter SENS_GAMMA_BUFFER = 0, // 1 - use "shadow" table for clean switching, 0 - single table per channel parameter SENS_GAMMA_BUFFER = 0, // 1 - use "shadow" table for clean switching, 0 - single table per channel
// parameters defining address map // parameters defining address map
parameter SENSOR_CTRL_RADDR = 0, //'h300 parameter SENSOR_CTRL_RADDR = 0, //'h00
parameter SENSOR_CTRL_ADDR_MASK = 'h7ff, // parameter SENSOR_CTRL_ADDR_MASK = 'h7ff, //
// bits of the SENSOR mode register // bits of the SENSOR mode register
parameter SENSOR_MODE_WIDTH = 9, parameter SENSOR_MODE_WIDTH = 9,
...@@ -47,13 +56,13 @@ module sensor_channel#( ...@@ -47,13 +56,13 @@ module sensor_channel#(
parameter SENSOR_HIST_NRST_BIT = 4, // 0 - immediately reset all histogram modules parameter SENSOR_HIST_NRST_BIT = 4, // 0 - immediately reset all histogram modules
parameter SENSOR_16BIT_BIT = 8, // 0 - 8 bpp mode, 1 - 16 bpp (bypass gamma). Gamma-processed data is still used for histograms parameter SENSOR_16BIT_BIT = 8, // 0 - 8 bpp mode, 1 - 16 bpp (bypass gamma). Gamma-processed data is still used for histograms
parameter SENSI2C_CTRL_RADDR = 2, // 302..'h303 parameter SENSI2C_CTRL_RADDR = 2, // 'h02..'h03
parameter SENSI2C_CTRL_MASK = 'h7fe, parameter SENSI2C_CTRL_MASK = 'h7fe,
// sensor_i2c_io relative control register addresses // sensor_i2c_io relative control register addresses
parameter SENSI2C_CTRL = 'h0, parameter SENSI2C_CTRL = 'h0,
parameter SENSI2C_STATUS = 'h1, parameter SENSI2C_STATUS = 'h1,
parameter SENS_GAMMA_RADDR = 4, parameter SENS_GAMMA_RADDR = 'h38, //4, 'h38..'h3b
parameter SENS_GAMMA_ADDR_MASK = 'h7fc, parameter SENS_GAMMA_ADDR_MASK = 'h7fc,
// sens_gamma registers // sens_gamma registers
parameter SENS_GAMMA_CTRL = 'h0, parameter SENS_GAMMA_CTRL = 'h0,
...@@ -68,7 +77,7 @@ module sensor_channel#( ...@@ -68,7 +77,7 @@ module sensor_channel#(
parameter SENS_GAMMA_MODE_REPET = 4, parameter SENS_GAMMA_MODE_REPET = 4,
parameter SENS_GAMMA_MODE_TRIG = 5, parameter SENS_GAMMA_MODE_TRIG = 5,
parameter SENSIO_RADDR = 8, //'h308 .. 'h30c parameter SENSIO_RADDR = 8, //'h308 .. 'h30f
parameter SENSIO_ADDR_MASK = 'h7f8, parameter SENSIO_ADDR_MASK = 'h7f8,
// sens_parallel12 registers // sens_parallel12 registers
parameter SENSIO_CTRL = 'h0, parameter SENSIO_CTRL = 'h0,
...@@ -167,12 +176,18 @@ module sensor_channel#( ...@@ -167,12 +176,18 @@ module sensor_channel#(
output status_rq, // input request to send status downstream 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)
input trigger_mode, // running in triggered mode (0 - free running mode)
input trig_in, // per-sensor trigger input
// 16/8-bit mode data to memory (8-bits are packed by 2 in 16 mode @posedge pclk // 16/8-bit mode data to memory (8-bits are packed by 2 in 16 mode @posedge pclk
output [15:0] dout, // @posedge pclk output [15:0] dout, // @posedge pclk
output dout_valid, // in 8-bit mode continues pixel flow have dout_valid alternating on/off output dout_valid, // in 8-bit mode continues pixel flow have dout_valid alternating on/off
output last_in_line, // valid with dout_valid - last in line dout output last_in_line, // valid with dout_valid - last in line dout
output sof_out, // start of frame 1-clk pulse with the same delays as output data
output eof_out, // end of frame 1-clk pulse with the same delays as output data output sof_out, // @pclk start of frame 1-clk pulse with the same delays as output data
output eof_out, // @pclk end of frame 1-clk pulse with the same delays as output data
output sof_out_mclk, // @mclk filtered, possibly decimated start of frame
output sof_late_mclk, // @mclk filtered, possibly decimated start of frame, delayed by specified number of lines
// histogram interface to S_AXI, 256x32bit continuous bursts @posedge mclk, each histogram having 4 bursts // histogram interface to S_AXI, 256x32bit continuous bursts @posedge mclk, each histogram having 4 bursts
output hist_request, // request to transfer a burst output hist_request, // request to transfer a burst
...@@ -186,14 +201,14 @@ module sensor_channel#( ...@@ -186,14 +201,14 @@ module sensor_channel#(
localparam SENSOR_BASE_ADDR = (SENSOR_GROUP_ADDR + SENSOR_NUMBER * SENSOR_BASE_INC); localparam SENSOR_BASE_ADDR = (SENSOR_GROUP_ADDR + SENSOR_NUMBER * SENSOR_BASE_INC);
localparam SENSI2C_STATUS_REG = (SENSI2C_STATUS_REG_BASE + SENSOR_NUMBER * SENSI2C_STATUS_REG_INC + SENSI2C_STATUS_REG_REL); localparam SENSI2C_STATUS_REG = (SENSI2C_STATUS_REG_BASE + SENSOR_NUMBER * SENSI2C_STATUS_REG_INC + SENSI2C_STATUS_REG_REL);
localparam SENSIO_STATUS_REG = (SENSI2C_STATUS_REG_BASE + SENSOR_NUMBER * SENSI2C_STATUS_REG_INC + SENSIO_STATUS_REG_REL); localparam SENSIO_STATUS_REG = (SENSI2C_STATUS_REG_BASE + SENSOR_NUMBER * SENSI2C_STATUS_REG_INC + SENSIO_STATUS_REG_REL);
localparam SENS_SYNC_ADDR = SENSOR_BASE_ADDR + SENS_SYNC_RADDR;
// parameter SENSOR_BASE_ADDR = 'h300; // sensor registers base address // parameter SENSOR_BASE_ADDR = 'h300; // sensor registers base address
localparam SENSOR_CTRL_ADDR = SENSOR_BASE_ADDR + SENSOR_CTRL_RADDR; // 'h300 localparam SENSOR_CTRL_ADDR = SENSOR_BASE_ADDR + SENSOR_CTRL_RADDR;
localparam SENSI2C_CTRL_ADDR = SENSOR_BASE_ADDR + SENSI2C_CTRL_RADDR; // 'h302..'h303 localparam SENSI2C_CTRL_ADDR = SENSOR_BASE_ADDR + SENSI2C_CTRL_RADDR;
localparam SENS_GAMMA_ADDR = SENSOR_BASE_ADDR + SENS_GAMMA_RADDR; // 'h304..'h307 localparam SENS_GAMMA_ADDR = SENSOR_BASE_ADDR + SENS_GAMMA_RADDR;
localparam SENSIO_ADDR = SENSOR_BASE_ADDR + SENSIO_RADDR; // 'h308 .. 'h30c localparam SENSIO_ADDR = SENSOR_BASE_ADDR + SENSIO_RADDR;
localparam SENSI2C_ABS_ADDR = SENSOR_BASE_ADDR + SENSI2C_ABS_RADDR; // 'h310..'h31f localparam SENSI2C_ABS_ADDR = SENSOR_BASE_ADDR + SENSI2C_ABS_RADDR;
localparam SENSI2C_REL_ADDR = SENSOR_BASE_ADDR + SENSI2C_REL_RADDR; // 'h320..'h32f localparam SENSI2C_REL_ADDR = SENSOR_BASE_ADDR + SENSI2C_REL_RADDR;
localparam HISTOGRAM_ADDR0 = (SENSOR_NUM_HISTOGRAM > 0)?(SENSOR_BASE_ADDR + HISTOGRAM_RADDR0):-1; // localparam HISTOGRAM_ADDR0 = (SENSOR_NUM_HISTOGRAM > 0)?(SENSOR_BASE_ADDR + HISTOGRAM_RADDR0):-1; //
localparam HISTOGRAM_ADDR1 = (SENSOR_NUM_HISTOGRAM > 1)?(SENSOR_BASE_ADDR + HISTOGRAM_RADDR1):-1; // localparam HISTOGRAM_ADDR1 = (SENSOR_NUM_HISTOGRAM > 1)?(SENSOR_BASE_ADDR + HISTOGRAM_RADDR1):-1; //
localparam HISTOGRAM_ADDR2 = (SENSOR_NUM_HISTOGRAM > 2)?(SENSOR_BASE_ADDR + HISTOGRAM_RADDR2):-1; // localparam HISTOGRAM_ADDR2 = (SENSOR_NUM_HISTOGRAM > 2)?(SENSOR_BASE_ADDR + HISTOGRAM_RADDR2):-1; //
...@@ -223,11 +238,15 @@ module sensor_channel#( ...@@ -223,11 +238,15 @@ module sensor_channel#(
wire sof; // start of frame wire sof; // start of frame
wire eof; // end of frame wire eof; // end of frame
wire sof_out_sync; // sof filtetred, optionally decimated (for linescan mode)
wire [15:0] gamma_pxd_in; wire [15:0] gamma_pxd_in;
wire gamma_hact_in; wire gamma_hact_in;
wire gamma_sof_in; wire gamma_sof_in;
wire gamma_eof_in; wire gamma_eof_in;
wire [7:0] gamma_pxd_out; wire [7:0] gamma_pxd_out;
wire gamma_hact_out; wire gamma_hact_out;
wire gamma_sof_out; wire gamma_sof_out;
...@@ -252,14 +271,14 @@ module sensor_channel#( ...@@ -252,14 +271,14 @@ module sensor_channel#(
reg dav_r; reg dav_r;
wire [15:0] dout_w; wire [15:0] dout_w;
wire dav_w; wire dav_w;
wire trig;
reg sof_out_r; reg sof_out_r;
reg eof_out_r; reg eof_out_r;
// TODO: insert vignetting and/or flat field, pixel defects before gamma_*_in // TODO: insert vignetting and/or flat field, pixel defects before gamma_*_in
assign gamma_pxd_in = {pxd[11:0],4'b0}; assign gamma_pxd_in = {pxd[11:0],4'b0};
assign gamma_hact_in = hact; assign gamma_hact_in = hact;
assign gamma_sof_in = sof; assign gamma_sof_in = sof_out_sync; // sof;
assign gamma_eof_in = eof; assign gamma_eof_in = eof;
assign dout = dout_r; assign dout = dout_r;
...@@ -403,6 +422,8 @@ module sensor_channel#( ...@@ -403,6 +422,8 @@ module sensor_channel#(
.pclk (pclk), // input .pclk (pclk), // input
.ipclk (ipclk), // output .ipclk (ipclk), // output
.ipclk2x (), // ipclk2x), // output .ipclk2x (), // ipclk2x), // output
.trigger_mode (trigger_mode), // input
.trig (trig), // input
.vact (sns_dn[1]), // input .vact (sns_dn[1]), // input
.hact (sns_dp[1]), // input .hact (sns_dp[1]), // input
.bpf (sns_dn[0]), // inout .bpf (sns_dn[0]), // inout
...@@ -440,6 +461,37 @@ module sensor_channel#( ...@@ -440,6 +461,37 @@ module sensor_channel#(
.eof (eof) // output .eof (eof) // output
); );
sens_sync #(
.SENS_SYNC_ADDR (SENS_SYNC_ADDR),
.SENS_SYNC_MASK (SENS_SYNC_MASK),
.SENS_SYNC_MULT (SENS_SYNC_MULT),
.SENS_SYNC_LATE (SENS_SYNC_LATE),
.SENS_SYNC_FBITS (SENS_SYNC_FBITS),
.SENS_SYNC_LBITS (SENS_SYNC_LBITS),
.SENS_SYNC_LATE_DFLT (SENS_SYNC_LATE_DFLT),
.SENS_SYNC_MINBITS (SENS_SYNC_MINBITS),
.SENS_SYNC_MINPER (SENS_SYNC_MINPER)
) sens_sync_i (
.rst (rst), // input
.pclk (pclk), // input
.mclk (), // input
.en(), // input
.sof_in (sof), // input
.eof_in (eof), // input
.hact (hact), // input
.trigger_mode (trigger_mode), // input
.trig_in (trig_in), // input
.trig (trig), // output
.sof_out_pclk (sof_out_sync), // output reg
.sof_out (sof_out_mclk), // output
.sof_late (sof_late_mclk), // output
.cmd_ad (cmd_ad), // input[7:0]
.cmd_stb (cmd_stb) // input
);
sens_gamma #( sens_gamma #(
.SENS_GAMMA_NUM_CHN (SENS_GAMMA_NUM_CHN), .SENS_GAMMA_NUM_CHN (SENS_GAMMA_NUM_CHN),
.SENS_GAMMA_BUFFER (SENS_GAMMA_BUFFER), .SENS_GAMMA_BUFFER (SENS_GAMMA_BUFFER),
......
...@@ -54,7 +54,15 @@ module sensors393 #( ...@@ -54,7 +54,15 @@ module sensors393 #(
parameter SENSI2C_CTRL = 'h0, parameter SENSI2C_CTRL = 'h0,
parameter SENSI2C_STATUS = 'h1, parameter SENSI2C_STATUS = 'h1,
parameter SENS_GAMMA_RADDR = 4, parameter SENS_SYNC_RADDR = 'h4,
parameter SENS_SYNC_MASK = 'h7fc,
// 2 locations reserved for control/status (if they will be needed)
parameter SENS_SYNC_MULT = 'h2, // relative register address to write number of frames to combine in one (minus 1, '0' - each farme)
parameter SENS_SYNC_LATE = 'h3, // number of lines to delay late frame sync
parameter SENS_GAMMA_RADDR = 'h38, // 'h38..'h3b was 4,
parameter SENS_GAMMA_ADDR_MASK = 'h7fc, parameter SENS_GAMMA_ADDR_MASK = 'h7fc,
// sens_gamma registers // sens_gamma registers
parameter SENS_GAMMA_CTRL = 'h0, parameter SENS_GAMMA_CTRL = 'h0,
...@@ -128,6 +136,13 @@ module sensors393 #( ...@@ -128,6 +136,13 @@ module sensors393 #(
parameter HIST_SAXI_MODE_ADDR_MASK = 'h7ff, parameter HIST_SAXI_MODE_ADDR_MASK = 'h7ff,
parameter NUM_FRAME_BITS = 4, // number of bits use for frame number parameter NUM_FRAME_BITS = 4, // number of bits use for frame number
// Other parameters
parameter SENS_SYNC_FBITS = 16, // number of bits in a frame counter for linescan mode
parameter SENS_SYNC_LBITS = 16, // number of bits in a line counter for sof_late output (limited by eof)
parameter SENS_SYNC_LATE_DFLT = 15, // number of lines to delay late frame sync
parameter SENS_SYNC_MINBITS = 8, // number of bits to enforce minimal frame period
parameter SENS_SYNC_MINPER = 130, // minimal frame period (in pclk/mclk?)
// sens_parallel12 other parameters // sens_parallel12 other parameters
...@@ -230,6 +245,15 @@ module sensors393 #( ...@@ -230,6 +245,15 @@ module sensors393 #(
output [63:0] buf_dout3, // data out output [63:0] buf_dout3, // data out
// Lower bits of frame numbers to use with the histograms, get from the sequencers // Lower bits of frame numbers to use with the histograms, get from the sequencers
// trigger inputs
input trigger_mode, // common to all sensors - running in triggered mode (0 - free running mode)
input [3:0] trig_in, // per-sensor trigger input
output [3:0] sof_out_pclk, // @ pclk start of frame
output [3:0] eof_out_pclk, // @ pclk end of frame
output [3:0] sof_out_mclk, // @ mclk start of frame - use to run sequencer, so register writes should be before compressor start
output [3:0] sof_late_mclk,// @ mclk start of frame, delayed (use to start compressor and interrupts)
input [NUM_FRAME_BITS-1:0] frame_num0, input [NUM_FRAME_BITS-1:0] frame_num0,
input [NUM_FRAME_BITS-1:0] frame_num1, input [NUM_FRAME_BITS-1:0] frame_num1,
input [NUM_FRAME_BITS-1:0] frame_num2, input [NUM_FRAME_BITS-1:0] frame_num2,
...@@ -263,67 +287,6 @@ module sensors393 #( ...@@ -263,67 +287,6 @@ module sensors393 #(
input [ 1:0] saxi_bresp // AXI PS Slave GP0 BRESP[1:0], output input [ 1:0] saxi_bresp // AXI PS Slave GP0 BRESP[1:0], output
); );
// parameter SENSOR_GROUP_ADDR = 'h300; // sensor registers base address
/*
localparam SENSOR_CTRL_ADDR = SENSOR_GROUP_ADDR + SENSOR_CTRL_RADDR; // 'h300
localparam SENSI2C_CTRL_ADDR = SENSOR_GROUP_ADDR + SENSI2C_CTRL_RADDR; // 'h302..'h303
localparam SENS_GAMMA_ADDR = SENSOR_GROUP_ADDR + SENS_GAMMA_RADDR; // 'h304..'h307
localparam SENSIO_ADDR = SENSOR_GROUP_ADDR + SENSIO_RADDR; // 'h308 .. 'h30c
localparam SENSI2C_ABS_ADDR = SENSOR_GROUP_ADDR + SENSI2C_ABS_RADDR; // 'h310..'h31f
localparam SENSI2C_REL_ADDR = SENSOR_GROUP_ADDR + SENSI2C_REL_RADDR; // 'h320..'h32f
localparam HISTOGRAM_ADDR0 = (SENSOR_NUM_HISTOGRAM > 0)?(SENSOR_GROUP_ADDR + HISTOGRAM_RADDR0):-1; //
localparam HISTOGRAM_ADDR1 = (SENSOR_NUM_HISTOGRAM > 1)?(SENSOR_GROUP_ADDR + HISTOGRAM_RADDR1):-1; //
localparam HISTOGRAM_ADDR2 = (SENSOR_NUM_HISTOGRAM > 2)?(SENSOR_GROUP_ADDR + HISTOGRAM_RADDR2):-1; //
localparam HISTOGRAM_ADDR3 = (SENSOR_NUM_HISTOGRAM > 3)?(SENSOR_GROUP_ADDR + HISTOGRAM_RADDR3):-1; //
output [15:0] dout, // @posedge pclk
output dout_valid, // in 8-bit mode continues pixel flow have dout_valid alternating on/off
output last_in_line, // valid with dout_valid - last in line dout
output sof_out, // start of frame 1-clk pulse with the same delays as output data
output eof_out, // end of frame 1-clk pulse with the same delays as output data
// histogram interface to S_AXI, 256x32bit continuous bursts @posedge mclk, each histogram having 4 bursts
output hist_request, // request to transfer a burst
input hist_grant, // request to transfer over S_AXI granted
output [1:0] hist_chn, // output[1:0] histogram (sub) channel, valid with request and transfer
output hist_dvalid, // output data valid - active when sending a burst
output [31:0] hist_data // output[31:0] histogram data
.rst (rst), // input
.pclk (), // input
.pclk2x (), // input
.sns_dp (), // inout[7:0]
.sns_dn (), // inout[7:0]
.sns_clkp (), // inout
.sns_clkn (), // inout
.sns_scl (), // inout
.sns_sda (), // inout
.sns_ctl (), // inout
.sns_pg (), // inout
.mclk (), // input
.cmd_ad_in (), // input[7:0]
.cmd_stb_in (), // input
.status_ad (), // output[7:0]
.status_rq (), // output
.status_start (), // input
.dout (), // output[15:0]
.dout_valid (), // output
.last_in_line (), // output
.sof_out (), // output
.eof_out (), // output
.hist_request (), // output
.hist_grant (), // input
.hist_chn (), // output[1:0]
.hist_dvalid (), // output
.hist_data () // output[31:0]
*/
// reg [1:0] wpage;
// wire pclk;
/// localparam FRAME_NUM_WIDTH = 32; // decide wher to keep the frame counter or get them from sequencer modules
/// wire [FRAME_NUM_WIDTH-1:0] frame_num;
// wire [NUM_FRAME_BITS-1:0] frame_num4[0:3]; // low 4 bits from the frame numbers
wire [3:0] rpage_set = {rpage_set3, rpage_set2, rpage_set1, rpage_set0}; // set internal read page to rpage_in (reset pointers) wire [3:0] rpage_set = {rpage_set3, rpage_set2, rpage_set1, rpage_set0}; // set internal read page to rpage_in (reset pointers)
...@@ -340,8 +303,6 @@ module sensors393 #( ...@@ -340,8 +303,6 @@ module sensors393 #(
wire [15:0] px_data[0:3]; wire [15:0] px_data[0:3];
wire [3:0] px_valid; wire [3:0] px_valid;
wire [3:0] last_in_line; wire [3:0] last_in_line;
wire [3:0] sof_out;
wire [3:0] eof_out;
wire [3:0] hist_request; wire [3:0] hist_request;
wire [3:0] hist_grant; wire [3:0] hist_grant;
wire [1:0] hist_chn[0:3]; wire [1:0] hist_chn[0:3];
...@@ -362,7 +323,7 @@ module sensors393 #( ...@@ -362,7 +323,7 @@ module sensors393 #(
generate generate
genvar i; genvar i;
for (i=0; i < 8; i=i+1) begin: sencor_channel_block for (i=0; i < 4; i=i+1) begin: sencor_channel_block
sensor_channel #( sensor_channel #(
.SENSOR_NUMBER (i), .SENSOR_NUMBER (i),
.SENSOR_GROUP_ADDR (SENSOR_GROUP_ADDR), .SENSOR_GROUP_ADDR (SENSOR_GROUP_ADDR),
...@@ -371,6 +332,15 @@ module sensors393 #( ...@@ -371,6 +332,15 @@ module sensors393 #(
.SENSI2C_STATUS_REG_INC (SENSI2C_STATUS_REG_INC), .SENSI2C_STATUS_REG_INC (SENSI2C_STATUS_REG_INC),
.SENSI2C_STATUS_REG_REL (SENSI2C_STATUS_REG_REL), .SENSI2C_STATUS_REG_REL (SENSI2C_STATUS_REG_REL),
.SENSIO_STATUS_REG_REL (SENSIO_STATUS_REG_REL), .SENSIO_STATUS_REG_REL (SENSIO_STATUS_REG_REL),
.SENS_SYNC_RADDR (SENS_SYNC_RADDR),
.SENS_SYNC_MASK (SENS_SYNC_MASK),
.SENS_SYNC_MULT (SENS_SYNC_MULT),
.SENS_SYNC_LATE (SENS_SYNC_LATE),
.SENS_SYNC_FBITS (SENS_SYNC_FBITS),
.SENS_SYNC_LBITS (SENS_SYNC_LBITS),
.SENS_SYNC_LATE_DFLT (SENS_SYNC_LATE_DFLT),
.SENS_SYNC_MINBITS (SENS_SYNC_MINBITS),
.SENS_SYNC_MINPER (SENS_SYNC_MINPER),
.SENSOR_NUM_HISTOGRAM (SENSOR_NUM_HISTOGRAM), .SENSOR_NUM_HISTOGRAM (SENSOR_NUM_HISTOGRAM),
.HISTOGRAM_RAM_MODE (HISTOGRAM_RAM_MODE), .HISTOGRAM_RAM_MODE (HISTOGRAM_RAM_MODE),
.SENS_GAMMA_NUM_CHN (SENS_GAMMA_NUM_CHN), .SENS_GAMMA_NUM_CHN (SENS_GAMMA_NUM_CHN),
...@@ -474,11 +444,16 @@ module sensors393 #( ...@@ -474,11 +444,16 @@ module sensors393 #(
.status_ad (status_ad_chn[i]), // output[7:0] .status_ad (status_ad_chn[i]), // output[7:0]
.status_rq (status_rq_chn[i]), // output .status_rq (status_rq_chn[i]), // output
.status_start (status_start_chn[i]), // input .status_start (status_start_chn[i]), // input
.trigger_mode (trigger_mode), // input
.trig_in (trig_in[i]), // input
.dout (px_data[i]), // output[15:0] .dout (px_data[i]), // output[15:0]
.dout_valid (px_valid[i]), // output .dout_valid (px_valid[i]), // output
.last_in_line (last_in_line[i]), // output .last_in_line (last_in_line[i]), // output
.sof_out (sof_out[i]), // output .sof_out (sof_out_pclk[i]), // output
.eof_out (eof_out[i]), // output .eof_out (eof_out_pclk[i]), // output
.sof_out_mclk (sof_out_mclk[i]), // output
.sof_late_mclk(sof_late_mclk[i]), // output
.hist_request (hist_request[i]), // output .hist_request (hist_request[i]), // output
.hist_grant (hist_grant[i]), // input .hist_grant (hist_grant[i]), // input
.hist_chn (hist_chn[i]), // output[1:0] .hist_chn (hist_chn[i]), // output[1:0]
......
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