Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
X
x393
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
x393
Commits
428053b8
Commit
428053b8
authored
Jul 06, 2015
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
reated a top module for all timestamp/synchroniztion functionality
parent
2675a8a1
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
374 additions
and
44 deletions
+374
-44
camsync393.v
timing/camsync393.v
+51
-37
rtc393.v
timing/rtc393.v
+50
-7
timing393.v
timing/timing393.v
+273
-0
No files found.
timing/camsync393.v
View file @
428053b8
...
...
@@ -27,7 +27,8 @@
// TODO: make a separate clock for transmission (program counters too?) and/or for the period timer?
// TODO: change timestamp to serial message
// 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
#(
parameter
CAMSYNC_ADDR
=
'h160
,
//TODO: assign valid address
parameter
CAMSYNC_MASK
=
'h3f8
,
...
...
@@ -81,26 +82,30 @@ module camsync393 #(
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)
output
trigger1_chn0
,
// @mclk 1 cycle-long trigger output
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
`ifdef
GENERATE_TRIG_OVERDUE
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
input
frsync_chn1
,
// @mclk trigrst, // single-clock start of frame input (resets trigger output) posedge (@pclk)
output
trigger1_chn1
,
// 1 cycle-long trigger output
`endif
input
frsync_chn1
,
// @mclk trigrst, // single-clock start of frame input (resets trigger output) posedge (@pclk)
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
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)
output
trigger1_chn2
,
// 1 cycle-long trigger output
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
output
trig_chn2
,
// 1 cycle-long trigger output
`ifdef
GENERATE_TRIG_OVERDUE
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)
output
trigger1_chn3
,
// 1 cycle-long trigger output
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
output
trig_chn3
,
// 1 cycle-long trigger output
`ifdef
GENERATE_TRIG_OVERDUE
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)
// this timestmp is used either to send local timestamp for synchronization, or
// to acquire local timestamp of sync pulse for logging
...
...
@@ -216,10 +221,13 @@ module camsync393 #(
reg
trigger_condition_d
;
// GPIO input trigger condition met, delayed (for edge detection)
reg
trigger_condition_filtered
;
// trigger condition filtered
reg
[
6
:
0
]
trigger_filter_cntr
;
reg
[
3
:
0
]
trigger1_r
;
wire
[
3
:
0
]
trigger1_r_mclk
;
// wire trigger1_dly16; // trigger1 delayed by 16 clk cycles to get local timestamp
reg
[
3
:
0
]
trig_r
;
wire
[
3
:
0
]
trig_r_mclk
;
// 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
]
overdue
;
`endif
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_chn1
;
// trigger delay counter
...
...
@@ -276,7 +284,6 @@ module camsync393 #(
wire
[
3
:
0
]
frame_sync
;
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)
reg
[
3
:
0
]
overdue
;
//! 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)
//! then that bit will be still from internall trigger to frame valid
...
...
@@ -290,17 +297,23 @@ module camsync393 #(
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
]
;
`ifdef
GENERATE_TRIG_OVERDUE
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
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_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
{
trigger1_chn3
,
trigger1_chn2
,
trigger1_chn1
,
trigger1_chn0
}
=
trigger1_r_mclk
;
assign
{
overdue_chn3
,
overdue_chn2
,
overdue_chn1
,
overdue_chn0
}
=
overdue
;
`endif
assign
frame_sync
=
{
frsync_chn3
,
frsync_chn2
,
frsync_chn1
,
frsync_chn0
};
assign
set_mode_reg_w
=
cmd_we
&&
(
cmd_a
==
CAMSYNC_MODE
)
;
...
...
@@ -394,7 +407,7 @@ module camsync393 #(
end
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
(
trig
ger1
_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
;
input_use_intern
<=
pre_input_use_intern
;
...
...
@@ -443,23 +456,24 @@ module camsync393 #(
(
dly_cntr_chn0
[
31
:
0
]
!=
0
)
?
1'b1
:
1'b0
};
end
always
@
(
posedge
rst
or
posedge
mclk
)
begin
`ifdef
GENERATE_TRIG_OVERDUE
always
@
(
posedge
rst
or
posedge
mclk
)
begin
if
(
rst
)
trigger_r
<=
0
;
else
if
(
!
triggered_mode
)
trigger_r
<=
0
;
else
trigger_r
<=
~
frame_sync
&
(
trig
ger1
_r_mclk
^
trigger_r
)
;
else
trigger_r
<=
~
frame_sync
&
(
trig_r_mclk
^
trigger_r
)
;
if
(
rst
)
overdue
<=
0
;
else
if
(
!
triggered_mode
)
overdue
<=
0
;
else
overdue
<=
((
overdue
^
trigger_r
)
&
trig
ger1
_r_mclk
)
^
overdue
;
else
overdue
<=
((
overdue
^
trigger_r
)
&
trig_r_mclk
)
^
overdue
;
end
`endif
// Detecting input sync pulse (filter - 64 pclk, pulse is 256 pclk)
/// Now trig
ger1
_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:
/// 1 - Sensoris in snapshot mode
/// 1 - Sensor
is in snapshot mode
/// 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
/// if the trigger pulses continue to come.
...
...
@@ -500,11 +514,11 @@ module camsync393 #(
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
]
;
/// bypass delay to trig
ger1
_r in internal trigger mode
trig
ger1
_r
[
0
]
<=
(
input_use_intern
&&
(
master_chn
==
0
))
?
(
start_late
&&
start_en
)
:
(
dly_cntr_run_d
[
0
]
&&
!
dly_cntr_run
[
0
])
;
trig
ger1
_r
[
1
]
<=
(
input_use_intern
&&
(
master_chn
==
1
))
?
(
start_late
&&
start_en
)
:
(
dly_cntr_run_d
[
1
]
&&
!
dly_cntr_run
[
1
])
;
trig
ger1
_r
[
2
]
<=
(
input_use_intern
&&
(
master_chn
==
2
))
?
(
start_late
&&
start_en
)
:
(
dly_cntr_run_d
[
2
]
&&
!
dly_cntr_run
[
2
])
;
trig
ger1
_r
[
3
]
<=
(
input_use_intern
&&
(
master_chn
==
3
))
?
(
start_late
&&
start_en
)
:
(
dly_cntr_run_d
[
3
]
&&
!
dly_cntr_run
[
3
])
;
/// bypass delay to trig_r in internal trigger mode
trig_r
[
0
]
<=
(
input_use_intern
&&
(
master_chn
==
0
))
?
(
start_late
&&
start_en
)
:
(
dly_cntr_run_d
[
0
]
&&
!
dly_cntr_run
[
0
])
;
trig_r
[
1
]
<=
(
input_use_intern
&&
(
master_chn
==
1
))
?
(
start_late
&&
start_en
)
:
(
dly_cntr_run_d
[
1
]
&&
!
dly_cntr_run
[
1
])
;
trig_r
[
2
]
<=
(
input_use_intern
&&
(
master_chn
==
2
))
?
(
start_late
&&
start_en
)
:
(
dly_cntr_run_d
[
2
]
&&
!
dly_cntr_run
[
2
])
;
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
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 #(
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_trig
ger1_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
ger1_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
ger1_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
ger1_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_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_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_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_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
timing/rtc393.v
View file @
428053b8
...
...
@@ -23,13 +23,17 @@
`timescale
1
ns
/
1
ps
module
rtc393
#(
parameter
RTC_ADDR
=
'h170
,
//TODO: assign valid address
parameter
RTC_MASK
=
'h3fc
,
parameter
RTC_MHZ
=
25
,
// RTC input clock in MHz (should be interger number)
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
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_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_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
// set status mode, and take a time snapshot (wait response and read time)
)
(
input
rst
,
...
...
@@ -38,9 +42,14 @@ module rtc393 #(
// programming interface
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)
output
[
31
:
0
]
live_sec
,
output
[
19
:
0
]
live_usec
)
;
// output reg snap); // take a snapshot (externally)
wire
[
31
:
0
]
cmd_data
;
wire
[
2
:
0
]
cmd_a
;
...
...
@@ -49,6 +58,7 @@ module rtc393 #(
wire
set_usec_w
;
wire
set_sec_w
;
wire
set_corr_w
;
wire
set_status_w
;
reg
[
19
:
0
]
wusec
;
reg
[
31
:
0
]
wsec
;
...
...
@@ -72,20 +82,34 @@ module rtc393 #(
reg
[
19
:
0
]
usec_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_sec_w
=
cmd_we
&&
(
cmd_a
==
RTC_SET_SEC
)
;
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
live_sec
=
sec
;
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
if
(
set_usec_w
)
wusec
<=
cmd_data
[
19
:
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
always
@
(
posedge
rst
or
posedge
mclk
)
begin
...
...
@@ -145,6 +169,25 @@ module rtc393 #(
.
data
(
cmd_data
)
,
// output[31:0]
.
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
timing/timing393.v
0 → 100644
View file @
428053b8
/*******************************************************************************
* 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
1
ns
/
1
ps
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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment