fix annoying alu test_pipe_caller bug, missing asmcode
[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 if hasattr(self.dec.op, "upd"):
373 # update mode LD/ST uses read-reg A also as an output
374 with m.If(self.dec.op.upd == LDSTMode.update):
375 comb += self.reg_out.eq(self.dec.RA)
376 comb += self.reg_out.ok.eq(1)
377
378 # B, BC or BCREG: potential implicit register (LR) output
379 # these give bl, bcl, bclrl, etc.
380 op = self.dec.op
381 with m.Switch(op.internal_op):
382
383 # BC* implicit register (LR)
384 with m.Case(MicrOp.OP_BC, MicrOp.OP_B, MicrOp.OP_BCREG):
385 with m.If(self.lk): # "link" mode
386 comb += self.fast_out.data.eq(FastRegs.LR) # constant: LR
387 comb += self.fast_out.ok.eq(1)
388
389 # RFID 2nd spr (fast)
390 with m.Case(MicrOp.OP_RFID):
391 comb += self.fast_out.data.eq(FastRegs.SRR1) # constant: SRR1
392 comb += self.fast_out.ok.eq(1)
393
394 return m
395
396
397 class DecodeRC(Elaboratable):
398 """DecodeRc from instruction
399
400 decodes Record bit Rc
401 """
402
403 def __init__(self, dec):
404 self.dec = dec
405 self.sel_in = Signal(RC, reset_less=True)
406 self.insn_in = Signal(32, reset_less=True)
407 self.rc_out = Data(1, "rc")
408
409 def elaborate(self, platform):
410 m = Module()
411 comb = m.d.comb
412
413 # select Record bit out field
414 with m.Switch(self.sel_in):
415 with m.Case(RC.RC):
416 comb += self.rc_out.data.eq(self.dec.Rc)
417 comb += self.rc_out.ok.eq(1)
418 with m.Case(RC.ONE):
419 comb += self.rc_out.data.eq(1)
420 comb += self.rc_out.ok.eq(1)
421 with m.Case(RC.NONE):
422 comb += self.rc_out.data.eq(0)
423 comb += self.rc_out.ok.eq(1)
424
425 return m
426
427
428 class DecodeOE(Elaboratable):
429 """DecodeOE from instruction
430
431 decodes OE field: uses RC decode detection which might not be good
432
433 -- For now, use "rc" in the decode table to decide whether oe exists.
434 -- This is not entirely correct architecturally: For mulhd and
435 -- mulhdu, the OE field is reserved. It remains to be seen what an
436 -- actual POWER9 does if we set it on those instructions, for now we
437 -- test that further down when assigning to the multiplier oe input.
438 """
439
440 def __init__(self, dec):
441 self.dec = dec
442 self.sel_in = Signal(RC, reset_less=True)
443 self.insn_in = Signal(32, reset_less=True)
444 self.oe_out = Data(1, "oe")
445
446 def elaborate(self, platform):
447 m = Module()
448 comb = m.d.comb
449 op = self.dec.op
450
451 with m.Switch(op.internal_op):
452
453 # mulhw, mulhwu, mulhd, mulhdu - these *ignore* OE
454 # also rotate
455 # XXX ARGH! ignoring OE causes incompatibility with microwatt
456 # http://lists.libre-soc.org/pipermail/libre-soc-dev/2020-August/000302.html
457 with m.Case(MicrOp.OP_MUL_H64, MicrOp.OP_MUL_H32,
458 MicrOp.OP_EXTS, MicrOp.OP_CNTZ,
459 MicrOp.OP_SHL, MicrOp.OP_SHR, MicrOp.OP_RLC,
460 MicrOp.OP_LOAD, MicrOp.OP_STORE,
461 MicrOp.OP_RLCL, MicrOp.OP_RLCR,
462 MicrOp.OP_EXTSWSLI):
463 pass
464
465 # all other ops decode OE field
466 with m.Default():
467 # select OE bit out field
468 with m.Switch(self.sel_in):
469 with m.Case(RC.RC):
470 comb += self.oe_out.data.eq(self.dec.OE)
471 comb += self.oe_out.ok.eq(1)
472
473 return m
474
475
476 class DecodeCRIn(Elaboratable):
477 """Decodes input CR from instruction
478
479 CR indices - insn fields - (not the data *in* the CR) require only 3
480 bits because they refer to CR0-CR7
481 """
482
483 def __init__(self, dec):
484 self.dec = dec
485 self.sel_in = Signal(CRInSel, reset_less=True)
486 self.insn_in = Signal(32, reset_less=True)
487 self.cr_bitfield = Data(3, "cr_bitfield")
488 self.cr_bitfield_b = Data(3, "cr_bitfield_b")
489 self.cr_bitfield_o = Data(3, "cr_bitfield_o")
490 self.whole_reg = Data(8, "cr_fxm")
491
492 def elaborate(self, platform):
493 m = Module()
494 m.submodules.ppick = ppick = PriorityPicker(8, reverse_i=True,
495 reverse_o=True)
496
497 comb = m.d.comb
498 op = self.dec.op
499
500 comb += self.cr_bitfield.ok.eq(0)
501 comb += self.cr_bitfield_b.ok.eq(0)
502 comb += self.whole_reg.ok.eq(0)
503 with m.Switch(self.sel_in):
504 with m.Case(CRInSel.NONE):
505 pass # No bitfield activated
506 with m.Case(CRInSel.CR0):
507 comb += self.cr_bitfield.data.eq(0) # CR0 (MSB0 numbering)
508 comb += self.cr_bitfield.ok.eq(1)
509 with m.Case(CRInSel.BI):
510 comb += self.cr_bitfield.data.eq(self.dec.BI[2:5])
511 comb += self.cr_bitfield.ok.eq(1)
512 with m.Case(CRInSel.BFA):
513 comb += self.cr_bitfield.data.eq(self.dec.FormX.BFA)
514 comb += self.cr_bitfield.ok.eq(1)
515 with m.Case(CRInSel.BA_BB):
516 comb += self.cr_bitfield.data.eq(self.dec.BA[2:5])
517 comb += self.cr_bitfield.ok.eq(1)
518 comb += self.cr_bitfield_b.data.eq(self.dec.BB[2:5])
519 comb += self.cr_bitfield_b.ok.eq(1)
520 comb += self.cr_bitfield_o.data.eq(self.dec.BT[2:5])
521 comb += self.cr_bitfield_o.ok.eq(1)
522 with m.Case(CRInSel.BC):
523 comb += self.cr_bitfield.data.eq(self.dec.BC[2:5])
524 comb += self.cr_bitfield.ok.eq(1)
525 with m.Case(CRInSel.WHOLE_REG):
526 comb += self.whole_reg.ok.eq(1)
527 move_one = Signal(reset_less=True)
528 comb += move_one.eq(self.insn_in[20]) # MSB0 bit 11
529 with m.If((op.internal_op == MicrOp.OP_MFCR) & move_one):
530 # must one-hot the FXM field
531 comb += ppick.i.eq(self.dec.FXM)
532 comb += self.whole_reg.data.eq(ppick.o)
533 with m.Else():
534 # otherwise use all of it
535 comb += self.whole_reg.data.eq(0xff)
536
537 return m
538
539
540 class DecodeCROut(Elaboratable):
541 """Decodes input CR from instruction
542
543 CR indices - insn fields - (not the data *in* the CR) require only 3
544 bits because they refer to CR0-CR7
545 """
546
547 def __init__(self, dec):
548 self.dec = dec
549 self.rc_in = Signal(reset_less=True)
550 self.sel_in = Signal(CROutSel, reset_less=True)
551 self.insn_in = Signal(32, reset_less=True)
552 self.cr_bitfield = Data(3, "cr_bitfield")
553 self.whole_reg = Data(8, "cr_fxm")
554
555 def elaborate(self, platform):
556 m = Module()
557 comb = m.d.comb
558 op = self.dec.op
559 m.submodules.ppick = ppick = PriorityPicker(8, reverse_i=True,
560 reverse_o=True)
561
562 comb += self.cr_bitfield.ok.eq(0)
563 comb += self.whole_reg.ok.eq(0)
564 with m.Switch(self.sel_in):
565 with m.Case(CROutSel.NONE):
566 pass # No bitfield activated
567 with m.Case(CROutSel.CR0):
568 comb += self.cr_bitfield.data.eq(0) # CR0 (MSB0 numbering)
569 comb += self.cr_bitfield.ok.eq(self.rc_in) # only when RC=1
570 with m.Case(CROutSel.BF):
571 comb += self.cr_bitfield.data.eq(self.dec.FormX.BF)
572 comb += self.cr_bitfield.ok.eq(1)
573 with m.Case(CROutSel.BT):
574 comb += self.cr_bitfield.data.eq(self.dec.FormXL.BT[2:5])
575 comb += self.cr_bitfield.ok.eq(1)
576 with m.Case(CROutSel.WHOLE_REG):
577 comb += self.whole_reg.ok.eq(1)
578 move_one = Signal(reset_less=True)
579 comb += move_one.eq(self.insn_in[20])
580 with m.If((op.internal_op == MicrOp.OP_MTCRF)):
581 with m.If(move_one):
582 # must one-hot the FXM field
583 comb += ppick.i.eq(self.dec.FXM)
584 with m.If(ppick.en_o):
585 comb += self.whole_reg.data.eq(ppick.o)
586 with m.Else():
587 comb += self.whole_reg.data.eq(0b00000001) # CR7
588 with m.Else():
589 comb += self.whole_reg.data.eq(self.dec.FXM)
590 with m.Else():
591 # otherwise use all of it
592 comb += self.whole_reg.data.eq(0xff)
593
594 return m
595
596 # dictionary of Input Record field names that, if they exist,
597 # will need a corresponding CSV Decoder file column (actually, PowerOp)
598 # to be decoded (this includes the single bit names)
599 record_names = {'insn_type': 'internal_op',
600 'fn_unit': 'function_unit',
601 'rc': 'rc_sel',
602 'oe': 'rc_sel',
603 'zero_a': 'in1_sel',
604 'imm_data': 'in2_sel',
605 'invert_in': 'inv_a',
606 'invert_out': 'inv_out',
607 'rc': 'cr_out',
608 'oe': 'cr_in',
609 'output_carry': 'cry_out',
610 'input_carry': 'cry_in',
611 'is_32bit': 'is_32b',
612 'is_signed': 'sgn',
613 'lk': 'lk',
614 'data_len': 'ldst_len',
615 'byte_reverse': 'br',
616 'sign_extend': 'sgn_ext',
617 'ldst_mode': 'upd',
618 }
619
620
621 class PowerDecodeSubset(Elaboratable):
622 """PowerDecodeSubset: dynamic subset decoder
623
624 """
625
626 def __init__(self, dec, opkls=None, fn_name=None,
627 final=False, state=None):
628
629 self.final = final
630 self.opkls = opkls
631 self.fn_name = fn_name
632 self.e = Decode2ToExecute1Type(name=self.fn_name, opkls=self.opkls)
633 col_subset = self.get_col_subset(self.e.do)
634
635 if dec is None:
636 dec = create_pdecode(name=fn_name, col_subset=col_subset,
637 row_subset=self.rowsubsetfn)
638 self.dec = dec
639
640 # state information needed by the Decoder
641 if state is None:
642 state = CoreState("dec2")
643 self.state = state
644
645 def get_col_subset(self, do):
646 subset = {'cr_in', 'cr_out', 'rc_sel'} # needed, non-optional
647 for k, v in record_names.items():
648 if hasattr(do, k):
649 subset.add(v)
650 print ("get_col_subset", self.fn_name, do.fields, subset)
651 return subset
652
653 def rowsubsetfn(self, opcode, row):
654 return row['unit'] == self.fn_name
655
656 def ports(self):
657 return self.dec.ports() + self.e.ports()
658
659 def needs_field(self, field, op_field):
660 if self.final:
661 do = self.e.do
662 else:
663 do = self.e_tmp.do
664 return hasattr(do, field) and self.op_get(op_field) is not None
665
666 def do_copy(self, field, val, final=False):
667 if final or self.final:
668 do = self.e.do
669 else:
670 do = self.e_tmp.do
671 if hasattr(do, field) and val is not None:
672 return getattr(do, field).eq(val)
673 return []
674
675 def op_get(self, op_field):
676 return getattr(self.dec.op, op_field, None)
677
678 def elaborate(self, platform):
679 m = Module()
680 comb = m.d.comb
681 state = self.state
682 e_out, op, do_out = self.e, self.dec.op, self.e.do
683 msr, cia = state.msr, state.pc
684
685 # fill in for a normal instruction (not an exception)
686 # copy over if non-exception, non-privileged etc. is detected
687 if self.final:
688 e = self.e
689 else:
690 if self.fn_name is None:
691 name = "tmp"
692 else:
693 name = self.fn_name + "tmp"
694 self.e_tmp = e = Decode2ToExecute1Type(name=name, opkls=self.opkls)
695 do = e.do
696
697 # set up submodule decoders
698 m.submodules.dec = self.dec
699 m.submodules.dec_rc = dec_rc = DecodeRC(self.dec)
700 m.submodules.dec_oe = dec_oe = DecodeOE(self.dec)
701 m.submodules.dec_cr_in = self.dec_cr_in = DecodeCRIn(self.dec)
702 m.submodules.dec_cr_out = self.dec_cr_out = DecodeCROut(self.dec)
703
704 # copy instruction through...
705 for i in [do.insn,
706 dec_rc.insn_in, dec_oe.insn_in,
707 self.dec_cr_in.insn_in, self.dec_cr_out.insn_in]:
708 comb += i.eq(self.dec.opcode_in)
709
710 # ...and subdecoders' input fields
711 comb += dec_rc.sel_in.eq(op.rc_sel)
712 comb += dec_oe.sel_in.eq(op.rc_sel) # XXX should be OE sel
713 comb += self.dec_cr_in.sel_in.eq(op.cr_in)
714 comb += self.dec_cr_out.sel_in.eq(op.cr_out)
715 comb += self.dec_cr_out.rc_in.eq(dec_rc.rc_out.data)
716
717 # copy "state" over
718 comb += self.do_copy("msr", msr)
719 comb += self.do_copy("cia", cia)
720
721 # set up instruction, pick fn unit
722 # no op: defaults to OP_ILLEGAL
723 comb += self.do_copy("insn_type", self.op_get("internal_op"))
724 comb += self.do_copy("fn_unit", self.op_get("function_unit"))
725
726 # immediates
727 if self.needs_field("zero_a", "in1_sel"):
728 m.submodules.dec_ai = dec_ai = DecodeAImm(self.dec)
729 comb += dec_ai.sel_in.eq(op.in1_sel)
730 comb += self.do_copy("zero_a", dec_ai.immz_out) # RA==0 detected
731 if self.needs_field("imm_data", "in2_sel"):
732 m.submodules.dec_bi = dec_bi = DecodeBImm(self.dec)
733 comb += dec_bi.sel_in.eq(op.in2_sel)
734 comb += self.do_copy("imm_data", dec_bi.imm_out) # imm in RB
735
736 # rc and oe out
737 comb += self.do_copy("rc", dec_rc.rc_out)
738 comb += self.do_copy("oe", dec_oe.oe_out)
739
740 # CR in/out
741 comb += self.do_copy("read_cr_whole", self.dec_cr_in.whole_reg)
742 comb += self.do_copy("write_cr_whole", self.dec_cr_out.whole_reg)
743 comb += self.do_copy("write_cr0", self.dec_cr_out.cr_bitfield.ok)
744
745 comb += self.do_copy("input_cr", self.op_get("cr_in")) # CR in
746 comb += self.do_copy("output_cr", self.op_get("cr_out")) # CR out
747
748 # decoded/selected instruction flags
749 comb += self.do_copy("data_len", self.op_get("ldst_len"))
750 comb += self.do_copy("invert_in", self.op_get("inv_a"))
751 comb += self.do_copy("invert_out", self.op_get("inv_out"))
752 comb += self.do_copy("input_carry", self.op_get("cry_in"))
753 comb += self.do_copy("output_carry", self.op_get("cry_out"))
754 comb += self.do_copy("is_32bit", self.op_get("is_32b"))
755 comb += self.do_copy("is_signed", self.op_get("sgn"))
756 lk = self.op_get("lk")
757 if lk is not None:
758 with m.If(lk):
759 comb += self.do_copy("lk", self.dec.LK) # XXX TODO: accessor
760
761 comb += self.do_copy("byte_reverse", self.op_get("br"))
762 comb += self.do_copy("sign_extend", self.op_get("sgn_ext"))
763 comb += self.do_copy("ldst_mode", self.op_get("upd")) # LD/ST mode
764
765 return m
766
767
768 class PowerDecode2(PowerDecodeSubset):
769 """PowerDecode2: the main instruction decoder.
770
771 whilst PowerDecode is responsible for decoding the actual opcode, this
772 module encapsulates further specialist, sparse information and
773 expansion of fields that is inconvenient to have in the CSV files.
774 for example: the encoding of the immediates, which are detected
775 and expanded out to their full value from an annotated (enum)
776 representation.
777
778 implicit register usage is also set up, here. for example: OP_BC
779 requires implicitly reading CTR, OP_RFID requires implicitly writing
780 to SRR1 and so on.
781
782 in addition, PowerDecoder2 is responsible for detecting whether
783 instructions are illegal (or privileged) or not, and instead of
784 just leaving at that, *replacing* the instruction to execute with
785 a suitable alternative (trap).
786 """
787
788 def get_col_subset(self, opkls):
789 subset = super().get_col_subset(opkls)
790 subset.add("in1_sel")
791 subset.add("asmcode")
792 subset.add("in2_sel")
793 subset.add("in3_sel")
794 subset.add("out_sel")
795 subset.add("lk")
796 subset.add("internal_op")
797 subset.add("form")
798 return subset
799
800 def elaborate(self, platform):
801 m = super().elaborate(platform)
802 comb = m.d.comb
803 state = self.state
804 e_out, op, do_out = self.e, self.dec.op, self.e.do
805 dec_spr, msr, cia, ext_irq = state.dec, state.msr, state.pc, state.eint
806 e = self.e_tmp
807 do = e.do
808
809 # fill in for a normal instruction (not an exception)
810 # copy over if non-exception, non-privileged etc. is detected
811
812 # set up submodule decoders
813 m.submodules.dec_a = dec_a = DecodeA(self.dec)
814 m.submodules.dec_b = dec_b = DecodeB(self.dec)
815 m.submodules.dec_c = dec_c = DecodeC(self.dec)
816 m.submodules.dec_o = dec_o = DecodeOut(self.dec)
817 m.submodules.dec_o2 = dec_o2 = DecodeOut2(self.dec)
818
819 # copy instruction through...
820 for i in [do.insn, dec_a.insn_in, dec_b.insn_in,
821 dec_c.insn_in, dec_o.insn_in, dec_o2.insn_in]:
822 comb += i.eq(self.dec.opcode_in)
823
824 # ...and subdecoders' input fields
825 comb += dec_a.sel_in.eq(op.in1_sel)
826 comb += dec_b.sel_in.eq(op.in2_sel)
827 comb += dec_c.sel_in.eq(op.in3_sel)
828 comb += dec_o.sel_in.eq(op.out_sel)
829 comb += dec_o2.sel_in.eq(op.out_sel)
830 if hasattr(do, "lk"):
831 comb += dec_o2.lk.eq(do.lk)
832
833 # registers a, b, c and out and out2 (LD/ST EA)
834 comb += e.read_reg1.eq(dec_a.reg_out)
835 comb += e.read_reg2.eq(dec_b.reg_out)
836 comb += e.read_reg3.eq(dec_c.reg_out)
837 comb += e.write_reg.eq(dec_o.reg_out)
838 comb += e.write_ea.eq(dec_o2.reg_out)
839
840 # SPRs out
841 comb += e.read_spr1.eq(dec_a.spr_out)
842 comb += e.write_spr.eq(dec_o.spr_out)
843
844 # Fast regs out
845 comb += e.read_fast1.eq(dec_a.fast_out)
846 comb += e.read_fast2.eq(dec_b.fast_out)
847 comb += e.write_fast1.eq(dec_o.fast_out)
848 comb += e.write_fast2.eq(dec_o2.fast_out)
849
850 # condition registers (CR)
851 comb += e.read_cr1.eq(self.dec_cr_in.cr_bitfield)
852 comb += e.read_cr2.eq(self.dec_cr_in.cr_bitfield_b)
853 comb += e.read_cr3.eq(self.dec_cr_in.cr_bitfield_o)
854 comb += e.write_cr.eq(self.dec_cr_out.cr_bitfield)
855
856 # sigh this is exactly the sort of thing for which the
857 # decoder is designed to not need. MTSPR, MFSPR and others need
858 # access to the XER bits. however setting e.oe is not appropriate
859 with m.If(op.internal_op == MicrOp.OP_MFSPR):
860 comb += e.xer_in.eq(0b111) # SO, CA, OV
861 with m.If(op.internal_op == MicrOp.OP_CMP):
862 comb += e.xer_in.eq(1<<XERRegs.SO) # SO
863 with m.If(op.internal_op == MicrOp.OP_MTSPR):
864 comb += e.xer_out.eq(1)
865
866 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
867 with m.If(op.internal_op == MicrOp.OP_TRAP):
868 # *DO NOT* call self.trap here. that would reset absolutely
869 # everything including destroying read of RA and RB.
870 comb += self.do_copy("trapaddr", 0x70) # strip first nibble
871
872 ####################
873 # ok so the instruction's been decoded, blah blah, however
874 # now we need to determine if it's actually going to go ahead...
875 # *or* if in fact it's a privileged operation, whether there's
876 # an external interrupt, etc. etc. this is a simple priority
877 # if-elif-elif sequence. decrement takes highest priority,
878 # EINT next highest, privileged operation third.
879
880 # check if instruction is privileged
881 is_priv_insn = instr_is_priv(m, op.internal_op, e.do.insn)
882
883 # different IRQ conditions
884 ext_irq_ok = Signal()
885 dec_irq_ok = Signal()
886 priv_ok = Signal()
887 illeg_ok = Signal()
888
889 comb += ext_irq_ok.eq(ext_irq & msr[MSR.EE]) # v3.0B p944 (MSR.EE)
890 comb += dec_irq_ok.eq(dec_spr[63] & msr[MSR.EE]) # v3.0B 6.5.11 p1076
891 comb += priv_ok.eq(is_priv_insn & msr[MSR.PR])
892 comb += illeg_ok.eq(op.internal_op == MicrOp.OP_ILLEGAL)
893
894 # decrement counter (v3.0B p1099): TODO 32-bit version (MSR.LPCR)
895 with m.If(dec_irq_ok):
896 self.trap(m, TT.DEC, 0x900) # v3.0B 6.5 p1065
897
898 # external interrupt? only if MSR.EE set
899 with m.Elif(ext_irq_ok):
900 self.trap(m, TT.EINT, 0x500)
901
902 # privileged instruction trap
903 with m.Elif(priv_ok):
904 self.trap(m, TT.PRIV, 0x700)
905
906 # illegal instruction must redirect to trap. this is done by
907 # *overwriting* the decoded instruction and starting again.
908 # (note: the same goes for interrupts and for privileged operations,
909 # just with different trapaddr and traptype)
910 with m.Elif(illeg_ok):
911 # illegal instruction trap
912 self.trap(m, TT.ILLEG, 0x700)
913
914 # no exception, just copy things to the output
915 with m.Else():
916 comb += e_out.eq(e)
917
918 ####################
919 # follow-up after trap/irq to set up SRR0/1
920
921 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
922 # Note: OP_SC could actually be modified to just be a trap
923 with m.If((do_out.insn_type == MicrOp.OP_TRAP) |
924 (do_out.insn_type == MicrOp.OP_SC)):
925 # TRAP write fast1 = SRR0
926 comb += e_out.write_fast1.data.eq(FastRegs.SRR0) # constant: SRR0
927 comb += e_out.write_fast1.ok.eq(1)
928 # TRAP write fast2 = SRR1
929 comb += e_out.write_fast2.data.eq(FastRegs.SRR1) # constant: SRR1
930 comb += e_out.write_fast2.ok.eq(1)
931
932 # RFID: needs to read SRR0/1
933 with m.If(do_out.insn_type == MicrOp.OP_RFID):
934 # TRAP read fast1 = SRR0
935 comb += e_out.read_fast1.data.eq(FastRegs.SRR0) # constant: SRR0
936 comb += e_out.read_fast1.ok.eq(1)
937 # TRAP read fast2 = SRR1
938 comb += e_out.read_fast2.data.eq(FastRegs.SRR1) # constant: SRR1
939 comb += e_out.read_fast2.ok.eq(1)
940
941 # annoying simulator bug
942 if hasattr(e_out, "asmcode") and hasattr(self.dec.op, "asmcode"):
943 comb += e_out.asmcode.eq(self.dec.op.asmcode)
944
945 return m
946
947 def trap(self, m, traptype, trapaddr):
948 """trap: this basically "rewrites" the decoded instruction as a trap
949 """
950 comb = m.d.comb
951 op, e = self.dec.op, self.e
952 comb += e.eq(0) # reset eeeeeverything
953
954 # start again
955 comb += self.do_copy("insn", self.dec.opcode_in, True)
956 comb += self.do_copy("insn_type", MicrOp.OP_TRAP, True)
957 comb += self.do_copy("fn_unit", Function.TRAP, True)
958 comb += self.do_copy("trapaddr", trapaddr >> 4, True) # bottom 4 bits
959 comb += self.do_copy("traptype", traptype, True) # request type
960 comb += self.do_copy("msr", self.state.msr, True) # copy of MSR "state"
961 comb += self.do_copy("cia", self.state.pc, True) # copy of PC "state"
962
963
964 def get_rdflags(e, cu):
965 rdl = []
966 for idx in range(cu.n_src):
967 regfile, regname, _ = cu.get_in_spec(idx)
968 rdflag, read = regspec_decode_read(e, regfile, regname)
969 rdl.append(rdflag)
970 print("rdflags", rdl)
971 return Cat(*rdl)
972
973
974 if __name__ == '__main__':
975 pdecode = create_pdecode()
976 dec2 = PowerDecode2(pdecode)
977 vl = rtlil.convert(dec2, ports=dec2.ports() + pdecode.ports())
978 with open("dec2.il", "w") as f:
979 f.write(vl)