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