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