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

Back to ROD documentation
proc_trace.vhd
1 ----------------------------------------------------------------------------------
2 -- Company: University of Cambridge
3 -- Engineer: Ed Flaherty
4 --
5 -- Create Date: 01.03.2022 17:29:31
6 -- Design Name:
7 -- Module Name: proc_trace - 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 -- Trace Module for the TOB processor
20 -- This module can trace processor states leading up to various events
21  --Immediate trigger (capture is once, immediatly after arming)
22  --WD timer overflow (capture is continuous after arming until a WD overflow occurs.
23  --State Trigger (capture is continuous after arming until the specified processor state occurs)
24 -- The trace_data_out is the trace memory's output
25 
26 --Connect this module to 3 ipbus registers
27 --- pulse register for arm signals
28 --- read only register for armed and triggered status
29 --- read only register for trace data out
30 
31 
32 --when the trace data out register is read, the trace memory address is decremented to provide the data from one clock earlier.
33 --read the traced data register multiple times to see the trace for all of the cycles leading up to the trigger.
34 
35 
36 
37 
38 
39 
40 ----------------------------------------------------------------------------------
41 
42 
43 library IEEE;
44 use IEEE.STD_LOGIC_1164.ALL;
45 
46 -- Uncomment the following library declaration if using
47 -- arithmetic functions with Signed or Unsigned values
48 --use IEEE.NUMERIC_STD.ALL;
49 use IEEE.STD_LOGIC_UNSIGNED.ALL;
50 -- Uncomment the following library declaration if instantiating
51 -- any Xilinx leaf cells in this code.
52 --library UNISIM;
53 --use UNISIM.VComponents.all;
54 
55 entity proc_trace is
56  generic ( addr_width : integer := 8); --6 equates to 64 words of trace data
57  Port (
58 
59 
60  clock : in STD_LOGIC;
61  reset : in STD_LOGIC;
62  trace_input : in STD_LOGIC_VECTOR (23 downto 0); --connect to signals to be traced in addition to state
63  state : in STD_LOGIC_VECTOR (7 downto 0); --processor "state" plus any other signals to trace
64  trig_state : in STD_LOGIC_VECTOR (7 downto 0); --the state to trigger on
65  wd_event : in STD_LOGIC; --watchdog overflow signal
66  timeout_error : in STD_LOGIC; --one pp_clock cycle timeout error pulse
67 
68  arm_wd : in STD_LOGIC; --from ipbus pulse register
69  arm_immediate : in STD_LOGIC; --from ipbus pulse register
70  arm_state : in STD_LOGIC; --from ipbus pulse register
71  arm_timeout : in STD_LOGIC; --from ipbus pulse register
72 
73  armed : out STD_LOGIC; --status output to ipbus read register
74  triggered : out STD_LOGIC; --status output to ipbus read register
75 
76  read : in STD_LOGIC; --ipbus register read signal for the trace data out register(strobe and not we)
77  reset_pointer : in STD_LOGIC; --reset the read pointer to start at beginning of trace again
78  -- trace_data_out : out Std_logic_vector (31 downto 0); --trace data output to ipbus read register
79  addr_pointer : out std_logic_vector(addr_width-1 downto 0)
80 
81 
82 
83 
84  );
85 end proc_trace;
86 
87 architecture RTL of proc_trace is
88 
89 
90 --COMPONENT default_reg_ila
91 --
92 --PORT (
93 -- clk : IN STD_LOGIC;
94 -- probe0 : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
95 -- probe1 : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
96 -- probe2 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
97 -- probe3 : IN STD_LOGIC_VECTOR(0 DOWNTO 0)--;
98 --
99 --);
100 --END COMPONENT ;
101 
102 
103 
104 signal addr_pointer_i : Std_logic_vector (addr_width-1 downto 0);
105 signal pointer_snap : Std_logic_vector (15 downto 0);
106 signal trace_data_in : Std_logic_vector (31 downto 0);
107 
108 signal write : std_logic;
109 signal read_sync : std_logic;
110 signal read_dly : std_logic;
111 signal arm : std_logic;
112 signal armed_i : std_logic;
113 signal trigger : std_logic;
114 signal read_pulse : std_logic; --synced to clock from ipbus
115 signal arm_wd_sync : std_logic;
116 signal arm_wd_dly : std_logic;
117 signal armed_wd : std_logic;
118 signal arm_wd_pulse : std_logic;
119 
120 signal arm_timeout_sync : std_logic;
121 signal arm_timeout_dly : std_logic;
122 signal armed_timeout : std_logic;
123 signal arm_timeout_pulse : std_logic;
124 
125 
126 signal arm_state_sync : std_logic; --sync from ipbus clock to processor clock
127 signal arm_state_dly : std_logic;
128 signal arm_state_pulse : std_logic;
129 signal armed_state : std_logic;
130 signal triggered_state : std_logic;
131 signal trigger_state : std_logic;
132 --signal trig_state : std_logic;
133 
134 signal arm_imm_sync : std_logic; --sync from ipbus clock to processor clock
135 signal arm_imm_dly : std_logic;
136 signal arm_imm_pulse : std_logic;
137 signal armed_imm : std_logic;
138 signal triggered_imm : std_logic;
139 signal address_max : std_logic_vector(addr_width-1 downto 0);
140 
141 
142 signal armed_wd_dly : std_logic := '0';
143 signal armed_timeout_dly : std_logic := '0';
144 signal armed_state_dly : std_logic := '0';
145 signal armed_imm_dly : std_logic := '0';
146 signal triggered_dly : std_logic := '0';
147 signal save_pointer : std_logic := '0';
148 signal saved_pointer : Std_logic_vector (addr_width-1 downto 0);
149 
150 
151 
152 
153 begin
154 
155 
156 address_max <= (others => '1');
157 
158 arm <= arm_wd;
159 trigger <= wd_event;
160 write <= (armed_wd and not wd_event) or (armed_state and not trigger_state) or (armed_imm and not triggered_imm) or (armed_timeout and not timeout_error);
161 triggered <= not armed_i;
162 
163 armed_i <= armed_wd or armed_imm or armed_state or armed_timeout;
164 armed <= armed_i;
165 
166 
167 process (clock) begin
168  if rising_edge(clock) then
169  read_sync <= read; --sync from ipbus clock to processor clock
170  read_dly <= read_sync; --cread a delayed read_sync
171  end if;
172 end process;
173 
174 read_pulse <= not read_sync and read_dly; --falling edge of read_sync
175 
176 
177 
178 
179 process (clock) begin
180  if rising_edge(clock) then
181  if (reset_pointer = '1') then
182  addr_pointer_i <= saved_pointer;
183  elsif (reset = '1') or (arm_wd_pulse = '1') or (arm_imm_pulse = '1') or (arm_state_pulse = '1')or (arm_timeout_pulse = '1') then
184  addr_pointer_i <= (others => '0');
185  elsif write = '1' then
186  addr_pointer_i <= addr_pointer_i + 1;
187  elsif read_pulse = '1' then
188  addr_pointer_i <= addr_pointer_i - 1;
189  else
190  addr_pointer_i <= addr_pointer_i;
191  end if;
192  end if;
193 end process;
194 
195 addr_pointer <= addr_pointer_i;
196 
197 
198 
199 
200 --trace_data_in <= addr_pointer & x"00" & "00" & state(5 downto 0);
201 trace_data_in <= trace_input(23 downto 0) & "00" & state(5 downto 0);
202 
203 --trace_mem : trace_memory
204 -- PORT MAP (
205 -- a => addr_pointer(addr_width-1 downto 0),
206 -- d => trace_data_in,
207 -- clk => clock,
208 -- we => armed_i,
209 -- spo => trace_data_out
210 -- );
211 
212 
213 -- trace_mem : ipbus_dpram
214 -- PORT MAP (
215 -- addr => addr_pointer_i(addr_width-1 downto 0),
216 -- d => trace_data_in,
217 -- we => armed_i,
218 -- ipb_addr => ipb_addr,
219 -- ipb_rdata => ipb_rdata,
220 -- ipb_strobe => ipb_strobe,
221 -- ipb_write => ipb_write,
222 -- ipb_wdata => ipb_wdata,
223 -- ipb_ack => ipb_ack,
224 -- ipb_err => ipb_err,
225 
226 
227 -- clk => ipb_clk,
228  -- rst => reset,
229 -- ipb_in: in ipb_wbus;
230 -- ipb_out: out ipb_rbus;
231 -- rclk => clock,
232 -- q => trace_data_out
233 
234 
235 
236 -- );
237 
238 
239 ---Watchdog trigger controls -----
240 
241 process (clock) begin
242  if rising_edge(clock) then
243  arm_wd_sync <= arm_wd; --sync from ipbus clock to processor clock
244  arm_wd_dly <= arm_wd_sync; --cread a delayed arm_immediate_sync
245  end if;
246 end process;
247 arm_wd_pulse <= not arm_wd_sync and arm_wd_dly; --falling edge
248 
249 
250 
251 process (clock) begin
252  if rising_edge(clock) then
253  if (reset = '1') or ((wd_event = '1') and (armed_wd = '1')) then
254  armed_wd <= '0';
255  elsif arm_wd_pulse = '1' then
256  armed_wd <= '1';
257  else
258  armed_wd <= armed_wd;
259  end if;
260  end if;
261  end process;
262 
263 
264 ---Timeout trigger controls -----
265 process (clock) begin
266  if rising_edge(clock) then
267  arm_timeout_sync <= arm_timeout; --sync from ipbus clock to processor clock
268  arm_timeout_dly <= arm_timeout_sync; --cread a delayed arm_immediate_sync
269  end if;
270 end process;
271 arm_timeout_pulse <= not arm_timeout_sync and arm_timeout_dly; --falling edge
272 
273 process (clock) begin
274  if rising_edge(clock) then
275  if (reset = '1') or ((timeout_error = '1') and (armed_timeout = '1')) then
276  armed_timeout <= '0';
277  elsif arm_timeout_pulse = '1' then
278  armed_timeout <= '1';
279  else
280  armed_timeout <= armed_timeout;
281  end if;
282  end if;
283  end process;
284 
285 
286 
287 ----state trigger controls
288 process (clock) begin
289  if rising_edge(clock) then
290  arm_state_sync <= arm_state; --sync from ipbus clock to processor clock
291  arm_state_dly <= arm_state_sync; --create a delayed arm__sync
292  end if;
293 end process;
294 arm_state_pulse <= not arm_state_sync and arm_state_dly; --falling edge of arm__sync
295 
296 trigger_state <= '1' when (state = trig_state) else '0';
297 
298 process (clock) begin
299  if rising_edge(clock) then
300  if (reset = '1') or ((trigger_state = '1') and (armed_state = '1')) then
301  armed_state <= '0';
302  elsif arm_state_pulse = '1' then
303  armed_state <= '1';
304  else
305  armed_state <= armed_state;
306  end if;
307  end if;
308  end process;
309 
310 
311 
312 
313 
314 
315 ---immediate trigger controls; If user does arm_immediate, the memory first fills once and then troggers.
316 
317 process (clock) begin
318  if rising_edge(clock) then
319  arm_imm_sync <= arm_immediate; --sync from ipbus clock to processor clock
320  arm_imm_dly <= arm_imm_sync; --cread a delayed arm_immediate_sync
321  end if;
322 end process;
323 arm_imm_pulse <= not arm_imm_sync and arm_imm_dly; --falling edge of arm_imm_sync
324 
325 
326 process (clock) begin
327  if rising_edge(clock) then
328  if (reset = '1') or (triggered_imm = '1') then
329  armed_imm <= '0';
330 
331  elsif arm_imm_pulse = '1' then
332  -- pointer_snap <= addr_pointer - 1;
333  armed_imm <= '1';
334  else
335  -- pointer_snap <= pointer_snap;
336  armed_imm <= armed_imm;
337  end if;
338  end if;
339 
340 end process;
341 
342 
343  process (clock) begin
344  if rising_edge(clock) then
345  if ((reset = '1') or (arm_imm_sync = '1')) then
346  triggered_imm <= '0';
347 
348  -- elsif (addr_pointer(addr_width-1 downto 0) = pointer_snap(addr_width-1 downto 0)) then
349  -- elsif addr_pointer(addr_width-1 downto 0) = "111111" then
350  elsif addr_pointer_i(addr_width-1 downto 0) = address_max then
351  triggered_imm <= '1';
352  else
353  triggered_imm <= triggered_imm;
354  end if;
355  end if;
356 
357 end process;
358 
359 
360 
361 
362 
363 
364 
365  process (clock) begin
366  if rising_edge(clock) then
367  armed_wd_dly <= armed_wd;
368  armed_timeout_dly <= armed_timeout;
369  armed_state_dly <= armed_state;
370  armed_imm_dly <= armed_imm;
371 
372  end if;
373 end process;
374 
375 save_pointer <= (armed_wd_dly and not armed_wd) or (armed_state_dly and not armed_state) or (armed_imm_dly and not armed_imm) or (armed_timeout_dly and not armed_timeout) ;
376 
377 process (clock) begin
378  if rising_edge(clock) then
379  if save_pointer = '1' then
380  saved_pointer <= addr_pointer_i;
381  else
382  saved_pointer <= saved_pointer;
383  end if;
384  end if;
385 end process;
386 
387 --trigger_ila : default_reg_ila
388 --PORT MAP (
389 --clk => clock,
390 -- probe0(addr_width -1 downto 0) => addr_pointer_i, --32
391 -- probe0(31) => armed,
392 -- probe0(30 downto addr_width) => (others => '0'),
393 -- probe1(0) => arm_immediate, --3
394 -- probe1(31 downto 1) => (others => '0'),
395 -- probe2(0) => arm_imm_pulse,
396 -- probe3(0) => armed_imm
397 --);
398 
399 
400 
401 
402 
403 end RTL;