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
60abe30e
Commit
60abe30e
authored
Aug 03, 2011
by
Sebastien Bourdeauducq
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Basic delay line and encoder
parent
0ac60964
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
243 additions
and
49 deletions
+243
-49
tdc_channel.vhd
core/tdc_channel.vhd
+87
-0
tdc_delayline.vhd
core/tdc_delayline.vhd
+28
-16
tdc_lbc.vhd
core/tdc_lbc.vhd
+45
-21
tdc_package.vhd
core/tdc_package.vhd
+51
-0
simulate.sh
tb/lbc/simulate.sh
+1
-1
tb_lbc.vhd
tb/lbc/tb_lbc.vhd
+31
-11
No files found.
core/tdc_channel.vhd
0 → 100644
View file @
60abe30e
-------------------------------------------------------------------------------
-- TDC Core / CERN
-------------------------------------------------------------------------------
--
-- unit name: tdc_channel
--
-- author: Sebastien Bourdeauducq, sebastien@milkymist.org
--
-- description: Per-channel processing
--
-- references: http://www.ohwr.org/projects/tdc-core
--
-------------------------------------------------------------------------------
-- last changes:
-- 2011-08-03 SB Created file
-------------------------------------------------------------------------------
-- Copyright (C) 2011 Sebastien Bourdeauducq
library
ieee
;
use
ieee
.
std_logic_1164
.
all
;
use
work
.
tdc_package
.
all
;
entity
tdc_channel
is
generic
(
-- Number of CARRY4 elements.
g_CARRY4_COUNT
:
positive
;
-- Number of raw output bits.
g_RAW_COUNT
:
positive
);
port
(
clk_i
:
in
std_logic
;
reset_i
:
in
std_logic
;
signal_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
)
);
end
entity
;
architecture
rtl
of
tdc_channel
is
signal
taps
:
std_logic_vector
(
4
*
g_CARRY4_COUNT
-1
downto
0
);
signal
polarity
,
polarity_d1
:
std_logic
;
signal
raw
:
std_logic_vector
(
g_RAW_COUNT
-1
downto
0
);
begin
cmp_delayline
:
tdc_delayline
generic
map
(
g_WIDTH
=>
g_CARRY4_COUNT
)
port
map
(
clk_i
=>
clk_i
,
reset_i
=>
reset_i
,
signal_i
=>
signal_i
,
taps_o
=>
taps
);
cmp_lbc
:
tdc_lbc
generic
map
(
g_N
=>
g_RAW_COUNT
,
g_NIN
=>
g_CARRY4_COUNT
*
4
)
port
map
(
clk_i
=>
clk_i
,
reset_i
=>
reset_i
,
d_i
=>
taps
,
polarity_o
=>
polarity
,
count_o
=>
raw
);
polarity_o
<=
polarity_d1
;
process
(
clk_i
)
begin
if
rising_edge
(
clk_i
)
then
if
reset_i
=
'1'
then
detect_o
<=
'0'
;
polarity_d1
<=
'1'
;
raw_o
<=
(
others
=>
'0'
);
else
detect_o
<=
polarity
xor
polarity_d1
;
polarity_d1
<=
polarity
;
raw_o
<=
raw
;
end
if
;
end
if
;
end
process
;
end
architecture
;
core/tdc_delayline.vhd
View file @
60abe30e
...
...
@@ -24,11 +24,13 @@ library UNISIM;
use
UNISIM
.
vcomponents
.
all
;
entity
tdc_delayline
is
generic
(
g_WIDTH
:
positive
-- number of CARRY4 elements
generic
(
-- Number of CARRY4 elements.
g_WIDTH
:
positive
);
port
(
clk_sample_i
:
in
std_logic
;
port
(
clk_i
:
in
std_logic
;
reset_i
:
in
std_logic
;
signal_i
:
in
std_logic
;
taps_o
:
out
std_logic_vector
(
4
*
g_WIDTH
-1
downto
0
)
);
...
...
@@ -41,7 +43,7 @@ begin
-- generate a carry chain
g_carry4
:
for
i
in
0
to
g_WIDTH
-1
generate
g_firstcarry4
:
if
i
=
0
generate
CARRY4_inst
:
CARRY4
port
map
(
cmp_CARRY4
:
CARRY4
port
map
(
CO
=>
unreg
(
3
downto
0
),
CI
=>
'0'
,
CYINIT
=>
signal_i
,
...
...
@@ -50,7 +52,7 @@ begin
);
end
generate
;
g_nextcarry4
:
if
i
>
0
generate
CARRY4_inst
:
CARRY4
port
map
(
cmp_CARRY4
:
CARRY4
port
map
(
CO
=>
unreg
(
4
*
(
i
+
1
)
-1
downto
4
*
i
),
CI
=>
unreg
(
4
*
i
-1
),
CYINIT
=>
'0'
,
...
...
@@ -62,15 +64,25 @@ begin
-- double latch the output
g_fd
:
for
j
in
0
to
4
*
g_WIDTH
-1
generate
FD_inst1
:
FD
port
map
(
C
=>
clk_sample_i
,
D
=>
unreg
(
j
),
Q
=>
reg1
(
j
)
);
FD_inst2
:
FD
port
map
(
C
=>
clk_sample_i
,
D
=>
reg1
(
j
),
Q
=>
taps_o
(
j
)
);
cmp_FDR_1
:
FDR
generic
map
(
INIT
=>
'0'
)
port
map
(
C
=>
clk_i
,
R
=>
reset_i
,
D
=>
unreg
(
j
),
Q
=>
reg1
(
j
)
);
cmp_FDR_2
:
FDR
generic
map
(
INIT
=>
'0'
)
port
map
(
C
=>
clk_i
,
R
=>
reset_i
,
D
=>
reg1
(
j
),
Q
=>
taps_o
(
j
)
);
end
generate
;
end
architecture
;
core/tdc_lbc.vhd
View file @
60abe30e
...
...
@@ -23,58 +23,82 @@ use ieee.std_logic_1164.all;
entity
tdc_lbc
is
generic
(
-- Number of output bits.
-- The number of input bits is 2^g_N-1.
g_N
:
positive
g_N
:
positive
;
-- Number of input bits. Maximum is 2^g_N-1.
g_NIN
:
positive
);
port
(
port
(
clk_i
:
in
std_logic
;
polarity_i
:
in
std_logic
;
d_i
:
in
std_logic_vector
(
2
**
g_N
-2
downto
0
);
reset_i
:
in
std_logic
;
d_i
:
in
std_logic_vector
(
g_NIN
-1
downto
0
);
polarity_o
:
out
std_logic
;
count_o
:
out
std_logic_vector
(
g_N
-1
downto
0
)
);
end
entity
;
architecture
rtl
of
tdc_lbc
is
-- "Count leading
ones
" function inspired by the post by Ulf Samuelsson
-- "Count leading
symbol
" function inspired by the post by Ulf Samuelsson
-- http://www.velocityreviews.com/forums/t25846-p4-how-to-count-zeros-in-registers.html
--
-- The idea is to use a divide-and-conquer approach to process a 2^N bit number.
-- We split the number in two equal halves of 2^(N-1) bits:
-- MMMMLLLL
-- then, we check if
MMMM is all 1's
.
-- then, we check if
all bits of MMMM are of the counted symbol
.
-- If it is,
-- then the number of leading
ones is 2^(N-1) + CLO
(LLLL)
-- then the number of leading
symbols is 2^(N-1) + CLS
(LLLL)
-- If it is not,
-- then the number of leading
ones is CLO
(MMMM)
-- Recursion stops with CL
O(0)=0 and CLO
(1)=1.
-- then the number of leading
symbols is CLS
(MMMM)
-- Recursion stops with CL
S(0)=0 and CLS
(1)=1.
--
-- If
the input is not all ones, we never propagate a carry and
-- the additions can be replaced by OR's, giving the result bit per bit.
-- We assume here an implicit LSB with a
0
value, and work with inputs
-- If
at least one bit of the input is not the symbol, we never propagate a carry
--
and
the additions can be replaced by OR's, giving the result bit per bit.
-- We assume here an implicit LSB with a
!symbol
value, and work with inputs
-- widths that are a power of 2 minus one.
function
f_cl
o
(
d
:
std_logic_vector
)
return
std_logic_vector
is
function
f_cl
s
(
d
:
std_logic_vector
;
symbol
:
std_logic
)
return
std_logic_vector
is
variable
v_d
:
std_logic_vector
(
d
'length
-1
downto
0
);
begin
v_d
:
=
d
;
-- fix indices
if
v_d
'length
=
1
then
return
v_d
(
0
downto
0
);
if
v_d
(
0
)
=
symbol
then
return
"1"
;
else
return
"0"
;
end
if
;
else
if
v_d
(
v_d
'length
-1
downto
v_d
'length
/
2
)
=
(
v_d
'length
-1
downto
v_d
'length
/
2
=>
'1'
)
then
return
"1"
&
f_cl
o
(
v_d
(
v_d
'length
/
2-1
downto
0
)
);
if
v_d
(
v_d
'length
-1
downto
v_d
'length
/
2
)
=
(
v_d
'length
-1
downto
v_d
'length
/
2
=>
symbol
)
then
return
"1"
&
f_cl
s
(
v_d
(
v_d
'length
/
2-1
downto
0
),
symbol
);
else
return
"0"
&
f_cl
o
(
v_d
(
v_d
'length
-1
downto
v_d
'length
/
2
+
1
)
);
return
"0"
&
f_cl
s
(
v_d
(
v_d
'length
-1
downto
v_d
'length
/
2
+
1
),
symbol
);
end
if
;
end
if
;
end
function
;
signal
d_x
:
std_logic_vector
(
d_i
'length
-1
downto
0
);
signal
polarity
:
std_logic
;
signal
count_reg
:
std_logic_vector
(
g_N
-1
downto
0
);
signal
d_completed
:
std_logic_vector
(
2
**
g_N
-2
downto
0
);
begin
d_x
<=
(
d_i
'length
-1
downto
0
=>
polarity_i
)
xor
d_i
;
polarity_o
<=
polarity
;
g_expand
:
if
g_NIN
<
2
**
g_N
-1
generate
d_completed
<=
d_i
&
(
2
**
g_N
-1
-
g_NIN
-1
downto
0
=>
not
polarity
);
end
generate
;
g_dontexpand
:
if
g_NIN
=
2
**
g_N
-1
generate
d_completed
<=
d_i
;
end
generate
;
process
(
clk_i
)
begin
if
rising_edge
(
clk_i
)
then
count_o
<=
f_clo
(
d_x
);
if
reset_i
=
'1'
then
polarity
<=
'1'
;
count_reg
<=
(
others
=>
'0'
);
count_o
<=
(
others
=>
'0'
);
else
polarity
<=
not
d_completed
(
2
**
g_N
-2
);
count_reg
<=
f_cls
(
d_completed
,
polarity
);
count_o
<=
count_reg
;
end
if
;
end
if
;
end
process
;
end
architecture
;
core/tdc_package.vhd
0 → 100644
View file @
60abe30e
-------------------------------------------------------------------------------
-- TDC Core / CERN
-------------------------------------------------------------------------------
--
-- unit name: tdc_package
--
-- author: Sebastien Bourdeauducq, sebastien@milkymist.org
--
-- description: Component declarations for the TDC core
--
-- references: http://www.ohwr.org/projects/tdc-core
--
-------------------------------------------------------------------------------
-- last changes:
-- 2011-08-03 SB Created file
-------------------------------------------------------------------------------
-- Copyright (C) 2011 Sebastien Bourdeauducq
library
ieee
;
use
ieee
.
std_logic_1164
.
all
;
package
tdc_package
is
component
tdc_lbc
is
generic
(
g_N
:
positive
;
g_NIN
:
positive
);
port
(
clk_i
:
in
std_logic
;
reset_i
:
in
std_logic
;
d_i
:
in
std_logic_vector
(
g_NIN
-1
downto
0
);
polarity_o
:
out
std_logic
;
count_o
:
out
std_logic_vector
(
g_N
-1
downto
0
)
);
end
component
;
component
tdc_delayline
is
generic
(
g_WIDTH
:
positive
);
port
(
clk_i
:
in
std_logic
;
reset_i
:
in
std_logic
;
signal_i
:
in
std_logic
;
taps_o
:
out
std_logic_vector
(
4
*
g_WIDTH
-1
downto
0
)
);
end
component
;
end
package
;
tb/lbc/simulate.sh
View file @
60abe30e
#!/bin/sh
set
-e
ghdl
-i
../../core/tdc_lbc.vhd tb_lbc.vhd
ghdl
-i
../../core/tdc_
package.vhd ../../core/tdc_
lbc.vhd tb_lbc.vhd
ghdl
-m
tb_lbc
ghdl
-r
tb_lbc
tb/lbc/tb_lbc.vhd
View file @
60abe30e
...
...
@@ -17,10 +17,13 @@
-- Copyright (C) 2011 Sebastien Bourdeauducq
-- TODO: test pipelining and polarity inversion
library
ieee
;
use
ieee
.
std_logic_1164
.
all
;
use
ieee
.
numeric_std
.
all
;
use
ieee
.
math_real
.
all
;
use
work
.
tdc_package
.
all
;
entity
tb_lbc
is
generic
(
...
...
@@ -60,22 +63,26 @@ begin
end
function
;
signal
clk
:
std_logic
;
signal
polarity
:
std_logic
;
signal
reset
:
std_logic
;
signal
d
:
std_logic_vector
(
2
**
g_N
-2
downto
0
);
signal
d_bak
:
std_logic_vector
(
2
**
g_N
-2
downto
0
);
signal
count
:
std_logic_vector
(
g_N
-1
downto
0
);
signal
polarity
:
std_logic
;
begin
dut
:
entity
work
.
tdc_lbc
cmp_dut
:
tdc_lbc
generic
map
(
g_N
=>
g_N
g_N
=>
g_N
,
g_NIN
=>
2
**
g_N
-1
)
port
map
(
clk_i
=>
clk
,
polarity_i
=>
polarity
,
reset_i
=>
reset
,
d_i
=>
d
,
count_o
=>
count
count_o
=>
count
,
polarity_o
=>
polarity
);
polarity
<=
'0'
;
reset
<=
'0'
;
process
variable
v_seed1
:
positive
:
=
1
;
variable
v_seed2
:
positive
:
=
2
;
...
...
@@ -83,6 +90,14 @@ begin
variable
v_int_rand
:
integer
;
variable
v_stim
:
std_logic_vector
(
0
downto
0
);
begin
-- reset
reset
<=
'1'
;
clk
<=
'0'
;
wait
for
4
ns
;
clk
<=
'1'
;
wait
for
4
ns
;
reset
<=
'0'
;
for
i
in
0
to
2
**
g_N
-1
loop
-- generate test vector
for
j
in
0
to
2
**
g_N
-2
loop
...
...
@@ -97,12 +112,17 @@ begin
d
(
j
)
<=
v_stim
(
0
);
end
if
;
end
loop
;
wait
for
0
ns
;
d_bak
<=
d
;
-- generate, print and verify output
clk
<=
'0'
;
wait
for
4
ns
;
clk
<=
'1'
;
wait
for
4
ns
;
report
"Vector:"
&
str
(
d
)
&
" Expected:"
&
integer
'image
(
i
)
&
" Result:"
&
integer
'image
(
to_integer
(
unsigned
(
count
)));
for
j
in
0
to
1
loop
clk
<=
'0'
;
wait
for
4
ns
;
clk
<=
'1'
;
wait
for
4
ns
;
d
<=
(
others
=>
'0'
);
end
loop
;
report
"Vector:"
&
str
(
d_bak
)
&
" Expected:"
&
integer
'image
(
i
)
&
" Result:"
&
integer
'image
(
to_integer
(
unsigned
(
count
)))
&
"("
&
chr
(
polarity
)
&
")"
;
assert
i
=
to_integer
(
unsigned
(
count
))
severity
failure
;
end
loop
;
report
"Test passed."
;
...
...
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