Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
F
FMC TDC 1ns 5cha - Gateware
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
FMC TDC 1ns 5cha - Gateware
Commits
6fa0c8c7
Commit
6fa0c8c7
authored
Sep 30, 2019
by
Evangelia Gousiou
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dlamprid-dev' into feature/convention
parents
04df2ba6
e66d3b45
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
1110 additions
and
926 deletions
+1110
-926
.gitmodules
.gitmodules
+1
-0
Manifest.py
hdl/rtl/Manifest.py
+2
-0
channel_regs.vhd
hdl/rtl/channel_regs.vhd
+224
-0
channel_regs_wbgen2_pkg.vhd
hdl/rtl/channel_regs_wbgen2_pkg.vhd
+110
-0
data_engine.vhd
hdl/rtl/data_engine.vhd
+0
-3
fmc_tdc_core.vhd
hdl/rtl/fmc_tdc_core.vhd
+17
-13
fmc_tdc_direct_readout.vhd
hdl/rtl/fmc_tdc_direct_readout.vhd
+30
-52
fmc_tdc_direct_readout_slave.vhd
hdl/rtl/fmc_tdc_direct_readout_slave.vhd
+8
-11
fmc_tdc_direct_readout_slave_pkg.vhd
hdl/rtl/fmc_tdc_direct_readout_slave_pkg.vhd
+6
-6
fmc_tdc_mezzanine.vhd
hdl/rtl/fmc_tdc_mezzanine.vhd
+49
-52
fmc_tdc_wrapper.vhd
hdl/rtl/fmc_tdc_wrapper.vhd
+22
-25
tdc_ts_addsub.vhd
hdl/rtl/tdc_ts_addsub.vhd
+36
-42
timestamp_convert_filter.vhd
hdl/rtl/timestamp_convert_filter.vhd
+148
-147
timestamp_fifo.vhd
hdl/rtl/timestamp_fifo.vhd
+132
-85
timestamp_fifo_wb.vhd
hdl/rtl/timestamp_fifo_wb.vhd
+141
-277
timestamp_fifo_wbgen2_pkg.vhd
hdl/rtl/timestamp_fifo_wbgen2_pkg.vhd
+51
-77
channel_regs.wb
hdl/rtl/wbgen/channel_regs.wb
+132
-0
fmc_tdc_direct_readout_slave.wb
hdl/rtl/wbgen/fmc_tdc_direct_readout_slave.wb
+1
-6
timestamp_fifo_wb.wb
hdl/rtl/wbgen/timestamp_fifo_wb.wb
+0
-130
No files found.
.gitmodules
View file @
6fa0c8c7
...
...
@@ -19,3 +19,4 @@
[submodule "hdl/ip_cores/svec"]
path = hdl/ip_cores/svec
url = https://ohwr.org/project/svec.git
hdl/rtl/Manifest.py
View file @
6fa0c8c7
...
...
@@ -22,6 +22,8 @@ files = [
"fmc_tdc_direct_readout_slave_pkg.vhd"
,
"fmc_tdc_wrapper.vhd"
,
"timestamp_fifo.vhd"
,
"channel_regs.vhd"
,
"channel_regs_wbgen2_pkg.vhd"
,
"timestamp_fifo_wb.vhd"
,
"timestamp_fifo_wbgen2_pkg.vhd"
,
"timestamp_convert_filter.vhd"
,
...
...
hdl/rtl/channel_regs.vhd
0 → 100644
View file @
6fa0c8c7
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for Channel registers
---------------------------------------------------------------------------------------
-- File : channel_regs.vhd
-- Author : auto-generated by wbgen2 from wbgen/channel_regs.wb
-- Created : Thu Sep 26 16:43:02 2019
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wbgen/channel_regs.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library
ieee
;
use
ieee
.
std_logic_1164
.
all
;
use
ieee
.
numeric_std
.
all
;
use
work
.
wishbone_pkg
.
all
;
use
work
.
ch_reg_wbgen2_pkg
.
all
;
entity
channel_regs
is
port
(
rst_n_i
:
in
std_logic
;
clk_sys_i
:
in
std_logic
;
slave_i
:
in
t_wishbone_slave_in
;
slave_o
:
out
t_wishbone_slave_out
;
int_o
:
out
std_logic
;
regs_i
:
in
t_ch_reg_in_registers
;
regs_o
:
out
t_ch_reg_out_registers
);
end
channel_regs
;
architecture
syn
of
channel_regs
is
signal
ch_reg_offset1_int
:
std_logic_vector
(
31
downto
0
);
signal
ch_reg_offset2_int
:
std_logic_vector
(
31
downto
0
);
signal
ch_reg_offset3_int
:
std_logic_vector
(
31
downto
0
);
signal
ch_reg_csr_delta_read_dly0
:
std_logic
;
signal
ch_reg_csr_delta_read_int
:
std_logic
;
signal
ch_reg_csr_rst_seq_dly0
:
std_logic
;
signal
ch_reg_csr_rst_seq_int
:
std_logic
;
signal
ch_reg_csr_delta_ref_int
:
std_logic_vector
(
2
downto
0
);
signal
ch_reg_csr_raw_mode_int
:
std_logic
;
signal
ack_sreg
:
std_logic_vector
(
9
downto
0
);
signal
rddata_reg
:
std_logic_vector
(
31
downto
0
);
signal
wrdata_reg
:
std_logic_vector
(
31
downto
0
);
signal
bwsel_reg
:
std_logic_vector
(
3
downto
0
);
signal
rwaddr_reg
:
std_logic_vector
(
2
downto
0
);
signal
ack_in_progress
:
std_logic
;
signal
wr_int
:
std_logic
;
signal
rd_int
:
std_logic
;
signal
allones
:
std_logic_vector
(
31
downto
0
);
signal
allzeros
:
std_logic_vector
(
31
downto
0
);
begin
-- Some internal signals assignments
wrdata_reg
<=
slave_i
.
dat
;
--
-- Main register bank access process.
process
(
clk_sys_i
,
rst_n_i
)
begin
if
(
rst_n_i
=
'0'
)
then
ack_sreg
<=
"0000000000"
;
ack_in_progress
<=
'0'
;
rddata_reg
<=
"00000000000000000000000000000000"
;
ch_reg_offset1_int
<=
"00000000000000000000000000000000"
;
ch_reg_offset2_int
<=
"00000000000000000000000000000000"
;
ch_reg_offset3_int
<=
"00000000000000000000000000000000"
;
ch_reg_csr_delta_read_int
<=
'0'
;
ch_reg_csr_rst_seq_int
<=
'0'
;
ch_reg_csr_delta_ref_int
<=
"000"
;
ch_reg_csr_raw_mode_int
<=
'0'
;
elsif
rising_edge
(
clk_sys_i
)
then
-- advance the ACK generator shift register
ack_sreg
(
8
downto
0
)
<=
ack_sreg
(
9
downto
1
);
ack_sreg
(
9
)
<=
'0'
;
if
(
ack_in_progress
=
'1'
)
then
if
(
ack_sreg
(
0
)
=
'1'
)
then
ch_reg_csr_delta_read_int
<=
'0'
;
ch_reg_csr_rst_seq_int
<=
'0'
;
ack_in_progress
<=
'0'
;
else
end
if
;
else
if
((
slave_i
.
cyc
=
'1'
)
and
(
slave_i
.
stb
=
'1'
))
then
case
rwaddr_reg
(
2
downto
0
)
is
when
"000"
=>
if
(
slave_i
.
we
=
'1'
)
then
end
if
;
rddata_reg
(
31
downto
0
)
<=
regs_i
.
delta1_i
;
ack_sreg
(
0
)
<=
'1'
;
ack_in_progress
<=
'1'
;
when
"001"
=>
if
(
slave_i
.
we
=
'1'
)
then
end
if
;
rddata_reg
(
31
downto
0
)
<=
regs_i
.
delta2_i
;
ack_sreg
(
0
)
<=
'1'
;
ack_in_progress
<=
'1'
;
when
"010"
=>
if
(
slave_i
.
we
=
'1'
)
then
end
if
;
rddata_reg
(
31
downto
0
)
<=
regs_i
.
delta3_i
;
ack_sreg
(
0
)
<=
'1'
;
ack_in_progress
<=
'1'
;
when
"011"
=>
if
(
slave_i
.
we
=
'1'
)
then
ch_reg_offset1_int
<=
wrdata_reg
(
31
downto
0
);
end
if
;
rddata_reg
(
31
downto
0
)
<=
ch_reg_offset1_int
;
ack_sreg
(
0
)
<=
'1'
;
ack_in_progress
<=
'1'
;
when
"100"
=>
if
(
slave_i
.
we
=
'1'
)
then
ch_reg_offset2_int
<=
wrdata_reg
(
31
downto
0
);
end
if
;
rddata_reg
(
31
downto
0
)
<=
ch_reg_offset2_int
;
ack_sreg
(
0
)
<=
'1'
;
ack_in_progress
<=
'1'
;
when
"101"
=>
if
(
slave_i
.
we
=
'1'
)
then
ch_reg_offset3_int
<=
wrdata_reg
(
31
downto
0
);
end
if
;
rddata_reg
(
31
downto
0
)
<=
ch_reg_offset3_int
;
ack_sreg
(
0
)
<=
'1'
;
ack_in_progress
<=
'1'
;
when
"110"
=>
if
(
slave_i
.
we
=
'1'
)
then
ch_reg_csr_delta_read_int
<=
wrdata_reg
(
1
);
ch_reg_csr_rst_seq_int
<=
wrdata_reg
(
2
);
ch_reg_csr_delta_ref_int
<=
wrdata_reg
(
5
downto
3
);
ch_reg_csr_raw_mode_int
<=
wrdata_reg
(
6
);
end
if
;
rddata_reg
(
0
)
<=
regs_i
.
csr_delta_ready_i
;
rddata_reg
(
1
)
<=
'0'
;
rddata_reg
(
2
)
<=
'0'
;
rddata_reg
(
5
downto
3
)
<=
ch_reg_csr_delta_ref_int
;
rddata_reg
(
6
)
<=
ch_reg_csr_raw_mode_int
;
rddata_reg
(
7
)
<=
'X'
;
rddata_reg
(
8
)
<=
'X'
;
rddata_reg
(
9
)
<=
'X'
;
rddata_reg
(
10
)
<=
'X'
;
rddata_reg
(
11
)
<=
'X'
;
rddata_reg
(
12
)
<=
'X'
;
rddata_reg
(
13
)
<=
'X'
;
rddata_reg
(
14
)
<=
'X'
;
rddata_reg
(
15
)
<=
'X'
;
rddata_reg
(
16
)
<=
'X'
;
rddata_reg
(
17
)
<=
'X'
;
rddata_reg
(
18
)
<=
'X'
;
rddata_reg
(
19
)
<=
'X'
;
rddata_reg
(
20
)
<=
'X'
;
rddata_reg
(
21
)
<=
'X'
;
rddata_reg
(
22
)
<=
'X'
;
rddata_reg
(
23
)
<=
'X'
;
rddata_reg
(
24
)
<=
'X'
;
rddata_reg
(
25
)
<=
'X'
;
rddata_reg
(
26
)
<=
'X'
;
rddata_reg
(
27
)
<=
'X'
;
rddata_reg
(
28
)
<=
'X'
;
rddata_reg
(
29
)
<=
'X'
;
rddata_reg
(
30
)
<=
'X'
;
rddata_reg
(
31
)
<=
'X'
;
ack_sreg
(
2
)
<=
'1'
;
ack_in_progress
<=
'1'
;
when
others
=>
-- prevent the slave from hanging the bus on invalid address
ack_in_progress
<=
'1'
;
ack_sreg
(
0
)
<=
'1'
;
end
case
;
end
if
;
end
if
;
end
if
;
end
process
;
-- Drive the data output bus
slave_o
.
dat
<=
rddata_reg
;
-- Delta Timestamp Word 1 (TAI cycles, signed)
-- Delta Timestamp Word 2 (8ns ticks, unsigned)
-- Delta Timestamp Word 3 (fractional part, unsigned)
-- Channel Offset Word 1 (TAI cycles, signed)
regs_o
.
offset1_o
<=
ch_reg_offset1_int
;
-- Channel Offset Word 2 (8ns ticks, unsigned)
regs_o
.
offset2_o
<=
ch_reg_offset2_int
;
-- Channel Offset Word 3 (fractional part, unsigned)
regs_o
.
offset3_o
<=
ch_reg_offset3_int
;
-- Delta Timestamp Ready
-- Read Delta Timestamp
process
(
clk_sys_i
,
rst_n_i
)
begin
if
(
rst_n_i
=
'0'
)
then
ch_reg_csr_delta_read_dly0
<=
'0'
;
regs_o
.
csr_delta_read_o
<=
'0'
;
elsif
rising_edge
(
clk_sys_i
)
then
ch_reg_csr_delta_read_dly0
<=
ch_reg_csr_delta_read_int
;
regs_o
.
csr_delta_read_o
<=
ch_reg_csr_delta_read_int
and
(
not
ch_reg_csr_delta_read_dly0
);
end
if
;
end
process
;
-- Reset Sequence Counter
process
(
clk_sys_i
,
rst_n_i
)
begin
if
(
rst_n_i
=
'0'
)
then
ch_reg_csr_rst_seq_dly0
<=
'0'
;
regs_o
.
csr_rst_seq_o
<=
'0'
;
elsif
rising_edge
(
clk_sys_i
)
then
ch_reg_csr_rst_seq_dly0
<=
ch_reg_csr_rst_seq_int
;
regs_o
.
csr_rst_seq_o
<=
ch_reg_csr_rst_seq_int
and
(
not
ch_reg_csr_rst_seq_dly0
);
end
if
;
end
process
;
-- Delta Timestamp Reference Channel
regs_o
.
csr_delta_ref_o
<=
ch_reg_csr_delta_ref_int
;
-- Raw readout mode
regs_o
.
csr_raw_mode_o
<=
ch_reg_csr_raw_mode_int
;
rwaddr_reg
<=
slave_i
.
adr
(
4
downto
2
);
slave_o
.
stall
<=
(
not
ack_sreg
(
0
))
and
(
slave_i
.
stb
and
slave_i
.
cyc
);
slave_o
.
err
<=
'0'
;
slave_o
.
rty
<=
'0'
;
-- ACK signal generation. Just pass the LSB of ACK counter.
slave_o
.
ack
<=
ack_sreg
(
0
);
end
syn
;
hdl/rtl/channel_regs_wbgen2_pkg.vhd
0 → 100644
View file @
6fa0c8c7
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for Channel registers
---------------------------------------------------------------------------------------
-- File : channel_regs_wbgen2_pkg.vhd
-- Author : auto-generated by wbgen2 from wbgen/channel_regs.wb
-- Created : Thu Sep 26 16:43:02 2019
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wbgen/channel_regs.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library
ieee
;
use
ieee
.
std_logic_1164
.
all
;
use
ieee
.
numeric_std
.
all
;
use
work
.
wishbone_pkg
.
all
;
package
ch_reg_wbgen2_pkg
is
-- Input registers (user design -> WB slave)
type
t_ch_reg_in_registers
is
record
delta1_i
:
std_logic_vector
(
31
downto
0
);
delta2_i
:
std_logic_vector
(
31
downto
0
);
delta3_i
:
std_logic_vector
(
31
downto
0
);
csr_delta_ready_i
:
std_logic
;
end
record
;
constant
c_ch_reg_in_registers_init_value
:
t_ch_reg_in_registers
:
=
(
delta1_i
=>
(
others
=>
'0'
),
delta2_i
=>
(
others
=>
'0'
),
delta3_i
=>
(
others
=>
'0'
),
csr_delta_ready_i
=>
'0'
);
-- Output registers (WB slave -> user design)
type
t_ch_reg_out_registers
is
record
offset1_o
:
std_logic_vector
(
31
downto
0
);
offset2_o
:
std_logic_vector
(
31
downto
0
);
offset3_o
:
std_logic_vector
(
31
downto
0
);
csr_delta_read_o
:
std_logic
;
csr_rst_seq_o
:
std_logic
;
csr_delta_ref_o
:
std_logic_vector
(
2
downto
0
);
csr_raw_mode_o
:
std_logic
;
end
record
;
constant
c_ch_reg_out_registers_init_value
:
t_ch_reg_out_registers
:
=
(
offset1_o
=>
(
others
=>
'0'
),
offset2_o
=>
(
others
=>
'0'
),
offset3_o
=>
(
others
=>
'0'
),
csr_delta_read_o
=>
'0'
,
csr_rst_seq_o
=>
'0'
,
csr_delta_ref_o
=>
(
others
=>
'0'
),
csr_raw_mode_o
=>
'0'
);
function
"or"
(
left
,
right
:
t_ch_reg_in_registers
)
return
t_ch_reg_in_registers
;
function
f_x_to_zero
(
x
:
std_logic
)
return
std_logic
;
function
f_x_to_zero
(
x
:
std_logic_vector
)
return
std_logic_vector
;
component
channel_regs
is
port
(
rst_n_i
:
in
std_logic
;
clk_sys_i
:
in
std_logic
;
slave_i
:
in
t_wishbone_slave_in
;
slave_o
:
out
t_wishbone_slave_out
;
int_o
:
out
std_logic
;
regs_i
:
in
t_ch_reg_in_registers
;
regs_o
:
out
t_ch_reg_out_registers
);
end
component
;
end
package
;
package
body
ch_reg_wbgen2_pkg
is
function
f_x_to_zero
(
x
:
std_logic
)
return
std_logic
is
begin
if
x
=
'1'
then
return
'1'
;
else
return
'0'
;
end
if
;
end
function
;
function
f_x_to_zero
(
x
:
std_logic_vector
)
return
std_logic_vector
is
variable
tmp
:
std_logic_vector
(
x
'length
-1
downto
0
);
begin
for
i
in
0
to
x
'length
-1
loop
if
(
x
(
i
)
=
'1'
)
then
tmp
(
i
):
=
'1'
;
else
tmp
(
i
):
=
'0'
;
end
if
;
end
loop
;
return
tmp
;
end
function
;
function
"or"
(
left
,
right
:
t_ch_reg_in_registers
)
return
t_ch_reg_in_registers
is
variable
tmp
:
t_ch_reg_in_registers
;
begin
tmp
.
delta1_i
:
=
f_x_to_zero
(
left
.
delta1_i
)
or
f_x_to_zero
(
right
.
delta1_i
);
tmp
.
delta2_i
:
=
f_x_to_zero
(
left
.
delta2_i
)
or
f_x_to_zero
(
right
.
delta2_i
);
tmp
.
delta3_i
:
=
f_x_to_zero
(
left
.
delta3_i
)
or
f_x_to_zero
(
right
.
delta3_i
);
tmp
.
csr_delta_ready_i
:
=
f_x_to_zero
(
left
.
csr_delta_ready_i
)
or
f_x_to_zero
(
right
.
csr_delta_ready_i
);
return
tmp
;
end
function
;
end
package
body
;
hdl/rtl/data_engine.vhd
View file @
6fa0c8c7
...
...
@@ -424,9 +424,6 @@ begin
if
acam_ef1_i
=
'0'
then
nxt_engine_st
<=
GET_STAMP1
;
elsif
acam_ef2_i
=
'0'
then
nxt_engine_st
<=
GET_STAMP2
;
else
nxt_engine_st
<=
ACTIVE
;
end
if
;
...
...
hdl/rtl/fmc_tdc_core.vhd
View file @
6fa0c8c7
...
...
@@ -150,12 +150,19 @@ use work.genram_pkg.all;
--=================================================================================================
entity
fmc_tdc_core
is
generic
(
g_span
:
integer
:
=
32
;
-- address span in bus interfaces
g_width
:
integer
:
=
32
;
-- data width in bus interfaces
g_simulation
:
boolean
:
=
false
;
g_with_dma_readout
:
boolean
:
=
false
;
g_with_fifo_readout
:
boolean
:
=
false
);
-- this generic is set to TRUE
-- when instantiated in a test-bench
(
g_span
:
integer
:
=
32
;
-- address span in bus interfaces
g_width
:
integer
:
=
32
;
-- data width in bus interfaces
g_simulation
:
boolean
:
=
false
;
-- Enable filtering based on pulse width. This will have the following effects:
-- * Suppress theforwarding of negative slope timestamps.
-- * Delay the forwarding of timestamps until after the falling edge timestamp.
-- Once enabled, all pulses wider than 1 second or narrower than
-- g_pulse_width_filter_min will be dropped.
g_pulse_width_filter
:
boolean
:
=
true
;
-- In 8ns ticks.
g_pulse_width_filter_min
:
natural
:
=
12
;
g_with_dma_readout
:
boolean
:
=
false
;
g_with_fifo_readout
:
boolean
:
=
false
);
port
(
clk_sys_i
:
in
std_logic
;
...
...
@@ -219,10 +226,6 @@ entity fmc_tdc_core is
timestamp_valid_o
:
out
std_logic_vector
(
4
downto
0
);
timestamp_ready_i
:
in
std_logic_vector
(
4
downto
0
);
-- direct interface, for compatibility with LIST/WRTD
direct_timestamp_o
:
out
std_logic_vector
(
127
downto
0
);
direct_timestamp_valid_o
:
out
std_logic
;
channel_enable_o
:
out
std_logic_vector
(
4
downto
0
);
irq_threshold_o
:
out
std_logic_vector
(
9
downto
0
);
irq_timeout_o
:
out
std_logic_vector
(
9
downto
0
);
...
...
@@ -539,6 +542,9 @@ begin
U_FilterAndConvert
:
entity
work
.
timestamp_convert_filter
generic
map
(
g_pulse_width_filter
=>
g_pulse_width_filter
,
g_pulse_width_filter_min
=>
g_pulse_width_filter_min
)
port
map
(
clk_tdc_i
=>
clk_tdc_i
,
rst_tdc_n_i
=>
rst_tdc_n_i
,
...
...
@@ -553,9 +559,7 @@ begin
ts_ready_i
=>
final_timestamp_ready
,
ts_offset_i
=>
ts_offset_i
,
reset_seq_i
=>
reset_seq_i
,
raw_enable_i
=>
raw_enable_i
,
direct_timestamp_o
=>
direct_timestamp_o
,
direct_timestamp_valid_o
=>
direct_timestamp_valid_o
raw_enable_i
=>
raw_enable_i
);
...
...
hdl/rtl/fmc_tdc_direct_readout.vhd
View file @
6fa0c8c7
...
...
@@ -11,14 +11,11 @@ use work.dr_wbgen2_pkg.all;
entity
fmc_tdc_direct_readout
is
port
(
clk_tdc_i
:
in
std_logic
;
rst_tdc_n_i
:
in
std_logic
;
clk_sys_i
:
in
std_logic
;
rst_sys_n_i
:
in
std_logic
;
direct_timestamp_i
:
in
std_logic_vector
(
127
downto
0
);
direct_timestamp_wr_i
:
in
std_logic
;
timestamp_i
:
in
t_tdc_timestamp_array
(
4
downto
0
);
timestamp_valid_i
:
in
std_logic_vector
(
4
downto
0
)
;
direct_slave_i
:
in
t_wishbone_slave_in
;
direct_slave_o
:
out
t_wishbone_slave_out
...
...
@@ -29,24 +26,6 @@ end entity;
architecture
rtl
of
fmc_tdc_direct_readout
is
component
fmc_tdc_direct_readout_wb_slave
is
port
(
rst_n_i
:
in
std_logic
;
clk_sys_i
:
in
std_logic
;
wb_adr_i
:
in
std_logic_vector
(
2
downto
0
);
wb_dat_i
:
in
std_logic_vector
(
31
downto
0
);
wb_dat_o
:
out
std_logic_vector
(
31
downto
0
);
wb_cyc_i
:
in
std_logic
;
wb_sel_i
:
in
std_logic_vector
(
3
downto
0
);
wb_stb_i
:
in
std_logic
;
wb_we_i
:
in
std_logic
;
wb_ack_o
:
out
std_logic
;
wb_stall_o
:
out
std_logic
;
clk_tdc_i
:
in
std_logic
;
regs_i
:
in
t_dr_in_registers
;
regs_o
:
out
t_dr_out_registers
);
end
component
fmc_tdc_direct_readout_wb_slave
;
constant
c_num_channels
:
integer
:
=
5
;
type
t_channel_state
is
record
...
...
@@ -65,24 +44,33 @@ architecture rtl of fmc_tdc_direct_readout is
signal
regs_out
:
t_dr_out_registers
;
signal
regs_in
:
t_dr_in_registers
;
signal
ts_cycles
:
std_logic_vector
(
31
downto
0
);
signal
ts_seconds
:
std_logic_vector
(
31
downto
0
);
signal
ts_bins
:
std_logic_vector
(
17
downto
0
);
signal
ts_edge
:
std_logic
;
signal
ts_channel
:
std_logic_vector
(
2
downto
0
);
signal
direct_slave_out
:
t_wishbone_slave_out
;
begin
signal
channel_select
:
integer
:
=
0
;
ts_channel
<=
direct_timestamp_i
(
98
downto
96
);
ts_edge
<=
direct_timestamp_i
(
100
);
ts_seconds
<=
direct_timestamp_i
(
95
downto
64
);
ts_cycles
<=
direct_timestamp_i
(
63
downto
32
);
ts_bins
<=
direct_timestamp_i
(
17
downto
0
);
begin
U_WB_Slave
:
fmc_tdc_direct_readout_wb_slave
p_channel_select
:
process
(
timestamp_valid_i
)
is
begin
case
timestamp_valid_i
is
when
"00001"
=>
channel_select
<=
0
;
when
"00010"
=>
channel_select
<=
1
;
when
"00100"
=>
channel_select
<=
2
;
when
"01000"
=>
channel_select
<=
3
;
when
"10000"
=>
channel_select
<=
4
;
when
others
=>
channel_select
<=
0
;
end
case
;
end
process
p_channel_select
;
regs_in
.
fifo_cycles_i
<=
timestamp_i
(
channel_select
)
.
coarse
;
regs_in
.
fifo_edge_i
<=
timestamp_i
(
channel_select
)
.
slope
;
regs_in
.
fifo_seconds_i
<=
timestamp_i
(
channel_select
)
.
tai
;
regs_in
.
fifo_channel_i
<=
'0'
&
timestamp_i
(
channel_select
)
.
channel
;
regs_in
.
fifo_bins_i
<=
"000000"
&
timestamp_i
(
channel_select
)
.
frac
;
regs_in
.
fifo_wr_req_i
<=
f_to_std_logic
(
fifo_wr
(
channel_select
)
=
'1'
and
regs_out
.
fifo_wr_full_o
=
'0'
);
U_WB_Slave
:
entity
work
.
fmc_tdc_direct_readout_wb_slave
port
map
(
rst_n_i
=>
rst_sys_n_i
,
clk_sys_i
=>
clk_sys_i
,
...
...
@@ -95,7 +83,6 @@ begin
wb_we_i
=>
direct_slave_i
.
we
,
wb_ack_o
=>
direct_slave_out
.
ack
,
wb_stall_o
=>
direct_slave_out
.
stall
,
clk_tdc_i
=>
clk_tdc_i
,
regs_i
=>
regs_in
,
regs_o
=>
regs_out
);
...
...
@@ -104,26 +91,17 @@ begin
direct_slave_o
<=
direct_slave_out
;
regs_in
.
fifo_cycles_i
<=
ts_cycles
;
regs_in
.
fifo_edge_i
<=
'1'
;
regs_in
.
fifo_seconds_i
<=
ts_seconds
;
regs_in
.
fifo_channel_i
<=
'0'
&
ts_channel
;
regs_in
.
fifo_bins_i
<=
ts_bins
;
regs_in
.
fifo_wr_req_i
<=
f_to_std_logic
(
fifo_wr
/=
(
fifo_wr
'range
=>
'0'
)
and
regs_out
.
fifo_wr_full_o
=
'0'
);
gen_channels
:
for
i
in
0
to
c_num_channels
-1
generate
c
(
i
)
.
enable
<=
regs_out
.
chan_enable_o
(
i
);
fifo_wr
(
i
)
<=
f_to_std_logic
(
unsigned
(
ts_channel
)
=
i
and
ts_edge
=
'1'
and
direct_timestamp_wr_i
=
'1'
and
c
(
i
)
.
ready
=
'1'
);
fifo_wr
(
i
)
<=
f_to_std_logic
(
timestamp_valid_i
(
i
)
=
'1'
and
c
(
i
)
.
ready
=
'1'
);
p_dead_time
:
process
(
clk_
tdc
_i
)
p_dead_time
:
process
(
clk_
sys
_i
)
begin
if
rising_edge
(
clk_
tdc
_i
)
then
if
rst_
tdc
_n_i
=
'0'
or
c
(
i
)
.
enable
=
'0'
then
if
rising_edge
(
clk_
sys
_i
)
then
if
rst_
sys
_n_i
=
'0'
or
c
(
i
)
.
enable
=
'0'
then
c
(
i
)
.
timeout
<=
(
others
=>
'0'
);
c
(
i
)
.
ready
<=
'0'
;
else
...
...
hdl/rtl/fmc_tdc_direct_readout_slave.vhd
View file @
6fa0c8c7
...
...
@@ -3,7 +3,7 @@
---------------------------------------------------------------------------------------
-- File : fmc_tdc_direct_readout_slave.vhd
-- Author : auto-generated by wbgen2 from fmc_tdc_direct_readout_slave.wb
-- Created : Thu
May 22 14:05:35 2014
-- Created : Thu
Sep 26 16:03:31 2019
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE fmc_tdc_direct_readout_slave.wb
...
...
@@ -30,8 +30,9 @@ entity fmc_tdc_direct_readout_wb_slave is
wb_stb_i
:
in
std_logic
;
wb_we_i
:
in
std_logic
;
wb_ack_o
:
out
std_logic
;
wb_err_o
:
out
std_logic
;
wb_rty_o
:
out
std_logic
;
wb_stall_o
:
out
std_logic
;
clk_tdc_i
:
in
std_logic
;
regs_i
:
in
t_dr_in_registers
;
regs_o
:
out
t_dr_out_registers
);
...
...
@@ -61,13 +62,8 @@ signal allones : std_logic_vector(31 downto 0);
signal
allzeros
:
std_logic_vector
(
31
downto
0
);
begin
-- Some internal signals assignments
. For (foreseen) compatibility with other bus standards.
-- Some internal signals assignments
wrdata_reg
<=
wb_dat_i
;
bwsel_reg
<=
wb_sel_i
;
rd_int
<=
wb_cyc_i
and
(
wb_stb_i
and
(
not
wb_we_i
));
wr_int
<=
wb_cyc_i
and
(
wb_stb_i
and
wb_we_i
);
allones
<=
(
others
=>
'1'
);
allzeros
<=
(
others
=>
'0'
);
--
-- Main register bank access process.
process
(
clk_sys_i
,
rst_n_i
)
...
...
@@ -223,7 +219,7 @@ begin
dr_fifo_in_int
(
82
)
<=
regs_i
.
fifo_edge_i
;
dr_fifo_in_int
(
86
downto
83
)
<=
regs_i
.
fifo_channel_i
;
dr_fifo_rst_n
<=
rst_n_i
;
dr_fifo_INST
:
wbgen2_fifo_
a
sync
dr_fifo_INST
:
wbgen2_fifo_sync
generic
map
(
g_size
=>
256
,
g_width
=>
87
,
...
...
@@ -239,8 +235,7 @@ begin
rd_usedw_o
=>
dr_fifo_usedw_int
,
rd_req_i
=>
dr_fifo_rdreq_int
,
rst_n_i
=>
dr_fifo_rst_n
,
wr_clk_i
=>
clk_tdc_i
,
rd_clk_i
=>
clk_sys_i
,
clk_i
=>
clk_sys_i
,
wr_data_i
=>
dr_fifo_in_int
,
rd_data_o
=>
dr_fifo_out_int
);
...
...
@@ -264,6 +259,8 @@ begin
-- extra code for reg/fifo/mem: FIFO 'Readout FIFO' data output register 2
rwaddr_reg
<=
wb_adr_i
;
wb_stall_o
<=
(
not
ack_sreg
(
0
))
and
(
wb_stb_i
and
wb_cyc_i
);
wb_err_o
<=
'0'
;
wb_rty_o
<=
'0'
;
-- ACK signal generation. Just pass the LSB of ACK counter.
wb_ack_o
<=
ack_sreg
(
0
);
end
syn
;
hdl/rtl/fmc_tdc_direct_readout_slave_pkg.vhd
View file @
6fa0c8c7
...
...
@@ -2,11 +2,11 @@
-- Title : Wishbone slave core for TDC Direct Readout WB Slave
---------------------------------------------------------------------------------------
-- File : fmc_tdc_direct_readout_slave_pkg.vhd
-- Author : auto-generated by wbgen2 from fmc_tdc_direct_readout_slave.wb
-- Created : Thu
May 22 14:05:35 2014
-- Author : auto-generated by wbgen2 from
wbgen/
fmc_tdc_direct_readout_slave.wb
-- Created : Thu
Sep 26 16:03:31 2019
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE fmc_tdc_direct_readout_slave.wb
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE
wbgen/
fmc_tdc_direct_readout_slave.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
...
...
@@ -73,10 +73,10 @@ function f_x_to_zero (x:std_logic_vector) return std_logic_vector is
variable
tmp
:
std_logic_vector
(
x
'length
-1
downto
0
);
begin
for
i
in
0
to
x
'length
-1
loop
if
(
x
(
i
)
=
'
X'
or
x
(
i
)
=
'U
'
)
then
tmp
(
i
):
=
'
0
'
;
if
(
x
(
i
)
=
'
1
'
)
then
tmp
(
i
):
=
'
1
'
;
else
tmp
(
i
):
=
x
(
i
)
;
tmp
(
i
):
=
'0'
;
end
if
;
end
loop
;
return
tmp
;
...
...
hdl/rtl/fmc_tdc_mezzanine.vhd
View file @
6fa0c8c7
...
...
@@ -110,6 +110,14 @@ entity fmc_tdc_mezzanine is
g_span
:
integer
:
=
32
;
g_width
:
integer
:
=
32
;
g_simulation
:
boolean
:
=
false
;
-- Enable filtering based on pulse width. This will have the following effects:
-- * Suppress theforwarding of negative slope timestamps.
-- * Delay the forwarding of timestamps until after the falling edge timestamp.
-- Once enabled, all pulses wider than 1 second or narrower than
-- g_pulse_width_filter_min will be dropped.
g_pulse_width_filter
:
boolean
:
=
true
;
-- In 8ns ticks.
g_pulse_width_filter_min
:
natural
:
=
12
;
g_use_dma_readout
:
boolean
:
=
true
;
g_use_fifo_readout
:
boolean
:
=
true
;
g_use_fake_timestamps_for_sim
:
boolean
:
=
false
);
...
...
@@ -188,8 +196,9 @@ entity fmc_tdc_mezzanine is
i2c_sda_i
:
in
std_logic
;
-- 1-Wire interface
onewire_b
:
inout
std_logic
;
direct_timestamp_o
:
out
std_logic_vector
(
127
downto
0
);
direct_timestamp_valid_o
:
out
std_logic
;
timestamp_o
:
out
t_tdc_timestamp_array
(
4
downto
0
);
timestamp_valid_o
:
out
std_logic_vector
(
4
downto
0
);
sim_timestamp_i
:
in
t_tdc_timestamp
:
=
c_dummy_timestamp
;
sim_timestamp_valid_i
:
in
std_logic
:
=
'0'
;
...
...
@@ -204,6 +213,9 @@ end fmc_tdc_mezzanine;
--=================================================================================================
architecture
rtl
of
fmc_tdc_mezzanine
is
constant
c_CLK_PERIOD
:
std_logic_vector
(
31
downto
0
)
:
=
work
.
tdc_core_pkg
.
f_pick
(
g_SIMULATION
,
c_SIM_CLK_PERIOD
,
c_SYN_CLK_PERIOD
);
---------------------------------------------------------------------------------------------------
-- SDB CONSTANTS --
---------------------------------------------------------------------------------------------------
...
...
@@ -214,7 +226,8 @@ architecture rtl of fmc_tdc_mezzanine is
constant
c_WB_SLAVE_TDC_CORE_CONFIG
:
integer
:
=
1
;
-- TDC core configuration registers
constant
c_WB_SLAVE_TDC_EIC
:
integer
:
=
2
;
-- TDC interrupts
constant
c_WB_SLAVE_TDC_I2C
:
integer
:
=
3
;
-- TDC mezzanine board system EEPROM I2C
constant
c_WB_SLAVE_TDC_FIFO0
:
integer
:
=
4
;
-- Access to TDC core FIFO for timestamps retrieval
constant
c_WB_SLAVE_TDC_CHANNEL0
:
integer
:
=
4
;
-- Access to TDC core channel registers
-- and FIFO for timestamps retrieval
constant
c_WB_SLAVE_TDC_DMA
:
integer
:
=
9
;
-- Access to TDC core DMA controller
-- Slave port on the wishbone crossbar
...
...
@@ -325,11 +338,13 @@ begin
---------------------------------------------------------------------------------------------------
cmp_tdc_core
:
entity
work
.
fmc_tdc_core
generic
map
(
g_span
=>
g_span
,
g_width
=>
g_width
,
g_simulation
=>
g_simulation
,
g_with_dma_readout
=>
g_use_dma_readout
,
g_with_fifo_readout
=>
g_use_fifo_readout
)
(
g_span
=>
g_span
,
g_width
=>
g_width
,
g_simulation
=>
g_simulation
,
g_pulse_width_filter
=>
g_pulse_width_filter
,
g_pulse_width_filter_min
=>
g_pulse_width_filter_min
,
g_with_dma_readout
=>
g_use_dma_readout
,
g_with_fifo_readout
=>
g_use_fifo_readout
)
port
map
(
-- clks, rst
clk_tdc_i
=>
clk_tdc_i
,
...
...
@@ -389,9 +404,6 @@ begin
ts_offset_i
=>
ts_offset
,
reset_seq_i
=>
reset_seq
,
direct_timestamp_valid_o
=>
direct_timestamp_valid_o
,
direct_timestamp_o
=>
direct_timestamp_o
,
fmc_id_i
=>
fmc_id_i
,
irq_threshold_o
=>
irq_threshold
,
...
...
@@ -426,47 +438,32 @@ begin
tdc_timestamp_ready
<=
timestamp_ready
;
end
generate
gen_use_real_timestamps
;
timestamp_o
<=
timestamp
;
timestamp_valid_o
<=
timestamp_valid
;
gen_fifos
:
for
i
in
0
to
4
generate
gen_enable_fifo_readout
:
if
g_use_fifo_readout
generate
gen_fifos
:
for
i
in
0
to
4
generate
U_TheFifo
:
entity
work
.
timestamp_fifo
generic
map
(
g_channel
=>
i
)
port
map
(
clk_sys_i
=>
clk_sys_i
,
rst_sys_n_i
=>
rst_sys_n_i
,
slave_i
=>
cnx_master_out
(
c_WB_SLAVE_TDC_FIFO0
+
i
),
slave_o
=>
cnx_master_in
(
c_WB_SLAVE_TDC_FIFO0
+
i
),
irq_o
=>
irq_fifo
(
i
),
enable_i
=>
channel_enable
(
i
),
tick_i
=>
tick_1ms
,
irq_threshold_i
=>
irq_threshold
,
irq_timeout_i
=>
irq_timeout
,
timestamp_i
=>
timestamp
,
timestamp_valid_i
=>
timestamp_stb
,
ts_offset_o
=>
ts_offset
(
i
),
reset_seq_o
=>
reset_seq
(
i
),
raw_enable_o
=>
raw_enable
(
i
));
timestamp_stb
(
i
)
<=
timestamp_valid
(
i
)
and
timestamp_ready
(
i
);
end
generate
gen_fifos
;
end
generate
gen_enable_fifo_readout
;
gen_disable_fifo_readout
:
if
not
g_use_fifo_readout
generate
gen_fifos
:
for
i
in
0
to
4
generate
timestamp_ready
(
i
)
<=
'1'
;
cnx_master_in
(
c_WB_SLAVE_TDC_FIFO0
+
i
)
.
ack
<=
'1'
;
cnx_master_in
(
c_WB_SLAVE_TDC_FIFO0
+
i
)
.
stall
<=
'0'
;
cnx_master_in
(
c_WB_SLAVE_TDC_FIFO0
+
i
)
.
err
<=
'0'
;
cnx_master_in
(
c_WB_SLAVE_TDC_FIFO0
+
i
)
.
rty
<=
'0'
;
end
generate
gen_fifos
;
end
generate
gen_disable_fifo_readout
;
U_TheFifo
:
entity
work
.
timestamp_fifo
generic
map
(
g_use_fifo_readout
=>
g_use_fifo_readout
)
port
map
(
clk_sys_i
=>
clk_sys_i
,
rst_sys_n_i
=>
rst_sys_n_i
,
slave_i
=>
cnx_master_out
(
c_WB_SLAVE_TDC_CHANNEL0
+
i
),
slave_o
=>
cnx_master_in
(
c_WB_SLAVE_TDC_CHANNEL0
+
i
),
irq_o
=>
irq_fifo
(
i
),
enable_i
=>
channel_enable
(
i
),
tick_i
=>
tick_1ms
,
irq_threshold_i
=>
irq_threshold
,
irq_timeout_i
=>
irq_timeout
,
timestamp_i
=>
timestamp
(
i
),
timestamp_valid_i
=>
timestamp_stb
(
i
),
ts_offset_o
=>
ts_offset
(
i
),
reset_seq_o
=>
reset_seq
(
i
),
raw_enable_o
=>
raw_enable
(
i
));
timestamp_stb
(
i
)
<=
timestamp_valid
(
i
)
and
timestamp_ready
(
i
);
end
generate
gen_fifos
;
gen_with_dma_readout
:
if
g_use_dma_readout
generate
U_DMA_Engine
:
entity
work
.
tdc_dma_engine
...
...
@@ -547,8 +544,8 @@ begin
wrabbit_utc_p
<=
'0'
;
else
if
wrabbit_clk_aux_locked_i
=
'1'
and
g_with_wrabbit_core
then
if
unsigned
(
wrabbit_cycles_i
)
=
(
unsigned
(
c_SYN_CLK_PERIOD
)
-3
)
then
-- so that the end of the puls
e
-- comes exactly upon the UTC change
-- so that the end of the pulse comes exactly upon the UTC chang
e
if
unsigned
(
wrabbit_cycles_i
)
=
(
unsigned
(
c_CLK_PERIOD
)
-
3
)
then
wrabbit_utc_p
<=
'1'
;
else
wrabbit_utc_p
<=
'0'
;
...
...
hdl/rtl/fmc_tdc_wrapper.vhd
View file @
6fa0c8c7
...
...
@@ -132,6 +132,14 @@ entity fmc_tdc_wrapper is
g_simulation
:
boolean
:
=
false
;
-- implement direct TDC timestamp readout FIFO, used in the WR Node projects
g_with_direct_readout
:
boolean
:
=
false
;
-- Enable filtering based on pulse width. This will have the following effects:
-- * Suppress theforwarding of negative slope timestamps.
-- * Delay the forwarding of timestamps until after the falling edge timestamp.
-- Once enabled, all pulses wider than 1 second or narrower than
-- g_pulse_width_filter_min will be dropped.
g_pulse_width_filter
:
boolean
:
=
true
;
-- In 8ns ticks.
g_pulse_width_filter_min
:
natural
:
=
12
;
g_use_dma_readout
:
boolean
:
=
false
;
g_use_fifo_readout
:
boolean
:
=
false
;
g_use_fake_timestamps_for_sim
:
boolean
:
=
false
...
...
@@ -242,18 +250,6 @@ end fmc_tdc_wrapper;
--=================================================================================================
architecture
rtl
of
fmc_tdc_wrapper
is
component
fmc_tdc_direct_readout
is
port
(
clk_tdc_i
:
in
std_logic
;
rst_tdc_n_i
:
in
std_logic
;
clk_sys_i
:
in
std_logic
;
rst_sys_n_i
:
in
std_logic
;
direct_timestamp_i
:
in
std_logic_vector
(
127
downto
0
);
direct_timestamp_wr_i
:
in
std_logic
;
direct_slave_i
:
in
t_wishbone_slave_in
;
direct_slave_o
:
out
t_wishbone_slave_out
);
end
component
fmc_tdc_direct_readout
;
-- WRabbit clocks
signal
clk_125m_mezz
:
std_logic
;
signal
rst_125m_mezz_n
,
rst_125m_mezz
:
std_logic
;
...
...
@@ -270,8 +266,8 @@ architecture rtl of fmc_tdc_wrapper is
signal
tdc_scl_out
,
tdc_scl_oen
,
tdc_sda_out
,
tdc_sda_oen
:
std_logic
;
signal
direct_timestamp
:
std_logic_vector
(
127
downto
0
);
signal
direct_timestamp_wr
:
std_logic
;
signal
timestamp
:
t_tdc_timestamp_array
(
4
downto
0
);
signal
timestamp_valid
:
std_logic_vector
(
4
downto
0
)
;
constant
c_cnx_slave_ports
:
integer
:
=
2
;
constant
c_cnx_master_ports
:
integer
:
=
2
;
...
...
@@ -322,16 +318,14 @@ begin
master_i
=>
cnx_master_in
,
master_o
=>
cnx_master_out
);
cmp_direct_readout
:
fmc_tdc_direct_readout
cmp_direct_readout
:
entity
work
.
fmc_tdc_direct_readout
port
map
(
clk_tdc_i
=>
clk_125m_mezz
,
rst_tdc_n_i
=>
rst_125m_mezz_n
,
clk_sys_i
=>
clk_sys_i
,
rst_sys_n_i
=>
rst_sys_n_i
,
direct_timestamp_i
=>
direct_timestamp
,
direct_timestamp_wr_i
=>
direct_timestamp_wr
,
direct_slave_i
=>
cnx_master_out
(
c_slave_direct
),
direct_slave_o
=>
cnx_master_in
(
c_slave_direct
));
clk_sys_i
=>
clk_sys_i
,
rst_sys_n_i
=>
rst_sys_n_i
,
timestamp_i
=>
timestamp
,
timestamp_valid_i
=>
timestamp_valid
,
direct_slave_i
=>
cnx_master_out
(
c_slave_direct
),
direct_slave_o
=>
cnx_master_in
(
c_slave_direct
));
end
generate
gen_with_direct_readout
;
...
...
@@ -406,6 +400,8 @@ begin
(
g_span
=>
32
,
g_width
=>
32
,
g_simulation
=>
g_simulation
,
g_pulse_width_filter
=>
g_pulse_width_filter
,
g_pulse_width_filter_min
=>
g_pulse_width_filter_min
,
g_use_fifo_readout
=>
g_use_fifo_readout
,
g_use_dma_readout
=>
g_use_dma_readout
,
g_use_fake_timestamps_for_sim
=>
g_use_fake_timestamps_for_sim
)
...
...
@@ -482,8 +478,9 @@ begin
i2c_sda_o
=>
tdc_sda_out
,
-- 1-Wire on TDC mezzanine
onewire_b
=>
mezz_one_wire_b
,
direct_timestamp_o
=>
direct_timestamp
,
direct_timestamp_valid_o
=>
direct_timestamp_wr
,
timestamp_o
=>
timestamp
,
timestamp_valid_o
=>
timestamp_valid
,
sim_timestamp_ready_o
=>
sim_timestamp_ready_o
,
sim_timestamp_valid_i
=>
sim_timestamp_valid_i
,
...
...
hdl/rtl/tdc_ts_addsub.vhd
View file @
6fa0c8c7
...
...
@@ -6,17 +6,19 @@
-- Author : Tomasz Wlostowski
-- Company : CERN
-- Created : 2011-08-29
-- Last update: 201
8-09-10
-- Last update: 201
9-09-29
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Pipelined timestamp adder with re-normalization of the result.
-- Adds a to b, producing normalized timestamp q. A timestmap is normalized when
-- the 0 <= frac <
2**g_frac_bits
, 0 <= coarse <= g_coarse_range-1 and utc >= 0.
-- the 0 <= frac <
g_frac_range
, 0 <= coarse <= g_coarse_range-1 and utc >= 0.
-- For correct operation of renormalizer, input timestamps must meet the
-- following constraints:
-- 1. 0 <= (a/b)_frac_i <= 2**g_frac_bits-1
-- 2. -g_coarse_range+1 <= (a_coarse_i + b_coarse_i) <= 3*g_coarse_range-1
-- 1. 0 <= a_tai + b_tai < 2**32 - 1
-- 2. 0 <= a_frac < g_frac_range
-- 3. -g_frac_range / 2 <= b_frac < g_frac_range / 2
-- 4. -g_coarse_range+1 <= (a_coarse + b_coarse) <= 3*g_coarse_range-1
-------------------------------------------------------------------------------
--
-- Copyright (c) 2011 CERN / BE-CO-HT
...
...
@@ -60,7 +62,7 @@ entity tdc_ts_addsub is
a_i
:
in
t_tdc_timestamp
;
b_i
:
in
t_tdc_timestamp
;
valid_o
:
out
std_logic
;
q_o
:
out
t_tdc_timestamp
);
...
...
@@ -71,12 +73,12 @@ architecture rtl of tdc_ts_addsub is
constant
c_NUM_PIPELINE_STAGES
:
integer
:
=
4
;
type
t_internal_sum
is
record
tai
:
signed
(
32
downto
0
);
coarse
:
signed
(
31
downto
0
);
frac
:
signed
(
15
downto
0
);
seq
:
std_logic_vector
(
31
downto
0
);
meta
:
std_logic_vector
(
31
downto
0
);
slope
:
std_logic
;
tai
:
signed
(
32
downto
0
);
coarse
:
signed
(
31
downto
0
);
frac
:
signed
(
15
downto
0
);
channel
:
std_logic_vector
(
2
downto
0
);
meta
:
std_logic_vector
(
31
downto
0
);
slope
:
std_logic
;
end
record
;
type
t_internal_sum_array
is
array
(
integer
range
<>
)
of
t_internal_sum
;
...
...
@@ -88,7 +90,7 @@ architecture rtl of tdc_ts_addsub is
signal
unf_frac
:
std_logic
;
signal
ovf_coarse
:
std_logic_vector
(
1
downto
0
);
signal
unf_coarse
:
std_logic_vector
(
1
downto
0
);
begin
-- rtl
-- Pipeline stage 0: just subtract the two timestamps field by field
...
...
@@ -100,15 +102,13 @@ begin -- rtl
elsif
(
enable_i
=
'1'
)
then
pipe
(
0
)
<=
valid_i
;
sums
(
0
)
.
tai
<=
signed
(
resize
(
unsigned
(
a_i
.
tai
)
+
unsigned
(
b_i
.
tai
),
33
)
);
sums
(
0
)
.
seq
<=
a_i
.
seq
;
sums
(
0
)
.
slope
<=
a_i
.
slope
;
sums
(
0
)
.
meta
<=
a_i
.
meta
;
sums
(
0
)
.
frac
<=
signed
(
resize
(
unsigned
(
a_i
.
frac
),
16
)
+
resize
(
unsigned
(
b_i
.
frac
),
16
)
);
sums
(
0
)
.
coarse
<=
signed
(
resize
(
unsigned
(
a_i
.
coarse
),
sums
(
0
)
.
coarse
'length
)
+
resize
(
unsigned
(
b_i
.
coarse
),
sums
(
0
)
.
coarse
'length
));
sums
(
0
)
.
channel
<=
a_i
.
channel
;
sums
(
0
)
.
slope
<=
a_i
.
slope
;
sums
(
0
)
.
meta
<=
a_i
.
meta
;
sums
(
0
)
.
tai
<=
signed
(
resize
(
unsigned
(
a_i
.
tai
)
+
unsigned
(
b_i
.
tai
),
33
));
sums
(
0
)
.
coarse
<=
signed
(
a_i
.
coarse
)
+
signed
(
b_i
.
coarse
);
sums
(
0
)
.
frac
<=
signed
(
resize
(
signed
(
'0'
&
a_i
.
frac
),
16
)
+
resize
(
signed
(
b_i
.
frac
),
16
));
else
pipe
(
0
)
<=
'0'
;
end
if
;
...
...
@@ -123,17 +123,16 @@ begin -- rtl
p_stage1
:
process
(
clk_i
)
begin
if
rising_edge
(
clk_i
)
then
if
rst_n_i
=
'0'
then
pipe
(
1
)
<=
'0'
;
else
pipe
(
1
)
<=
pipe
(
0
);
sums
(
1
)
.
seq
<=
sums
(
0
)
.
seq
;
sums
(
1
)
.
meta
<=
sums
(
0
)
.
meta
;
sums
(
1
)
.
slope
<=
sums
(
0
)
.
slope
;
sums
(
1
)
<=
sums
(
0
);
sums
(
1
)
<=
sums
(
0
);
sums
(
1
)
<=
sums
(
0
);
if
(
ovf_frac
=
'1'
)
then
sums
(
1
)
.
frac
<=
sums
(
0
)
.
frac
-
g_frac_range
;
sums
(
1
)
.
coarse
<=
sums
(
0
)
.
coarse
+
1
;
...
...
@@ -145,7 +144,6 @@ begin -- rtl
sums
(
1
)
.
coarse
<=
sums
(
0
)
.
coarse
;
end
if
;
sums
(
1
)
.
tai
<=
sums
(
0
)
.
tai
;
end
if
;
end
if
;
end
process
;
...
...
@@ -170,14 +168,14 @@ begin -- rtl
unf_coarse
<=
"00"
;
end
if
;
if
(
sums
(
1
)
.
coarse
>=
g_
frac
_range
)
then
if
(
sums
(
1
)
.
coarse
>=
g_
coarse
_range
)
then
ovf_coarse
<=
"10"
;
elsif
(
sums
(
1
)
.
coarse
>=
2
*
g_
frac
_range
)
then
elsif
(
sums
(
1
)
.
coarse
>=
2
*
g_
coarse
_range
)
then
ovf_coarse
<=
"01"
;
else
ovf_coarse
<=
"00"
;
end
if
;
end
if
;
end
if
;
end
process
;
...
...
@@ -192,9 +190,7 @@ begin -- rtl
else
pipe
(
3
)
<=
pipe
(
2
);
sums
(
3
)
.
seq
<=
sums
(
2
)
.
seq
;
sums
(
3
)
.
slope
<=
sums
(
2
)
.
slope
;
sums
(
3
)
.
meta
<=
sums
(
2
)
.
meta
;
sums
(
3
)
<=
sums
(
2
);
if
(
unf_coarse
=
"10"
)
then
sums
(
3
)
.
coarse
<=
sums
(
2
)
.
coarse
+
g_coarse_range
;
...
...
@@ -213,18 +209,16 @@ begin -- rtl
sums
(
3
)
.
tai
<=
sums
(
2
)
.
tai
;
end
if
;
sums
(
3
)
.
frac
<=
sums
(
2
)
.
frac
;
end
if
;
end
if
;
end
process
;
-- clip the extra bits and output the result
valid_o
<=
pipe
(
c_NUM_PIPELINE_STAGES
-1
);
q_o
.
tai
<=
std_logic_vector
(
sums
(
c_NUM_PIPELINE_STAGES
-1
)
.
tai
(
31
downto
0
));
q_o
.
coarse
<=
std_logic_vector
(
sums
(
c_NUM_PIPELINE_STAGES
-1
)
.
coarse
(
31
downto
0
));
q_o
.
frac
<=
std_logic_vector
(
sums
(
c_NUM_PIPELINE_STAGES
-1
)
.
frac
(
11
downto
0
));
q_o
.
s
eq
<=
sums
(
c_NUM_PIPELINE_STAGES
-1
)
.
seq
;
q_o
.
slope
<=
sums
(
c_NUM_PIPELINE_STAGES
-1
)
.
slope
;
q_o
.
meta
<=
sums
(
c_NUM_PIPELINE_STAGES
-1
)
.
meta
;
valid_o
<=
pipe
(
c_NUM_PIPELINE_STAGES
-1
);
q_o
.
tai
<=
std_logic_vector
(
sums
(
c_NUM_PIPELINE_STAGES
-1
)
.
tai
(
31
downto
0
));
q_o
.
coarse
<=
std_logic_vector
(
sums
(
c_NUM_PIPELINE_STAGES
-1
)
.
coarse
(
31
downto
0
));
q_o
.
frac
<=
std_logic_vector
(
sums
(
c_NUM_PIPELINE_STAGES
-1
)
.
frac
(
11
downto
0
));
q_o
.
s
lope
<=
sums
(
c_NUM_PIPELINE_STAGES
-1
)
.
slope
;
q_o
.
meta
<=
sums
(
c_NUM_PIPELINE_STAGES
-1
)
.
meta
;
q_o
.
channel
<=
sums
(
c_NUM_PIPELINE_STAGES
-1
)
.
channel
;
end
rtl
;
hdl/rtl/timestamp_convert_filter.vhd
View file @
6fa0c8c7
...
...
@@ -8,6 +8,15 @@ use work.gencores_pkg.all;
use
work
.
genram_pkg
.
all
;
entity
timestamp_convert_filter
is
generic
(
-- Enable filtering based on pulse width. This will have the following effects:
-- * Suppress theforwarding of negative slope timestamps.
-- * Delay the forwarding of timestamps until after the falling edge timestamp.
-- Once enabled, all pulses wider than 1 second or narrower than
-- g_PULSE_WIDTH_FILTER_MIN will be dropped.
g_PULSE_WIDTH_FILTER
:
boolean
:
=
TRUE
;
-- In 8ns ticks.
g_PULSE_WIDTH_FILTER_MIN
:
natural
:
=
12
);
port
(
clk_tdc_i
:
in
std_logic
;
rst_tdc_n_i
:
in
std_logic
;
...
...
@@ -26,24 +35,16 @@ entity timestamp_convert_filter is
ts_offset_i
:
in
t_tdc_timestamp_array
(
4
downto
0
);
ts_o
:
out
t_tdc_timestamp_array
(
4
downto
0
);
ts_valid_o
:
buffer
std_logic_vector
(
4
downto
0
);
ts_ready_i
:
in
std_logic_vector
(
4
downto
0
);
direct_timestamp_o
:
out
std_logic_vector
(
127
downto
0
);
direct_timestamp_valid_o
:
out
std_logic
ts_ready_i
:
in
std_logic_vector
(
4
downto
0
)
);
end
timestamp_convert_filter
;
architecture
rtl
of
timestamp_convert_filter
is
constant
c_MIN_PULSE_WIDTH_TICKS
:
integer
:
=
12
;
-- 12 * 8 ns = 96 ns
constant
c_FINE_SF
:
unsigned
(
17
downto
0
)
:
=
to_unsigned
(
84934
,
18
);
constant
c_FINE_SHIFT
:
integer
:
=
11
;
type
t_channel_state
is
record
expected_edge
:
std_logic
;
last_ts
:
t_tdc_timestamp
;
last_valid
:
std_logic
;
seq
:
unsigned
(
31
downto
0
);
...
...
@@ -68,18 +69,19 @@ architecture rtl of timestamp_convert_filter is
signal
s1_channel
,
s2_channel
,
s3_channel
:
std_logic_vector
(
2
downto
0
);
signal
s1_edge
,
s2_edge
,
s3_edge
:
std_logic
;
signal
s3_ts
:
t_tdc_timestamp
;
signal
fifo_we
,
fifo_rd
:
std_logic
;
signal
fifo_empty
,
fifo_rd_d
:
std_logic
;
signal
fifo_d
,
fifo_q
:
std_logic_vector
(
127
downto
0
);
signal
ts_valid_sys
:
std_logic
;
signal
fifo_we
,
fifo_rd
,
fifo_empty
,
fifo_full
,
fifo_rd_d
:
std_logic
;
signal
fifo_d
,
fifo_q
:
std_logic_vector
(
127
downto
0
);
signal
ts_fifo_out
:
t_acam_timestamp
;
signal
ts_valid_preoffset
,
ts_ready_preoffset
,
ts_valid_postoffset
:
std_logic_vector
(
4
downto
0
);
signal
ts_preoffset
,
ts_postoffset
:
t_tdc_timestamp_array
(
4
downto
0
);
signal
s1_meta
,
s2_meta
,
s3_meta
:
std_logic_vector
(
31
downto
0
);
signal
ts_valid_postoffset
:
std_logic
;
signal
ts_valid_preseq
:
std_logic_vector
(
4
downto
0
);
signal
ts_valid_postseq
:
std_logic_vector
(
4
downto
0
);
signal
ts_preoffset
,
ts_postoffset
:
t_tdc_timestamp
;
signal
ts_offset
:
t_tdc_timestamp
;
signal
ts_preseq
,
ts_postseq
:
t_tdc_timestamp_array
(
4
downto
0
);
signal
s1_meta
,
s2_meta
,
s3_meta
:
std_logic_vector
(
31
downto
0
);
function
f_pack_acam_timestamp
(
ts
:
t_acam_timestamp
)
return
std_logic_vector
is
variable
rv
:
std_logic_vector
(
127
downto
0
);
...
...
@@ -93,55 +95,54 @@ architecture rtl of timestamp_convert_filter is
return
rv
;
end
f_pack_acam_timestamp
;
function
f_unpack_acam_timestamp
(
p
:
std_logic_vector
)
return
t_acam_timestamp
is
function
f_unpack_acam_timestamp
(
p
:
std_logic_vector
)
return
t_acam_timestamp
is
variable
ts
:
t_acam_timestamp
;
begin
ts
.
tai
:
=
p
(
31
downto
0
);
ts
.
coarse
:
=
p
(
63
downto
32
);
ts
.
n_bins
:
=
p
(
80
downto
64
);
ts
.
tai
:
=
p
(
31
downto
0
);
ts
.
coarse
:
=
p
(
63
downto
32
);
ts
.
n_bins
:
=
p
(
80
downto
64
);
ts
.
channel
:
=
p
(
83
downto
81
);
ts
.
slope
:
=
p
(
84
);
ts
.
meta
:
=
p
(
116
downto
85
);
ts
.
slope
:
=
p
(
84
);
ts
.
meta
:
=
p
(
116
downto
85
);
return
ts
;
end
f_unpack_acam_timestamp
;
begin
begin
fifo_d
<=
f_pack_acam_timestamp
(
ts_i
);
fifo_d
<=
f_pack_acam_timestamp
(
ts_i
);
fifo_we
<=
ts_valid_i
;
U_Sync_FIFO
:
generic_async_fifo
U_Sync_FIFO
:
generic_async_fifo
generic
map
(
g_data_width
=>
128
,
g_size
=>
16
,
g_show_ahead
=>
false
)
g_data_width
=>
128
,
g_size
=>
16
,
g_show_ahead
=>
FALSE
)
port
map
(
rst_n_i
=>
rst_sys_n_i
,
clk_wr_i
=>
clk_tdc_i
,
d_i
=>
fifo_d
,
we_i
=>
fifo_we
,
clk_rd_i
=>
clk_sys_i
,
q_o
=>
fifo_q
,
rd_i
=>
fifo_rd
,
rd_empty_o
=>
fifo_empty
);
rst_n_i
=>
rst_sys_n_i
,
clk_wr_i
=>
clk_tdc_i
,
d_i
=>
fifo_d
,
we_i
=>
fifo_we
,
clk_rd_i
=>
clk_sys_i
,
q_o
=>
fifo_q
,
rd_i
=>
fifo_rd
,
rd_empty_o
=>
fifo_empty
);
ts_fifo_out
<=
f_unpack_acam_timestamp
(
fifo_q
);
fifo_rd
<=
not
fifo_empty
;
fifo_rd
<=
not
fifo_empty
;
process
(
clk_sys_i
)
begin
if
rising_edge
(
clk_sys_i
)
then
if
rst_sys_n_i
=
'0'
then
s1_valid
<=
'0'
;
s2_valid
<=
'0'
;
s3_valid
<=
'0'
;
s1_valid
<=
'0'
;
s2_valid
<=
'0'
;
s3_valid
<=
'0'
;
fifo_rd_d
<=
'0'
;
else
fifo_rd_d
<=
fifo_rd
;
-- 64/125 = 4096/8000: reduce fraction to avoid 64-bit division
-- 64/125 = 4096/8000: reduce fraction to avoid 64-bit division
-- frac = hwts->bins * 81 * 64 / 125;
-- stage 1: scale frac
...
...
@@ -159,7 +160,7 @@ architecture rtl of timestamp_convert_filter is
s2_tai
<=
s1_tai
;
s2_edge
<=
s1_edge
;
s2_channel
<=
s1_channel
;
s2_meta
<=
s1_meta
;
s2_meta
<=
s1_meta
;
s2_valid
<=
s1_valid
;
-- stage 3: roll-over coarse
...
...
@@ -174,7 +175,7 @@ architecture rtl of timestamp_convert_filter is
s3_tai
<=
s2_tai
;
end
if
;
s3_meta
<=
s2_meta
;
s3_meta
<=
s2_meta
;
s3_frac
<=
s2_frac
;
s3_edge
<=
s2_edge
;
s3_channel
<=
s2_channel
;
...
...
@@ -183,116 +184,126 @@ architecture rtl of timestamp_convert_filter is
end
if
;
end
process
;
s3_ts
.
frac
<=
std_logic_vector
(
s3_frac
);
s3_ts
.
coarse
<=
std_logic_vector
(
s3_coarse
);
s3_ts
.
tai
<=
std_logic_vector
(
s3_tai
);
s3_ts
.
slope
<=
s3_edge
;
s3_ts
.
channel
<=
s3_channel
;
s3_ts
.
meta
<=
s3_meta
;
ts_preoffset
.
frac
<=
std_logic_vector
(
s3_frac
);
ts_preoffset
.
coarse
<=
std_logic_vector
(
s3_coarse
);
ts_preoffset
.
tai
<=
std_logic_vector
(
s3_tai
);
ts_preoffset
.
slope
<=
s3_edge
;
ts_preoffset
.
channel
<=
s3_channel
;
ts_preoffset
.
meta
<=
s3_meta
;
ts_offset
<=
ts_offset_i
(
to_integer
(
unsigned
(
s3_channel
)));
U_Offset_Adder
:
entity
work
.
tdc_ts_addsub
port
map
(
clk_i
=>
clk_sys_i
,
rst_n_i
=>
rst_sys_n_i
,
valid_i
=>
s3_valid
,
enable_i
=>
'1'
,
a_i
=>
ts_preoffset
,
b_i
=>
ts_offset
,
valid_o
=>
ts_valid_postoffset
,
q_o
=>
ts_postoffset
);
p_direct_output
:
process
(
clk_sys_i
)
begin
if
rising_edge
(
clk_sys_i
)
then
if
rst_sys_n_i
=
'0'
then
direct_timestamp_valid_o
<=
'0'
;
else
direct_timestamp_o
(
31
downto
0
)
<=
s3_ts
.
tai
;
direct_timestamp_o
(
63
downto
32
)
<=
s3_ts
.
coarse
;
direct_timestamp_o
(
95
downto
64
)
<=
x"00000"
&
s3_ts
.
frac
;
direct_timestamp_o
(
96
+
2
downto
96
)
<=
s3_ts
.
channel
;
direct_timestamp_o
(
96
+
3
)
<=
s3_ts
.
slope
;
direct_timestamp_o
(
127
downto
100
)
<=
(
others
=>
'0'
);
direct_timestamp_valid_o
<=
s3_valid
;
end
if
;
end
if
;
end
process
;
gen_channels
:
for
i
in
0
to
4
generate
p_fsm
:
process
(
clk_sys_i
)
begin
if
rising_edge
(
clk_sys_i
)
then
if
rst_sys_n_i
=
'0'
or
enable_i
(
i
)
=
'0'
then
ts_valid_preoffset
(
i
)
<=
'0'
;
channels
(
i
)
.
expected_edge
<=
'1'
;
channels
(
i
)
.
s1_valid
<=
'0'
;
channels
(
i
)
.
s2_valid
<=
'0'
;
channels
(
i
)
.
last_valid
<=
'0'
;
channels
(
i
)
.
seq
<=
(
others
=>
'0'
);
else
channels
(
i
)
.
s1_valid
<=
'0'
;
gen_with_pwidth_filter
:
if
g_PULSE_WIDTH_FILTER
generate
p_fsm
:
process
(
clk_sys_i
)
begin
if
rising_edge
(
clk_sys_i
)
then
if
rst_sys_n_i
=
'0'
or
enable_i
(
i
)
=
'0'
then
ts_valid_preseq
(
i
)
<=
'0'
;
channels
(
i
)
.
s1_valid
<=
'0'
;
channels
(
i
)
.
s2_valid
<=
'0'
;
channels
(
i
)
.
last_valid
<=
'0'
;
else
channels
(
i
)
.
s1_valid
<=
'0'
;
if
(
reset_seq_i
(
i
)
=
'1'
)
then
channels
(
i
)
.
seq
<=
(
others
=>
'0'
);
end
if
;
if
ts_valid_postoffset
=
'1'
and
unsigned
(
ts_postoffset
.
channel
)
=
i
then
if
(
ts_postoffset
.
slope
=
'1'
)
then
-- rising edge
channels
(
i
)
.
last_ts
<=
ts_postoffset
;
channels
(
i
)
.
last_valid
<=
'1'
;
channels
(
i
)
.
s1_valid
<=
'0'
;
else
channels
(
i
)
.
last_valid
<=
'0'
;
channels
(
i
)
.
s1_valid
<=
'1'
;
end
if
;
if
s3_valid
=
'1'
and
unsigned
(
s3_channel
)
=
i
then
channels
(
i
)
.
s1_delta_coarse
<=
unsigned
(
ts_postoffset
.
coarse
)
-
unsigned
(
channels
(
i
)
.
last_ts
.
coarse
);
if
(
s3_ts
.
slope
=
'1'
)
then
-- rising edge
channels
(
i
)
.
last_ts
<=
s3_ts
;
channels
(
i
)
.
last_valid
<=
'1'
;
channels
(
i
)
.
s1_valid
<=
'0'
;
else
channels
(
i
)
.
last_valid
<=
'0'
;
channels
(
i
)
.
s1_valid
<=
'1'
;
channels
(
i
)
.
s1_delta_tai
<=
unsigned
(
ts_postoffset
.
tai
)
-
unsigned
(
channels
(
i
)
.
last_ts
.
tai
);
end
if
;
channels
(
i
)
.
s1_delta_coarse
<=
unsigned
(
s3_ts
.
coarse
)
-
unsigned
(
channels
(
i
)
.
last_ts
.
coarse
);
channels
(
i
)
.
s1_delta_tai
<=
unsigned
(
s3_ts
.
tai
)
-
unsigned
(
channels
(
i
)
.
last_ts
.
tai
);
end
if
;
if
channels
(
i
)
.
s1_delta_coarse
(
31
)
=
'1'
then
channels
(
i
)
.
s2_delta_coarse
<=
channels
(
i
)
.
s1_delta_coarse
+
to_unsigned
(
125000000
,
32
);
channels
(
i
)
.
s2_delta_tai
<=
channels
(
i
)
.
s1_delta_tai
-
1
;
else
channels
(
i
)
.
s2_delta_coarse
<=
channels
(
i
)
.
s1_delta_coarse
;
channels
(
i
)
.
s2_delta_tai
<=
channels
(
i
)
.
s1_delta_tai
;
end
if
;
channels
(
i
)
.
s2_valid
<=
channels
(
i
)
.
s1_valid
;
if
channels
(
i
)
.
s1_delta_coarse
(
31
)
=
'1'
then
channels
(
i
)
.
s2_delta_coarse
<=
channels
(
i
)
.
s1_delta_coarse
+
to_unsigned
(
125000000
,
32
);
channels
(
i
)
.
s2_delta_tai
<=
channels
(
i
)
.
s1_delta_tai
-
1
;
else
channels
(
i
)
.
s2_delta_coarse
<=
channels
(
i
)
.
s1_delta_coarse
;
channels
(
i
)
.
s2_delta_tai
<=
channels
(
i
)
.
s1_delta_tai
;
end
if
;
if
channels
(
i
)
.
s2_valid
=
'1'
then
if
channels
(
i
)
.
s2_delta_tai
=
0
and
channels
(
i
)
.
s2_delta_coarse
>=
12
then
channels
(
i
)
.
s2_valid
<=
channels
(
i
)
.
s1_valid
;
ts_preoffset
(
i
)
.
tai
<=
channels
(
i
)
.
last_ts
.
tai
;
ts_preoffset
(
i
)
.
coarse
<=
channels
(
i
)
.
last_ts
.
coarse
;
ts_preoffset
(
i
)
.
frac
<=
channels
(
i
)
.
last_ts
.
frac
;
ts_preoffset
(
i
)
.
channel
<=
channels
(
i
)
.
last_ts
.
channel
;
ts_preoffset
(
i
)
.
slope
<=
channels
(
i
)
.
last_ts
.
slope
;
ts_preoffset
(
i
)
.
meta
<=
channels
(
i
)
.
last_ts
.
meta
;
if
channels
(
i
)
.
s2_valid
=
'1'
then
if
channels
(
i
)
.
s2_delta_tai
=
0
and
channels
(
i
)
.
s2_delta_coarse
>=
12
then
ts_valid_preoffset
(
i
)
<=
'1'
;
ts_preseq
(
i
)
.
tai
<=
channels
(
i
)
.
last_ts
.
tai
;
ts_preseq
(
i
)
.
coarse
<=
channels
(
i
)
.
last_ts
.
coarse
;
ts_preseq
(
i
)
.
frac
<=
channels
(
i
)
.
last_ts
.
frac
;
ts_preseq
(
i
)
.
channel
<=
channels
(
i
)
.
last_ts
.
channel
;
ts_preseq
(
i
)
.
slope
<=
channels
(
i
)
.
last_ts
.
slope
;
ts_preseq
(
i
)
.
meta
<=
channels
(
i
)
.
last_ts
.
meta
;
if
(
reset_seq_i
(
i
)
=
'1'
)
then
channels
(
i
)
.
seq
<=
(
others
=>
'0'
);
ts_preoffset
(
i
)
.
seq
<=
(
others
=>
'0'
);
ts_valid_preseq
(
i
)
<=
'1'
;
else
channels
(
i
)
.
seq
<=
channels
(
i
)
.
seq
+
1
;
ts_preoffset
(
i
)
.
seq
<=
std_logic_vector
(
channels
(
i
)
.
seq
);
ts_valid_preseq
(
i
)
<=
'0'
;
end
if
;
else
ts_valid_pre
offset
(
i
)
<=
'0'
;
ts_valid_pre
seq
(
i
)
<=
'0'
;
end
if
;
end
if
;
end
if
;
end
process
p_fsm
;
end
generate
gen_with_pwidth_filter
;
gen_without_pwidth_filter
:
if
not
g_PULSE_WIDTH_FILTER
generate
p_fsm
:
process
(
clk_sys_i
)
begin
if
rising_edge
(
clk_sys_i
)
then
if
rst_sys_n_i
=
'0'
or
enable_i
(
i
)
=
'0'
then
ts_valid_preseq
(
i
)
<=
'0'
;
else
ts_valid_preoffset
(
i
)
<=
'0'
;
if
ts_valid_postoffset
=
'1'
and
unsigned
(
ts_postoffset
.
channel
)
=
i
then
ts_valid_preseq
(
i
)
<=
'1'
;
ts_preseq
(
i
)
<=
ts_postoffset
;
else
ts_valid_preseq
(
i
)
<=
'0'
;
end
if
;
end
if
;
end
if
;
end
process
p_fsm
;
end
generate
gen_without_pwidth_filter
;
p_seq_count
:
process
(
clk_sys_i
)
is
begin
if
rising_edge
(
clk_sys_i
)
then
if
rst_sys_n_i
=
'0'
or
enable_i
(
i
)
=
'0'
or
reset_seq_i
(
i
)
=
'1'
then
channels
(
i
)
.
seq
<=
(
others
=>
'0'
);
else
if
ts_valid_preseq
(
i
)
=
'1'
then
channels
(
i
)
.
seq
<=
channels
(
i
)
.
seq
+
1
;
ts_valid_postseq
(
i
)
<=
'1'
;
ts_postseq
(
i
)
<=
ts_preseq
(
i
);
ts_postseq
(
i
)
.
seq
<=
std_logic_vector
(
channels
(
i
)
.
seq
);
else
ts_valid_postseq
(
i
)
<=
'0'
;
end
if
;
end
if
;
end
if
;
end
process
;
U_Offset_Adder
:
entity
work
.
tdc_ts_addsub
port
map
(
clk_i
=>
clk_sys_i
,
rst_n_i
=>
rst_sys_n_i
,
valid_i
=>
ts_valid_preoffset
(
i
),
enable_i
=>
'1'
,
a_i
=>
ts_preoffset
(
i
),
b_i
=>
ts_offset_i
(
i
),
valid_o
=>
ts_valid_postoffset
(
i
),
q_o
=>
ts_postoffset
(
i
));
end
process
p_seq_count
;
p_output
:
process
(
clk_sys_i
)
begin
...
...
@@ -306,31 +317,21 @@ architecture rtl of timestamp_convert_filter is
end
if
;
if
raw_enable_i
(
i
)
=
'1'
then
--if ts_valid_sys = '1' and unsigned(ts_latched.channel) = i then
-- ts_valid_o(i) <= '1';
-- ts_o(i).raw <= ts_latched.raw;
--end if;
else
if
ts_valid_postoffset
(
i
)
=
'1'
then
if
ts_valid_postseq
(
i
)
=
'1'
then
ts_valid_o
(
i
)
<=
'1'
;
ts_o
(
i
)
<=
ts_post
offset
(
i
);
ts_o
(
i
)
<=
ts_post
seq
(
i
);
end
if
;
end
if
;
end
if
;
end
if
;
end
process
;
end
generate
gen_channels
;
end
rtl
;
hdl/rtl/timestamp_fifo.vhd
View file @
6fa0c8c7
...
...
@@ -23,14 +23,14 @@ use ieee.std_logic_1164.all;
use
ieee
.
NUMERIC_STD
.
all
;
use
work
.
tsf_wbgen2_pkg
.
all
;
use
work
.
ch_reg_wbgen2_pkg
.
all
;
use
work
.
tdc_core_pkg
.
all
;
use
work
.
wishbone_pkg
.
all
;
use
work
.
gencores_pkg
.
all
;
entity
timestamp_fifo
is
generic
(
g_channel
:
integer
);
g_USE_FIFO_READOUT
:
boolean
:
=
TRUE
);
port
(
clk_sys_i
:
in
std_logic
;
rst_sys_n_i
:
in
std_logic
;
...
...
@@ -47,8 +47,8 @@ entity timestamp_fifo is
irq_threshold_i
:
in
std_logic_vector
(
9
downto
0
);
irq_timeout_i
:
in
std_logic_vector
(
9
downto
0
);
timestamp_i
:
in
t_tdc_timestamp
_array
(
4
downto
0
)
;
timestamp_valid_i
:
in
std_logic
_vector
(
4
downto
0
)
;
timestamp_i
:
in
t_tdc_timestamp
;
timestamp_valid_i
:
in
std_logic
;
ts_offset_o
:
out
t_tdc_timestamp
;
reset_seq_o
:
out
std_logic
;
...
...
@@ -64,74 +64,70 @@ architecture rtl of timestamp_fifo is
signal
buf_count
:
unsigned
(
9
downto
0
);
signal
last_ts
:
std_logic_vector
(
127
downto
0
);
signal
regs_in
:
t_tsf_in_registers
;
signal
regs_out
:
t_tsf_out_registers
;
signal
channel_id
:
std_logic_vector
(
2
downto
0
);
signal
ts_match
:
std_logic
;
signal
timestamp_with_seq
:
std_logic_vector
(
127
downto
0
);
signal
ref_valid
:
std_logic
;
signal
ref_ts
:
t_tdc_timestamp
;
signal
ref_channel
:
integer
range
0
to
4
;
signal
sub_valid
:
std_logic
;
signal
sub_in_valid
,
sub_out_valid
:
std_logic
;
signal
sub_result
:
t_tdc_timestamp
;
signal
sub_result_latched
:
t_tdc_timestamp
;
signal
sub_out_valid_latched
:
std_logic
;
begin
signal
channel_reg_in
:
t_ch_reg_in_registers
;
signal
channel_reg_out
:
t_ch_reg_out_registers
;
signal
channel_reg_slave_in
:
t_wishbone_slave_in
;
signal
channel_reg_slave_out
:
t_wishbone_slave_out
;
ts_offset_o
.
tai
<=
regs_out
.
offset1_o
;
ts_offset_o
.
coarse
<=
regs_out
.
offset2_o
;
ts_offset_o
.
frac
<=
regs_out
.
offset3_o
(
11
downto
0
);
reset_seq_o
<=
regs_out
.
csr_rst_seq_o
;
raw_enable_o
<=
regs_out
.
csr_raw_mode_o
;
signal
fifo_reg_in
:
t_tsf_in_registers
;
signal
fifo_reg_out
:
t_tsf_out_registers
;
signal
fifo_reg_slave_in
:
t_wishbone_slave_in
;
signal
fifo_reg_slave_out
:
t_wishbone_slave_out
;
timestamp_with_seq
(
31
downto
0
)
<=
std_logic_vector
(
resize
(
unsigned
(
timestamp_i
(
g_channel
)
.
tai
),
32
));
timestamp_with_seq
(
63
downto
32
)
<=
std_logic_vector
(
resize
(
unsigned
(
timestamp_i
(
g_channel
)
.
coarse
),
32
));
timestamp_with_seq
(
95
downto
64
)
<=
std_logic_vector
(
resize
(
unsigned
(
timestamp_i
(
g_channel
)
.
frac
),
32
));
timestamp_with_seq
(
98
downto
96
)
<=
timestamp_i
(
g_channel
)
.
channel
;
timestamp_with_seq
(
99
)
<=
timestamp_i
(
g_channel
)
.
slope
;
timestamp_with_seq
(
127
downto
100
)
<=
timestamp_i
(
g_channel
)
.
seq
(
27
downto
0
);
begin
-- Hack to maintain backward compatibility with previous
-- versions of the code when channel_regs and fifo_regs were
-- part of the same wbgen source, and the FIFO registers were
-- right after the channel registers.
--
-- For this to work now and in the future (without editing),
-- slave_i.adr must be byte addressed, and there can be no more
-- than 8 32-bit channel registers.
p_wb_mux
:
process
(
channel_reg_slave_out
,
fifo_reg_slave_out
,
slave_i
)
is
begin
-- register access
if
slave_i
.
adr
(
5
)
=
'0'
then
channel_reg_slave_in
<=
slave_i
;
slave_o
<=
channel_reg_slave_out
;
fifo_reg_slave_in
<=
c_DUMMY_WB_SLAVE_IN
;
-- FIFO access
else
fifo_reg_slave_in
<=
slave_i
;
fifo_reg_slave_in
.
adr
(
5
)
<=
'0'
;
slave_o
<=
fifo_reg_slave_out
;
channel_reg_slave_in
<=
c_DUMMY_WB_SLAVE_IN
;
end
if
;
end
process
p_wb_mux
;
U_
WB_Slave
:
entity
work
.
timestamp_fifo_wb
U_
CHANNEL_REG_WB_Slave
:
channel_regs
port
map
(
rst_n_i
=>
rst_sys_n_i
,
clk_sys_i
=>
clk_sys_i
,
slave_i
=>
slave_i
,
slave_o
=>
slave_o
,
regs_i
=>
regs
_in
,
regs_o
=>
regs
_out
);
slave_i
=>
channel_reg_slave_in
,
slave_o
=>
channel_reg_slave_out
,
regs_i
=>
channel_reg
_in
,
regs_o
=>
channel_reg
_out
);
buf_count
<=
resize
(
unsigned
(
regs_out
.
fifo_wr_usedw_o
),
10
);
ts_match
<=
timestamp_valid_i
(
g_channel
);
p_fifo_write
:
process
(
clk_sys_i
)
begin
if
rising_edge
(
clk_sys_i
)
then
if
rst_sys_n_i
=
'0'
then
regs_in
.
fifo_wr_req_i
<=
'0'
;
else
ts_offset_o
.
tai
<=
channel_reg_out
.
offset1_o
;
ts_offset_o
.
coarse
<=
channel_reg_out
.
offset2_o
;
ts_offset_o
.
frac
<=
channel_reg_out
.
offset3_o
(
11
downto
0
);
if
(
enable_i
=
'1'
and
regs_out
.
fifo_wr_full_o
=
'0'
and
ts_match
=
'1'
)
then
regs_in
.
fifo_wr_req_i
<=
'1'
;
else
regs_in
.
fifo_wr_req_i
<=
'0'
;
end
if
;
end
if
;
end
if
;
end
process
;
reset_seq_o
<=
channel_reg_out
.
csr_rst_seq_o
;
regs_in
.
fifo_ts0_i
<=
timestamp_with_seq
(
31
downto
0
);
regs_in
.
fifo_ts1_i
<=
timestamp_with_seq
(
63
downto
32
);
regs_in
.
fifo_ts2_i
<=
timestamp_with_seq
(
95
downto
64
);
regs_in
.
fifo_ts3_i
<=
timestamp_with_seq
(
127
downto
96
);
raw_enable_o
<=
channel_reg_out
.
csr_raw_mode_o
;
p_latch_ref_timestamp
:
process
(
clk_sys_i
)
begin
...
...
@@ -140,23 +136,23 @@ begin
ref_valid
<=
'0'
;
else
-- latch only the last rising edge TS
if
(
enable_i
=
'1'
and
timestamp_valid_i
(
ref_channel
)
=
'1'
)
then
if
(
enable_i
=
'1'
and
timestamp_valid_i
=
'1'
)
then
ref_valid
<=
'1'
;
ref_ts
<=
timestamp_i
(
ref_channel
)
;
ref_ts
<=
timestamp_i
;
end
if
;
end
if
;
end
if
;
end
process
;
sub_valid
<=
ref_valid
and
t
s_match
;
U_Subtractor
:
entity
work
.
tdc_ts_sub
sub_valid
<=
ref_valid
and
t
imestamp_valid_i
;
U_Subtractor
:
entity
work
.
tdc_ts_sub
port
map
(
clk_i
=>
clk_sys_i
,
rst_n_i
=>
rst_sys_n_i
,
valid_i
=>
sub_in_valid
,
enable_i
=>
enable_i
,
a_i
=>
timestamp_i
(
g_channel
)
,
a_i
=>
timestamp_i
,
b_i
=>
ref_ts
,
valid_o
=>
sub_out_valid
,
q_o
=>
sub_result
);
...
...
@@ -167,57 +163,108 @@ begin
if
rst_sys_n_i
=
'0'
or
enable_i
=
'0'
then
sub_out_valid_latched
<=
'0'
;
else
if
regs
_out
.
csr_delta_read_o
=
'1'
then
sub_out_valid_latched
<=
'0'
;
regs
_in
.
delta1_i
<=
sub_result_latched
.
tai
;
regs
_in
.
delta2_i
<=
sub_result_latched
.
coarse
;
regs
_in
.
delta3_i
<=
x"00000"
&
sub_result_latched
.
frac
;
if
channel_reg
_out
.
csr_delta_read_o
=
'1'
then
sub_out_valid_latched
<=
'0'
;
channel_reg
_in
.
delta1_i
<=
sub_result_latched
.
tai
;
channel_reg
_in
.
delta2_i
<=
sub_result_latched
.
coarse
;
channel_reg
_in
.
delta3_i
<=
x"00000"
&
sub_result_latched
.
frac
;
end
if
;
if
(
sub_out_valid
=
'1'
)
then
sub_out_valid_latched
<=
'1'
;
sub_result_latched
<=
sub_result
;
sub_result_latched
<=
sub_result
;
end
if
;
end
if
;
end
if
;
end
process
;
regs_in
.
csr_delta_ready_i
<=
sub_out_valid_latched
;
p_coalesce_irq
:
process
(
clk_sys_i
)
begin
if
rising_edge
(
clk_sys_i
)
then
if
rst_sys_n_i
=
'0'
or
enable_i
=
'0'
then
buf_irq_int
<=
'0'
;
else
if
(
regs_out
.
fifo_wr_empty_o
=
'1'
)
then
channel_reg_in
.
csr_delta_ready_i
<=
sub_out_valid_latched
;
gen_without_fifo_readout
:
if
not
g_USE_FIFO_READOUT
generate
fifo_reg_slave_out
<=
c_DUMMY_WB_SLAVE_OUT
;
fifo_reg_out
<=
c_tsf_out_registers_init_value
;
irq_o
<=
'0'
;
end
generate
gen_without_fifo_readout
;
gen_with_fifo_readout
:
if
g_USE_FIFO_READOUT
generate
timestamp_with_seq
(
31
downto
0
)
<=
std_logic_vector
(
resize
(
unsigned
(
timestamp_i
.
tai
),
32
));
timestamp_with_seq
(
63
downto
32
)
<=
std_logic_vector
(
resize
(
unsigned
(
timestamp_i
.
coarse
),
32
));
timestamp_with_seq
(
95
downto
64
)
<=
std_logic_vector
(
resize
(
unsigned
(
timestamp_i
.
frac
),
32
));
timestamp_with_seq
(
98
downto
96
)
<=
timestamp_i
.
channel
;
timestamp_with_seq
(
99
)
<=
timestamp_i
.
slope
;
timestamp_with_seq
(
127
downto
100
)
<=
timestamp_i
.
seq
(
27
downto
0
);
U_FIFO_WB_Slave
:
timestamp_fifo_wb
port
map
(
rst_n_i
=>
rst_sys_n_i
,
clk_sys_i
=>
clk_sys_i
,
slave_i
=>
fifo_reg_slave_in
,
slave_o
=>
fifo_reg_slave_out
,
regs_i
=>
fifo_reg_in
,
regs_o
=>
fifo_reg_out
);
buf_count
<=
resize
(
unsigned
(
fifo_reg_out
.
fifo_wr_usedw_o
),
10
);
p_fifo_write
:
process
(
clk_sys_i
)
begin
if
rising_edge
(
clk_sys_i
)
then
if
rst_sys_n_i
=
'0'
then
fifo_reg_in
.
fifo_wr_req_i
<=
'0'
;
else
if
(
enable_i
=
'1'
and
fifo_reg_out
.
fifo_wr_full_o
=
'0'
and
timestamp_valid_i
=
'1'
)
then
fifo_reg_in
.
fifo_wr_req_i
<=
'1'
;
else
fifo_reg_in
.
fifo_wr_req_i
<=
'0'
;
end
if
;
end
if
;
end
if
;
end
process
;
fifo_reg_in
.
fifo_ts0_i
<=
timestamp_with_seq
(
31
downto
0
);
fifo_reg_in
.
fifo_ts1_i
<=
timestamp_with_seq
(
63
downto
32
);
fifo_reg_in
.
fifo_ts2_i
<=
timestamp_with_seq
(
95
downto
64
);
fifo_reg_in
.
fifo_ts3_i
<=
timestamp_with_seq
(
127
downto
96
);
p_coalesce_irq
:
process
(
clk_sys_i
)
begin
if
rising_edge
(
clk_sys_i
)
then
if
rst_sys_n_i
=
'0'
or
enable_i
=
'0'
then
buf_irq_int
<=
'0'
;
tmr_timeout
<=
(
others
=>
'0'
);
else
if
(
fifo_reg_out
.
fifo_wr_empty_o
=
'1'
)
then
buf_irq_int
<=
'0'
;
tmr_timeout
<=
(
others
=>
'0'
);
else
-- Simple interrupt coalescing :
-- Case 1: There is some data in the buffer
-- (but not exceeding the threshold) - assert the IRQ line after a
-- certain timeout.
if
(
buf_irq_int
=
'0'
)
then
if
(
tmr_timeout
=
unsigned
(
irq_timeout_i
(
9
downto
0
)))
then
buf_irq_int
<=
'1'
;
tmr_timeout
<=
(
others
=>
'0'
);
elsif
(
tick_i
=
'1'
)
then
tmr_timeout
<=
tmr_timeout
+
1
;
if
(
buf_irq_int
=
'0'
)
then
if
(
tmr_timeout
=
unsigned
(
irq_timeout_i
(
9
downto
0
)))
then
buf_irq_int
<=
'1'
;
tmr_timeout
<=
(
others
=>
'0'
);
elsif
(
tick_i
=
'1'
)
then
tmr_timeout
<=
tmr_timeout
+
1
;
end
if
;
end
if
;
end
if
;
-- Case 2: amount of data exceeded the threshold - assert the IRQ
-- line immediately.
if
(
regs_out
.
fifo_wr_full_o
=
'1'
or
(
buf_count
>
unsigned
(
irq_threshold_i
(
9
downto
0
))))
then
buf_irq_int
<=
'1'
;
if
(
fifo_reg_out
.
fifo_wr_full_o
=
'1'
or
(
buf_count
>
unsigned
(
irq_threshold_i
(
9
downto
0
))))
then
buf_irq_int
<=
'1'
;
end
if
;
end
if
;
end
if
;
end
if
;
end
if
;
end
process
;
end
process
;
irq_o
<=
buf_irq_int
;
irq_o
<=
buf_irq_in
t
;
end
generate
gen_with_fifo_readou
t
;
end
rtl
;
hdl/rtl/timestamp_fifo_wb.vhd
View file @
6fa0c8c7
...
...
@@ -3,7 +3,7 @@
---------------------------------------------------------------------------------------
-- File : timestamp_fifo_wb.vhd
-- Author : auto-generated by wbgen2 from wbgen/timestamp_fifo_wb.wb
-- Created :
Sun Sep 2 15:37:55 2018
-- Created :
Thu Sep 26 16:42:08 2019
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wbgen/timestamp_fifo_wb.wb
...
...
@@ -20,15 +20,15 @@ use work.tsf_wbgen2_pkg.all;
entity
timestamp_fifo_wb
is
port
(
rst_n_i
:
in
std_logic
;
clk_sys_i
:
in
std_logic
;
slave_i
:
in
t_wishbone_slave_in
;
slave_o
:
out
t_wishbone_slave_out
;
int_o
:
out
std_logic
;
regs_i
:
in
t_tsf_in_registers
;
regs_o
:
out
t_tsf_out_registers
);
port
(
rst_n_i
:
in
std_logic
;
clk_sys_i
:
in
std_logic
;
slave_i
:
in
t_wishbone_slave_in
;
slave_o
:
out
t_wishbone_slave_out
;
int_o
:
out
std_logic
;
regs_i
:
in
t_tsf_in_registers
;
regs_o
:
out
t_tsf_out_registers
);
end
timestamp_fifo_wb
;
architecture
syn
of
timestamp_fifo_wb
is
...
...
@@ -38,15 +38,6 @@ signal tsf_fifo_in_int : std_logic_vector(127 downto 0)
signal
tsf_fifo_out_int
:
std_logic_vector
(
127
downto
0
);
signal
tsf_fifo_rdreq_int
:
std_logic
;
signal
tsf_fifo_rdreq_int_d0
:
std_logic
;
signal
tsf_offset1_int
:
std_logic_vector
(
31
downto
0
);
signal
tsf_offset2_int
:
std_logic_vector
(
31
downto
0
);
signal
tsf_offset3_int
:
std_logic_vector
(
31
downto
0
);
signal
tsf_csr_delta_read_dly0
:
std_logic
;
signal
tsf_csr_delta_read_int
:
std_logic
;
signal
tsf_csr_rst_seq_dly0
:
std_logic
;
signal
tsf_csr_rst_seq_int
:
std_logic
;
signal
tsf_csr_delta_ref_int
:
std_logic_vector
(
2
downto
0
);
signal
tsf_csr_raw_mode_int
:
std_logic
;
signal
tsf_fifo_full_int
:
std_logic
;
signal
tsf_fifo_empty_int
:
std_logic
;
signal
tsf_fifo_clear_bus_int
:
std_logic
;
...
...
@@ -55,7 +46,7 @@ signal ack_sreg : std_logic_vector(9 downto 0);
signal
rddata_reg
:
std_logic_vector
(
31
downto
0
);
signal
wrdata_reg
:
std_logic_vector
(
31
downto
0
);
signal
bwsel_reg
:
std_logic_vector
(
3
downto
0
);
signal
rwaddr_reg
:
std_logic_vector
(
3
downto
0
);
signal
rwaddr_reg
:
std_logic_vector
(
2
downto
0
);
signal
ack_in_progress
:
std_logic
;
signal
wr_int
:
std_logic
;
signal
rd_int
:
std_logic
;
...
...
@@ -64,278 +55,151 @@ signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments
wrdata_reg
<=
slave_i
.
dat
;
wrdata_reg
<=
slave_i
.
dat
;
--
-- Main register bank access process.
process
(
clk_sys_i
,
rst_n_i
)
begin
if
(
rst_n_i
=
'0'
)
then
ack_sreg
<=
"0000000000"
;
ack_in_progress
<=
'0'
;
rddata_reg
<=
"00000000000000000000000000000000"
;
tsf_offset1_int
<=
"00000000000000000000000000000000"
;
tsf_offset2_int
<=
"00000000000000000000000000000000"
;
tsf_offset3_int
<=
"00000000000000000000000000000000"
;
tsf_csr_delta_read_int
<=
'0'
;
tsf_csr_rst_seq_int
<=
'0'
;
tsf_csr_delta_ref_int
<=
"000"
;
tsf_csr_raw_mode_int
<=
'0'
;
tsf_fifo_clear_bus_int
<=
'0'
;
tsf_fifo_rdreq_int
<=
'0'
;
elsif
rising_edge
(
clk_sys_i
)
then
process
(
clk_sys_i
,
rst_n_i
)
begin
if
(
rst_n_i
=
'0'
)
then
ack_sreg
<=
"0000000000"
;
ack_in_progress
<=
'0'
;
rddata_reg
<=
"00000000000000000000000000000000"
;
tsf_fifo_clear_bus_int
<=
'0'
;
tsf_fifo_rdreq_int
<=
'0'
;
elsif
rising_edge
(
clk_sys_i
)
then
-- advance the ACK generator shift register
ack_sreg
(
8
downto
0
)
<=
ack_sreg
(
9
downto
1
);
ack_sreg
(
9
)
<=
'0'
;
if
(
ack_in_progress
=
'1'
)
then
if
(
ack_sreg
(
0
)
=
'1'
)
then
tsf_csr_delta_read
_int
<=
'0'
;
tsf_csr_rst_seq_int
<=
'0'
;
tsf_fifo_clear_bus_int
<=
'0'
;
ack_in_progress
<=
'0'
;
ack_sreg
(
8
downto
0
)
<=
ack_sreg
(
9
downto
1
);
ack_sreg
(
9
)
<=
'0'
;
if
(
ack_in_progress
=
'1'
)
then
if
(
ack_sreg
(
0
)
=
'1'
)
then
tsf_fifo_clear_bus
_int
<=
'0'
;
ack_in_progress
<=
'0'
;
else
end
if
;
else
end
if
;
else
if
((
slave_i
.
cyc
=
'1'
)
and
(
slave_i
.
stb
=
'1'
))
then
case
rwaddr_reg
(
3
downto
0
)
is
when
"0000"
=>
if
(
slave_i
.
we
=
'1'
)
then
end
if
;
rddata_reg
(
31
downto
0
)
<=
regs_i
.
delta1_i
;
ack_sreg
(
0
)
<=
'1'
;
ack_in_progress
<=
'1'
;
when
"0001"
=>
if
(
slave_i
.
we
=
'1'
)
then
end
if
;
rddata_reg
(
31
downto
0
)
<=
regs_i
.
delta2_i
;
ack_sreg
(
0
)
<=
'1'
;
ack_in_progress
<=
'1'
;
when
"0010"
=>
if
(
slave_i
.
we
=
'1'
)
then
end
if
;
rddata_reg
(
31
downto
0
)
<=
regs_i
.
delta3_i
;
ack_sreg
(
0
)
<=
'1'
;
ack_in_progress
<=
'1'
;
when
"0011"
=>
if
(
slave_i
.
we
=
'1'
)
then
tsf_offset1_int
<=
wrdata_reg
(
31
downto
0
);
end
if
;
rddata_reg
(
31
downto
0
)
<=
tsf_offset1_int
;
ack_sreg
(
0
)
<=
'1'
;
ack_in_progress
<=
'1'
;
when
"0100"
=>
if
(
slave_i
.
we
=
'1'
)
then
tsf_offset2_int
<=
wrdata_reg
(
31
downto
0
);
end
if
;
rddata_reg
(
31
downto
0
)
<=
tsf_offset2_int
;
ack_sreg
(
0
)
<=
'1'
;
ack_in_progress
<=
'1'
;
when
"0101"
=>
if
(
slave_i
.
we
=
'1'
)
then
tsf_offset3_int
<=
wrdata_reg
(
31
downto
0
);
end
if
;
rddata_reg
(
31
downto
0
)
<=
tsf_offset3_int
;
ack_sreg
(
0
)
<=
'1'
;
ack_in_progress
<=
'1'
;
when
"0110"
=>
if
(
slave_i
.
we
=
'1'
)
then
tsf_csr_delta_read_int
<=
wrdata_reg
(
1
);
tsf_csr_rst_seq_int
<=
wrdata_reg
(
2
);
tsf_csr_delta_ref_int
<=
wrdata_reg
(
5
downto
3
);
tsf_csr_raw_mode_int
<=
wrdata_reg
(
6
);
end
if
;
rddata_reg
(
0
)
<=
regs_i
.
csr_delta_ready_i
;
rddata_reg
(
1
)
<=
'0'
;
rddata_reg
(
2
)
<=
'0'
;
rddata_reg
(
5
downto
3
)
<=
tsf_csr_delta_ref_int
;
rddata_reg
(
6
)
<=
tsf_csr_raw_mode_int
;
rddata_reg
(
7
)
<=
'X'
;
rddata_reg
(
8
)
<=
'X'
;
rddata_reg
(
9
)
<=
'X'
;
rddata_reg
(
10
)
<=
'X'
;
rddata_reg
(
11
)
<=
'X'
;
rddata_reg
(
12
)
<=
'X'
;
rddata_reg
(
13
)
<=
'X'
;
rddata_reg
(
14
)
<=
'X'
;
rddata_reg
(
15
)
<=
'X'
;
rddata_reg
(
16
)
<=
'X'
;
rddata_reg
(
17
)
<=
'X'
;
rddata_reg
(
18
)
<=
'X'
;
rddata_reg
(
19
)
<=
'X'
;
rddata_reg
(
20
)
<=
'X'
;
rddata_reg
(
21
)
<=
'X'
;
rddata_reg
(
22
)
<=
'X'
;
rddata_reg
(
23
)
<=
'X'
;
rddata_reg
(
24
)
<=
'X'
;
rddata_reg
(
25
)
<=
'X'
;
rddata_reg
(
26
)
<=
'X'
;
rddata_reg
(
27
)
<=
'X'
;
rddata_reg
(
28
)
<=
'X'
;
rddata_reg
(
29
)
<=
'X'
;
rddata_reg
(
30
)
<=
'X'
;
rddata_reg
(
31
)
<=
'X'
;
ack_sreg
(
2
)
<=
'1'
;
ack_in_progress
<=
'1'
;
when
"0111"
=>
if
(
slave_i
.
we
=
'1'
)
then
end
if
;
if
(
tsf_fifo_rdreq_int_d0
=
'0'
)
then
tsf_fifo_rdreq_int
<=
not
tsf_fifo_rdreq_int
;
else
rddata_reg
(
31
downto
0
)
<=
tsf_fifo_out_int
(
31
downto
0
);
if
((
slave_i
.
cyc
=
'1'
)
and
(
slave_i
.
stb
=
'1'
))
then
case
rwaddr_reg
(
2
downto
0
)
is
when
"000"
=>
if
(
slave_i
.
we
=
'1'
)
then
end
if
;
if
(
tsf_fifo_rdreq_int_d0
=
'0'
)
then
tsf_fifo_rdreq_int
<=
not
tsf_fifo_rdreq_int
;
else
rddata_reg
(
31
downto
0
)
<=
tsf_fifo_out_int
(
31
downto
0
);
ack_in_progress
<=
'1'
;
ack_sreg
(
0
)
<=
'1'
;
end
if
;
when
"001"
=>
if
(
slave_i
.
we
=
'1'
)
then
end
if
;
rddata_reg
(
31
downto
0
)
<=
tsf_fifo_out_int
(
63
downto
32
);
ack_sreg
(
0
)
<=
'1'
;
ack_in_progress
<=
'1'
;
when
"010"
=>
if
(
slave_i
.
we
=
'1'
)
then
end
if
;
rddata_reg
(
31
downto
0
)
<=
tsf_fifo_out_int
(
95
downto
64
);
ack_sreg
(
0
)
<=
'1'
;
end
if
;
when
"1000"
=>
if
(
slave_i
.
we
=
'1'
)
then
end
if
;
rddata_reg
(
31
downto
0
)
<=
tsf_fifo_out_int
(
63
downto
32
);
ack_sreg
(
0
)
<=
'1'
;
ack_in_progress
<=
'1'
;
when
"1001"
=>
if
(
slave_i
.
we
=
'1'
)
then
end
if
;
rddata_reg
(
31
downto
0
)
<=
tsf_fifo_out_int
(
95
downto
64
);
ack_sreg
(
0
)
<=
'1'
;
ack_in_progress
<=
'1'
;
when
"1010"
=>
if
(
slave_i
.
we
=
'1'
)
then
end
if
;
rddata_reg
(
31
downto
0
)
<=
tsf_fifo_out_int
(
127
downto
96
);
ack_sreg
(
0
)
<=
'1'
;
ack_in_progress
<=
'1'
;
when
"1011"
=>
if
(
slave_i
.
we
=
'1'
)
then
if
(
wrdata_reg
(
18
)
=
'1'
)
then
tsf_fifo_clear_bus_int
<=
'1'
;
ack_in_progress
<=
'1'
;
when
"011"
=>
if
(
slave_i
.
we
=
'1'
)
then
end
if
;
rddata_reg
(
31
downto
0
)
<=
tsf_fifo_out_int
(
127
downto
96
);
ack_sreg
(
0
)
<=
'1'
;
ack_in_progress
<=
'1'
;
when
"100"
=>
if
(
slave_i
.
we
=
'1'
)
then
if
(
wrdata_reg
(
18
)
=
'1'
)
then
tsf_fifo_clear_bus_int
<=
'1'
;
end
if
;
end
if
;
end
if
;
rddata_reg
(
16
)
<=
tsf_fifo_full_int
;
rddata_reg
(
17
)
<=
tsf_fifo_empty_int
;
rddata_reg
(
18
)
<=
'0'
;
rddata_reg
(
5
downto
0
)
<=
tsf_fifo_usedw_int
;
rddata_reg
(
6
)
<=
'X'
;
rddata_reg
(
7
)
<=
'X'
;
rddata_reg
(
8
)
<=
'X'
;
rddata_reg
(
9
)
<=
'X'
;
rddata_reg
(
10
)
<=
'X'
;
rddata_reg
(
11
)
<=
'X'
;
rddata_reg
(
12
)
<=
'X'
;
rddata_reg
(
13
)
<=
'X'
;
rddata_reg
(
14
)
<=
'X'
;
rddata_reg
(
15
)
<=
'X'
;
rddata_reg
(
19
)
<=
'X'
;
rddata_reg
(
20
)
<=
'X'
;
rddata_reg
(
21
)
<=
'X'
;
rddata_reg
(
22
)
<=
'X'
;
rddata_reg
(
23
)
<=
'X'
;
rddata_reg
(
24
)
<=
'X'
;
rddata_reg
(
25
)
<=
'X'
;
rddata_reg
(
26
)
<=
'X'
;
rddata_reg
(
27
)
<=
'X'
;
rddata_reg
(
28
)
<=
'X'
;
rddata_reg
(
29
)
<=
'X'
;
rddata_reg
(
30
)
<=
'X'
;
rddata_reg
(
31
)
<=
'X'
;
ack_sreg
(
0
)
<=
'1'
;
ack_in_progress
<=
'1'
;
when
others
=>
rddata_reg
(
16
)
<=
tsf_fifo_full_int
;
rddata_reg
(
17
)
<=
tsf_fifo_empty_int
;
rddata_reg
(
18
)
<=
'0'
;
rddata_reg
(
5
downto
0
)
<=
tsf_fifo_usedw_int
;
rddata_reg
(
6
)
<=
'X'
;
rddata_reg
(
7
)
<=
'X'
;
rddata_reg
(
8
)
<=
'X'
;
rddata_reg
(
9
)
<=
'X'
;
rddata_reg
(
10
)
<=
'X'
;
rddata_reg
(
11
)
<=
'X'
;
rddata_reg
(
12
)
<=
'X'
;
rddata_reg
(
13
)
<=
'X'
;
rddata_reg
(
14
)
<=
'X'
;
rddata_reg
(
15
)
<=
'X'
;
rddata_reg
(
19
)
<=
'X'
;
rddata_reg
(
20
)
<=
'X'
;
rddata_reg
(
21
)
<=
'X'
;
rddata_reg
(
22
)
<=
'X'
;
rddata_reg
(
23
)
<=
'X'
;
rddata_reg
(
24
)
<=
'X'
;
rddata_reg
(
25
)
<=
'X'
;
rddata_reg
(
26
)
<=
'X'
;
rddata_reg
(
27
)
<=
'X'
;
rddata_reg
(
28
)
<=
'X'
;
rddata_reg
(
29
)
<=
'X'
;
rddata_reg
(
30
)
<=
'X'
;
rddata_reg
(
31
)
<=
'X'
;
ack_sreg
(
0
)
<=
'1'
;
ack_in_progress
<=
'1'
;
when
others
=>
-- prevent the slave from hanging the bus on invalid address
ack_in_progress
<=
'1'
;
ack_sreg
(
0
)
<=
'1'
;
end
case
;
ack_in_progress
<=
'1'
;
ack_sreg
(
0
)
<=
'1'
;
end
case
;
end
if
;
end
if
;
end
if
;
end
if
;
end
process
;
end
process
;
-- Drive the data output bus
slave_o
.
dat
<=
rddata_reg
;
slave_o
.
dat
<=
rddata_reg
;
-- extra code for reg/fifo/mem: Timestamp FIFO
tsf_fifo_in_int
(
31
downto
0
)
<=
regs_i
.
fifo_ts0_i
;
tsf_fifo_in_int
(
63
downto
32
)
<=
regs_i
.
fifo_ts1_i
;
tsf_fifo_in_int
(
95
downto
64
)
<=
regs_i
.
fifo_ts2_i
;
tsf_fifo_in_int
(
127
downto
96
)
<=
regs_i
.
fifo_ts3_i
;
tsf_fifo_rst_n
<=
rst_n_i
and
(
not
tsf_fifo_clear_bus_int
);
tsf_fifo_INST
:
wbgen2_fifo_sync
generic
map
(
g_size
=>
64
,
g_width
=>
128
,
g_usedw_size
=>
6
)
port
map
(
wr_req_i
=>
regs_i
.
fifo_wr_req_i
,
wr_full_o
=>
regs_o
.
fifo_wr_full_o
,
wr_empty_o
=>
regs_o
.
fifo_wr_empty_o
,
wr_usedw_o
=>
regs_o
.
fifo_wr_usedw_o
,
rd_full_o
=>
tsf_fifo_full_int
,
rd_empty_o
=>
tsf_fifo_empty_int
,
rd_usedw_o
=>
tsf_fifo_usedw_int
,
rd_req_i
=>
tsf_fifo_rdreq_int
,
rst_n_i
=>
tsf_fifo_rst_n
,
clk_i
=>
clk_sys_i
,
wr_data_i
=>
tsf_fifo_in_int
,
rd_data_o
=>
tsf_fifo_out_int
);
-- Delta Timestamp Word 1 (TAI cycles, signed)
-- Delta Timestamp Word 2 (8ns ticks, unsigned)
-- Delta Timestamp Word 3 (fractional part, unsigned)
-- Channel Offset Word 1 (TAI cycles, signed)
regs_o
.
offset1_o
<=
tsf_offset1_int
;
-- Channel Offset Word 2 (8ns ticks, unsigned)
regs_o
.
offset2_o
<=
tsf_offset2_int
;
-- Channel Offset Word 3 (fractional part, unsigned)
regs_o
.
offset3_o
<=
tsf_offset3_int
;
-- Delta Timestamp Ready
-- Read Delta Timestamp
process
(
clk_sys_i
,
rst_n_i
)
begin
if
(
rst_n_i
=
'0'
)
then
tsf_csr_delta_read_dly0
<=
'0'
;
regs_o
.
csr_delta_read_o
<=
'0'
;
elsif
rising_edge
(
clk_sys_i
)
then
tsf_csr_delta_read_dly0
<=
tsf_csr_delta_read_int
;
regs_o
.
csr_delta_read_o
<=
tsf_csr_delta_read_int
and
(
not
tsf_csr_delta_read_dly0
);
end
if
;
end
process
;
-- Reset Sequence Counter
process
(
clk_sys_i
,
rst_n_i
)
begin
if
(
rst_n_i
=
'0'
)
then
tsf_csr_rst_seq_dly0
<=
'0'
;
regs_o
.
csr_rst_seq_o
<=
'0'
;
elsif
rising_edge
(
clk_sys_i
)
then
tsf_csr_rst_seq_dly0
<=
tsf_csr_rst_seq_int
;
regs_o
.
csr_rst_seq_o
<=
tsf_csr_rst_seq_int
and
(
not
tsf_csr_rst_seq_dly0
);
end
if
;
end
process
;
-- Delta Timestamp Reference Channel
regs_o
.
csr_delta_ref_o
<=
tsf_csr_delta_ref_int
;
-- Raw readout mode
regs_o
.
csr_raw_mode_o
<=
tsf_csr_raw_mode_int
;
tsf_fifo_in_int
(
31
downto
0
)
<=
regs_i
.
fifo_ts0_i
;
tsf_fifo_in_int
(
63
downto
32
)
<=
regs_i
.
fifo_ts1_i
;
tsf_fifo_in_int
(
95
downto
64
)
<=
regs_i
.
fifo_ts2_i
;
tsf_fifo_in_int
(
127
downto
96
)
<=
regs_i
.
fifo_ts3_i
;
tsf_fifo_rst_n
<=
rst_n_i
and
(
not
tsf_fifo_clear_bus_int
);
tsf_fifo_INST
:
wbgen2_fifo_sync
generic
map
(
g_size
=>
64
,
g_width
=>
128
,
g_usedw_size
=>
6
)
port
map
(
wr_req_i
=>
regs_i
.
fifo_wr_req_i
,
wr_full_o
=>
regs_o
.
fifo_wr_full_o
,
wr_empty_o
=>
regs_o
.
fifo_wr_empty_o
,
wr_usedw_o
=>
regs_o
.
fifo_wr_usedw_o
,
rd_full_o
=>
tsf_fifo_full_int
,
rd_empty_o
=>
tsf_fifo_empty_int
,
rd_usedw_o
=>
tsf_fifo_usedw_int
,
rd_req_i
=>
tsf_fifo_rdreq_int
,
rst_n_i
=>
tsf_fifo_rst_n
,
clk_i
=>
clk_sys_i
,
wr_data_i
=>
tsf_fifo_in_int
,
rd_data_o
=>
tsf_fifo_out_int
);
-- extra code for reg/fifo/mem: FIFO 'Timestamp FIFO' data output register 0
process
(
clk_sys_i
,
rst_n_i
)
begin
if
(
rst_n_i
=
'0'
)
then
tsf_fifo_rdreq_int_d0
<=
'0'
;
elsif
rising_edge
(
clk_sys_i
)
then
tsf_fifo_rdreq_int_d0
<=
tsf_fifo_rdreq_int
;
end
if
;
end
process
;
process
(
clk_sys_i
,
rst_n_i
)
begin
if
(
rst_n_i
=
'0'
)
then
tsf_fifo_rdreq_int_d0
<=
'0'
;
elsif
rising_edge
(
clk_sys_i
)
then
tsf_fifo_rdreq_int_d0
<=
tsf_fifo_rdreq_int
;
end
if
;
end
process
;
-- extra code for reg/fifo/mem: FIFO 'Timestamp FIFO' data output register 1
-- extra code for reg/fifo/mem: FIFO 'Timestamp FIFO' data output register 2
-- extra code for reg/fifo/mem: FIFO 'Timestamp FIFO' data output register 3
rwaddr_reg
<=
slave_i
.
adr
(
5
downto
2
);
slave_o
.
stall
<=
(
not
ack_sreg
(
0
))
and
(
slave_i
.
stb
and
slave_i
.
cyc
);
slave_o
.
err
<=
'0'
;
slave_o
.
rty
<=
'0'
;
rwaddr_reg
<=
slave_i
.
adr
(
4
downto
2
);
slave_o
.
stall
<=
(
not
ack_sreg
(
0
))
and
(
slave_i
.
stb
and
slave_i
.
cyc
);
slave_o
.
err
<=
'0'
;
slave_o
.
rty
<=
'0'
;
-- ACK signal generation. Just pass the LSB of ACK counter.
slave_o
.
ack
<=
ack_sreg
(
0
);
slave_o
.
ack
<=
ack_sreg
(
0
);
end
syn
;
hdl/rtl/timestamp_fifo_wbgen2_pkg.vhd
View file @
6fa0c8c7
...
...
@@ -3,7 +3,7 @@
---------------------------------------------------------------------------------------
-- File : timestamp_fifo_wbgen2_pkg.vhd
-- Author : auto-generated by wbgen2 from wbgen/timestamp_fifo_wb.wb
-- Created :
Sun Sep 2 15:37:55 2018
-- Created :
Thu Sep 26 16:42:08 2019
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wbgen/timestamp_fifo_wb.wb
...
...
@@ -27,10 +27,6 @@ package tsf_wbgen2_pkg is
fifo_ts1_i
:
std_logic_vector
(
31
downto
0
);
fifo_ts2_i
:
std_logic_vector
(
31
downto
0
);
fifo_ts3_i
:
std_logic_vector
(
31
downto
0
);
delta1_i
:
std_logic_vector
(
31
downto
0
);
delta2_i
:
std_logic_vector
(
31
downto
0
);
delta3_i
:
std_logic_vector
(
31
downto
0
);
csr_delta_ready_i
:
std_logic
;
end
record
;
constant
c_tsf_in_registers_init_value
:
t_tsf_in_registers
:
=
(
...
...
@@ -38,11 +34,7 @@ package tsf_wbgen2_pkg is
fifo_ts0_i
=>
(
others
=>
'0'
),
fifo_ts1_i
=>
(
others
=>
'0'
),
fifo_ts2_i
=>
(
others
=>
'0'
),
fifo_ts3_i
=>
(
others
=>
'0'
),
delta1_i
=>
(
others
=>
'0'
),
delta2_i
=>
(
others
=>
'0'
),
delta3_i
=>
(
others
=>
'0'
),
csr_delta_ready_i
=>
'0'
fifo_ts3_i
=>
(
others
=>
'0'
)
);
-- Output registers (WB slave -> user design)
...
...
@@ -51,82 +43,64 @@ package tsf_wbgen2_pkg is
fifo_wr_full_o
:
std_logic
;
fifo_wr_empty_o
:
std_logic
;
fifo_wr_usedw_o
:
std_logic_vector
(
5
downto
0
);
offset1_o
:
std_logic_vector
(
31
downto
0
);
offset2_o
:
std_logic_vector
(
31
downto
0
);
offset3_o
:
std_logic_vector
(
31
downto
0
);
csr_delta_read_o
:
std_logic
;
csr_rst_seq_o
:
std_logic
;
csr_delta_ref_o
:
std_logic_vector
(
2
downto
0
);
csr_raw_mode_o
:
std_logic
;
end
record
;
constant
c_tsf_out_registers_init_value
:
t_tsf_out_registers
:
=
(
fifo_wr_full_o
=>
'0'
,
fifo_wr_empty_o
=>
'0'
,
fifo_wr_usedw_o
=>
(
others
=>
'0'
),
offset1_o
=>
(
others
=>
'0'
),
offset2_o
=>
(
others
=>
'0'
),
offset3_o
=>
(
others
=>
'0'
),
csr_delta_read_o
=>
'0'
,
csr_rst_seq_o
=>
'0'
,
csr_delta_ref_o
=>
(
others
=>
'0'
),
csr_raw_mode_o
=>
'0'
fifo_wr_usedw_o
=>
(
others
=>
'0'
)
);
function
"or"
(
left
,
right
:
t_tsf_in_registers
)
return
t_tsf_in_registers
;
function
f_x_to_zero
(
x
:
std_logic
)
return
std_logic
;
function
f_x_to_zero
(
x
:
std_logic_vector
)
return
std_logic_vector
;
component
timestamp_fifo_wb
is
port
(
rst_n_i
:
in
std_logic
;
clk_sys_i
:
in
std_logic
;
slave_i
:
in
t_wishbone_slave_in
;
slave_o
:
out
t_wishbone_slave_out
;
int_o
:
out
std_logic
;
regs_i
:
in
t_tsf_in_registers
;
regs_o
:
out
t_tsf_out_registers
);
end
component
;
function
"or"
(
left
,
right
:
t_tsf_in_registers
)
return
t_tsf_in_registers
;
function
f_x_to_zero
(
x
:
std_logic
)
return
std_logic
;
function
f_x_to_zero
(
x
:
std_logic_vector
)
return
std_logic_vector
;
component
timestamp_fifo_wb
is
port
(
rst_n_i
:
in
std_logic
;
clk_sys_i
:
in
std_logic
;
slave_i
:
in
t_wishbone_slave_in
;
slave_o
:
out
t_wishbone_slave_out
;
int_o
:
out
std_logic
;
regs_i
:
in
t_tsf_in_registers
;
regs_o
:
out
t_tsf_out_registers
);
end
component
;
end
package
;
package
body
tsf_wbgen2_pkg
is
function
f_x_to_zero
(
x
:
std_logic
)
return
std_logic
is
begin
if
x
=
'1'
then
return
'1'
;
else
return
'0'
;
end
if
;
end
function
;
function
f_x_to_zero
(
x
:
std_logic_vector
)
return
std_logic_vector
is
variable
tmp
:
std_logic_vector
(
x
'length
-1
downto
0
);
begin
for
i
in
0
to
x
'length
-1
loop
if
(
x
(
i
)
=
'X'
or
x
(
i
)
=
'U'
)
then
tmp
(
i
):
=
'0'
;
function
f_x_to_zero
(
x
:
std_logic
)
return
std_logic
is
begin
if
x
=
'1'
then
return
'1'
;
else
tmp
(
i
):
=
x
(
i
);
end
if
;
end
loop
;
return
tmp
;
end
function
;
function
"or"
(
left
,
right
:
t_tsf_in_registers
)
return
t_tsf_in_registers
is
variable
tmp
:
t_tsf_in_registers
;
begin
tmp
.
fifo_wr_req_i
:
=
f_x_to_zero
(
left
.
fifo_wr_req_i
)
or
f_x_to_zero
(
right
.
fifo_wr_req_i
);
tmp
.
fifo_ts0_i
:
=
f_x_to_zero
(
left
.
fifo_ts0_i
)
or
f_x_to_zero
(
right
.
fifo_ts0_i
);
tmp
.
fifo_ts1_i
:
=
f_x_to_zero
(
left
.
fifo_ts1_i
)
or
f_x_to_zero
(
right
.
fifo_ts1_i
);
tmp
.
fifo_ts2_i
:
=
f_x_to_zero
(
left
.
fifo_ts2_i
)
or
f_x_to_zero
(
right
.
fifo_ts2_i
);
tmp
.
fifo_ts3_i
:
=
f_x_to_zero
(
left
.
fifo_ts3_i
)
or
f_x_to_zero
(
right
.
fifo_ts3_i
);
tmp
.
delta1_i
:
=
f_x_to_zero
(
left
.
delta1_i
)
or
f_x_to_zero
(
right
.
delta1_i
);
tmp
.
delta2_i
:
=
f_x_to_zero
(
left
.
delta2_i
)
or
f_x_to_zero
(
right
.
delta2_i
);
tmp
.
delta3_i
:
=
f_x_to_zero
(
left
.
delta3_i
)
or
f_x_to_zero
(
right
.
delta3_i
);
tmp
.
csr_delta_ready_i
:
=
f_x_to_zero
(
left
.
csr_delta_ready_i
)
or
f_x_to_zero
(
right
.
csr_delta_ready_i
);
return
tmp
;
end
function
;
return
'0'
;
end
if
;
end
function
;
function
f_x_to_zero
(
x
:
std_logic_vector
)
return
std_logic_vector
is
variable
tmp
:
std_logic_vector
(
x
'length
-1
downto
0
);
begin
for
i
in
0
to
x
'length
-1
loop
if
(
x
(
i
)
=
'1'
)
then
tmp
(
i
):
=
'1'
;
else
tmp
(
i
):
=
'0'
;
end
if
;
end
loop
;
return
tmp
;
end
function
;
function
"or"
(
left
,
right
:
t_tsf_in_registers
)
return
t_tsf_in_registers
is
variable
tmp
:
t_tsf_in_registers
;
begin
tmp
.
fifo_wr_req_i
:
=
f_x_to_zero
(
left
.
fifo_wr_req_i
)
or
f_x_to_zero
(
right
.
fifo_wr_req_i
);
tmp
.
fifo_ts0_i
:
=
f_x_to_zero
(
left
.
fifo_ts0_i
)
or
f_x_to_zero
(
right
.
fifo_ts0_i
);
tmp
.
fifo_ts1_i
:
=
f_x_to_zero
(
left
.
fifo_ts1_i
)
or
f_x_to_zero
(
right
.
fifo_ts1_i
);
tmp
.
fifo_ts2_i
:
=
f_x_to_zero
(
left
.
fifo_ts2_i
)
or
f_x_to_zero
(
right
.
fifo_ts2_i
);
tmp
.
fifo_ts3_i
:
=
f_x_to_zero
(
left
.
fifo_ts3_i
)
or
f_x_to_zero
(
right
.
fifo_ts3_i
);
return
tmp
;
end
function
;
end
package
body
;
hdl/rtl/wbgen/channel_regs.wb
0 → 100644
View file @
6fa0c8c7
-- -*- Mode: LUA; tab-width: 2 -*-
peripheral {
name = "Channel registers";
prefix="ch_reg";
hdl_entity="channel_regs";
reg {
name = "Delta Timestamp Word 1";
prefix = "DELTA1";
field {
name = "Delta Timestamp Word 1 (TAI cycles, signed)";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "Delta Timestamp Word 2";
prefix = "DELTA2";
field {
name = "Delta Timestamp Word 2 (8ns ticks, unsigned)";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "Delta Timestamp Word 3";
prefix = "DELTA3";
field {
name = "Delta Timestamp Word 3 (fractional part, unsigned)";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "Channel Offset Word 1";
prefix = "OFFSET1";
field {
name = "Channel Offset Word 1 (TAI cycles, signed)";
type = SLV;
size = 32;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "Channel Offset Word 2";
prefix = "OFFSET2";
field {
name = "Channel Offset Word 2 (8ns ticks, unsigned)";
type = SLV;
size = 32;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "Channel Offset Word 3";
prefix = "OFFSET3";
field {
name = "Channel Offset Word 3 (fractional part, unsigned)";
type = SLV;
size = 32;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "Control/Status";
prefix = "CSR";
field {
name = "Delta Timestamp Ready";
prefix = "DELTA_READY";
type = BIT;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
field {
name = "Read Delta Timestamp";
prefix = "DELTA_READ";
type = MONOSTABLE;
};
field {
name = "Reset Sequence Counter";
prefix = "RST_SEQ";
type = MONOSTABLE;
};
field {
name = "Delta Timestamp Reference Channel";
description = "Channel (0-4) to take as the reference for the delta timestamps";
prefix = "DELTA_REF";
type = SLV;
size = 3;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
field {
name = "Raw readout mode";
description = "1: enables readout of raw timestamps";
prefix = "RAW_MODE";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
};
hdl/rtl/wbgen/fmc_tdc_direct_readout_slave.wb
View file @
6fa0c8c7
...
...
@@ -13,8 +13,6 @@ peripheral
flags_bus = {FIFO_EMPTY, FIFO_FULL, FIFO_COUNT, FIFO_RESET};
flags_dev = {FIFO_EMPTY, FIFO_FULL, FIFO_COUNT, FIFO_RESET};
clock = "clk_tdc_i";
field {
name = "Seconds";
prefix = "SECONDS";
...
...
@@ -53,7 +51,6 @@ peripheral
reg {
name = "Channel Enable Register";
prefix = "CHAN_ENABLE";
clock = "clk_tdc_i";
field {
name = "Channel enable";
size = 5;
...
...
@@ -66,8 +63,6 @@ peripheral
reg {
name = "Dead Time Register";
prefix = "DEAD_TIME";
clock = "clk_tdc_i";
field {
name = "Dead time (8ns ticks)";
size = 24;
...
...
@@ -76,4 +71,4 @@ peripheral
access_dev = READ_ONLY;
};
};
};
\ No newline at end of file
};
hdl/rtl/wbgen/timestamp_fifo_wb.wb
View file @
6fa0c8c7
...
...
@@ -45,134 +45,4 @@ peripheral {
size = 32;
};
};
reg {
name = "Delta Timestamp Word 1";
prefix = "DELTA1";
field {
name = "Delta Timestamp Word 1 (TAI cycles, signed)";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "Delta Timestamp Word 2";
prefix = "DELTA2";
field {
name = "Delta Timestamp Word 2 (8ns ticks, unsigned)";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "Delta Timestamp Word 3";
prefix = "DELTA3";
field {
name = "Delta Timestamp Word 3 (fractional part, unsigned)";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "Channel Offset Word 1";
prefix = "OFFSET1";
field {
name = "Channel Offset Word 1 (TAI cycles, signed)";
type = SLV;
size = 32;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "Channel Offset Word 2";
prefix = "OFFSET2";
field {
name = "Channel Offset Word 2 (8ns ticks, unsigned)";
type = SLV;
size = 32;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "Channel Offset Word 3";
prefix = "OFFSET3";
field {
name = "Channel Offset Word 3 (fractional part, unsigned)";
type = SLV;
size = 32;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "Control/Status";
prefix = "CSR";
field {
name = "Delta Timestamp Ready";
prefix = "DELTA_READY";
type = BIT;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
field {
name = "Read Delta Timestamp";
prefix = "DELTA_READ";
type = MONOSTABLE;
};
field {
name = "Reset Sequence Counter";
prefix = "RST_SEQ";
type = MONOSTABLE;
};
field {
name = "Delta Timestamp Reference Channel";
description = "Channel (0-4) to take as the reference for the delta timestamps";
prefix = "DELTA_REF";
type = SLV;
size = 3;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
field {
name = "Raw readout mode";
description = "1: enables readout of raw timestamps";
prefix = "RAW_MODE";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
};
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