0f2a48601d2c02f42fdca87be406745180168fc0
[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
494 comb = m.d.comb
495 op = self.dec.op
496
497 comb += self.cr_bitfield.ok.eq(0)
498 comb += self.cr_bitfield_b.ok.eq(0)
499 comb += self.whole_reg.ok.eq(0)
500 with m.Switch(self.sel_in):
501 with m.Case(CRInSel.NONE):
502 pass # No bitfield activated
503 with m.Case(CRInSel.CR0):
504 comb += self.cr_bitfield.data.eq(0)
505 comb += self.cr_bitfield.ok.eq(1)
506 with m.Case(CRInSel.BI):
507 comb += self.cr_bitfield.data.eq(self.dec.BI[2:5])
508 comb += self.cr_bitfield.ok.eq(1)
509 with m.Case(CRInSel.BFA):
510 comb += self.cr_bitfield.data.eq(self.dec.FormX.BFA)
511 comb += self.cr_bitfield.ok.eq(1)
512 with m.Case(CRInSel.BA_BB):
513 comb += self.cr_bitfield.data.eq(self.dec.BA[2:5])
514 comb += self.cr_bitfield.ok.eq(1)
515 comb += self.cr_bitfield_b.data.eq(self.dec.BB[2:5])
516 comb += self.cr_bitfield_b.ok.eq(1)
517 comb += self.cr_bitfield_o.data.eq(self.dec.BT[2:5])
518 comb += self.cr_bitfield_o.ok.eq(1)
519 with m.Case(CRInSel.BC):
520 comb += self.cr_bitfield.data.eq(self.dec.BC[2:5])
521 comb += self.cr_bitfield.ok.eq(1)
522 with m.Case(CRInSel.WHOLE_REG):
523 comb += self.whole_reg.ok.eq(1)
524 move_one = Signal(reset_less=True)
525 comb += move_one.eq(self.insn_in[20]) # MSB0 bit 11
526 with m.If((op.internal_op == MicrOp.OP_MFCR) & move_one):
527 # must one-hot the FXM field
528 comb += ppick.i.eq(self.dec.FXM)
529 comb += self.whole_reg.data.eq(ppick.o)
530 with m.Else():
531 # otherwise use all of it
532 comb += self.whole_reg.data.eq(0xff)
533
534 return m
535
536
537 class DecodeCROut(Elaboratable):
538 """Decodes input CR from instruction
539
540 CR indices - insn fields - (not the data *in* the CR) require only 3
541 bits because they refer to CR0-CR7
542 """
543
544 def __init__(self, dec):
545 self.dec = dec
546 self.rc_in = Signal(reset_less=True)
547 self.sel_in = Signal(CROutSel, reset_less=True)
548 self.insn_in = Signal(32, reset_less=True)
549 self.cr_bitfield = Data(3, "cr_bitfield")
550 self.whole_reg = Data(8, "cr_fxm")
551
552 def elaborate(self, platform):
553 m = Module()
554 comb = m.d.comb
555 op = self.dec.op
556 m.submodules.ppick = ppick = PriorityPicker(8)
557
558 comb += self.cr_bitfield.ok.eq(0)
559 comb += self.whole_reg.ok.eq(0)
560 with m.Switch(self.sel_in):
561 with m.Case(CROutSel.NONE):
562 pass # No bitfield activated
563 with m.Case(CROutSel.CR0):
564 comb += self.cr_bitfield.data.eq(0)
565 comb += self.cr_bitfield.ok.eq(self.rc_in) # only when RC=1
566 with m.Case(CROutSel.BF):
567 comb += self.cr_bitfield.data.eq(self.dec.FormX.BF)
568 comb += self.cr_bitfield.ok.eq(1)
569 with m.Case(CROutSel.BT):
570 comb += self.cr_bitfield.data.eq(self.dec.FormXL.BT[2:5])
571 comb += self.cr_bitfield.ok.eq(1)
572 with m.Case(CROutSel.WHOLE_REG):
573 comb += self.whole_reg.ok.eq(1)
574 move_one = Signal(reset_less=True)
575 comb += move_one.eq(self.insn_in[20])
576 with m.If((op.internal_op == MicrOp.OP_MTCRF)):
577 with m.If(move_one):
578 # must one-hot the FXM field
579 comb += ppick.i.eq(self.dec.FXM)
580 comb += self.whole_reg.data.eq(ppick.o)
581 with m.Else():
582 comb += self.whole_reg.data.eq(self.dec.FXM)
583 with m.Else():
584 # otherwise use all of it
585 comb += self.whole_reg.data.eq(0xff)
586
587 return m
588
589
590 class PowerDecode2(Elaboratable):
591 """PowerDecode2: the main instruction decoder.
592
593 whilst PowerDecode is responsible for decoding the actual opcode, this
594 module encapsulates further specialist, sparse information and
595 expansion of fields that is inconvenient to have in the CSV files.
596 for example: the encoding of the immediates, which are detected
597 and expanded out to their full value from an annotated (enum)
598 representation.
599
600 implicit register usage is also set up, here. for example: OP_BC
601 requires implicitly reading CTR, OP_RFID requires implicitly writing
602 to SRR1 and so on.
603
604 in addition, PowerDecoder2 is responsible for detecting whether
605 instructions are illegal (or privileged) or not, and instead of
606 just leaving at that, *replacing* the instruction to execute with
607 a suitable alternative (trap).
608 """
609
610 def __init__(self, dec):
611
612 self.dec = dec
613 self.e = Decode2ToExecute1Type()
614
615 # state information needed by the Decoder (TODO: this as a Record)
616 self.state = CoreState("dec2")
617
618 def ports(self):
619 return self.dec.ports() + self.e.ports()
620
621 def elaborate(self, platform):
622 m = Module()
623 comb = m.d.comb
624 e_out, op, do_out = self.e, self.dec.op, self.e.do
625 msr, cia = self.state.msr, self.state.pc
626
627 # fill in for a normal instruction (not an exception)
628 # copy over if non-exception, non-privileged etc. is detected
629 e = Decode2ToExecute1Type()
630 do = e.do
631
632 # set up submodule decoders
633 m.submodules.dec = self.dec
634 m.submodules.dec_a = dec_a = DecodeA(self.dec)
635 m.submodules.dec_b = dec_b = DecodeB(self.dec)
636 m.submodules.dec_c = dec_c = DecodeC(self.dec)
637 m.submodules.dec_o = dec_o = DecodeOut(self.dec)
638 m.submodules.dec_o2 = dec_o2 = DecodeOut2(self.dec)
639 m.submodules.dec_rc = dec_rc = DecodeRC(self.dec)
640 m.submodules.dec_oe = dec_oe = DecodeOE(self.dec)
641 m.submodules.dec_cr_in = dec_cr_in = DecodeCRIn(self.dec)
642 m.submodules.dec_cr_out = dec_cr_out = DecodeCROut(self.dec)
643
644 # copy instruction through...
645 for i in [do.insn, dec_a.insn_in, dec_b.insn_in,
646 dec_c.insn_in, dec_o.insn_in, dec_o2.insn_in, dec_rc.insn_in,
647 dec_oe.insn_in, dec_cr_in.insn_in, dec_cr_out.insn_in]:
648 comb += i.eq(self.dec.opcode_in)
649
650 # ...and subdecoders' input fields
651 comb += dec_a.sel_in.eq(op.in1_sel)
652 comb += dec_b.sel_in.eq(op.in2_sel)
653 comb += dec_c.sel_in.eq(op.in3_sel)
654 comb += dec_o.sel_in.eq(op.out_sel)
655 comb += dec_o2.sel_in.eq(op.out_sel)
656 comb += dec_o2.lk.eq(do.lk)
657 comb += dec_rc.sel_in.eq(op.rc_sel)
658 comb += dec_oe.sel_in.eq(op.rc_sel) # XXX should be OE sel
659 comb += dec_cr_in.sel_in.eq(op.cr_in)
660 comb += dec_cr_out.sel_in.eq(op.cr_out)
661 comb += dec_cr_out.rc_in.eq(dec_rc.rc_out.data)
662
663 # copy "state" over
664 comb += do.msr.eq(msr)
665 comb += do.cia.eq(cia)
666
667 # set up instruction, pick fn unit
668 # no op: defaults to OP_ILLEGAL
669 comb += do.insn_type.eq(op.internal_op)
670 comb += do.fn_unit.eq(op.function_unit)
671
672 # registers a, b, c and out and out2 (LD/ST EA)
673 comb += e.read_reg1.eq(dec_a.reg_out)
674 comb += e.read_reg2.eq(dec_b.reg_out)
675 comb += e.read_reg3.eq(dec_c.reg_out)
676 comb += e.write_reg.eq(dec_o.reg_out)
677 comb += e.write_ea.eq(dec_o2.reg_out)
678 comb += do.imm_data.eq(dec_b.imm_out) # immediate in RB (usually)
679 comb += do.zero_a.eq(dec_a.immz_out) # RA==0 detected
680
681 # rc and oe out
682 comb += do.rc.eq(dec_rc.rc_out)
683 comb += do.oe.eq(dec_oe.oe_out)
684
685 # SPRs out
686 comb += e.read_spr1.eq(dec_a.spr_out)
687 comb += e.write_spr.eq(dec_o.spr_out)
688
689 # Fast regs out
690 comb += e.read_fast1.eq(dec_a.fast_out)
691 comb += e.read_fast2.eq(dec_b.fast_out)
692 comb += e.write_fast1.eq(dec_o.fast_out)
693 comb += e.write_fast2.eq(dec_o2.fast_out)
694
695 # condition registers (CR)
696 comb += e.read_cr1.eq(dec_cr_in.cr_bitfield)
697 comb += e.read_cr2.eq(dec_cr_in.cr_bitfield_b)
698 comb += e.read_cr3.eq(dec_cr_in.cr_bitfield_o)
699 comb += e.write_cr.eq(dec_cr_out.cr_bitfield)
700
701 comb += do.read_cr_whole.eq(dec_cr_in.whole_reg)
702 comb += do.write_cr_whole.eq(dec_cr_out.whole_reg)
703 comb += do.write_cr0.eq(dec_cr_out.cr_bitfield.ok)
704
705 # decoded/selected instruction flags
706 comb += do.data_len.eq(op.ldst_len)
707 comb += do.invert_in.eq(op.inv_a)
708 comb += do.invert_out.eq(op.inv_out)
709 comb += do.input_carry.eq(op.cry_in) # carry comes in
710 comb += do.output_carry.eq(op.cry_out) # carry goes out
711 comb += do.is_32bit.eq(op.is_32b)
712 comb += do.is_signed.eq(op.sgn)
713 with m.If(op.lk):
714 comb += do.lk.eq(self.dec.LK) # XXX TODO: accessor
715
716 comb += do.byte_reverse.eq(op.br)
717 comb += do.sign_extend.eq(op.sgn_ext)
718 comb += do.ldst_mode.eq(op.upd) # LD/ST mode (update, cache-inhibit)
719
720 # These should be removed eventually
721 comb += do.input_cr.eq(op.cr_in) # condition reg comes in
722 comb += do.output_cr.eq(op.cr_out) # condition reg goes in
723
724 # sigh this is exactly the sort of thing for which the
725 # decoder is designed to not need. MTSPR, MFSPR and others need
726 # access to the XER bits. however setting e.oe is not appropriate
727 with m.If(op.internal_op == MicrOp.OP_MFSPR):
728 comb += e.xer_in.eq(1)
729 with m.If(op.internal_op == MicrOp.OP_MTSPR):
730 comb += e.xer_out.eq(1)
731
732 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
733 with m.If(op.internal_op == MicrOp.OP_TRAP):
734 # *DO NOT* call self.trap here. that would reset absolutely
735 # rverything including destroying read of RA and RB.
736 comb += do.trapaddr.eq(0x70) # addr=0x700 (strip first nibble)
737
738 # TODO: get msr, then can do privileged instruction
739 with m.If(instr_is_priv(m, op.internal_op, e.do.insn) & msr[MSR.PR]):
740 # privileged instruction trap
741 self.trap(m, TT.PRIV, 0x700)
742
743 # illegal instruction must redirect to trap. this is done by
744 # *overwriting* the decoded instruction and starting again.
745 # (note: the same goes for interrupts and for privileged operations,
746 # just with different trapaddr and traptype)
747 with m.Elif(op.internal_op == MicrOp.OP_ILLEGAL):
748 # illegal instruction trap
749 self.trap(m, TT.ILLEG, 0x700)
750
751 # no exception, just copy things to the output
752 with m.Else():
753 comb += e_out.eq(e)
754
755 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
756 # Note: OP_SC could actually be modified to just be a trap
757 with m.If((do_out.insn_type == MicrOp.OP_TRAP) |
758 (do_out.insn_type == MicrOp.OP_SC)):
759 # TRAP write fast1 = SRR0
760 comb += e_out.write_fast1.data.eq(FastRegs.SRR0) # constant: SRR0
761 comb += e_out.write_fast1.ok.eq(1)
762 # TRAP write fast2 = SRR1
763 comb += e_out.write_fast2.data.eq(FastRegs.SRR1) # constant: SRR1
764 comb += e_out.write_fast2.ok.eq(1)
765
766 # RFID: needs to read SRR0/1
767 with m.If(do_out.insn_type == MicrOp.OP_RFID):
768 # TRAP read fast1 = SRR0
769 comb += e_out.read_fast1.data.eq(FastRegs.SRR0) # constant: SRR0
770 comb += e_out.read_fast1.ok.eq(1)
771 # TRAP read fast2 = SRR1
772 comb += e_out.read_fast2.data.eq(FastRegs.SRR1) # constant: SRR1
773 comb += e_out.read_fast2.ok.eq(1)
774
775 return m
776
777 def trap(self, m, traptype, trapaddr):
778 """trap: this basically "rewrites" the decoded instruction as a trap
779 """
780 comb = m.d.comb
781 op, do, e = self.dec.op, self.e.do, self.e
782 comb += e.eq(0) # reset eeeeeverything
783
784 # start again
785 comb += do.insn.eq(self.dec.opcode_in)
786 comb += do.insn_type.eq(MicrOp.OP_TRAP)
787 comb += do.fn_unit.eq(Function.TRAP)
788 comb += do.trapaddr.eq(trapaddr >> 4) # cut bottom 4 bits
789 comb += do.traptype.eq(traptype) # request type
790 comb += do.msr.eq(self.state.msr) # copy of MSR "state"
791 comb += do.cia.eq(self.state.pc) # copy of PC "state"
792
793
794 def get_rdflags(e, cu):
795 rdl = []
796 for idx in range(cu.n_src):
797 regfile, regname, _ = cu.get_in_spec(idx)
798 rdflag, read = regspec_decode_read(e, regfile, regname)
799 rdl.append(rdflag)
800 print("rdflags", rdl)
801 return Cat(*rdl)
802
803
804 if __name__ == '__main__':
805 pdecode = create_pdecode()
806 dec2 = PowerDecode2(pdecode)
807 vl = rtlil.convert(dec2, ports=dec2.ports() + pdecode.ports())
808 with open("dec2.il", "w") as f:
809 f.write(vl)