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