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