Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
F
FMC DEL 1ns 4cha
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
2
Issues
2
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 DEL 1ns 4cha
Commits
adf2cf8c
Commit
adf2cf8c
authored
Aug 30, 2011
by
Tomasz Wlostowski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ACAM timestamper: working counter sync
parent
ac2786b3
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
82 additions
and
68 deletions
+82
-68
fd_acam_timestamper.vhd
hdl/rtl/fd_acam_timestamper.vhd
+82
-68
No files found.
hdl/rtl/fd_acam_timestamper.vhd
View file @
adf2cf8c
...
...
@@ -6,7 +6,7 @@
-- Author : Tomasz Wlostowski
-- Company : CERN
-- Created : 2011-08-24
-- Last update: 2011-08-
26
-- Last update: 2011-08-
30
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
...
...
@@ -106,7 +106,7 @@ entity fd_acam_timestamper is
tag_rearm_p1_i
:
in
std_logic
;
-- single-cycle pulse indicates presence of a valid time tag on the tag_xxx_o lines.
tag_valid_
p1_
o
:
out
std_logic
;
tag_valid_o
:
out
std_logic
;
-------------------------------------------------------------------------------
-- Time base synchronization/alignment (clk_ref_i domain). Must not be used
...
...
@@ -135,36 +135,31 @@ end fd_acam_timestamper;
architecture
behavioral
of
fd_acam_timestamper
is
-- FIFO timeout in clk_ref_i cycles. If there's no data in the ACAM FIFO
-- c_ACAM_TIMEOUT after the trigger pulse, we ignore the tag it and reset the TDC.
constant
c_ACAM_TIMEOUT
:
integer
:
=
60
;
-- Value which ACAM adds to each timestamp to avoid negative numbers. Must match
-- the value written to ACAM control registers by the driver.
--constant c_ACAM_START_OFFSET : integer := 10000;
-- Timestamp "wraparound" parameters, used to merge the coarse timestamp
-- produced inside the FPGA with the fine value obtained from ACAM.
--constant c_WRAPAROUND_START_THRESHOLD : integer := 1;
--constant c_WRAPAROUND_FRAC_THRESHOLD : integer := 2000 + c_ACAM_START_OFFSET*3;
-- Refernce clock period in picoseconds
-- constant c_REFCLK_PERIOD : real := 8000.0;
-- ACAM bin size in picoseconds (calculated from the reference clock frequency and ACAM's
-- PLL parameters - see TDC-GPX datasheet page 15).
--constant c_ACAM_BIN_SIZE : real := 27.0127677;
component
fd_ts_adder
generic
(
g_frac_bits
:
integer
;
g_coarse_bits
:
integer
;
g_utc_bits
:
integer
;
g_coarse_range
:
integer
);
port
(
clk_i
:
in
std_logic
;
rst_n_i
:
in
std_logic
;
valid_i
:
in
std_logic
;
a_utc_i
:
in
std_logic_vector
(
g_utc_bits
-1
downto
0
);
a_coarse_i
:
in
std_logic_vector
(
g_coarse_bits
-1
downto
0
);
a_frac_i
:
in
std_logic_vector
(
g_frac_bits
-1
downto
0
);
b_utc_i
:
in
std_logic_vector
(
g_utc_bits
-1
downto
0
);
b_coarse_i
:
in
std_logic_vector
(
g_coarse_bits
-1
downto
0
);
b_frac_i
:
in
std_logic_vector
(
g_frac_bits
-1
downto
0
);
valid_o
:
out
std_logic
;
q_utc_o
:
out
std_logic_vector
(
g_utc_bits
-1
downto
0
);
q_coarse_o
:
out
std_logic_vector
(
g_coarse_bits
-1
downto
0
);
q_frac_o
:
out
std_logic_vector
(
g_frac_bits
-1
downto
0
));
end
component
;
-- Number of scaling coefficient fractional bits. Too low = low resolution,
-- too high = unmet timing constraints.
constant
c_ACAM_TIMEOUT
:
integer
:
=
60
;
constant
c_SCALER_SHIFT
:
integer
:
=
12
;
-- Scale factor between ACAM bins and WR timebase
-- constant c_FRAC_SCALEFACTOR : integer := integer(real(2**((g_frac_bits-1) + c_SCALER_SHIFT)) * c_ACAM_BIN_SIZE / c_REFCLK_PERIOD);
-- states of the main ACAM FSM reading/writing data from/to the TDC
type
t_acam_fsm_state
is
(
IDLE
,
R_ADDR
,
R_PULSE
,
R_READ
,
W_DATA_ADDR
,
W_PULSE
,
W_WAIT
,
RMODE_PURGE_FIFO
,
...
...
@@ -203,7 +198,7 @@ architecture behavioral of fd_acam_timestamper is
-- delay/sync chains
signal
tdc_start_d
:
std_logic_vector
(
2
downto
0
);
signal
trig_d
:
std_logic_vector
(
2
downto
0
);
signal
trig_d
:
std_logic_vector
(
2
downto
0
);
signal
acam_ef_d
:
std_logic_vector
(
1
downto
0
);
signal
trig_pulse
:
std_logic
;
...
...
@@ -216,7 +211,7 @@ architecture behavioral of fd_acam_timestamper is
signal
subcycle_offset
:
signed
(
4
downto
0
);
-- raw time tag (unprocessed)
signal
raw_tag_valid
_p1
:
std_logic
;
signal
raw_tag_valid
:
std_logic
;
signal
raw_tag_coarse
:
unsigned
(
23
downto
0
);
signal
raw_tag_frac
:
unsigned
(
22
downto
0
);
signal
raw_tag_start_offset
:
unsigned
(
3
downto
0
);
...
...
@@ -229,7 +224,7 @@ architecture behavioral of fd_acam_timestamper is
signal
post_frac_multiplied
:
signed
(
c_SCALER_SHIFT
+
g_frac_bits
+
8
downto
0
);
signal
post_frac_start_adj
:
unsigned
(
22
downto
0
);
signal
pp_pipe
:
std_logic_vector
(
2
downto
0
);
signal
pp_pipe
:
std_logic_vector
(
2
downto
0
);
signal
width_check_sreg
:
std_logic_vector
(
g_min_pulse_width
-2
downto
0
);
signal
width_check_mask
:
std_logic_vector
(
g_min_pulse_width
-2
downto
0
);
...
...
@@ -245,10 +240,12 @@ architecture behavioral of fd_acam_timestamper is
signal
start_ok_sreg
:
std_logic_vector
(
2
downto
0
);
signal
start_ok
:
std_logic
;
signal
dbg_utc
:
unsigned
(
31
downto
0
);
signal
dbg_coarse
:
unsigned
(
27
downto
0
);
begin
-- behave
-- regs_b <= c_fd_registers_init_value; -- drive to 'Z'
regs_b
<=
c_fd_registers_init_value
;
-- Process: p_sync_trigger
-- Inputs: trig_a_n_i, tag_enable
...
...
@@ -386,7 +383,7 @@ begin -- behave
advance_coarse
<=
'0'
;
else
if
(
csync_p1_i
=
'1'
)
then
subcycle_offset
<=
resize
(
signed
(
start_count
),
5
)
-
resize
(
signed
(
csync_coarse_i
(
3
downto
0
)),
5
)
;
subcycle_offset
<=
signed
(
'0'
&
csync_coarse_i
(
3
downto
0
))
-
signed
(
'0'
&
start_count
)
-
1
;
end
if
;
if
(
tdc_start_d
(
1
)
=
'1'
and
tdc_start_d
(
2
)
=
'0'
)
then
...
...
@@ -436,7 +433,11 @@ begin -- behave
else
if
(
csync_p1_i
=
'1'
)
then
if
(
advance_coarse
=
'1'
)
then
coarse_count
<=
unsigned
(
csync_coarse_i
(
27
downto
4
))
+
1
;
else
coarse_count
<=
unsigned
(
csync_coarse_i
(
27
downto
4
));
end
if
;
elsif
(
advance_coarse
=
'1'
)
then
if
(
coarse_count
=
(
g_clk_ref_freq
/
16
)
-
1
)
then
coarse_count
<=
(
others
=>
'0'
);
...
...
@@ -454,7 +455,14 @@ begin -- behave
if
(
rst_n_i
=
'0'
)
then
utc_count
<=
(
others
=>
'0'
);
else
if
(
advance_coarse
=
'1'
and
coarse_count
=
(
g_clk_ref_freq
/
16
)
-
1
)
then
if
(
csync_p1_i
=
'1'
)
then
--if(advance_coarse = '1') then
-- utc_count <= unsigned(csync_utc_i) + 1;
--else
utc_count
<=
unsigned
(
csync_utc_i
);
--end if;
elsif
(
advance_coarse
=
'1'
and
coarse_count
=
(
g_clk_ref_freq
/
16
)
-
1
)
then
utc_count
<=
utc_count
+
1
;
end
if
;
end
if
;
...
...
@@ -474,6 +482,10 @@ begin -- behave
end
if
;
end
process
;
dbg_utc
<=
unsigned
(
utc_count
);
dbg_coarse
<=
unsigned
(
signed
(
coarse_count
&
start_count
)
+
subcycle_offset
);
p_main_fsm
:
process
(
clk_ref_i
)
begin
if
rising_edge
(
clk_ref_i
)
then
...
...
@@ -493,7 +505,7 @@ begin -- behave
timeout_counter
<=
(
others
=>
'0'
);
raw_tag_valid
_p1
<=
'0'
;
raw_tag_valid
<=
'0'
;
raw_tag_start_offset
<=
(
others
=>
'0'
);
raw_tag_coarse
<=
(
others
=>
'0'
);
raw_tag_utc
<=
(
others
=>
'0'
);
...
...
@@ -504,7 +516,7 @@ begin -- behave
else
case
afsm_state
is
when
IDLE
=>
raw_tag_valid
_p1
<=
'0'
;
raw_tag_valid
<=
'0'
;
-- TDC controlled by the host
if
(
regs_b
.
gcr_bypass_o
=
'1'
)
then
acam_reset_int
<=
'0'
;
...
...
@@ -614,7 +626,7 @@ begin -- behave
if
(
acam_ef_i
=
'1'
)
then
afsm_state
<=
IDLE
;
raw_tag_valid
_p1
<=
'1'
;
raw_tag_valid
<=
'1'
;
tag_enable
<=
'0'
;
else
...
...
@@ -691,7 +703,7 @@ begin -- behave
event_count_raw
<=
event_count_raw
+
1
;
end
if
;
if
(
raw_tag_valid
_p1
=
'1'
)
then
if
(
raw_tag_valid
=
'1'
)
then
event_count_tagged
<=
event_count_tagged
+
1
;
end
if
;
end
if
;
...
...
@@ -717,7 +729,7 @@ begin -- behave
end
if
;
when
PD_WAIT_TAG
=>
if
(
raw_tag_valid
_p1
=
'1'
)
then
if
(
raw_tag_valid
=
'1'
)
then
pd_state
<=
PD_UPDATE_STATS
;
else
cur_pdelay
<=
cur_pdelay
+
1
;
...
...
@@ -741,18 +753,20 @@ begin -- behave
acam_alutrigger_o
<=
acam_reset_int
;
p_postprocess_tags
:
process
(
clk_ref_i
)
begin
if
rising_edge
(
clk_ref_i
)
then
if
rst_n_i
=
'0'
then
tag_valid_
p1_o
<=
'0'
;
tag_valid_
o
<=
'0'
;
tag_coarse_o
<=
(
others
=>
'0'
);
tag_utc_o
<=
(
others
=>
'0'
);
tag_frac_o
<=
(
others
=>
'0'
);
else
--stage 1
pp_pipe
(
0
)
<=
raw_tag_valid
_p1
;
pp_pipe
(
0
)
<=
raw_tag_valid
;
if
(
raw_tag_start_offset
<=
unsigned
(
regs_b
.
atmcr_c_thr_o
))
and
(
raw_tag_frac
>
unsigned
(
regs_b
.
atmcr_f_thr_o
))
then
post_tag_coarse
(
post_tag_coarse
'left
downto
4
)
<=
raw_tag_coarse
-
1
;
...
...
@@ -779,7 +793,7 @@ begin -- behave
tag_frac_o
<=
std_logic_vector
(
post_frac_multiplied
(
c_SCALER_SHIFT
+
g_frac_bits
-1
downto
c_SCALER_SHIFT
));
-- tag_raw_frac_o <= std_logic_vector(raw_tag_frac);
tag_valid_
p1_
o
<=
pp_pipe
(
2
);
tag_valid_o
<=
pp_pipe
(
2
);
end
if
;
end
if
;
...
...
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