investigating CR mtocrf / mfocrf
[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
12 from nmutil.picker import PriorityPicker
13 from nmutil.iocontrol import RecordObject
14 from nmutil.extend import exts
15
16 from soc.decoder.power_regspec_map import regspec_decode_read
17 from soc.decoder.power_regspec_map import regspec_decode_write
18 from soc.decoder.power_decoder import create_pdecode
19 from soc.decoder.power_enums import (MicrOp, CryIn, Function,
20 CRInSel, CROutSel,
21 LdstLen, In1Sel, In2Sel, In3Sel,
22 OutSel, SPR, RC, LDSTMode)
23 from soc.decoder.decode2execute1 import Decode2ToExecute1Type, Data
24 from soc.consts import MSR
25
26 from soc.regfile.regfiles import FastRegs
27 from soc.consts import TT
28 from soc.config.state import CoreState
29
30
31 def decode_spr_num(spr):
32 return Cat(spr[5:10], spr[0:5])
33
34
35 def instr_is_priv(m, op, insn):
36 """determines if the instruction is privileged or not
37 """
38 comb = m.d.comb
39 is_priv_insn = Signal(reset_less=True)
40 with m.Switch(op):
41 with m.Case(MicrOp.OP_ATTN, MicrOp.OP_MFMSR, MicrOp.OP_MTMSRD,
42 MicrOp.OP_MTMSR, MicrOp.OP_RFID):
43 comb += is_priv_insn.eq(1)
44 # XXX TODO
45 #with m.Case(MicrOp.OP_TLBIE) : comb += is_priv_insn.eq(1)
46 with m.Case(MicrOp.OP_MFSPR, MicrOp.OP_MTSPR):
47 with m.If(insn[20]): # field XFX.spr[-1] i think
48 comb += is_priv_insn.eq(1)
49 return is_priv_insn
50
51
52 class SPRMap(Elaboratable):
53 """SPRMap: maps POWER9 SPR numbers to internal enum values
54 """
55
56 def __init__(self):
57 self.spr_i = Signal(10, reset_less=True)
58 self.spr_o = Signal(SPR, reset_less=True)
59
60 def elaborate(self, platform):
61 m = Module()
62 with m.Switch(self.spr_i):
63 for i, x in enumerate(SPR):
64 with m.Case(x.value):
65 m.d.comb += self.spr_o.eq(i)
66 return m
67
68
69 class DecodeA(Elaboratable):
70 """DecodeA from instruction
71
72 decodes register RA, whether immediate-zero, implicit and
73 explicit CSRs
74 """
75
76 def __init__(self, dec):
77 self.dec = dec
78 self.sel_in = Signal(In1Sel, reset_less=True)
79 self.insn_in = Signal(32, reset_less=True)
80 self.reg_out = Data(5, name="reg_a")
81 self.immz_out = Signal(reset_less=True)
82 self.spr_out = Data(SPR, "spr_a")
83 self.fast_out = Data(3, "fast_a")
84
85 def elaborate(self, platform):
86 m = Module()
87 comb = m.d.comb
88 m.submodules.sprmap = sprmap = SPRMap()
89
90 # select Register A field
91 ra = Signal(5, reset_less=True)
92 comb += ra.eq(self.dec.RA)
93 with m.If((self.sel_in == In1Sel.RA) |
94 ((self.sel_in == In1Sel.RA_OR_ZERO) &
95 (ra != Const(0, 5)))):
96 comb += self.reg_out.data.eq(ra)
97 comb += self.reg_out.ok.eq(1)
98
99 # zero immediate requested
100 with m.If((self.sel_in == In1Sel.RA_OR_ZERO) &
101 (self.reg_out.data == Const(0, 5))):
102 comb += self.immz_out.eq(1)
103
104 # some Logic/ALU ops have RS as the 3rd arg, but no "RA".
105 with m.If(self.sel_in == In1Sel.RS):
106 comb += self.reg_out.data.eq(self.dec.RS)
107 comb += self.reg_out.ok.eq(1)
108
109 # decode Fast-SPR based on instruction type
110 op = self.dec.op
111 with m.Switch(op.internal_op):
112
113 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeOut
114 with m.Case(MicrOp.OP_BC):
115 with m.If(~self.dec.BO[2]): # 3.0B p38 BO2=0, use CTR reg
116 # constant: CTR
117 comb += self.fast_out.data.eq(FastRegs.CTR)
118 comb += self.fast_out.ok.eq(1)
119 with m.Case(MicrOp.OP_BCREG):
120 xo9 = self.dec.FormXL.XO[9] # 3.0B p38 top bit of XO
121 xo5 = self.dec.FormXL.XO[5] # 3.0B p38
122 with m.If(xo9 & ~xo5):
123 # constant: CTR
124 comb += self.fast_out.data.eq(FastRegs.CTR)
125 comb += self.fast_out.ok.eq(1)
126
127 # MFSPR move from SPRs
128 with m.Case(MicrOp.OP_MFSPR):
129 spr = Signal(10, reset_less=True)
130 comb += spr.eq(decode_spr_num(self.dec.SPR)) # from XFX
131 with m.Switch(spr):
132 # fast SPRs
133 with m.Case(SPR.CTR.value):
134 comb += self.fast_out.data.eq(FastRegs.CTR)
135 comb += self.fast_out.ok.eq(1)
136 with m.Case(SPR.LR.value):
137 comb += self.fast_out.data.eq(FastRegs.LR)
138 comb += self.fast_out.ok.eq(1)
139 with m.Case(SPR.TAR.value):
140 comb += self.fast_out.data.eq(FastRegs.TAR)
141 comb += self.fast_out.ok.eq(1)
142 with m.Case(SPR.SRR0.value):
143 comb += self.fast_out.data.eq(FastRegs.SRR0)
144 comb += self.fast_out.ok.eq(1)
145 with m.Case(SPR.SRR1.value):
146 comb += self.fast_out.data.eq(FastRegs.SRR1)
147 comb += self.fast_out.ok.eq(1)
148 with m.Case(SPR.XER.value):
149 pass # do nothing
150 # : map to internal SPR numbers
151 # XXX TODO: dec and tb not to go through mapping.
152 with m.Default():
153 comb += sprmap.spr_i.eq(spr)
154 comb += self.spr_out.data.eq(sprmap.spr_o)
155 comb += self.spr_out.ok.eq(1)
156
157 return m
158
159
160 class DecodeB(Elaboratable):
161 """DecodeB from instruction
162
163 decodes register RB, different forms of immediate (signed, unsigned),
164 and implicit SPRs. register B is basically "lane 2" into the CompUnits.
165 by industry-standard convention, "lane 2" is where fully-decoded
166 immediates are muxed in.
167 """
168
169 def __init__(self, dec):
170 self.dec = dec
171 self.sel_in = Signal(In2Sel, reset_less=True)
172 self.insn_in = Signal(32, reset_less=True)
173 self.reg_out = Data(5, "reg_b")
174 self.imm_out = Data(64, "imm_b")
175 self.fast_out = Data(3, "fast_b")
176
177 def elaborate(self, platform):
178 m = Module()
179 comb = m.d.comb
180
181 # select Register B field
182 with m.Switch(self.sel_in):
183 with m.Case(In2Sel.RB):
184 comb += self.reg_out.data.eq(self.dec.RB)
185 comb += self.reg_out.ok.eq(1)
186 with m.Case(In2Sel.RS):
187 # for M-Form shiftrot
188 comb += self.reg_out.data.eq(self.dec.RS)
189 comb += self.reg_out.ok.eq(1)
190 with m.Case(In2Sel.CONST_UI): # unsigned
191 comb += self.imm_out.data.eq(self.dec.UI)
192 comb += self.imm_out.ok.eq(1)
193 with m.Case(In2Sel.CONST_SI): # sign-extended 16-bit
194 si = Signal(16, reset_less=True)
195 comb += si.eq(self.dec.SI)
196 comb += self.imm_out.data.eq(exts(si, 16, 64))
197 comb += self.imm_out.ok.eq(1)
198 with m.Case(In2Sel.CONST_SI_HI): # sign-extended 16+16=32 bit
199 si_hi = Signal(32, reset_less=True)
200 comb += si_hi.eq(self.dec.SI << 16)
201 comb += self.imm_out.data.eq(exts(si_hi, 32, 64))
202 comb += self.imm_out.ok.eq(1)
203 with m.Case(In2Sel.CONST_UI_HI): # unsigned
204 ui = Signal(16, reset_less=True)
205 comb += ui.eq(self.dec.UI)
206 comb += self.imm_out.data.eq(ui << 16)
207 comb += self.imm_out.ok.eq(1)
208 with m.Case(In2Sel.CONST_LI): # sign-extend 24+2=26 bit
209 li = Signal(26, reset_less=True)
210 comb += li.eq(self.dec.LI << 2)
211 comb += self.imm_out.data.eq(exts(li, 26, 64))
212 comb += self.imm_out.ok.eq(1)
213 with m.Case(In2Sel.CONST_BD): # sign-extend (14+2)=16 bit
214 bd = Signal(16, reset_less=True)
215 comb += bd.eq(self.dec.BD << 2)
216 comb += self.imm_out.data.eq(exts(bd, 16, 64))
217 comb += self.imm_out.ok.eq(1)
218 with m.Case(In2Sel.CONST_DS): # sign-extended (14+2=16) bit
219 ds = Signal(16, reset_less=True)
220 comb += ds.eq(self.dec.DS << 2)
221 comb += self.imm_out.data.eq(exts(ds, 16, 64))
222 comb += self.imm_out.ok.eq(1)
223 with m.Case(In2Sel.CONST_M1): # signed (-1)
224 comb += self.imm_out.data.eq(~Const(0, 64)) # all 1s
225 comb += self.imm_out.ok.eq(1)
226 with m.Case(In2Sel.CONST_SH): # unsigned - for shift
227 comb += self.imm_out.data.eq(self.dec.sh)
228 comb += self.imm_out.ok.eq(1)
229 with m.Case(In2Sel.CONST_SH32): # unsigned - for shift
230 comb += self.imm_out.data.eq(self.dec.SH32)
231 comb += self.imm_out.ok.eq(1)
232
233 # decode SPR2 based on instruction type
234 op = self.dec.op
235 # BCREG implicitly uses LR or TAR for 2nd reg
236 # CTR however is already in fast_spr1 *not* 2.
237 with m.If(op.internal_op == MicrOp.OP_BCREG):
238 xo9 = self.dec.FormXL.XO[9] # 3.0B p38 top bit of XO
239 xo5 = self.dec.FormXL.XO[5] # 3.0B p38
240 with m.If(~xo9):
241 comb += self.fast_out.data.eq(FastRegs.LR)
242 comb += self.fast_out.ok.eq(1)
243 with m.Elif(xo5):
244 comb += self.fast_out.data.eq(FastRegs.TAR)
245 comb += self.fast_out.ok.eq(1)
246
247 return m
248
249
250 class DecodeC(Elaboratable):
251 """DecodeC from instruction
252
253 decodes register RC. this is "lane 3" into some CompUnits (not many)
254 """
255
256 def __init__(self, dec):
257 self.dec = dec
258 self.sel_in = Signal(In3Sel, reset_less=True)
259 self.insn_in = Signal(32, reset_less=True)
260 self.reg_out = Data(5, "reg_c")
261
262 def elaborate(self, platform):
263 m = Module()
264 comb = m.d.comb
265
266 # select Register C field
267 with m.Switch(self.sel_in):
268 with m.Case(In3Sel.RB):
269 # for M-Form shiftrot
270 comb += self.reg_out.data.eq(self.dec.RB)
271 comb += self.reg_out.ok.eq(1)
272 with m.Case(In3Sel.RS):
273 comb += self.reg_out.data.eq(self.dec.RS)
274 comb += self.reg_out.ok.eq(1)
275
276 return m
277
278
279 class DecodeOut(Elaboratable):
280 """DecodeOut from instruction
281
282 decodes output register RA, RT or SPR
283 """
284
285 def __init__(self, dec):
286 self.dec = dec
287 self.sel_in = Signal(OutSel, reset_less=True)
288 self.insn_in = Signal(32, reset_less=True)
289 self.reg_out = Data(5, "reg_o")
290 self.spr_out = Data(SPR, "spr_o")
291 self.fast_out = Data(3, "fast_o")
292
293 def elaborate(self, platform):
294 m = Module()
295 comb = m.d.comb
296 m.submodules.sprmap = sprmap = SPRMap()
297 op = self.dec.op
298
299 # select Register out field
300 with m.Switch(self.sel_in):
301 with m.Case(OutSel.RT):
302 comb += self.reg_out.data.eq(self.dec.RT)
303 comb += self.reg_out.ok.eq(1)
304 with m.Case(OutSel.RA):
305 comb += self.reg_out.data.eq(self.dec.RA)
306 comb += self.reg_out.ok.eq(1)
307 with m.Case(OutSel.SPR):
308 spr = Signal(10, reset_less=True)
309 comb += spr.eq(decode_spr_num(self.dec.SPR)) # from XFX
310 # TODO MTSPR 1st spr (fast)
311 with m.If(op.internal_op == MicrOp.OP_MTSPR):
312 with m.Switch(spr):
313 # fast SPRs
314 with m.Case(SPR.CTR.value):
315 comb += self.fast_out.data.eq(FastRegs.CTR)
316 comb += self.fast_out.ok.eq(1)
317 with m.Case(SPR.LR.value):
318 comb += self.fast_out.data.eq(FastRegs.LR)
319 comb += self.fast_out.ok.eq(1)
320 with m.Case(SPR.TAR.value):
321 comb += self.fast_out.data.eq(FastRegs.TAR)
322 comb += self.fast_out.ok.eq(1)
323 with m.Case(SPR.SRR0.value):
324 comb += self.fast_out.data.eq(FastRegs.SRR0)
325 comb += self.fast_out.ok.eq(1)
326 with m.Case(SPR.SRR1.value):
327 comb += self.fast_out.data.eq(FastRegs.SRR1)
328 comb += self.fast_out.ok.eq(1)
329 with m.Case(SPR.XER.value):
330 pass # do nothing
331 # : map to internal SPR numbers
332 # XXX TODO: dec and tb not to go through mapping.
333 with m.Default():
334 comb += sprmap.spr_i.eq(spr)
335 comb += self.spr_out.data.eq(sprmap.spr_o)
336 comb += self.spr_out.ok.eq(1)
337
338 with m.Switch(op.internal_op):
339
340 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeA
341 with m.Case(MicrOp.OP_BC, MicrOp.OP_BCREG):
342 with m.If(~self.dec.BO[2]): # 3.0B p38 BO2=0, use CTR reg
343 # constant: CTR
344 comb += self.fast_out.data.eq(FastRegs.CTR)
345 comb += self.fast_out.ok.eq(1)
346
347 # RFID 1st spr (fast)
348 with m.Case(MicrOp.OP_RFID):
349 comb += self.fast_out.data.eq(FastRegs.SRR0) # constant: SRR0
350 comb += self.fast_out.ok.eq(1)
351
352 return m
353
354
355 class DecodeOut2(Elaboratable):
356 """DecodeOut2 from instruction
357
358 decodes output registers
359 """
360
361 def __init__(self, dec):
362 self.dec = dec
363 self.sel_in = Signal(OutSel, reset_less=True)
364 self.lk = Signal(reset_less=True)
365 self.insn_in = Signal(32, reset_less=True)
366 self.reg_out = Data(5, "reg_o")
367 self.fast_out = Data(3, "fast_o")
368
369 def elaborate(self, platform):
370 m = Module()
371 comb = m.d.comb
372
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_SHL, MicrOp.OP_SHR, MicrOp.OP_RLC,
459 MicrOp.OP_RLCL, MicrOp.OP_RLCR,
460 MicrOp.OP_EXTSWSLI):
461 pass
462
463 # all other ops decode OE field
464 with m.Default():
465 # select OE bit out field
466 with m.Switch(self.sel_in):
467 with m.Case(RC.RC):
468 comb += self.oe_out.data.eq(self.dec.OE)
469 comb += self.oe_out.ok.eq(1)
470
471 return m
472
473
474 class DecodeCRIn(Elaboratable):
475 """Decodes input CR from instruction
476
477 CR indices - insn fields - (not the data *in* the CR) require only 3
478 bits because they refer to CR0-CR7
479 """
480
481 def __init__(self, dec):
482 self.dec = dec
483 self.sel_in = Signal(CRInSel, reset_less=True)
484 self.insn_in = Signal(32, reset_less=True)
485 self.cr_bitfield = Data(3, "cr_bitfield")
486 self.cr_bitfield_b = Data(3, "cr_bitfield_b")
487 self.cr_bitfield_o = Data(3, "cr_bitfield_o")
488 self.whole_reg = Data(8, "cr_fxm")
489
490 def elaborate(self, platform):
491 m = Module()
492 m.submodules.ppick = ppick = PriorityPicker(8, reverse_i=True,
493 reverse_o=True)
494
495 comb = m.d.comb
496 op = self.dec.op
497
498 comb += self.cr_bitfield.ok.eq(0)
499 comb += self.cr_bitfield_b.ok.eq(0)
500 comb += self.whole_reg.ok.eq(0)
501 with m.Switch(self.sel_in):
502 with m.Case(CRInSel.NONE):
503 pass # No bitfield activated
504 with m.Case(CRInSel.CR0):
505 comb += self.cr_bitfield.data.eq(0)
506 comb += self.cr_bitfield.ok.eq(1)
507 with m.Case(CRInSel.BI):
508 comb += self.cr_bitfield.data.eq(self.dec.BI[2:5])
509 comb += self.cr_bitfield.ok.eq(1)
510 with m.Case(CRInSel.BFA):
511 comb += self.cr_bitfield.data.eq(self.dec.FormX.BFA)
512 comb += self.cr_bitfield.ok.eq(1)
513 with m.Case(CRInSel.BA_BB):
514 comb += self.cr_bitfield.data.eq(self.dec.BA[2:5])
515 comb += self.cr_bitfield.ok.eq(1)
516 comb += self.cr_bitfield_b.data.eq(self.dec.BB[2:5])
517 comb += self.cr_bitfield_b.ok.eq(1)
518 comb += self.cr_bitfield_o.data.eq(self.dec.BT[2:5])
519 comb += self.cr_bitfield_o.ok.eq(1)
520 with m.Case(CRInSel.BC):
521 comb += self.cr_bitfield.data.eq(self.dec.BC[2:5])
522 comb += self.cr_bitfield.ok.eq(1)
523 with m.Case(CRInSel.WHOLE_REG):
524 comb += self.whole_reg.ok.eq(1)
525 move_one = Signal(reset_less=True)
526 comb += move_one.eq(self.insn_in[20]) # MSB0 bit 11
527 with m.If((op.internal_op == MicrOp.OP_MFCR) & move_one):
528 # must one-hot the FXM field
529 comb += ppick.i.eq(self.dec.FXM)
530 comb += self.whole_reg.data.eq(ppick.o)
531 with m.Else():
532 # otherwise use all of it
533 comb += self.whole_reg.data.eq(0xff)
534
535 return m
536
537
538 class DecodeCROut(Elaboratable):
539 """Decodes input CR from instruction
540
541 CR indices - insn fields - (not the data *in* the CR) require only 3
542 bits because they refer to CR0-CR7
543 """
544
545 def __init__(self, dec):
546 self.dec = dec
547 self.rc_in = Signal(reset_less=True)
548 self.sel_in = Signal(CROutSel, reset_less=True)
549 self.insn_in = Signal(32, reset_less=True)
550 self.cr_bitfield = Data(3, "cr_bitfield")
551 self.whole_reg = Data(8, "cr_fxm")
552
553 def elaborate(self, platform):
554 m = Module()
555 comb = m.d.comb
556 op = self.dec.op
557 m.submodules.ppick = ppick = PriorityPicker(8)
558
559 comb += self.cr_bitfield.ok.eq(0)
560 comb += self.whole_reg.ok.eq(0)
561 with m.Switch(self.sel_in):
562 with m.Case(CROutSel.NONE):
563 pass # No bitfield activated
564 with m.Case(CROutSel.CR0):
565 comb += self.cr_bitfield.data.eq(0)
566 comb += self.cr_bitfield.ok.eq(self.rc_in) # only when RC=1
567 with m.Case(CROutSel.BF):
568 comb += self.cr_bitfield.data.eq(self.dec.FormX.BF)
569 comb += self.cr_bitfield.ok.eq(1)
570 with m.Case(CROutSel.BT):
571 comb += self.cr_bitfield.data.eq(self.dec.FormXL.BT[2:5])
572 comb += self.cr_bitfield.ok.eq(1)
573 with m.Case(CROutSel.WHOLE_REG):
574 comb += self.whole_reg.ok.eq(1)
575 move_one = Signal(reset_less=True)
576 comb += move_one.eq(self.insn_in[20])
577 with m.If((op.internal_op == MicrOp.OP_MTCRF)):
578 with m.If(move_one):
579 # must one-hot the FXM field
580 comb += ppick.i.eq(self.dec.FXM)
581 comb += self.whole_reg.data.eq(ppick.o)
582 with m.Else():
583 comb += self.whole_reg.data.eq(self.dec.FXM)
584 with m.Else():
585 # otherwise use all of it
586 comb += self.whole_reg.data.eq(0xff)
587
588 return m
589
590
591 class PowerDecode2(Elaboratable):
592 """PowerDecode2: the main instruction decoder.
593
594 whilst PowerDecode is responsible for decoding the actual opcode, this
595 module encapsulates further specialist, sparse information and
596 expansion of fields that is inconvenient to have in the CSV files.
597 for example: the encoding of the immediates, which are detected
598 and expanded out to their full value from an annotated (enum)
599 representation.
600
601 implicit register usage is also set up, here. for example: OP_BC
602 requires implicitly reading CTR, OP_RFID requires implicitly writing
603 to SRR1 and so on.
604
605 in addition, PowerDecoder2 is responsible for detecting whether
606 instructions are illegal (or privileged) or not, and instead of
607 just leaving at that, *replacing* the instruction to execute with
608 a suitable alternative (trap).
609 """
610
611 def __init__(self, dec):
612
613 self.dec = dec
614 self.e = Decode2ToExecute1Type()
615
616 # state information needed by the Decoder (TODO: this as a Record)
617 self.state = CoreState("dec2")
618
619 def ports(self):
620 return self.dec.ports() + self.e.ports()
621
622 def elaborate(self, platform):
623 m = Module()
624 comb = m.d.comb
625 e_out, op, do_out = self.e, self.dec.op, self.e.do
626 msr, cia = self.state.msr, self.state.pc
627
628 # fill in for a normal instruction (not an exception)
629 # copy over if non-exception, non-privileged etc. is detected
630 e = Decode2ToExecute1Type()
631 do = e.do
632
633 # set up submodule decoders
634 m.submodules.dec = self.dec
635 m.submodules.dec_a = dec_a = DecodeA(self.dec)
636 m.submodules.dec_b = dec_b = DecodeB(self.dec)
637 m.submodules.dec_c = dec_c = DecodeC(self.dec)
638 m.submodules.dec_o = dec_o = DecodeOut(self.dec)
639 m.submodules.dec_o2 = dec_o2 = DecodeOut2(self.dec)
640 m.submodules.dec_rc = dec_rc = DecodeRC(self.dec)
641 m.submodules.dec_oe = dec_oe = DecodeOE(self.dec)
642 m.submodules.dec_cr_in = dec_cr_in = DecodeCRIn(self.dec)
643 m.submodules.dec_cr_out = dec_cr_out = DecodeCROut(self.dec)
644
645 # copy instruction through...
646 for i in [do.insn, dec_a.insn_in, dec_b.insn_in,
647 dec_c.insn_in, dec_o.insn_in, dec_o2.insn_in, dec_rc.insn_in,
648 dec_oe.insn_in, dec_cr_in.insn_in, dec_cr_out.insn_in]:
649 comb += i.eq(self.dec.opcode_in)
650
651 # ...and subdecoders' input fields
652 comb += dec_a.sel_in.eq(op.in1_sel)
653 comb += dec_b.sel_in.eq(op.in2_sel)
654 comb += dec_c.sel_in.eq(op.in3_sel)
655 comb += dec_o.sel_in.eq(op.out_sel)
656 comb += dec_o2.sel_in.eq(op.out_sel)
657 comb += dec_o2.lk.eq(do.lk)
658 comb += dec_rc.sel_in.eq(op.rc_sel)
659 comb += dec_oe.sel_in.eq(op.rc_sel) # XXX should be OE sel
660 comb += dec_cr_in.sel_in.eq(op.cr_in)
661 comb += dec_cr_out.sel_in.eq(op.cr_out)
662 comb += dec_cr_out.rc_in.eq(dec_rc.rc_out.data)
663
664 # copy "state" over
665 comb += do.msr.eq(msr)
666 comb += do.cia.eq(cia)
667
668 # set up instruction, pick fn unit
669 # no op: defaults to OP_ILLEGAL
670 comb += do.insn_type.eq(op.internal_op)
671 comb += do.fn_unit.eq(op.function_unit)
672
673 # registers a, b, c and out and out2 (LD/ST EA)
674 comb += e.read_reg1.eq(dec_a.reg_out)
675 comb += e.read_reg2.eq(dec_b.reg_out)
676 comb += e.read_reg3.eq(dec_c.reg_out)
677 comb += e.write_reg.eq(dec_o.reg_out)
678 comb += e.write_ea.eq(dec_o2.reg_out)
679 comb += do.imm_data.eq(dec_b.imm_out) # immediate in RB (usually)
680 comb += do.zero_a.eq(dec_a.immz_out) # RA==0 detected
681
682 # rc and oe out
683 comb += do.rc.eq(dec_rc.rc_out)
684 comb += do.oe.eq(dec_oe.oe_out)
685
686 # SPRs out
687 comb += e.read_spr1.eq(dec_a.spr_out)
688 comb += e.write_spr.eq(dec_o.spr_out)
689
690 # Fast regs out
691 comb += e.read_fast1.eq(dec_a.fast_out)
692 comb += e.read_fast2.eq(dec_b.fast_out)
693 comb += e.write_fast1.eq(dec_o.fast_out)
694 comb += e.write_fast2.eq(dec_o2.fast_out)
695
696 # condition registers (CR)
697 comb += e.read_cr1.eq(dec_cr_in.cr_bitfield)
698 comb += e.read_cr2.eq(dec_cr_in.cr_bitfield_b)
699 comb += e.read_cr3.eq(dec_cr_in.cr_bitfield_o)
700 comb += e.write_cr.eq(dec_cr_out.cr_bitfield)
701
702 comb += do.read_cr_whole.eq(dec_cr_in.whole_reg)
703 comb += do.write_cr_whole.eq(dec_cr_out.whole_reg)
704 comb += do.write_cr0.eq(dec_cr_out.cr_bitfield.ok)
705
706 # decoded/selected instruction flags
707 comb += do.data_len.eq(op.ldst_len)
708 comb += do.invert_in.eq(op.inv_a)
709 comb += do.invert_out.eq(op.inv_out)
710 comb += do.input_carry.eq(op.cry_in) # carry comes in
711 comb += do.output_carry.eq(op.cry_out) # carry goes out
712 comb += do.is_32bit.eq(op.is_32b)
713 comb += do.is_signed.eq(op.sgn)
714 with m.If(op.lk):
715 comb += do.lk.eq(self.dec.LK) # XXX TODO: accessor
716
717 comb += do.byte_reverse.eq(op.br)
718 comb += do.sign_extend.eq(op.sgn_ext)
719 comb += do.ldst_mode.eq(op.upd) # LD/ST mode (update, cache-inhibit)
720
721 # These should be removed eventually
722 comb += do.input_cr.eq(op.cr_in) # condition reg comes in
723 comb += do.output_cr.eq(op.cr_out) # condition reg goes in
724
725 # sigh this is exactly the sort of thing for which the
726 # decoder is designed to not need. MTSPR, MFSPR and others need
727 # access to the XER bits. however setting e.oe is not appropriate
728 with m.If(op.internal_op == MicrOp.OP_MFSPR):
729 comb += e.xer_in.eq(1)
730 with m.If(op.internal_op == MicrOp.OP_MTSPR):
731 comb += e.xer_out.eq(1)
732
733 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
734 with m.If(op.internal_op == MicrOp.OP_TRAP):
735 # *DO NOT* call self.trap here. that would reset absolutely
736 # rverything including destroying read of RA and RB.
737 comb += do.trapaddr.eq(0x70) # addr=0x700 (strip first nibble)
738
739 # TODO: get msr, then can do privileged instruction
740 with m.If(instr_is_priv(m, op.internal_op, e.do.insn) & msr[MSR.PR]):
741 # privileged instruction trap
742 self.trap(m, TT.PRIV, 0x700)
743
744 # illegal instruction must redirect to trap. this is done by
745 # *overwriting* the decoded instruction and starting again.
746 # (note: the same goes for interrupts and for privileged operations,
747 # just with different trapaddr and traptype)
748 with m.Elif(op.internal_op == MicrOp.OP_ILLEGAL):
749 # illegal instruction trap
750 self.trap(m, TT.ILLEG, 0x700)
751
752 # no exception, just copy things to the output
753 with m.Else():
754 comb += e_out.eq(e)
755
756 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
757 # Note: OP_SC could actually be modified to just be a trap
758 with m.If((do_out.insn_type == MicrOp.OP_TRAP) |
759 (do_out.insn_type == MicrOp.OP_SC)):
760 # TRAP write fast1 = SRR0
761 comb += e_out.write_fast1.data.eq(FastRegs.SRR0) # constant: SRR0
762 comb += e_out.write_fast1.ok.eq(1)
763 # TRAP write fast2 = SRR1
764 comb += e_out.write_fast2.data.eq(FastRegs.SRR1) # constant: SRR1
765 comb += e_out.write_fast2.ok.eq(1)
766
767 # RFID: needs to read SRR0/1
768 with m.If(do_out.insn_type == MicrOp.OP_RFID):
769 # TRAP read fast1 = SRR0
770 comb += e_out.read_fast1.data.eq(FastRegs.SRR0) # constant: SRR0
771 comb += e_out.read_fast1.ok.eq(1)
772 # TRAP read fast2 = SRR1
773 comb += e_out.read_fast2.data.eq(FastRegs.SRR1) # constant: SRR1
774 comb += e_out.read_fast2.ok.eq(1)
775
776 return m
777
778 def trap(self, m, traptype, trapaddr):
779 """trap: this basically "rewrites" the decoded instruction as a trap
780 """
781 comb = m.d.comb
782 op, do, e = self.dec.op, self.e.do, self.e
783 comb += e.eq(0) # reset eeeeeverything
784
785 # start again
786 comb += do.insn.eq(self.dec.opcode_in)
787 comb += do.insn_type.eq(MicrOp.OP_TRAP)
788 comb += do.fn_unit.eq(Function.TRAP)
789 comb += do.trapaddr.eq(trapaddr >> 4) # cut bottom 4 bits
790 comb += do.traptype.eq(traptype) # request type
791 comb += do.msr.eq(self.state.msr) # copy of MSR "state"
792 comb += do.cia.eq(self.state.pc) # copy of PC "state"
793
794
795 def get_rdflags(e, cu):
796 rdl = []
797 for idx in range(cu.n_src):
798 regfile, regname, _ = cu.get_in_spec(idx)
799 rdflag, read = regspec_decode_read(e, regfile, regname)
800 rdl.append(rdflag)
801 print("rdflags", rdl)
802 return Cat(*rdl)
803
804
805 if __name__ == '__main__':
806 pdecode = create_pdecode()
807 dec2 = PowerDecode2(pdecode)
808 vl = rtlil.convert(dec2, ports=dec2.ports() + pdecode.ports())
809 with open("dec2.il", "w") as f:
810 f.write(vl)