Commit 336ffeec authored by David Cussans's avatar David Cussans

Version of TLU firmware that seems to vaguely function:

- changed IPBus read from FIFO in eventBuffer_rtl.vhd. Probably uncessary, but not going back now. In process changed FIFO to standard rather than fall-through and decreased size ( to try to help with timing closure )

- Put SHREG attribute in logic_clocks_rtl.vhd. Should also add to other places.

- Added pulse stretch to stretchPulse_rtl.vhd ( used to be just delay )

- Randomly hacked event formatter until it records which trigger fired.

- trigger logic hacked to provide only a single clock cycle trigger ( rather than staying high for however long the trigger combination was active.

- Trying to reduce timing errors by specifying which nets don't need timing closure ( using TIG ) in sp605_FMC_mTLU_v1a.ucf

- Uncommented re-generate IP in build_bitstream.tcl 
parent d0e50c4d
#ChipScope Core Inserter Project File Version 3.0
#Thu Aug 27 14:43:06 BST 2015
Project.device.designInputFile=/users/phdgc/IPBus_stuff/fmc_tlu_test_modify_tpix3_nov14_aug15/workspace/top_extphy_cs.ngc
Project.device.designOutputFile=/users/phdgc/IPBus_stuff/fmc_tlu_test_modify_tpix3_nov14_aug15/workspace/top_extphy_cs.ngc
#Wed Oct 28 14:11:18 CET 2015
Project.device.designInputFile=/afs/cern.ch/user/c/cussans/IPBus_stuff/fmc_tlu_test_modify_tpix3_nov14_aug15/workspace/top_extphy_cs.ngc
Project.device.designOutputFile=/afs/cern.ch/user/c/cussans/IPBus_stuff/fmc_tlu_test_modify_tpix3_nov14_aug15/workspace/top_extphy_cs.ngc
Project.device.deviceFamily=18
Project.device.enableRPMs=true
Project.device.outputDirectory=/users/phdgc/IPBus_stuff/fmc_tlu_test_modify_tpix3_nov14_aug15/workspace/_ngo
Project.device.outputDirectory=/afs/cern.ch/user/c/cussans/IPBus_stuff/fmc_tlu_test_modify_tpix3_nov14_aug15/workspace/_ngo
Project.device.useSRL16=true
Project.filter.dimension=19
Project.filter<0>=*veto*
Project.filter<10>=*T0*
Project.filter<11>=T0
Project.filter<12>=I2/s_coarse_timestamp_h*
Project.filter<13>=I2/*ignore*
Project.filter<14>=I2/*coarse_timestamp*
Project.filter<15>=*coarse_timestamp*
Project.filter<16>=*s_coarse_timestamp_h*
Project.filter<17>=*reset_timestamp*
Project.filter<18>=*coarse_timestamp_h*
Project.filter<1>=*busy*
Project.filter<0>=*trig*
Project.filter<10>=*clk*
Project.filter<11>=clk*
Project.filter<12>=*veto*
Project.filter<13>=*busy*
Project.filter<14>=*external*
Project.filter<15>=*externali*
Project.filter<16>=*veto_i*
Project.filter<17>=*ignore*
Project.filter<18>=*ignore_busy*
Project.filter<1>=*fired*
Project.filter<2>=
Project.filter<3>=*external*
Project.filter<4>=*externali*
Project.filter<5>=*veto_i*
Project.filter<6>=*ignore*
Project.filter<7>=*ignore_busy*
Project.filter<8>=I0/*busy*
Project.filter<9>=*shutter*
Project.filter<3>=*CLK*4*
Project.filter<4>=i2/*STROBE*
Project.filter<5>=i2/*TRIG*
Project.filter<6>=*word*
Project.filter<7>=*type*
Project.filter<8>=*evt*
Project.filter<9>=*clk*4*
Project.icon.boundaryScanChain=1
Project.icon.enableExtTriggerIn=false
Project.icon.enableExtTriggerOut=false
......@@ -35,18 +35,18 @@ Project.unit.dimension=1
Project.unit<0>.clockChannel=clk_4x_logic
Project.unit<0>.clockEdge=Rising
Project.unit<0>.dataChannel<0>=I2/s_coarse_timestamp_h<0>
Project.unit<0>.dataChannel<10>=I0/s_busy_from_dut<2>
Project.unit<0>.dataChannel<11>=I0/veto_o
Project.unit<0>.dataChannel<12>=overall_veto
Project.unit<0>.dataChannel<10>=I2/trigger_inputs_fired_d1<1>
Project.unit<0>.dataChannel<11>=I2/trigger_inputs_fired_d1<2>
Project.unit<0>.dataChannel<12>=I2/trigger_inputs_fired_d1<3>
Project.unit<0>.dataChannel<1>=I2/s_coarse_timestamp_h<1>
Project.unit<0>.dataChannel<2>=I2/s_coarse_timestamp_h<2>
Project.unit<0>.dataChannel<3>=I2/s_coarse_timestamp_h<3>
Project.unit<0>.dataChannel<4>=I2/s_reset_timestamp_ipbus
Project.unit<0>.dataChannel<5>=I2/s_reset_timestamp_4x
Project.unit<0>.dataChannel<6>=I10/T0_o
Project.unit<0>.dataChannel<7>=I10/shutter_o
Project.unit<0>.dataChannel<8>=I0/s_busy_from_dut<0>
Project.unit<0>.dataChannel<9>=I0/s_busy_from_dut<1>
Project.unit<0>.dataChannel<4>=I2/s_event_strobe_d3
Project.unit<0>.dataChannel<5>=I2/s_event_strobe_d2
Project.unit<0>.dataChannel<6>=I2/s_event_strobe_d1
Project.unit<0>.dataChannel<7>=I2/data_strobe_o
Project.unit<0>.dataChannel<8>=I3/s_post_veto_trigger
Project.unit<0>.dataChannel<9>=I2/trigger_inputs_fired_d1<0>
Project.unit<0>.dataDepth=2048
Project.unit<0>.dataEqualsTrigger=true
Project.unit<0>.dataPortWidth=13
......@@ -56,18 +56,18 @@ Project.unit<0>.enableTimestamps=false
Project.unit<0>.timestampDepth=0
Project.unit<0>.timestampWidth=0
Project.unit<0>.triggerChannel<0><0>=I2/s_coarse_timestamp_h<0>
Project.unit<0>.triggerChannel<0><10>=I3/Mcount_s_post_veto_trigger_counter_cy<2>
Project.unit<0>.triggerChannel<0><11>=I3/Mcount_s_post_veto_trigger_counter_cy<1>
Project.unit<0>.triggerChannel<0><12>=I3/Mcount_s_post_veto_trigger_counter_cy<0>
Project.unit<0>.triggerChannel<0><10>=I3/trigger_o<2>
Project.unit<0>.triggerChannel<0><11>=I3/trigger_o<1>
Project.unit<0>.triggerChannel<0><12>=I3/trigger_o<0>
Project.unit<0>.triggerChannel<0><1>=I2/s_coarse_timestamp_h<1>
Project.unit<0>.triggerChannel<0><2>=I2/s_coarse_timestamp_h<2>
Project.unit<0>.triggerChannel<0><3>=I2/s_coarse_timestamp_h<3>
Project.unit<0>.triggerChannel<0><4>=I2/s_reset_timestamp_ipbus
Project.unit<0>.triggerChannel<0><5>=I2/s_reset_timestamp_4x
Project.unit<0>.triggerChannel<0><6>=I10/T0_o
Project.unit<0>.triggerChannel<0><7>=I10/shutter_o
Project.unit<0>.triggerChannel<0><4>=I2/s_event_strobe_d3
Project.unit<0>.triggerChannel<0><5>=I2/s_event_strobe_d2
Project.unit<0>.triggerChannel<0><6>=I2/s_event_strobe_d1
Project.unit<0>.triggerChannel<0><7>=I2/data_strobe_o
Project.unit<0>.triggerChannel<0><8>=I3/s_post_veto_trigger
Project.unit<0>.triggerChannel<0><9>=I3/Mcount_s_post_veto_trigger_counter_cy<3>
Project.unit<0>.triggerChannel<0><9>=I3/trigger_o<3>
Project.unit<0>.triggerConditionCountWidth=0
Project.unit<0>.triggerMatchCount<0>=1
Project.unit<0>.triggerMatchCountWidth<0><0>=0
......
project open fmc-mtlu
##puts "Regenerating cores"
##cd $::env(FW_WORKSPACE)/workspace/ipcore_dir
##catch {exec coregen -r -b tri_mode_eth_mac_v5_4.xco -p coregen.cgp}
##catch {exec coregen -r -b mac_fifo_axi4.xco -p coregen.cgp}
puts "Regenerating cores"
cd $::env(FW_WORKSPACE)/workspace/ipcore_dir
catch {exec coregen -r -b tri_mode_eth_mac_v5_4.xco -p coregen.cgp}
catch {exec coregen -r -b mac_fifo_axi4.xco -p coregen.cgp}
##catch {exec coregen -r -b tlu_event_fifo.xco -p coregen.cgp}
##catch {exec coregen -r -b FIFO.xco -p coregen.cgp}
### catch {exec coregen -r -b CounterUp.xco -p coregen.cgp}
##catch {exec coregen -r -b internalTriggerGenerator.xco -p coregen.cgp}
catch {exec coregen -r -b tlu_event_fifo.xco -p coregen.cgp}
catch {exec coregen -r -b FIFO.xco -p coregen.cgp}
# catch {exec coregen -r -b CounterUp.xco -p coregen.cgp}
catch {exec coregen -r -b internalTriggerGenerator.xco -p coregen.cgp}
process run "Synthesize"
......
......@@ -41,7 +41,7 @@ ENTITY eventBuffer IS
GENERIC(
g_EVENT_DATA_WIDTH : positive := 64;
g_IPBUS_WIDTH : positive := 32;
g_READ_COUNTER_WIDTH : positive := 16
g_READ_COUNTER_WIDTH : positive := 14
);
PORT(
clk_4x_logic_i : IN std_logic;
......@@ -78,6 +78,7 @@ ARCHITECTURE rtl OF eventBuffer IS
signal s_fifo_valid : std_logic := '1'; -- ! High when data in FIFO
signal s_fifo_full, s_fifo_almost_full, s_fifo_empty, s_fifo_almost_empty : std_logic := '0'; -- ! full and empty FIFO flags
signal s_fifo_status_ipb , s_fifo_fill_level_d1 : std_logic_vector(ipbus_o.ipb_rdata'range) := (others => '0'); -- data registered onto IPBus clock
signal s_ack : std_logic := '0'; -- -- IPBus ACK signal
BEGIN
......@@ -85,18 +86,28 @@ BEGIN
-- IPBus IO
-----------------------------------------------------------------------------
--! Generate FIFO read enable
s_fifo_rd_en <= '1' when ipbus_i.ipb_strobe = '1' and ipbus_i.ipb_write = '0' and ipbus_i.ipb_addr(1 downto 0) = "00" else '0';
s_fifo_valid <= '1';
--! Generate IPBus ACK
ipbus_o.ipb_ack <= (ipbus_i.ipb_strobe and not s_fifo_rd_en) or (s_fifo_valid and s_fifo_rd_en);
ipbus_ack: process(ipbus_clk_i)
begin
if rising_edge(ipbus_clk_i) then
s_ack <= ipbus_i.ipb_strobe and not s_ack;
end if;
end process ipbus_ack;
ipbus_o.ipb_ack <= s_ack;
--! Generate FIFO read enable
--! take high for one cycle ( when ipb_strobe goes high but before ACK goes
--high to follow it
s_fifo_rd_en <= '1' when
ipbus_i.ipb_strobe = '1' and ipbus_i.ipb_write = '0' and ipbus_i.ipb_addr(1 downto 0) = "00" and s_ack = '0'
else '0';
ipbus_o.ipb_err <= '0';
--! Multiplex output data.
with ipbus_i.ipb_addr(1 downto 0) select ipbus_o.ipb_rdata <=
s_fifo_dout when "00",
s_fifo_fill_level when "01",
s_fifo_fill_level when "01",
s_fifo_status_ipb when "10",
(others => '1') when others;
......@@ -110,7 +121,7 @@ BEGIN
-- Register data onto IPBus clock domain to ease timing closure.
s_fifo_status_ipb <= X"000000" & "000" & s_fifo_prog_full & s_fifo_full & s_fifo_almost_full & s_fifo_almost_empty & s_fifo_empty;
s_fifo_fill_level <= X"0000" & s_rd_data_count;
s_fifo_fill_level <= X"0000" & "00" & s_rd_data_count;
end if;
end process ipbus_write;
......
......@@ -165,7 +165,6 @@ ARCHITECTURE rtl OF eventFormatter IS
signal s_word0_d1 , s_word1_d1, s_word2_d1 : std_logic_vector(g_EVENT_DATA_WIDTH-1 downto 0) := (others => '0'); -- clocked to data output on logic_strobe , s_logic_strobe_d1 , etc.
signal s_word0_d2 , s_word1_d2, s_word2_d2 : std_logic_vector(g_EVENT_DATA_WIDTH-1 downto 0) := (others => '0'); -- clocked to data output on logic_strobe , s_logic_strobe_d1 , etc.
signal s_word0_d3 , s_word1_d3, s_word2_d3 : std_logic_vector(g_EVENT_DATA_WIDTH-1 downto 0) := (others => '0'); -- clocked to data output on logic_strobe , s_logic_strobe_d1 , etc.
signal trigger_inputs_fired_d1 : std_logic_vector (g_NUM_TRIG_INPUTS-1 DOWNTO 0) := (others => '0');
signal trigger_times_d1 : t_triggerTimeArray (g_NUM_TRIG_INPUTS-1 DOWNTO 0) := (others => (others=>'0'));
signal s_reset_timestamp_4x, s_reset_timestamp_4x_ipbus , s_reset_timestamp_4x_external , s_reset_timestamp_4x_external_p1 , s_reset_timestamp_4x_external_p2 : std_logic := '0'; --! Single pulse on 4x domain
......@@ -180,6 +179,7 @@ ARCHITECTURE rtl OF eventFormatter IS
signal s_rst_fifo_d1 , s_rst_fifo_d2 , s_rst_fifo_clk4x : std_logic := '0';
signal s_buffer_full_d1 , s_buffer_full_d2 , s_buffer_full_clk4x : std_logic := '0';
signal s_trigger : std_logic := '0'; -- pulses on risng edge of triger in
BEGIN
......@@ -279,7 +279,13 @@ BEGIN
end if;
end process p_signals_clk_domain;
cmp_triggerEdgeDetect: entity work.single_pulse
port map (
level => trigger_i,
clk => clk_4x_logic_i,
pulse => s_trigger
);
-- purpose: generate delayed strobes and write enable flags to the FIFOs
-- type : combinational
-- inputs : clk_4x_logic_i , s_FIFO_rd
......@@ -292,8 +298,12 @@ BEGIN
s_event_strobe_d2 <= '0';
s_event_strobe_d3 <= '0';
else
s_event_strobe_d1 <= trigger_i and s_enable_trigger and not buffer_full_i;
else
-- set s_event_strobe high if trigger_i is high and pipeline is empty
-- ( i.e. all event_strobe are zero)
s_event_strobe_d1 <= s_trigger and s_enable_trigger and not buffer_full_i and
(not s_event_strobe_d1 ) and (not s_event_strobe_d2 ) and (not s_event_strobe_d3 );
s_event_strobe_d2 <= s_event_strobe_d1;
s_event_strobe_d3 <= s_event_strobe_d2;
......@@ -305,11 +315,6 @@ BEGIN
begin -- process p_generate_strobes
if rising_edge(clk_4x_logic_i) then
-- Swap order of trigger inputs. WHY????
for i in 0 to g_NUM_TRIG_INPUTS-1 loop
trigger_inputs_fired_d1(g_NUM_TRIG_INPUTS-1-i) <= trigger_inputs_fired_i(i);
end loop;
trigger_times_d1 <= trigger_times_i;
s_word0_d1 <= s_word0;
......@@ -338,10 +343,16 @@ BEGIN
-------------------------------------------------------------------------------
-- Trigger event formater
-------------------------------------------------------------------------------
s_evttype <= "0000" when unsigned(trigger_inputs_fired_d1) = 0 and trigger_i = '1' else
"0001";
-- s_evttype <= "0000" when unsigned(trigger_inputs_fired_d1) = 0 and trigger_i = '1' else
-- s_evttype <= "0000" when unsigned(trigger_inputs_fired_i) = 0 and trigger_i = '1' else
-- "0001";
-- s_evttype <= "0000" when unsigned(trigger_inputs_fired_d1) = 0 else
-- "0001";
s_evttype <= "0000" when unsigned(trigger_inputs_fired_i) = 0 else "0001";
-- s_var <= trigger_inputs_fired_d1 & std_logic_vector(to_unsigned(0,s_var'length-g_NUM_TRIG_INPUTS));
s_var <= trigger_inputs_fired_i & std_logic_vector(to_unsigned(0,s_var'length-g_NUM_TRIG_INPUTS));
s_var <= trigger_inputs_fired_d1 & std_logic_vector(to_unsigned(0,s_var'length-g_NUM_TRIG_INPUTS));
--s_word0 <= s_evttype(0) & s_var(0) & std_logic_vector(s_coarse_timestamp_d2);
s_word0 <= s_evttype & s_var & std_logic_vector(s_coarse_timestamp_h_d2) & std_logic_vector(s_coarse_timestamp_l_d2);
......
......@@ -25,7 +25,7 @@ architecture rtl of ipbus_ver is
begin
ipbus_out.ipb_rdata <= X"a612" & X"1008"; -- Lower 16b are ipbus firmware build ID (temporary arrangement).
ipbus_out.ipb_rdata <= X"a618" & X"1008"; -- Lower 16b are ipbus firmware build ID (temporary arrangement).
ipbus_out.ipb_ack <= ipbus_in.ipb_strobe;
ipbus_out.ipb_err <= '0';
......
......@@ -115,6 +115,12 @@ ARCHITECTURE rtl OF logic_clocks IS
-- ! Reset signal in IPBus clock domain
signal s_logic_reset , s_logic_reset_d1 , s_logic_reset_d2 , s_logic_reset_d3 , s_logic_reset_d4 : std_logic := '0';
-- ! reset signal clocked onto logic-clock domain.
attribute SHREG_EXTRACT: string;
attribute SHREG_EXTRACT of s_logic_reset_d1: signal is "no"; -- Synchroniser not to be optimised into shre
attribute SHREG_EXTRACT of s_logic_reset_d2: signal is "no"; -- Synchroniser not to be optimised into shreg
attribute SHREG_EXTRACT of s_logic_reset_d3: signal is "no"; -- Synchroniser not to be optimised into shreg
attribute SHREG_EXTRACT of s_logic_reset_d4: signal is "no"; -- Synchroniser not to be optimised into shreg
signal s_ipbus_ack : std_logic := '0';
signal s_reset_pll : std_logic := '0';
......@@ -157,7 +163,7 @@ BEGIN
-- register the clock status signals onto IPBus domain.
--s_clock_status_ipb <= x"0000000" & s_extclk_is_input & s_clk_is_xtal & s_locked_bufpll & s_locked_pll;
s_clock_status_ipb <= x"0000000" & '0' & s_clk_is_xtal & s_locked_bufpll & s_locked_pll;
s_clock_status_ipb <= x"0000000" & '0' & s_clk_is_xtal & s_locked_bufpll & s_locked_pll;
end if;
end process ipbus_write;
......
......@@ -36,19 +36,33 @@ end entity stretchPulse;
architecture rtl of stretchPulse is
signal s_delaySR : std_logic_vector( (2**g_PARAM_WIDTH) -1 downto 0) := ( others => '0' ); -- --! Shift register to generate delay
signal s_stretchSR : std_logic_vector( (2**g_PARAM_WIDTH) -1 downto 0) := ( others => '0' ); -- --! Shift register to generate stretch
signal s_delayedPulse : std_logic := '0'; -- delayed pulse before stretch
begin -- architecture rtl
--! Delay pulse
p_registerPulse: process (clk_i , pulse_i) is
begin -- process p_registerPulse
p_delayPulse: process (clk_i , pulse_i) is
begin -- process p_delayPulse
if rising_edge(clk_i) then
s_delaySR <= s_delaySR( (s_delaySR'left -1) downto 0 ) & pulse_i;
pulse_o <= s_delaySR( to_integer(unsigned(pulseWidth_i)) );
s_delayedPulse <= s_delaySR( to_integer(unsigned(pulseDelay_i)) );
end if;
end process p_delayPulse;
--! Stretch pulse. the output pulse is always at least as long as the input pulse
p_stretchPulse: process (clk_i , pulse_i) is
begin -- process p_stretchPulse
if rising_edge(clk_i) then
if s_delayedPulse = '1' then
s_stretchSR <= ( others => '1' ) ;
pulse_o <= s_delayedPulse ;
else
s_stretchSR <= s_stretchSR( (s_stretchSR'left -1) downto 0 ) & '0';
pulse_o <= s_stretchSR( to_integer(unsigned(pulseWidth_i)) );
end if;
end if;
end process p_registerPulse;
end process p_stretchPulse;
end architecture rtl;
......@@ -80,7 +80,7 @@ ARCHITECTURE rtl OF triggerLogic IS
--! vector that stores trigger output for each combination of trigger inputs.
signal s_trigger_inputs_enabled , s_trigger_inputs_enabled_ipb : std_logic_vector(g_IPBUS_WIDTH-1 downto 0) := x"00000001";--(others=>'1');
signal s_external_trigger , s_auxTrigger , s_internal_veto , s_internal_veto_ipb : std_logic := '0';
signal s_external_trigger_p , s_external_trigger_l , s_auxTrigger , s_internal_veto , s_internal_veto_ipb : std_logic := '0';
signal s_internal_trigger_interval: std_logic_vector(g_IPBUS_WIDTH-1 downto 0) := (others => '0'); -- setting s_internal_trigger_interval to zero means no internal triggers
signal s_pre_veto_trigger_counter , s_post_veto_trigger_counter , s_aux_trigger_counter: unsigned(g_IPBUS_WIDTH-1 downto 0) := (others => '0'); -- ! counters for triggers before and after veto
signal s_pre_veto_trigger_counter_ipb , s_post_veto_trigger_counter_ipb : std_logic_vector(g_IPBUS_WIDTH-1 downto 0) := (others => '0'); -- ! counters for triggers before and after veto, on ipbus clock domain
......@@ -100,6 +100,7 @@ ARCHITECTURE rtl OF triggerLogic IS
signal s_PulseStretchWord : std_logic_vector(g_IPBUS_WIDTH-1 downto 0) := (others => '0'); --! Length of trigger pulses
signal s_PulseDelayWord : std_logic_vector(g_IPBUS_WIDTH-1 downto 0) := (others => '0'); --!number of cycles to delay trigger pulses.
constant c_PARAM_WIDTH : positive := 5; -- length of pulse width and delay.
constant c_BYTE_WIDTH : positive := 8; -- trying to make code clearer...
constant c_N_CTRL : positive := 8;
constant c_N_STAT : positive := 8;
......@@ -111,7 +112,7 @@ ARCHITECTURE rtl OF triggerLogic IS
signal s_external_veto_word : std_logic_vector(g_IPBUS_WIDTH-1 downto 0) := (others => '0');
signal s_loadTriggerPattern , s_loadTriggerPattern_p1 : std_logic := '0'; -- take high to load trigger pattern
signal s_stretchedTriggers : std_logic_vector( trigger_i'range) := (others => '0'); -- --! Triggers after stretch and delay
signal s_stretchedTriggers , s_stretchedTriggers_d1 , s_stretchedTriggers_d2 : std_logic_vector( trigger_i'range) := (others => '0'); -- --! Triggers after stretch and delay
BEGIN
-----------------------------------------------------------------------------
......@@ -198,10 +199,10 @@ BEGIN
clk_i => clk_4x_logic_i,
pulse_i => trigger_i(v_inputNumber),
pulse_o => s_stretchedTriggers(v_inputNumber),
-- pulsewidth_i => s_PulseStretchWord( (2*v_inputNumber*c_PARAM_WIDTH) + c_PARAM_WIDTH -1 downto 2*v_inputNumber*c_PARAM_WIDTH ),
-- pulseDelay_i => s_PulseDelayWord( (2*v_inputNumber*c_PARAM_WIDTH) + (2*c_PARAM_WIDTH)-1 downto (2*v_inputNumber*c_PARAM_WIDTH) + c_PARAM_WIDTH )
pulsewidth_i => s_PulseStretchWord( c_PARAM_WIDTH-1 downto 0 ),
pulseDelay_i => s_PulseDelayWord( c_PARAM_WIDTH-1 downto 0 )
pulsewidth_i => s_PulseStretchWord( (v_inputNumber*c_BYTE_WIDTH) + c_PARAM_WIDTH -1 downto v_inputNumber*c_BYTE_WIDTH ),
pulseDelay_i => s_PulseDelayWord( (v_inputNumber*c_BYTE_WIDTH) + c_PARAM_WIDTH -1 downto v_inputNumber*c_BYTE_WIDTH )
-- pulsewidth_i => s_PulseStretchWord( c_PARAM_WIDTH-1 downto 0 ),
-- pulseDelay_i => s_PulseDelayWord( c_PARAM_WIDTH-1 downto 0 )
);
end generate gen_stretchVals;
......@@ -215,25 +216,36 @@ BEGIN
configClk_i => ipbus_clk_i, --! No point in moving off IPBus clock
logicClk_i => clk_4x_logic_i,
triggers_i => s_stretchedTriggers,
trigger_o => s_external_trigger,
trigger_o => s_external_trigger_l,
auxTrigger_o => s_auxTrigger,
-- Control ports...
triggerPattern_i => s_TriggerPattern,
loadPattern_i => s_loadTriggerPattern
);
--! just look for the rising edge ( with long stretch can get multiple clock
--! cycle triggers )
cmp_triggerRisingEdge : entity work.single_pulse
port map (
level => s_external_trigger_l,
clk => clk_4x_logic_i,
pulse => s_external_trigger_p
);
--! Produce triggers....
trigGen : process ( clk_4x_logic_i )
begin
if rising_edge(clk_4x_logic_i) then
s_post_veto_trigger <= (s_external_trigger or s_internal_trigger) and (not ( s_internal_veto or veto_i) );
s_pre_veto_trigger <= (s_external_trigger or s_internal_trigger);
s_post_veto_trigger <= (s_external_trigger_p or s_internal_trigger) and (not ( s_internal_veto or veto_i) );
s_pre_veto_trigger <= (s_external_trigger_p or s_internal_trigger);
-- Change Me
-- Process triggers , but for now pass through.
trigger_o <= s_stretchedTriggers;
-- delay output of which input triggers fired so that they go high at the
-- same time as the pre/post veto trigger signals.
s_stretchedTriggers_d1 <= s_stretchedTriggers;
s_stretchedTriggers_d2 <= s_stretchedTriggers_d1;
trigger_o <= s_stretchedTriggers_d2;
trigger_times_o <= trigger_times_i;
end if;
......
......@@ -496,7 +496,7 @@ BEGIN
GENERIC MAP (
g_EVENT_DATA_WIDTH => g_EVENT_DATA_WIDTH,
g_IPBUS_WIDTH => g_IPBUS_WIDTH,
g_READ_COUNTER_WIDTH => 16
g_READ_COUNTER_WIDTH => 14
)
PORT MAP (
clk_4x_logic_i => clk_4x_logic,
......
......@@ -13,7 +13,30 @@ import uhal
import sys
import time
def initTLU( uhalDevice , pychipsBoard , listenForTelescopeShutter , pulseDelay , pulseStretch , DUTMask , triggerInterval , thresholdVoltage , writeTimestamps):
def startTLU( uhalDevice , pychipsBoard , writeTimestamps):
print "Reseting FIFO"
pychipsBoard.write("EventFifoCSR",0x2)
eventFifoFillLevel = pychipsBoard.read("EventFifoFillLevel")
print "FIFO fill level after resetting FIFO = " , eventFifoFillLevel
if writeTimestamps:
print "Enabling data recording"
pychipsBoard.write("Enable_Record_Data",1)
else:
print "Disabling data recording"
pychipsBoard.write("Enable_Record_Data",0)
print "Pulsing T0"
pychipsBoard.write("PulseT0",1)
print "Turning off software trigger veto"
pychipsBoard.write("TriggerVetoW",0)
print "TLU is running"
def initTLU( uhalDevice , pychipsBoard , listenForTelescopeShutter , pulseDelay , pulseStretch , DUTMask , triggerInterval , thresholdVoltage ):
print "Setting up AIDA TLU \n"
......@@ -21,9 +44,8 @@ def initTLU( uhalDevice , pychipsBoard , listenForTelescopeShutter , pulseDelay
uhalDevice.dispatch()
print "Version (uHAL)= " , hex(fwVersion)
firmwareID=pychipsBoard.read("FirmwareId")
print "Firmware (from PyChips) = " , hex(firmwareID)
print "Turning on software trigger veto"
pychipsBoard.write("TriggerVetoW",1)
# Check the bus for I2C devices
pychipsBoardi2c = FmcTluI2c(pychipsBoard)
......@@ -133,22 +155,6 @@ def initTLU( uhalDevice , pychipsBoard , listenForTelescopeShutter , pulseDelay
IgnoreDUTBusy = pychipsBoard.read("IgnoreDUTBusyR")
print "IgnoreDUTBusyR = " , IgnoreDUTBusy
print "Turning off software trigger veto"
pychipsBoard.write("TriggerVetoW",0)
print "Reseting FIFO"
pychipsBoard.write("EventFifoCSR",0x2)
eventFifoFillLevel = pychipsBoard.read("EventFifoFillLevel")
print "FIFO fill level after resetting FIFO = " , eventFifoFillLevel
if writeTimestamps:
print "Enabling data recording"
pychipsBoard.write("Enable_Record_Data",1)
else:
print "Disabling data recording"
pychipsBoard.write("Enable_Record_Data",0)
#print "Enabling handshake: No-handshake"
#board.write("HandshakeTypeW",1)
......
......@@ -12,7 +12,7 @@ import uhal
import sys
import time
import time , datetime
# For single character non-blocking input:
import select
......@@ -60,14 +60,17 @@ writeTimestamps = True
listenForTelescopeShutter = False
#TriggerInterval = 400000 # Units = 160MHz clock ticks.
#loopWait = 1.0 # polling interval ( seconds )
TriggerInterval = 16000 # Units = 160MHz clock ticks.
#TriggerInterval = 0 # Units = 160MHz clock ticks.
#TriggerInterval = 16000 # Units = 160MHz clock ticks.
#TriggerInterval = 4000 # Units = 160MHz clock ticks.
TriggerInterval = 0 # Units = 160MHz clock ticks.
loopWait = 0.05 # polling interval ( seconds )
pulseDelay = 0 # between 0 and 31 in units of 160MHz clock.
pulseStretch = 4 # between 0 and 31 in units of 160MHz clock.
DUTMask = 1 # bit mask to indicate with DUT are active
writeTimestamps = True
printTimestamps = False
rootFname = "OutputData.root"
rootFname = "/data/tlu/OutputData.root"
# Point to board in uHAL
manager = uhal.ConnectionManager("file://./connection.xml")
......@@ -87,7 +90,7 @@ tree.Branch( 'tluInts', tluEvtStruct, 'Bufpos/l:HighWord/l:LowWord/l:EvtNumber/l
# Initialize TLU registers
initTLU( uhalDevice = hw, pychipsBoard = board, listenForTelescopeShutter = listenForTelescopeShutter, pulseDelay = pulseDelay, pulseStretch = pulseStretch, DUTMask = DUTMask, triggerInterval = TriggerInterval, thresholdVoltage =-0.2 , writeTimestamps = True )
initTLU( uhalDevice = hw, pychipsBoard = board, listenForTelescopeShutter = listenForTelescopeShutter, pulseDelay = pulseDelay, pulseStretch = pulseStretch, DUTMask = DUTMask, triggerInterval = TriggerInterval, thresholdVoltage =-0.2 )
oldEvtNumber = 0
......@@ -101,6 +104,8 @@ eventFifoFillLevel = 0
loopRunning = True
runStarted = False
oldTime = time.time()
# Save old terminal settings
oldTermSettings = termios.tcgetattr(sys.stdin)
tty.setcbreak(sys.stdin.fileno())
......@@ -113,16 +118,13 @@ while loopRunning:
if c == 'q':
loopRunning = False
print "Terminating loop"
elif c == 's':
elif c == 'c':
runStarted = True
print "Starting Run"
startTLU( uhalDevice = hw, pychipsBoard = board, writeTimestamps = writeTimestamps )
if runStarted:
nEvents = int(eventFifoFillLevel)//4 # only read out whole events ( 4 x 32-bit words )
wordsToRead = nEvents*4
# get timestamp data and fifo fill in same outgoing packet.
timestampData = hw.getNode("eventBuffer.EventFifoData").readBlock(wordsToRead)
eventFifoFillLevel = hw.getNode("eventBuffer.EventFifoFillLevel").read()
preVetotriggerCount = hw.getNode("triggerLogic.PreVetoTriggersR").read()
......@@ -133,8 +135,12 @@ while loopRunning:
hw.dispatch()
preVetoFreq = (preVetotriggerCount-oldPreVetotriggerCount)/loopWait
postVetoFreq = (postVetotriggerCount-oldPostVetotriggerCount)/loopWait
newTime = time.time()
timeDelta = newTime - oldTime
oldTime = newTime
#print "time delta = " , timeDelta
preVetoFreq = (preVetotriggerCount-oldPreVetotriggerCount)/timeDelta # loopWait
postVetoFreq = (postVetotriggerCount-oldPostVetotriggerCount)/timeDelta #loopWait
oldPreVetotriggerCount = preVetotriggerCount
oldPostVetotriggerCount = postVetotriggerCount
......@@ -142,11 +148,21 @@ while loopRunning:
print "Current timestamp High,Low (hex) = " , hex(timestampHigh) , hex(timestampLow)
nEvents = int(eventFifoFillLevel)//4 # only read out whole events ( 4 x 32-bit words )
wordsToRead = nEvents*4
print "FIFO fill level = " , eventFifoFillLevel
print "number of events in FIFO = ",nEvents
print "words to read from FIFO = ",wordsToRead
# get timestamp data and fifo fill in same outgoing packet.
timestampData = hw.getNode("eventBuffer.EventFifoData").readBlock(wordsToRead)
hw.dispatch()
# print timestampData
for evt in range (0, nEvents-1 ):
for evt in range (0, nEvents ):
lowWord = timestampData[evt*4 + 1] + 0x100000000* timestampData[ (evt*4) + 0] # timestamp
highWord = timestampData[evt*4 + 3] + 0x100000000* timestampData[ (evt*4) + 2] # evt number
......@@ -163,7 +179,8 @@ while loopRunning:
trigsFired = (timestampData[ (evt*4) + 0] >> 16) & 0xFFF
print "bufferPos, highWord , lowWord , event-number , timestamp , evtType = %x %016x %016x %08x %012x %01x %03x" % ( evt , highWord , lowWord, evtNumber , timeStamp , evtType , trigsFired)
if printTimestamps:
print "bufferPos, highWord , lowWord , event-number , timestamp , evtType = %x %016x %016x %08x %012x %01x %03x" % ( evt , highWord , lowWord, evtNumber , timeStamp , evtType , trigsFired)
tluEvtStruct.uBufpos = evt
tluEvtStruct.ulHighWord = highWord;
......
......@@ -23,6 +23,10 @@ TIMESPEC TS_sysclk = PERIOD "tnm_sysclk" 200 MHz;
# NET clocks/rst* TIG;
NET "I6/s_clk_is_xtal" TIG;
NET "I6/s_clock_status_ipb*" TIG;
NET "I6/s_logic_reset" TIG;
NET "I5/s_rst_fifo_ipb" TIG;
NET "leds_o[0]" LOC = D17;
NET "leds_o[0]" IOSTANDARD = LVCMOS25;
NET "leds_o[1]" LOC = AB4;
......
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