Merge pull request #81 from antonblanchard/logical
[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.common.all;
7
8 entity core_debug is
9 port (
10 clk : in std_logic;
11 rst : in std_logic;
12
13 dmi_addr : in std_ulogic_vector(3 downto 0);
14 dmi_din : in std_ulogic_vector(63 downto 0);
15 dmi_dout : out std_ulogic_vector(63 downto 0);
16 dmi_req : in std_ulogic;
17 dmi_wr : in std_ulogic;
18 dmi_ack : out std_ulogic;
19
20 -- Debug actions
21 core_stop : out std_ulogic;
22 core_rst : out std_ulogic;
23 icache_rst : out std_ulogic;
24
25 -- Core status inputs
26 terminate : in std_ulogic;
27 core_stopped : in std_ulogic;
28 nia : in std_ulogic_vector(63 downto 0);
29
30 -- Misc
31 terminated_out : out std_ulogic
32 );
33 end core_debug;
34
35 architecture behave of core_debug is
36 -- DMI needs fixing... make a one clock pulse
37 signal dmi_req_1: std_ulogic;
38
39 -- CTRL register (direct actions, write 1 to act, read back 0)
40 -- bit 0 : Core stop
41 -- bit 1 : Core reset (doesn't clear stop)
42 -- bit 2 : Icache reset
43 -- bit 3 : Single step
44 -- bit 4 : Core start
45 constant DBG_CORE_CTRL : std_ulogic_vector(3 downto 0) := "0000";
46 constant DBG_CORE_CTRL_STOP : integer := 0;
47 constant DBG_CORE_CTRL_RESET : integer := 1;
48 constant DBG_CORE_CTRL_ICRESET : integer := 2;
49 constant DBG_CORE_CTRL_STEP : integer := 3;
50 constant DBG_CORE_CTRL_START : integer := 4;
51
52 -- STAT register (read only)
53 -- bit 0 : Core stopping (wait til bit 1 set)
54 -- bit 1 : Core stopped
55 -- bit 2 : Core terminated (clears with start or reset)
56 constant DBG_CORE_STAT : std_ulogic_vector(3 downto 0) := "0001";
57 constant DBG_CORE_STAT_STOPPING : integer := 0;
58 constant DBG_CORE_STAT_STOPPED : integer := 1;
59 constant DBG_CORE_STAT_TERM : integer := 2;
60
61 -- NIA register (read only for now)
62 constant DBG_CORE_NIA : std_ulogic_vector(3 downto 0) := "0010";
63
64 -- Some internal wires
65 signal stat_reg : std_ulogic_vector(63 downto 0);
66
67 -- Some internal latches
68 signal stopping : std_ulogic;
69 signal do_step : std_ulogic;
70 signal do_reset : std_ulogic;
71 signal do_icreset : std_ulogic;
72 signal terminated : std_ulogic;
73
74 begin
75 -- Single cycle register accesses on DMI
76 dmi_ack <= dmi_req;
77
78 -- Status register read composition
79 stat_reg <= (2 => terminated,
80 1 => core_stopped,
81 0 => stopping,
82 others => '0');
83
84 -- DMI read data mux
85 with dmi_addr select dmi_dout <=
86 stat_reg when DBG_CORE_STAT,
87 nia when DBG_CORE_NIA,
88 (others => '0') when others;
89
90 -- DMI writes
91 reg_write: process(clk)
92 begin
93 if rising_edge(clk) then
94 -- Reset the 1-cycle "do" signals
95 do_step <= '0';
96 do_reset <= '0';
97 do_icreset <= '0';
98
99 if (rst) then
100 stopping <= '0';
101 terminated <= '0';
102 else
103 -- Edge detect on dmi_req for 1-shot pulses
104 dmi_req_1 <= dmi_req;
105 if dmi_req = '1' and dmi_req_1 = '0' then
106 if dmi_wr = '1' then
107 report("DMI write to " & to_hstring(dmi_addr));
108
109 -- Control register actions
110 if dmi_addr = DBG_CORE_CTRL then
111 if dmi_din(DBG_CORE_CTRL_RESET) = '1' then
112 do_reset <= '1';
113 terminated <= '0';
114 end if;
115 if dmi_din(DBG_CORE_CTRL_STOP) = '1' then
116 stopping <= '1';
117 end if;
118 if dmi_din(DBG_CORE_CTRL_STEP) = '1' then
119 do_step <= '1';
120 terminated <= '0';
121 end if;
122 if dmi_din(DBG_CORE_CTRL_ICRESET) = '1' then
123 do_icreset <= '1';
124 end if;
125 if dmi_din(DBG_CORE_CTRL_START) = '1' then
126 stopping <= '0';
127 terminated <= '0';
128 end if;
129 end if;
130 else
131 report("DMI read from " & to_string(dmi_addr));
132 end if;
133 end if;
134
135 -- Set core stop on terminate. We'll be stopping some time *after*
136 -- the offending instruction, at least until we can do back flushes
137 -- that preserve NIA which we can't just yet.
138 if terminate = '1' then
139 stopping <= '1';
140 terminated <= '1';
141 end if;
142 end if;
143 end if;
144 end process;
145
146 -- Core control signals generated by the debug module
147 core_stop <= stopping and not do_step;
148 core_rst <= do_reset;
149 icache_rst <= do_icreset;
150 terminated_out <= terminated;
151 end behave;
152