Commit cd1b1bc7 authored by Alvaro Dosil's avatar Alvaro Dosil

fix bug from a combinational delay and synchronize fifos reset

parent 6e6ff933
......@@ -66,7 +66,8 @@ ENTITY eventBuffer IS
ipbus_reset_i : IN std_logic;
strobe_4x_logic_i : IN std_logic;
--trigger_count_i : IN std_logic_vector (g_IPBUS_WIDTH-1 DOWNTO 0); --! Not used yet.
buffer_full_o : OUT std_logic; --! Goes high when event buffer almost full
rst_fifo_o : OUT std_logic; --! rst signal to first level fifos
buffer_full_o : OUT std_logic; --! Goes high when event buffer almost full
ipbus_o : OUT ipb_rbus;
logic_reset_i : IN std_logic -- reset buffers when high. Synch withclk_4x_logic
);
......@@ -88,7 +89,7 @@ ARCHITECTURE rtl OF eventBuffer IS
signal s_fifo_fill_level : std_logic_vector(g_IPBUS_WIDTH-1 downto 0) := (others =>'0'); -- read-counter - 2*write_count
signal s_write_strobe : std_logic := '0';
signal s_rst_fifo : std_logic := '0'; -- ! Take high to reset FIFO pointers.
signal s_rst_fifo, s_rst_fifo_ipb : std_logic := '0'; -- ! Take high to reset FIFO pointers.
signal s_fifo_prog_full : std_logic := '0'; -- ! Controlled by programmable-full flag of FIFO core
signal s_fifo_rd_en : std_logic := '0'; -- ! Take high to clock data out of FIFO
signal s_fifo_dout : std_logic_vector(g_IPBUS_WIDTH-1 downto 0); -- ! Output from FIFO ( fall-through mode)
......@@ -113,7 +114,6 @@ BEGIN
--! 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_d1 when "01",
s_fifo_fill_level when "01",
s_fifo_status_ipb when "10",
(others => '1') when others;
......@@ -121,9 +121,9 @@ BEGIN
ipbus_write: process (ipbus_clk_i)
begin -- process ipbus_write
if rising_edge(ipbus_clk_i) then
s_rst_fifo <= '0';
s_rst_fifo_ipb <= '0';
if ipbus_i.ipb_strobe = '1' and ipbus_i.ipb_addr(1 downto 0) = "10" and ipbus_i.ipb_write = '1' then
s_rst_fifo <= '1';
s_rst_fifo_ipb <= '1';
end if;
-- Register data onto IPBus clock domain to ease timing closure.
......@@ -133,6 +133,9 @@ BEGIN
end if;
end process ipbus_write;
rst_fifo_o <= s_rst_fifo_ipb;
s_rst_fifo <= s_rst_fifo_ipb or logic_reset_i;
-----------------------------------------------------------------------------
-- FIFO and fill-level calculation
-----------------------------------------------------------------------------
......
......@@ -67,7 +67,9 @@ ENTITY eventFormatter IS
ipbus_clk_i : IN std_logic;
logic_strobe_i : IN std_logic; -- ! Pulses high once every 4 cycles of clk_4x_logic
logic_reset_i : IN std_logic; -- goes high to reset counters. Synchronous with clk_4x_logic
rst_fifo_i : IN std_logic; --! Reset fifos
buffer_full_i : IN std_logic; -- Buffer full signal from main buffer
trigger_i : IN std_logic; --! goes high to load trigger data. One cycle of clk_4x_logic
trigger_times_i : IN t_triggerTimeArray (g_NUM_TRIG_INPUTS-1 DOWNTO 0); -- Array of trigger times ( w.r.t. logic_strobe)
trigger_inputs_fired_i : IN std_logic_vector (g_NUM_TRIG_INPUTS-1 DOWNTO 0); -- high for each input that "fired"
......@@ -137,6 +139,7 @@ ARCHITECTURE rtl OF eventFormatter IS
signal s_FIFO_rd_d2 : std_logic_vector(3+g_NUM_EDGE_INPUTS-1 downto 0) := (others=>'0'); -- FIFO read signals delayed
signal s_FIFO_rd_mask : unsigned(3+g_NUM_EDGE_INPUTS-1 downto 0) := (0 =>'1',others=>'0'); --(3+g_NUM_EDGE_INPUTS-1 =>'1',others=>'0'); -- FIFO read mask
signal s_FIFO_empty : std_logic_vector(3+g_NUM_EDGE_INPUTS-1 downto 0) := (others=>'0'); -- FIFO empty signals
signal s_FIFO_full : std_logic_vector(3+g_NUM_EDGE_INPUTS-1 downto 0) := (others=>'0'); -- FIFO full signals
signal s_FIFO_i : t_fifo_io(3+g_NUM_EDGE_INPUTS-1 downto 0) :=(others=>(others=>'0')); -- FIFO input data
signal s_FIFO_o : t_fifo_io(3+g_NUM_EDGE_INPUTS-1 downto 0) :=(others=>(others=>'0')); -- FIFO output data
......@@ -216,17 +219,45 @@ BEGIN
end process p_signals_clk_domain;
-- purpose: generate delayed strobes, generate event types and write enable flags to the FIFOs
-- purpose: generate delayed strobes and write enable flags to the FIFOs
-- type : combinational
-- inputs : clk_4x_logic_i , s_FIFO_rd
-- outputs: s_event_strobe_d1 , s_event_strobe_d2 , s_event_strobe_d3 , s_FIFO_rd_d , s_**_evttype
p_reg: process (clk_4x_logic_i)
p_ff_rst: process (clk_4x_logic_i)
begin -- process p_generate_strobes
if rising_edge(clk_4x_logic_i) then
s_event_strobe_d1 <= trigger_i and s_enable_trigger;
if rst_fifo_i = '1' then
s_event_strobe_d1 <= '0';
s_event_strobe_d2 <= '0';
s_event_strobe_d3 <= '0';
shutter_i_d1 <= '0';
shutter_i_d2 <= '0';
spill_i_d1 <= '0';
spill_i_d2 <= '0';
s_FIFO_rd_d1 <= (others=>'0');
s_FIFO_rd_d2 <= (others=>'0');
elsif rising_edge(clk_4x_logic_i) then
s_event_strobe_d1 <= trigger_i and s_enable_trigger and not s_FIFO_full(0);
s_event_strobe_d2 <= s_event_strobe_d1;
s_event_strobe_d3 <= s_event_strobe_d2;
shutter_i_d1 <= shutter_i and s_enable_shutter and not s_FIFO_full(1);
shutter_i_d2 <= shutter_i_d1;
spill_i_d1 <= spill_i and s_enable_spill and not s_FIFO_full(3+g_NUM_EDGE_INPUTS-1);
spill_i_d2 <= spill_i_d1;
s_FIFO_rd_d1 <= s_FIFO_rd;
s_FIFO_rd_d2 <= s_FIFO_rd_d1;
end if;
end process p_ff_rst;
p_ff: process (clk_4x_logic_i)
begin -- process p_generate_strobes
if rising_edge(clk_4x_logic_i) then
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;
......@@ -239,25 +270,15 @@ BEGIN
s_word2_d2 <= s_word2_d1;
s_word2_d3 <= s_word2_d2;
s_FIFO_rd_d1 <= s_FIFO_rd;
s_FIFO_rd_d2 <= s_FIFO_rd_d1;
shutter_i_d1 <= shutter_i and s_enable_shutter;
shutter_i_d2 <= shutter_i_d1;
spill_i_d1 <= spill_i and s_enable_spill;
spill_i_d2 <= spill_i_d1;
s_coarse_timestamp_l_d1 <= s_coarse_timestamp_l;
s_coarse_timestamp_l_d2 <= s_coarse_timestamp_l_d1;
s_coarse_timestamp_l_d3 <= s_coarse_timestamp_l_d2;
s_coarse_timestamp_h_d1 <= s_coarse_timestamp_h;
s_coarse_timestamp_h_d2 <= s_coarse_timestamp_h_d1;
s_coarse_timestamp_h_d3 <= s_coarse_timestamp_h_d2;
end if;
end process p_reg;
end if;
end process;
-- If there are more than 4 trigger inputs we need to fill a second word.
-- .. do this by having an optional strobe.
-- If 4 or fewer trigger inputs, just leave s_event_strobe_d3_opt at zero..
......@@ -293,22 +314,30 @@ BEGIN
--! Could also output data on trigger_i , but let's use the delayed signals. \n
--! The counters are one cycle delayed from the signal generation
s_FIFO_i(0) <= s_word0_d1 when (s_event_strobe_d1 = '1') else
s_word1_d2 when (s_event_strobe_d2 = '1') else
s_word2_d3 when (s_event_strobe_d3_opt = '1') else
(others => '0');
--! If there is data in the FIFO output we put the strobe signal at high level.
s_FIFO_wr(0) <= s_event_strobe_d1 or s_event_strobe_d2 or s_event_strobe_d3_opt;
p_fifo_i : process (clk_4x_logic_i)
begin
if rising_edge(clk_4x_logic_i) then
s_FIFO_wr(0) <= s_event_strobe_d1 or s_event_strobe_d2 or s_event_strobe_d3_opt;
s_FIFO_wr(1) <= shutter_i_d1 xor shutter_i_d2;
if s_event_strobe_d1 = '1' then
s_FIFO_i(0) <= s_word0_d1;
elsif s_event_strobe_d2 = '1' then
s_FIFO_i(0) <= s_word1_d2;
elsif s_event_strobe_d3_opt = '1' then
s_FIFO_i(0) <= s_word2_d3;
else
s_FIFO_i(0) <= (others=>'0');
end if;
end if;
end process;
s_evttype(1) <= "0011" when shutter_i_d1 = '1' and shutter_i_d2 = '0' else
"0010" when shutter_i_d1 = '0' and shutter_i_d2 = '1' else
(others=>'0');
s_var(1) <= shutter_cnt_i;
edge_formatting : for i in 0 to (g_NUM_EDGE_INPUTS-1) generate
s_FIFO_wr(i+2) <= (edge_rise_i(i) or edge_fall_i(i)) and s_enable_edges(i);
s_evttype(i+2) <= "0101" when edge_rise_i(i) = '1' else
"0100" when edge_fall_i(i) = '1' else
(others=>'0');
......@@ -317,21 +346,44 @@ BEGIN
(others=>'0');
end generate;
-- The spill signal has to be the last signal to give it the lowest priority to save
s_FIFO_wr(3+g_NUM_EDGE_INPUTS-1) <= spill_i_d1 xor spill_i_d2;
s_evttype(3+g_NUM_EDGE_INPUTS-1) <= "0111" when spill_i_d1 = '1' and spill_i_d2 = '0' else
"0110" when spill_i_d1 = '0' and spill_i_d2 = '1' else
(others=>'0');
s_var(3+g_NUM_EDGE_INPUTS-1) <= spill_cnt_i;
-------------------------------------------------------------------------------
-- Data event formater and types
-------------------------------------------------------------------------------
p_fifo_wr : process (clk_4x_logic_i)
begin
if rising_edge(clk_4x_logic_i) then
s_FIFO_wr(1) <= shutter_i_d1 xor shutter_i_d2;
s_FIFO_wr(3+g_NUM_EDGE_INPUTS-1) <= spill_i_d1 xor spill_i_d2;
end if;
end process;
gen_fifo_wr_edge : for i in 0 to (g_NUM_EDGE_INPUTS-1) generate
p_fifo_wr : process (clk_4x_logic_i)
begin
if rising_edge(clk_4x_logic_i) then
s_FIFO_wr(i+2) <= (edge_rise_i(i) or edge_fall_i(i)) and s_enable_edges(i) and not s_FIFO_full(i+2);
end if;
end process;
end generate;
gen_FIFO_i : for i in 1 to 3+g_NUM_EDGE_INPUTS-1 generate
--s_FIFO_i(i) <= s_evttype(i) & s_var(i) & std_logic_vector(s_coarse_timestamp_d2);
s_FIFO_i(i) <= s_evttype(i) & s_var(i) & std_logic_vector(s_coarse_timestamp_h_d2) & std_logic_vector(s_coarse_timestamp_l_d2);
gen_FIFO_i : for i in 1 to 3+g_NUM_EDGE_INPUTS-1 generate
p_fifo_i_n : process (clk_4x_logic_i)
begin
if rising_edge(clk_4x_logic_i) then
s_FIFO_i(i) <= s_evttype(i) & s_var(i) & std_logic_vector(s_coarse_timestamp_h_d2) & std_logic_vector(s_coarse_timestamp_l_d2);
end if;
end process;
end generate gen_FIFO_i;
-------------------------------------------------------------------------------
-- first level of FIFOs
-------------------------------------------------------------------------------
gen_FIFOs : for i in 0 to 3+g_NUM_EDGE_INPUTS-1 generate
begin
......@@ -339,12 +391,13 @@ BEGIN
FIFO_i : entity work.FIFO
PORT MAP (
clk => clk_4x_logic_i,
rst => logic_reset_i,
rst => rst_fifo_i, --logic_reset_i,
din => s_FIFO_i(i),
wr_en => s_FIFO_wr(i),
rd_en => s_FIFO_rd(i),
dout => s_FIFO_o(i),
full => open,
prog_full => s_FIFO_full(i),
empty => s_FIFO_empty(i)
);
......@@ -360,15 +413,17 @@ BEGIN
-- Mux to send the read signal to only one FIFO. Priority order: trigger, shutter, edge, spill
-- every trigger word will be read before jump to other data
p_FIFO_rd: process (s_FIFO_empty,s_FIFO_rd_mask)
p_FIFO_rd: process (rst_fifo_i, s_FIFO_empty,s_FIFO_rd_mask, buffer_full_i)
begin -- process p_generate_strobes
s_FIFO_rd <= (others=>'0');
l_FIFO_rd: for i in 0 to 3+g_NUM_EDGE_INPUTS-1 loop
if s_FIFO_empty(i) = '0' then
s_FIFO_rd <= std_logic_vector(s_FIFO_rd_mask sll i);
exit l_FIFO_rd;
end if;
end loop;
if buffer_full_i = '0' and rst_fifo_i = '0' then
l_FIFO_rd: for i in 0 to 3+g_NUM_EDGE_INPUTS-1 loop
if s_FIFO_empty(i) = '0' then
s_FIFO_rd <= std_logic_vector(s_FIFO_rd_mask sll i);
exit l_FIFO_rd;
end if;
end loop;
end if;
end process;
......
......@@ -138,7 +138,8 @@ ARCHITECTURE struct OF top_extphy IS
SIGNAL overall_trigger : std_logic; --! goes high to load trigger data
SIGNAL overall_veto : std_logic; --! Halts triggers when high
SIGNAL postVeto_trigger_times : t_triggerTimeArray(g_NUM_TRIG_INPUTS-1 DOWNTO 0); -- ! trigger arrival time ( w.r.t. logic_strobe)
SIGNAL s_AIDAhandshake : std_logic;
SIGNAL s_rst_buffer : std_logic;
SIGNAL s_AIDAhandshake : std_logic;
SIGNAL s_i2c_scl_enb : std_logic;
SIGNAL s_i2c_sda_enb : std_logic;
SIGNAL shutter_cnt_i : std_logic_vector(g_SPILL_COUNTER_WIDTH-1 DOWNTO 0);
......@@ -227,7 +228,8 @@ ARCHITECTURE struct OF top_extphy IS
ipbus_reset_i : IN std_logic ;
strobe_4x_logic_i : IN std_logic ;
--trigger_count_i : IN std_logic_vector (g_IPBUS_WIDTH-1 DOWNTO 0); --! Not used yet.
buffer_full_o : OUT std_logic ; --! Goes high when event buffer almost full
rst_fifo_o : OUT std_logic; --! rst signal to first level fifos
buffer_full_o : OUT std_logic ; --! Goes high when event buffer almost full
ipbus_o : OUT ipb_rbus ;
logic_reset_i : IN std_logic -- reset buffers when high. Synch withclk_4x_logic
);
......@@ -248,7 +250,9 @@ ARCHITECTURE struct OF top_extphy IS
ipbus_clk_i : IN std_logic ;
logic_strobe_i : IN std_logic ; -- ! Pulses high once every 4 cycles of clk_4x_logic
logic_reset_i : IN std_logic ; -- goes high TO reset counters. Synchronous with clk_4x_logic
trigger_i : IN std_logic ; --! goes high TO load trigger data. One cycle of clk_4x_logic
rst_fifo_i : IN std_logic; --! Reset fifos
buffer_full_i : IN std_logic; -- Buffer full signal from main buffer
trigger_i : IN std_logic ; --! goes high TO load trigger data. One cycle of clk_4x_logic
trigger_times_i : IN t_triggerTimeArray (g_NUM_TRIG_INPUTS-1 DOWNTO 0); -- Array of trigger times ( w.r.t. logic_strobe)
trigger_inputs_fired_i : IN std_logic_vector (g_NUM_TRIG_INPUTS-1 DOWNTO 0); -- high for each input that "fired"
trigger_cnt_i : IN std_logic_vector (g_COUNTER_TRIG_WIDTH-1 DOWNTO 0);
......@@ -260,7 +264,7 @@ ARCHITECTURE struct OF top_extphy IS
edge_fall_i : IN std_logic_vector (g_NUM_EDGE_INPUTS-1 DOWNTO 0); -- ! High when falling edge
edge_rise_time_i : IN t_triggerTimeArray (g_NUM_EDGE_INPUTS-1 DOWNTO 0); -- Array of edge times ( w.r.t. logic_strobe)
edge_fall_time_i : IN t_triggerTimeArray (g_NUM_EDGE_INPUTS-1 DOWNTO 0); -- Array of edge times ( w.r.t. logic_strobe)
ipbus_i : IN ipb_wbus ;
ipbus_i : IN ipb_wbus ;
ipbus_o : OUT ipb_rbus ;
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);
......@@ -413,7 +417,7 @@ BEGIN
shutter_cnt_i <= (OTHERS => '0');
-- ModuleWare code(v1.12) for instance 'I8' of 'sor'
overall_veto <= '0';--buffer_full_o OR veto_o;
overall_veto <= buffer_full_o; -- OR veto_o;
-- Instance port mappings.
I0 : DUTInterfaces
......@@ -484,6 +488,7 @@ BEGIN
ipbus_reset_i => ipbus_reset,
strobe_4x_logic_i => strobe_4x_logic,
--trigger_count_i => trigger_count,
rst_fifo_o => s_rst_buffer,
buffer_full_o => buffer_full_o,
ipbus_o => ipbr(3),
logic_reset_i => logic_reset or reset_i
......@@ -504,9 +509,11 @@ BEGIN
ipbus_clk_i => ipbus_clk,
logic_strobe_i => strobe_4x_logic,
logic_reset_i => logic_reset or reset_i,
rst_fifo_i => s_rst_buffer,
buffer_full_i => buffer_full_o,
trigger_i => overall_trigger,
trigger_times_i => postVeto_trigger_times,
trigger_inputs_fired_i => postVeto_triggers, --triggers,
trigger_inputs_fired_i => postVeto_triggers,
trigger_cnt_i => trigger_cnt_i,
shutter_i => shutter_i,
shutter_cnt_i => shutter_cnt_i,
......
......@@ -117,12 +117,14 @@ board.write("Enable_Record_Data",1)
print "Enabling handshake: No-handshake"
board.write("HandshakeTypeW",1)
TriggerInterval = 1000
TriggerInterval = 160
board.write("InternalTriggerIntervalW",TriggerInterval) #0->Internal pulse generator disabled. Any other value will generate pulses with a frequency of n*6.25ns
#sys.exit(0)
n=60000 #number of measurements
f=open("data/data.dat",'w')
n=600000 #number of measurements
data={"EvtType":[],"InputTrig":[],"CoarseTS":[],"FineTS0":[],"FineTS1":[],"FineTS2":[],"FineTS3":[],"EvtNumber":[], "TS":[]}
read=range(4)
trigger_old=0
......@@ -130,9 +132,11 @@ i=0
while i<n:
PostVetoTrig = board.read("PostVetoTriggersR")
if PostVetoTrig!=trigger_old:
for j in range(4):
read[j] = board.read("EventFifoData")
trigger_old = PostVetoTrig
f.write("word "+str(hex(i))+"\n")
for j in range(4):
read[j] = board.read("EventFifoData")
f.write(str(hex(read[j]))+"\n")
trigger_old = PostVetoTrig
else: continue
data["EvtType"].append(read[0] >> 28)
data["InputTrig"].append((read[0]&0xfff0000)>>16)
......@@ -142,6 +146,8 @@ while i<n:
data["FineTS2"].append(read[2]>>8 & 0xff)
data["FineTS3"].append(read[2] & 0xff)
data["EvtNumber"].append(read[3])
#if read[3]&0x84000000!=0: sys.exit(0)
if data["InputTrig"][i]==0x800:
data["TS"].append(data["CoarseTS"][i]*25+(data["FineTS0"][i]>>3)*6.25+(data["FineTS0"][i]&0x7)*0.781)
elif data["InputTrig"][i]==0x400:
......@@ -160,9 +166,13 @@ while i<n:
if TriggerInterval==0 and data["EvtType"][i]==0:
print "Error!!! internal trigger detected!"
if TriggerInterval!=0 and data["EvtType"][i]!=0:
print "Error!!! external trigger detected!"
time.sleep(.05)
print "Error!!! external trigger detected!",
print hex(data["InputTrig"][i]), "EvtNumber:",data["EvtNumber"][i]
#time.sleep(.05)
#if i%100000==0: board.write("EventFifoCSR",0x2)
i+=1
f.close()
meanVal=0
if len(data["TS"])<500:
......@@ -170,7 +180,7 @@ if len(data["TS"])<500:
else:
meanVal=mean(data["TS"][0:500])
print meanVal
plotWidth=10
plotWidth=100
hTS = TH1D("hTS", "hTS", int(plotWidth/0.78), meanVal-plotWidth/2., meanVal+plotWidth/2.)
hFineTS0 = TH1D("hFineTS0", "hFineTS0", 8, 0, 8)
......@@ -181,7 +191,7 @@ h6TS0 = TH1D("h6TS3","h6TS0",4,0,4)
h6TS1 = TH1D("h6TS3","h6TS1",4,0,4)
h6TS2 = TH1D("h6TS3","h6TS2",4,0,4)
h6TS3 = TH1D("h6TS3","h6TS3",4,0,4)
hEvtNumber = TH1D("hEvtNumber", "hEvtNumber", 5, -1, 4)
hEvtNumber = TH1D("hEvtNumber", "hEvtNumber", 11, -1, 10)
hTS.GetXaxis().SetTitle("#Delta Time stamp [ns]")
hTS.GetYaxis().SetTitle("#events")
......
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