Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
T
TDC core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
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
TDC core
Commits
5b4244cb
Commit
5b4244cb
authored
Oct 25, 2011
by
Sebastien Bourdeauducq
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
channelbank: support single-channel configuration
parent
96fd461c
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
748 additions
and
223 deletions
+748
-223
tdc_channelbank.vhd
core/tdc_channelbank.vhd
+98
-215
tdc_channelbank_multi.vhd
core/tdc_channelbank_multi.vhd
+325
-0
tdc_channelbank_single.vhd
core/tdc_channelbank_single.vhd
+217
-0
tdc_package.vhd
core/tdc_package.vhd
+102
-0
system.v
demo/boards/spec/rtl/system.v
+4
-4
common.ucf
demo/boards/spec/synthesis/common.ucf
+2
-4
No files found.
core/tdc_channelbank.vhd
View file @
5b4244cb
...
...
@@ -6,15 +6,13 @@
--
-- author: Sebastien Bourdeauducq, sebastien@milkymist.org
--
-- description:
C
hannel bank
-- description:
Automatic c
hannel bank
--
-- references: http://www.ohwr.org/projects/tdc-core
--
-------------------------------------------------------------------------------
-- last changes:
-- 2011-08-18 SB Added histogram
-- 2011-08-17 SB Added frequency counter
-- 2011-08-08 SB Created file
-- 2011-10-25 SB Created file
-------------------------------------------------------------------------------
-- Copyright (C) 2011 CERN
...
...
@@ -29,20 +27,8 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
-- DESCRIPTION:
-- This module instantiates all the channels and provides a control interface
-- independent of the number of channels.
-- It provides a simple two-wire interface to select the current channel to
-- operate one, using the next_i (switch to next channel) and last_o (current
-- channel is the current channel, next channel is the first channel).
-- It provides multiplexed access to the LUT of the current channel, to the
-- histogram of the current channel, and to the ring oscillator frequency
-- of the current channel.
--
-- To save resources:
-- * the histogram is implemented as one large block RAM common to all
-- channels
-- * the frequency counter logic is shared among all channels, each channel
-- only implements a ring oscillator.
-- This module instantiates the single- or multi-channel bank depending
-- on the g_CHANNEL_COUNT generic.
library
ieee
;
use
ieee
.
std_logic_1164
.
all
;
...
...
@@ -50,7 +36,6 @@ use ieee.numeric_std.all;
library
work
;
use
work
.
tdc_package
.
all
;
use
work
.
genram_pkg
.
all
;
entity
tdc_channelbank
is
generic
(
...
...
@@ -119,208 +104,106 @@ entity tdc_channelbank is
end
entity
;
architecture
rtl
of
tdc_channelbank
is
signal
detect
:
std_logic_vector
(
g_CHANNEL_COUNT
-1
downto
0
);
signal
raw
:
std_logic_vector
(
g_CHANNEL_COUNT
*
g_RAW_COUNT
-1
downto
0
);
signal
coarse_counter
:
std_logic_vector
(
g_COARSE_COUNT
-1
downto
0
);
signal
current_channel_onehot
:
std_logic_vector
(
g_CHANNEL_COUNT
-1
downto
0
);
signal
current_channel
:
std_logic_vector
(
f_log2_size
(
g_CHANNEL_COUNT
)
-1
downto
0
);
signal
lut_d_o_s
:
std_logic_vector
(
g_CHANNEL_COUNT
*
g_FP_COUNT
-1
downto
0
);
signal
his_full_a
:
std_logic_vector
(
f_log2_size
(
g_CHANNEL_COUNT
)
+
g_RAW_COUNT
-1
downto
0
);
signal
ro_clk_s
:
std_logic_vector
(
g_CHANNEL_COUNT
-1
downto
0
);
signal
ro_clk
:
std_logic
;
signal
freq
:
std_logic_vector
(
g_FCOUNTER_WIDTH
-1
downto
0
);
signal
sfreq_s
:
std_logic_vector
(
g_CHANNEL_COUNT
*
g_FCOUNTER_WIDTH
-1
downto
0
);
begin
-- Per-channel processing.
g_channels
:
for
i
in
0
to
g_CHANNEL_COUNT
-1
generate
signal
this_calib_sel
:
std_logic
;
signal
this_lut_we
:
std_logic
;
begin
this_calib_sel
<=
current_channel_onehot
(
i
)
and
calib_sel_i
;
this_lut_we
<=
current_channel_onehot
(
i
)
and
lut_we_i
;
cmp_channel
:
tdc_channel
g_single
:
if
g_CHANNEL_COUNT
=
1
generate
cmp_channelbank
:
tdc_channelbank_single
generic
map
(
g_CARRY4_COUNT
=>
g_CARRY4_COUNT
,
g_RAW_COUNT
=>
g_RAW_COUNT
,
g_FP_COUNT
=>
g_FP_COUNT
,
g_COARSE_COUNT
=>
g_COARSE_COUNT
,
g_RO_LENGTH
=>
g_RO_LENGTH
g_CARRY4_COUNT
=>
g_CARRY4_COUNT
,
g_RAW_COUNT
=>
g_RAW_COUNT
,
g_FP_COUNT
=>
g_FP_COUNT
,
g_COARSE_COUNT
=>
g_COARSE_COUNT
,
g_RO_LENGTH
=>
g_RO_LENGTH
,
g_FCOUNTER_WIDTH
=>
g_FCOUNTER_WIDTH
,
g_FTIMER_WIDTH
=>
g_FTIMER_WIDTH
)
port
map
(
clk_i
=>
clk_i
,
reset_i
=>
reset_i
,
coarse_i
=>
coarse_counter
,
deskew_i
=>
deskew_i
((
i
+
1
)
*
(
g_COARSE_COUNT
+
g_FP_COUNT
)
-1
downto
i
*
(
g_COARSE_COUNT
+
g_FP_COUNT
)),
signal_i
=>
signal_i
(
i
),
calib_i
=>
calib_i
(
i
),
calib_sel_i
=>
this_calib_sel
,
detect_o
=>
detect
(
i
),
polarity_o
=>
polarity_o
(
i
),
raw_o
=>
raw
((
i
+
1
)
*
g_RAW_COUNT
-1
downto
i
*
g_RAW_COUNT
),
fp_o
=>
fp_o
((
i
+
1
)
*
(
g_COARSE_COUNT
+
g_FP_COUNT
)
-1
downto
i
*
(
g_COARSE_COUNT
+
g_FP_COUNT
)),
lut_a_i
=>
lut_a_i
,
lut_we_i
=>
this_lut_we
,
lut_d_i
=>
lut_d_i
,
lut_d_o
=>
lut_d_o_s
((
i
+
1
)
*
g_FP_COUNT
-1
downto
i
*
g_FP_COUNT
),
clk_i
=>
clk_i
,
reset_i
=>
reset_i
,
cc_rst_i
=>
cc_rst_i
,
cc_cy_o
=>
cc_cy_o
,
next_i
=>
next_i
,
last_o
=>
last_o
,
calib_sel_i
=>
calib_sel_i
,
deskew_i
=>
deskew_i
,
signal_i
=>
signal_i
(
0
),
calib_i
=>
calib_i
(
0
),
detect_o
=>
detect_o
(
0
),
polarity_o
=>
polarity_o
(
0
),
raw_o
=>
raw_o
,
fp_o
=>
fp_o
,
lut_a_i
=>
lut_a_i
,
lut_we_i
=>
lut_we_i
,
lut_d_i
=>
lut_d_i
,
lut_d_o
=>
lut_d_o
,
c_detect_o
=>
c_detect_o
,
c_raw_o
=>
c_raw_o
,
his_a_i
=>
his_a_i
,
his_we_i
=>
his_we_i
,
his_d_i
=>
his_d_i
,
his_d_o
=>
his_d_o
,
ro_en_i
=>
current_channel_onehot
(
i
),
ro_clk_o
=>
ro_clk_s
(
i
)
oc_start_i
=>
oc_start_i
,
oc_ready_o
=>
oc_ready_o
,
oc_freq_o
=>
oc_freq_o
,
oc_store_i
=>
oc_store_i
,
oc_sfreq_o
=>
oc_sfreq_o
);
end
generate
;
detect_o
<=
detect
;
raw_o
<=
raw
;
-- Histogram memory.
cmp_histogram
:
generic_spram
generic
map
(
g_data_width
=>
g_FP_COUNT
,
g_size
=>
g_CHANNEL_COUNT
*
2
**
g_RAW_COUNT
,
g_with_byte_enable
=>
false
,
g_init_file
=>
""
,
g_addr_conflict_resolution
=>
"read_first"
)
port
map
(
rst_n_i
=>
'1'
,
clk_i
=>
clk_i
,
bwe_i
=>
(
others
=>
'0'
),
we_i
=>
his_we_i
,
a_i
=>
his_full_a
,
d_i
=>
his_d_i
,
q_o
=>
his_d_o
);
his_full_a
<=
current_channel
&
his_a_i
;
-- Frequency counter.
cmp_freqc
:
tdc_freqc
generic
map
(
g_COUNTER_WIDTH
=>
g_FCOUNTER_WIDTH
,
g_TIMER_WIDTH
=>
g_FTIMER_WIDTH
)
port
map
(
clk_i
=>
clk_i
,
reset_i
=>
reset_i
,
clk_m_i
=>
ro_clk
,
start_i
=>
oc_start_i
,
ready_o
=>
oc_ready_o
,
freq_o
=>
freq
);
oc_freq_o
<=
freq
;
-- Coarse counter.
process
(
clk_i
)
begin
if
rising_edge
(
clk_i
)
then
if
(
reset_i
=
'1'
)
or
(
cc_rst_i
=
'1'
)
then
coarse_counter
<=
(
coarse_counter
'range
=>
'0'
);
cc_cy_o
<=
'0'
;
else
coarse_counter
<=
std_logic_vector
(
unsigned
(
coarse_counter
)
+
1
);
if
coarse_counter
=
(
coarse_counter
'range
=>
'1'
)
then
cc_cy_o
<=
'1'
;
else
cc_cy_o
<=
'0'
;
end
if
;
end
if
;
end
if
;
end
process
;
-- Combine LUT outputs.
process
(
lut_d_o_s
,
current_channel_onehot
)
variable
v_lut_d_o
:
std_logic_vector
(
g_FP_COUNT
-1
downto
0
);
begin
v_lut_d_o
:
=
(
v_lut_d_o
'range
=>
'0'
);
for
i
in
0
to
g_CHANNEL_COUNT
-1
loop
if
current_channel_onehot
(
i
)
=
'1'
then
v_lut_d_o
:
=
v_lut_d_o
or
lut_d_o_s
((
i
+
1
)
*
g_FP_COUNT
-1
downto
i
*
g_FP_COUNT
);
end
if
;
end
loop
;
lut_d_o
<=
v_lut_d_o
;
end
process
;
-- Select detect and raw outputs for histogram generation.
process
(
detect
,
raw
,
current_channel_onehot
)
variable
v_c_detect_o
:
std_logic
;
variable
v_c_raw_o
:
std_logic_vector
(
g_RAW_COUNT
-1
downto
0
);
begin
v_c_detect_o
:
=
'0'
;
v_c_raw_o
:
=
(
v_c_raw_o
'range
=>
'0'
);
for
i
in
0
to
g_CHANNEL_COUNT
-1
loop
if
current_channel_onehot
(
i
)
=
'1'
then
v_c_detect_o
:
=
v_c_detect_o
or
detect
(
i
);
v_c_raw_o
:
=
v_c_raw_o
or
raw
((
i
+
1
)
*
g_RAW_COUNT
-1
downto
i
*
g_RAW_COUNT
);
end
if
;
end
loop
;
c_detect_o
<=
v_c_detect_o
;
c_raw_o
<=
v_c_raw_o
;
end
process
;
-- Combine ring oscillator outputs. When disabled, a ring oscillator
-- outputs 0, so we can simply OR all outputs together.
ro_clk
<=
'0'
when
(
ro_clk_s
=
(
ro_clk_s
'range
=>
'0'
))
else
'1'
;
-- Store and retrieve per-channel ring oscillator frequencies.
process
(
clk_i
)
begin
if
rising_edge
(
clk_i
)
then
if
oc_store_i
=
'1'
then
for
i
in
0
to
g_CHANNEL_COUNT
-1
loop
if
current_channel_onehot
(
i
)
=
'1'
then
sfreq_s
((
i
+
1
)
*
g_FCOUNTER_WIDTH
-1
downto
i
*
g_FCOUNTER_WIDTH
)
<=
freq
;
end
if
;
end
loop
;
end
if
;
end
if
;
end
process
;
process
(
sfreq_s
,
current_channel_onehot
)
variable
v_oc_sfreq_o
:
std_logic_vector
(
g_FCOUNTER_WIDTH
-1
downto
0
);
begin
v_oc_sfreq_o
:
=
(
v_oc_sfreq_o
'range
=>
'0'
);
for
i
in
0
to
g_CHANNEL_COUNT
-1
loop
if
current_channel_onehot
(
i
)
=
'1'
then
v_oc_sfreq_o
:
=
v_oc_sfreq_o
or
sfreq_s
((
i
+
1
)
*
g_FCOUNTER_WIDTH
-1
downto
i
*
g_FCOUNTER_WIDTH
);
end
if
;
end
loop
;
oc_sfreq_o
<=
v_oc_sfreq_o
;
end
process
;
-- Generate channel selection signals.
process
(
clk_i
)
begin
if
rising_edge
(
clk_i
)
then
if
reset_i
=
'1'
then
current_channel_onehot
<=
(
0
=>
'1'
,
others
=>
'0'
);
else
if
next_i
=
'1'
then
current_channel_onehot
<=
std_logic_vector
(
rotate_left
(
unsigned
(
current_channel_onehot
),
1
));
end
if
;
end
if
;
end
if
;
end
process
;
last_o
<=
current_channel_onehot
(
g_CHANNEL_COUNT
-1
);
g_encode
:
if
g_CHANNEL_COUNT
>
1
generate
process
(
current_channel_onehot
)
variable
v_current_channel
:
std_logic_vector
(
f_log2_size
(
g_CHANNEL_COUNT
)
-1
downto
0
);
begin
v_current_channel
:
=
(
v_current_channel
'range
=>
'0'
);
for
i
in
0
to
g_CHANNEL_COUNT
-1
loop
if
current_channel_onehot
(
i
)
=
'1'
then
v_current_channel
:
=
v_current_channel
or
std_logic_vector
(
to_unsigned
(
i
,
v_current_channel
'length
));
end
if
;
end
loop
;
current_channel
<=
v_current_channel
;
end
process
;
end
generate
;
g_multi
:
if
g_CHANNEL_COUNT
>
1
generate
cmp_channelbank
:
tdc_channelbank_multi
generic
map
(
g_CHANNEL_COUNT
=>
g_CHANNEL_COUNT
,
g_CARRY4_COUNT
=>
g_CARRY4_COUNT
,
g_RAW_COUNT
=>
g_RAW_COUNT
,
g_FP_COUNT
=>
g_FP_COUNT
,
g_COARSE_COUNT
=>
g_COARSE_COUNT
,
g_RO_LENGTH
=>
g_RO_LENGTH
,
g_FCOUNTER_WIDTH
=>
g_FCOUNTER_WIDTH
,
g_FTIMER_WIDTH
=>
g_FTIMER_WIDTH
)
port
map
(
clk_i
=>
clk_i
,
reset_i
=>
reset_i
,
cc_rst_i
=>
cc_rst_i
,
cc_cy_o
=>
cc_cy_o
,
next_i
=>
next_i
,
last_o
=>
last_o
,
calib_sel_i
=>
calib_sel_i
,
deskew_i
=>
deskew_i
,
signal_i
=>
signal_i
,
calib_i
=>
calib_i
,
detect_o
=>
detect_o
,
polarity_o
=>
polarity_o
,
raw_o
=>
raw_o
,
fp_o
=>
fp_o
,
lut_a_i
=>
lut_a_i
,
lut_we_i
=>
lut_we_i
,
lut_d_i
=>
lut_d_i
,
lut_d_o
=>
lut_d_o
,
c_detect_o
=>
c_detect_o
,
c_raw_o
=>
c_raw_o
,
his_a_i
=>
his_a_i
,
his_we_i
=>
his_we_i
,
his_d_i
=>
his_d_i
,
his_d_o
=>
his_d_o
,
oc_start_i
=>
oc_start_i
,
oc_ready_o
=>
oc_ready_o
,
oc_freq_o
=>
oc_freq_o
,
oc_store_i
=>
oc_store_i
,
oc_sfreq_o
=>
oc_sfreq_o
);
end
generate
;
end
architecture
;
core/tdc_channelbank_multi.vhd
0 → 100644
View file @
5b4244cb
-------------------------------------------------------------------------------
-- TDC Core / CERN
-------------------------------------------------------------------------------
--
-- unit name: tdc_channelbank_multi
--
-- author: Sebastien Bourdeauducq, sebastien@milkymist.org
--
-- description: Channel bank (multi-channel)
--
-- references: http://www.ohwr.org/projects/tdc-core
--
-------------------------------------------------------------------------------
-- last changes:
-- 2011-10-25 SB Renamed to channelbank_multi
-- 2011-08-18 SB Added histogram
-- 2011-08-17 SB Added frequency counter
-- 2011-08-08 SB Created file
-------------------------------------------------------------------------------
-- Copyright (C) 2011 CERN
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Lesser General Public License as published by
-- the Free Software Foundation, version 3 of the License.
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
-- You should have received a copy of the GNU Lesser General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
-- DESCRIPTION:
-- This module instantiates all the channels and provides a control interface
-- independent of the number of channels.
-- It provides a simple two-wire interface to select the current channel to
-- operate one, using the next_i (switch to next channel) and last_o (current
-- channel is the current channel, next channel is the first channel).
-- It provides multiplexed access to the LUT of the current channel, to the
-- histogram of the current channel, and to the ring oscillator frequency
-- of the current channel.
--
-- To save resources:
-- * the histogram is implemented as one large block RAM common to all
-- channels
-- * the frequency counter logic is shared among all channels, each channel
-- only implements a ring oscillator.
library
ieee
;
use
ieee
.
std_logic_1164
.
all
;
use
ieee
.
numeric_std
.
all
;
library
work
;
use
work
.
tdc_package
.
all
;
use
work
.
genram_pkg
.
all
;
entity
tdc_channelbank_multi
is
generic
(
-- Number of channels.
g_CHANNEL_COUNT
:
positive
;
-- Number of CARRY4 elements per channel.
g_CARRY4_COUNT
:
positive
;
-- Number of raw output bits.
g_RAW_COUNT
:
positive
;
-- Number of fractional part bits.
g_FP_COUNT
:
positive
;
-- Number of coarse counter bits.
g_COARSE_COUNT
:
positive
;
-- Length of each ring oscillator.
g_RO_LENGTH
:
positive
;
-- Frequency counter width.
g_FCOUNTER_WIDTH
:
positive
;
-- Frequency counter timer width.
g_FTIMER_WIDTH
:
positive
);
port
(
clk_i
:
in
std_logic
;
reset_i
:
in
std_logic
;
-- Control.
cc_rst_i
:
in
std_logic
;
cc_cy_o
:
out
std_logic
;
next_i
:
in
std_logic
;
last_o
:
out
std_logic
;
calib_sel_i
:
in
std_logic
;
-- Per-channel deskew inputs.
deskew_i
:
in
std_logic_vector
(
g_CHANNEL_COUNT
*
(
g_COARSE_COUNT
+
g_FP_COUNT
)
-1
downto
0
);
-- Per-channel signal inputs.
signal_i
:
in
std_logic_vector
(
g_CHANNEL_COUNT
-1
downto
0
);
calib_i
:
in
std_logic_vector
(
g_CHANNEL_COUNT
-1
downto
0
);
-- Per-channel detection outputs.
detect_o
:
out
std_logic_vector
(
g_CHANNEL_COUNT
-1
downto
0
);
polarity_o
:
out
std_logic_vector
(
g_CHANNEL_COUNT
-1
downto
0
);
raw_o
:
out
std_logic_vector
(
g_CHANNEL_COUNT
*
g_RAW_COUNT
-1
downto
0
);
fp_o
:
out
std_logic_vector
(
g_CHANNEL_COUNT
*
(
g_COARSE_COUNT
+
g_FP_COUNT
)
-1
downto
0
);
-- LUT access.
lut_a_i
:
in
std_logic_vector
(
g_RAW_COUNT
-1
downto
0
);
lut_we_i
:
in
std_logic
;
lut_d_i
:
in
std_logic_vector
(
g_FP_COUNT
-1
downto
0
);
lut_d_o
:
out
std_logic_vector
(
g_FP_COUNT
-1
downto
0
);
-- Histogram.
c_detect_o
:
out
std_logic
;
c_raw_o
:
out
std_logic_vector
(
g_RAW_COUNT
-1
downto
0
);
his_a_i
:
in
std_logic_vector
(
g_RAW_COUNT
-1
downto
0
);
his_we_i
:
in
std_logic
;
his_d_i
:
in
std_logic_vector
(
g_FP_COUNT
-1
downto
0
);
his_d_o
:
out
std_logic_vector
(
g_FP_COUNT
-1
downto
0
);
-- Online calibration.
oc_start_i
:
in
std_logic
;
oc_ready_o
:
out
std_logic
;
oc_freq_o
:
out
std_logic_vector
(
g_FCOUNTER_WIDTH
-1
downto
0
);
oc_store_i
:
in
std_logic
;
oc_sfreq_o
:
out
std_logic_vector
(
g_FCOUNTER_WIDTH
-1
downto
0
)
);
end
entity
;
architecture
rtl
of
tdc_channelbank_multi
is
signal
detect
:
std_logic_vector
(
g_CHANNEL_COUNT
-1
downto
0
);
signal
raw
:
std_logic_vector
(
g_CHANNEL_COUNT
*
g_RAW_COUNT
-1
downto
0
);
signal
coarse_counter
:
std_logic_vector
(
g_COARSE_COUNT
-1
downto
0
);
signal
current_channel_onehot
:
std_logic_vector
(
g_CHANNEL_COUNT
-1
downto
0
);
signal
current_channel
:
std_logic_vector
(
f_log2_size
(
g_CHANNEL_COUNT
)
-1
downto
0
);
signal
lut_d_o_s
:
std_logic_vector
(
g_CHANNEL_COUNT
*
g_FP_COUNT
-1
downto
0
);
signal
his_full_a
:
std_logic_vector
(
f_log2_size
(
g_CHANNEL_COUNT
)
+
g_RAW_COUNT
-1
downto
0
);
signal
ro_clk_s
:
std_logic_vector
(
g_CHANNEL_COUNT
-1
downto
0
);
signal
ro_clk
:
std_logic
;
signal
freq
:
std_logic_vector
(
g_FCOUNTER_WIDTH
-1
downto
0
);
signal
sfreq_s
:
std_logic_vector
(
g_CHANNEL_COUNT
*
g_FCOUNTER_WIDTH
-1
downto
0
);
begin
-- Per-channel processing.
g_channels
:
for
i
in
0
to
g_CHANNEL_COUNT
-1
generate
signal
this_calib_sel
:
std_logic
;
signal
this_lut_we
:
std_logic
;
begin
this_calib_sel
<=
current_channel_onehot
(
i
)
and
calib_sel_i
;
this_lut_we
<=
current_channel_onehot
(
i
)
and
lut_we_i
;
cmp_channel
:
tdc_channel
generic
map
(
g_CARRY4_COUNT
=>
g_CARRY4_COUNT
,
g_RAW_COUNT
=>
g_RAW_COUNT
,
g_FP_COUNT
=>
g_FP_COUNT
,
g_COARSE_COUNT
=>
g_COARSE_COUNT
,
g_RO_LENGTH
=>
g_RO_LENGTH
)
port
map
(
clk_i
=>
clk_i
,
reset_i
=>
reset_i
,
coarse_i
=>
coarse_counter
,
deskew_i
=>
deskew_i
((
i
+
1
)
*
(
g_COARSE_COUNT
+
g_FP_COUNT
)
-1
downto
i
*
(
g_COARSE_COUNT
+
g_FP_COUNT
)),
signal_i
=>
signal_i
(
i
),
calib_i
=>
calib_i
(
i
),
calib_sel_i
=>
this_calib_sel
,
detect_o
=>
detect
(
i
),
polarity_o
=>
polarity_o
(
i
),
raw_o
=>
raw
((
i
+
1
)
*
g_RAW_COUNT
-1
downto
i
*
g_RAW_COUNT
),
fp_o
=>
fp_o
((
i
+
1
)
*
(
g_COARSE_COUNT
+
g_FP_COUNT
)
-1
downto
i
*
(
g_COARSE_COUNT
+
g_FP_COUNT
)),
lut_a_i
=>
lut_a_i
,
lut_we_i
=>
this_lut_we
,
lut_d_i
=>
lut_d_i
,
lut_d_o
=>
lut_d_o_s
((
i
+
1
)
*
g_FP_COUNT
-1
downto
i
*
g_FP_COUNT
),
ro_en_i
=>
current_channel_onehot
(
i
),
ro_clk_o
=>
ro_clk_s
(
i
)
);
end
generate
;
detect_o
<=
detect
;
raw_o
<=
raw
;
-- Histogram memory.
cmp_histogram
:
generic_spram
generic
map
(
g_data_width
=>
g_FP_COUNT
,
g_size
=>
g_CHANNEL_COUNT
*
2
**
g_RAW_COUNT
,
g_with_byte_enable
=>
false
,
g_init_file
=>
""
,
g_addr_conflict_resolution
=>
"read_first"
)
port
map
(
rst_n_i
=>
'1'
,
clk_i
=>
clk_i
,
bwe_i
=>
(
others
=>
'0'
),
we_i
=>
his_we_i
,
a_i
=>
his_full_a
,
d_i
=>
his_d_i
,
q_o
=>
his_d_o
);
his_full_a
<=
current_channel
&
his_a_i
;
-- Frequency counter.
cmp_freqc
:
tdc_freqc
generic
map
(
g_COUNTER_WIDTH
=>
g_FCOUNTER_WIDTH
,
g_TIMER_WIDTH
=>
g_FTIMER_WIDTH
)
port
map
(
clk_i
=>
clk_i
,
reset_i
=>
reset_i
,
clk_m_i
=>
ro_clk
,
start_i
=>
oc_start_i
,
ready_o
=>
oc_ready_o
,
freq_o
=>
freq
);
oc_freq_o
<=
freq
;
-- Coarse counter.
process
(
clk_i
)
begin
if
rising_edge
(
clk_i
)
then
if
(
reset_i
=
'1'
)
or
(
cc_rst_i
=
'1'
)
then
coarse_counter
<=
(
coarse_counter
'range
=>
'0'
);
cc_cy_o
<=
'0'
;
else
coarse_counter
<=
std_logic_vector
(
unsigned
(
coarse_counter
)
+
1
);
if
coarse_counter
=
(
coarse_counter
'range
=>
'1'
)
then
cc_cy_o
<=
'1'
;
else
cc_cy_o
<=
'0'
;
end
if
;
end
if
;
end
if
;
end
process
;
-- Combine LUT outputs.
process
(
lut_d_o_s
,
current_channel_onehot
)
variable
v_lut_d_o
:
std_logic_vector
(
g_FP_COUNT
-1
downto
0
);
begin
v_lut_d_o
:
=
(
v_lut_d_o
'range
=>
'0'
);
for
i
in
0
to
g_CHANNEL_COUNT
-1
loop
if
current_channel_onehot
(
i
)
=
'1'
then
v_lut_d_o
:
=
v_lut_d_o
or
lut_d_o_s
((
i
+
1
)
*
g_FP_COUNT
-1
downto
i
*
g_FP_COUNT
);
end
if
;
end
loop
;
lut_d_o
<=
v_lut_d_o
;
end
process
;
-- Select detect and raw outputs for histogram generation.
process
(
detect
,
raw
,
current_channel_onehot
)
variable
v_c_detect_o
:
std_logic
;
variable
v_c_raw_o
:
std_logic_vector
(
g_RAW_COUNT
-1
downto
0
);
begin
v_c_detect_o
:
=
'0'
;
v_c_raw_o
:
=
(
v_c_raw_o
'range
=>
'0'
);
for
i
in
0
to
g_CHANNEL_COUNT
-1
loop
if
current_channel_onehot
(
i
)
=
'1'
then
v_c_detect_o
:
=
v_c_detect_o
or
detect
(
i
);
v_c_raw_o
:
=
v_c_raw_o
or
raw
((
i
+
1
)
*
g_RAW_COUNT
-1
downto
i
*
g_RAW_COUNT
);
end
if
;
end
loop
;
c_detect_o
<=
v_c_detect_o
;
c_raw_o
<=
v_c_raw_o
;
end
process
;
-- Combine ring oscillator outputs. When disabled, a ring oscillator
-- outputs 0, so we can simply OR all outputs together.
ro_clk
<=
'0'
when
(
ro_clk_s
=
(
ro_clk_s
'range
=>
'0'
))
else
'1'
;
-- Store and retrieve per-channel ring oscillator frequencies.
process
(
clk_i
)
begin
if
rising_edge
(
clk_i
)
then
if
oc_store_i
=
'1'
then
for
i
in
0
to
g_CHANNEL_COUNT
-1
loop
if
current_channel_onehot
(
i
)
=
'1'
then
sfreq_s
((
i
+
1
)
*
g_FCOUNTER_WIDTH
-1
downto
i
*
g_FCOUNTER_WIDTH
)
<=
freq
;
end
if
;
end
loop
;
end
if
;
end
if
;
end
process
;
process
(
sfreq_s
,
current_channel_onehot
)
variable
v_oc_sfreq_o
:
std_logic_vector
(
g_FCOUNTER_WIDTH
-1
downto
0
);
begin
v_oc_sfreq_o
:
=
(
v_oc_sfreq_o
'range
=>
'0'
);
for
i
in
0
to
g_CHANNEL_COUNT
-1
loop
if
current_channel_onehot
(
i
)
=
'1'
then
v_oc_sfreq_o
:
=
v_oc_sfreq_o
or
sfreq_s
((
i
+
1
)
*
g_FCOUNTER_WIDTH
-1
downto
i
*
g_FCOUNTER_WIDTH
);
end
if
;
end
loop
;
oc_sfreq_o
<=
v_oc_sfreq_o
;
end
process
;
-- Generate channel selection signals.
process
(
clk_i
)
begin
if
rising_edge
(
clk_i
)
then
if
reset_i
=
'1'
then
current_channel_onehot
<=
(
0
=>
'1'
,
others
=>
'0'
);
else
if
next_i
=
'1'
then
current_channel_onehot
<=
std_logic_vector
(
rotate_left
(
unsigned
(
current_channel_onehot
),
1
));
end
if
;
end
if
;
end
if
;
end
process
;
last_o
<=
current_channel_onehot
(
g_CHANNEL_COUNT
-1
);
process
(
current_channel_onehot
)
variable
v_current_channel
:
std_logic_vector
(
f_log2_size
(
g_CHANNEL_COUNT
)
-1
downto
0
);
begin
v_current_channel
:
=
(
v_current_channel
'range
=>
'0'
);
for
i
in
0
to
g_CHANNEL_COUNT
-1
loop
if
current_channel_onehot
(
i
)
=
'1'
then
v_current_channel
:
=
v_current_channel
or
std_logic_vector
(
to_unsigned
(
i
,
v_current_channel
'length
));
end
if
;
end
loop
;
current_channel
<=
v_current_channel
;
end
process
;
end
architecture
;
core/tdc_channelbank_single.vhd
0 → 100644
View file @
5b4244cb
-------------------------------------------------------------------------------
-- TDC Core / CERN
-------------------------------------------------------------------------------
--
-- unit name: tdc_channelbank_single
--
-- author: Sebastien Bourdeauducq, sebastien@milkymist.org
--
-- description: Channel bank (single-channel)
--
-- references: http://www.ohwr.org/projects/tdc-core
--
-------------------------------------------------------------------------------
-- last changes:
-- 2011-10-25 SB Created file
-------------------------------------------------------------------------------
-- Copyright (C) 2011 CERN
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Lesser General Public License as published by
-- the Free Software Foundation, version 3 of the License.
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
-- You should have received a copy of the GNU Lesser General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
-- DESCRIPTION:
-- Simplified version of tdc_channelbank_multi for the single-channel case.
library
ieee
;
use
ieee
.
std_logic_1164
.
all
;
use
ieee
.
numeric_std
.
all
;
library
work
;
use
work
.
tdc_package
.
all
;
use
work
.
genram_pkg
.
all
;
entity
tdc_channelbank_single
is
generic
(
-- Number of CARRY4 elements per channel.
g_CARRY4_COUNT
:
positive
;
-- Number of raw output bits.
g_RAW_COUNT
:
positive
;
-- Number of fractional part bits.
g_FP_COUNT
:
positive
;
-- Number of coarse counter bits.
g_COARSE_COUNT
:
positive
;
-- Length of each ring oscillator.
g_RO_LENGTH
:
positive
;
-- Frequency counter width.
g_FCOUNTER_WIDTH
:
positive
;
-- Frequency counter timer width.
g_FTIMER_WIDTH
:
positive
);
port
(
clk_i
:
in
std_logic
;
reset_i
:
in
std_logic
;
-- Control.
cc_rst_i
:
in
std_logic
;
cc_cy_o
:
out
std_logic
;
next_i
:
in
std_logic
;
last_o
:
out
std_logic
;
calib_sel_i
:
in
std_logic
;
-- Per-channel deskew inputs.
deskew_i
:
in
std_logic_vector
(
g_COARSE_COUNT
+
g_FP_COUNT
-1
downto
0
);
-- Per-channel signal inputs.
signal_i
:
in
std_logic
;
calib_i
:
in
std_logic
;
-- Per-channel detection outputs.
detect_o
:
out
std_logic
;
polarity_o
:
out
std_logic
;
raw_o
:
out
std_logic_vector
(
g_RAW_COUNT
-1
downto
0
);
fp_o
:
out
std_logic_vector
(
g_COARSE_COUNT
+
g_FP_COUNT
-1
downto
0
);
-- LUT access.
lut_a_i
:
in
std_logic_vector
(
g_RAW_COUNT
-1
downto
0
);
lut_we_i
:
in
std_logic
;
lut_d_i
:
in
std_logic_vector
(
g_FP_COUNT
-1
downto
0
);
lut_d_o
:
out
std_logic_vector
(
g_FP_COUNT
-1
downto
0
);
-- Histogram.
c_detect_o
:
out
std_logic
;
c_raw_o
:
out
std_logic_vector
(
g_RAW_COUNT
-1
downto
0
);
his_a_i
:
in
std_logic_vector
(
g_RAW_COUNT
-1
downto
0
);
his_we_i
:
in
std_logic
;
his_d_i
:
in
std_logic_vector
(
g_FP_COUNT
-1
downto
0
);
his_d_o
:
out
std_logic_vector
(
g_FP_COUNT
-1
downto
0
);
-- Online calibration.
oc_start_i
:
in
std_logic
;
oc_ready_o
:
out
std_logic
;
oc_freq_o
:
out
std_logic_vector
(
g_FCOUNTER_WIDTH
-1
downto
0
);
oc_store_i
:
in
std_logic
;
oc_sfreq_o
:
out
std_logic_vector
(
g_FCOUNTER_WIDTH
-1
downto
0
)
);
end
entity
;
architecture
rtl
of
tdc_channelbank_single
is
signal
detect
:
std_logic
;
signal
raw
:
std_logic_vector
(
g_RAW_COUNT
-1
downto
0
);
signal
coarse_counter
:
std_logic_vector
(
g_COARSE_COUNT
-1
downto
0
);
signal
ro_clk
:
std_logic
;
signal
freq
:
std_logic_vector
(
g_FCOUNTER_WIDTH
-1
downto
0
);
signal
sfreq_s
:
std_logic_vector
(
g_FCOUNTER_WIDTH
-1
downto
0
);
begin
-- Per-channel processing.
cmp_channel
:
tdc_channel
generic
map
(
g_CARRY4_COUNT
=>
g_CARRY4_COUNT
,
g_RAW_COUNT
=>
g_RAW_COUNT
,
g_FP_COUNT
=>
g_FP_COUNT
,
g_COARSE_COUNT
=>
g_COARSE_COUNT
,
g_RO_LENGTH
=>
g_RO_LENGTH
)
port
map
(
clk_i
=>
clk_i
,
reset_i
=>
reset_i
,
coarse_i
=>
coarse_counter
,
deskew_i
=>
deskew_i
,
signal_i
=>
signal_i
,
calib_i
=>
calib_i
,
calib_sel_i
=>
calib_sel_i
,
detect_o
=>
detect
,
polarity_o
=>
polarity_o
,
raw_o
=>
raw
,
fp_o
=>
fp_o
,
lut_a_i
=>
lut_a_i
,
lut_we_i
=>
lut_we_i
,
lut_d_i
=>
lut_d_i
,
lut_d_o
=>
lut_d_o
,
ro_en_i
=>
'1'
,
ro_clk_o
=>
ro_clk
);
detect_o
<=
detect
;
raw_o
<=
raw
;
c_detect_o
<=
detect
;
c_raw_o
<=
raw
;
-- Histogram memory.
cmp_histogram
:
generic_spram
generic
map
(
g_data_width
=>
g_FP_COUNT
,
g_size
=>
2
**
g_RAW_COUNT
,
g_with_byte_enable
=>
false
,
g_init_file
=>
""
,
g_addr_conflict_resolution
=>
"read_first"
)
port
map
(
rst_n_i
=>
'1'
,
clk_i
=>
clk_i
,
bwe_i
=>
(
others
=>
'0'
),
we_i
=>
his_we_i
,
a_i
=>
his_a_i
,
d_i
=>
his_d_i
,
q_o
=>
his_d_o
);
-- Frequency counter.
cmp_freqc
:
tdc_freqc
generic
map
(
g_COUNTER_WIDTH
=>
g_FCOUNTER_WIDTH
,
g_TIMER_WIDTH
=>
g_FTIMER_WIDTH
)
port
map
(
clk_i
=>
clk_i
,
reset_i
=>
reset_i
,
clk_m_i
=>
ro_clk
,
start_i
=>
oc_start_i
,
ready_o
=>
oc_ready_o
,
freq_o
=>
freq
);
oc_freq_o
<=
freq
;
-- Coarse counter.
process
(
clk_i
)
begin
if
rising_edge
(
clk_i
)
then
if
(
reset_i
=
'1'
)
or
(
cc_rst_i
=
'1'
)
then
coarse_counter
<=
(
coarse_counter
'range
=>
'0'
);
cc_cy_o
<=
'0'
;
else
coarse_counter
<=
std_logic_vector
(
unsigned
(
coarse_counter
)
+
1
);
if
coarse_counter
=
(
coarse_counter
'range
=>
'1'
)
then
cc_cy_o
<=
'1'
;
else
cc_cy_o
<=
'0'
;
end
if
;
end
if
;
end
if
;
end
process
;
-- Store and retrieve per-channel ring oscillator frequencies.
process
(
clk_i
)
begin
if
rising_edge
(
clk_i
)
then
if
oc_store_i
=
'1'
then
sfreq_s
<=
freq
;
end
if
;
end
if
;
end
process
;
oc_sfreq_o
<=
sfreq_s
;
-- Generate channel selection signals.
last_o
<=
'1'
;
end
architecture
;
core/tdc_package.vhd
View file @
5b4244cb
...
...
@@ -12,6 +12,7 @@
--
-------------------------------------------------------------------------------
-- last changes:
-- 2011-10-25 SB Added single/multi channel bank components
-- 2011-08-03 SB Created file
-------------------------------------------------------------------------------
...
...
@@ -169,6 +170,107 @@ component tdc_channelbank is
);
end
component
;
component
tdc_channelbank_single
is
generic
(
g_CARRY4_COUNT
:
positive
;
g_RAW_COUNT
:
positive
;
g_FP_COUNT
:
positive
;
g_COARSE_COUNT
:
positive
;
g_RO_LENGTH
:
positive
;
g_FCOUNTER_WIDTH
:
positive
;
g_FTIMER_WIDTH
:
positive
);
port
(
clk_i
:
in
std_logic
;
reset_i
:
in
std_logic
;
cc_rst_i
:
in
std_logic
;
cc_cy_o
:
out
std_logic
;
next_i
:
in
std_logic
;
last_o
:
out
std_logic
;
calib_sel_i
:
in
std_logic
;
deskew_i
:
in
std_logic_vector
(
g_COARSE_COUNT
+
g_FP_COUNT
-1
downto
0
);
signal_i
:
in
std_logic
;
calib_i
:
in
std_logic
;
detect_o
:
out
std_logic
;
polarity_o
:
out
std_logic
;
raw_o
:
out
std_logic_vector
(
g_RAW_COUNT
-1
downto
0
);
fp_o
:
out
std_logic_vector
(
g_COARSE_COUNT
+
g_FP_COUNT
-1
downto
0
);
lut_a_i
:
in
std_logic_vector
(
g_RAW_COUNT
-1
downto
0
);
lut_we_i
:
in
std_logic
;
lut_d_i
:
in
std_logic_vector
(
g_FP_COUNT
-1
downto
0
);
lut_d_o
:
out
std_logic_vector
(
g_FP_COUNT
-1
downto
0
);
c_detect_o
:
out
std_logic
;
c_raw_o
:
out
std_logic_vector
(
g_RAW_COUNT
-1
downto
0
);
his_a_i
:
in
std_logic_vector
(
g_RAW_COUNT
-1
downto
0
);
his_we_i
:
in
std_logic
;
his_d_i
:
in
std_logic_vector
(
g_FP_COUNT
-1
downto
0
);
his_d_o
:
out
std_logic_vector
(
g_FP_COUNT
-1
downto
0
);
oc_start_i
:
in
std_logic
;
oc_ready_o
:
out
std_logic
;
oc_freq_o
:
out
std_logic_vector
(
g_FCOUNTER_WIDTH
-1
downto
0
);
oc_store_i
:
in
std_logic
;
oc_sfreq_o
:
out
std_logic_vector
(
g_FCOUNTER_WIDTH
-1
downto
0
)
);
end
component
;
component
tdc_channelbank_multi
is
generic
(
g_CHANNEL_COUNT
:
positive
;
g_CARRY4_COUNT
:
positive
;
g_RAW_COUNT
:
positive
;
g_FP_COUNT
:
positive
;
g_COARSE_COUNT
:
positive
;
g_RO_LENGTH
:
positive
;
g_FCOUNTER_WIDTH
:
positive
;
g_FTIMER_WIDTH
:
positive
);
port
(
clk_i
:
in
std_logic
;
reset_i
:
in
std_logic
;
cc_rst_i
:
in
std_logic
;
cc_cy_o
:
out
std_logic
;
next_i
:
in
std_logic
;
last_o
:
out
std_logic
;
calib_sel_i
:
in
std_logic
;
deskew_i
:
in
std_logic_vector
(
g_CHANNEL_COUNT
*
(
g_COARSE_COUNT
+
g_FP_COUNT
)
-1
downto
0
);
signal_i
:
in
std_logic_vector
(
g_CHANNEL_COUNT
-1
downto
0
);
calib_i
:
in
std_logic_vector
(
g_CHANNEL_COUNT
-1
downto
0
);
detect_o
:
out
std_logic_vector
(
g_CHANNEL_COUNT
-1
downto
0
);
polarity_o
:
out
std_logic_vector
(
g_CHANNEL_COUNT
-1
downto
0
);
raw_o
:
out
std_logic_vector
(
g_CHANNEL_COUNT
*
g_RAW_COUNT
-1
downto
0
);
fp_o
:
out
std_logic_vector
(
g_CHANNEL_COUNT
*
(
g_COARSE_COUNT
+
g_FP_COUNT
)
-1
downto
0
);
lut_a_i
:
in
std_logic_vector
(
g_RAW_COUNT
-1
downto
0
);
lut_we_i
:
in
std_logic
;
lut_d_i
:
in
std_logic_vector
(
g_FP_COUNT
-1
downto
0
);
lut_d_o
:
out
std_logic_vector
(
g_FP_COUNT
-1
downto
0
);
c_detect_o
:
out
std_logic
;
c_raw_o
:
out
std_logic_vector
(
g_RAW_COUNT
-1
downto
0
);
his_a_i
:
in
std_logic_vector
(
g_RAW_COUNT
-1
downto
0
);
his_we_i
:
in
std_logic
;
his_d_i
:
in
std_logic_vector
(
g_FP_COUNT
-1
downto
0
);
his_d_o
:
out
std_logic_vector
(
g_FP_COUNT
-1
downto
0
);
oc_start_i
:
in
std_logic
;
oc_ready_o
:
out
std_logic
;
oc_freq_o
:
out
std_logic_vector
(
g_FCOUNTER_WIDTH
-1
downto
0
);
oc_store_i
:
in
std_logic
;
oc_sfreq_o
:
out
std_logic_vector
(
g_FCOUNTER_WIDTH
-1
downto
0
)
);
end
component
;
component
tdc_freqc
is
generic
(
g_COUNTER_WIDTH
:
positive
;
...
...
demo/boards/spec/rtl/system.v
View file @
5b4244cb
...
...
@@ -32,7 +32,7 @@ module system(
output
[
3
:
0
]
led
,
// TDC
input
[
1
:
0
]
tdc_signal
input
tdc_signal
)
;
//------------------------------------------------------------------
...
...
@@ -455,10 +455,10 @@ sysctl #(
//---------------------------------------------------------------------------
// TDC
//---------------------------------------------------------------------------
wire
[
1
:
0
]
tdc_calib
;
wire
tdc_calib
;
tdc_hostif
#(
.
g_CHANNEL_COUNT
(
2
)
,
.
g_CHANNEL_COUNT
(
1
)
,
.
g_CARRY4_COUNT
(
100
)
,
.
g_RAW_COUNT
(
9
)
,
.
g_FP_COUNT
(
13
)
,
...
...
@@ -499,6 +499,6 @@ reg [3:0] cal_clkdiv;
always
@
(
posedge
cal_clk16x
)
cal_clkdiv
<=
cal_clkdiv
+
4'd1
;
assign
cal_clk
=
cal_clkdiv
[
3
]
;
assign
tdc_calib
=
{
2
{
cal_clk
}}
;
assign
tdc_calib
=
cal_clk
;
endmodule
demo/boards/spec/synthesis/common.ucf
View file @
5b4244cb
...
...
@@ -24,9 +24,7 @@ NET "led[3]" LOC = C20 | IOSTANDARD = "LVCMOS18";
# ==== TDC inputs ====
# FIXME
NET "tdc_signal[0]" LOC = AB11 | IOSTANDARD = LVCMOS25 | PULLDOWN;
NET "tdc_signal[1]" LOC = Y11 | IOSTANDARD = LVCMOS25 | PULLDOWN;
NET "tdc_signal" LOC = AB11 | IOSTANDARD = LVCMOS25 | PULLDOWN;
# ==== TDC core ====
NET "tdc/cmp_tdc/cmp_channelbank/g_channels[0].cmp_channel/muxed_signal" TIG;
NET "tdc/cmp_tdc/cmp_channelbank/g_channels[1].cmp_channel/muxed_signal" TIG;
NET "tdc/cmp_tdc/cmp_channelbank/g_single.cmp_channelbank/cmp_channel/muxed_signal" TIG;
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