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