Commit 6ed2a256 authored by Dimitris Lampridis's avatar Dimitris Lampridis

[hdl] make pulse width filtering optional

parent 97684cd3
...@@ -150,12 +150,19 @@ use work.genram_pkg.all; ...@@ -150,12 +150,19 @@ use work.genram_pkg.all;
--================================================================================================= --=================================================================================================
entity fmc_tdc_core is entity fmc_tdc_core is
generic generic
(g_span : integer := 32; -- address span in bus interfaces (g_span : integer := 32; -- address span in bus interfaces
g_width : integer := 32; -- data width in bus interfaces g_width : integer := 32; -- data width in bus interfaces
g_simulation : boolean := false; g_simulation : boolean := false;
g_with_dma_readout : boolean := false; -- Enable filtering based on pulse width. This will have the following effects:
g_with_fifo_readout : boolean := false); -- this generic is set to TRUE -- * Suppress theforwarding of negative slope timestamps.
-- when instantiated in a test-bench -- * Delay the forwarding of timestamps until after the falling edge timestamp.
-- Once enabled, all pulses wider than 1 second or narrower than
-- g_pulse_width_filter_min will be dropped.
g_pulse_width_filter : boolean := true;
-- In 8ns ticks.
g_pulse_width_filter_min : natural := 12;
g_with_dma_readout : boolean := false;
g_with_fifo_readout : boolean := false);
port port
( (
clk_sys_i : in std_logic; clk_sys_i : in std_logic;
...@@ -536,6 +543,9 @@ begin ...@@ -536,6 +543,9 @@ begin
U_FilterAndConvert : entity work.timestamp_convert_filter U_FilterAndConvert : entity work.timestamp_convert_filter
generic map (
g_pulse_width_filter => g_pulse_width_filter,
g_pulse_width_filter_min => g_pulse_width_filter_min)
port map ( port map (
clk_tdc_i => clk_tdc_i, clk_tdc_i => clk_tdc_i,
rst_tdc_n_i => rst_tdc_n_i, rst_tdc_n_i => rst_tdc_n_i,
......
...@@ -110,6 +110,14 @@ entity fmc_tdc_mezzanine is ...@@ -110,6 +110,14 @@ entity fmc_tdc_mezzanine is
g_span : integer := 32; g_span : integer := 32;
g_width : integer := 32; g_width : integer := 32;
g_simulation : boolean := false; g_simulation : boolean := false;
-- Enable filtering based on pulse width. This will have the following effects:
-- * Suppress theforwarding of negative slope timestamps.
-- * Delay the forwarding of timestamps until after the falling edge timestamp.
-- Once enabled, all pulses wider than 1 second or narrower than
-- g_pulse_width_filter_min will be dropped.
g_pulse_width_filter : boolean := true;
-- In 8ns ticks.
g_pulse_width_filter_min : natural := 12;
g_use_dma_readout : boolean := true; g_use_dma_readout : boolean := true;
g_use_fifo_readout : boolean := true; g_use_fifo_readout : boolean := true;
g_use_fake_timestamps_for_sim : boolean := false); g_use_fake_timestamps_for_sim : boolean := false);
...@@ -326,11 +334,13 @@ begin ...@@ -326,11 +334,13 @@ begin
--------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------
cmp_tdc_core : entity work.fmc_tdc_core cmp_tdc_core : entity work.fmc_tdc_core
generic map generic map
(g_span => g_span, (g_span => g_span,
g_width => g_width, g_width => g_width,
g_simulation => g_simulation, g_simulation => g_simulation,
g_with_dma_readout => g_use_dma_readout, g_pulse_width_filter => g_pulse_width_filter,
g_with_fifo_readout => g_use_fifo_readout) g_pulse_width_filter_min => g_pulse_width_filter_min,
g_with_dma_readout => g_use_dma_readout,
g_with_fifo_readout => g_use_fifo_readout)
port map port map
( -- clks, rst ( -- clks, rst
clk_tdc_i => clk_tdc_i, clk_tdc_i => clk_tdc_i,
......
...@@ -132,6 +132,14 @@ entity fmc_tdc_wrapper is ...@@ -132,6 +132,14 @@ entity fmc_tdc_wrapper is
g_simulation : boolean := false; g_simulation : boolean := false;
-- implement direct TDC timestamp readout FIFO, used in the WR Node projects -- implement direct TDC timestamp readout FIFO, used in the WR Node projects
g_with_direct_readout : boolean := false; g_with_direct_readout : boolean := false;
-- Enable filtering based on pulse width. This will have the following effects:
-- * Suppress theforwarding of negative slope timestamps.
-- * Delay the forwarding of timestamps until after the falling edge timestamp.
-- Once enabled, all pulses wider than 1 second or narrower than
-- g_pulse_width_filter_min will be dropped.
g_pulse_width_filter : boolean := true;
-- In 8ns ticks.
g_pulse_width_filter_min : natural := 12;
g_use_dma_readout : boolean := false; g_use_dma_readout : boolean := false;
g_use_fifo_readout : boolean := false; g_use_fifo_readout : boolean := false;
g_use_fake_timestamps_for_sim : boolean := false g_use_fake_timestamps_for_sim : boolean := false
...@@ -404,6 +412,8 @@ begin ...@@ -404,6 +412,8 @@ begin
(g_span => 32, (g_span => 32,
g_width => 32, g_width => 32,
g_simulation => g_simulation, g_simulation => g_simulation,
g_pulse_width_filter => g_pulse_width_filter,
g_pulse_width_filter_min => g_pulse_width_filter_min,
g_use_fifo_readout => g_use_fifo_readout, g_use_fifo_readout => g_use_fifo_readout,
g_use_dma_readout => g_use_dma_readout, g_use_dma_readout => g_use_dma_readout,
g_use_fake_timestamps_for_sim => g_use_fake_timestamps_for_sim) g_use_fake_timestamps_for_sim => g_use_fake_timestamps_for_sim)
......
...@@ -8,6 +8,15 @@ use work.gencores_pkg.all; ...@@ -8,6 +8,15 @@ use work.gencores_pkg.all;
use work.genram_pkg.all; use work.genram_pkg.all;
entity timestamp_convert_filter is entity timestamp_convert_filter is
generic (
-- Enable filtering based on pulse width. This will have the following effects:
-- * Suppress theforwarding of negative slope timestamps.
-- * Delay the forwarding of timestamps until after the falling edge timestamp.
-- Once enabled, all pulses wider than 1 second or narrower than
-- g_PULSE_WIDTH_FILTER_MIN will be dropped.
g_PULSE_WIDTH_FILTER : boolean := TRUE;
-- In 8ns ticks.
g_PULSE_WIDTH_FILTER_MIN : natural := 12);
port ( port (
clk_tdc_i : in std_logic; clk_tdc_i : in std_logic;
rst_tdc_n_i : in std_logic; rst_tdc_n_i : in std_logic;
...@@ -37,13 +46,10 @@ end timestamp_convert_filter; ...@@ -37,13 +46,10 @@ end timestamp_convert_filter;
architecture rtl of timestamp_convert_filter is architecture rtl of timestamp_convert_filter is
constant c_MIN_PULSE_WIDTH_TICKS : integer := 12; -- 12 * 8 ns = 96 ns
constant c_FINE_SF : unsigned(17 downto 0) := to_unsigned(84934, 18); constant c_FINE_SF : unsigned(17 downto 0) := to_unsigned(84934, 18);
constant c_FINE_SHIFT : integer := 11; constant c_FINE_SHIFT : integer := 11;
type t_channel_state is record type t_channel_state is record
expected_edge : std_logic;
last_ts : t_tdc_timestamp; last_ts : t_tdc_timestamp;
last_valid : std_logic; last_valid : std_logic;
seq : unsigned(31 downto 0); seq : unsigned(31 downto 0);
...@@ -211,65 +217,84 @@ architecture rtl of timestamp_convert_filter is ...@@ -211,65 +217,84 @@ architecture rtl of timestamp_convert_filter is
gen_channels : for i in 0 to 4 generate gen_channels : for i in 0 to 4 generate
p_fsm : process(clk_sys_i) gen_with_pwidth_filter : if g_PULSE_WIDTH_FILTER generate
begin p_fsm : process(clk_sys_i)
if rising_edge(clk_sys_i) then begin
if rst_sys_n_i = '0' or enable_i(i) = '0' then if rising_edge(clk_sys_i) then
ts_valid_preoffset(i) <= '0'; if rst_sys_n_i = '0' or enable_i(i) = '0' then
channels(i).expected_edge <= '1'; ts_valid_preoffset(i) <= '0';
channels(i).s1_valid <= '0'; channels(i).s1_valid <= '0';
channels(i).s2_valid <= '0'; channels(i).s2_valid <= '0';
channels(i).last_valid <= '0'; channels(i).last_valid <= '0';
else else
channels(i).s1_valid <= '0'; channels(i).s1_valid <= '0';
if s3_valid = '1' and unsigned(s3_channel) = i then if s3_valid = '1' and unsigned(s3_channel) = i then
if (s3_ts.slope = '1') then -- rising edge if (s3_ts.slope = '1') then -- rising edge
channels(i).last_ts <= s3_ts; channels(i).last_ts <= s3_ts;
channels(i).last_valid <= '1'; channels(i).last_valid <= '1';
channels(i).s1_valid <= '0'; channels(i).s1_valid <= '0';
else else
channels(i).last_valid <= '0'; channels(i).last_valid <= '0';
channels(i).s1_valid <= '1'; channels(i).s1_valid <= '1';
end if;
channels(i).s1_delta_coarse <= unsigned(s3_ts.coarse) - unsigned(channels(i).last_ts.coarse);
channels(i).s1_delta_tai <= unsigned(s3_ts.tai) - unsigned(channels(i).last_ts.tai);
end if; end if;
channels(i).s1_delta_coarse <= unsigned(s3_ts.coarse) - unsigned(channels(i).last_ts.coarse);
channels(i).s1_delta_tai <= unsigned(s3_ts.tai) - unsigned(channels(i).last_ts.tai);
end if;
if channels(i).s1_delta_coarse(31) = '1' then
channels(i).s2_delta_coarse <= channels(i).s1_delta_coarse + to_unsigned(125000000, 32);
channels(i).s2_delta_tai <= channels(i).s1_delta_tai - 1;
else
channels(i).s2_delta_coarse <= channels(i).s1_delta_coarse;
channels(i).s2_delta_tai <= channels(i).s1_delta_tai;
end if;
if channels(i).s1_delta_coarse(31) = '1' then channels(i).s2_valid <= channels(i).s1_valid;
channels(i).s2_delta_coarse <= channels(i).s1_delta_coarse + to_unsigned(125000000, 32);
channels(i).s2_delta_tai <= channels(i).s1_delta_tai - 1;
else
channels(i).s2_delta_coarse <= channels(i).s1_delta_coarse;
channels(i).s2_delta_tai <= channels(i).s1_delta_tai;
end if;
channels(i).s2_valid <= channels(i).s1_valid; if channels(i).s2_valid = '1' then
if channels(i).s2_delta_tai = 0 and channels(i).s2_delta_coarse >= 12 then
if channels(i).s2_valid = '1' then ts_preoffset(i).tai <= channels(i).last_ts.tai;
if channels(i).s2_delta_tai = 0 and channels(i).s2_delta_coarse >= 12 then ts_preoffset(i).coarse <= channels(i).last_ts.coarse;
ts_preoffset(i).frac <= channels(i).last_ts.frac;
ts_preoffset(i).channel <= channels(i).last_ts.channel;
ts_preoffset(i).slope <= channels(i).last_ts.slope;
ts_preoffset(i).meta <= channels(i).last_ts.meta;
ts_preoffset(i).tai <= channels(i).last_ts.tai; ts_valid_preoffset(i) <= '1';
ts_preoffset(i).coarse <= channels(i).last_ts.coarse; else
ts_preoffset(i).frac <= channels(i).last_ts.frac; ts_valid_preoffset(i) <= '0';
ts_preoffset(i).channel <= channels(i).last_ts.channel; end if;
ts_preoffset(i).slope <= channels(i).last_ts.slope; else
ts_preoffset(i).meta <= channels(i).last_ts.meta; ts_valid_preoffset(i) <= '0';
end if;
end if;
end if;
end process p_fsm;
end generate gen_with_pwidth_filter;
gen_without_pwidth_filter : if not g_PULSE_WIDTH_FILTER generate
p_fsm : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_sys_n_i = '0' or enable_i(i) = '0' then
ts_valid_preoffset(i) <= '0';
else
if s3_valid = '1' and unsigned(s3_channel) = i then
ts_valid_preoffset(i) <= '1'; ts_valid_preoffset(i) <= '1';
ts_preoffset(i) <= s3_ts;
else else
ts_valid_preoffset(i) <= '0'; ts_valid_preoffset(i) <= '0';
end if; end if;
else
ts_valid_preoffset(i) <= '0';
end if; end if;
end if; end if;
end if; end process p_fsm;
end process; end generate gen_without_pwidth_filter;
U_Offset_Adder : entity work.tdc_ts_addsub U_Offset_Adder : entity work.tdc_ts_addsub
port map ( port map (
......
Markdown is supported
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