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