Commit a590a053 authored by David Cussans's avatar David Cussans

Adding bottom 3 bits of 40MHz time stamp to fine-grain timestamp

parent a59dc76e
...@@ -61,6 +61,7 @@ use work.ipbus_reg_types.all; ...@@ -61,6 +61,7 @@ use work.ipbus_reg_types.all;
ENTITY eventFormatter IS ENTITY eventFormatter IS
GENERIC( GENERIC(
g_EVENT_DATA_WIDTH : positive := 64; g_EVENT_DATA_WIDTH : positive := 64;
g_COARSE_TIMESTAMP_WIDTH : positive := 48; -- ! Number of bits in 40MHz timestamp
g_IPBUS_WIDTH : positive := 32; g_IPBUS_WIDTH : positive := 32;
g_COUNTER_TRIG_WIDTH : positive := 32; g_COUNTER_TRIG_WIDTH : positive := 32;
g_COUNTER_WIDTH : positive := 12; g_COUNTER_WIDTH : positive := 12;
...@@ -92,6 +93,7 @@ ENTITY eventFormatter IS ...@@ -92,6 +93,7 @@ ENTITY eventFormatter IS
ipbus_o : OUT ipb_rbus; ipbus_o : OUT ipb_rbus;
data_strobe_o : OUT std_logic; --! goes high when data ready to load into event buffer data_strobe_o : OUT std_logic; --! goes high when data ready to load into event buffer
event_data_o : OUT std_logic_vector (g_EVENT_DATA_WIDTH-1 DOWNTO 0); event_data_o : OUT std_logic_vector (g_EVENT_DATA_WIDTH-1 DOWNTO 0);
coarse_timestamp_o : OUT std_logic_vector (g_COUNTER_TRIG_WIDTH-1 DOWNTO 0); --! Global timestamp. Clocked on clk_4x_logic, but only increments with logic_strobe
reset_timestamp_i : IN std_logic; --! Taking high causes timestamp to be reset. Combined with internal timestmap reset and written to reset_timestamp_o reset_timestamp_i : IN std_logic; --! Taking high causes timestamp to be reset. Combined with internal timestmap reset and written to reset_timestamp_o
reset_timestamp_o : OUT std_logic --! Goes high for one clock cycle of clk_4x_logic when timestamp reset reset_timestamp_o : OUT std_logic --! Goes high for one clock cycle of clk_4x_logic when timestamp reset
); );
...@@ -134,8 +136,7 @@ ARCHITECTURE rtl OF eventFormatter IS ...@@ -134,8 +136,7 @@ ARCHITECTURE rtl OF eventFormatter IS
signal s_data_o : std_logic_vector(g_EVENT_DATA_WIDTH-1 DOWNTO 0); -- Multiplexed data from FIFOs signal s_data_o : std_logic_vector(g_EVENT_DATA_WIDTH-1 DOWNTO 0); -- Multiplexed data from FIFOs
constant c_COARSE_TIMESTAMP_WIDTH : positive := 48; -- ! Number of bits in 40MHz timestamp signal s_coarse_timestamp : std_logic_vector(g_COARSE_TIMESTAMP_WIDTH-1 downto 0) := (others => '0'); -- 40MHz timestamp.
signal s_coarse_timestamp : std_logic_vector(c_COARSE_TIMESTAMP_WIDTH-1 downto 0) := (others => '0'); -- 40MHz timestamp.
signal s_coarse_timestamp_ipbus : ipb_reg_v(1 downto 0) := ( others => (others => '0')); --! 40MHz timestamp on IPB clock domain. signal s_coarse_timestamp_ipbus : ipb_reg_v(1 downto 0) := ( others => (others => '0')); --! 40MHz timestamp on IPB clock domain.
-- signal s_event_number : unsigned(g_IPBUS_WIDTH-1 downto 0) := (others => '0'); -- increment after each post-veto trigger. -- signal s_event_number : unsigned(g_IPBUS_WIDTH-1 downto 0) := (others => '0'); -- increment after each post-veto trigger.
...@@ -327,8 +328,8 @@ BEGIN ...@@ -327,8 +328,8 @@ BEGIN
s_word0_p1 <= s_evttype & s_var & s_coarse_timestamp; s_word0_p1 <= s_evttype & s_var & s_coarse_timestamp;
s_word1 <= "000" & trigger_times_d1(0) & "000" & trigger_times_d1(1) & s_word1 <= trigger_times_d1(0) & trigger_times_d1(1) &
"000" & trigger_times_d1(2) & "000" & trigger_times_d1(3) & trigger_times_d1(2) & trigger_times_d1(3) &
trigger_cnt_i; trigger_cnt_i;
...@@ -375,7 +376,8 @@ BEGIN ...@@ -375,7 +376,8 @@ BEGIN
enable_i => logic_strobe_i, enable_i => logic_strobe_i,
result_o => s_coarse_timestamp); result_o => s_coarse_timestamp);
coarse_timestamp_o <= s_coarse_timestamp;
-- Generate data in format decided at DESY. Put out two strobes for the -- Generate data in format decided at DESY. Put out two strobes for the
-- two 64 bit words. -- two 64 bit words.
-- get trigger inputs to also generate a global time-stamp ?? -- get trigger inputs to also generate a global time-stamp ??
......
...@@ -13,11 +13,13 @@ LIBRARY ieee; ...@@ -13,11 +13,13 @@ LIBRARY ieee;
USE ieee.std_logic_1164.all; USE ieee.std_logic_1164.all;
PACKAGE fmcTLU IS PACKAGE fmcTLU IS
constant c_NUM_TIME_BITS : natural := 5; constant c_NUM_TIME_BITS : natural := 8;
constant c_NUM_TRIG_INPUTS : natural := 4; constant c_NUM_TRIG_INPUTS : natural := 4;
constant c_EVENT_DATA_WIDTH : natural := 32; constant c_EVENT_DATA_WIDTH : natural := 32;
constant c_DATA_WIDTH : natural := 32; constant c_DATA_WIDTH : natural := 32;
constant c_COARSE_TIMESTAMP_WIDTH : natural := 48;
constant c_TRIGIN_NUM_COARSE_TS_BITS : natural := 3;
subtype t_triggerTime is std_logic_vector(c_NUM_TIME_BITS-1 downto 0); subtype t_triggerTime is std_logic_vector(c_NUM_TIME_BITS-1 downto 0);
--type t_triggerTimeArray is array(natural range <>) of t_triggerTime; --type t_triggerTimeArray is array(natural range <>) of t_triggerTime;
type t_triggerTimeArray is array(natural range <>) of std_logic_vector(c_NUM_TIME_BITS-1 downto 0) ; type t_triggerTimeArray is array(natural range <>) of std_logic_vector(c_NUM_TIME_BITS-1 downto 0) ;
......
...@@ -82,7 +82,8 @@ use unisim.vcomponents.all; ...@@ -82,7 +82,8 @@ use unisim.vcomponents.all;
ENTITY triggerInputs_newTLU IS ENTITY triggerInputs_newTLU IS
GENERIC( GENERIC(
g_NUM_INPUTS : natural := 1;--1 g_NUM_INPUTS : natural := 1;--1
g_NUM_COARSE_TS_BITS : natural := 3; --! Number of coarse ( clk_1x_logic normally 40MHz ) timestamp bits to add to MSB of trigger times.
g_IPBUS_WIDTH : positive := 32 g_IPBUS_WIDTH : positive := 32
); );
PORT( PORT(
...@@ -94,6 +95,7 @@ ENTITY triggerInputs_newTLU IS ...@@ -94,6 +95,7 @@ ENTITY triggerInputs_newTLU IS
threshold_discr_p_i : IN std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0); --! inputs from threshold comparators threshold_discr_p_i : IN std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0); --! inputs from threshold comparators
threshold_discr_n_i : IN std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0); --! inputs from threshold comparators threshold_discr_n_i : IN std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0); --! inputs from threshold comparators
reset_i : IN std_logic; reset_i : IN std_logic;
coarse_timestamp_i : in std_logic_vector (g_NUM_COARSE_TS_BITS-1 DOWNTO 0); --! Global timestamp. Clocked on clk_4x_logic, but only increments with logic_strobe
trigger_times_o : OUT t_triggerTimeArray (g_NUM_INPUTS-1 DOWNTO 0); --! trigger arrival time ( w.r.t. logic_strobe) trigger_times_o : OUT t_triggerTimeArray (g_NUM_INPUTS-1 DOWNTO 0); --! trigger arrival time ( w.r.t. logic_strobe)
trigger_o : OUT std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0); --! Goes high on leading edge of trigger, in sync with clk_4x_logic_i trigger_o : OUT std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0); --! Goes high on leading edge of trigger, in sync with clk_4x_logic_i
--trigger_debug_o : OUT std_logic_vector ( ((2*g_NUM_INPUTS)-1) DOWNTO 0); --! Copy of input trigger level. High bits CFD, Low threshold --trigger_debug_o : OUT std_logic_vector ( ((2*g_NUM_INPUTS)-1) DOWNTO 0); --! Copy of input trigger level. High bits CFD, Low threshold
...@@ -199,7 +201,11 @@ BEGIN ...@@ -199,7 +201,11 @@ BEGIN
--BEGIN FOR LOOP --BEGIN FOR LOOP
-- Instantiate one for each trigger input of the TLU -- Instantiate one for each trigger input of the TLU
trigger_input_loop: for triggerInput in 0 to (g_NUM_INPUTS-1) generate trigger_input_loop: for triggerInput in 0 to (g_NUM_INPUTS-1) generate
signal s_edge_rising_time_short : std_logic_vector( (c_NUM_TIME_BITS-c_TRIGIN_NUM_COARSE_TS_BITS)-1 downto 0);
signal s_edge_falling_time_short : std_logic_vector( (c_NUM_TIME_BITS-c_TRIGIN_NUM_COARSE_TS_BITS)-1 downto 0);
begin
-- Differential buffer. Receives differential trigger input and produces a buffered differential signal. -- Differential buffer. Receives differential trigger input and produces a buffered differential signal.
IBUFDS_DIFF_OUT_inst : IBUFDS_DIFF_OUT IBUFDS_DIFF_OUT_inst : IBUFDS_DIFF_OUT
generic map ( generic map (
...@@ -238,25 +244,13 @@ BEGIN ...@@ -238,25 +244,13 @@ BEGIN
clk_4x_logic_i => clk_4x_logic, clk_4x_logic_i => clk_4x_logic,
strobe_4x_logic_i => strobe_4x_logic_i, strobe_4x_logic_i => strobe_4x_logic_i,
deserialized_data_i => s_deserialized_threshold_data_l(triggerInput), deserialized_data_i => s_deserialized_threshold_data_l(triggerInput),
first_rising_edge_time_o => s_edge_rising_times(triggerInput), first_rising_edge_time_o => s_edge_rising_time_short,
last_falling_edge_time_o => s_edge_falling_times(triggerInput), last_falling_edge_time_o => s_edge_falling_time_short,
rising_edge_o => s_edge_rising(triggerInput), rising_edge_o => s_edge_rising(triggerInput),
falling_edge_o => s_edge_falling(triggerInput), falling_edge_o => s_edge_falling(triggerInput),
multiple_edges_o => open multiple_edges_o => open
); );
-- The leading edge may be a high-->low or a low-->high transition (
-- depending on polarity of input signal. ). For now assume that leading
-- edge is low-->high and connect trigger times and trigger output accordingly.
-- In the future have this selectable.
edge_rising_times_o(triggerInput) <= s_edge_rising_times(triggerInput);
edge_falling_times_o(triggerInput) <= s_edge_falling_times(triggerInput);
edge_rising_o(triggerInput) <= s_edge_rising(triggerInput);
edge_falling_o(triggerInput) <= s_edge_falling(triggerInput);
trigger_times_o(triggerInput) <= s_edge_rising_times(triggerInput);
trigger_o(triggerInput) <= s_edge_rising(triggerInput);
p_register_delayed_bits : process ( clk_4x_logic ) p_register_delayed_bits : process ( clk_4x_logic )
begin begin
if rising_edge(clk_4x_logic) then if rising_edge(clk_4x_logic) then
...@@ -269,7 +263,37 @@ BEGIN ...@@ -269,7 +263,37 @@ BEGIN
--s_status_to_ipbus(0)(24+triggerInput) <= s_CFD_previous_late_bit(triggerInput); --s_status_to_ipbus(0)(24+triggerInput) <= s_CFD_previous_late_bit(triggerInput);
end if ; end if ;
end process; end process;
s_edge_rising_times(triggerInput) <= coarse_timestamp_i & s_edge_rising_time_short;
s_edge_falling_times(triggerInput) <= coarse_timestamp_i & s_edge_falling_time_short;
-- purpose: registers output of arrivalTimeLUT and performs optional edge
proc_registerLUT_output : process (clk_4x_logic) is
begin -- process proc_registerLUT_output
if rising_edge(clk_4x_logic) then
-- The leading edge may be a high-->low or a low-->high transition (
-- depending on polarity of input signal. ). For now assume that leading
-- edge is low-->high and connect trigger times and trigger output accordingly.
-- In the future have this selectable.
edge_rising_o(triggerInput) <= s_edge_rising(triggerInput);
if (s_edge_rising(triggerInput) = '1') then
trigger_times_o(triggerInput) <= s_edge_rising_times(triggerInput);
edge_rising_times_o(triggerInput) <= s_edge_rising_times(triggerInput);
end if;
edge_falling_o(triggerInput) <= s_edge_falling(triggerInput);
if (s_edge_falling(triggerInput) = '1') then
edge_falling_times_o(triggerInput) <= s_edge_falling_times(triggerInput);
end if;
trigger_o(triggerInput) <= s_edge_rising(triggerInput);
end if;
end process proc_registerLUT_output;
--! Instantiate counter for output triggers. --! Instantiate counter for output triggers.
--! Input I is connected to address I+1 --! Input I is connected to address I+1
cmp_inputTriggerCounter : entity work.counterWithReset cmp_inputTriggerCounter : entity work.counterWithReset
......
...@@ -20,6 +20,7 @@ architecture bench of triggerInputs_newTLU_tb is ...@@ -20,6 +20,7 @@ architecture bench of triggerInputs_newTLU_tb is
component triggerInputs_newTLU component triggerInputs_newTLU
generic( generic(
g_NUM_INPUTS : natural := g_NUM_INPUTS; g_NUM_INPUTS : natural := g_NUM_INPUTS;
g_NUM_COARSE_TS_BITS : natural := 3; --! Number of coarse ( clk_1x_logic normally 40MHz ) timestamp bits to add to MSB of trigger times.
g_IPBUS_WIDTH : positive := g_IPBUS_WIDTH g_IPBUS_WIDTH : positive := g_IPBUS_WIDTH
); );
port( port(
...@@ -29,6 +30,7 @@ architecture bench of triggerInputs_newTLU_tb is ...@@ -29,6 +30,7 @@ architecture bench of triggerInputs_newTLU_tb is
threshold_discr_p_i : in std_logic_vector (g_NUM_INPUTS-1 downto 0); threshold_discr_p_i : in std_logic_vector (g_NUM_INPUTS-1 downto 0);
threshold_discr_n_i : in std_logic_vector (g_NUM_INPUTS-1 downto 0); threshold_discr_n_i : in std_logic_vector (g_NUM_INPUTS-1 downto 0);
reset_i : in std_logic; reset_i : in std_logic;
coarse_timestamp_i : in std_logic_vector (g_NUM_COARSE_TS_BITS-1 DOWNTO 0); --! Global timestamp. Clocked on clk_4x_logic, but only increments with logic_strobe
trigger_times_o : out t_triggerTimeArray (g_NUM_INPUTS-1 downto 0); trigger_times_o : out t_triggerTimeArray (g_NUM_INPUTS-1 downto 0);
trigger_o : out std_logic_vector (g_NUM_INPUTS-1 downto 0); trigger_o : out std_logic_vector (g_NUM_INPUTS-1 downto 0);
edge_rising_times_o : out t_triggerTimeArray (g_NUM_INPUTS-1 downto 0); edge_rising_times_o : out t_triggerTimeArray (g_NUM_INPUTS-1 downto 0);
...@@ -64,6 +66,7 @@ architecture bench of triggerInputs_newTLU_tb is ...@@ -64,6 +66,7 @@ architecture bench of triggerInputs_newTLU_tb is
signal clk_8x_logic_i : std_logic; signal clk_8x_logic_i : std_logic;
signal clk_logic : std_logic; signal clk_logic : std_logic;
signal strobe_8x_logic_i : std_logic; signal strobe_8x_logic_i : std_logic;
signal s_coarse_timestamp : std_logic_vector(c_TRIGIN_NUM_COARSE_TS_BITS-1 downto 0) := ( others => '0' ); -- counts on each strobe_4x_logic pulse
-- constant C_NUM_STROBE_TAPS : positive := 2; --! Adjust to shift strobes relative to 40MHz clock edge -- constant C_NUM_STROBE_TAPS : positive := 2; --! Adjust to shift strobes relative to 40MHz clock edge
-- signal s_clk40_delayed_160 : std_logic_vector(C_NUM_STROBE_TAPS downto 0); --! Shift register used to generate clock_4x strobe. Adjust length for correct alignment with incoming clock -- signal s_clk40_delayed_160 : std_logic_vector(C_NUM_STROBE_TAPS downto 0); --! Shift register used to generate clock_4x strobe. Adjust length for correct alignment with incoming clock
-- signal s_clk40_delayed_320 : std_logic_vector((2*C_NUM_STROBE_TAPS)+1 downto 0); --! Shift register used to generate clock_8x strobe. Adjust length for correct alignment with incoming clock -- signal s_clk40_delayed_320 : std_logic_vector((2*C_NUM_STROBE_TAPS)+1 downto 0); --! Shift register used to generate clock_8x strobe. Adjust length for correct alignment with incoming clock
...@@ -97,6 +100,7 @@ begin ...@@ -97,6 +100,7 @@ begin
threshold_discr_p_i => threshold_discr_p_i, threshold_discr_p_i => threshold_discr_p_i,
threshold_discr_n_i => threshold_discr_n_i, threshold_discr_n_i => threshold_discr_n_i,
reset_i => s_logic_reset, reset_i => s_logic_reset,
coarse_timestamp_i => s_coarse_timestamp,
trigger_times_o => trigger_times_o, trigger_times_o => trigger_times_o,
trigger_o => trigger_o, trigger_o => trigger_o,
edge_rising_times_o => edge_rising_times_o, edge_rising_times_o => edge_rising_times_o,
...@@ -156,8 +160,9 @@ begin ...@@ -156,8 +160,9 @@ begin
triggerNumber_o => open, triggerNumber_o => open,
timeStamp_o => open timeStamp_o => open
); );
threshold_discr_p_i <= s_pulses;
threshold_discr_n_i <= not s_pulses; threshold_discr_p_i <= s_pulses;
threshold_discr_n_i <= not s_pulses;
clockGenerator : entity work.logic_clocks clockGenerator : entity work.logic_clocks
port map ( port map (
...@@ -204,5 +209,20 @@ threshold_discr_n_i <= not s_pulses; ...@@ -204,5 +209,20 @@ threshold_discr_n_i <= not s_pulses;
wait; wait;
end process; end process;
tsCounter : process
variable v_tsctr : unsigned ( c_TRIGIN_NUM_COARSE_TS_BITS-1 downto 0) := (others => '0') ;
begin
while not stop_the_clock loop
wait until rising_edge(clk_4x_logic);
if reset_i = '1' then
v_tsctr := ( others => '0');
elsif strobe_4x_logic_i ='1' then
v_tsctr := v_tsctr + 1;
end if;
s_coarse_timestamp <= std_logic_vector(v_tsctr);
end loop;
end process;
end; end;
...@@ -16,76 +16,81 @@ use work.BFMTypes.all; ...@@ -16,76 +16,81 @@ use work.BFMTypes.all;
use std.TEXTIO.all; use std.TEXTIO.all;
entity variablePulseTransactor is entity variablePulseTransactor is
generic( generic(
g_BUSWIDTH : integer := 32); -- width for triggernumber and timestamp g_BUSWIDTH : integer := 32); -- width for triggernumber and timestamp
port( port(
clk_i : in std_logic; clk_i : in std_logic;
trans_i : in t_pulseTransaction; trans_i : in t_pulseTransaction;
returnedData_o : out t_pulseTransactionReturn; returnedData_o : out t_pulseTransactionReturn;
signal_o : out std_logic_vector(c_NPULSE_CHANNELS - 1 downto 0); --! Signal pulses low-high-low signal_o : out std_logic_vector(c_NPULSE_CHANNELS - 1 downto 0); --! Signal pulses low-high-low
triggerNumber_o : out std_logic_vector(g_BUSWIDTH - 1 downto 0); triggerNumber_o : out std_logic_vector(g_BUSWIDTH - 1 downto 0);
timeStamp_o : out std_logic_vector(g_BUSWIDTH - 1 downto 0) timeStamp_o : out std_logic_vector(g_BUSWIDTH - 1 downto 0)
); );
end variablePulseTransactor; end variablePulseTransactor;
architecture rtl of variablePulseTransactor is architecture rtl of variablePulseTransactor is
signal s_timeStamp : unsigned(g_BUSWIDTH - 1 downto 0) := (others => '0'); signal s_timeStamp : unsigned(g_BUSWIDTH - 1 downto 0) := (others => '0');
constant c_timeGranularity : time := 1 ps; constant c_timeGranularity : time := 1 ps;
signal s_pulseNum : integer := 0; signal s_pulseNum : integer := 0;
begin -- rtl begin -- rtl
p_pulseGen : process is p_pulseGen : process is
variable v_pulseDelay : time := 0 ps; variable v_pulseDelay : time := 0 ps;
variable v_pulseWidth : time := 0 ps; variable v_pulseWidth : time := 0 ps;
variable v_lastEdge : time := 0 ps; variable v_lastEdge : time := 0 ps;
begin
report "variablePulseBFM: waiting for transaction" severity note;
signal_o <= (others => '0'); begin
report "variablePulseBFM: waiting for transaction" severity note;
wait on trans_i'transaction; signal_o <= (others => '0');
report "variablePulseBFM: Got transaction" severity note;
wait until rising_edge(clk_i); wait on trans_i'transaction;
report "variablePulseBFM: Got transaction" severity note;
for chan in 0 to signal_o'length - 1 loop wait until rising_edge(clk_i);
v_pulseDelay := trans_i(chan).r_delay * TIMEUNIT;
v_pulseWidth := trans_i(chan).r_width * TIMEUNIT;
if (v_pulseDelay + v_pulseWidth ) > v_lastEdge then for chan in 0 to signal_o'length - 1 loop
v_lastEdge := (v_pulseDelay + v_pulseWidth ); v_pulseDelay := trans_i(chan).r_delay * TIMEUNIT;
end if; v_pulseWidth := trans_i(chan).r_width * TIMEUNIT;
report "Queing pulse . chan , delay , width " & integer'image(chan) & " " & time'image(v_pulseDelay) & " " & time'image(v_pulseWidth);
signal_o(chan) <= '1' after v_pulseDelay, '0' after (v_pulseDelay + v_pulseWidth);
end loop; if (v_pulseDelay + v_pulseWidth) > v_lastEdge then
v_lastEdge := (v_pulseDelay + v_pulseWidth);
end if;
wait for v_lastEdge; if trans_i(chan).r_delay > 0 then
report "Queing pulse . chan , delay , width " & integer'image(chan) & " " & time'image(v_pulseDelay) & " " & time'image(v_pulseWidth);
-- Update trigger number signal_o(chan) <= '1' after v_pulseDelay, '0' after (v_pulseDelay + v_pulseWidth);
s_pulseNum <= s_pulseNum + 1; else
triggerNumber_o <= std_logic_vector(to_unsigned(s_pulseNum, g_BUSWIDTH)); report "NO Pulse queued chr chan " & integer'image(chan);
end if;
-- output current time-stamp
timeStamp_o <= std_logic_vector(s_timeStamp);
returnedData_o <= s_pulseNum; end loop;
end process p_pulseGen; wait for v_lastEdge;
-- purpose: keeps a timestamp in terms of clock cycles -- Update trigger number
-- type : sequential s_pulseNum <= s_pulseNum + 1;
-- inputs : clk_i, s_timeStamp triggerNumber_o <= std_logic_vector(to_unsigned(s_pulseNum, g_BUSWIDTH));
-- outputs: s_timeStamp
p_timeStamp : process(clk_i) -- output current time-stamp
begin -- process p_timeStamp timeStamp_o <= std_logic_vector(s_timeStamp);
if rising_edge(clk_i) then
s_timeStamp <= s_timeStamp + 1; returnedData_o <= s_pulseNum;
end if;
end process p_timeStamp; end process p_pulseGen;
-- purpose: keeps a timestamp in terms of clock cycles
-- type : sequential
-- inputs : clk_i, s_timeStamp
-- outputs: s_timeStamp
p_timeStamp : process(clk_i)
begin -- process p_timeStamp
if rising_edge(clk_i) then
s_timeStamp <= s_timeStamp + 1;
end if;
end process p_timeStamp;
end rtl; end rtl;
...@@ -51,7 +51,7 @@ use work.ipbus.ALL; ...@@ -51,7 +51,7 @@ use work.ipbus.ALL;
entity top is entity top is
generic( generic(
constant FW_VERSION : unsigned(31 downto 0):= X"1e000024"; -- Firmware revision. Remember to change this as needed. constant FW_VERSION : unsigned(31 downto 0):= X"1e000025"; -- Firmware revision. Remember to change this as needed.
g_NUM_DUTS : positive := 4; -- <- was 3 g_NUM_DUTS : positive := 4; -- <- was 3
g_NUM_TRIG_INPUTS :positive := 6;-- <- was 4 g_NUM_TRIG_INPUTS :positive := 6;-- <- was 4
g_NUM_EDGE_INPUTS :positive := 6;-- <-- was 4 g_NUM_EDGE_INPUTS :positive := 6;-- <-- was 4
...@@ -171,6 +171,7 @@ architecture rtl of top is ...@@ -171,6 +171,7 @@ architecture rtl of top is
SIGNAL triggers : std_logic_vector(g_NUM_TRIG_INPUTS-1 DOWNTO 0); --! Rising edge of trigger inputs SIGNAL triggers : std_logic_vector(g_NUM_TRIG_INPUTS-1 DOWNTO 0); --! Rising edge of trigger inputs
SIGNAL s_veto : std_logic; --! goes high when one or more DUT are busy SIGNAL s_veto : std_logic; --! goes high when one or more DUT are busy
signal s_shutter_veto : std_logic; --! Goes high when triggers should be vetoed by shutter signal s_shutter_veto : std_logic; --! Goes high when triggers should be vetoed by shutter
signal s_coarse_timestamp : std_logic_vector(c_COARSE_TIMESTAMP_WIDTH-1 downto 0) := (others => '0'); -- 40MHz timestamp.
signal ctrl, stat: ipb_reg_v(0 downto 0); signal ctrl, stat: ipb_reg_v(0 downto 0);
--My signals --My signals
--SIGNAL busy_toggle_o : std_logic_vector(g_NUM_DUTS-1 downto 0); --SIGNAL busy_toggle_o : std_logic_vector(g_NUM_DUTS-1 downto 0);
...@@ -257,6 +258,7 @@ architecture rtl of top is ...@@ -257,6 +258,7 @@ architecture rtl of top is
COMPONENT eventFormatter COMPONENT eventFormatter
GENERIC ( GENERIC (
g_EVENT_DATA_WIDTH : positive := 64; g_EVENT_DATA_WIDTH : positive := 64;
g_COARSE_TIMESTAMP_WIDTH : positive := 48; -- ! Number of bits in 40MHz timestamp
g_IPBUS_WIDTH : positive := 32; g_IPBUS_WIDTH : positive := 32;
g_COUNTER_TRIG_WIDTH : positive := 32; g_COUNTER_TRIG_WIDTH : positive := 32;
g_COUNTER_WIDTH : positive := 12; g_COUNTER_WIDTH : positive := 12;
...@@ -288,6 +290,7 @@ architecture rtl of top is ...@@ -288,6 +290,7 @@ architecture rtl of top is
ipbus_o : OUT ipb_rbus ; ipbus_o : OUT ipb_rbus ;
data_strobe_o : OUT std_logic ; --! goes high when data ready TO load into event buffer data_strobe_o : OUT std_logic ; --! goes high when data ready TO load into event buffer
event_data_o : OUT std_logic_vector (g_EVENT_DATA_WIDTH-1 DOWNTO 0); event_data_o : OUT std_logic_vector (g_EVENT_DATA_WIDTH-1 DOWNTO 0);
coarse_timestamp_o : out std_logic_vector (g_COUNTER_TRIG_WIDTH-1 DOWNTO 0); --! Global timestamp. Clocked on clk_4x_logic, but only increments with logic_strobe
reset_timestamp_i : IN std_logic ; --! Taking high causes timestamp TO be reset. Combined with internal timestmap reset and written to reset_timestamp_o reset_timestamp_i : IN std_logic ; --! Taking high causes timestamp TO be reset. Combined with internal timestmap reset and written to reset_timestamp_o
reset_timestamp_o : OUT std_logic --! Goes high for one clock cycle of clk_4x_logic when timestamp reset reset_timestamp_o : OUT std_logic --! Goes high for one clock cycle of clk_4x_logic when timestamp reset
); );
...@@ -320,7 +323,8 @@ architecture rtl of top is ...@@ -320,7 +323,8 @@ architecture rtl of top is
---------------------------------------------- ----------------------------------------------
COMPONENT triggerInputs_newTLU COMPONENT triggerInputs_newTLU
GENERIC ( GENERIC (
g_NUM_INPUTS : natural := 1; g_NUM_INPUTS : natural := 1;
g_NUM_COARSE_TS_BITS : natural := 3; --! Number of coarse ( clk_1x_logic normally 40MHz ) timestamp bits to add to MSB of trigger times.
g_IPBUS_WIDTH : positive := 32 g_IPBUS_WIDTH : positive := 32
); );
PORT ( PORT (
...@@ -332,6 +336,7 @@ architecture rtl of top is ...@@ -332,6 +336,7 @@ architecture rtl of top is
threshold_discr_p_i : IN std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0); --! inputs from threshold comparators threshold_discr_p_i : IN std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0); --! inputs from threshold comparators
threshold_discr_n_i : IN std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0); --! inputs from threshold comparators threshold_discr_n_i : IN std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0); --! inputs from threshold comparators
reset_i : IN std_logic ; reset_i : IN std_logic ;
coarse_timestamp_i : in std_logic_vector (g_NUM_COARSE_TS_BITS-1 DOWNTO 0); --! Global timestamp. Clocked on clk_4x_logic, but only increments with logic_strobe
trigger_times_o : OUT t_triggerTimeArray (g_NUM_INPUTS-1 DOWNTO 0); --! trigger arrival time ( w.r.t. logic_strobe) trigger_times_o : OUT t_triggerTimeArray (g_NUM_INPUTS-1 DOWNTO 0); --! trigger arrival time ( w.r.t. logic_strobe)
trigger_o : OUT std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0); --! Goes high on leading edge of trigger, in sync with clk_4x_logic_i trigger_o : OUT std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0); --! Goes high on leading edge of trigger, in sync with clk_4x_logic_i
--trigger_debug_o : OUT std_logic_vector ( ((2*g_NUM_INPUTS)-1) DOWNTO 0); --! Copy of input trigger level. High bits CFD, Low threshold --trigger_debug_o : OUT std_logic_vector ( ((2*g_NUM_INPUTS)-1) DOWNTO 0); --! Copy of input trigger level. High bits CFD, Low threshold
...@@ -566,6 +571,7 @@ begin ...@@ -566,6 +571,7 @@ begin
threshold_discr_p_i => threshold_discr_p_i, threshold_discr_p_i => threshold_discr_p_i,
threshold_discr_n_i => threshold_discr_n_i, threshold_discr_n_i => threshold_discr_n_i,
reset_i => logic_reset, reset_i => logic_reset,
coarse_timestamp_i => s_coarse_timestamp(c_TRIGIN_NUM_COARSE_TS_BITS-1 downto 0),
trigger_times_o => trigger_times, trigger_times_o => trigger_times,
trigger_o => triggers, trigger_o => triggers,
--trigger_debug_o => OPEN, --trigger_debug_o => OPEN,
...@@ -616,6 +622,7 @@ begin ...@@ -616,6 +622,7 @@ begin
ipbus_o => ipbrr(N_SLV_EVENT_FORMATTER), ipbus_o => ipbrr(N_SLV_EVENT_FORMATTER),
data_strobe_o => data_strobe, data_strobe_o => data_strobe,
event_data_o => event_data, event_data_o => event_data,
coarse_timestamp_o => s_coarse_timestamp,
reset_timestamp_i => s_T0, reset_timestamp_i => s_T0,
reset_timestamp_o => OPEN reset_timestamp_o => OPEN
); );
......
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