Commit 6896864b authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

working on the plan B, WIP

parent c9d9b7d6
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.
This diff is collapsed.
modules = { "local" : [ "../core" ] }
files = [ "tdc_hostif_package.vhd", "tdc_hostif.vhd", "tdc_wb.vhd" ]
This diff is collapsed.
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
......@@ -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,
......
This diff is collapsed.
This diff is collapsed.
-- -*- 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
);
......
......@@ -92,14 +92,14 @@ begin
end process;
-- Synchronisers.
cmp_sync_start: tdc_psync
cmp_sync_start: entity work.tdc_psync
port map(
clk_src_i => clk_i,
p_i => start,
clk_dst_i => clk_m_i,
p_o => m_start
);
cmp_sync_stop: tdc_psync
cmp_sync_stop: entity work.tdc_psync
port map(
clk_src_i => clk_i,
p_i => stop,
......@@ -107,7 +107,7 @@ begin
p_o => m_stop
);
cmp_sync_stop_ack: tdc_psync
cmp_sync_stop_ack: entity work.tdc_psync
port map(
clk_src_i => clk_m_i,
p_i => m_stop,
......
This diff is collapsed.
library ieee;
use ieee.std_logic_1164.all;