whoops got Function.NONE test wrong 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 (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 with m.If((fu == Function.NONE) &
592 (op.internal_op != InternalOp.OP_ATTN)):
593 comb += do.insn_type.eq(InternalOp.OP_ILLEGAL)
594 with m.Else():
595 comb += do.insn_type.eq(op.internal_op)
596 comb += do.fn_unit.eq(fu)
597
598 # registers a, b, c and out and out2 (LD/ST EA)
599 comb += e.read_reg1.eq(dec_a.reg_out)
600 comb += e.read_reg2.eq(dec_b.reg_out)
601 comb += e.read_reg3.eq(dec_c.reg_out)
602 comb += e.write_reg.eq(dec_o.reg_out)
603 comb += e.write_ea.eq(dec_o2.reg_out)
604 comb += do.imm_data.eq(dec_b.imm_out) # immediate in RB (usually)
605 comb += do.zero_a.eq(dec_a.immz_out) # RA==0 detected
606
607 # rc and oe out
608 comb += do.rc.eq(dec_rc.rc_out)
609 comb += do.oe.eq(dec_oe.oe_out)
610
611 # SPRs out
612 comb += e.read_spr1.eq(dec_a.spr_out)
613 comb += e.write_spr.eq(dec_o.spr_out)
614
615 # Fast regs out
616 comb += e.read_fast1.eq(dec_a.fast_out)
617 comb += e.read_fast2.eq(dec_b.fast_out)
618 comb += e.write_fast1.eq(dec_o.fast_out)
619 comb += e.write_fast2.eq(dec_o2.fast_out)
620
621 # condition registers (CR)
622 comb += e.read_cr1.eq(dec_cr_in.cr_bitfield)
623 comb += e.read_cr2.eq(dec_cr_in.cr_bitfield_b)
624 comb += e.read_cr3.eq(dec_cr_in.cr_bitfield_o)
625 comb += e.write_cr.eq(dec_cr_out.cr_bitfield)
626
627 comb += do.read_cr_whole.eq(dec_cr_in.whole_reg)
628 comb += do.write_cr_whole.eq(dec_cr_out.whole_reg)
629 comb += do.write_cr0.eq(dec_cr_out.cr_bitfield.ok)
630
631 # decoded/selected instruction flags
632 comb += do.data_len.eq(op.ldst_len)
633 comb += do.invert_a.eq(op.inv_a)
634 comb += do.invert_out.eq(op.inv_out)
635 comb += do.input_carry.eq(op.cry_in) # carry comes in
636 comb += do.output_carry.eq(op.cry_out) # carry goes out
637 comb += do.is_32bit.eq(op.is_32b)
638 comb += do.is_signed.eq(op.sgn)
639 with m.If(op.lk):
640 comb += do.lk.eq(self.dec.LK) # XXX TODO: accessor
641
642 comb += do.byte_reverse.eq(op.br)
643 comb += do.sign_extend.eq(op.sgn_ext)
644 comb += do.update.eq(op.upd) # LD/ST "update" mode.
645
646 # These should be removed eventually
647 comb += do.input_cr.eq(op.cr_in) # condition reg comes in
648 comb += do.output_cr.eq(op.cr_out) # condition reg goes in
649
650 # sigh this is exactly the sort of thing for which the
651 # decoder is designed to not need. MTSPR, MFSPR and others need
652 # access to the XER bits. however setting e.oe is not appropriate
653 with m.If(op.internal_op == InternalOp.OP_MFSPR):
654 comb += e.xer_in.eq(1)
655 with m.If(op.internal_op == InternalOp.OP_MTSPR):
656 comb += e.xer_out.eq(1)
657
658 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
659 with m.If(op.internal_op == InternalOp.OP_TRAP):
660 comb += do.trapaddr.eq(0x70) # addr=0x700 (strip first nibble)
661
662 # illegal instruction must redirect to trap. this is done by
663 # *overwriting* the decoded instruction and starting again.
664 # (note: the same goes for interrupts and for privileged operations,
665 # just with different trapaddr and traptype)
666 with m.If(op.internal_op == InternalOp.OP_ILLEGAL):
667 # illegal instruction trap
668 self.trap(m, TT_ILLEG, 0x700)
669
670 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
671 # Note: OP_SC could actually be modified to just be a trap
672 with m.If((do.insn_type == InternalOp.OP_TRAP) |
673 (do.insn_type == InternalOp.OP_SC)):
674 # TRAP write fast1 = SRR0
675 comb += e.write_fast1.data.eq(FastRegs.SRR0) # constant: SRR0
676 comb += e.write_fast1.ok.eq(1)
677 # TRAP write fast2 = SRR1
678 comb += e.write_fast2.data.eq(FastRegs.SRR1) # constant: SRR1
679 comb += e.write_fast2.ok.eq(1)
680
681 # RFID: needs to read SRR0/1
682 with m.If(do.insn_type == InternalOp.OP_RFID):
683 # TRAP read fast1 = SRR0
684 comb += e.read_fast1.data.eq(FastRegs.SRR0) # constant: SRR0
685 comb += e.read_fast1.ok.eq(1)
686 # TRAP read fast2 = SRR1
687 comb += e.read_fast2.data.eq(FastRegs.SRR1) # constant: SRR1
688 comb += e.read_fast2.ok.eq(1)
689
690 return m
691
692 # TODO: get msr, then can do privileged instruction
693 with m.If(instr_is_priv(m, op.internal_op, e.insn) & msr[MSR_PR]):
694 # privileged instruction trap
695 self.trap(m, TT_PRIV, 0x700)
696 return m
697
698 def trap(self, m, traptype, trapaddr):
699 """trap: this basically "rewrites" the decoded instruction as a trap
700 """
701 comb = m.d.comb
702 e, op, do = self.e, self.dec.op, self.e.do
703 comb += e.eq(0) # reset eeeeeverything
704 # start again
705 comb += do.insn.eq(self.dec.opcode_in)
706 comb += do.insn_type.eq(InternalOp.OP_TRAP)
707 comb += do.fn_unit.eq(Function.TRAP)
708 comb += do.trapaddr.eq(trapaddr >> 4) # cut bottom 4 bits
709 comb += do.traptype.eq(traptype) # request type
710
711 def regspecmap_read(self, regfile, regname):
712 """regspecmap_read: provides PowerDecode2 with an encoding relationship
713 to Function Unit port regfiles (read-enable, read regnum, write regnum)
714 regfile and regname arguments are fields 1 and 2 from a given regspec.
715 """
716 return regspec_decode_read(self.e, regfile, regname)
717
718 def regspecmap_write(self, regfile, regname):
719 """regspecmap_write: provides PowerDecode2 with an encoding relationship
720 to Function Unit port regfiles (write port, write regnum)
721 regfile and regname arguments are fields 1 and 2 from a given regspec.
722 """
723 return regspec_decode_write(self.e, regfile, regname)
724
725 def rdflags(self, cu):
726 rdl = []
727 for idx in range(cu.n_src):
728 regfile, regname, _ = cu.get_in_spec(idx)
729 rdflag, read = self.regspecmap_read(regfile, regname)
730 rdl.append(rdflag)
731 print ("rdflags", rdl)
732 return Cat(*rdl)
733
734
735 if __name__ == '__main__':
736 pdecode = create_pdecode()
737 dec2 = PowerDecode2(pdecode)
738 vl = rtlil.convert(dec2, ports=dec2.ports() + pdecode.ports())
739 with open("dec2.il", "w") as f:
740 f.write(vl)
741