Skip to content
Snippets Groups Projects
Commit 6896864b authored by Tomasz Wlostowski's avatar Tomasz Wlostowski
Browse files

working on the plan B, WIP

parent c9d9b7d6
No related merge requests found
Showing with 1057 additions and 1431 deletions
files = [
"tdc_controller.vhd", "tdc_freqc.vhd", "tdc_psync.vhd",
"tdc_channelbank.vhd", "tdc_delayline.vhd", "tdc_lbc.vhd", "tdc_ringosc.vhd",
"tdc_channel.vhd", "tdc_divider.vhd", "tdc_package.vhd", "tdc.vhd"
];
-------------------------------------------------------------------------------
-- 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-11-07 SB Pre-inversion
-- 2011-10-25 SB Disable ring oscillator on reset
-- 2011-08-03 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 contains the elements needed for each channel:
-- * Delay line
-- * Encoder
-- * LUT
-- * Deskew stage
-- * Online calibration 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_channel is
generic(
-- Number of CARRY4 elements.
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 the ring oscillator.
g_RO_LENGTH : positive
);
port(
clk_i : in std_logic;
reset_i : in std_logic;
-- Coarse counter and deskew inputs.
coarse_i : in std_logic_vector(g_COARSE_COUNT-1 downto 0);
deskew_i : in std_logic_vector((g_COARSE_COUNT+g_FP_COUNT)-1 downto 0);
-- Signal input.
signal_i : in std_logic;
calib_i : in std_logic;
calib_sel_i : in std_logic;
-- 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);
-- Calibration ring oscillator.
ro_en_i : in std_logic;
ro_clk_o : out std_logic
);
end entity;
architecture rtl of tdc_channel is
signal calib_sel_d : std_logic;
signal muxed_signal : std_logic;
signal inv_signal : std_logic;
signal taps : std_logic_vector(4*g_CARRY4_COUNT-1 downto 0);
signal ipolarity : std_logic;
signal polarity : std_logic;
signal polarity_d1 : std_logic;
signal polarity_d2 : std_logic;
signal detect_d1 : std_logic;
signal raw : std_logic_vector(g_RAW_COUNT-1 downto 0);
signal raw_d1 : std_logic_vector(g_RAW_COUNT-1 downto 0);
signal raw_d2 : std_logic_vector(g_RAW_COUNT-1 downto 0);
signal lut : std_logic_vector(g_FP_COUNT-1 downto 0);
signal ro_en : std_logic;
begin
-- register calibration select signal to avoid glitches
process(clk_i)
begin
if rising_edge(clk_i) then
calib_sel_d <= calib_sel_i;
end if;
end process;
with calib_sel_d select
muxed_signal <= calib_i when '1', signal_i when others;
inv_signal <= muxed_signal xor not ipolarity;
cmp_delayline: tdc_delayline
generic map(
g_WIDTH => g_CARRY4_COUNT
)
port map(
clk_i => clk_i,
reset_i => reset_i,
signal_i => inv_signal,
taps_o => taps
);
cmp_lbc: tdc_lbc
generic map(
g_N => g_RAW_COUNT,
g_NIN => g_CARRY4_COUNT*4,
g_IGNORE => 2
)
port map(
clk_i => clk_i,
reset_i => reset_i,
d_i => taps,
ipolarity_o => ipolarity,
polarity_o => polarity,
count_o => raw
);
cmp_lut: generic_dpram
generic map(
g_data_width => g_FP_COUNT,
g_size => 2**g_RAW_COUNT,
g_with_byte_enable => false,
g_addr_conflict_resolution => "read_first",
g_init_file => "",
g_dual_clock => false
)
port map(
clka_i => clk_i,
clkb_i => '0',
wea_i => '0',
bwea_i => (others => '0'),
aa_i => raw,
da_i => (others => '0'),
qa_o => lut,
web_i => lut_we_i,
bweb_i => (others => '0'),
ab_i => lut_a_i,
db_i => lut_d_i,
qb_o => lut_d_o
);
cmp_ringosc: tdc_ringosc
generic map(
g_LENGTH => g_RO_LENGTH
)
port map(
en_i => ro_en,
clk_o => ro_clk_o
);
ro_en <= ro_en_i and not reset_i;
detect_d1 <= polarity_d1 xor polarity_d2;
process(clk_i)
begin
if rising_edge(clk_i) then
if reset_i = '1' then
detect_o <= '0';
polarity_d1 <= '1';
polarity_d2 <= '1';
raw_d1 <= (others => '0');
raw_d2 <= (others => '0');
else
detect_o <= detect_d1;
polarity_d1 <= polarity;
raw_d1 <= raw;
if detect_d1 = '1' then
polarity_d2 <= polarity_d1;
raw_d2 <= raw_d1;
end if;
end if;
end if;
end process;
polarity_o <= polarity_d2;
raw_o <= raw_d2;
-- Combine coarse counter value and deskew.
process(clk_i)
begin
if rising_edge(clk_i) then
if reset_i = '1' then
fp_o <= (others => '0');
else
if detect_d1 = '1' then
fp_o <= std_logic_vector(
unsigned(coarse_i & (lut'range => '0'))
- unsigned(lut)
+ unsigned(deskew_i));
end if;
end if;
end if;
end process;
end architecture;
This diff is collapsed.
-------------------------------------------------------------------------------
-- 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-11-07 SB Pre-inversion
-- 2011-11-05 SB Added extra histogram bits support
-- 2011-10-25 SB Added single/multi channel bank components
-- 2011-08-03 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 contains component declarations for all the modules of the TDC core.
-- It is used both internally to instantiate modules, and by the user to
-- instantiate the top-level "tdc" module.
library ieee;
use ieee.std_logic_1164.all;
package tdc_package is
component tdc is
generic(
g_CHANNEL_COUNT : positive := 2;
g_CARRY4_COUNT : positive := 100;
g_RAW_COUNT : positive := 9;
g_FP_COUNT : positive := 13;
g_EXHIS_COUNT : positive := 4;
g_COARSE_COUNT : positive := 25;
g_RO_LENGTH : positive := 20;
g_FCOUNTER_WIDTH : positive := 13;
g_FTIMER_WIDTH : positive := 10
);
port(
clk_i : in std_logic;
reset_i : in std_logic;
ready_o : out std_logic;
cc_rst_i : in std_logic;
cc_cy_o : out 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);
freeze_req_i : in std_logic;
freeze_ack_o : out std_logic;
cs_next_i : in std_logic;
cs_last_o : out std_logic;
calib_sel_i : in std_logic;
lut_a_i : in std_logic_vector(g_RAW_COUNT-1 downto 0);
lut_d_o : out std_logic_vector(g_FP_COUNT-1 downto 0);
his_a_i : in std_logic_vector(g_RAW_COUNT-1 downto 0);
his_d_o : out std_logic_vector(g_FP_COUNT+g_EXHIS_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_sfreq_o : out std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0)
);
end component;
component tdc_controller is
generic(
g_RAW_COUNT : positive;
g_FP_COUNT : positive;
g_EXHIS_COUNT : positive;
g_FCOUNTER_WIDTH : positive
);
port(
clk_i : in std_logic;
reset_i : in std_logic;
ready_o : out std_logic;
next_o : out std_logic;
last_i : in std_logic;
calib_sel_o : out std_logic;
lut_a_o : out std_logic_vector(g_RAW_COUNT-1 downto 0);
lut_we_o : out std_logic;
lut_d_o : out std_logic_vector(g_FP_COUNT-1 downto 0);
c_detect_i : in std_logic;
c_raw_i : in std_logic_vector(g_RAW_COUNT-1 downto 0);
his_a_o : out std_logic_vector(g_RAW_COUNT-1 downto 0);
his_we_o : out std_logic;
his_d_o : out std_logic_vector(g_FP_COUNT+g_EXHIS_COUNT-1 downto 0);
his_d_i : in std_logic_vector(g_FP_COUNT+g_EXHIS_COUNT-1 downto 0);
oc_start_o : out std_logic;
oc_ready_i : in std_logic;
oc_freq_i : in std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0);
oc_store_o : out std_logic;
oc_sfreq_i : in std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0);
freeze_req_i : in std_logic;
freeze_ack_o : out std_logic
);
end component;
component tdc_channelbank is
generic(
g_CHANNEL_COUNT : positive;
g_CARRY4_COUNT : positive;
g_RAW_COUNT : positive;
g_FP_COUNT : positive;
g_EXHIS_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+g_EXHIS_COUNT-1 downto 0);
his_d_o : out std_logic_vector(g_FP_COUNT+g_EXHIS_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_single is
generic(
g_CARRY4_COUNT : positive;
g_RAW_COUNT : positive;
g_FP_COUNT : positive;
g_EXHIS_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+g_EXHIS_COUNT-1 downto 0);
his_d_o : out std_logic_vector(g_FP_COUNT+g_EXHIS_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_EXHIS_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+g_EXHIS_COUNT-1 downto 0);
his_d_o : out std_logic_vector(g_FP_COUNT+g_EXHIS_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;
g_TIMER_WIDTH : positive
);
port(
clk_i : in std_logic;
reset_i : in std_logic;
clk_m_i : in std_logic;
start_i : in std_logic;
ready_o : out std_logic;
freq_o : out std_logic_vector(g_COUNTER_WIDTH-1 downto 0)
);
end component;
component tdc_channel is
generic(
g_CARRY4_COUNT : positive;
g_RAW_COUNT : positive;
g_FP_COUNT : positive;
g_COARSE_COUNT : positive;
g_RO_LENGTH : positive
);
port(
clk_i : in std_logic;
reset_i : in std_logic;
coarse_i : in std_logic_vector(g_COARSE_COUNT-1 downto 0);
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;
calib_sel_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);
ro_en_i : in std_logic;
ro_clk_o : out std_logic
);
end component;
component tdc_ringosc is
generic(
g_LENGTH: positive
);
port(
en_i : in std_logic;
clk_o : out std_logic
);
end component;
component tdc_lbc is
generic(
g_N : positive;
g_NIN : positive;
g_IGNORE : natural
);
port(
clk_i : in std_logic;
reset_i : in std_logic;
d_i : in std_logic_vector(g_NIN-1 downto 0);
ipolarity_o : out std_logic;
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;
component tdc_ordertaps is
generic(
g_WIDTH: positive
);
port(
unsorted_i : in std_logic_vector(4*g_WIDTH-1 downto 0);
sorted_o : out std_logic_vector(4*g_WIDTH-1 downto 0)
);
end component;
component tdc_divider is
generic(
g_WIDTH: positive
);
port(
clk_i : in std_logic;
reset_i : in std_logic;
start_i : in std_logic;
dividend_i : in std_logic_vector(g_WIDTH-1 downto 0);
divisor_i : in std_logic_vector(g_WIDTH-1 downto 0);
ready_o : out std_logic;
quotient_o : out std_logic_vector(g_WIDTH-1 downto 0);
remainder_o : out std_logic_vector(g_WIDTH-1 downto 0)
);
end component;
component tdc_psync is
port(
clk_src_i : in std_logic;
p_i : in std_logic;
clk_dst_i : in std_logic;
p_o : out std_logic
);
end component;
end package;
modules = { "local" : [ "../core" ] }
files = [ "tdc_hostif_package.vhd", "tdc_hostif.vhd", "tdc_wb.vhd" ]
-------------------------------------------------------------------------------
-- TDC Core / CERN
-------------------------------------------------------------------------------
--
-- unit name: tdc_hostif
--
-- author: Sebastien Bourdeauducq, sebastien@milkymist.org
--
-- description: Host interface for the TDC core
--
-- references: http://www.ohwr.org/projects/tdc-core
--
-------------------------------------------------------------------------------
-- last changes:
-- 2011-11-05 SB Added extra histogram bits support
-- 2011-08-27 SB Reduced supported channel count to 8
-- 2011-08-26 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:
-- Top level module of the TDC core, contains all logic including the optional
-- host interface. It instantiates the basic TDC core and a Wishbone interface.
library ieee;
use ieee.std_logic_1164.all;
library work;
use work.tdc_package.all;
use work.tdc_hostif_package.all;
entity tdc_hostif is
generic(
g_CHANNEL_COUNT : positive := 1;
g_CARRY4_COUNT : positive := 124;
g_RAW_COUNT : positive := 9;
g_FP_COUNT : positive := 13;
g_EXHIS_COUNT : positive := 4;
g_COARSE_COUNT : positive := 25;
g_RO_LENGTH : positive := 31;
g_FCOUNTER_WIDTH : positive := 13;
g_FTIMER_WIDTH : positive := 14
);
port(
rst_n_i : in std_logic;
wb_clk_i : in std_logic;
wb_addr_i : in std_logic_vector(5 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_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_irq_o : out std_logic;
cc_rst_i : in std_logic;
cc_cy_o : out std_logic;
signal_i : in std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
calib_i : in std_logic_vector(g_CHANNEL_COUNT-1 downto 0)
);
end entity;
architecture rtl of tdc_hostif is
signal reset : std_logic;
signal ready : std_logic;
signal cc_cy : std_logic;
signal deskew : std_logic_vector(g_CHANNEL_COUNT*(g_COARSE_COUNT+g_FP_COUNT)-1 downto 0);
signal detect : std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
signal polarity : std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
signal raw : std_logic_vector(g_CHANNEL_COUNT*g_RAW_COUNT-1 downto 0);
signal fp : std_logic_vector(g_CHANNEL_COUNT*(g_COARSE_COUNT+g_FP_COUNT)-1 downto 0);
signal freeze_req : std_logic;
signal freeze_ack : std_logic;
signal cs_next : std_logic;
signal cs_last : std_logic;
signal calib_sel : std_logic;
signal lut_a : std_logic_vector(g_RAW_COUNT-1 downto 0);
signal lut_d : std_logic_vector(g_FP_COUNT-1 downto 0);
signal his_a : std_logic_vector(g_RAW_COUNT-1 downto 0);
signal his_d : std_logic_vector(g_FP_COUNT+g_EXHIS_COUNT-1 downto 0);
signal oc_start : std_logic;
signal oc_ready : std_logic;
signal oc_freq : std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0);
signal oc_sfreq : std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0);
signal wbg_luta : std_logic_vector(15 downto 0);
signal wbg_lutd : std_logic_vector(31 downto 0);
signal wbg_hisa : std_logic_vector(15 downto 0);
signal wbg_hisd : std_logic_vector(31 downto 0);
signal wbg_fcr : std_logic_vector(31 downto 0);
signal wbg_fcsr : std_logic_vector(31 downto 0);
-- maximum number of channels the host interface can support
constant c_NCHAN: positive := 8;
signal wbg_des : std_logic_vector(c_NCHAN*64-1 downto 0);
signal wbg_pol : std_logic_vector(c_NCHAN-1 downto 0);
signal wbg_raw : std_logic_vector(c_NCHAN*32-1 downto 0);
signal wbg_mes : std_logic_vector(c_NCHAN*64-1 downto 0);
signal wbg_ie : std_logic_vector(c_NCHAN-1 downto 0);
begin
cmp_tdc: tdc
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_EXHIS_COUNT => g_EXHIS_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 => wb_clk_i,
reset_i => reset,
ready_o => ready,
cc_rst_i => cc_rst_i,
cc_cy_o => cc_cy,
deskew_i => deskew,
signal_i => signal_i,
calib_i => calib_i,
detect_o => detect,
polarity_o => polarity,
raw_o => raw,
fp_o => fp,
freeze_req_i => freeze_req,
freeze_ack_o => freeze_ack,
cs_next_i => cs_next,
cs_last_o => cs_last,
calib_sel_i => calib_sel,
lut_a_i => lut_a,
lut_d_o => lut_d,
his_a_i => his_a,
his_d_o => his_d,
oc_start_i => oc_start,
oc_ready_o => oc_ready,
oc_freq_o => oc_freq,
oc_sfreq_o => oc_sfreq
);
cc_cy_o <= cc_cy;
cmp_wb: tdc_wb
port map(
rst_n_i => rst_n_i,
wb_clk_i => wb_clk_i,
wb_addr_i => wb_addr_i,
wb_data_i => wb_data_i,
wb_data_o => wb_data_o,
wb_cyc_i => wb_cyc_i,
wb_sel_i => wb_sel_i,
wb_stb_i => wb_stb_i,
wb_we_i => wb_we_i,
wb_ack_o => wb_ack_o,
wb_irq_o => wb_irq_o,
tdc_cs_rst_o => reset,
tdc_cs_rdy_i => ready,
irq_isc_i => ready,
irq_icc_i => cc_cy,
tdc_dctl_req_o => freeze_req,
tdc_dctl_ack_i => freeze_ack,
tdc_csel_next_o => cs_next,
tdc_csel_last_i => cs_last,
tdc_cal_o => calib_sel,
tdc_fcc_st_o => oc_start,
tdc_fcc_rdy_i => oc_ready,
tdc_luta_o => wbg_luta,
tdc_lutd_i => wbg_lutd,
tdc_hisa_o => wbg_hisa,
tdc_hisd_i => wbg_hisd,
tdc_fcr_i => wbg_fcr,
tdc_fcsr_i => wbg_fcsr,
tdc_pol_i => wbg_pol,
-- begin autogenerated connections
tdc_desh0_o => wbg_des(63 downto 32),
tdc_desl0_o => wbg_des(31 downto 0),
tdc_desh1_o => wbg_des(127 downto 96),
tdc_desl1_o => wbg_des(95 downto 64),
tdc_desh2_o => wbg_des(191 downto 160),
tdc_desl2_o => wbg_des(159 downto 128),
tdc_desh3_o => wbg_des(255 downto 224),
tdc_desl3_o => wbg_des(223 downto 192),
tdc_desh4_o => wbg_des(319 downto 288),
tdc_desl4_o => wbg_des(287 downto 256),
tdc_desh5_o => wbg_des(383 downto 352),
tdc_desl5_o => wbg_des(351 downto 320),
tdc_desh6_o => wbg_des(447 downto 416),
tdc_desl6_o => wbg_des(415 downto 384),
tdc_desh7_o => wbg_des(511 downto 480),
tdc_desl7_o => wbg_des(479 downto 448),
tdc_raw0_i => wbg_raw(31 downto 0),
tdc_mesh0_i => wbg_mes(63 downto 32),
tdc_mesl0_i => wbg_mes(31 downto 0),
tdc_raw1_i => wbg_raw(63 downto 32),
tdc_mesh1_i => wbg_mes(127 downto 96),
tdc_mesl1_i => wbg_mes(95 downto 64),
tdc_raw2_i => wbg_raw(95 downto 64),
tdc_mesh2_i => wbg_mes(191 downto 160),
tdc_mesl2_i => wbg_mes(159 downto 128),
tdc_raw3_i => wbg_raw(127 downto 96),
tdc_mesh3_i => wbg_mes(255 downto 224),
tdc_mesl3_i => wbg_mes(223 downto 192),
tdc_raw4_i => wbg_raw(159 downto 128),
tdc_mesh4_i => wbg_mes(319 downto 288),
tdc_mesl4_i => wbg_mes(287 downto 256),
tdc_raw5_i => wbg_raw(191 downto 160),
tdc_mesh5_i => wbg_mes(383 downto 352),
tdc_mesl5_i => wbg_mes(351 downto 320),
tdc_raw6_i => wbg_raw(223 downto 192),
tdc_mesh6_i => wbg_mes(447 downto 416),
tdc_mesl6_i => wbg_mes(415 downto 384),
tdc_raw7_i => wbg_raw(255 downto 224),
tdc_mesh7_i => wbg_mes(511 downto 480),
tdc_mesl7_i => wbg_mes(479 downto 448),
irq_ie0_i => wbg_ie(0),
irq_ie1_i => wbg_ie(1),
irq_ie2_i => wbg_ie(2),
irq_ie3_i => wbg_ie(3),
irq_ie4_i => wbg_ie(4),
irq_ie5_i => wbg_ie(5),
irq_ie6_i => wbg_ie(6),
irq_ie7_i => wbg_ie(7)
-- end autogenerated connections
);
-- All synthesizers I know of will set unconnected bits to 0.
lut_a <= wbg_luta(g_RAW_COUNT-1 downto 0);
wbg_lutd(lut_d'range) <= lut_d;
his_a <= wbg_hisa(g_RAW_COUNT-1 downto 0);
wbg_hisd(his_d'range) <= his_d;
wbg_fcr(oc_freq'range) <= oc_freq;
wbg_fcsr(oc_sfreq'range) <= oc_sfreq;
g_connect: for i in 0 to g_CHANNEL_COUNT-1 generate
deskew((i+1)*(g_COARSE_COUNT+g_FP_COUNT)-1 downto i*(g_COARSE_COUNT+g_FP_COUNT))
<= wbg_des(i*64+g_COARSE_COUNT+g_FP_COUNT-1 downto i*64);
wbg_raw(i*32+g_RAW_COUNT-1 downto i*32)
<= raw((i+1)*g_RAW_COUNT-1 downto i*g_RAW_COUNT);
wbg_mes(i*64+g_COARSE_COUNT+g_FP_COUNT-1 downto i*64)
<= fp((i+1)*(g_COARSE_COUNT+g_FP_COUNT)-1 downto i*(g_COARSE_COUNT+g_FP_COUNT));
end generate;
wbg_pol(polarity'range) <= polarity;
wbg_ie(detect'range) <= detect;
end architecture;
files = [
"tdc_freqc.vhd",
"tdc_psync.vhd",
"tdc_delayline.vhd",
"tdc_lbc.vhd",
"tdc_ringosc.vhd",
"tdc_channel.vhd",
"tdc_divider.vhd",
"tdc_package.vhd",
"tdc_ordertaps.vhd",
"tdc_order_picker.vhd",
"tdc_channel_wb.vhd",
"tdc_wbgen2_pkg.vhd",
"tdc_core.vhd",
"xwb_urv_mcs.vhd"
];
modules = { "local" : [
"../ip_cores/general-cores",
"../ip_cores/urv-core"] };
wbgen2 -H record_full -K ../testbench/include/tdc_channel_wb.vh -V tdc_channel_wb.vhd -p tdc_wbgen2_pkg.vhd tdc_channel_wb.wb
\ No newline at end of file
File moved
File moved
......@@ -127,7 +127,7 @@ signal oc_sfreq : std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0);
signal freeze_ack : std_logic;
begin
cmp_channelbank: tdc_channelbank
cmp_channelbank: entity work.tdc_channelbank
generic map(
g_CHANNEL_COUNT => g_CHANNEL_COUNT,
g_CARRY4_COUNT => g_CARRY4_COUNT,
......@@ -178,7 +178,7 @@ begin
oc_sfreq_o => oc_sfreq
);
cmp_controller: tdc_controller
cmp_controller: entity work.tdc_controller
generic map(
g_RAW_COUNT => g_RAW_COUNT,
g_FP_COUNT => g_FP_COUNT,
......
-------------------------------------------------------------------------------
-- 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-11-07 SB Pre-inversion
-- 2011-10-25 SB Disable ring oscillator on reset
-- 2011-08-03 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 contains the elements needed for each channel:
-- * Delay line
-- * Encoder
-- * LUT
-- * Deskew stage
-- * Online calibration 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;
use work.wishbone_pkg.all;
use work.tdc_wbgen2_pkg.all;
use work.gencores_pkg.all;
entity tdc_channel is
generic(
-- Number of CARRY4 elements.
g_CARRY4_COUNT : positive := 124;
-- Number of raw output bits.
g_RAW_COUNT : positive := 9;
-- Number of fractional part bits.
g_FP_COUNT : positive := 13;
-- Number of coarse counter bits.
g_COARSE_COUNT : positive := 25;
-- Length of the ring oscillator.
g_RO_LENGTH : positive := 31
);
port(
clk_sys_i : in std_logic;
rst_sys_n_i : in std_logic;
clk_tdc_i : in std_logic;
rst_tdc_n_i : in std_logic;
clk_cal_i : in std_logic;
-- Coarse counter and deskew inputs.
coarse_i : in std_logic_vector(g_COARSE_COUNT-1 downto 0);
-- Signal input.
signal_i : in std_logic;
slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out
-- calib_sel_i : in std_logic;
-- 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);
--raw_taps_o : out std_logic_vector(g_CARRY4_COUNT*4- 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);
-- Calibration ring oscillator.
-- ro_en_i : in std_logic;
-- ro_clk_o : out std_logic
);
end entity;
architecture rtl of tdc_channel is
signal calib_sel_d : std_logic;
signal muxed_signal : std_logic;
signal tdc_inv_input_signal : std_logic;
attribute keep : string;
attribute keep of tdc_inv_input_signal : signal is "true";
signal taps : std_logic_vector(4*g_CARRY4_COUNT-1 downto 0);
signal taps_latched : std_logic_vector(4*g_CARRY4_COUNT-1 downto 0);
signal ipolarity : std_logic;
signal polarity : std_logic;
signal polarity_d1 : std_logic;
signal polarity_d2 : std_logic;
signal detect_d1 : std_logic;
signal raw, raw_d1 : std_logic_vector(g_RAW_COUNT-1 downto 0);
signal raw_d2 : std_logic_vector(g_RAW_COUNT-1 downto 0);
signal lut_rvalue : std_logic_vector(g_FP_COUNT-1 downto 0);
signal ro_en : std_logic;
signal tdc_slave_out : t_wishbone_slave_out;
signal tdc_slave_in : t_wishbone_slave_in;
signal regs_in : t_tdc_in_registers;
signal regs_out : t_tdc_out_registers;
signal calib_next_sample : unsigned(14 downto 0);
signal calib_cur_sample : unsigned(14 downto 0);
signal calib_step_d : unsigned(14 downto 0);
signal calib_offset_d : unsigned(14 downto 0);
signal calib_p : std_logic;
signal calib_rst_n : std_logic;
signal rst_tdc : std_logic;
signal ro_clk : std_logic;
signal detect : std_logic;
signal prev_taps_zero : std_logic;
signal taps_latched_ready : std_logic;
constant c_max_tap_bank : integer := (g_CARRY4_COUNT*4 + 31) / 32;
function f_max(x : integer; y : integer) return integer is
begin
if (x > y) then
return x;
else
return y;
end if;
end f_max;
function f_clamp(x : integer; max : integer) return integer is
begin
if (x > max) then
return max;
else
return x;
end if;
end f_clamp;
begin
rst_tdc <= not rst_tdc_n_i;
--slave_o <= tdc_slave_out;
-- tdc_slave_in <= slave_i;
U_Clock_Crossing : xwb_clock_crossing
port map (
slave_clk_i => clk_sys_i,
slave_rst_n_i => rst_sys_n_i,
slave_i => slave_i,
slave_o => slave_o,
master_clk_i => clk_tdc_i,
master_rst_n_i => rst_tdc_n_i,
master_i => tdc_slave_out,
master_o => tdc_slave_in);
U_WB_Slave : entity work.tdc_channel_wb
port map (
rst_n_i => rst_tdc_n_i,
clk_sys_i => clk_tdc_i,
slave_i => tdc_slave_in,
slave_o => tdc_slave_out,
int_o => open,
regs_i => regs_in,
regs_o => regs_out);
U_Sync_Calib_Sel : gc_sync_ffs
port map (
clk_i => clk_cal_i,
rst_n_i => rst_tdc_n_i,
data_i => regs_out.calr_cal_mode_o,
synced_o => calib_sel_d);
U_Sync_Calib_Reset : gc_sync_ffs
port map (
clk_i => clk_cal_i,
rst_n_i => '1',
data_i => rst_tdc_n_i,
synced_o => calib_rst_n);
-- register calibration select signal to avoid glitches
p_reg_calib_regs : process(clk_cal_i)
begin
if rising_edge(clk_cal_i) then
if calib_rst_n = '0' then
calib_step_d <= (others => '0');
calib_offset_d <= (others => '0');
else
calib_step_d <= unsigned(regs_out.calr_cal_step_o);
calib_offset_d <= unsigned(regs_out.calr_cal_offset_o);
end if;
end if;
end process;
p_calib_pattern_gen : process(clk_cal_i)
begin
if rising_edge(clk_cal_i) then
if calib_rst_n = '0' then
calib_cur_sample <= (others => '0');
calib_next_sample <= (others => '0');
calib_p <= '0';
elsif calib_cur_sample = resize(calib_next_sample + calib_offset_d, calib_cur_sample'Length) and calib_step_d /= 0 then
calib_next_sample <= calib_next_sample + calib_step_d;
calib_cur_sample <= calib_cur_sample + 1;
calib_p <= '1';
elsif calib_step_d /= 0 then
calib_cur_sample <= calib_cur_sample + 1;
calib_p <= '0';
end if;
end if;
end process;
muxed_signal <= calib_p when calib_sel_d = '1' else signal_i;
tdc_inv_input_signal <= muxed_signal xor not ipolarity;
cmp_delayline : entity work.tdc_delayline
generic map(
g_WIDTH => g_CARRY4_COUNT
)
port map(
clk_i => clk_tdc_i,
reset_i => rst_tdc,
signal_i => tdc_inv_input_signal,
taps_o => taps
);
cmp_lbc : entity work.tdc_lbc
generic map(
g_N => g_RAW_COUNT,
g_NIN => g_CARRY4_COUNT*4,
g_IGNORE => 2
)
port map(
clk_i => clk_tdc_i,
reset_i => rst_tdc,
d_i => taps,
ipolarity_o => ipolarity,
polarity_o => polarity,
count_o => raw
);
process(clk_tdc_i)
begin
if rising_edge(clk_tdc_i) then
if rst_tdc = '1' then
prev_taps_zero <= '1';
taps_latched_ready <= '0';
else
if regs_out.raw_csr_ack_o = '1' then
taps_latched_ready <= '0';
end if;
if unsigned(taps) = 0 then
prev_taps_zero <= '1';
elsif prev_taps_zero = '1' and unsigned(taps) /= 0 and taps_latched_ready = '0' then
taps_latched <= taps;
taps_latched_ready <= '1';
prev_taps_zero <= '0';
end if;
end if;
end if;
end process;
regs_in.raw_csr_valid_i <= taps_latched_ready;
process(clk_tdc_i)
variable idx : integer;
variable idx_h, idx_l : integer;
begin
if rising_edge(clk_sys_i) then
idx := to_integer(unsigned(regs_out.raw_bank_o));
idx_l := idx * 32;
idx_h := f_clamp(idx_l + 31, g_CARRY4_COUNT*4-1);
regs_in.raw_taps_i <= std_logic_vector(resize(unsigned(taps_latched( idx_h downto idx_l)), 32));
end if;
end process;
--cmp_lut : generic_dpram
-- generic map(
-- g_data_width => g_FP_COUNT,
-- g_size => 2**g_RAW_COUNT,
-- g_with_byte_enable => false,
-- g_addr_conflict_resolution => "read_first",
-- g_init_file => "",
-- g_dual_clock => false
-- )
-- port map(
-- clka_i => clk_i,
-- clkb_i => '0',
-- wea_i => '0',
-- bwea_i => (others => '0'),
-- aa_i => raw,
-- da_i => (others => '0'),
-- qa_o => lut_rvalue,
-- web_i => lut_we_i,
-- bweb_i => (others => '0'),
-- ab_i => lut_a_i,
-- db_i => lut_d_i,
-- qb_o => lut_d_o
-- );
cmp_ringosc : entity work.tdc_ringosc
generic map(
g_LENGTH => g_RO_LENGTH
)
port map(
en_i => ro_en,
clk_o => ro_clk
);
ro_en <= regs_out.csr_ro_en_o and rst_tdc_n_i;
detect_d1 <= polarity_d1 xor polarity_d2;
process(clk_tdc_i)
begin
if rising_edge(clk_tdc_i) then
if rst_tdc = '1' then
detect <= '0';
polarity_d1 <= '1';
polarity_d2 <= '1';
raw_d1 <= (others => '0');
raw_d2 <= (others => '0');
else
detect <= detect_d1;
polarity_d1 <= polarity;
raw_d1 <= raw;
if detect_d1 = '1' then
polarity_d2 <= polarity_d1;
raw_d2 <= raw_d1;
end if;
end if;
end if;
end process;
-- polarity_o <= polarity_d2;
-- raw_o <= raw_d2;
-- Combine coarse counter value and deskew.
--process(clk_i)
--begin
-- if rising_edge(clk_i) then
-- if reset_i = '1' then
-- fp_o <= (others => '0');
-- else
-- if detect_d1 = '1' then
-- fp_o <= std_logic_vector(
-- (resize(unsigned(coarse_i), g_FP_COUNT+g_COARSE_COUNT) sll g_FP_COUNT)
-- - unsigned(lut_rvalue)
-- + unsigned(deskew_i)
-- );
-- end if;
-- end if;
-- end if;
--end process;
regs_in.csr_valid_i <= '0';
regs_in.csr_rdy_i <= '0';
end architecture;
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for TDC
---------------------------------------------------------------------------------------
-- File : tdc_channel_wb.vhd
-- Author : auto-generated by wbgen2 from tdc_channel_wb.wb
-- Created : Tue Sep 11 22:15:48 2018
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE tdc_channel_wb.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.tdc_wbgen2_pkg.all;
entity tdc_channel_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_tdc_in_registers;
regs_o : out t_tdc_out_registers
);
end tdc_channel_wb;
architecture syn of tdc_channel_wb is
signal tdc_csr_rst_dly0 : std_logic ;
signal tdc_csr_rst_int : std_logic ;
signal tdc_csr_ro_en_int : std_logic ;
signal tdc_calr_cal_mode_int : std_logic ;
signal tdc_calr_cal_step_int : std_logic_vector(14 downto 0);
signal tdc_calr_cal_offset_int : std_logic_vector(14 downto 0);
signal tdc_raw_csr_ack_dly0 : std_logic ;
signal tdc_raw_csr_ack_int : std_logic ;
signal tdc_raw_bank_int : std_logic_vector(7 downto 0);
signal tdc_luta_int : std_logic_vector(15 downto 0);
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 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";
tdc_csr_rst_int <= '0';
tdc_csr_ro_en_int <= '0';
tdc_calr_cal_mode_int <= '0';
tdc_calr_cal_step_int <= "000000000000000";
tdc_calr_cal_offset_int <= "000000000000000";
tdc_raw_csr_ack_int <= '0';
tdc_raw_bank_int <= "00000000";
tdc_luta_int <= "0000000000000000";
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
tdc_csr_rst_int <= '0';
tdc_raw_csr_ack_int <= '0';
ack_in_progress <= '0';
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
tdc_csr_rst_int <= wrdata_reg(0);
tdc_csr_ro_en_int <= wrdata_reg(3);
end if;
rddata_reg(0) <= '0';
rddata_reg(1) <= regs_i.csr_rdy_i;
rddata_reg(2) <= regs_i.csr_valid_i;
rddata_reg(3) <= tdc_csr_ro_en_int;
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
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(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 "0001" =>
if (slave_i.we = '1') then
tdc_calr_cal_mode_int <= wrdata_reg(0);
tdc_calr_cal_step_int <= wrdata_reg(15 downto 1);
tdc_calr_cal_offset_int <= wrdata_reg(30 downto 16);
end if;
rddata_reg(0) <= tdc_calr_cal_mode_int;
rddata_reg(15 downto 1) <= tdc_calr_cal_step_int;
rddata_reg(30 downto 16) <= tdc_calr_cal_offset_int;
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "0010" =>
if (slave_i.we = '1') then
tdc_raw_csr_ack_int <= wrdata_reg(1);
end if;
rddata_reg(0) <= regs_i.raw_csr_valid_i;
rddata_reg(1) <= '0';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
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(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 "0011" =>
if (slave_i.we = '1') then
tdc_raw_bank_int <= wrdata_reg(7 downto 0);
end if;
rddata_reg(7 downto 0) <= tdc_raw_bank_int;
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(0) <= '1';
ack_in_progress <= '1';
when "0100" =>
if (slave_i.we = '1') then
end if;
rddata_reg(31 downto 0) <= regs_i.raw_taps_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "0101" =>
if (slave_i.we = '1') then
tdc_luta_int <= wrdata_reg(15 downto 0);
end if;
rddata_reg(15 downto 0) <= tdc_luta_int;
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(0) <= '1';
ack_in_progress <= '1';
when "0110" =>
if (slave_i.we = '1') then
end if;
rddata_reg(31 downto 0) <= regs_i.lutd_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "0111" =>
if (slave_i.we = '1') then
end if;
rddata_reg(31 downto 0) <= regs_i.fcr_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "1000" =>
if (slave_i.we = '1') then
end if;
rddata_reg(31 downto 0) <= regs_i.fcsr_i;
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;
end if;
end if;
end if;
end process;
-- Drive the data output bus
slave_o.dat <= rddata_reg;
-- Reset
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
tdc_csr_rst_dly0 <= '0';
regs_o.csr_rst_o <= '0';
elsif rising_edge(clk_sys_i) then
tdc_csr_rst_dly0 <= tdc_csr_rst_int;
regs_o.csr_rst_o <= tdc_csr_rst_int and (not tdc_csr_rst_dly0);
end if;
end process;
-- Ready
-- TS valid
-- Enable ring oscillator
regs_o.csr_ro_en_o <= tdc_csr_ro_en_int;
-- Calibration mode select
regs_o.calr_cal_mode_o <= tdc_calr_cal_mode_int;
-- Calibration step select
regs_o.calr_cal_step_o <= tdc_calr_cal_step_int;
-- Calibration offset select
regs_o.calr_cal_offset_o <= tdc_calr_cal_offset_int;
-- TS valid
-- TS ack
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
tdc_raw_csr_ack_dly0 <= '0';
regs_o.raw_csr_ack_o <= '0';
elsif rising_edge(clk_sys_i) then
tdc_raw_csr_ack_dly0 <= tdc_raw_csr_ack_int;
regs_o.raw_csr_ack_o <= tdc_raw_csr_ack_int and (not tdc_raw_csr_ack_dly0);
end if;
end process;
-- raw bank select
regs_o.raw_bank_o <= tdc_raw_bank_int;
-- raw taps
-- Address
regs_o.luta_o <= tdc_luta_int;
-- Data
-- Result
-- Result
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';
-- ACK signal generation. Just pass the LSB of ACK counter.
slave_o.ack <= ack_sreg(0);
end syn;
-- -*- Mode: LUA; tab-width: 2 -*-
peripheral
{
name = "TDC";
description = "Time to digital converter (signle channel).";
hdl_entity = "tdc_channel_wb";
prefix = "tdc";
reg {
name = "Control and status";
description = "Control and status.";
prefix = "csr";
field {
name = "Reset";
prefix = "rst";
type = MONOSTABLE;
};
field {
name = "Ready";
prefix = "rdy";
type = BIT;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
field {
name = "TS valid";
prefix = "valid";
type = BIT;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
field {
name = "Enable ring oscillator";
prefix = "ro_en";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "Calibration control";
prefix = "calr";
field {
name = "Calibration mode select";
prefix = "cal_mode";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
field {
name = "Calibration step select";
prefix = "cal_step";
type = SLV;
size = 15;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
field {
name = "Calibration offset select";
prefix = "cal_offset";
type = SLV;
size = 15;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "TS raw CSR";
prefix = "raw_csr";
field {
name = "TS valid";
prefix = "valid";
type = BIT;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
field {
name = "TS ack";
prefix = "ack";
type = MONOSTABLE;
};
};
reg {
name = "TS raw taps bank select";
prefix = "raw_bank";
field {
name = "raw bank select";
type = SLV;
size = 8;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "TS raw taps";
prefix = "raw_taps";
field {
name = "raw taps";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "LUT read address";
description = "LUT address to read when debugging.";
prefix = "luta";
field {
name = "Address";
type = SLV;
size = 16;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "LUT read data";
description = "LUT data readback for debugging.";
prefix = "lutd";
field {
name = "Data";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "Frequency counter current value";
description = "Reports the latest measurement result of the frequency counter for debugging.";
prefix = "fcr";
field {
name = "Result";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "Frequency counter stored value";
description = "Reports the latest stored measurement result of the frequency counter for debugging.";
prefix = "fcsr";
field {
name = "Result";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
};
......@@ -109,7 +109,7 @@ end entity;
architecture rtl of tdc_channelbank is
begin
g_single: if g_CHANNEL_COUNT = 1 generate
cmp_channelbank: tdc_channelbank_single
cmp_channelbank: entity work.tdc_channelbank_single
generic map(
g_CARRY4_COUNT => g_CARRY4_COUNT,
g_RAW_COUNT => g_RAW_COUNT,
......@@ -160,7 +160,7 @@ begin
);
end generate;
g_multi: if g_CHANNEL_COUNT > 1 generate
cmp_channelbank: tdc_channelbank_multi
cmp_channelbank: entity work.tdc_channelbank_multi
generic map(
g_CHANNEL_COUNT => g_CHANNEL_COUNT,
g_CARRY4_COUNT => g_CARRY4_COUNT,
......
......@@ -133,7 +133,7 @@ begin
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
cmp_channel: entity work.tdc_channel
generic map(
g_CARRY4_COUNT => g_CARRY4_COUNT,
g_RAW_COUNT => g_RAW_COUNT,
......@@ -192,7 +192,7 @@ begin
his_full_a <= current_channel & his_a_i;
-- Frequency counter.
cmp_freqc: tdc_freqc
cmp_freqc: entity work.tdc_freqc
generic map(
g_COUNTER_WIDTH => g_FCOUNTER_WIDTH,
g_TIMER_WIDTH => g_FTIMER_WIDTH
......
......@@ -105,7 +105,7 @@ 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
cmp_channel: entity work.tdc_channel
generic map(
g_CARRY4_COUNT => g_CARRY4_COUNT,
g_RAW_COUNT => g_RAW_COUNT,
......@@ -162,7 +162,7 @@ begin
);
-- Frequency counter.
cmp_freqc: tdc_freqc
cmp_freqc: entity work.tdc_freqc
generic map(
g_COUNTER_WIDTH => g_FCOUNTER_WIDTH,
g_TIMER_WIDTH => g_FTIMER_WIDTH
......
......@@ -185,7 +185,7 @@ begin
end process;
-- divider
cmp_divider: tdc_divider
cmp_divider: entity work.tdc_divider
generic map(
g_WIDTH => g_FP_COUNT+g_FCOUNTER_WIDTH
)
......
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wishbone_pkg.all;
entity tdc_core is
generic (
g_CARRY4_COUNT : positive := 124;
g_RAW_COUNT : positive := 9;
g_FP_COUNT : positive := 13;
g_COARSE_COUNT : positive := 25;
g_RO_LENGTH : positive := 31);
port (
clk_sys_i : in std_logic;
rst_sys_n_i : in std_logic;
clk_tdc_i : in std_logic;
rst_tdc_n_i : in std_logic;
clk_cal_i : in std_logic;
coarse_i : in std_logic_vector(g_COARSE_COUNT-1 downto 0) := (others => '0');
signal_i : in std_logic;
slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out;
dbg_txd_o : out std_logic;
dbg_rxd_i : in std_logic := '1');
end entity tdc_core;
architecture rtl of tdc_core is
constant c_cnx_slave_ports : integer := 2;
constant c_cnx_master_ports : integer := 3;
constant c_master_host : integer := 0;
constant c_master_urv : integer := 1;
constant c_slave_csr : integer := 0;
constant c_slave_vuart : integer := 1;
constant c_slave_tdc : integer := 2;
signal cnx_master_in : t_wishbone_master_in_array(c_cnx_master_ports-1 downto 0);
signal cnx_master_out : t_wishbone_master_out_array(c_cnx_master_ports-1 downto 0);
signal cnx_slave_in : t_wishbone_slave_in_array(c_cnx_slave_ports-1 downto 0);
signal cnx_slave_out : t_wishbone_slave_out_array(c_cnx_slave_ports-1 downto 0);
constant c_cfg_base_addr : t_wishbone_address_array(c_cnx_master_ports-1 downto 0) :=
(c_slave_csr => x"00000000",
c_slave_vuart => x"00001000",
c_slave_tdc => x"00002000"
);
constant c_cfg_base_mask : t_wishbone_address_array(c_cnx_master_ports-1 downto 0) :=
(c_slave_csr => x"0000f000",
c_slave_vuart => x"0000f000",
c_slave_tdc => x"0000f000"
);
begin
slave_o <= cnx_slave_out(c_master_host);
cnx_slave_in(c_master_host) <= slave_i;
U_MCU : entity work.xwb_urv_mcs
generic map (
g_iram_size => 65536,
g_with_host_if => true
)
port map (
clk_sys_i => clk_sys_i,
rst_n_i => rst_sys_n_i,
host_wb_i => cnx_master_out(c_slave_csr),
host_wb_o => cnx_master_in(c_slave_csr),
dwb_o => cnx_slave_in(c_master_urv),
dwb_i => cnx_slave_out(c_master_urv));
U_Host_Intercon : xwb_crossbar
generic map (
g_num_masters => c_cnx_slave_ports,
g_num_slaves => c_cnx_master_ports,
g_registered => true,
g_address => c_cfg_base_addr,
g_mask => c_cfg_base_mask)
port map (
clk_sys_i => clk_sys_i,
rst_n_i => rst_sys_n_i,
slave_i => cnx_slave_in,
slave_o => cnx_slave_out,
master_i => cnx_master_in,
master_o => cnx_master_out);
U_CH1 : entity work.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_sys_i => clk_sys_i,
rst_sys_n_i => rst_sys_n_i,
clk_tdc_i => clk_tdc_i,
rst_tdc_n_i => rst_tdc_n_i,
clk_cal_i => clk_cal_i,
coarse_i => coarse_i,
signal_i => signal_i,
slave_i => cnx_master_out(c_slave_tdc),
slave_o => cnx_master_in(c_slave_tdc));
U_VUART : xwb_simple_uart
generic map (
g_with_virtual_uart => true,
g_with_physical_uart => true,
g_interface_mode => PIPELINED,
g_address_granularity => BYTE)
port map (
clk_sys_i => clk_sys_i,
rst_n_i => rst_sys_n_i,
slave_i => cnx_master_out(c_slave_vuart),
slave_o => cnx_master_in(c_slave_vuart),
uart_rxd_i => dbg_rxd_i,
uart_txd_o => dbg_txd_o);
end rtl;
......@@ -41,8 +41,8 @@
library ieee;
use ieee.std_logic_1164.all;
library unisim;
use unisim.vcomponents.all;
--library unisim;
--use unisim.vcomponents.all;
library work;
use work.tdc_package.all;
......@@ -96,6 +96,7 @@ begin
S => "1111"
);
end generate;
end generate;
-- double latch the output
......@@ -123,11 +124,13 @@ begin
end generate;
-- sort taps by increasing delays, according to static timing model
cmp_ordertaps: tdc_ordertaps
cmp_ordertaps: entity work.tdc_ordertaps
generic map(
g_WIDTH => g_WIDTH
)
port map(
port map(
clk_i => clk_i,
rst_i => reset_i,
unsorted_i => taps_rev,
sorted_o => taps_rev_sorted
);
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment