Commit 428053b8 authored by Andrey Filippov's avatar Andrey Filippov

reated a top module for all timestamp/synchroniztion functionality

parent 2675a8a1
...@@ -27,7 +27,8 @@ ...@@ -27,7 +27,8 @@
// TODO: make a separate clock for transmission (program counters too?) and/or for the period timer? // TODO: make a separate clock for transmission (program counters too?) and/or for the period timer?
// TODO: change timestamp to serial message // TODO: change timestamp to serial message
// TODO: see what depends on pclk and if can be made independent of the sensor clock. // TODO: see what depends on pclk and if can be made independent of the sensor clock.
//`define GENERATE_TRIG_OVERDUE 1
`undef GENERATE_TRIG_OVERDUE
module camsync393 #( module camsync393 #(
parameter CAMSYNC_ADDR = 'h160, //TODO: assign valid address parameter CAMSYNC_ADDR = 'h160, //TODO: assign valid address
parameter CAMSYNC_MASK = 'h3f8, parameter CAMSYNC_MASK = 'h3f8,
...@@ -81,26 +82,30 @@ module camsync393 #( ...@@ -81,26 +82,30 @@ module camsync393 #(
output triggered_mode, // use triggered mode (0 - sensors are free-running) @mclk output triggered_mode, // use triggered mode (0 - sensors are free-running) @mclk
input frsync_chn0, // @mclk trigrst, // single-clock start of frame input (resets trigger output) posedge (@pclk) input frsync_chn0, // @mclk trigrst, // single-clock start of frame input (resets trigger output) posedge (@pclk)
output trigger1_chn0, // @mclk 1 cycle-long trigger output output trig_chn0, // @mclk 1 cycle-long trigger output
`ifdef GENERATE_TRIG_OVERDUE
output trigger_chn0, // @mclk active high trigger to the sensor (reset by vacts) output trigger_chn0, // @mclk active high trigger to the sensor (reset by vacts)
output overdue_chn0, // @mclk prevents lock-up when no vact was detected during one period and trigger was toggled output overdue_chn0, // @mclk prevents lock-up when no vact was detected during one period and trigger was toggled
`endif
input frsync_chn1, // @mclk trigrst, // single-clock start of frame input (resets trigger output) posedge (@pclk) input frsync_chn1, // @mclk trigrst, // single-clock start of frame input (resets trigger output) posedge (@pclk)
output trigger1_chn1, // 1 cycle-long trigger output output trig_chn1, // 1 cycle-long trigger output
`ifdef GENERATE_TRIG_OVERDUE
output trigger_chn1, // active high trigger to the sensor (reset by vacts) output trigger_chn1, // active high trigger to the sensor (reset by vacts)
output overdue_chn1, // prevents lock-up when no vact was detected during one period and trigger was toggled output overdue_chn1, // prevents lock-up when no vact was detected during one period and trigger was toggled
`endif
input frsync_chn2, // @mclk trigrst, // single-clock start of frame input (resets trigger output) posedge (@pclk) input frsync_chn2, // @mclk trigrst, // single-clock start of frame input (resets trigger output) posedge (@pclk)
output trigger1_chn2, // 1 cycle-long trigger output output trig_chn2, // 1 cycle-long trigger output
output trigger_chn2, // active high trigger to the sensor (reset by vacts) `ifdef GENERATE_TRIG_OVERDUE
output overdue_chn2, // prevents lock-up when no vact was detected during one period and trigger was toggled output trigger_chn2, // active high trigger to the sensor (reset by vacts)
output overdue_chn2, // prevents lock-up when no vact was detected during one period and trigger was toggled
`endif
input frsync_chn3, // @mclk trigrst, // single-clock start of frame input (resets trigger output) posedge (@pclk) input frsync_chn3, // @mclk trigrst, // single-clock start of frame input (resets trigger output) posedge (@pclk)
output trigger1_chn3, // 1 cycle-long trigger output output trig_chn3, // 1 cycle-long trigger output
output trigger_chn3, // active high trigger to the sensor (reset by vacts) `ifdef GENERATE_TRIG_OVERDUE
output overdue_chn3, // prevents lock-up when no vact was detected during one period and trigger was toggled output trigger_chn3, // active high trigger to the sensor (reset by vacts)
output overdue_chn3, // prevents lock-up when no vact was detected during one period and trigger was toggled
`endif
// getting timestamp from rtc module, all @posedge mclk (from timestmp_snapshot) // getting timestamp from rtc module, all @posedge mclk (from timestmp_snapshot)
// this timestmp is used either to send local timestamp for synchronization, or // this timestmp is used either to send local timestamp for synchronization, or
// to acquire local timestamp of sync pulse for logging // to acquire local timestamp of sync pulse for logging
...@@ -216,10 +221,13 @@ module camsync393 #( ...@@ -216,10 +221,13 @@ module camsync393 #(
reg trigger_condition_d; // GPIO input trigger condition met, delayed (for edge detection) reg trigger_condition_d; // GPIO input trigger condition met, delayed (for edge detection)
reg trigger_condition_filtered; // trigger condition filtered reg trigger_condition_filtered; // trigger condition filtered
reg [6:0] trigger_filter_cntr; reg [6:0] trigger_filter_cntr;
reg [3:0] trigger1_r; reg [3:0] trig_r;
wire [3:0] trigger1_r_mclk; wire [3:0] trig_r_mclk;
// wire trigger1_dly16; // trigger1 delayed by 16 clk cycles to get local timestamp // wire trig_dly16; // trigger1 delayed by 16 clk cycles to get local timestamp
`ifdef GENERATE_TRIG_OVERDUE
reg [3:0] trigger_r=0; // for happy simulator reg [3:0] trigger_r=0; // for happy simulator
reg [3:0] overdue;
`endif
reg start_dly; // start delay (external input filtered or from internal single/rep) reg start_dly; // start delay (external input filtered or from internal single/rep)
reg [31:0] dly_cntr_chn0; // trigger delay counter reg [31:0] dly_cntr_chn0; // trigger delay counter
reg [31:0] dly_cntr_chn1; // trigger delay counter reg [31:0] dly_cntr_chn1; // trigger delay counter
...@@ -276,7 +284,6 @@ module camsync393 #( ...@@ -276,7 +284,6 @@ module camsync393 #(
wire [3:0] frame_sync; wire [3:0] frame_sync;
reg [3:0] ts_snap_triggered; // make a timestamp pulse single @(posedge pclk) reg [3:0] ts_snap_triggered; // make a timestamp pulse single @(posedge pclk)
wire [3:0] ts_snap_triggered_mclk; // make a timestamp pulse single @(posedge pclk) wire [3:0] ts_snap_triggered_mclk; // make a timestamp pulse single @(posedge pclk)
reg [3:0] overdue;
//! in testmode GPIO[9] and GPIO[8] use internal signals instead of the outsync: //! in testmode GPIO[9] and GPIO[8] use internal signals instead of the outsync:
//! bit 11 - same as TRIGGER output to the sensor (signal to the sensor may be disabled externally) //! bit 11 - same as TRIGGER output to the sensor (signal to the sensor may be disabled externally)
//! then that bit will be still from internall trigger to frame valid //! then that bit will be still from internall trigger to frame valid
...@@ -290,17 +297,23 @@ module camsync393 #( ...@@ -290,17 +297,23 @@ module camsync393 #(
assign gpio_out[7: 0] = out_data? gpio_active[7: 0]: ~gpio_active[7: 0]; assign gpio_out[7: 0] = out_data? gpio_active[7: 0]: ~gpio_active[7: 0];
assign gpio_out[8] = (testmode? dly_cntr_run[0]: out_data)? gpio_active[8]: ~gpio_active[8]; assign gpio_out[8] = (testmode? dly_cntr_run[0]: out_data)? gpio_active[8]: ~gpio_active[8];
`ifdef GENERATE_TRIG_OVERDUE
assign gpio_out[9] = (testmode? trigger_r[0]: out_data)? gpio_active[9]: ~gpio_active[9]; assign gpio_out[9] = (testmode? trigger_r[0]: out_data)? gpio_active[9]: ~gpio_active[9];
`else
assign gpio_out[9] = (out_data)? gpio_active[9]: ~gpio_active[9];
`endif
assign restart= restart_cntr_run[1] && !restart_cntr_run[0]; assign restart= restart_cntr_run[1] && !restart_cntr_run[0];
assign pre_set_bit= (|cmd_data[31:8]==0) && |cmd_data[7:1]; // 2..255 assign pre_set_bit= (|cmd_data[31:8]==0) && |cmd_data[7:1]; // 2..255
assign pre_start0= |cmd_data[31:0] && !pre_set_bit; assign pre_start0= |cmd_data[31:0] && !pre_set_bit;
assign pre_set_period = !pre_set_bit; assign pre_set_period = !pre_set_bit;
assign {trig_chn3, trig_chn2, trig_chn1, trig_chn0} = trig_r_mclk;
`ifdef GENERATE_TRIG_OVERDUE
assign {trigger_chn3, trigger_chn2, trigger_chn1, trigger_chn0} = trigger_r; assign {trigger_chn3, trigger_chn2, trigger_chn1, trigger_chn0} = trigger_r;
assign {trigger1_chn3, trigger1_chn2, trigger1_chn1, trigger1_chn0} = trigger1_r_mclk;
assign {overdue_chn3, overdue_chn2, overdue_chn1, overdue_chn0} = overdue; assign {overdue_chn3, overdue_chn2, overdue_chn1, overdue_chn0} = overdue;
`endif
assign frame_sync = {frsync_chn3, frsync_chn2, frsync_chn1, frsync_chn0}; assign frame_sync = {frsync_chn3, frsync_chn2, frsync_chn1, frsync_chn0};
assign set_mode_reg_w = cmd_we && (cmd_a == CAMSYNC_MODE); assign set_mode_reg_w = cmd_we && (cmd_a == CAMSYNC_MODE);
...@@ -394,7 +407,7 @@ module camsync393 #( ...@@ -394,7 +407,7 @@ module camsync393 #(
end end
always @ (posedge pclk) begin always @ (posedge pclk) begin
ts_snap_triggered <= chn_en & ({4{(start_pclk[2] & ts_snd_en_pclk)}} | //strobe by internal generator if output timestamp is enabled ts_snap_triggered <= chn_en & ({4{(start_pclk[2] & ts_snd_en_pclk)}} | //strobe by internal generator if output timestamp is enabled
(trigger1_r & ~{4{ts_external_pclk}})); // get local timestamp of the trigger (ext/int) (trig_r & ~{4{ts_external_pclk}})); // get local timestamp of the trigger (ext/int)
ts_snd_en_pclk<=ts_snd_en; ts_snd_en_pclk<=ts_snd_en;
input_use_intern <= pre_input_use_intern; input_use_intern <= pre_input_use_intern;
...@@ -443,23 +456,24 @@ module camsync393 #( ...@@ -443,23 +456,24 @@ module camsync393 #(
(dly_cntr_chn0[31:0]!=0)?1'b1:1'b0}; (dly_cntr_chn0[31:0]!=0)?1'b1:1'b0};
end end
always @ (posedge rst or posedge mclk) begin `ifdef GENERATE_TRIG_OVERDUE
always @ (posedge rst or posedge mclk) begin
if (rst) trigger_r <= 0; if (rst) trigger_r <= 0;
else if (!triggered_mode) trigger_r <= 0; else if (!triggered_mode) trigger_r <= 0;
else trigger_r <= ~frame_sync & (trigger1_r_mclk ^ trigger_r); else trigger_r <= ~frame_sync & (trig_r_mclk ^ trigger_r);
if (rst) overdue <= 0; if (rst) overdue <= 0;
else if (!triggered_mode) overdue <= 0; else if (!triggered_mode) overdue <= 0;
else overdue <= ((overdue ^ trigger_r) & trigger1_r_mclk) ^ overdue; else overdue <= ((overdue ^ trigger_r) & trig_r_mclk) ^ overdue;
end end
`endif
// Detecting input sync pulse (filter - 64 pclk, pulse is 256 pclk) // Detecting input sync pulse (filter - 64 pclk, pulse is 256 pclk)
/// Now trigger1_r toggles trigger output to prevent lock-up if no vacts /// Now trig_r toggles trigger output to prevent lock-up if no vacts
/// Lock-up could take place if: /// Lock-up could take place if:
/// 1 - Sensoris in snapshot mode /// 1 - Sensor is in snapshot mode
/// 2 - trigger was applied before end of previous frame. /// 2 - trigger was applied before end of previous frame.
/// With implemented toggling 1 extra pulse can be missed (2 with the original missed one), but the system will not lock-up /// With implemented toggling 1 extra pulse can be missed (2 with the original missed one), but the system will not lock-up
/// if the trigger pulses continue to come. /// if the trigger pulses continue to come.
...@@ -500,11 +514,11 @@ module camsync393 #( ...@@ -500,11 +514,11 @@ module camsync393 #(
if (dly_cntr_run[3]) dly_cntr_chn3[31:0] <= dly_cntr_chn3[31:0] -1; if (dly_cntr_run[3]) dly_cntr_chn3[31:0] <= dly_cntr_chn3[31:0] -1;
else dly_cntr_chn3[31:0] <= input_dly_chn3[31:0]; else dly_cntr_chn3[31:0] <= input_dly_chn3[31:0];
/// bypass delay to trigger1_r in internal trigger mode /// bypass delay to trig_r in internal trigger mode
trigger1_r[0] <= (input_use_intern && (master_chn ==0)) ? (start_late && start_en):(dly_cntr_run_d[0] && !dly_cntr_run[0]); trig_r[0] <= (input_use_intern && (master_chn ==0)) ? (start_late && start_en):(dly_cntr_run_d[0] && !dly_cntr_run[0]);
trigger1_r[1] <= (input_use_intern && (master_chn ==1)) ? (start_late && start_en):(dly_cntr_run_d[1] && !dly_cntr_run[1]); trig_r[1] <= (input_use_intern && (master_chn ==1)) ? (start_late && start_en):(dly_cntr_run_d[1] && !dly_cntr_run[1]);
trigger1_r[2] <= (input_use_intern && (master_chn ==2)) ? (start_late && start_en):(dly_cntr_run_d[2] && !dly_cntr_run[2]); trig_r[2] <= (input_use_intern && (master_chn ==2)) ? (start_late && start_en):(dly_cntr_run_d[2] && !dly_cntr_run[2]);
trigger1_r[3] <= (input_use_intern && (master_chn ==3)) ? (start_late && start_en):(dly_cntr_run_d[3] && !dly_cntr_run[3]); trig_r[3] <= (input_use_intern && (master_chn ==3)) ? (start_late && start_en):(dly_cntr_run_d[3] && !dly_cntr_run[3]);
/// 64-bit serial receiver (52 bit payload, 6 pre magic and 6 bits post magic for error checking /// 64-bit serial receiver (52 bit payload, 6 pre magic and 6 bits post magic for error checking
if (!rcv_run_or_deaf) bit_rcv_duration[7:0] <= bit_length_short[7:0]; // 3/4 bit length-1 if (!rcv_run_or_deaf) bit_rcv_duration[7:0] <= bit_length_short[7:0]; // 3/4 bit length-1
...@@ -663,10 +677,10 @@ module camsync393 #( ...@@ -663,10 +677,10 @@ module camsync393 #(
pulse_cross_clock i_local_got_pclk2(.rst(1'b0), .src_clk(mclk), .dst_clk(pclk), .in_pulse(local_got[2]), .out_pulse(local_got_pclk[2]),.busy()); pulse_cross_clock i_local_got_pclk2(.rst(1'b0), .src_clk(mclk), .dst_clk(pclk), .in_pulse(local_got[2]), .out_pulse(local_got_pclk[2]),.busy());
pulse_cross_clock i_local_got_pclk3(.rst(1'b0), .src_clk(mclk), .dst_clk(pclk), .in_pulse(local_got[3]), .out_pulse(local_got_pclk[3]),.busy()); pulse_cross_clock i_local_got_pclk3(.rst(1'b0), .src_clk(mclk), .dst_clk(pclk), .in_pulse(local_got[3]), .out_pulse(local_got_pclk[3]),.busy());
pulse_cross_clock i_trigger1_r_mclk0 (.rst(1'b0), .src_clk(pclk), .dst_clk(mclk), .in_pulse(trigger1_r[0]), .out_pulse(trigger1_r_mclk[0]),.busy()); pulse_cross_clock i_trig_r_mclk0 (.rst(1'b0), .src_clk(pclk), .dst_clk(mclk), .in_pulse(trig_r[0]), .out_pulse(trig_r_mclk[0]),.busy());
pulse_cross_clock i_trigger1_r_mclk1 (.rst(1'b0), .src_clk(pclk), .dst_clk(mclk), .in_pulse(trigger1_r[1]), .out_pulse(trigger1_r_mclk[1]),.busy()); pulse_cross_clock i_trig_r_mclk1 (.rst(1'b0), .src_clk(pclk), .dst_clk(mclk), .in_pulse(trig_r[1]), .out_pulse(trig_r_mclk[1]),.busy());
pulse_cross_clock i_trigger1_r_mclk2 (.rst(1'b0), .src_clk(pclk), .dst_clk(mclk), .in_pulse(trigger1_r[2]), .out_pulse(trigger1_r_mclk[2]),.busy()); pulse_cross_clock i_trig_r_mclk2 (.rst(1'b0), .src_clk(pclk), .dst_clk(mclk), .in_pulse(trig_r[2]), .out_pulse(trig_r_mclk[2]),.busy());
pulse_cross_clock i_trigger1_r_mclk3 (.rst(1'b0), .src_clk(pclk), .dst_clk(mclk), .in_pulse(trigger1_r[3]), .out_pulse(trigger1_r_mclk[3]),.busy()); pulse_cross_clock i_trig_r_mclk3 (.rst(1'b0), .src_clk(pclk), .dst_clk(mclk), .in_pulse(trig_r[3]), .out_pulse(trig_r_mclk[3]),.busy());
endmodule endmodule
...@@ -23,13 +23,17 @@ ...@@ -23,13 +23,17 @@
`timescale 1ns/1ps `timescale 1ns/1ps
module rtc393 #( module rtc393 #(
parameter RTC_ADDR= 'h170, //TODO: assign valid address parameter RTC_ADDR = 'h170, //TODO: assign valid address
parameter RTC_MASK= 'h3fc, parameter RTC_STATUS_REG_ADDR = 7, // address where status can be read out (currnelti just sequence # and alternating bit)
parameter RTC_MHZ= 25, // RTC input clock in MHz (should be interger number) parameter RTC_SEC_USEC_ADDR = 8, // address where seconds of the snapshot can be read (microseconds - next adderss)
parameter RTC_MASK = 'h3fc,
parameter RTC_MHZ = 25, // RTC input clock in MHz (should be interger number)
parameter RTC_BITC_PREDIV = 5, // number of bits to generate 2 MHz pulses counting refclk parameter RTC_BITC_PREDIV = 5, // number of bits to generate 2 MHz pulses counting refclk
parameter RTC_SET_USEC= 0, // 20-bit number of microseconds parameter RTC_SET_USEC = 0, // 20-bit number of microseconds
parameter RTC_SET_SEC= 1, // 32-bit full number of seconds (und actually update timer) parameter RTC_SET_SEC = 1, // 32-bit full number of seconds (und actually update timer)
parameter RTC_SET_CORR= 2 // write correction 16-bit signed parameter RTC_SET_CORR = 2, // write correction 16-bit signed
parameter RTC_SET_STATUS = 3 // set status mode, and take a time snapshot (wait response and read time)
) ( ) (
input rst, input rst,
...@@ -38,9 +42,14 @@ module rtc393 #( ...@@ -38,9 +42,14 @@ module rtc393 #(
// programming interface // programming interface
input [7:0] cmd_ad, // byte-serial command address/data (up to 6 bytes: AL-AH-D0-D1-D2-D3 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 cmd_stb, // 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 [31:0] live_sec, output [31:0] live_sec,
output [19:0] live_usec); output [19:0] live_usec);
// output reg snap); // take a snapshot (externally)
wire [31:0] cmd_data; wire [31:0] cmd_data;
wire [2:0] cmd_a; wire [2:0] cmd_a;
...@@ -49,6 +58,7 @@ module rtc393 #( ...@@ -49,6 +58,7 @@ module rtc393 #(
wire set_usec_w; wire set_usec_w;
wire set_sec_w; wire set_sec_w;
wire set_corr_w; wire set_corr_w;
wire set_status_w;
reg [19:0] wusec; reg [19:0] wusec;
reg [31:0] wsec; reg [31:0] wsec;
...@@ -72,20 +82,34 @@ module rtc393 #( ...@@ -72,20 +82,34 @@ module rtc393 #(
reg [19:0] usec_plus1; reg [19:0] usec_plus1;
reg [31:0] sec_plus1; reg [31:0] sec_plus1;
reg [31:0] pio_sec; // seconds snapshot to be read as PIO
reg [19:0] pio_usec; // micro seconds snapshot to be read as PIO
reg pio_alt_snap; // FF to invert after each PIO snapshot (used to generate status)
assign set_usec_w = cmd_we && (cmd_a == RTC_SET_USEC); assign set_usec_w = cmd_we && (cmd_a == RTC_SET_USEC);
assign set_sec_w = cmd_we && (cmd_a == RTC_SET_SEC); assign set_sec_w = cmd_we && (cmd_a == RTC_SET_SEC);
assign set_corr_w = cmd_we && (cmd_a == RTC_SET_CORR); assign set_corr_w = cmd_we && (cmd_a == RTC_SET_CORR);
assign set_status_w = cmd_we && (cmd_a == RTC_SET_STATUS);
assign next_acc[24:0]= {1'b0,acc[23:0]} + {1'b0,~corr [15], {7{corr [15]}}, corr[15:0]}; assign next_acc[24:0]= {1'b0,acc[23:0]} + {1'b0,~corr [15], {7{corr [15]}}, corr[15:0]};
assign live_sec = sec; assign live_sec = sec;
assign live_usec = usec; assign live_usec = usec;
always @ (posedge rst or posedge mclk) begin
if (rst) pio_alt_snap <= 0;
else if (set_status_w) pio_alt_snap <= ~pio_alt_snap;
end
always @ (posedge mclk) begin
if (set_status_w) pio_sec <= live_sec;
if (set_status_w) pio_usec <= live_usec;
end
always @ (posedge mclk) begin always @ (posedge mclk) begin
if (set_usec_w) wusec <= cmd_data[19:0]; if (set_usec_w) wusec <= cmd_data[19:0];
if (set_sec_w) wsec <= cmd_data[31:0]; if (set_sec_w) wsec <= cmd_data[31:0];
if (set_corr_w) corr <= cmd_data[15:0]; if (set_corr_w) corr <= cmd_data[15:0];
end end
always @ (posedge rst or posedge mclk) begin always @ (posedge rst or posedge mclk) begin
...@@ -145,6 +169,25 @@ module rtc393 #( ...@@ -145,6 +169,25 @@ module rtc393 #(
.data (cmd_data), // output[31:0] .data (cmd_data), // output[31:0]
.we (cmd_we) // output .we (cmd_we) // output
); );
status_generate #(
.STATUS_REG_ADDR (RTC_STATUS_REG_ADDR),
.PAYLOAD_BITS (1),
.REGISTER_STATUS (0),
.EXTRA_WORDS (2),
.EXTRA_REG_ADDR (RTC_SEC_USEC_ADDR)
) status_generate_i (
.rst (), // input
.clk (mclk), // input
.we (set_status_w), // input
.wd (cmd_data[7:0]), // input[7:0]
.status ({12'b0,pio_usec,pio_sec,pio_alt_snap}), // input[14:0]
.ad (status_ad), // output[7:0]
.rq (status_rq), // output
.start (status_start) // input
);
endmodule endmodule
/*******************************************************************************
* Module: timing393
* Date:2015-07-05
* Author: andrey
* Description: timestamp realrted functionality, extrenal synchronization
*
* Copyright (c) 2015 <set up in Preferences-Verilog/VHDL Editor-Templates> .
* timing393.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.
*
* timing393.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 timing393 #(
parameter CAMSYNC_ADDR = 'h160, //TODO: assign valid address
parameter RTC_ADDR= 'h170, //TODO: assign valid address
parameter RTC_STATUS_REG_ADDR = 7, // address where status can be read out (currnelti just sequence # and alternating bit)
parameter RTC_SEC_USEC_ADDR = 8, // address where seconds of the snapshot can be read (microseconds - next adderss)
parameter CAMSYNC_MASK = 'h3f8,
parameter RTC_MASK= 'h3fc,
parameter CAMSYNC_MODE = 'h0,
parameter CAMSYNC_TRIG_SRC = 'h1, // setup trigger source
parameter CAMSYNC_TRIG_DST = 'h2, // setup trigger destination line(s)
parameter CAMSYNC_TRIG_PERIOD = 'h3, // setup output trigger period
parameter CAMSYNC_TRIG_DELAY0 = 'h4, // setup input trigger delay
parameter CAMSYNC_TRIG_DELAY1 = 'h5, // setup input trigger delay
parameter CAMSYNC_TRIG_DELAY2 = 'h6, // setup input trigger delay
parameter CAMSYNC_TRIG_DELAY3 = 'h7, // setup input trigger delay
parameter CAMSYNC_SNDEN_BIT = 'h1, // enable writing ts_snd_en
parameter CAMSYNC_EXTERNAL_BIT = 'h3, // enable writing ts_external
parameter CAMSYNC_TRIGGERED_BIT = 'h5, // enable writing ts_external
parameter CAMSYNC_MASTER_BIT = 'h8, // select a 2-bit master channel (master delay may be used as a flash delay)
parameter CAMSYNC_CHN_EN_BIT = 'hd, // per-channel enable timestamp generation
parameter CAMSYNC_PRE_MAGIC = 6'b110100,
parameter CAMSYNC_POST_MAGIC = 6'b001101,
parameter RTC_MHZ= 25, // RTC input clock in MHz (should be interger number)
parameter RTC_BITC_PREDIV = 5, // number of bits to generate 2 MHz pulses counting refclk
parameter RTC_SET_USEC= 0, // 20-bit number of microseconds
parameter RTC_SET_SEC= 1, // 32-bit full number of seconds (und actually update timer)
parameter RTC_SET_CORR= 2, // write correction 16-bit signed
parameter RTC_SET_STATUS= 3 // generate an output pulse to take a snapshot
)(
input rst, // global reset
input mclk, // system clock
input pclk, // pixel clock (global) - switch it to 100MHz (mclk/2)?
input refclk, // not a global clock, reference frequency < mclk/2
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
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)
// connection to the general purpose I/O control
input [9:0] gpio_in, // 12-bit input from GPIO pins -> 10 bit
output [9:0] gpio_out,// 12-bit output to GPIO pins
output [9:0] gpio_out_en,// 12-bit output enable to GPIO pins
// common for all sensors - use triggered mode (as opposed to a free-running mode)
output triggered_mode, // use triggered mode (0 - sensors are free-running) @mclk - common to all sensors
// per-channel frame sync inputs and trigger outputs. Both single-cycle mclk pulses
input frsync_chn0, // @mclk trigrst, // single-clock start of frame input (resets trigger output) posedge (@pclk)
output trig_chn0, // @mclk 1 cycle-long trigger output
input frsync_chn1, // @mclk trigrst, // single-clock start of frame input (resets trigger output) posedge (@pclk)
output trig_chn1, // 1 cycle-long trigger output
input frsync_chn2, // @mclk trigrst, // single-clock start of frame input (resets trigger output) posedge (@pclk)
output trig_chn2, // 1 cycle-long trigger output
input frsync_chn3, // @mclk trigrst, // single-clock start of frame input (resets trigger output) posedge (@pclk)
output trig_chn3, // 1 cycle-long trigger output
// timestamps used by the compressor channel (to be included in the image file) and to the event logger (i.e. as a master timestamp)
output ts_stb_chn0, // 1 clock before ts_rcv_data is valid
output [7:0] ts_data_chn0, // byte-wide serialized timestamp message received or local
output ts_stb_chn1, // 1 clock before ts_rcv_data is valid
output [7:0] ts_data_chn1, // byte-wide serialized timestamp message received or local
output ts_stb_chn2, // 1 clock before ts_rcv_data is valid
output [7:0] ts_data_chn2, // byte-wide serialized timestamp message received or local
output ts_stb_chn3, // 1 clock before ts_rcv_data is valid
output [7:0] ts_data_chn3, // byte-wide serialized timestamp message received or local
// timestamp for the event logger
input lclk, // clock used by the evebt logger
input ts_logger_snap, // request from the logger to take a snapshot
output ts_logger_stb, // one clock pulse before sending TS data
output [7:0] ts_logger_data // timestamp data (s0,s1,s2,s3,u0,u1,u2,u3==0)
);
wire [3:0] frame_sync;
wire [3:0] trig;
wire [3:0] ts_local_snap; // ts_snap_mclk make a timestamp pulse single @(posedge pclk)
wire [3:0] ts_local_stb; // 1 clk before ts_snd_data is valid
wire [7:0] ts_local_data [0:3]; // byte-wide serialized timestamp message
// wire ts_pio_snap; // ts_snap_mclk make a timestamp pulse single @(posedge pclk)
// wire ts_pio_stb; // 1 clk before ts_snd_data is valid
// wire [7:0] ts_pio_data; // byte-wide serialized timestamp message
wire [3:0] ts_stb; // 1 clk before ts_snd_data is valid
wire [7:0] ts_data [0:3]; // byte-wide serialized timestamp message
wire [31:0] live_sec; // current time seconds, updated @ mclk
wire [19:0] live_usec; // current time microseconds, updated @ mclk
assign {ts_stb_chn3, ts_stb_chn2, ts_stb_chn1, ts_stb_chn0} = ts_stb;
assign ts_data_chn0 = ts_data[0];
assign ts_data_chn1 = ts_data[1];
assign ts_data_chn2 = ts_data[2];
assign ts_data_chn3 = ts_data[3];
assign {trig_chn3, trig_chn2, trig_chn1, trig_chn0} = trig;
assign frame_sync = {frsync_chn3, frsync_chn2, frsync_chn1, frsync_chn0};
rtc393 #(
.RTC_ADDR (RTC_ADDR),
.RTC_STATUS_REG_ADDR (RTC_STATUS_REG_ADDR),
.RTC_SEC_USEC_ADDR (RTC_SEC_USEC_ADDR),
.RTC_MASK (RTC_MASK),
.RTC_MHZ (RTC_MHZ),
.RTC_BITC_PREDIV (RTC_BITC_PREDIV),
.RTC_SET_USEC (RTC_SET_USEC),
.RTC_SET_SEC (RTC_SET_SEC),
.RTC_SET_CORR (RTC_SET_CORR),
.RTC_SET_STATUS (RTC_SET_STATUS)
) rtc393_i (
.rst (rst), // input
.mclk (mclk), // input
.refclk (refclk), // input
.cmd_ad (cmd_ad), // input[7:0]
.cmd_stb (cmd_stb), // input
.status_ad (status_ad), // output[7:0]
.status_rq (status_rq), // output
.status_start (status_start), // input
.live_sec (live_sec), // output[31:0]
.live_usec (live_usec) // output[19:0]
);
timestamp_snapshot timestamp_snapshot_logger_i (
.rst (rst), // input
.tclk (mclk), // input
.sec (live_sec), // input[31:0]
.usec (live_usec), // input[19:0]
.sclk (lclk), // input
.snap (ts_logger_snap), // input
.pre_stb (ts_logger_stb), // output
.ts_data (ts_logger_data) // output[7:0] reg
);
timestamp_snapshot timestamp_snapshot_chn0_i (
.rst (rst), // input
.tclk (mclk), // input
.sec (live_sec), // input[31:0]
.usec (live_usec), // input[19:0]
.sclk (mclk), // input
.snap (ts_local_snap[0]), // input
.pre_stb (ts_local_stb[0]), // output
.ts_data (ts_local_data[0]) // output[7:0] reg
);
timestamp_snapshot timestamp_snapshot_chn1_i (
.rst (rst), // input
.tclk (mclk), // input
.sec (live_sec), // input[31:0]
.usec (live_usec), // input[19:0]
.sclk (mclk), // input
.snap (ts_local_snap[1]), // input
.pre_stb (ts_local_stb[1]), // output
.ts_data (ts_local_data[1]) // output[7:0] reg
);
timestamp_snapshot timestamp_snapshot_chn2_i (
.rst (rst), // input
.tclk (mclk), // input
.sec (live_sec), // input[31:0]
.usec (live_usec), // input[19:0]
.sclk (mclk), // input
.snap (ts_local_snap[2]), // input
.pre_stb (ts_local_stb[2]), // output
.ts_data (ts_local_data[2]) // output[7:0] reg
);
timestamp_snapshot timestamp_snapshot_chn3_i (
.rst (rst), // input
.tclk (mclk), // input
.sec (live_sec), // input[31:0]
.usec (live_usec), // input[19:0]
.sclk (mclk), // input
.snap (ts_local_snap[3]), // input
.pre_stb (ts_local_stb[3]), // output
.ts_data (ts_local_data[3]) // output[7:0] reg
);
camsync393 #(
.CAMSYNC_ADDR (CAMSYNC_ADDR),
.CAMSYNC_MASK (CAMSYNC_MASK),
.CAMSYNC_MODE (CAMSYNC_MODE),
.CAMSYNC_TRIG_SRC (CAMSYNC_TRIG_SRC),
.CAMSYNC_TRIG_DST (CAMSYNC_TRIG_DST),
.CAMSYNC_TRIG_PERIOD (CAMSYNC_TRIG_PERIOD),
.CAMSYNC_TRIG_DELAY0 (CAMSYNC_TRIG_DELAY0),
.CAMSYNC_TRIG_DELAY1 (CAMSYNC_TRIG_DELAY1),
.CAMSYNC_TRIG_DELAY2 (CAMSYNC_TRIG_DELAY2),
.CAMSYNC_TRIG_DELAY3 (CAMSYNC_TRIG_DELAY3),
.CAMSYNC_SNDEN_BIT (CAMSYNC_SNDEN_BIT),
.CAMSYNC_EXTERNAL_BIT (CAMSYNC_EXTERNAL_BIT),
.CAMSYNC_TRIGGERED_BIT (CAMSYNC_TRIGGERED_BIT),
.CAMSYNC_MASTER_BIT (CAMSYNC_MASTER_BIT),
.CAMSYNC_CHN_EN_BIT (CAMSYNC_CHN_EN_BIT),
.CAMSYNC_PRE_MAGIC (CAMSYNC_PRE_MAGIC),
.CAMSYNC_POST_MAGIC (CAMSYNC_POST_MAGIC)
) camsync393_i (
.rst (rst), // input
.mclk (mclk), // input
.cmd_ad (cmd_ad), // input[7:0]
.cmd_stb (cmd_stb), // input
.pclk (pclk), // input
.gpio_in (gpio_in), // input[9:0]
.gpio_out (gpio_out), // output[9:0]
.gpio_out_en (gpio_out_en), // output[9:0] reg
.triggered_mode (triggered_mode), // output
.frsync_chn0 (frame_sync[0]), // input
.trig_chn0 (trig[0]), // output
.frsync_chn1 (frame_sync[1]), // input
.trig_chn1 (trig[1]), // output
.frsync_chn2 (frame_sync[2]), // input
.trig_chn2 (trig[2]), // output
.frsync_chn3 (frame_sync[3]), // input
.trig_chn3 (trig[3]), // output
.ts_snap_mclk_chn0 (ts_local_snap[0]), // output
.ts_snd_stb_chn0 (ts_local_stb[0]), // input
.ts_snd_data_chn0 (ts_local_data[0]), // input[7:0]
.ts_snap_mclk_chn1 (ts_local_snap[1]), // output
.ts_snd_stb_chn1 (ts_local_stb[1]), // input
.ts_snd_data_chn1 (ts_local_data[1]), // input[7:0]
.ts_snap_mclk_chn2 (ts_local_snap[2]), // output
.ts_snd_stb_chn2 (ts_local_stb[2]), // input
.ts_snd_data_chn2 (ts_local_data[2]), // input[7:0]
.ts_snap_mclk_chn3 (ts_local_snap[3]), // output
.ts_snd_stb_chn3 (ts_local_stb[3]), // input
.ts_snd_data_chn3 (ts_local_data[3]), // input[7:0]
.ts_rcv_stb_chn0 (ts_stb[0]), // output
.ts_rcv_data_chn0 (ts_data[0]), // output[7:0]
.ts_rcv_stb_chn1 (ts_stb[1]), // output
.ts_rcv_data_chn1 (ts_data[1]), // output[7:0]
.ts_rcv_stb_chn2 (ts_stb[2]), // output
.ts_rcv_data_chn2 (ts_data[2]), // output[7:0]
.ts_rcv_stb_chn3 (ts_stb[3]), // output
.ts_rcv_data_chn3 (ts_data[3]) // output[7: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