split out SVEXTRA field selection/decoding into separate class SVP64ExtraSpec
[soc.git] / src / soc / decoder / power_decoder2.py
1 """Power ISA Decoder second stage
2
3 based on Anton Blanchard microwatt decode2.vhdl
4
5 Note: OP_TRAP is used for exceptions and interrupts (micro-code style) by
6 over-riding the internal opcode when an exception is needed.
7 """
8
9 from nmigen import Module, Elaboratable, Signal, Mux, Const, Cat, Repl, Record
10 from nmigen.cli import rtlil
11 from soc.regfile.regfiles import XERRegs
12
13 from nmutil.picker import PriorityPicker
14 from nmutil.iocontrol import RecordObject
15 from nmutil.extend import exts
16
17 from soc.experiment.mem_types import LDSTException
18
19 from soc.decoder.power_regspec_map import regspec_decode_read
20 from soc.decoder.power_regspec_map import regspec_decode_write
21 from soc.decoder.power_decoder import create_pdecode
22 from soc.decoder.power_enums import (MicrOp, CryIn, Function,
23 CRInSel, CROutSel,
24 LdstLen, In1Sel, In2Sel, In3Sel,
25 OutSel, SPR, RC, LDSTMode,
26 SVEXTRA, SVEtype)
27 from soc.decoder.decode2execute1 import (Decode2ToExecute1Type, Data,
28 Decode2ToOperand)
29 from soc.sv.svp64 import SVP64Rec
30 from soc.consts import MSR
31
32 from soc.regfile.regfiles import FastRegs
33 from soc.consts import TT
34 from soc.config.state import CoreState
35 from soc.regfile.util import spr_to_fast
36
37
38 def decode_spr_num(spr):
39 return Cat(spr[5:10], spr[0:5])
40
41
42 def instr_is_priv(m, op, insn):
43 """determines if the instruction is privileged or not
44 """
45 comb = m.d.comb
46 is_priv_insn = Signal(reset_less=True)
47 with m.Switch(op):
48 with m.Case(MicrOp.OP_ATTN, MicrOp.OP_MFMSR, MicrOp.OP_MTMSRD,
49 MicrOp.OP_MTMSR, MicrOp.OP_RFID):
50 comb += is_priv_insn.eq(1)
51 # XXX TODO
52 #with m.Case(MicrOp.OP_TLBIE) : comb += is_priv_insn.eq(1)
53 with m.Case(MicrOp.OP_MFSPR, MicrOp.OP_MTSPR):
54 with m.If(insn[20]): # field XFX.spr[-1] i think
55 comb += is_priv_insn.eq(1)
56 return is_priv_insn
57
58
59 class SPRMap(Elaboratable):
60 """SPRMap: maps POWER9 SPR numbers to internal enum values, fast and slow
61 """
62
63 def __init__(self):
64 self.spr_i = Signal(10, reset_less=True)
65 self.spr_o = Data(SPR, name="spr_o")
66 self.fast_o = Data(3, name="fast_o")
67
68 def elaborate(self, platform):
69 m = Module()
70 with m.Switch(self.spr_i):
71 for i, x in enumerate(SPR):
72 with m.Case(x.value):
73 m.d.comb += self.spr_o.data.eq(i)
74 m.d.comb += self.spr_o.ok.eq(1)
75 for x, v in spr_to_fast.items():
76 with m.Case(x.value):
77 m.d.comb += self.fast_o.data.eq(v)
78 m.d.comb += self.fast_o.ok.eq(1)
79 return m
80
81
82 class SVP64ExtraSpec(Elaboratable):
83 """SVP64ExtraSpec - decodes SVP64 Extra specification.
84
85 selects the required EXTRA2/3 field.
86
87 see https://libre-soc.org/openpower/sv/svp64/
88 """
89 def __init__(self):
90 self.extra = Signal(10, reset_less=True)
91 self.etype = Signal(SVEtype, reset_less=True) # 2 or 3 bits
92 self.idx = Signal(SVEXTRA, reset_less=True) # which part of extra
93 self.spec = Signal(3) # EXTRA spec for the register
94
95 def elaborate(self, platform):
96 m = Module()
97 comb = m.d.comb
98 spec = self.spec
99
100 # back in the LDSTRM-* and RM-* files generated by sv_analysis.py
101 # we marked every op with an Etype: EXTRA2 or EXTRA3, and also said
102 # which of the 4 (or 3 for EXTRA3) sub-fields of bits 10:18 contain
103 # the register-extension information. extract those how
104 with m.Switch(self.etype):
105 # 2-bit index selection mode
106 with m.Case(SVEtype.EXTRA2):
107 with m.Switch(self.idx):
108 with m.Case(SVEXTRA.Idx0): # 1st 2 bits
109 comb += spec[1:3].eq(self.extra[0:2])
110 with m.Case(SVEXTRA.Idx1): # 2nd 2 bits
111 comb += spec[1:3].eq(self.extra[2:4])
112 with m.Case(SVEXTRA.Idx2): # 3rd 2 bits
113 comb += spec[1:3].eq(self.extra[4:6])
114 with m.Case(SVEXTRA.Idx3): # 4th 2 bits
115 comb += spec[1:3].eq(self.extra[6:8])
116 # 3-bit index selection mode
117 with m.Case(SVEtype.EXTRA3):
118 with m.Switch(self.idx):
119 with m.Case(SVEXTRA.Idx0): # 1st 3 bits
120 comb += spec.eq(self.extra[0:3])
121 with m.Case(SVEXTRA.Idx1): # 2nd 3 bits
122 comb += spec.eq(self.extra[3:6])
123 with m.Case(SVEXTRA.Idx2): # 3rd 3 bits
124 comb += spec.eq(self.extra[6:9])
125 # cannot fit more than 9 bits so there is no 4th thing
126
127 return m
128
129
130 class SVP64RegExtra(SVP64ExtraSpec):
131 """SVP64RegExtra - decodes SVP64 Extra fields to determine reg extension
132
133 incoming 5-bit GPR/FP is turned into a 7-bit and marked as scalar/vector
134 depending on info in one of the positions in the EXTRA field.
135
136 designed so that "no change" to the 5-bit register number occurs if
137 SV either does not apply or the relevant EXTRA2/3 field bits are zero.
138
139 see https://libre-soc.org/openpower/sv/svp64/
140 """
141 def __init__(self):
142 SVP64ExtraSpec.__init__(self)
143 self.reg_in = Signal(5) # incoming reg number (5 bits, RA, RB)
144 self.reg_out = Signal(7) # extra-augmented output (7 bits)
145 self.isvec = Signal(1) # reg is marked as vector if true
146
147 def elaborate(self, platform):
148 m = super().elaborate(platform)
149 comb = m.d.comb
150
151 # first get the spec. if not changed it's "scalar identity behaviour"
152 # which is zero which is ok.
153 spec = self.spec
154
155 # now decode it. bit 2 is "scalar/vector". note that spec could be zero
156 # from above, which (by design) has the effect of "no change", below.
157
158 # simple: isvec is top bit of spec
159 comb += self.isvec.eq(spec[2])
160
161 # decode vector differently from scalar
162 with m.If(self.isvec):
163 # Vector: shifted up, extra in LSBs (RA << 2) | spec[0:1]
164 comb += self.reg_out.eq(Cat(spec[:2], self.reg_in))
165 with m.Else():
166 # Scalar: not shifted up, extra in MSBs RA | (spec[0:1] << 5)
167 comb += self.reg_out.eq(Cat(self.reg_in, spec[:2]))
168
169 return m
170
171
172 class DecodeA(Elaboratable):
173 """DecodeA from instruction
174
175 decodes register RA, implicit and explicit CSRs
176 """
177
178 def __init__(self, dec):
179 self.dec = dec
180 self.sv_rm = SVP64Rec() # SVP64 RM field
181 self.sel_in = Signal(In1Sel, reset_less=True)
182 self.insn_in = Signal(32, reset_less=True)
183 self.reg_out = Data(7, name="reg_a")
184 self.reg_isvec = Signal(1, name="reg_a_isvec") # TODO: in reg_out
185 self.spr_out = Data(SPR, "spr_a")
186 self.fast_out = Data(3, "fast_a")
187
188 def elaborate(self, platform):
189 m = Module()
190 comb = m.d.comb
191 op = self.dec.op
192 m.submodules.sprmap = sprmap = SPRMap()
193 m.submodules.svdec = svdec = SVP64RegExtra()
194
195 # get the 5-bit reg data before svp64-munging it into 7-bit plus isvec
196 reg = Signal(5, reset_less=True)
197
198 # select Register A field
199 ra = Signal(5, reset_less=True)
200 comb += ra.eq(self.dec.RA)
201 with m.If((self.sel_in == In1Sel.RA) |
202 ((self.sel_in == In1Sel.RA_OR_ZERO) &
203 (ra != Const(0, 5)))):
204 comb += reg.eq(ra)
205 comb += self.reg_out.ok.eq(1)
206
207 # some Logic/ALU ops have RS as the 3rd arg, but no "RA".
208 # moved it to 1st position (in1_sel)... because
209 rs = Signal(5, reset_less=True)
210 comb += rs.eq(self.dec.RS)
211 with m.If(self.sel_in == In1Sel.RS):
212 comb += reg.eq(rs)
213 comb += self.reg_out.ok.eq(1)
214
215 # now do the SVP64 munging. op.SV_Etype and op.sv_in1 comes from
216 # PowerDecoder which in turn comes from LDST-RM*.csv and RM-*.csv
217 # which in turn were auto-generated by sv_analysis.py
218
219 extra = self.sv_rm.extra # SVP64 extra bits 10:18
220 comb += svdec.extra.eq(extra) # EXTRA field of SVP64 RM
221 comb += svdec.etype.eq(op.SV_Etype) # EXTRA2/3 for this insn
222 comb += svdec.idx.eq(op.sv_in1) # SVP64 reg #1 (matches in1_sel)
223 comb += svdec.reg_in.eq(reg) # 5-bit (RA, RS)
224
225 # outputs: 7-bit reg number and whether it's vectorised
226 comb += self.reg_out.data.eq(svdec.reg_out)
227 comb += self.reg_isvec.eq(svdec.isvec)
228
229 # decode Fast-SPR based on instruction type
230 with m.Switch(op.internal_op):
231
232 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeOut
233 with m.Case(MicrOp.OP_BC):
234 with m.If(~self.dec.BO[2]): # 3.0B p38 BO2=0, use CTR reg
235 # constant: CTR
236 comb += self.fast_out.data.eq(FastRegs.CTR)
237 comb += self.fast_out.ok.eq(1)
238 with m.Case(MicrOp.OP_BCREG):
239 xo9 = self.dec.FormXL.XO[9] # 3.0B p38 top bit of XO
240 xo5 = self.dec.FormXL.XO[5] # 3.0B p38
241 with m.If(xo9 & ~xo5):
242 # constant: CTR
243 comb += self.fast_out.data.eq(FastRegs.CTR)
244 comb += self.fast_out.ok.eq(1)
245
246 # MFSPR move from SPRs
247 with m.Case(MicrOp.OP_MFSPR):
248 spr = Signal(10, reset_less=True)
249 comb += spr.eq(decode_spr_num(self.dec.SPR)) # from XFX
250 comb += sprmap.spr_i.eq(spr)
251 comb += self.spr_out.eq(sprmap.spr_o)
252 comb += self.fast_out.eq(sprmap.fast_o)
253
254 return m
255
256
257 class DecodeAImm(Elaboratable):
258 """DecodeA immediate from instruction
259
260 decodes register RA, whether immediate-zero, implicit and
261 explicit CSRs
262 """
263
264 def __init__(self, dec):
265 self.dec = dec
266 self.sel_in = Signal(In1Sel, reset_less=True)
267 self.immz_out = Signal(reset_less=True)
268
269 def elaborate(self, platform):
270 m = Module()
271 comb = m.d.comb
272
273 # zero immediate requested
274 ra = Signal(5, reset_less=True)
275 comb += ra.eq(self.dec.RA)
276 with m.If((self.sel_in == In1Sel.RA_OR_ZERO) & (ra == Const(0, 5))):
277 comb += self.immz_out.eq(1)
278
279 return m
280
281
282 class DecodeB(Elaboratable):
283 """DecodeB from instruction
284
285 decodes register RB, different forms of immediate (signed, unsigned),
286 and implicit SPRs. register B is basically "lane 2" into the CompUnits.
287 by industry-standard convention, "lane 2" is where fully-decoded
288 immediates are muxed in.
289 """
290
291 def __init__(self, dec):
292 self.dec = dec
293 self.sv_rm = SVP64Rec() # SVP64 RM field
294 self.sel_in = Signal(In2Sel, reset_less=True)
295 self.insn_in = Signal(32, reset_less=True)
296 self.reg_out = Data(7, "reg_b")
297 self.reg_isvec = Signal(1, name="reg_b_isvec") # TODO: in reg_out
298 self.fast_out = Data(3, "fast_b")
299
300 def elaborate(self, platform):
301 m = Module()
302 comb = m.d.comb
303 op = self.dec.op
304 m.submodules.svdec = svdec = SVP64RegExtra()
305
306 # get the 5-bit reg data before svp64-munging it into 7-bit plus isvec
307 reg = Signal(5, reset_less=True)
308
309 # select Register B field
310 with m.Switch(self.sel_in):
311 with m.Case(In2Sel.RB):
312 comb += reg.eq(self.dec.RB)
313 comb += self.reg_out.ok.eq(1)
314 with m.Case(In2Sel.RS):
315 # for M-Form shiftrot
316 comb += reg.eq(self.dec.RS)
317 comb += self.reg_out.ok.eq(1)
318
319 # now do the SVP64 munging. different from DecodeA only by sv_in2
320
321 extra = self.sv_rm.extra # SVP64 extra bits 10:18
322 comb += svdec.extra.eq(extra) # EXTRA field of SVP64 RM
323 comb += svdec.etype.eq(op.SV_Etype) # EXTRA2/3 for this insn
324 comb += svdec.idx.eq(op.sv_in2) # SVP64 reg #2 (matches in2_sel)
325 comb += svdec.reg_in.eq(reg) # 5-bit (RA, RS)
326
327 # outputs: 7-bit reg number and whether it's vectorised
328 comb += self.reg_out.data.eq(svdec.reg_out)
329 comb += self.reg_isvec.eq(svdec.isvec)
330
331 # decode SPR2 based on instruction type
332 # BCREG implicitly uses LR or TAR for 2nd reg
333 # CTR however is already in fast_spr1 *not* 2.
334 with m.If(op.internal_op == MicrOp.OP_BCREG):
335 xo9 = self.dec.FormXL.XO[9] # 3.0B p38 top bit of XO
336 xo5 = self.dec.FormXL.XO[5] # 3.0B p38
337 with m.If(~xo9):
338 comb += self.fast_out.data.eq(FastRegs.LR)
339 comb += self.fast_out.ok.eq(1)
340 with m.Elif(xo5):
341 comb += self.fast_out.data.eq(FastRegs.TAR)
342 comb += self.fast_out.ok.eq(1)
343
344 return m
345
346
347 class DecodeBImm(Elaboratable):
348 """DecodeB immediate from instruction
349 """
350 def __init__(self, dec):
351 self.dec = dec
352 self.sel_in = Signal(In2Sel, reset_less=True)
353 self.imm_out = Data(64, "imm_b")
354
355 def elaborate(self, platform):
356 m = Module()
357 comb = m.d.comb
358
359 # select Register B Immediate
360 with m.Switch(self.sel_in):
361 with m.Case(In2Sel.CONST_UI): # unsigned
362 comb += self.imm_out.data.eq(self.dec.UI)
363 comb += self.imm_out.ok.eq(1)
364 with m.Case(In2Sel.CONST_SI): # sign-extended 16-bit
365 si = Signal(16, reset_less=True)
366 comb += si.eq(self.dec.SI)
367 comb += self.imm_out.data.eq(exts(si, 16, 64))
368 comb += self.imm_out.ok.eq(1)
369 with m.Case(In2Sel.CONST_SI_HI): # sign-extended 16+16=32 bit
370 si_hi = Signal(32, reset_less=True)
371 comb += si_hi.eq(self.dec.SI << 16)
372 comb += self.imm_out.data.eq(exts(si_hi, 32, 64))
373 comb += self.imm_out.ok.eq(1)
374 with m.Case(In2Sel.CONST_UI_HI): # unsigned
375 ui = Signal(16, reset_less=True)
376 comb += ui.eq(self.dec.UI)
377 comb += self.imm_out.data.eq(ui << 16)
378 comb += self.imm_out.ok.eq(1)
379 with m.Case(In2Sel.CONST_LI): # sign-extend 24+2=26 bit
380 li = Signal(26, reset_less=True)
381 comb += li.eq(self.dec.LI << 2)
382 comb += self.imm_out.data.eq(exts(li, 26, 64))
383 comb += self.imm_out.ok.eq(1)
384 with m.Case(In2Sel.CONST_BD): # sign-extend (14+2)=16 bit
385 bd = Signal(16, reset_less=True)
386 comb += bd.eq(self.dec.BD << 2)
387 comb += self.imm_out.data.eq(exts(bd, 16, 64))
388 comb += self.imm_out.ok.eq(1)
389 with m.Case(In2Sel.CONST_DS): # sign-extended (14+2=16) bit
390 ds = Signal(16, reset_less=True)
391 comb += ds.eq(self.dec.DS << 2)
392 comb += self.imm_out.data.eq(exts(ds, 16, 64))
393 comb += self.imm_out.ok.eq(1)
394 with m.Case(In2Sel.CONST_M1): # signed (-1)
395 comb += self.imm_out.data.eq(~Const(0, 64)) # all 1s
396 comb += self.imm_out.ok.eq(1)
397 with m.Case(In2Sel.CONST_SH): # unsigned - for shift
398 comb += self.imm_out.data.eq(self.dec.sh)
399 comb += self.imm_out.ok.eq(1)
400 with m.Case(In2Sel.CONST_SH32): # unsigned - for shift
401 comb += self.imm_out.data.eq(self.dec.SH32)
402 comb += self.imm_out.ok.eq(1)
403
404 return m
405
406
407 class DecodeC(Elaboratable):
408 """DecodeC from instruction
409
410 decodes register RC. this is "lane 3" into some CompUnits (not many)
411 """
412
413 def __init__(self, dec):
414 self.dec = dec
415 self.sv_rm = SVP64Rec() # SVP64 RM field
416 self.sel_in = Signal(In3Sel, reset_less=True)
417 self.insn_in = Signal(32, reset_less=True)
418 self.reg_out = Data(7, "reg_c")
419 self.reg_isvec = Signal(1, name="reg_c_isvec") # TODO: in reg_out
420
421 def elaborate(self, platform):
422 m = Module()
423 comb = m.d.comb
424 op = self.dec.op
425 m.submodules.svdec = svdec = SVP64RegExtra()
426
427 # get the 5-bit reg data before svp64-munging it into 7-bit plus isvec
428 reg = Signal(5, reset_less=True)
429
430 # select Register C field
431 with m.Switch(self.sel_in):
432 with m.Case(In3Sel.RB):
433 # for M-Form shiftrot
434 comb += reg.eq(self.dec.RB)
435 comb += self.reg_out.ok.eq(1)
436 with m.Case(In3Sel.RS):
437 comb += reg.eq(self.dec.RS)
438 comb += self.reg_out.ok.eq(1)
439
440 # now do the SVP64 munging. different from DecodeA only by sv_in3
441
442 extra = self.sv_rm.extra # SVP64 extra bits 10:18
443 comb += svdec.extra.eq(extra) # EXTRA field of SVP64 RM
444 comb += svdec.etype.eq(op.SV_Etype) # EXTRA2/3 for this insn
445 comb += svdec.idx.eq(op.sv_in3) # SVP64 reg #3 (matches in3_sel)
446 comb += svdec.reg_in.eq(reg) # 5-bit (RA, RS)
447
448 # outputs: 7-bit reg number and whether it's vectorised
449 comb += self.reg_out.data.eq(svdec.reg_out)
450 comb += self.reg_isvec.eq(svdec.isvec)
451
452 return m
453
454
455 class DecodeOut(Elaboratable):
456 """DecodeOut from instruction
457
458 decodes output register RA, RT or SPR
459 """
460
461 def __init__(self, dec):
462 self.dec = dec
463 self.sv_rm = SVP64Rec() # SVP64 RM field
464 self.sel_in = Signal(OutSel, reset_less=True)
465 self.insn_in = Signal(32, reset_less=True)
466 self.reg_out = Data(7, "reg_o")
467 self.reg_isvec = Signal(1, name="reg_o_isvec") # TODO: in reg_out
468 self.spr_out = Data(SPR, "spr_o")
469 self.fast_out = Data(3, "fast_o")
470
471 def elaborate(self, platform):
472 m = Module()
473 comb = m.d.comb
474 m.submodules.sprmap = sprmap = SPRMap()
475 op = self.dec.op
476 m.submodules.svdec = svdec = SVP64RegExtra()
477
478 # get the 5-bit reg data before svp64-munging it into 7-bit plus isvec
479 reg = Signal(5, reset_less=True)
480
481 # select Register out field
482 with m.Switch(self.sel_in):
483 with m.Case(OutSel.RT):
484 comb += reg.eq(self.dec.RT)
485 comb += self.reg_out.ok.eq(1)
486 with m.Case(OutSel.RA):
487 comb += reg.eq(self.dec.RA)
488 comb += self.reg_out.ok.eq(1)
489 with m.Case(OutSel.SPR):
490 spr = Signal(10, reset_less=True)
491 comb += spr.eq(decode_spr_num(self.dec.SPR)) # from XFX
492 # MFSPR move to SPRs - needs mapping
493 with m.If(op.internal_op == MicrOp.OP_MTSPR):
494 comb += sprmap.spr_i.eq(spr)
495 comb += self.spr_out.eq(sprmap.spr_o)
496 comb += self.fast_out.eq(sprmap.fast_o)
497
498 # now do the SVP64 munging. different from DecodeA only by sv_out
499
500 extra = self.sv_rm.extra # SVP64 extra bits 10:18
501 comb += svdec.extra.eq(extra) # EXTRA field of SVP64 RM
502 comb += svdec.etype.eq(op.SV_Etype) # EXTRA2/3 for this insn
503 comb += svdec.idx.eq(op.sv_out) # SVP64 reg out1 (matches out_sel)
504 comb += svdec.reg_in.eq(reg) # 5-bit (RA, RS)
505
506 # outputs: 7-bit reg number and whether it's vectorised
507 comb += self.reg_out.data.eq(svdec.reg_out)
508 comb += self.reg_isvec.eq(svdec.isvec)
509
510 # determine Fast Reg
511 with m.Switch(op.internal_op):
512
513 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeA
514 with m.Case(MicrOp.OP_BC, MicrOp.OP_BCREG):
515 with m.If(~self.dec.BO[2]): # 3.0B p38 BO2=0, use CTR reg
516 # constant: CTR
517 comb += self.fast_out.data.eq(FastRegs.CTR)
518 comb += self.fast_out.ok.eq(1)
519
520 # RFID 1st spr (fast)
521 with m.Case(MicrOp.OP_RFID):
522 comb += self.fast_out.data.eq(FastRegs.SRR0) # constant: SRR0
523 comb += self.fast_out.ok.eq(1)
524
525 return m
526
527
528 class DecodeOut2(Elaboratable):
529 """DecodeOut2 from instruction
530
531 decodes output registers (2nd one). note that RA is *implicit* below,
532 which now causes problems with SVP64
533
534 TODO: SVP64 is a little more complex, here. svp64 allows extending
535 by one more destination by having one more EXTRA field. RA-as-src
536 is not the same as RA-as-dest. limited in that it's the same first
537 5 bits (from the v3.0B opcode), but still kinda cool. mostly used
538 for operations that have src-as-dest: mostly this is LD/ST-with-update
539 but there are others.
540 """
541
542 def __init__(self, dec):
543 self.dec = dec
544 self.sv_rm = SVP64Rec() # SVP64 RM field
545 self.sel_in = Signal(OutSel, reset_less=True)
546 self.lk = Signal(reset_less=True)
547 self.insn_in = Signal(32, reset_less=True)
548 self.reg_out = Data(7, "reg_o2")
549 #self.reg_isvec = Signal(1, name="reg_o2_isvec") # TODO: in reg_out
550 self.fast_out = Data(3, "fast_o2")
551
552 def elaborate(self, platform):
553 m = Module()
554 comb = m.d.comb
555 op = self.dec.op
556 #m.submodules.svdec = svdec = SVP64RegExtra()
557
558 # get the 5-bit reg data before svp64-munging it into 7-bit plus isvec
559 #reg = Signal(5, reset_less=True)
560
561 if hasattr(self.dec.op, "upd"):
562 # update mode LD/ST uses read-reg A also as an output
563 with m.If(self.dec.op.upd == LDSTMode.update):
564 comb += self.reg_out.data.eq(self.dec.RA)
565 comb += self.reg_out.ok.eq(1)
566
567 # B, BC or BCREG: potential implicit register (LR) output
568 # these give bl, bcl, bclrl, etc.
569 with m.Switch(op.internal_op):
570
571 # BC* implicit register (LR)
572 with m.Case(MicrOp.OP_BC, MicrOp.OP_B, MicrOp.OP_BCREG):
573 with m.If(self.lk): # "link" mode
574 comb += self.fast_out.data.eq(FastRegs.LR) # constant: LR
575 comb += self.fast_out.ok.eq(1)
576
577 # RFID 2nd spr (fast)
578 with m.Case(MicrOp.OP_RFID):
579 comb += self.fast_out.data.eq(FastRegs.SRR1) # constant: SRR1
580 comb += self.fast_out.ok.eq(1)
581
582 return m
583
584
585 class DecodeRC(Elaboratable):
586 """DecodeRc from instruction
587
588 decodes Record bit Rc
589 """
590
591 def __init__(self, dec):
592 self.dec = dec
593 self.sel_in = Signal(RC, reset_less=True)
594 self.insn_in = Signal(32, reset_less=True)
595 self.rc_out = Data(1, "rc")
596
597 def elaborate(self, platform):
598 m = Module()
599 comb = m.d.comb
600
601 # select Record bit out field
602 with m.Switch(self.sel_in):
603 with m.Case(RC.RC):
604 comb += self.rc_out.data.eq(self.dec.Rc)
605 comb += self.rc_out.ok.eq(1)
606 with m.Case(RC.ONE):
607 comb += self.rc_out.data.eq(1)
608 comb += self.rc_out.ok.eq(1)
609 with m.Case(RC.NONE):
610 comb += self.rc_out.data.eq(0)
611 comb += self.rc_out.ok.eq(1)
612
613 return m
614
615
616 class DecodeOE(Elaboratable):
617 """DecodeOE from instruction
618
619 decodes OE field: uses RC decode detection which might not be good
620
621 -- For now, use "rc" in the decode table to decide whether oe exists.
622 -- This is not entirely correct architecturally: For mulhd and
623 -- mulhdu, the OE field is reserved. It remains to be seen what an
624 -- actual POWER9 does if we set it on those instructions, for now we
625 -- test that further down when assigning to the multiplier oe input.
626 """
627
628 def __init__(self, dec):
629 self.dec = dec
630 self.sel_in = Signal(RC, reset_less=True)
631 self.insn_in = Signal(32, reset_less=True)
632 self.oe_out = Data(1, "oe")
633
634 def elaborate(self, platform):
635 m = Module()
636 comb = m.d.comb
637 op = self.dec.op
638
639 with m.Switch(op.internal_op):
640
641 # mulhw, mulhwu, mulhd, mulhdu - these *ignore* OE
642 # also rotate
643 # XXX ARGH! ignoring OE causes incompatibility with microwatt
644 # http://lists.libre-soc.org/pipermail/libre-soc-dev/2020-August/000302.html
645 with m.Case(MicrOp.OP_MUL_H64, MicrOp.OP_MUL_H32,
646 MicrOp.OP_EXTS, MicrOp.OP_CNTZ,
647 MicrOp.OP_SHL, MicrOp.OP_SHR, MicrOp.OP_RLC,
648 MicrOp.OP_LOAD, MicrOp.OP_STORE,
649 MicrOp.OP_RLCL, MicrOp.OP_RLCR,
650 MicrOp.OP_EXTSWSLI):
651 pass
652
653 # all other ops decode OE field
654 with m.Default():
655 # select OE bit out field
656 with m.Switch(self.sel_in):
657 with m.Case(RC.RC):
658 comb += self.oe_out.data.eq(self.dec.OE)
659 comb += self.oe_out.ok.eq(1)
660
661 return m
662
663
664 class DecodeCRIn(Elaboratable):
665 """Decodes input CR from instruction
666
667 CR indices - insn fields - (not the data *in* the CR) require only 3
668 bits because they refer to CR0-CR7
669 """
670
671 def __init__(self, dec):
672 self.dec = dec
673 self.sv_rm = SVP64Rec() # SVP64 RM field
674 self.sel_in = Signal(CRInSel, reset_less=True)
675 self.insn_in = Signal(32, reset_less=True)
676 self.cr_bitfield = Data(3, "cr_bitfield")
677 self.cr_bitfield_b = Data(3, "cr_bitfield_b")
678 self.cr_bitfield_o = Data(3, "cr_bitfield_o")
679 self.whole_reg = Data(8, "cr_fxm")
680
681 def elaborate(self, platform):
682 m = Module()
683 m.submodules.ppick = ppick = PriorityPicker(8, reverse_i=True,
684 reverse_o=True)
685
686 comb = m.d.comb
687 op = self.dec.op
688
689 comb += self.cr_bitfield.ok.eq(0)
690 comb += self.cr_bitfield_b.ok.eq(0)
691 comb += self.cr_bitfield_o.ok.eq(0)
692 comb += self.whole_reg.ok.eq(0)
693
694 with m.Switch(self.sel_in):
695 with m.Case(CRInSel.NONE):
696 pass # No bitfield activated
697 with m.Case(CRInSel.CR0):
698 comb += self.cr_bitfield.data.eq(0) # CR0 (MSB0 numbering)
699 comb += self.cr_bitfield.ok.eq(1)
700 with m.Case(CRInSel.BI):
701 comb += self.cr_bitfield.data.eq(self.dec.BI[2:5])
702 comb += self.cr_bitfield.ok.eq(1)
703 with m.Case(CRInSel.BFA):
704 comb += self.cr_bitfield.data.eq(self.dec.FormX.BFA)
705 comb += self.cr_bitfield.ok.eq(1)
706 with m.Case(CRInSel.BA_BB):
707 comb += self.cr_bitfield.data.eq(self.dec.BA[2:5])
708 comb += self.cr_bitfield.ok.eq(1)
709 comb += self.cr_bitfield_b.data.eq(self.dec.BB[2:5])
710 comb += self.cr_bitfield_b.ok.eq(1)
711 comb += self.cr_bitfield_o.data.eq(self.dec.BT[2:5])
712 comb += self.cr_bitfield_o.ok.eq(1)
713 with m.Case(CRInSel.BC):
714 comb += self.cr_bitfield.data.eq(self.dec.BC[2:5])
715 comb += self.cr_bitfield.ok.eq(1)
716 with m.Case(CRInSel.WHOLE_REG):
717 comb += self.whole_reg.ok.eq(1)
718 move_one = Signal(reset_less=True)
719 comb += move_one.eq(self.insn_in[20]) # MSB0 bit 11
720 with m.If((op.internal_op == MicrOp.OP_MFCR) & move_one):
721 # must one-hot the FXM field
722 comb += ppick.i.eq(self.dec.FXM)
723 comb += self.whole_reg.data.eq(ppick.o)
724 with m.Else():
725 # otherwise use all of it
726 comb += self.whole_reg.data.eq(0xff)
727
728 return m
729
730
731 class DecodeCROut(Elaboratable):
732 """Decodes input CR from instruction
733
734 CR indices - insn fields - (not the data *in* the CR) require only 3
735 bits because they refer to CR0-CR7
736 """
737
738 def __init__(self, dec):
739 self.dec = dec
740 self.sv_rm = SVP64Rec() # SVP64 RM field
741 self.rc_in = Signal(reset_less=True)
742 self.sel_in = Signal(CROutSel, reset_less=True)
743 self.insn_in = Signal(32, reset_less=True)
744 self.cr_bitfield = Data(3, "cr_bitfield")
745 self.whole_reg = Data(8, "cr_fxm")
746
747 def elaborate(self, platform):
748 m = Module()
749 comb = m.d.comb
750 op = self.dec.op
751 m.submodules.ppick = ppick = PriorityPicker(8, reverse_i=True,
752 reverse_o=True)
753
754 comb += self.cr_bitfield.ok.eq(0)
755 comb += self.whole_reg.ok.eq(0)
756 with m.Switch(self.sel_in):
757 with m.Case(CROutSel.NONE):
758 pass # No bitfield activated
759 with m.Case(CROutSel.CR0):
760 comb += self.cr_bitfield.data.eq(0) # CR0 (MSB0 numbering)
761 comb += self.cr_bitfield.ok.eq(self.rc_in) # only when RC=1
762 with m.Case(CROutSel.BF):
763 comb += self.cr_bitfield.data.eq(self.dec.FormX.BF)
764 comb += self.cr_bitfield.ok.eq(1)
765 with m.Case(CROutSel.BT):
766 comb += self.cr_bitfield.data.eq(self.dec.FormXL.BT[2:5])
767 comb += self.cr_bitfield.ok.eq(1)
768 with m.Case(CROutSel.WHOLE_REG):
769 comb += self.whole_reg.ok.eq(1)
770 move_one = Signal(reset_less=True)
771 comb += move_one.eq(self.insn_in[20])
772 with m.If((op.internal_op == MicrOp.OP_MTCRF)):
773 with m.If(move_one):
774 # must one-hot the FXM field
775 comb += ppick.i.eq(self.dec.FXM)
776 with m.If(ppick.en_o):
777 comb += self.whole_reg.data.eq(ppick.o)
778 with m.Else():
779 comb += self.whole_reg.data.eq(0b00000001) # CR7
780 with m.Else():
781 comb += self.whole_reg.data.eq(self.dec.FXM)
782 with m.Else():
783 # otherwise use all of it
784 comb += self.whole_reg.data.eq(0xff)
785
786 return m
787
788 # dictionary of Input Record field names that, if they exist,
789 # will need a corresponding CSV Decoder file column (actually, PowerOp)
790 # to be decoded (this includes the single bit names)
791 record_names = {'insn_type': 'internal_op',
792 'fn_unit': 'function_unit',
793 'rc': 'rc_sel',
794 'oe': 'rc_sel',
795 'zero_a': 'in1_sel',
796 'imm_data': 'in2_sel',
797 'invert_in': 'inv_a',
798 'invert_out': 'inv_out',
799 'rc': 'cr_out',
800 'oe': 'cr_in',
801 'output_carry': 'cry_out',
802 'input_carry': 'cry_in',
803 'is_32bit': 'is_32b',
804 'is_signed': 'sgn',
805 'lk': 'lk',
806 'data_len': 'ldst_len',
807 'byte_reverse': 'br',
808 'sign_extend': 'sgn_ext',
809 'ldst_mode': 'upd',
810 }
811
812
813 class PowerDecodeSubset(Elaboratable):
814 """PowerDecodeSubset: dynamic subset decoder
815
816 only fields actually requested are copied over. hence, "subset" (duh).
817 """
818 def __init__(self, dec, opkls=None, fn_name=None, final=False, state=None):
819
820 self.sv_rm = SVP64Rec(name="dec_svp64") # SVP64 RM field
821 self.final = final
822 self.opkls = opkls
823 self.fn_name = fn_name
824 if opkls is None:
825 opkls = Decode2ToOperand
826 self.do = opkls(fn_name)
827 col_subset = self.get_col_subset(self.do)
828
829 # only needed for "main" PowerDecode2
830 if not self.final:
831 self.e = Decode2ToExecute1Type(name=self.fn_name, do=self.do)
832
833 # create decoder if one not already given
834 if dec is None:
835 dec = create_pdecode(name=fn_name, col_subset=col_subset,
836 row_subset=self.rowsubsetfn)
837 self.dec = dec
838
839 # state information needed by the Decoder
840 if state is None:
841 state = CoreState("dec2")
842 self.state = state
843
844 def get_col_subset(self, do):
845 subset = {'cr_in', 'cr_out', 'rc_sel'} # needed, non-optional
846 for k, v in record_names.items():
847 if hasattr(do, k):
848 subset.add(v)
849 print ("get_col_subset", self.fn_name, do.fields, subset)
850 return subset
851
852 def rowsubsetfn(self, opcode, row):
853 return row['unit'] == self.fn_name
854
855 def ports(self):
856 return self.dec.ports() + self.e.ports() + self.sv_rm.ports()
857
858 def needs_field(self, field, op_field):
859 if self.final:
860 do = self.do
861 else:
862 do = self.e_tmp.do
863 return hasattr(do, field) and self.op_get(op_field) is not None
864
865 def do_copy(self, field, val, final=False):
866 if final or self.final:
867 do = self.do
868 else:
869 do = self.e_tmp.do
870 if hasattr(do, field) and val is not None:
871 return getattr(do, field).eq(val)
872 return []
873
874 def op_get(self, op_field):
875 return getattr(self.dec.op, op_field, None)
876
877 def elaborate(self, platform):
878 m = Module()
879 comb = m.d.comb
880 state = self.state
881 op, do = self.dec.op, self.do
882 msr, cia = state.msr, state.pc
883
884 # fill in for a normal instruction (not an exception)
885 # copy over if non-exception, non-privileged etc. is detected
886 if not self.final:
887 if self.fn_name is None:
888 name = "tmp"
889 else:
890 name = self.fn_name + "tmp"
891 self.e_tmp = Decode2ToExecute1Type(name=name, opkls=self.opkls)
892
893 # set up submodule decoders
894 m.submodules.dec = self.dec
895 m.submodules.dec_rc = dec_rc = DecodeRC(self.dec)
896 m.submodules.dec_oe = dec_oe = DecodeOE(self.dec)
897 m.submodules.dec_cr_in = self.dec_cr_in = DecodeCRIn(self.dec)
898 m.submodules.dec_cr_out = self.dec_cr_out = DecodeCROut(self.dec)
899
900 # copy instruction through...
901 for i in [do.insn,
902 dec_rc.insn_in, dec_oe.insn_in,
903 self.dec_cr_in.insn_in, self.dec_cr_out.insn_in]:
904 comb += i.eq(self.dec.opcode_in)
905
906 # ...and subdecoders' input fields
907 comb += dec_rc.sel_in.eq(op.rc_sel)
908 comb += dec_oe.sel_in.eq(op.rc_sel) # XXX should be OE sel
909 comb += self.dec_cr_in.sel_in.eq(op.cr_in)
910 comb += self.dec_cr_in.sv_rm.eq(self.sv_rm)
911 comb += self.dec_cr_out.sv_rm.eq(self.sv_rm)
912 comb += self.dec_cr_out.sel_in.eq(op.cr_out)
913 comb += self.dec_cr_out.rc_in.eq(dec_rc.rc_out.data)
914
915 # copy "state" over
916 comb += self.do_copy("msr", msr)
917 comb += self.do_copy("cia", cia)
918
919 # set up instruction type
920 # no op: defaults to OP_ILLEGAL
921 comb += self.do_copy("insn_type", self.op_get("internal_op"))
922
923 # function unit for decoded instruction: requires minor redirect
924 # for SPR set/get
925 fn = self.op_get("function_unit")
926 spr = Signal(10, reset_less=True)
927 comb += spr.eq(decode_spr_num(self.dec.SPR)) # from XFX
928
929 # for first test only forward SPRs 18 and 19 to MMU, when
930 # operation is MTSPR or MFSPR. TODO: add other MMU SPRs
931 with m.If(((self.dec.op.internal_op == MicrOp.OP_MTSPR) |
932 (self.dec.op.internal_op == MicrOp.OP_MFSPR)) &
933 ((spr == SPR.DSISR) | (spr == SPR.DAR))):
934 comb += self.do_copy("fn_unit", Function.MMU)
935 with m.Else():
936 comb += self.do_copy("fn_unit",fn)
937
938 # immediates
939 if self.needs_field("zero_a", "in1_sel"):
940 m.submodules.dec_ai = dec_ai = DecodeAImm(self.dec)
941 comb += dec_ai.sel_in.eq(op.in1_sel)
942 comb += self.do_copy("zero_a", dec_ai.immz_out) # RA==0 detected
943 if self.needs_field("imm_data", "in2_sel"):
944 m.submodules.dec_bi = dec_bi = DecodeBImm(self.dec)
945 comb += dec_bi.sel_in.eq(op.in2_sel)
946 comb += self.do_copy("imm_data", dec_bi.imm_out) # imm in RB
947
948 # rc and oe out
949 comb += self.do_copy("rc", dec_rc.rc_out)
950 comb += self.do_copy("oe", dec_oe.oe_out)
951
952 # CR in/out
953 comb += self.do_copy("read_cr_whole", self.dec_cr_in.whole_reg)
954 comb += self.do_copy("write_cr_whole", self.dec_cr_out.whole_reg)
955 comb += self.do_copy("write_cr0", self.dec_cr_out.cr_bitfield.ok)
956
957 comb += self.do_copy("input_cr", self.op_get("cr_in")) # CR in
958 comb += self.do_copy("output_cr", self.op_get("cr_out")) # CR out
959
960 # decoded/selected instruction flags
961 comb += self.do_copy("data_len", self.op_get("ldst_len"))
962 comb += self.do_copy("invert_in", self.op_get("inv_a"))
963 comb += self.do_copy("invert_out", self.op_get("inv_out"))
964 comb += self.do_copy("input_carry", self.op_get("cry_in"))
965 comb += self.do_copy("output_carry", self.op_get("cry_out"))
966 comb += self.do_copy("is_32bit", self.op_get("is_32b"))
967 comb += self.do_copy("is_signed", self.op_get("sgn"))
968 lk = self.op_get("lk")
969 if lk is not None:
970 with m.If(lk):
971 comb += self.do_copy("lk", self.dec.LK) # XXX TODO: accessor
972
973 comb += self.do_copy("byte_reverse", self.op_get("br"))
974 comb += self.do_copy("sign_extend", self.op_get("sgn_ext"))
975 comb += self.do_copy("ldst_mode", self.op_get("upd")) # LD/ST mode
976
977 return m
978
979
980 class PowerDecode2(PowerDecodeSubset):
981 """PowerDecode2: the main instruction decoder.
982
983 whilst PowerDecode is responsible for decoding the actual opcode, this
984 module encapsulates further specialist, sparse information and
985 expansion of fields that is inconvenient to have in the CSV files.
986 for example: the encoding of the immediates, which are detected
987 and expanded out to their full value from an annotated (enum)
988 representation.
989
990 implicit register usage is also set up, here. for example: OP_BC
991 requires implicitly reading CTR, OP_RFID requires implicitly writing
992 to SRR1 and so on.
993
994 in addition, PowerDecoder2 is responsible for detecting whether
995 instructions are illegal (or privileged) or not, and instead of
996 just leaving at that, *replacing* the instruction to execute with
997 a suitable alternative (trap).
998
999 LDSTExceptions are done the cycle _after_ they're detected (after
1000 they come out of LDSTCompUnit). basically despite the instruction
1001 being decoded, the results of the decode are completely ignored
1002 and "exception.happened" used to set the "actual" instruction to
1003 "OP_TRAP". the LDSTException data structure gets filled in,
1004 in the CompTrapOpSubset and that's what it fills in SRR.
1005
1006 to make this work, TestIssuer must notice "exception.happened"
1007 after the (failed) LD/ST and copies the LDSTException info from
1008 the output, into here (PowerDecoder2). without incrementing PC.
1009 """
1010
1011 def __init__(self, dec, opkls=None, fn_name=None, final=False, state=None):
1012 super().__init__(dec, opkls, fn_name, final, state)
1013 self.exc = LDSTException("dec2_exc")
1014
1015 def get_col_subset(self, opkls):
1016 subset = super().get_col_subset(opkls)
1017 subset.add("asmcode")
1018 subset.add("in1_sel")
1019 subset.add("in2_sel")
1020 subset.add("in3_sel")
1021 subset.add("out_sel")
1022 subset.add("sv_in1")
1023 subset.add("sv_in2")
1024 subset.add("sv_in3")
1025 subset.add("sv_out")
1026 subset.add("SV_Etype")
1027 subset.add("SV_Ptype")
1028 subset.add("lk")
1029 subset.add("internal_op")
1030 subset.add("form")
1031 return subset
1032
1033 def elaborate(self, platform):
1034 m = super().elaborate(platform)
1035 comb = m.d.comb
1036 state = self.state
1037 e_out, op, do_out = self.e, self.dec.op, self.e.do
1038 dec_spr, msr, cia, ext_irq = state.dec, state.msr, state.pc, state.eint
1039 e = self.e_tmp
1040 do = e.do
1041
1042 # fill in for a normal instruction (not an exception)
1043 # copy over if non-exception, non-privileged etc. is detected
1044
1045 # set up submodule decoders
1046 m.submodules.dec_a = dec_a = DecodeA(self.dec)
1047 m.submodules.dec_b = dec_b = DecodeB(self.dec)
1048 m.submodules.dec_c = dec_c = DecodeC(self.dec)
1049 m.submodules.dec_o = dec_o = DecodeOut(self.dec)
1050 m.submodules.dec_o2 = dec_o2 = DecodeOut2(self.dec)
1051
1052 # copy instruction through...
1053 for i in [do.insn, dec_a.insn_in, dec_b.insn_in,
1054 dec_c.insn_in, dec_o.insn_in, dec_o2.insn_in]:
1055 comb += i.eq(self.dec.opcode_in)
1056
1057 # ... and svp64 rm
1058 for i in [dec_a.insn_in, dec_b.insn_in,
1059 dec_c.insn_in, dec_o.insn_in, dec_o2.insn_in]:
1060 comb += i.eq(self.sv_rm)
1061
1062 # ...and subdecoders' input fields
1063 comb += dec_a.sel_in.eq(op.in1_sel)
1064 comb += dec_b.sel_in.eq(op.in2_sel)
1065 comb += dec_c.sel_in.eq(op.in3_sel)
1066 comb += dec_o.sel_in.eq(op.out_sel)
1067 comb += dec_o2.sel_in.eq(op.out_sel)
1068 if hasattr(do, "lk"):
1069 comb += dec_o2.lk.eq(do.lk)
1070
1071 # registers a, b, c and out and out2 (LD/ST EA)
1072 for to_reg, fromreg in (
1073 (e.read_reg1, dec_a.reg_out),
1074 (e.read_reg2, dec_b.reg_out),
1075 (e.read_reg3, dec_c.reg_out),
1076 (e.write_reg, dec_o.reg_out),
1077 (e.write_ea, dec_o2.reg_out)):
1078 comb += to_reg.data.eq(fromreg.data)
1079 comb += to_reg.ok.eq(fromreg.ok)
1080
1081 # SPRs out
1082 comb += e.read_spr1.eq(dec_a.spr_out)
1083 comb += e.write_spr.eq(dec_o.spr_out)
1084
1085 # Fast regs out
1086 comb += e.read_fast1.eq(dec_a.fast_out)
1087 comb += e.read_fast2.eq(dec_b.fast_out)
1088 comb += e.write_fast1.eq(dec_o.fast_out)
1089 comb += e.write_fast2.eq(dec_o2.fast_out)
1090
1091 # condition registers (CR)
1092 comb += e.read_cr1.eq(self.dec_cr_in.cr_bitfield)
1093 comb += e.read_cr2.eq(self.dec_cr_in.cr_bitfield_b)
1094 comb += e.read_cr3.eq(self.dec_cr_in.cr_bitfield_o)
1095 comb += e.write_cr.eq(self.dec_cr_out.cr_bitfield)
1096
1097 # sigh this is exactly the sort of thing for which the
1098 # decoder is designed to not need. MTSPR, MFSPR and others need
1099 # access to the XER bits. however setting e.oe is not appropriate
1100 with m.If(op.internal_op == MicrOp.OP_MFSPR):
1101 comb += e.xer_in.eq(0b111) # SO, CA, OV
1102 with m.If(op.internal_op == MicrOp.OP_CMP):
1103 comb += e.xer_in.eq(1<<XERRegs.SO) # SO
1104 with m.If(op.internal_op == MicrOp.OP_MTSPR):
1105 comb += e.xer_out.eq(1)
1106
1107 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
1108 with m.If(op.internal_op == MicrOp.OP_TRAP):
1109 # *DO NOT* call self.trap here. that would reset absolutely
1110 # everything including destroying read of RA and RB.
1111 comb += self.do_copy("trapaddr", 0x70) # strip first nibble
1112
1113 ####################
1114 # ok so the instruction's been decoded, blah blah, however
1115 # now we need to determine if it's actually going to go ahead...
1116 # *or* if in fact it's a privileged operation, whether there's
1117 # an external interrupt, etc. etc. this is a simple priority
1118 # if-elif-elif sequence. decrement takes highest priority,
1119 # EINT next highest, privileged operation third.
1120
1121 # check if instruction is privileged
1122 is_priv_insn = instr_is_priv(m, op.internal_op, e.do.insn)
1123
1124 # different IRQ conditions
1125 ext_irq_ok = Signal()
1126 dec_irq_ok = Signal()
1127 priv_ok = Signal()
1128 illeg_ok = Signal()
1129 exc = self.exc
1130
1131 comb += ext_irq_ok.eq(ext_irq & msr[MSR.EE]) # v3.0B p944 (MSR.EE)
1132 comb += dec_irq_ok.eq(dec_spr[63] & msr[MSR.EE]) # 6.5.11 p1076
1133 comb += priv_ok.eq(is_priv_insn & msr[MSR.PR])
1134 comb += illeg_ok.eq(op.internal_op == MicrOp.OP_ILLEGAL)
1135
1136 # LD/ST exceptions. TestIssuer copies the exception info at us
1137 # after a failed LD/ST.
1138 with m.If(exc.happened):
1139 with m.If(exc.alignment):
1140 self.trap(m, TT.PRIV, 0x600)
1141 with m.Elif(exc.instr_fault):
1142 with m.If(exc.segment_fault):
1143 self.trap(m, TT.PRIV, 0x480)
1144 with m.Else():
1145 # pass exception info to trap to create SRR1
1146 self.trap(m, TT.MEMEXC, 0x400, exc)
1147 with m.Else():
1148 with m.If(exc.segment_fault):
1149 self.trap(m, TT.PRIV, 0x380)
1150 with m.Else():
1151 self.trap(m, TT.PRIV, 0x300)
1152
1153 # decrement counter (v3.0B p1099): TODO 32-bit version (MSR.LPCR)
1154 with m.Elif(dec_irq_ok):
1155 self.trap(m, TT.DEC, 0x900) # v3.0B 6.5 p1065
1156
1157 # external interrupt? only if MSR.EE set
1158 with m.Elif(ext_irq_ok):
1159 self.trap(m, TT.EINT, 0x500)
1160
1161 # privileged instruction trap
1162 with m.Elif(priv_ok):
1163 self.trap(m, TT.PRIV, 0x700)
1164
1165 # illegal instruction must redirect to trap. this is done by
1166 # *overwriting* the decoded instruction and starting again.
1167 # (note: the same goes for interrupts and for privileged operations,
1168 # just with different trapaddr and traptype)
1169 with m.Elif(illeg_ok):
1170 # illegal instruction trap
1171 self.trap(m, TT.ILLEG, 0x700)
1172
1173 # no exception, just copy things to the output
1174 with m.Else():
1175 comb += e_out.eq(e)
1176
1177 ####################
1178 # follow-up after trap/irq to set up SRR0/1
1179
1180 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
1181 # Note: OP_SC could actually be modified to just be a trap
1182 with m.If((do_out.insn_type == MicrOp.OP_TRAP) |
1183 (do_out.insn_type == MicrOp.OP_SC)):
1184 # TRAP write fast1 = SRR0
1185 comb += e_out.write_fast1.data.eq(FastRegs.SRR0) # constant: SRR0
1186 comb += e_out.write_fast1.ok.eq(1)
1187 # TRAP write fast2 = SRR1
1188 comb += e_out.write_fast2.data.eq(FastRegs.SRR1) # constant: SRR1
1189 comb += e_out.write_fast2.ok.eq(1)
1190
1191 # RFID: needs to read SRR0/1
1192 with m.If(do_out.insn_type == MicrOp.OP_RFID):
1193 # TRAP read fast1 = SRR0
1194 comb += e_out.read_fast1.data.eq(FastRegs.SRR0) # constant: SRR0
1195 comb += e_out.read_fast1.ok.eq(1)
1196 # TRAP read fast2 = SRR1
1197 comb += e_out.read_fast2.data.eq(FastRegs.SRR1) # constant: SRR1
1198 comb += e_out.read_fast2.ok.eq(1)
1199
1200 # annoying simulator bug
1201 if hasattr(e_out, "asmcode") and hasattr(self.dec.op, "asmcode"):
1202 comb += e_out.asmcode.eq(self.dec.op.asmcode)
1203
1204 return m
1205
1206 def trap(self, m, traptype, trapaddr, exc=None):
1207 """trap: this basically "rewrites" the decoded instruction as a trap
1208 """
1209 comb = m.d.comb
1210 op, e = self.dec.op, self.e
1211 comb += e.eq(0) # reset eeeeeverything
1212
1213 # start again
1214 comb += self.do_copy("insn", self.dec.opcode_in, True)
1215 comb += self.do_copy("insn_type", MicrOp.OP_TRAP, True)
1216 comb += self.do_copy("fn_unit", Function.TRAP, True)
1217 comb += self.do_copy("trapaddr", trapaddr >> 4, True) # bottom 4 bits
1218 comb += self.do_copy("traptype", traptype, True) # request type
1219 comb += self.do_copy("ldst_exc", exc, True) # request type
1220 comb += self.do_copy("msr", self.state.msr, True) # copy of MSR "state"
1221 comb += self.do_copy("cia", self.state.pc, True) # copy of PC "state"
1222
1223
1224 def get_rdflags(e, cu):
1225 rdl = []
1226 for idx in range(cu.n_src):
1227 regfile, regname, _ = cu.get_in_spec(idx)
1228 rdflag, read = regspec_decode_read(e, regfile, regname)
1229 rdl.append(rdflag)
1230 print("rdflags", rdl)
1231 return Cat(*rdl)
1232
1233
1234 if __name__ == '__main__':
1235 pdecode = create_pdecode()
1236 dec2 = PowerDecode2(pdecode)
1237 vl = rtlil.convert(dec2, ports=dec2.ports() + pdecode.ports())
1238 with open("dec2.il", "w") as f:
1239 f.write(vl)