ROD firmware  1.0.5
ATLAS l1-calo - ROD_eFEX and ROD_jFEX firmware for the L1Calo ROD board

Back to ROD documentation
event_timer.vhd
1 ----------------------------------------------------------------------------------
2 -- Company:
3 -- Engineer:
4 --
5 -- Create Date: 03.03.2022 11:38:31
6 -- Design Name:
7 -- Module Name: event timer - RTL
8 -- Project Name:
9 -- Target Devices:
10 -- Tool Versions:
11 -- Description:
12 --
13 -- Dependencies:
14 --
15 -- Revision:
16 -- Revision 0.01 - File Created
17 -- Additional Comments:
18 --
19 ----------------------------------------------------------------------------------
20 
21 
22 library IEEE;
23 use IEEE.STD_LOGIC_1164.ALL;
24 use IEEE.STD_LOGIC_UNSIGNED.ALL;
25 
26 -- Uncomment the following library declaration if using
27 -- arithmetic functions with Signed or Unsigned values
28 --use IEEE.NUMERIC_STD.ALL;
29 
30 -- Uncomment the following library declaration if instantiating
31 -- any Xilinx leaf cells in this code.
32 --library UNISIM;
33 --use UNISIM.VComponents.all;
34 
35 entity event_timer is
36  generic ( start_state : std_logic_vector := x"12"; --read_ttc := x"02"; --start_reading
37  stop_state : std_logic_vector := x"11" --wait for event
38  );
39 
40  Port ( clock : in STD_LOGIC; --processor clock
41  reset : in STD_LOGIC; --reset from a pulse register or reset
42  current_state : in STD_LOGIC_vector (7 downto 0); --current_state of the processor
43 
44 
45  event_time : out std_logic_vector(15 downto 0) ; --duration of last event processing - route to ipbus register
46  watermark : out std_logic_vector(15 downto 0); --largest duration recorded - route to ipbus register
47  avg_time : out std_logic_vector(15 downto 0) --average duration of event processing - route to ipbus register
48  --total 30 bits can be connected to a single read-only register
49 
50  );
51 end event_timer;
52 
53 architecture RTL of event_timer is
54 
55 signal samp_0 : std_logic_vector(17 downto 0);
56 signal samp_1 : std_logic_vector(17 downto 0);
57 signal samp_2 : std_logic_vector(17 downto 0);
58 signal samp_3 : std_logic_vector(17 downto 0);
59 signal event_time_i : std_logic_vector(15 downto 0) := x"0000";
60 signal timer : std_logic_vector(16 downto 0);
61 signal watermark_i : std_logic_vector(15 downto 0) := x"0000";
62 signal run : std_logic := '0';
63 signal clr_timer : std_logic;
64 signal stop_timer : std_logic := '0';
65 signal start_timer : std_logic := '0';
66 signal stop_dly : std_logic := '0';
67 signal start_dly : std_logic := '0';
68 signal stop_pulse : std_logic ;
69 signal start_pulse : std_logic ;
70 signal samp_sum : std_logic_vector(17 downto 0) := 18x"00000";
71 --signal avg_time_i : std_logic_vector(9 downto 0) := 10x"000";
72 
73 begin
74 
75 
76 --start/stop pulses (processor may stay in state for multiple cycles
77 process (clock) begin
78  if rising_edge(clock) then
79  if (current_state = stop_state) then
80  stop_timer <= '1';
81  else
82  stop_timer <= '0';
83  end if;
84  end if;
85 end process;
86 
87  process (clock) begin
88  if rising_edge(clock) then
89  if (current_state = start_state) then
90  start_timer <= '1';
91  else
92  start_timer <= '0';
93  end if;
94  end if;
95 end process;
96 
97 process (clock) begin
98  if rising_edge(clock) then
99  start_dly <= start_timer;
100  stop_dly <= stop_timer;
101  end if;
102 end process;
103 
104 start_pulse <= start_timer and not start_dly;
105 stop_pulse <= stop_timer and not stop_dly;
106 
107 
108 
109 ---start/stop control -------
110 process (clock) begin
111  if rising_edge(clock) then
112  if (reset = '1') or (stop_pulse = '1') then
113  run <= '0';
114  elsif (start_pulse = '1') then
115  run <= '1';
116  else
117  run <= run;
118  end if;
119  end if;
120 end process;
121 
122 
123 
124 --Event duration counter/timer-----
125 process (clock) begin
126  if rising_edge(clock) then
127  if (reset = '1') or (stop_pulse = '1') then
128  timer <= (others => '0');
129  elsif (run = '1') and (timer /= x"1FFFF") then
130  timer <= (timer + 1);
131  else
132  timer <= timer;
133  end if;
134  end if;
135 end process;
136 
137 
138 process (clock) begin
139  if rising_edge(clock) then
140  if (reset = '1') then
141  event_time_i <= (others => '0');
142  samp_0 <= (others => '0');
143  samp_1 <= (others => '0');
144  samp_2 <= (others => '0');
145  samp_3 <= (others => '0');
146  elsif stop_pulse = '1' then
147  event_time_i <= timer(16 downto 1);
148  samp_0(15 downto 0) <= timer(16 downto 1);
149  samp_1 <= samp_0;
150  samp_2 <= samp_1;
151  samp_3 <= samp_2;
152  else
153  event_time_i <= event_time_i;
154  samp_0 <= samp_0;
155  samp_1 <= samp_1;
156  samp_2 <= samp_2;
157  samp_3 <= samp_3;
158  end if;
159  end if;
160  end process;
161 
162  event_time <= event_time_i;
163 
164 
165 ---record largest time taken
166 
167 process (clock) begin
168  if rising_edge(clock) then
169  if (reset = '1') then
170  watermark_i <= (others => '0');
171  elsif (stop_pulse = '1') and (timer(16 downto 1) > watermark_i) then
172  watermark_i <= timer(16 downto 1);
173  else
174  watermark_i <= watermark_i;
175  end if;
176  end if;
177 end process;
178 watermark <= watermark_i;
179 
180 
181 --calculate running average of last 4 events
182 
183 process (clock) begin
184  if rising_edge(clock) then
185  samp_sum <= (samp_0 + samp_1 + samp_2 + samp_3);
186  end if;
187 end process;
188 
189 --avg_time <= "00" & samp_sum(17 downto 2);
190 avg_time <= samp_sum(17 downto 2);
191 
192 
193 end RTL;