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