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
11 from soc
.regfile
.regfiles
import XERRegs
13 from nmutil
.picker
import PriorityPicker
14 from nmutil
.iocontrol
import RecordObject
15 from nmutil
.extend
import exts
17 from soc
.decoder
.power_regspec_map
import regspec_decode_read
18 from soc
.decoder
.power_regspec_map
import regspec_decode_write
19 from soc
.decoder
.power_decoder
import create_pdecode
20 from soc
.decoder
.power_enums
import (MicrOp
, CryIn
, Function
,
22 LdstLen
, In1Sel
, In2Sel
, In3Sel
,
23 OutSel
, SPR
, RC
, LDSTMode
)
24 from soc
.decoder
.decode2execute1
import Decode2ToExecute1Type
, Data
25 from soc
.consts
import MSR
27 from soc
.regfile
.regfiles
import FastRegs
28 from soc
.consts
import TT
29 from soc
.config
.state
import CoreState
30 from soc
.regfile
.util
import spr_to_fast
33 def decode_spr_num(spr
):
34 return Cat(spr
[5:10], spr
[0:5])
37 def instr_is_priv(m
, op
, insn
):
38 """determines if the instruction is privileged or not
41 is_priv_insn
= Signal(reset_less
=True)
43 with m
.Case(MicrOp
.OP_ATTN
, MicrOp
.OP_MFMSR
, MicrOp
.OP_MTMSRD
,
44 MicrOp
.OP_MTMSR
, MicrOp
.OP_RFID
):
45 comb
+= is_priv_insn
.eq(1)
47 #with m.Case(MicrOp.OP_TLBIE) : comb += is_priv_insn.eq(1)
48 with m
.Case(MicrOp
.OP_MFSPR
, MicrOp
.OP_MTSPR
):
49 with m
.If(insn
[20]): # field XFX.spr[-1] i think
50 comb
+= is_priv_insn
.eq(1)
54 class SPRMap(Elaboratable
):
55 """SPRMap: maps POWER9 SPR numbers to internal enum values, fast and slow
59 self
.spr_i
= Signal(10, reset_less
=True)
60 self
.spr_o
= Data(SPR
, name
="spr_o")
61 self
.fast_o
= Data(3, name
="fast_o")
63 def elaborate(self
, platform
):
65 with m
.Switch(self
.spr_i
):
66 for i
, x
in enumerate(SPR
):
68 m
.d
.comb
+= self
.spr_o
.data
.eq(i
)
69 m
.d
.comb
+= self
.spr_o
.ok
.eq(1)
70 for x
, v
in spr_to_fast
.items():
72 m
.d
.comb
+= self
.fast_o
.data
.eq(v
)
73 m
.d
.comb
+= self
.fast_o
.ok
.eq(1)
77 class DecodeA(Elaboratable
):
78 """DecodeA from instruction
80 decodes register RA, implicit and explicit CSRs
83 def __init__(self
, dec
):
85 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
86 self
.insn_in
= Signal(32, reset_less
=True)
87 self
.reg_out
= Data(5, name
="reg_a")
88 self
.spr_out
= Data(SPR
, "spr_a")
89 self
.fast_out
= Data(3, "fast_a")
91 def elaborate(self
, platform
):
94 m
.submodules
.sprmap
= sprmap
= SPRMap()
96 # select Register A field
97 ra
= Signal(5, reset_less
=True)
98 comb
+= ra
.eq(self
.dec
.RA
)
99 with m
.If((self
.sel_in
== In1Sel
.RA
) |
100 ((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
101 (ra
!= Const(0, 5)))):
102 comb
+= self
.reg_out
.data
.eq(ra
)
103 comb
+= self
.reg_out
.ok
.eq(1)
105 # some Logic/ALU ops have RS as the 3rd arg, but no "RA".
106 with m
.If(self
.sel_in
== In1Sel
.RS
):
107 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
108 comb
+= self
.reg_out
.ok
.eq(1)
110 # decode Fast-SPR based on instruction type
112 with m
.Switch(op
.internal_op
):
114 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeOut
115 with m
.Case(MicrOp
.OP_BC
):
116 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
118 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
119 comb
+= self
.fast_out
.ok
.eq(1)
120 with m
.Case(MicrOp
.OP_BCREG
):
121 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
122 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
123 with m
.If(xo9
& ~xo5
):
125 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
126 comb
+= self
.fast_out
.ok
.eq(1)
128 # MFSPR move from SPRs
129 with m
.Case(MicrOp
.OP_MFSPR
):
130 spr
= Signal(10, reset_less
=True)
131 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
132 comb
+= sprmap
.spr_i
.eq(spr
)
133 comb
+= self
.spr_out
.eq(sprmap
.spr_o
)
134 comb
+= self
.fast_out
.eq(sprmap
.fast_o
)
139 class DecodeAImm(Elaboratable
):
140 """DecodeA immediate from instruction
142 decodes register RA, whether immediate-zero, implicit and
146 def __init__(self
, dec
):
148 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
149 self
.immz_out
= Signal(reset_less
=True)
151 def elaborate(self
, platform
):
155 # zero immediate requested
156 ra
= Signal(5, reset_less
=True)
157 comb
+= ra
.eq(self
.dec
.RA
)
158 with m
.If((self
.sel_in
== In1Sel
.RA_OR_ZERO
) & (ra
== Const(0, 5))):
159 comb
+= self
.immz_out
.eq(1)
164 class DecodeB(Elaboratable
):
165 """DecodeB from instruction
167 decodes register RB, different forms of immediate (signed, unsigned),
168 and implicit SPRs. register B is basically "lane 2" into the CompUnits.
169 by industry-standard convention, "lane 2" is where fully-decoded
170 immediates are muxed in.
173 def __init__(self
, dec
):
175 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
176 self
.insn_in
= Signal(32, reset_less
=True)
177 self
.reg_out
= Data(5, "reg_b")
178 self
.imm_out
= Data(64, "imm_b")
179 self
.fast_out
= Data(3, "fast_b")
181 def elaborate(self
, platform
):
185 # select Register B field
186 with m
.Switch(self
.sel_in
):
187 with m
.Case(In2Sel
.RB
):
188 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
)
189 comb
+= self
.reg_out
.ok
.eq(1)
190 with m
.Case(In2Sel
.RS
):
191 # for M-Form shiftrot
192 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
193 comb
+= self
.reg_out
.ok
.eq(1)
194 with m
.Case(In2Sel
.CONST_UI
): # unsigned
195 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
)
196 comb
+= self
.imm_out
.ok
.eq(1)
197 with m
.Case(In2Sel
.CONST_SI
): # sign-extended 16-bit
198 si
= Signal(16, reset_less
=True)
199 comb
+= si
.eq(self
.dec
.SI
)
200 comb
+= self
.imm_out
.data
.eq(exts(si
, 16, 64))
201 comb
+= self
.imm_out
.ok
.eq(1)
202 with m
.Case(In2Sel
.CONST_SI_HI
): # sign-extended 16+16=32 bit
203 si_hi
= Signal(32, reset_less
=True)
204 comb
+= si_hi
.eq(self
.dec
.SI
<< 16)
205 comb
+= self
.imm_out
.data
.eq(exts(si_hi
, 32, 64))
206 comb
+= self
.imm_out
.ok
.eq(1)
207 with m
.Case(In2Sel
.CONST_UI_HI
): # unsigned
208 ui
= Signal(16, reset_less
=True)
209 comb
+= ui
.eq(self
.dec
.UI
)
210 comb
+= self
.imm_out
.data
.eq(ui
<< 16)
211 comb
+= self
.imm_out
.ok
.eq(1)
212 with m
.Case(In2Sel
.CONST_LI
): # sign-extend 24+2=26 bit
213 li
= Signal(26, reset_less
=True)
214 comb
+= li
.eq(self
.dec
.LI
<< 2)
215 comb
+= self
.imm_out
.data
.eq(exts(li
, 26, 64))
216 comb
+= self
.imm_out
.ok
.eq(1)
217 with m
.Case(In2Sel
.CONST_BD
): # sign-extend (14+2)=16 bit
218 bd
= Signal(16, reset_less
=True)
219 comb
+= bd
.eq(self
.dec
.BD
<< 2)
220 comb
+= self
.imm_out
.data
.eq(exts(bd
, 16, 64))
221 comb
+= self
.imm_out
.ok
.eq(1)
222 with m
.Case(In2Sel
.CONST_DS
): # sign-extended (14+2=16) bit
223 ds
= Signal(16, reset_less
=True)
224 comb
+= ds
.eq(self
.dec
.DS
<< 2)
225 comb
+= self
.imm_out
.data
.eq(exts(ds
, 16, 64))
226 comb
+= self
.imm_out
.ok
.eq(1)
227 with m
.Case(In2Sel
.CONST_M1
): # signed (-1)
228 comb
+= self
.imm_out
.data
.eq(~
Const(0, 64)) # all 1s
229 comb
+= self
.imm_out
.ok
.eq(1)
230 with m
.Case(In2Sel
.CONST_SH
): # unsigned - for shift
231 comb
+= self
.imm_out
.data
.eq(self
.dec
.sh
)
232 comb
+= self
.imm_out
.ok
.eq(1)
233 with m
.Case(In2Sel
.CONST_SH32
): # unsigned - for shift
234 comb
+= self
.imm_out
.data
.eq(self
.dec
.SH32
)
235 comb
+= self
.imm_out
.ok
.eq(1)
237 # decode SPR2 based on instruction type
239 # BCREG implicitly uses LR or TAR for 2nd reg
240 # CTR however is already in fast_spr1 *not* 2.
241 with m
.If(op
.internal_op
== MicrOp
.OP_BCREG
):
242 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
243 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
245 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
246 comb
+= self
.fast_out
.ok
.eq(1)
248 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
249 comb
+= self
.fast_out
.ok
.eq(1)
254 class DecodeC(Elaboratable
):
255 """DecodeC from instruction
257 decodes register RC. this is "lane 3" into some CompUnits (not many)
260 def __init__(self
, dec
):
262 self
.sel_in
= Signal(In3Sel
, reset_less
=True)
263 self
.insn_in
= Signal(32, reset_less
=True)
264 self
.reg_out
= Data(5, "reg_c")
266 def elaborate(self
, platform
):
270 # select Register C field
271 with m
.Switch(self
.sel_in
):
272 with m
.Case(In3Sel
.RB
):
273 # for M-Form shiftrot
274 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
)
275 comb
+= self
.reg_out
.ok
.eq(1)
276 with m
.Case(In3Sel
.RS
):
277 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
278 comb
+= self
.reg_out
.ok
.eq(1)
283 class DecodeOut(Elaboratable
):
284 """DecodeOut from instruction
286 decodes output register RA, RT or SPR
289 def __init__(self
, dec
):
291 self
.sel_in
= Signal(OutSel
, reset_less
=True)
292 self
.insn_in
= Signal(32, reset_less
=True)
293 self
.reg_out
= Data(5, "reg_o")
294 self
.spr_out
= Data(SPR
, "spr_o")
295 self
.fast_out
= Data(3, "fast_o")
297 def elaborate(self
, platform
):
300 m
.submodules
.sprmap
= sprmap
= SPRMap()
303 # select Register out field
304 with m
.Switch(self
.sel_in
):
305 with m
.Case(OutSel
.RT
):
306 comb
+= self
.reg_out
.data
.eq(self
.dec
.RT
)
307 comb
+= self
.reg_out
.ok
.eq(1)
308 with m
.Case(OutSel
.RA
):
309 comb
+= self
.reg_out
.data
.eq(self
.dec
.RA
)
310 comb
+= self
.reg_out
.ok
.eq(1)
311 with m
.Case(OutSel
.SPR
):
312 spr
= Signal(10, reset_less
=True)
313 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
314 # MFSPR move to SPRs - needs mapping
315 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
316 comb
+= sprmap
.spr_i
.eq(spr
)
317 comb
+= self
.spr_out
.eq(sprmap
.spr_o
)
318 comb
+= self
.fast_out
.eq(sprmap
.fast_o
)
320 with m
.Switch(op
.internal_op
):
322 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeA
323 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_BCREG
):
324 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
326 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
327 comb
+= self
.fast_out
.ok
.eq(1)
329 # RFID 1st spr (fast)
330 with m
.Case(MicrOp
.OP_RFID
):
331 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
332 comb
+= self
.fast_out
.ok
.eq(1)
337 class DecodeOut2(Elaboratable
):
338 """DecodeOut2 from instruction
340 decodes output registers
343 def __init__(self
, dec
):
345 self
.sel_in
= Signal(OutSel
, reset_less
=True)
346 self
.lk
= Signal(reset_less
=True)
347 self
.insn_in
= Signal(32, reset_less
=True)
348 self
.reg_out
= Data(5, "reg_o")
349 self
.fast_out
= Data(3, "fast_o")
351 def elaborate(self
, platform
):
355 # update mode LD/ST uses read-reg A also as an output
356 with m
.If(self
.dec
.op
.upd
== LDSTMode
.update
):
357 comb
+= self
.reg_out
.eq(self
.dec
.RA
)
358 comb
+= self
.reg_out
.ok
.eq(1)
360 # B, BC or BCREG: potential implicit register (LR) output
361 # these give bl, bcl, bclrl, etc.
363 with m
.Switch(op
.internal_op
):
365 # BC* implicit register (LR)
366 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_B
, MicrOp
.OP_BCREG
):
367 with m
.If(self
.lk
): # "link" mode
368 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
) # constant: LR
369 comb
+= self
.fast_out
.ok
.eq(1)
371 # RFID 2nd spr (fast)
372 with m
.Case(MicrOp
.OP_RFID
):
373 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
374 comb
+= self
.fast_out
.ok
.eq(1)
379 class DecodeRC(Elaboratable
):
380 """DecodeRc from instruction
382 decodes Record bit Rc
385 def __init__(self
, dec
):
387 self
.sel_in
= Signal(RC
, reset_less
=True)
388 self
.insn_in
= Signal(32, reset_less
=True)
389 self
.rc_out
= Data(1, "rc")
391 def elaborate(self
, platform
):
395 # select Record bit out field
396 with m
.Switch(self
.sel_in
):
398 comb
+= self
.rc_out
.data
.eq(self
.dec
.Rc
)
399 comb
+= self
.rc_out
.ok
.eq(1)
401 comb
+= self
.rc_out
.data
.eq(1)
402 comb
+= self
.rc_out
.ok
.eq(1)
403 with m
.Case(RC
.NONE
):
404 comb
+= self
.rc_out
.data
.eq(0)
405 comb
+= self
.rc_out
.ok
.eq(1)
410 class DecodeOE(Elaboratable
):
411 """DecodeOE from instruction
413 decodes OE field: uses RC decode detection which might not be good
415 -- For now, use "rc" in the decode table to decide whether oe exists.
416 -- This is not entirely correct architecturally: For mulhd and
417 -- mulhdu, the OE field is reserved. It remains to be seen what an
418 -- actual POWER9 does if we set it on those instructions, for now we
419 -- test that further down when assigning to the multiplier oe input.
422 def __init__(self
, dec
):
424 self
.sel_in
= Signal(RC
, reset_less
=True)
425 self
.insn_in
= Signal(32, reset_less
=True)
426 self
.oe_out
= Data(1, "oe")
428 def elaborate(self
, platform
):
433 with m
.Switch(op
.internal_op
):
435 # mulhw, mulhwu, mulhd, mulhdu - these *ignore* OE
437 # XXX ARGH! ignoring OE causes incompatibility with microwatt
438 # http://lists.libre-soc.org/pipermail/libre-soc-dev/2020-August/000302.html
439 with m
.Case(MicrOp
.OP_MUL_H64
, MicrOp
.OP_MUL_H32
,
440 MicrOp
.OP_EXTS
, MicrOp
.OP_CNTZ
,
441 MicrOp
.OP_SHL
, MicrOp
.OP_SHR
, MicrOp
.OP_RLC
,
442 MicrOp
.OP_LOAD
, MicrOp
.OP_STORE
,
443 MicrOp
.OP_RLCL
, MicrOp
.OP_RLCR
,
447 # all other ops decode OE field
449 # select OE bit out field
450 with m
.Switch(self
.sel_in
):
452 comb
+= self
.oe_out
.data
.eq(self
.dec
.OE
)
453 comb
+= self
.oe_out
.ok
.eq(1)
458 class DecodeCRIn(Elaboratable
):
459 """Decodes input CR from instruction
461 CR indices - insn fields - (not the data *in* the CR) require only 3
462 bits because they refer to CR0-CR7
465 def __init__(self
, dec
):
467 self
.sel_in
= Signal(CRInSel
, reset_less
=True)
468 self
.insn_in
= Signal(32, reset_less
=True)
469 self
.cr_bitfield
= Data(3, "cr_bitfield")
470 self
.cr_bitfield_b
= Data(3, "cr_bitfield_b")
471 self
.cr_bitfield_o
= Data(3, "cr_bitfield_o")
472 self
.whole_reg
= Data(8, "cr_fxm")
474 def elaborate(self
, platform
):
476 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
482 comb
+= self
.cr_bitfield
.ok
.eq(0)
483 comb
+= self
.cr_bitfield_b
.ok
.eq(0)
484 comb
+= self
.whole_reg
.ok
.eq(0)
485 with m
.Switch(self
.sel_in
):
486 with m
.Case(CRInSel
.NONE
):
487 pass # No bitfield activated
488 with m
.Case(CRInSel
.CR0
):
489 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
490 comb
+= self
.cr_bitfield
.ok
.eq(1)
491 with m
.Case(CRInSel
.BI
):
492 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BI
[2:5])
493 comb
+= self
.cr_bitfield
.ok
.eq(1)
494 with m
.Case(CRInSel
.BFA
):
495 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BFA
)
496 comb
+= self
.cr_bitfield
.ok
.eq(1)
497 with m
.Case(CRInSel
.BA_BB
):
498 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BA
[2:5])
499 comb
+= self
.cr_bitfield
.ok
.eq(1)
500 comb
+= self
.cr_bitfield_b
.data
.eq(self
.dec
.BB
[2:5])
501 comb
+= self
.cr_bitfield_b
.ok
.eq(1)
502 comb
+= self
.cr_bitfield_o
.data
.eq(self
.dec
.BT
[2:5])
503 comb
+= self
.cr_bitfield_o
.ok
.eq(1)
504 with m
.Case(CRInSel
.BC
):
505 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BC
[2:5])
506 comb
+= self
.cr_bitfield
.ok
.eq(1)
507 with m
.Case(CRInSel
.WHOLE_REG
):
508 comb
+= self
.whole_reg
.ok
.eq(1)
509 move_one
= Signal(reset_less
=True)
510 comb
+= move_one
.eq(self
.insn_in
[20]) # MSB0 bit 11
511 with m
.If((op
.internal_op
== MicrOp
.OP_MFCR
) & move_one
):
512 # must one-hot the FXM field
513 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
514 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
516 # otherwise use all of it
517 comb
+= self
.whole_reg
.data
.eq(0xff)
522 class DecodeCROut(Elaboratable
):
523 """Decodes input CR from instruction
525 CR indices - insn fields - (not the data *in* the CR) require only 3
526 bits because they refer to CR0-CR7
529 def __init__(self
, dec
):
531 self
.rc_in
= Signal(reset_less
=True)
532 self
.sel_in
= Signal(CROutSel
, reset_less
=True)
533 self
.insn_in
= Signal(32, reset_less
=True)
534 self
.cr_bitfield
= Data(3, "cr_bitfield")
535 self
.whole_reg
= Data(8, "cr_fxm")
537 def elaborate(self
, platform
):
541 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
544 comb
+= self
.cr_bitfield
.ok
.eq(0)
545 comb
+= self
.whole_reg
.ok
.eq(0)
546 with m
.Switch(self
.sel_in
):
547 with m
.Case(CROutSel
.NONE
):
548 pass # No bitfield activated
549 with m
.Case(CROutSel
.CR0
):
550 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
551 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
552 with m
.Case(CROutSel
.BF
):
553 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BF
)
554 comb
+= self
.cr_bitfield
.ok
.eq(1)
555 with m
.Case(CROutSel
.BT
):
556 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormXL
.BT
[2:5])
557 comb
+= self
.cr_bitfield
.ok
.eq(1)
558 with m
.Case(CROutSel
.WHOLE_REG
):
559 comb
+= self
.whole_reg
.ok
.eq(1)
560 move_one
= Signal(reset_less
=True)
561 comb
+= move_one
.eq(self
.insn_in
[20])
562 with m
.If((op
.internal_op
== MicrOp
.OP_MTCRF
)):
564 # must one-hot the FXM field
565 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
566 with m
.If(ppick
.en_o
):
567 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
569 comb
+= self
.whole_reg
.data
.eq(0b00000001) # CR7
571 comb
+= self
.whole_reg
.data
.eq(self
.dec
.FXM
)
573 # otherwise use all of it
574 comb
+= self
.whole_reg
.data
.eq(0xff)
579 class PowerDecode2(Elaboratable
):
580 """PowerDecode2: the main instruction decoder.
582 whilst PowerDecode is responsible for decoding the actual opcode, this
583 module encapsulates further specialist, sparse information and
584 expansion of fields that is inconvenient to have in the CSV files.
585 for example: the encoding of the immediates, which are detected
586 and expanded out to their full value from an annotated (enum)
589 implicit register usage is also set up, here. for example: OP_BC
590 requires implicitly reading CTR, OP_RFID requires implicitly writing
593 in addition, PowerDecoder2 is responsible for detecting whether
594 instructions are illegal (or privileged) or not, and instead of
595 just leaving at that, *replacing* the instruction to execute with
596 a suitable alternative (trap).
599 def __init__(self
, dec
):
602 self
.e
= Decode2ToExecute1Type()
604 # state information needed by the Decoder (TODO: this as a Record)
605 self
.state
= CoreState("dec2")
608 return self
.dec
.ports() + self
.e
.ports()
610 def elaborate(self
, platform
):
614 e_out
, op
, do_out
= self
.e
, self
.dec
.op
, self
.e
.do
615 dec_spr
, msr
, cia
, ext_irq
= state
.dec
, state
.msr
, state
.pc
, state
.eint
617 # fill in for a normal instruction (not an exception)
618 # copy over if non-exception, non-privileged etc. is detected
619 e
= Decode2ToExecute1Type()
622 # set up submodule decoders
623 m
.submodules
.dec
= self
.dec
624 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
)
625 m
.submodules
.dec_ai
= dec_ai
= DecodeAImm(self
.dec
)
626 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
)
627 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
)
628 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
)
629 m
.submodules
.dec_o2
= dec_o2
= DecodeOut2(self
.dec
)
630 m
.submodules
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
631 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
)
632 m
.submodules
.dec_cr_in
= dec_cr_in
= DecodeCRIn(self
.dec
)
633 m
.submodules
.dec_cr_out
= dec_cr_out
= DecodeCROut(self
.dec
)
635 # copy instruction through...
636 for i
in [do
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
637 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
, dec_rc
.insn_in
,
638 dec_oe
.insn_in
, dec_cr_in
.insn_in
, dec_cr_out
.insn_in
]:
639 comb
+= i
.eq(self
.dec
.opcode_in
)
641 # ...and subdecoders' input fields
642 comb
+= dec_a
.sel_in
.eq(op
.in1_sel
)
643 comb
+= dec_ai
.sel_in
.eq(op
.in1_sel
)
644 comb
+= dec_b
.sel_in
.eq(op
.in2_sel
)
645 comb
+= dec_c
.sel_in
.eq(op
.in3_sel
)
646 comb
+= dec_o
.sel_in
.eq(op
.out_sel
)
647 comb
+= dec_o2
.sel_in
.eq(op
.out_sel
)
648 comb
+= dec_o2
.lk
.eq(do
.lk
)
649 comb
+= dec_rc
.sel_in
.eq(op
.rc_sel
)
650 comb
+= dec_oe
.sel_in
.eq(op
.rc_sel
) # XXX should be OE sel
651 comb
+= dec_cr_in
.sel_in
.eq(op
.cr_in
)
652 comb
+= dec_cr_out
.sel_in
.eq(op
.cr_out
)
653 comb
+= dec_cr_out
.rc_in
.eq(dec_rc
.rc_out
.data
)
656 comb
+= do
.msr
.eq(msr
)
657 comb
+= do
.cia
.eq(cia
)
659 # set up instruction, pick fn unit
660 # no op: defaults to OP_ILLEGAL
661 comb
+= do
.insn_type
.eq(op
.internal_op
)
662 comb
+= do
.fn_unit
.eq(op
.function_unit
)
664 # registers a, b, c and out and out2 (LD/ST EA)
665 comb
+= e
.read_reg1
.eq(dec_a
.reg_out
)
666 comb
+= e
.read_reg2
.eq(dec_b
.reg_out
)
667 comb
+= e
.read_reg3
.eq(dec_c
.reg_out
)
668 comb
+= e
.write_reg
.eq(dec_o
.reg_out
)
669 comb
+= e
.write_ea
.eq(dec_o2
.reg_out
)
670 comb
+= do
.imm_data
.eq(dec_b
.imm_out
) # immediate in RB (usually)
671 comb
+= do
.zero_a
.eq(dec_ai
.immz_out
) # RA==0 detected
674 comb
+= do
.rc
.eq(dec_rc
.rc_out
)
675 comb
+= do
.oe
.eq(dec_oe
.oe_out
)
678 comb
+= e
.read_spr1
.eq(dec_a
.spr_out
)
679 comb
+= e
.write_spr
.eq(dec_o
.spr_out
)
682 comb
+= e
.read_fast1
.eq(dec_a
.fast_out
)
683 comb
+= e
.read_fast2
.eq(dec_b
.fast_out
)
684 comb
+= e
.write_fast1
.eq(dec_o
.fast_out
)
685 comb
+= e
.write_fast2
.eq(dec_o2
.fast_out
)
687 # condition registers (CR)
688 comb
+= e
.read_cr1
.eq(dec_cr_in
.cr_bitfield
)
689 comb
+= e
.read_cr2
.eq(dec_cr_in
.cr_bitfield_b
)
690 comb
+= e
.read_cr3
.eq(dec_cr_in
.cr_bitfield_o
)
691 comb
+= e
.write_cr
.eq(dec_cr_out
.cr_bitfield
)
693 comb
+= do
.read_cr_whole
.eq(dec_cr_in
.whole_reg
)
694 comb
+= do
.write_cr_whole
.eq(dec_cr_out
.whole_reg
)
695 comb
+= do
.write_cr0
.eq(dec_cr_out
.cr_bitfield
.ok
)
697 # decoded/selected instruction flags
698 comb
+= do
.data_len
.eq(op
.ldst_len
)
699 comb
+= do
.invert_in
.eq(op
.inv_a
)
700 comb
+= do
.invert_out
.eq(op
.inv_out
)
701 comb
+= do
.input_carry
.eq(op
.cry_in
) # carry comes in
702 comb
+= do
.output_carry
.eq(op
.cry_out
) # carry goes out
703 comb
+= do
.is_32bit
.eq(op
.is_32b
)
704 comb
+= do
.is_signed
.eq(op
.sgn
)
706 comb
+= do
.lk
.eq(self
.dec
.LK
) # XXX TODO: accessor
708 comb
+= do
.byte_reverse
.eq(op
.br
)
709 comb
+= do
.sign_extend
.eq(op
.sgn_ext
)
710 comb
+= do
.ldst_mode
.eq(op
.upd
) # LD/ST mode (update, cache-inhibit)
712 # These should be removed eventually
713 comb
+= do
.input_cr
.eq(op
.cr_in
) # condition reg comes in
714 comb
+= do
.output_cr
.eq(op
.cr_out
) # condition reg goes in
716 # sigh this is exactly the sort of thing for which the
717 # decoder is designed to not need. MTSPR, MFSPR and others need
718 # access to the XER bits. however setting e.oe is not appropriate
719 with m
.If(op
.internal_op
== MicrOp
.OP_MFSPR
):
720 comb
+= e
.xer_in
.eq(0b111) # SO, CA, OV
721 with m
.If(op
.internal_op
== MicrOp
.OP_CMP
):
722 comb
+= e
.xer_in
.eq(1<<XERRegs
.SO
) # SO
723 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
724 comb
+= e
.xer_out
.eq(1)
726 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
727 with m
.If(op
.internal_op
== MicrOp
.OP_TRAP
):
728 # *DO NOT* call self.trap here. that would reset absolutely
729 # rverything including destroying read of RA and RB.
730 comb
+= do
.trapaddr
.eq(0x70) # addr=0x700 (strip first nibble)
732 # check if instruction is privileged
733 is_priv_insn
= instr_is_priv(m
, op
.internal_op
, e
.do
.insn
)
735 # external interrupt? only if MSR.EE set
736 with m
.If(ext_irq
& msr
[MSR
.EE
]): # v3.0B p944 (MSR.EE)
737 self
.trap(m
, TT
.EINT
, 0x500)
739 # decrement counter (v3.0B p1099): TODO 32-bit version (MSR.LPCR)
740 with m
.If(dec_spr
[63] & msr
[MSR
.EE
]): # v3.0B 6.5.11 p1076
741 self
.trap(m
, TT
.DEC
, 0x900) # v3.0B 6.5 p1065
743 # privileged instruction trap
744 with m
.Elif(is_priv_insn
& msr
[MSR
.PR
]):
745 self
.trap(m
, TT
.PRIV
, 0x700)
747 # illegal instruction must redirect to trap. this is done by
748 # *overwriting* the decoded instruction and starting again.
749 # (note: the same goes for interrupts and for privileged operations,
750 # just with different trapaddr and traptype)
751 with m
.Elif(op
.internal_op
== MicrOp
.OP_ILLEGAL
):
752 # illegal instruction trap
753 self
.trap(m
, TT
.ILLEG
, 0x700)
755 # no exception, just copy things to the output
759 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
760 # Note: OP_SC could actually be modified to just be a trap
761 with m
.If((do_out
.insn_type
== MicrOp
.OP_TRAP
) |
762 (do_out
.insn_type
== MicrOp
.OP_SC
)):
763 # TRAP write fast1 = SRR0
764 comb
+= e_out
.write_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
765 comb
+= e_out
.write_fast1
.ok
.eq(1)
766 # TRAP write fast2 = SRR1
767 comb
+= e_out
.write_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
768 comb
+= e_out
.write_fast2
.ok
.eq(1)
770 # RFID: needs to read SRR0/1
771 with m
.If(do_out
.insn_type
== MicrOp
.OP_RFID
):
772 # TRAP read fast1 = SRR0
773 comb
+= e_out
.read_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
774 comb
+= e_out
.read_fast1
.ok
.eq(1)
775 # TRAP read fast2 = SRR1
776 comb
+= e_out
.read_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
777 comb
+= e_out
.read_fast2
.ok
.eq(1)
781 def trap(self
, m
, traptype
, trapaddr
):
782 """trap: this basically "rewrites" the decoded instruction as a trap
785 op
, do
, e
= self
.dec
.op
, self
.e
.do
, self
.e
786 comb
+= e
.eq(0) # reset eeeeeverything
789 comb
+= do
.insn
.eq(self
.dec
.opcode_in
)
790 comb
+= do
.insn_type
.eq(MicrOp
.OP_TRAP
)
791 comb
+= do
.fn_unit
.eq(Function
.TRAP
)
792 comb
+= do
.trapaddr
.eq(trapaddr
>> 4) # cut bottom 4 bits
793 comb
+= do
.traptype
.eq(traptype
) # request type
794 comb
+= do
.msr
.eq(self
.state
.msr
) # copy of MSR "state"
795 comb
+= do
.cia
.eq(self
.state
.pc
) # copy of PC "state"
798 def get_rdflags(e
, cu
):
800 for idx
in range(cu
.n_src
):
801 regfile
, regname
, _
= cu
.get_in_spec(idx
)
802 rdflag
, read
= regspec_decode_read(e
, regfile
, regname
)
804 print("rdflags", rdl
)
808 if __name__
== '__main__':
809 pdecode
= create_pdecode()
810 dec2
= PowerDecode2(pdecode
)
811 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
812 with
open("dec2.il", "w") as f
: