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