ignore /abc.history
[microwatt.git] / core_debug.vhdl
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4
5 library work;
6 use work.utils.all;
7 use work.common.all;
8 use work.wishbone_types.all;
9
10 entity core_debug is
11 generic (
12 -- Length of log buffer
13 LOG_LENGTH : natural := 512
14 );
15 port (
16 clk : in std_logic;
17 rst : in std_logic;
18
19 dmi_addr : in std_ulogic_vector(3 downto 0);
20 dmi_din : in std_ulogic_vector(63 downto 0);
21 dmi_dout : out std_ulogic_vector(63 downto 0);
22 dmi_req : in std_ulogic;
23 dmi_wr : in std_ulogic;
24 dmi_ack : out std_ulogic;
25
26 -- Debug actions
27 core_stop : out std_ulogic;
28 core_rst : out std_ulogic;
29 icache_rst : out std_ulogic;
30
31 -- Core status inputs
32 terminate : in std_ulogic;
33 core_stopped : in std_ulogic;
34 nia : in std_ulogic_vector(63 downto 0);
35 msr : in std_ulogic_vector(63 downto 0);
36 wb_snoop_in : in wishbone_master_out := wishbone_master_out_init;
37
38 -- GPR/FPR register read port
39 dbg_gpr_req : out std_ulogic;
40 dbg_gpr_ack : in std_ulogic;
41 dbg_gpr_addr : out gspr_index_t;
42 dbg_gpr_data : in std_ulogic_vector(63 downto 0);
43
44 -- SPR register read port for SPRs in execute1
45 dbg_spr_req : out std_ulogic;
46 dbg_spr_ack : in std_ulogic;
47 dbg_spr_addr : out std_ulogic_vector(7 downto 0);
48 dbg_spr_data : in std_ulogic_vector(63 downto 0);
49
50 -- SPR register read port for SPRs in loadstore1 and mmu
51 dbg_ls_spr_req : out std_ulogic;
52 dbg_ls_spr_ack : in std_ulogic;
53 dbg_ls_spr_addr : out std_ulogic_vector(1 downto 0);
54 dbg_ls_spr_data : in std_ulogic_vector(63 downto 0);
55
56 -- Core logging data
57 log_data : in std_ulogic_vector(255 downto 0);
58 log_read_addr : in std_ulogic_vector(31 downto 0);
59 log_read_data : out std_ulogic_vector(63 downto 0);
60 log_write_addr : out std_ulogic_vector(31 downto 0);
61
62 -- Misc
63 terminated_out : out std_ulogic
64 );
65 end core_debug;
66
67 architecture behave of core_debug is
68 -- DMI needs fixing... make a one clock pulse
69 signal dmi_req_1: std_ulogic;
70
71 -- CTRL register (direct actions, write 1 to act, read back 0)
72 -- bit 0 : Core stop
73 -- bit 1 : Core reset (doesn't clear stop)
74 -- bit 2 : Icache reset
75 -- bit 3 : Single step
76 -- bit 4 : Core start
77 constant DBG_CORE_CTRL : std_ulogic_vector(3 downto 0) := "0000";
78 constant DBG_CORE_CTRL_STOP : integer := 0;
79 constant DBG_CORE_CTRL_RESET : integer := 1;
80 constant DBG_CORE_CTRL_ICRESET : integer := 2;
81 constant DBG_CORE_CTRL_STEP : integer := 3;
82 constant DBG_CORE_CTRL_START : integer := 4;
83
84 -- STAT register (read only)
85 -- bit 0 : Core stopping (wait til bit 1 set)
86 -- bit 1 : Core stopped
87 -- bit 2 : Core terminated (clears with start or reset)
88 constant DBG_CORE_STAT : std_ulogic_vector(3 downto 0) := "0001";
89 constant DBG_CORE_STAT_STOPPING : integer := 0;
90 constant DBG_CORE_STAT_STOPPED : integer := 1;
91 constant DBG_CORE_STAT_TERM : integer := 2;
92
93 -- NIA register (read only for now)
94 constant DBG_CORE_NIA : std_ulogic_vector(3 downto 0) := "0010";
95
96 -- MSR (read only)
97 constant DBG_CORE_MSR : std_ulogic_vector(3 downto 0) := "0011";
98
99 -- GSPR register index
100 constant DBG_CORE_GSPR_INDEX : std_ulogic_vector(3 downto 0) := "0100";
101
102 -- GSPR register data
103 constant DBG_CORE_GSPR_DATA : std_ulogic_vector(3 downto 0) := "0101";
104
105 -- Log buffer address and data registers
106 constant DBG_CORE_LOG_ADDR : std_ulogic_vector(3 downto 0) := "0110";
107 constant DBG_CORE_LOG_DATA : std_ulogic_vector(3 downto 0) := "0111";
108 constant DBG_CORE_LOG_TRIGGER : std_ulogic_vector(3 downto 0) := "1000";
109 constant DBG_CORE_LOG_MTRIGGER : std_ulogic_vector(3 downto 0) := "1001";
110
111 constant LOG_INDEX_BITS : natural := log2(LOG_LENGTH);
112
113 -- Some internal wires
114 signal stat_reg : std_ulogic_vector(63 downto 0);
115
116 -- Some internal latches
117 signal stopping : std_ulogic;
118 signal do_step : std_ulogic;
119 signal do_reset : std_ulogic;
120 signal do_icreset : std_ulogic;
121 signal terminated : std_ulogic;
122 signal do_gspr_rd : std_ulogic;
123 signal gspr_index : std_ulogic_vector(7 downto 0);
124 signal gspr_data : std_ulogic_vector(63 downto 0);
125
126 signal spr_index_valid : std_ulogic;
127
128 signal log_dmi_addr : std_ulogic_vector(31 downto 0) := (others => '0');
129 signal log_dmi_data : std_ulogic_vector(63 downto 0) := (others => '0');
130 signal log_dmi_trigger : std_ulogic_vector(63 downto 0) := (others => '0');
131 signal log_mem_trigger : std_ulogic_vector(63 downto 0) := (others => '0');
132 signal do_log_trigger : std_ulogic := '0';
133 signal do_log_mtrigger : std_ulogic := '0';
134 signal trigger_was_log : std_ulogic := '0';
135 signal trigger_was_mem : std_ulogic := '0';
136 signal do_dmi_log_rd : std_ulogic;
137 signal dmi_read_log_data : std_ulogic;
138 signal dmi_read_log_data_1 : std_ulogic;
139 signal log_trigger_delay : integer range 0 to 255 := 0;
140
141 begin
142 -- Single cycle register accesses on DMI except for GSPR data
143 dmi_ack <= dmi_req when dmi_addr /= DBG_CORE_GSPR_DATA
144 else dbg_gpr_ack or dbg_spr_ack or dbg_ls_spr_ack;
145
146 -- Status register read composition
147 stat_reg <= (2 => terminated,
148 1 => core_stopped,
149 0 => stopping,
150 others => '0');
151
152 gspr_data <= dbg_gpr_data when gspr_index(5) = '0' else
153 dbg_ls_spr_data when dbg_ls_spr_req = '1' else
154 dbg_spr_data when spr_index_valid = '1' else
155 (others => '0');
156
157 -- DMI read data mux
158 with dmi_addr select dmi_dout <=
159 stat_reg when DBG_CORE_STAT,
160 nia when DBG_CORE_NIA,
161 msr when DBG_CORE_MSR,
162 gspr_data when DBG_CORE_GSPR_DATA,
163 log_write_addr & log_dmi_addr when DBG_CORE_LOG_ADDR,
164 log_dmi_data when DBG_CORE_LOG_DATA,
165 log_dmi_trigger when DBG_CORE_LOG_TRIGGER,
166 log_mem_trigger when DBG_CORE_LOG_MTRIGGER,
167 (others => '0') when others;
168
169 -- DMI writes
170 reg_write: process(clk)
171 begin
172 if rising_edge(clk) then
173 -- Reset the 1-cycle "do" signals
174 do_step <= '0';
175 do_reset <= '0';
176 do_icreset <= '0';
177 do_dmi_log_rd <= '0';
178
179 if (rst) then
180 stopping <= '0';
181 terminated <= '0';
182 log_trigger_delay <= 0;
183 gspr_index <= (others => '0');
184 log_dmi_addr <= (others => '0');
185 trigger_was_log <= '0';
186 trigger_was_mem <= '0';
187 else
188 if do_log_trigger = '1' or do_log_mtrigger = '1' or log_trigger_delay /= 0 then
189 if log_trigger_delay = 255 or
190 (LOG_LENGTH < 1024 and log_trigger_delay = LOG_LENGTH / 4) then
191 log_dmi_trigger(1) <= trigger_was_log;
192 log_mem_trigger(1) <= trigger_was_mem;
193 log_trigger_delay <= 0;
194 trigger_was_log <= '0';
195 trigger_was_mem <= '0';
196 else
197 log_trigger_delay <= log_trigger_delay + 1;
198 end if;
199 end if;
200 if do_log_trigger = '1' then
201 trigger_was_log <= '1';
202 end if;
203 if do_log_mtrigger = '1' then
204 trigger_was_mem <= '1';
205 end if;
206 -- Edge detect on dmi_req for 1-shot pulses
207 dmi_req_1 <= dmi_req;
208 if dmi_req = '1' and dmi_req_1 = '0' then
209 if dmi_wr = '1' then
210 report("DMI write to " & to_hstring(dmi_addr));
211
212 -- Control register actions
213 if dmi_addr = DBG_CORE_CTRL then
214 if dmi_din(DBG_CORE_CTRL_RESET) = '1' then
215 do_reset <= '1';
216 terminated <= '0';
217 end if;
218 if dmi_din(DBG_CORE_CTRL_STOP) = '1' then
219 stopping <= '1';
220 end if;
221 if dmi_din(DBG_CORE_CTRL_STEP) = '1' then
222 do_step <= '1';
223 terminated <= '0';
224 end if;
225 if dmi_din(DBG_CORE_CTRL_ICRESET) = '1' then
226 do_icreset <= '1';
227 end if;
228 if dmi_din(DBG_CORE_CTRL_START) = '1' then
229 stopping <= '0';
230 terminated <= '0';
231 end if;
232 elsif dmi_addr = DBG_CORE_GSPR_INDEX then
233 gspr_index <= dmi_din(7 downto 0);
234 elsif dmi_addr = DBG_CORE_LOG_ADDR then
235 log_dmi_addr <= dmi_din(31 downto 0);
236 do_dmi_log_rd <= '1';
237 elsif dmi_addr = DBG_CORE_LOG_TRIGGER then
238 log_dmi_trigger <= dmi_din;
239 elsif dmi_addr = DBG_CORE_LOG_MTRIGGER then
240 log_mem_trigger <= dmi_din;
241 end if;
242 else
243 report("DMI read from " & to_string(dmi_addr));
244 end if;
245
246 elsif dmi_read_log_data = '0' and dmi_read_log_data_1 = '1' then
247 -- Increment log_dmi_addr after the end of a read from DBG_CORE_LOG_DATA
248 log_dmi_addr(LOG_INDEX_BITS + 1 downto 0) <=
249 std_ulogic_vector(unsigned(log_dmi_addr(LOG_INDEX_BITS+1 downto 0)) + 1);
250 do_dmi_log_rd <= '1';
251 end if;
252 dmi_read_log_data_1 <= dmi_read_log_data;
253 if dmi_req = '1' and dmi_addr = DBG_CORE_LOG_DATA then
254 dmi_read_log_data <= '1';
255 else
256 dmi_read_log_data <= '0';
257 end if;
258
259 -- Set core stop on terminate. We'll be stopping some time *after*
260 -- the offending instruction, at least until we can do back flushes
261 -- that preserve NIA which we can't just yet.
262 if terminate = '1' then
263 stopping <= '1';
264 terminated <= '1';
265 end if;
266 end if;
267 end if;
268 end process;
269
270 gspr_access: process(clk)
271 variable valid : std_ulogic;
272 variable sel : spr_selector;
273 variable isram : std_ulogic;
274 variable raddr : ramspr_index;
275 variable odd : std_ulogic;
276 begin
277 if rising_edge(clk) then
278 dbg_gpr_req <= '0';
279 dbg_spr_req <= '0';
280 dbg_ls_spr_req <= '0';
281 if rst = '0' and dmi_req = '1' and dmi_addr = DBG_CORE_GSPR_DATA then
282 if gspr_index(5) = '0' then
283 dbg_gpr_req <= '1';
284 elsif gspr_index(4 downto 2) = "111" then
285 dbg_ls_spr_req <= '1';
286 else
287 dbg_spr_req <= '1';
288 end if;
289 end if;
290
291 -- Map 0 - 0x1f to GPRs, 0x20 - 0x3f to SPRs, and 0x40 - 0x5f to FPRs
292 dbg_gpr_addr <= gspr_index(6) & gspr_index(4 downto 0);
293 dbg_ls_spr_addr <= gspr_index(1 downto 0);
294
295 -- For SPRs, use the same mapping as when the fast SPRs were in the GPR file
296 valid := '1';
297 sel := "000";
298 isram := '1';
299 raddr := (others => '0');
300 odd := '0';
301 case gspr_index(4 downto 0) is
302 when 5x"00" =>
303 raddr := RAMSPR_LR;
304 when 5x"01" =>
305 odd := '1';
306 raddr := RAMSPR_CTR;
307 when 5x"02" | 5x"03" =>
308 odd := gspr_index(0);
309 raddr := RAMSPR_SRR0;
310 when 5x"04" | 5x"05" =>
311 odd := gspr_index(0);
312 raddr := RAMSPR_HSRR0;
313 when 5x"06" | 5x"07" =>
314 odd := gspr_index(0);
315 raddr := RAMSPR_SPRG0;
316 when 5x"08" | 5x"09" =>
317 odd := gspr_index(0);
318 raddr := RAMSPR_SPRG2;
319 when 5x"0a" | 5x"0b" =>
320 odd := gspr_index(0);
321 raddr := RAMSPR_HSPRG0;
322 when 5x"0c" =>
323 isram := '0';
324 sel := SPRSEL_XER;
325 when 5x"0d" =>
326 raddr := RAMSPR_TAR;
327 when others =>
328 valid := '0';
329 end case;
330 dbg_spr_addr <= isram & sel & std_ulogic_vector(raddr) & odd;
331 spr_index_valid <= valid;
332 end if;
333 end process;
334
335 -- Core control signals generated by the debug module
336 core_stop <= stopping and not do_step;
337 core_rst <= do_reset;
338 icache_rst <= do_icreset;
339 terminated_out <= terminated;
340
341 -- Logging RAM
342 maybe_log: if LOG_LENGTH > 0 generate
343 subtype log_ptr_t is unsigned(LOG_INDEX_BITS - 1 downto 0);
344 type log_array_t is array(0 to LOG_LENGTH - 1) of std_ulogic_vector(255 downto 0);
345 signal log_array : log_array_t;
346 signal log_rd_ptr : log_ptr_t;
347 signal log_wr_ptr : log_ptr_t;
348 signal log_toggle : std_ulogic;
349 signal log_wr_enable : std_ulogic;
350 signal log_rd_ptr_latched : log_ptr_t;
351 signal log_rd : std_ulogic_vector(255 downto 0);
352 signal log_dmi_reading : std_ulogic;
353 signal log_dmi_read_done : std_ulogic;
354
355 function select_dword(data : std_ulogic_vector(255 downto 0);
356 addr : std_ulogic_vector(31 downto 0)) return std_ulogic_vector is
357 variable firstbit : integer;
358 begin
359 assert not is_X(addr);
360 firstbit := to_integer(unsigned(addr(1 downto 0))) * 64;
361 return data(firstbit + 63 downto firstbit);
362 end;
363
364 attribute ram_style : string;
365 attribute ram_style of log_array : signal is "block";
366 attribute ram_decomp : string;
367 attribute ram_decomp of log_array : signal is "power";
368
369 begin
370 -- Use MSB of read addresses to stop the logging
371 log_wr_enable <= not (log_read_addr(31) or log_dmi_addr(31) or log_dmi_trigger(1) or log_mem_trigger(1));
372
373 log_ram: process(clk)
374 begin
375 if rising_edge(clk) then
376 if log_wr_enable = '1' then
377 assert not is_X(log_wr_ptr);
378 log_array(to_integer(log_wr_ptr)) <= log_data;
379 end if;
380 if is_X(log_rd_ptr_latched) then
381 log_rd <= (others => 'X');
382 else
383 log_rd <= log_array(to_integer(log_rd_ptr_latched));
384 end if;
385 end if;
386 end process;
387
388
389 log_buffer: process(clk)
390 variable b : integer;
391 variable data : std_ulogic_vector(255 downto 0);
392 begin
393 if rising_edge(clk) then
394 if rst = '1' then
395 log_wr_ptr <= (others => '0');
396 log_toggle <= '0';
397 log_rd_ptr_latched <= (others => '0');
398 elsif log_wr_enable = '1' then
399 if log_wr_ptr = to_unsigned(LOG_LENGTH - 1, LOG_INDEX_BITS) then
400 log_toggle <= not log_toggle;
401 end if;
402 log_wr_ptr <= log_wr_ptr + 1;
403 end if;
404 if do_dmi_log_rd = '1' then
405 log_rd_ptr_latched <= unsigned(log_dmi_addr(LOG_INDEX_BITS + 1 downto 2));
406 else
407 log_rd_ptr_latched <= unsigned(log_read_addr(LOG_INDEX_BITS + 1 downto 2));
408 end if;
409 if log_dmi_read_done = '1' then
410 log_dmi_data <= select_dword(log_rd, log_dmi_addr);
411 else
412 log_read_data <= select_dword(log_rd, log_read_addr);
413 end if;
414 log_dmi_read_done <= log_dmi_reading;
415 log_dmi_reading <= do_dmi_log_rd;
416 do_log_trigger <= '0';
417 if log_data(42) = log_dmi_trigger(63) and
418 log_data(41 downto 0) = log_dmi_trigger(43 downto 2) and
419 log_dmi_trigger(0) = '1' then
420 do_log_trigger <= '1';
421 end if;
422 do_log_mtrigger <= '0';
423 if (wb_snoop_in.cyc and wb_snoop_in.stb and wb_snoop_in.we) = '1' and
424 wb_snoop_in.adr = log_mem_trigger(wishbone_addr_bits + wishbone_log2_width - 1
425 downto wishbone_log2_width) and
426 log_mem_trigger(0) = '1' then
427 do_log_mtrigger <= '1';
428 end if;
429 end if;
430 end process;
431 log_write_addr(LOG_INDEX_BITS - 1 downto 0) <= std_ulogic_vector(log_wr_ptr);
432 log_write_addr(LOG_INDEX_BITS) <= '1';
433 log_write_addr(31 downto LOG_INDEX_BITS + 1) <= (others => '0');
434 end generate;
435
436 no_log: if LOG_LENGTH = 0 generate
437 begin
438 log_read_data <= (others => '0');
439 log_write_addr <= x"00000001";
440 end generate;
441
442 end behave;
443