begin working on linux verilator simulation
[microwatt.git] / pmu.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 use work.decode_types.all;
8
9 entity pmu is
10 port (
11 clk : in std_ulogic;
12 rst : in std_ulogic;
13 p_in : in Execute1ToPMUType;
14 p_out : out PMUToExecute1Type
15 );
16 end entity pmu;
17
18 architecture behaviour of pmu is
19
20 -- MMCR0 bit numbers
21 constant MMCR0_FC : integer := 63 - 32;
22 constant MMCR0_FCS : integer := 63 - 33;
23 constant MMCR0_FCP : integer := 63 - 34;
24 constant MMCR0_FCM1 : integer := 63 - 35;
25 constant MMCR0_FCM0 : integer := 63 - 36;
26 constant MMCR0_PMAE : integer := 63 - 37;
27 constant MMCR0_FCECE : integer := 63 - 38;
28 constant MMCR0_TBSEL : integer := 63 - 40;
29 constant MMCR0_TBEE : integer := 63 - 41;
30 constant MMCR0_BHRBA : integer := 63 - 42;
31 constant MMCR0_EBE : integer := 63 - 43;
32 constant MMCR0_PMCC : integer := 63 - 45;
33 constant MMCR0_PMC1CE : integer := 63 - 48;
34 constant MMCR0_PMCjCE : integer := 63 - 49;
35 constant MMCR0_TRIGGER : integer := 63 - 50;
36 constant MMCR0_FCPC : integer := 63 - 51;
37 constant MMCR0_PMAQ : integer := 63 - 52;
38 constant MMCR0_PMCCEXT : integer := 63 - 54;
39 constant MMCR0_CC56RUN : integer := 63 - 55;
40 constant MMCR0_PMAO : integer := 63 - 56;
41 constant MMCR0_FC1_4 : integer := 63 - 58;
42 constant MMCR0_FC5_6 : integer := 63 - 59;
43 constant MMCR0_FC1_4W : integer := 63 - 62;
44
45 -- MMCR2 bit numbers
46 constant MMCR2_FC0S : integer := 63 - 0;
47 constant MMCR2_FC0P0 : integer := 63 - 1;
48 constant MMCR2_FC0M1 : integer := 63 - 3;
49 constant MMCR2_FC0M0 : integer := 63 - 4;
50 constant MMCR2_FC0WAIT : integer := 63 - 5;
51 constant MMCR2_FC1S : integer := 54 - 0;
52 constant MMCR2_FC1P0 : integer := 54 - 1;
53 constant MMCR2_FC1M1 : integer := 54 - 3;
54 constant MMCR2_FC1M0 : integer := 54 - 4;
55 constant MMCR2_FC1WAIT : integer := 54 - 5;
56 constant MMCR2_FC2S : integer := 45 - 0;
57 constant MMCR2_FC2P0 : integer := 45 - 1;
58 constant MMCR2_FC2M1 : integer := 45 - 3;
59 constant MMCR2_FC2M0 : integer := 45 - 4;
60 constant MMCR2_FC2WAIT : integer := 45 - 5;
61 constant MMCR2_FC3S : integer := 36 - 0;
62 constant MMCR2_FC3P0 : integer := 36 - 1;
63 constant MMCR2_FC3M1 : integer := 36 - 3;
64 constant MMCR2_FC3M0 : integer := 36 - 4;
65 constant MMCR2_FC3WAIT : integer := 36 - 5;
66 constant MMCR2_FC4S : integer := 27 - 0;
67 constant MMCR2_FC4P0 : integer := 27 - 1;
68 constant MMCR2_FC4M1 : integer := 27 - 3;
69 constant MMCR2_FC4M0 : integer := 27 - 4;
70 constant MMCR2_FC4WAIT : integer := 27 - 5;
71 constant MMCR2_FC5S : integer := 18 - 0;
72 constant MMCR2_FC5P0 : integer := 18 - 1;
73 constant MMCR2_FC5M1 : integer := 18 - 3;
74 constant MMCR2_FC5M0 : integer := 18 - 4;
75 constant MMCR2_FC5WAIT : integer := 18 - 5;
76 constant MMCR2_FC6S : integer := 9 - 0;
77 constant MMCR2_FC6P0 : integer := 9 - 1;
78 constant MMCR2_FC6M1 : integer := 9 - 3;
79 constant MMCR2_FC6M0 : integer := 9 - 4;
80 constant MMCR2_FC6WAIT : integer := 9 - 5;
81
82 -- MMCRA bit numbers
83 constant MMCRA_TECX : integer := 63 - 36;
84 constant MMCRA_TECM : integer := 63 - 44;
85 constant MMCRA_TECE : integer := 63 - 47;
86 constant MMCRA_TS : integer := 63 - 51;
87 constant MMCRA_TE : integer := 63 - 55;
88 constant MMCRA_ES : integer := 63 - 59;
89 constant MMCRA_SM : integer := 63 - 62;
90 constant MMCRA_SE : integer := 63 - 63;
91
92 -- SIER bit numbers
93 constant SIER_SAMPPR : integer := 63 - 38;
94 constant SIER_SIARV : integer := 63 - 41;
95 constant SIER_SDARV : integer := 63 - 42;
96 constant SIER_TE : integer := 63 - 43;
97 constant SIER_SITYPE : integer := 63 - 48;
98 constant SIER_SICACHE : integer := 63 - 51;
99 constant SIER_SITAKBR : integer := 63 - 52;
100 constant SIER_SIMISPR : integer := 63 - 53;
101 constant SIER_SIMISPRI : integer := 63 - 55;
102 constant SIER_SIDERAT : integer := 63 - 56;
103 constant SIER_SIDAXL : integer := 63 - 59;
104 constant SIER_SIDSAI : integer := 63 - 62;
105 constant SIER_SICMPL : integer := 63 - 63;
106
107 type pmc_array is array(1 to 6) of std_ulogic_vector(31 downto 0);
108 signal pmcs : pmc_array;
109 signal mmcr0 : std_ulogic_vector(31 downto 0);
110 signal mmcr1 : std_ulogic_vector(63 downto 0);
111 signal mmcr2 : std_ulogic_vector(63 downto 0);
112 signal mmcra : std_ulogic_vector(63 downto 0);
113 signal siar : std_ulogic_vector(63 downto 0);
114 signal sdar : std_ulogic_vector(63 downto 0);
115 signal sier : std_ulogic_vector(63 downto 0);
116
117 signal doinc : std_ulogic_vector(1 to 6);
118 signal doalert : std_ulogic;
119 signal doevent : std_ulogic;
120
121 signal prev_tb : std_ulogic_vector(3 downto 0);
122
123 begin
124 -- mfspr mux
125 with p_in.spr_num(3 downto 0) select p_out.spr_val <=
126 32x"0" & pmcs(1) when "0011",
127 32x"0" & pmcs(2) when "0100",
128 32x"0" & pmcs(3) when "0101",
129 32x"0" & pmcs(4) when "0110",
130 32x"0" & pmcs(5) when "0111",
131 32x"0" & pmcs(6) when "1000",
132 32x"0" & mmcr0 when "1011",
133 mmcr1 when "1110",
134 mmcr2 when "0001",
135 mmcra when "0010",
136 siar when "1100",
137 sdar when "1101",
138 sier when "0000",
139 64x"0" when others;
140
141 p_out.intr <= mmcr0(MMCR0_PMAO);
142
143 pmu_1: process(clk)
144 begin
145 if rising_edge(clk) then
146 if rst = '1' then
147 mmcr0 <= 32x"80000000";
148 else
149 for i in 1 to 6 loop
150 if p_in.mtspr = '1' and to_integer(unsigned(p_in.spr_num(3 downto 0))) = i + 2 then
151 pmcs(i) <= p_in.spr_val(31 downto 0);
152 elsif doinc(i) = '1' then
153 pmcs(i) <= std_ulogic_vector(unsigned(pmcs(i)) + 1);
154 end if;
155 end loop;
156 if p_in.mtspr = '1' and p_in.spr_num(3 downto 0) = "1011" then
157 mmcr0 <= p_in.spr_val(31 downto 0);
158 mmcr0(MMCR0_BHRBA) <= '0'; -- no BHRB yet
159 mmcr0(MMCR0_EBE) <= '0'; -- no EBBs yet
160 else
161 if doalert = '1' then
162 mmcr0(MMCR0_PMAE) <= '0';
163 mmcr0(MMCR0_PMAO) <= '1';
164 mmcr0(MMCR0_PMAQ) <= '0';
165 end if;
166 if doevent = '1' and mmcr0(MMCR0_FCECE) = '1' and mmcr0(MMCR0_TRIGGER) = '0' then
167 mmcr0(MMCR0_FC) <= '1';
168 end if;
169 if (doevent = '1' or pmcs(1)(31) = '1') and mmcr0(MMCR0_TRIGGER) = '1' then
170 mmcr0(MMCR0_TRIGGER) <= '0';
171 end if;
172 end if;
173 if p_in.mtspr = '1' and p_in.spr_num(3 downto 0) = "1110" then
174 mmcr1 <= p_in.spr_val;
175 end if;
176 if p_in.mtspr = '1' and p_in.spr_num(3 downto 0) = "0001" then
177 mmcr2 <= p_in.spr_val;
178 end if;
179 if p_in.mtspr = '1' and p_in.spr_num(3 downto 0) = "0010" then
180 mmcra <= p_in.spr_val;
181 -- we don't support random sampling yet
182 mmcra(MMCRA_SE) <= '0';
183 end if;
184 if p_in.mtspr = '1' and p_in.spr_num(3 downto 0) = "1100" then
185 siar <= p_in.spr_val;
186 elsif doalert = '1' then
187 siar <= p_in.nia;
188 end if;
189 if p_in.mtspr = '1' and p_in.spr_num(3 downto 0) = "1101" then
190 sdar <= p_in.spr_val;
191 elsif doalert = '1' then
192 sdar <= p_in.addr;
193 end if;
194 if p_in.mtspr = '1' and p_in.spr_num(3 downto 0) = "0000" then
195 sier <= p_in.spr_val;
196 elsif doalert = '1' then
197 sier <= (others => '0');
198 sier(SIER_SAMPPR) <= p_in.pr_msr;
199 sier(SIER_SIARV) <= '1';
200 sier(SIER_SDARV) <= p_in.addr_v;
201 end if;
202 end if;
203 prev_tb <= p_in.tbbits;
204 end if;
205 end process;
206
207 pmu_2: process(all)
208 variable tbdiff : std_ulogic_vector(3 downto 0);
209 variable tbbit : std_ulogic;
210 variable freeze : std_ulogic;
211 variable event : std_ulogic;
212 variable j : integer;
213 variable inc : std_ulogic_vector(1 to 6);
214 variable fc14wo : std_ulogic;
215 begin
216 event := '0';
217
218 -- Check for timebase events
219 tbdiff := p_in.tbbits and not prev_tb;
220 tbbit := tbdiff(3 - to_integer(unsigned(mmcr0(MMCR0_TBSEL + 1 downto MMCR0_TBSEL))));
221 if tbbit = '1' and mmcr0(MMCR0_TBEE) = '1' then
222 event := '1';
223 end if;
224
225 -- Check for counter negative events
226 if mmcr0(MMCR0_PMC1CE) = '1' and pmcs(1)(31) = '1' then
227 event := '1';
228 end if;
229 if mmcr0(MMCR0_PMCjCE) = '1' and
230 (pmcs(2)(31) or pmcs(3)(31) or pmcs(4)(31)) = '1' then
231 event := '1';
232 end if;
233 if mmcr0(MMCR0_PMCjCE) = '1' and
234 mmcr0(MMCR0_PMCC + 1 downto MMCR0_PMCC) /= "11" and
235 (pmcs(5)(31) or pmcs(6)(31)) = '1' then
236 event := '1';
237 end if;
238
239 -- Event selection
240 inc := (others => '0');
241 fc14wo := '0';
242 case mmcr1(31 downto 24) is
243 when x"f0" =>
244 inc(1) := '1';
245 fc14wo := '1'; -- override MMCR0[FC1_4WAIT]
246 when x"f2" | x"fe" =>
247 inc(1) := p_in.occur.instr_complete;
248 when x"f4" =>
249 inc(1) := p_in.occur.fp_complete;
250 when x"f6" =>
251 inc(1) := p_in.occur.itlb_miss;
252 when x"f8" =>
253 inc(1) := p_in.occur.no_instr_avail;
254 when x"fa" =>
255 inc(1) := p_in.run;
256 when x"fc" =>
257 inc(1) := p_in.occur.ld_complete;
258 when others =>
259 end case;
260
261 case mmcr1(23 downto 16) is
262 when x"f0" =>
263 inc(2) := p_in.occur.st_complete;
264 when x"f2" =>
265 inc(2) := p_in.occur.dispatch;
266 when x"f4" =>
267 inc(2) := p_in.run;
268 when x"f6" =>
269 inc(2) := p_in.occur.dtlb_miss_resolved;
270 when x"f8" =>
271 inc(2) := p_in.occur.ext_interrupt;
272 when x"fa" =>
273 inc(2) := p_in.occur.br_taken_complete;
274 when x"fc" =>
275 inc(2) := p_in.occur.icache_miss;
276 when x"fe" =>
277 inc(2) := p_in.occur.dc_miss_resolved;
278 when others =>
279 end case;
280
281 case mmcr1(15 downto 8) is
282 when x"f0" =>
283 inc(3) := p_in.occur.dc_store_miss;
284 when x"f2" =>
285 inc(3) := p_in.occur.dispatch;
286 when x"f4" =>
287 inc(3) := p_in.occur.instr_complete and p_in.run;
288 when x"f6" =>
289 inc(3) := p_in.occur.dc_ld_miss_resolved;
290 when x"f8" =>
291 inc(3) := tbbit;
292 when x"fe" =>
293 inc(3) := p_in.occur.dtlb_miss;
294 when others =>
295 end case;
296
297 case mmcr1(7 downto 0) is
298 when x"f0" =>
299 inc(4) := p_in.occur.dc_load_miss;
300 when x"f2" =>
301 inc(4) := p_in.occur.dispatch;
302 when x"f4" =>
303 inc(4) := p_in.run;
304 when x"f6" =>
305 inc(4) := p_in.occur.br_mispredict;
306 when x"f8" =>
307 inc(4) := p_in.occur.ipref_discard;
308 when x"fa" =>
309 inc(4) := p_in.occur.instr_complete and p_in.run;
310 when x"fc" =>
311 inc(4) := p_in.occur.itlb_miss_resolved;
312 when x"fe" =>
313 inc(4) := p_in.occur.ld_miss_nocache;
314 when others =>
315 end case;
316
317 inc(5) := (mmcr0(MMCR0_CC56RUN) or p_in.run) and p_in.occur.instr_complete;
318 inc(6) := mmcr0(MMCR0_CC56RUN) or p_in.run;
319
320 -- Evaluate freeze conditions
321 freeze := mmcr0(MMCR0_FC) or
322 (mmcr0(MMCR0_FCS) and not p_in.pr_msr) or
323 (mmcr0(MMCR0_FCP) and not mmcr0(MMCR0_FCPC) and p_in.pr_msr) or
324 (not mmcr0(MMCR0_FCP) and mmcr0(MMCR0_FCPC) and p_in.pr_msr) or
325 (mmcr0(MMCR0_FCM1) and p_in.pmm_msr) or
326 (mmcr0(MMCR0_FCM0) and not p_in.pmm_msr);
327
328 if freeze = '1' or mmcr0(MMCR0_FC1_4) = '1' or
329 (mmcr0(MMCR0_FC1_4W) = '1' and p_in.run = '0' and fc14wo = '0') then
330 inc(1) := '0';
331 end if;
332 if freeze = '1' or mmcr0(MMCR0_FC1_4) = '1' or
333 (mmcr0(MMCR0_FC1_4W) = '1' and p_in.run = '0') then
334 inc(2 to 4) := "000";
335 end if;
336 if freeze = '1' or mmcr0(MMCR0_FC5_6) = '1' then
337 inc(5 to 6) := "00";
338 end if;
339 if mmcr0(MMCR0_TRIGGER) = '1' then
340 inc(2 to 6) := "00000";
341 end if;
342 for i in 1 to 6 loop
343 j := (i - 1) * 9;
344 if (mmcr2(MMCR2_FC0S - j) = '1' and p_in.pr_msr = '0') or
345 (mmcr2(MMCR2_FC0P0 - j) = '1' and p_in.pr_msr = '1') or
346 (mmcr2(MMCR2_FC0M1 - j) = '1' and p_in.pmm_msr = '1') or
347 (mmcr2(MMCR2_FC0M1 - j) = '1' and p_in.pmm_msr = '1') then
348 inc(i) := '0';
349 end if;
350 end loop;
351
352 -- When MMCR0[PMCC] = "11", PMC5 and PMC6 are not controlled by the
353 -- MMCRs and don't generate events, but do continue to count run
354 -- instructions and run cycles.
355 if mmcr0(MMCR0_PMCC + 1 downto MMCR0_PMCC) = "11" then
356 inc(5) := p_in.run and p_in.occur.instr_complete;
357 inc(6) := p_in.run;
358 end if;
359
360 doinc <= inc;
361 doevent <= event;
362 doalert <= event and mmcr0(MMCR0_PMAE);
363 end process;
364
365 end architecture behaviour;