45b60fb9da2fa2a81abee144c9f4f28da86bbd8e
[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 (InternalOp, 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(InternalOp.OP_ATTN) : comb += is_priv_insn.eq(1)
45 with m.Case(InternalOp.OP_MFMSR) : comb += is_priv_insn.eq(1)
46 with m.Case(InternalOp.OP_MTMSRD): comb += is_priv_insn.eq(1)
47 with m.Case(InternalOp.OP_MTMSR): comb += is_priv_insn.eq(1)
48 with m.Case(InternalOp.OP_RFID) : comb += is_priv_insn.eq(1)
49 with m.Case(InternalOp.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 == InternalOp.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 == InternalOp.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 == InternalOp.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 == InternalOp.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 == InternalOp.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 == InternalOp.OP_BC) |
330 (op.internal_op == InternalOp.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 == InternalOp.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 # BC or BCREG: potential implicit register (LR) output
367 op = self.dec.op
368 with m.If((op.internal_op == InternalOp.OP_BC) |
369 (op.internal_op == InternalOp.OP_BCREG)):
370 with m.If(self.lk): # "link" mode
371 comb += self.fast_out.data.eq(FastRegs.LR) # constant: LR
372 comb += self.fast_out.ok.eq(1)
373
374 # RFID 2nd spr (fast)
375 with m.If(op.internal_op == InternalOp.OP_RFID):
376 comb += self.fast_out.data.eq(FastRegs.SRR1) # constant: SRR1
377 comb += self.fast_out.ok.eq(1)
378
379 return m
380
381
382 class DecodeRC(Elaboratable):
383 """DecodeRc from instruction
384
385 decodes Record bit Rc
386 """
387 def __init__(self, dec):
388 self.dec = dec
389 self.sel_in = Signal(RC, reset_less=True)
390 self.insn_in = Signal(32, reset_less=True)
391 self.rc_out = Data(1, "rc")
392
393 def elaborate(self, platform):
394 m = Module()
395 comb = m.d.comb
396
397 # select Record bit out field
398 with m.Switch(self.sel_in):
399 with m.Case(RC.RC):
400 comb += self.rc_out.data.eq(self.dec.Rc)
401 comb += self.rc_out.ok.eq(1)
402 with m.Case(RC.ONE):
403 comb += self.rc_out.data.eq(1)
404 comb += self.rc_out.ok.eq(1)
405 with m.Case(RC.NONE):
406 comb += self.rc_out.data.eq(0)
407 comb += self.rc_out.ok.eq(1)
408
409 return m
410
411
412 class DecodeOE(Elaboratable):
413 """DecodeOE from instruction
414
415 decodes OE field: uses RC decode detection which might not be good
416
417 -- For now, use "rc" in the decode table to decide whether oe exists.
418 -- This is not entirely correct architecturally: For mulhd and
419 -- mulhdu, the OE field is reserved. It remains to be seen what an
420 -- actual POWER9 does if we set it on those instructions, for now we
421 -- test that further down when assigning to the multiplier oe input.
422 """
423 def __init__(self, dec):
424 self.dec = dec
425 self.sel_in = Signal(RC, reset_less=True)
426 self.insn_in = Signal(32, reset_less=True)
427 self.oe_out = Data(1, "oe")
428
429 def elaborate(self, platform):
430 m = Module()
431 comb = m.d.comb
432
433 # select OE bit out field
434 with m.Switch(self.sel_in):
435 with m.Case(RC.RC):
436 comb += self.oe_out.data.eq(self.dec.OE)
437 comb += self.oe_out.ok.eq(1)
438
439 return m
440
441 class DecodeCRIn(Elaboratable):
442 """Decodes input CR from instruction
443
444 CR indices - insn fields - (not the data *in* the CR) require only 3
445 bits because they refer to CR0-CR7
446 """
447
448 def __init__(self, dec):
449 self.dec = dec
450 self.sel_in = Signal(CRInSel, reset_less=True)
451 self.insn_in = Signal(32, reset_less=True)
452 self.cr_bitfield = Data(3, "cr_bitfield")
453 self.cr_bitfield_b = Data(3, "cr_bitfield_b")
454 self.cr_bitfield_o = Data(3, "cr_bitfield_o")
455 self.whole_reg = Signal(reset_less=True)
456
457 def elaborate(self, platform):
458 m = Module()
459 comb = m.d.comb
460
461 comb += self.cr_bitfield.ok.eq(0)
462 comb += self.cr_bitfield_b.ok.eq(0)
463 comb += self.whole_reg.eq(0)
464 with m.Switch(self.sel_in):
465 with m.Case(CRInSel.NONE):
466 pass # No bitfield activated
467 with m.Case(CRInSel.CR0):
468 comb += self.cr_bitfield.data.eq(0)
469 comb += self.cr_bitfield.ok.eq(1)
470 with m.Case(CRInSel.BI):
471 comb += self.cr_bitfield.data.eq(self.dec.BI[2:5])
472 comb += self.cr_bitfield.ok.eq(1)
473 with m.Case(CRInSel.BFA):
474 comb += self.cr_bitfield.data.eq(self.dec.FormX.BFA)
475 comb += self.cr_bitfield.ok.eq(1)
476 with m.Case(CRInSel.BA_BB):
477 comb += self.cr_bitfield.data.eq(self.dec.BA[2:5])
478 comb += self.cr_bitfield.ok.eq(1)
479 comb += self.cr_bitfield_b.data.eq(self.dec.BB[2:5])
480 comb += self.cr_bitfield_b.ok.eq(1)
481 comb += self.cr_bitfield_o.data.eq(self.dec.BT[2:5])
482 comb += self.cr_bitfield_o.ok.eq(1)
483 with m.Case(CRInSel.BC):
484 comb += self.cr_bitfield.data.eq(self.dec.BC[2:5])
485 comb += self.cr_bitfield.ok.eq(1)
486 with m.Case(CRInSel.WHOLE_REG):
487 comb += self.whole_reg.eq(1)
488
489 return m
490
491
492 class DecodeCROut(Elaboratable):
493 """Decodes input CR from instruction
494
495 CR indices - insn fields - (not the data *in* the CR) require only 3
496 bits because they refer to CR0-CR7
497 """
498
499 def __init__(self, dec):
500 self.dec = dec
501 self.rc_in = Signal(reset_less=True)
502 self.sel_in = Signal(CROutSel, reset_less=True)
503 self.insn_in = Signal(32, reset_less=True)
504 self.cr_bitfield = Data(3, "cr_bitfield")
505 self.whole_reg = Signal(reset_less=True)
506
507 def elaborate(self, platform):
508 m = Module()
509 comb = m.d.comb
510
511 comb += self.cr_bitfield.ok.eq(0)
512 comb += self.whole_reg.eq(0)
513 with m.Switch(self.sel_in):
514 with m.Case(CROutSel.NONE):
515 pass # No bitfield activated
516 with m.Case(CROutSel.CR0):
517 comb += self.cr_bitfield.data.eq(0)
518 comb += self.cr_bitfield.ok.eq(self.rc_in) # only when RC=1
519 with m.Case(CROutSel.BF):
520 comb += self.cr_bitfield.data.eq(self.dec.FormX.BF)
521 comb += self.cr_bitfield.ok.eq(1)
522 with m.Case(CROutSel.BT):
523 comb += self.cr_bitfield.data.eq(self.dec.FormXL.BT[2:5])
524 comb += self.cr_bitfield.ok.eq(1)
525 with m.Case(CROutSel.WHOLE_REG):
526 comb += self.whole_reg.eq(1)
527
528 return m
529
530
531 class XerBits:
532 def __init__(self):
533 self.ca = Signal(2, reset_less=True)
534 self.ov = Signal(2, reset_less=True)
535 self.so = Signal(reset_less=True)
536
537 def ports(self):
538 return [self.ca, self.ov, self.so]
539
540
541 class PowerDecode2(Elaboratable):
542
543 def __init__(self, dec):
544
545 self.dec = dec
546 self.e = Decode2ToExecute1Type()
547 self.valid = Signal()
548
549 def ports(self):
550 return self.dec.ports() + self.e.ports()
551
552 def elaborate(self, platform):
553 m = Module()
554 comb = m.d.comb
555 e, op, do = self.e, self.dec.op, self.e.do
556
557 # set up submodule decoders
558 m.submodules.dec = self.dec
559 m.submodules.dec_a = dec_a = DecodeA(self.dec)
560 m.submodules.dec_b = dec_b = DecodeB(self.dec)
561 m.submodules.dec_c = dec_c = DecodeC(self.dec)
562 m.submodules.dec_o = dec_o = DecodeOut(self.dec)
563 m.submodules.dec_o2 = dec_o2 = DecodeOut2(self.dec)
564 m.submodules.dec_rc = dec_rc = DecodeRC(self.dec)
565 m.submodules.dec_oe = dec_oe = DecodeOE(self.dec)
566 m.submodules.dec_cr_in = dec_cr_in = DecodeCRIn(self.dec)
567 m.submodules.dec_cr_out = dec_cr_out = DecodeCROut(self.dec)
568
569 # copy instruction through...
570 for i in [do.insn, dec_a.insn_in, dec_b.insn_in,
571 dec_c.insn_in, dec_o.insn_in, dec_o2.insn_in, dec_rc.insn_in,
572 dec_oe.insn_in, dec_cr_in.insn_in, dec_cr_out.insn_in]:
573 comb += i.eq(self.dec.opcode_in)
574
575 # ...and subdecoders' input fields
576 comb += dec_a.sel_in.eq(op.in1_sel)
577 comb += dec_b.sel_in.eq(op.in2_sel)
578 comb += dec_c.sel_in.eq(op.in3_sel)
579 comb += dec_o.sel_in.eq(op.out_sel)
580 comb += dec_o2.sel_in.eq(op.out_sel)
581 comb += dec_o2.lk.eq(do.lk)
582 comb += dec_rc.sel_in.eq(op.rc_sel)
583 comb += dec_oe.sel_in.eq(op.rc_sel) # XXX should be OE sel
584 comb += dec_cr_in.sel_in.eq(op.cr_in)
585 comb += dec_cr_out.sel_in.eq(op.cr_out)
586 comb += dec_cr_out.rc_in.eq(dec_rc.rc_out.data)
587
588 # set up instruction, pick fn unit
589 comb += e.nia.eq(0) # XXX TODO (or remove? not sure yet)
590 fu = op.function_unit
591 itype = Mux(fu == Function.NONE, InternalOp.OP_ILLEGAL, op.internal_op)
592 comb += do.insn_type.eq(itype)
593 comb += do.fn_unit.eq(fu)
594
595 # registers a, b, c and out and out2 (LD/ST EA)
596 comb += e.read_reg1.eq(dec_a.reg_out)
597 comb += e.read_reg2.eq(dec_b.reg_out)
598 comb += e.read_reg3.eq(dec_c.reg_out)
599 comb += e.write_reg.eq(dec_o.reg_out)
600 comb += e.write_ea.eq(dec_o2.reg_out)
601 comb += do.imm_data.eq(dec_b.imm_out) # immediate in RB (usually)
602 comb += do.zero_a.eq(dec_a.immz_out) # RA==0 detected
603
604 # rc and oe out
605 comb += do.rc.eq(dec_rc.rc_out)
606 comb += do.oe.eq(dec_oe.oe_out)
607
608 # SPRs out
609 comb += e.read_spr1.eq(dec_a.spr_out)
610 comb += e.write_spr.eq(dec_o.spr_out)
611
612 # Fast regs out
613 comb += e.read_fast1.eq(dec_a.fast_out)
614 comb += e.read_fast2.eq(dec_b.fast_out)
615 comb += e.write_fast1.eq(dec_o.fast_out)
616 comb += e.write_fast2.eq(dec_o2.fast_out)
617
618 # condition registers (CR)
619 comb += e.read_cr1.eq(dec_cr_in.cr_bitfield)
620 comb += e.read_cr2.eq(dec_cr_in.cr_bitfield_b)
621 comb += e.read_cr3.eq(dec_cr_in.cr_bitfield_o)
622 comb += e.write_cr.eq(dec_cr_out.cr_bitfield)
623
624 comb += do.read_cr_whole.eq(dec_cr_in.whole_reg)
625 comb += do.write_cr_whole.eq(dec_cr_out.whole_reg)
626 comb += do.write_cr0.eq(dec_cr_out.cr_bitfield.ok)
627
628 # decoded/selected instruction flags
629 comb += do.data_len.eq(op.ldst_len)
630 comb += do.invert_a.eq(op.inv_a)
631 comb += do.invert_out.eq(op.inv_out)
632 comb += do.input_carry.eq(op.cry_in) # carry comes in
633 comb += do.output_carry.eq(op.cry_out) # carry goes out
634 comb += do.is_32bit.eq(op.is_32b)
635 comb += do.is_signed.eq(op.sgn)
636 with m.If(op.lk):
637 comb += do.lk.eq(self.dec.LK) # XXX TODO: accessor
638
639 comb += do.byte_reverse.eq(op.br)
640 comb += do.sign_extend.eq(op.sgn_ext)
641 comb += do.update.eq(op.upd) # LD/ST "update" mode.
642
643 # These should be removed eventually
644 comb += do.input_cr.eq(op.cr_in) # condition reg comes in
645 comb += do.output_cr.eq(op.cr_out) # condition reg goes in
646
647 # sigh this is exactly the sort of thing for which the
648 # decoder is designed to not need. MTSPR, MFSPR and others need
649 # access to the XER bits. however setting e.oe is not appropriate
650 with m.If(op.internal_op == InternalOp.OP_MFSPR):
651 comb += e.xer_in.eq(1)
652 with m.If(op.internal_op == InternalOp.OP_MTSPR):
653 comb += e.xer_out.eq(1)
654
655 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
656 with m.If(op.internal_op == InternalOp.OP_TRAP):
657 comb += do.trapaddr.eq(0x70) # addr=0x700 (strip first nibble)
658
659 # illegal instruction must redirect to trap. this is done by
660 # *overwriting* the decoded instruction and starting again.
661 # (note: the same goes for interrupts and for privileged operations,
662 # just with different trapaddr and traptype)
663 with m.If(op.internal_op == InternalOp.OP_ILLEGAL):
664 # illegal instruction trap
665 self.trap(m, TT_ILLEG, 0x700)
666
667 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
668 # Note: OP_SC could actually be modified to just be a trap
669 with m.If((do.insn_type == InternalOp.OP_TRAP) |
670 (do.insn_type == InternalOp.OP_SC)):
671 # TRAP write fast1 = SRR0
672 comb += e.write_fast1.data.eq(FastRegs.SRR0) # constant: SRR0
673 comb += e.write_fast1.ok.eq(1)
674 # TRAP write fast2 = SRR1
675 comb += e.write_fast2.data.eq(FastRegs.SRR1) # constant: SRR1
676 comb += e.write_fast2.ok.eq(1)
677
678 # RFID: needs to read SRR0/1
679 with m.If(do.insn_type == InternalOp.OP_RFID):
680 # TRAP read fast1 = SRR0
681 comb += e.read_fast1.data.eq(FastRegs.SRR0) # constant: SRR0
682 comb += e.read_fast1.ok.eq(1)
683 # TRAP read fast2 = SRR1
684 comb += e.read_fast2.data.eq(FastRegs.SRR1) # constant: SRR1
685 comb += e.read_fast2.ok.eq(1)
686
687 return m
688
689 # TODO: get msr, then can do privileged instruction
690 with m.If(instr_is_priv(m, op.internal_op, e.insn) & msr[MSR_PR]):
691 # privileged instruction trap
692 self.trap(m, TT_PRIV, 0x700)
693 return m
694
695 def trap(self, m, traptype, trapaddr):
696 """trap: this basically "rewrites" the decoded instruction as a trap
697 """
698 comb = m.d.comb
699 e, op, do = self.e, self.dec.op, self.e.do
700 comb += e.eq(0) # reset eeeeeverything
701 # start again
702 comb += do.insn.eq(self.dec.opcode_in)
703 comb += do.insn_type.eq(InternalOp.OP_TRAP)
704 comb += do.fn_unit.eq(Function.TRAP)
705 comb += do.trapaddr.eq(trapaddr >> 4) # cut bottom 4 bits
706 comb += do.traptype.eq(traptype) # request type
707
708 def regspecmap_read(self, regfile, regname):
709 """regspecmap_read: provides PowerDecode2 with an encoding relationship
710 to Function Unit port regfiles (read-enable, read regnum, write regnum)
711 regfile and regname arguments are fields 1 and 2 from a given regspec.
712 """
713 return regspec_decode_read(self.e, regfile, regname)
714
715 def regspecmap_write(self, regfile, regname):
716 """regspecmap_write: provides PowerDecode2 with an encoding relationship
717 to Function Unit port regfiles (write port, write regnum)
718 regfile and regname arguments are fields 1 and 2 from a given regspec.
719 """
720 return regspec_decode_write(self.e, regfile, regname)
721
722 def rdflags(self, cu):
723 rdl = []
724 for idx in range(cu.n_src):
725 regfile, regname, _ = cu.get_in_spec(idx)
726 rdflag, read = self.regspecmap_read(regfile, regname)
727 rdl.append(rdflag)
728 print ("rdflags", rdl)
729 return Cat(*rdl)
730
731
732 if __name__ == '__main__':
733 pdecode = create_pdecode()
734 dec2 = PowerDecode2(pdecode)
735 vl = rtlil.convert(dec2, ports=dec2.ports() + pdecode.ports())
736 with open("dec2.il", "w") as f:
737 f.write(vl)
738