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
.experiment
.mem_types
import LDSTException
19 from soc
.decoder
.power_regspec_map
import regspec_decode_read
20 from soc
.decoder
.power_regspec_map
import regspec_decode_write
21 from soc
.decoder
.power_decoder
import create_pdecode
22 from soc
.decoder
.power_enums
import (MicrOp
, CryIn
, Function
,
24 LdstLen
, In1Sel
, In2Sel
, In3Sel
,
25 OutSel
, SPR
, RC
, LDSTMode
)
26 from soc
.decoder
.decode2execute1
import (Decode2ToExecute1Type
, Data
,
28 from soc
.consts
import MSR
30 from soc
.regfile
.regfiles
import FastRegs
31 from soc
.consts
import TT
32 from soc
.config
.state
import CoreState
33 from soc
.regfile
.util
import spr_to_fast
36 def decode_spr_num(spr
):
37 return Cat(spr
[5:10], spr
[0:5])
40 def instr_is_priv(m
, op
, insn
):
41 """determines if the instruction is privileged or not
44 is_priv_insn
= Signal(reset_less
=True)
46 with m
.Case(MicrOp
.OP_ATTN
, MicrOp
.OP_MFMSR
, MicrOp
.OP_MTMSRD
,
47 MicrOp
.OP_MTMSR
, MicrOp
.OP_RFID
):
48 comb
+= is_priv_insn
.eq(1)
50 #with m.Case(MicrOp.OP_TLBIE) : comb += is_priv_insn.eq(1)
51 with m
.Case(MicrOp
.OP_MFSPR
, MicrOp
.OP_MTSPR
):
52 with m
.If(insn
[20]): # field XFX.spr[-1] i think
53 comb
+= is_priv_insn
.eq(1)
57 class SPRMap(Elaboratable
):
58 """SPRMap: maps POWER9 SPR numbers to internal enum values, fast and slow
62 self
.spr_i
= Signal(10, reset_less
=True)
63 self
.spr_o
= Data(SPR
, name
="spr_o")
64 self
.fast_o
= Data(3, name
="fast_o")
66 def elaborate(self
, platform
):
68 with m
.Switch(self
.spr_i
):
69 for i
, x
in enumerate(SPR
):
71 m
.d
.comb
+= self
.spr_o
.data
.eq(i
)
72 m
.d
.comb
+= self
.spr_o
.ok
.eq(1)
73 for x
, v
in spr_to_fast
.items():
75 m
.d
.comb
+= self
.fast_o
.data
.eq(v
)
76 m
.d
.comb
+= self
.fast_o
.ok
.eq(1)
80 class DecodeA(Elaboratable
):
81 """DecodeA from instruction
83 decodes register RA, implicit and explicit CSRs
86 def __init__(self
, dec
):
88 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
89 self
.insn_in
= Signal(32, reset_less
=True)
90 self
.reg_out
= Data(5, name
="reg_a")
91 self
.spr_out
= Data(SPR
, "spr_a")
92 self
.fast_out
= Data(3, "fast_a")
94 def elaborate(self
, platform
):
97 m
.submodules
.sprmap
= sprmap
= SPRMap()
99 # select Register A field
100 ra
= Signal(5, reset_less
=True)
101 comb
+= ra
.eq(self
.dec
.RA
)
102 with m
.If((self
.sel_in
== In1Sel
.RA
) |
103 ((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
104 (ra
!= Const(0, 5)))):
105 comb
+= self
.reg_out
.data
.eq(ra
)
106 comb
+= self
.reg_out
.ok
.eq(1)
108 # some Logic/ALU ops have RS as the 3rd arg, but no "RA".
109 with m
.If(self
.sel_in
== In1Sel
.RS
):
110 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
111 comb
+= self
.reg_out
.ok
.eq(1)
113 # decode Fast-SPR based on instruction type
115 with m
.Switch(op
.internal_op
):
117 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeOut
118 with m
.Case(MicrOp
.OP_BC
):
119 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
121 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
122 comb
+= self
.fast_out
.ok
.eq(1)
123 with m
.Case(MicrOp
.OP_BCREG
):
124 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
125 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
126 with m
.If(xo9
& ~xo5
):
128 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
129 comb
+= self
.fast_out
.ok
.eq(1)
131 # MFSPR move from SPRs
132 with m
.Case(MicrOp
.OP_MFSPR
):
133 spr
= Signal(10, reset_less
=True)
134 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
135 comb
+= sprmap
.spr_i
.eq(spr
)
136 comb
+= self
.spr_out
.eq(sprmap
.spr_o
)
137 comb
+= self
.fast_out
.eq(sprmap
.fast_o
)
142 class DecodeAImm(Elaboratable
):
143 """DecodeA immediate from instruction
145 decodes register RA, whether immediate-zero, implicit and
149 def __init__(self
, dec
):
151 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
152 self
.immz_out
= Signal(reset_less
=True)
154 def elaborate(self
, platform
):
158 # zero immediate requested
159 ra
= Signal(5, reset_less
=True)
160 comb
+= ra
.eq(self
.dec
.RA
)
161 with m
.If((self
.sel_in
== In1Sel
.RA_OR_ZERO
) & (ra
== Const(0, 5))):
162 comb
+= self
.immz_out
.eq(1)
167 class DecodeB(Elaboratable
):
168 """DecodeB from instruction
170 decodes register RB, different forms of immediate (signed, unsigned),
171 and implicit SPRs. register B is basically "lane 2" into the CompUnits.
172 by industry-standard convention, "lane 2" is where fully-decoded
173 immediates are muxed in.
176 def __init__(self
, dec
):
178 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
179 self
.insn_in
= Signal(32, reset_less
=True)
180 self
.reg_out
= Data(5, "reg_b")
181 self
.fast_out
= Data(3, "fast_b")
183 def elaborate(self
, platform
):
187 # select Register B field
188 with m
.Switch(self
.sel_in
):
189 with m
.Case(In2Sel
.RB
):
190 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
)
191 comb
+= self
.reg_out
.ok
.eq(1)
192 with m
.Case(In2Sel
.RS
):
193 # for M-Form shiftrot
194 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
195 comb
+= self
.reg_out
.ok
.eq(1)
197 # decode SPR2 based on instruction type
199 # BCREG implicitly uses LR or TAR for 2nd reg
200 # CTR however is already in fast_spr1 *not* 2.
201 with m
.If(op
.internal_op
== MicrOp
.OP_BCREG
):
202 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
203 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
205 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
206 comb
+= self
.fast_out
.ok
.eq(1)
208 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
209 comb
+= self
.fast_out
.ok
.eq(1)
214 class DecodeBImm(Elaboratable
):
215 """DecodeB immediate from instruction
217 def __init__(self
, dec
):
219 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
220 self
.imm_out
= Data(64, "imm_b")
222 def elaborate(self
, platform
):
226 # select Register B Immediate
227 with m
.Switch(self
.sel_in
):
228 with m
.Case(In2Sel
.CONST_UI
): # unsigned
229 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
)
230 comb
+= self
.imm_out
.ok
.eq(1)
231 with m
.Case(In2Sel
.CONST_SI
): # sign-extended 16-bit
232 si
= Signal(16, reset_less
=True)
233 comb
+= si
.eq(self
.dec
.SI
)
234 comb
+= self
.imm_out
.data
.eq(exts(si
, 16, 64))
235 comb
+= self
.imm_out
.ok
.eq(1)
236 with m
.Case(In2Sel
.CONST_SI_HI
): # sign-extended 16+16=32 bit
237 si_hi
= Signal(32, reset_less
=True)
238 comb
+= si_hi
.eq(self
.dec
.SI
<< 16)
239 comb
+= self
.imm_out
.data
.eq(exts(si_hi
, 32, 64))
240 comb
+= self
.imm_out
.ok
.eq(1)
241 with m
.Case(In2Sel
.CONST_UI_HI
): # unsigned
242 ui
= Signal(16, reset_less
=True)
243 comb
+= ui
.eq(self
.dec
.UI
)
244 comb
+= self
.imm_out
.data
.eq(ui
<< 16)
245 comb
+= self
.imm_out
.ok
.eq(1)
246 with m
.Case(In2Sel
.CONST_LI
): # sign-extend 24+2=26 bit
247 li
= Signal(26, reset_less
=True)
248 comb
+= li
.eq(self
.dec
.LI
<< 2)
249 comb
+= self
.imm_out
.data
.eq(exts(li
, 26, 64))
250 comb
+= self
.imm_out
.ok
.eq(1)
251 with m
.Case(In2Sel
.CONST_BD
): # sign-extend (14+2)=16 bit
252 bd
= Signal(16, reset_less
=True)
253 comb
+= bd
.eq(self
.dec
.BD
<< 2)
254 comb
+= self
.imm_out
.data
.eq(exts(bd
, 16, 64))
255 comb
+= self
.imm_out
.ok
.eq(1)
256 with m
.Case(In2Sel
.CONST_DS
): # sign-extended (14+2=16) bit
257 ds
= Signal(16, reset_less
=True)
258 comb
+= ds
.eq(self
.dec
.DS
<< 2)
259 comb
+= self
.imm_out
.data
.eq(exts(ds
, 16, 64))
260 comb
+= self
.imm_out
.ok
.eq(1)
261 with m
.Case(In2Sel
.CONST_M1
): # signed (-1)
262 comb
+= self
.imm_out
.data
.eq(~
Const(0, 64)) # all 1s
263 comb
+= self
.imm_out
.ok
.eq(1)
264 with m
.Case(In2Sel
.CONST_SH
): # unsigned - for shift
265 comb
+= self
.imm_out
.data
.eq(self
.dec
.sh
)
266 comb
+= self
.imm_out
.ok
.eq(1)
267 with m
.Case(In2Sel
.CONST_SH32
): # unsigned - for shift
268 comb
+= self
.imm_out
.data
.eq(self
.dec
.SH32
)
269 comb
+= self
.imm_out
.ok
.eq(1)
274 class DecodeC(Elaboratable
):
275 """DecodeC from instruction
277 decodes register RC. this is "lane 3" into some CompUnits (not many)
280 def __init__(self
, dec
):
282 self
.sel_in
= Signal(In3Sel
, reset_less
=True)
283 self
.insn_in
= Signal(32, reset_less
=True)
284 self
.reg_out
= Data(5, "reg_c")
286 def elaborate(self
, platform
):
290 # select Register C field
291 with m
.Switch(self
.sel_in
):
292 with m
.Case(In3Sel
.RB
):
293 # for M-Form shiftrot
294 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
)
295 comb
+= self
.reg_out
.ok
.eq(1)
296 with m
.Case(In3Sel
.RS
):
297 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
298 comb
+= self
.reg_out
.ok
.eq(1)
303 class DecodeOut(Elaboratable
):
304 """DecodeOut from instruction
306 decodes output register RA, RT or SPR
309 def __init__(self
, dec
):
311 self
.sel_in
= Signal(OutSel
, reset_less
=True)
312 self
.insn_in
= Signal(32, reset_less
=True)
313 self
.reg_out
= Data(5, "reg_o")
314 self
.spr_out
= Data(SPR
, "spr_o")
315 self
.fast_out
= Data(3, "fast_o")
317 def elaborate(self
, platform
):
320 m
.submodules
.sprmap
= sprmap
= SPRMap()
323 # select Register out field
324 with m
.Switch(self
.sel_in
):
325 with m
.Case(OutSel
.RT
):
326 comb
+= self
.reg_out
.data
.eq(self
.dec
.RT
)
327 comb
+= self
.reg_out
.ok
.eq(1)
328 with m
.Case(OutSel
.RA
):
329 comb
+= self
.reg_out
.data
.eq(self
.dec
.RA
)
330 comb
+= self
.reg_out
.ok
.eq(1)
331 with m
.Case(OutSel
.SPR
):
332 spr
= Signal(10, reset_less
=True)
333 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
334 # MFSPR move to SPRs - needs mapping
335 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
336 comb
+= sprmap
.spr_i
.eq(spr
)
337 comb
+= self
.spr_out
.eq(sprmap
.spr_o
)
338 comb
+= self
.fast_out
.eq(sprmap
.fast_o
)
340 with m
.Switch(op
.internal_op
):
342 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeA
343 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_BCREG
):
344 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
346 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
347 comb
+= self
.fast_out
.ok
.eq(1)
349 # RFID 1st spr (fast)
350 with m
.Case(MicrOp
.OP_RFID
):
351 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
352 comb
+= self
.fast_out
.ok
.eq(1)
357 class DecodeOut2(Elaboratable
):
358 """DecodeOut2 from instruction
360 decodes output registers
363 def __init__(self
, dec
):
365 self
.sel_in
= Signal(OutSel
, reset_less
=True)
366 self
.lk
= Signal(reset_less
=True)
367 self
.insn_in
= Signal(32, reset_less
=True)
368 self
.reg_out
= Data(5, "reg_o")
369 self
.fast_out
= Data(3, "fast_o")
371 def elaborate(self
, platform
):
375 if hasattr(self
.dec
.op
, "upd"):
376 # update mode LD/ST uses read-reg A also as an output
377 with m
.If(self
.dec
.op
.upd
== LDSTMode
.update
):
378 comb
+= self
.reg_out
.eq(self
.dec
.RA
)
379 comb
+= self
.reg_out
.ok
.eq(1)
381 # B, BC or BCREG: potential implicit register (LR) output
382 # these give bl, bcl, bclrl, etc.
384 with m
.Switch(op
.internal_op
):
386 # BC* implicit register (LR)
387 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_B
, MicrOp
.OP_BCREG
):
388 with m
.If(self
.lk
): # "link" mode
389 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
) # constant: LR
390 comb
+= self
.fast_out
.ok
.eq(1)
392 # RFID 2nd spr (fast)
393 with m
.Case(MicrOp
.OP_RFID
):
394 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
395 comb
+= self
.fast_out
.ok
.eq(1)
400 class DecodeRC(Elaboratable
):
401 """DecodeRc from instruction
403 decodes Record bit Rc
406 def __init__(self
, dec
):
408 self
.sel_in
= Signal(RC
, reset_less
=True)
409 self
.insn_in
= Signal(32, reset_less
=True)
410 self
.rc_out
= Data(1, "rc")
412 def elaborate(self
, platform
):
416 # select Record bit out field
417 with m
.Switch(self
.sel_in
):
419 comb
+= self
.rc_out
.data
.eq(self
.dec
.Rc
)
420 comb
+= self
.rc_out
.ok
.eq(1)
422 comb
+= self
.rc_out
.data
.eq(1)
423 comb
+= self
.rc_out
.ok
.eq(1)
424 with m
.Case(RC
.NONE
):
425 comb
+= self
.rc_out
.data
.eq(0)
426 comb
+= self
.rc_out
.ok
.eq(1)
431 class DecodeOE(Elaboratable
):
432 """DecodeOE from instruction
434 decodes OE field: uses RC decode detection which might not be good
436 -- For now, use "rc" in the decode table to decide whether oe exists.
437 -- This is not entirely correct architecturally: For mulhd and
438 -- mulhdu, the OE field is reserved. It remains to be seen what an
439 -- actual POWER9 does if we set it on those instructions, for now we
440 -- test that further down when assigning to the multiplier oe input.
443 def __init__(self
, dec
):
445 self
.sel_in
= Signal(RC
, reset_less
=True)
446 self
.insn_in
= Signal(32, reset_less
=True)
447 self
.oe_out
= Data(1, "oe")
449 def elaborate(self
, platform
):
454 with m
.Switch(op
.internal_op
):
456 # mulhw, mulhwu, mulhd, mulhdu - these *ignore* OE
458 # XXX ARGH! ignoring OE causes incompatibility with microwatt
459 # http://lists.libre-soc.org/pipermail/libre-soc-dev/2020-August/000302.html
460 with m
.Case(MicrOp
.OP_MUL_H64
, MicrOp
.OP_MUL_H32
,
461 MicrOp
.OP_EXTS
, MicrOp
.OP_CNTZ
,
462 MicrOp
.OP_SHL
, MicrOp
.OP_SHR
, MicrOp
.OP_RLC
,
463 MicrOp
.OP_LOAD
, MicrOp
.OP_STORE
,
464 MicrOp
.OP_RLCL
, MicrOp
.OP_RLCR
,
468 # all other ops decode OE field
470 # select OE bit out field
471 with m
.Switch(self
.sel_in
):
473 comb
+= self
.oe_out
.data
.eq(self
.dec
.OE
)
474 comb
+= self
.oe_out
.ok
.eq(1)
479 class DecodeCRIn(Elaboratable
):
480 """Decodes input CR from instruction
482 CR indices - insn fields - (not the data *in* the CR) require only 3
483 bits because they refer to CR0-CR7
486 def __init__(self
, dec
):
488 self
.sel_in
= Signal(CRInSel
, reset_less
=True)
489 self
.insn_in
= Signal(32, reset_less
=True)
490 self
.cr_bitfield
= Data(3, "cr_bitfield")
491 self
.cr_bitfield_b
= Data(3, "cr_bitfield_b")
492 self
.cr_bitfield_o
= Data(3, "cr_bitfield_o")
493 self
.whole_reg
= Data(8, "cr_fxm")
495 def elaborate(self
, platform
):
497 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
503 comb
+= self
.cr_bitfield
.ok
.eq(0)
504 comb
+= self
.cr_bitfield_b
.ok
.eq(0)
505 comb
+= self
.whole_reg
.ok
.eq(0)
506 with m
.Switch(self
.sel_in
):
507 with m
.Case(CRInSel
.NONE
):
508 pass # No bitfield activated
509 with m
.Case(CRInSel
.CR0
):
510 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
511 comb
+= self
.cr_bitfield
.ok
.eq(1)
512 with m
.Case(CRInSel
.BI
):
513 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BI
[2:5])
514 comb
+= self
.cr_bitfield
.ok
.eq(1)
515 with m
.Case(CRInSel
.BFA
):
516 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BFA
)
517 comb
+= self
.cr_bitfield
.ok
.eq(1)
518 with m
.Case(CRInSel
.BA_BB
):
519 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BA
[2:5])
520 comb
+= self
.cr_bitfield
.ok
.eq(1)
521 comb
+= self
.cr_bitfield_b
.data
.eq(self
.dec
.BB
[2:5])
522 comb
+= self
.cr_bitfield_b
.ok
.eq(1)
523 comb
+= self
.cr_bitfield_o
.data
.eq(self
.dec
.BT
[2:5])
524 comb
+= self
.cr_bitfield_o
.ok
.eq(1)
525 with m
.Case(CRInSel
.BC
):
526 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BC
[2:5])
527 comb
+= self
.cr_bitfield
.ok
.eq(1)
528 with m
.Case(CRInSel
.WHOLE_REG
):
529 comb
+= self
.whole_reg
.ok
.eq(1)
530 move_one
= Signal(reset_less
=True)
531 comb
+= move_one
.eq(self
.insn_in
[20]) # MSB0 bit 11
532 with m
.If((op
.internal_op
== MicrOp
.OP_MFCR
) & move_one
):
533 # must one-hot the FXM field
534 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
535 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
537 # otherwise use all of it
538 comb
+= self
.whole_reg
.data
.eq(0xff)
543 class DecodeCROut(Elaboratable
):
544 """Decodes input CR from instruction
546 CR indices - insn fields - (not the data *in* the CR) require only 3
547 bits because they refer to CR0-CR7
550 def __init__(self
, dec
):
552 self
.rc_in
= Signal(reset_less
=True)
553 self
.sel_in
= Signal(CROutSel
, reset_less
=True)
554 self
.insn_in
= Signal(32, reset_less
=True)
555 self
.cr_bitfield
= Data(3, "cr_bitfield")
556 self
.whole_reg
= Data(8, "cr_fxm")
558 def elaborate(self
, platform
):
562 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
565 comb
+= self
.cr_bitfield
.ok
.eq(0)
566 comb
+= self
.whole_reg
.ok
.eq(0)
567 with m
.Switch(self
.sel_in
):
568 with m
.Case(CROutSel
.NONE
):
569 pass # No bitfield activated
570 with m
.Case(CROutSel
.CR0
):
571 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
572 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
573 with m
.Case(CROutSel
.BF
):
574 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BF
)
575 comb
+= self
.cr_bitfield
.ok
.eq(1)
576 with m
.Case(CROutSel
.BT
):
577 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormXL
.BT
[2:5])
578 comb
+= self
.cr_bitfield
.ok
.eq(1)
579 with m
.Case(CROutSel
.WHOLE_REG
):
580 comb
+= self
.whole_reg
.ok
.eq(1)
581 move_one
= Signal(reset_less
=True)
582 comb
+= move_one
.eq(self
.insn_in
[20])
583 with m
.If((op
.internal_op
== MicrOp
.OP_MTCRF
)):
585 # must one-hot the FXM field
586 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
587 with m
.If(ppick
.en_o
):
588 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
590 comb
+= self
.whole_reg
.data
.eq(0b00000001) # CR7
592 comb
+= self
.whole_reg
.data
.eq(self
.dec
.FXM
)
594 # otherwise use all of it
595 comb
+= self
.whole_reg
.data
.eq(0xff)
599 # dictionary of Input Record field names that, if they exist,
600 # will need a corresponding CSV Decoder file column (actually, PowerOp)
601 # to be decoded (this includes the single bit names)
602 record_names
= {'insn_type': 'internal_op',
603 'fn_unit': 'function_unit',
607 'imm_data': 'in2_sel',
608 'invert_in': 'inv_a',
609 'invert_out': 'inv_out',
612 'output_carry': 'cry_out',
613 'input_carry': 'cry_in',
614 'is_32bit': 'is_32b',
617 'data_len': 'ldst_len',
618 'byte_reverse': 'br',
619 'sign_extend': 'sgn_ext',
624 class PowerDecodeSubset(Elaboratable
):
625 """PowerDecodeSubset: dynamic subset decoder
627 def __init__(self
, dec
, opkls
=None, fn_name
=None, final
=False, state
=None):
631 self
.fn_name
= fn_name
633 opkls
= Decode2ToOperand
634 self
.do
= opkls(fn_name
)
635 col_subset
= self
.get_col_subset(self
.do
)
637 # only needed for "main" PowerDecode2
639 self
.e
= Decode2ToExecute1Type(name
=self
.fn_name
, do
=self
.do
)
641 # create decoder if one not already given
643 dec
= create_pdecode(name
=fn_name
, col_subset
=col_subset
,
644 row_subset
=self
.rowsubsetfn
)
647 # state information needed by the Decoder
649 state
= CoreState("dec2")
652 def get_col_subset(self
, do
):
653 subset
= {'cr_in', 'cr_out', 'rc_sel'} # needed, non-optional
654 for k
, v
in record_names
.items():
657 print ("get_col_subset", self
.fn_name
, do
.fields
, subset
)
660 def rowsubsetfn(self
, opcode
, row
):
661 return row
['unit'] == self
.fn_name
664 return self
.dec
.ports() + self
.e
.ports()
666 def needs_field(self
, field
, op_field
):
671 return hasattr(do
, field
) and self
.op_get(op_field
) is not None
673 def do_copy(self
, field
, val
, final
=False):
674 if final
or self
.final
:
678 if hasattr(do
, field
) and val
is not None:
679 return getattr(do
, field
).eq(val
)
682 def op_get(self
, op_field
):
683 return getattr(self
.dec
.op
, op_field
, None)
685 def elaborate(self
, platform
):
689 op
, do
= self
.dec
.op
, self
.do
690 msr
, cia
= state
.msr
, state
.pc
692 # fill in for a normal instruction (not an exception)
693 # copy over if non-exception, non-privileged etc. is detected
695 if self
.fn_name
is None:
698 name
= self
.fn_name
+ "tmp"
699 self
.e_tmp
= Decode2ToExecute1Type(name
=name
, opkls
=self
.opkls
)
701 # set up submodule decoders
702 m
.submodules
.dec
= self
.dec
703 m
.submodules
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
704 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
)
705 m
.submodules
.dec_cr_in
= self
.dec_cr_in
= DecodeCRIn(self
.dec
)
706 m
.submodules
.dec_cr_out
= self
.dec_cr_out
= DecodeCROut(self
.dec
)
708 # copy instruction through...
710 dec_rc
.insn_in
, dec_oe
.insn_in
,
711 self
.dec_cr_in
.insn_in
, self
.dec_cr_out
.insn_in
]:
712 comb
+= i
.eq(self
.dec
.opcode_in
)
714 # ...and subdecoders' input fields
715 comb
+= dec_rc
.sel_in
.eq(op
.rc_sel
)
716 comb
+= dec_oe
.sel_in
.eq(op
.rc_sel
) # XXX should be OE sel
717 comb
+= self
.dec_cr_in
.sel_in
.eq(op
.cr_in
)
718 comb
+= self
.dec_cr_out
.sel_in
.eq(op
.cr_out
)
719 comb
+= self
.dec_cr_out
.rc_in
.eq(dec_rc
.rc_out
.data
)
722 comb
+= self
.do_copy("msr", msr
)
723 comb
+= self
.do_copy("cia", cia
)
725 # set up instruction, pick fn unit
726 # no op: defaults to OP_ILLEGAL
727 comb
+= self
.do_copy("insn_type", self
.op_get("internal_op"))
729 #function unit for decoded instruction
730 fn
= self
.op_get("function_unit")
731 spr
= Signal(10, reset_less
=True)
732 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
734 # for first test only forward SPR 18 to mmu
735 with m
.If(self
.dec
.op
.internal_op
== MicrOp
.OP_MTSPR
):
736 with m
.If((spr
== 18) |
(spr
== 19)):
737 comb
+= self
.do_copy("fn_unit",Function
.MMU
)
739 comb
+= self
.do_copy("fn_unit",fn
)
740 with m
.If(self
.dec
.op
.internal_op
== MicrOp
.OP_MFSPR
):
741 with m
.If((spr
== 18) |
(spr
== 19)):
742 comb
+= self
.do_copy("fn_unit",Function
.MMU
)
744 comb
+= self
.do_copy("fn_unit",fn
)
746 comb
+= self
.do_copy("fn_unit",fn
)
749 if self
.needs_field("zero_a", "in1_sel"):
750 m
.submodules
.dec_ai
= dec_ai
= DecodeAImm(self
.dec
)
751 comb
+= dec_ai
.sel_in
.eq(op
.in1_sel
)
752 comb
+= self
.do_copy("zero_a", dec_ai
.immz_out
) # RA==0 detected
753 if self
.needs_field("imm_data", "in2_sel"):
754 m
.submodules
.dec_bi
= dec_bi
= DecodeBImm(self
.dec
)
755 comb
+= dec_bi
.sel_in
.eq(op
.in2_sel
)
756 comb
+= self
.do_copy("imm_data", dec_bi
.imm_out
) # imm in RB
759 comb
+= self
.do_copy("rc", dec_rc
.rc_out
)
760 comb
+= self
.do_copy("oe", dec_oe
.oe_out
)
763 comb
+= self
.do_copy("read_cr_whole", self
.dec_cr_in
.whole_reg
)
764 comb
+= self
.do_copy("write_cr_whole", self
.dec_cr_out
.whole_reg
)
765 comb
+= self
.do_copy("write_cr0", self
.dec_cr_out
.cr_bitfield
.ok
)
767 comb
+= self
.do_copy("input_cr", self
.op_get("cr_in")) # CR in
768 comb
+= self
.do_copy("output_cr", self
.op_get("cr_out")) # CR out
770 # decoded/selected instruction flags
771 comb
+= self
.do_copy("data_len", self
.op_get("ldst_len"))
772 comb
+= self
.do_copy("invert_in", self
.op_get("inv_a"))
773 comb
+= self
.do_copy("invert_out", self
.op_get("inv_out"))
774 comb
+= self
.do_copy("input_carry", self
.op_get("cry_in"))
775 comb
+= self
.do_copy("output_carry", self
.op_get("cry_out"))
776 comb
+= self
.do_copy("is_32bit", self
.op_get("is_32b"))
777 comb
+= self
.do_copy("is_signed", self
.op_get("sgn"))
778 lk
= self
.op_get("lk")
781 comb
+= self
.do_copy("lk", self
.dec
.LK
) # XXX TODO: accessor
783 comb
+= self
.do_copy("byte_reverse", self
.op_get("br"))
784 comb
+= self
.do_copy("sign_extend", self
.op_get("sgn_ext"))
785 comb
+= self
.do_copy("ldst_mode", self
.op_get("upd")) # LD/ST mode
790 class PowerDecode2(PowerDecodeSubset
):
791 """PowerDecode2: the main instruction decoder.
793 whilst PowerDecode is responsible for decoding the actual opcode, this
794 module encapsulates further specialist, sparse information and
795 expansion of fields that is inconvenient to have in the CSV files.
796 for example: the encoding of the immediates, which are detected
797 and expanded out to their full value from an annotated (enum)
800 implicit register usage is also set up, here. for example: OP_BC
801 requires implicitly reading CTR, OP_RFID requires implicitly writing
804 in addition, PowerDecoder2 is responsible for detecting whether
805 instructions are illegal (or privileged) or not, and instead of
806 just leaving at that, *replacing* the instruction to execute with
807 a suitable alternative (trap).
809 LDSTExceptions are done the cycle _after_ they're detected (after
810 they come out of LDSTCompUnit). basically despite the instruction
811 being decoded, the results of the decode are completely ignored
812 and "exception.happened" used to set the "actual" instruction to
813 "OP_TRAP". the LDSTException data structure gets filled in,
814 in the CompTrapOpSubset and that's what it fills in SRR.
816 to make this work, TestIssuer must notice "exception.happened"
817 after the (failed) LD/ST and copies the LDSTException info from
818 the output, into here (PowerDecoder2). without incrementing PC.
821 def __init__(self
, dec
, opkls
=None, fn_name
=None, final
=False, state
=None):
822 super().__init
__(dec
, opkls
, fn_name
, final
, state
)
823 self
.exc
= LDSTException("dec2_exc")
825 def get_col_subset(self
, opkls
):
826 subset
= super().get_col_subset(opkls
)
827 subset
.add("in1_sel")
828 subset
.add("asmcode")
829 subset
.add("in2_sel")
830 subset
.add("in3_sel")
831 subset
.add("out_sel")
833 subset
.add("internal_op")
837 def elaborate(self
, platform
):
838 m
= super().elaborate(platform
)
841 e_out
, op
, do_out
= self
.e
, self
.dec
.op
, self
.e
.do
842 dec_spr
, msr
, cia
, ext_irq
= state
.dec
, state
.msr
, state
.pc
, state
.eint
846 # fill in for a normal instruction (not an exception)
847 # copy over if non-exception, non-privileged etc. is detected
849 # set up submodule decoders
850 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
)
851 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
)
852 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
)
853 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
)
854 m
.submodules
.dec_o2
= dec_o2
= DecodeOut2(self
.dec
)
856 # copy instruction through...
857 for i
in [do
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
858 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
]:
859 comb
+= i
.eq(self
.dec
.opcode_in
)
861 # ...and subdecoders' input fields
862 comb
+= dec_a
.sel_in
.eq(op
.in1_sel
)
863 comb
+= dec_b
.sel_in
.eq(op
.in2_sel
)
864 comb
+= dec_c
.sel_in
.eq(op
.in3_sel
)
865 comb
+= dec_o
.sel_in
.eq(op
.out_sel
)
866 comb
+= dec_o2
.sel_in
.eq(op
.out_sel
)
867 if hasattr(do
, "lk"):
868 comb
+= dec_o2
.lk
.eq(do
.lk
)
870 # registers a, b, c and out and out2 (LD/ST EA)
871 comb
+= e
.read_reg1
.eq(dec_a
.reg_out
)
872 comb
+= e
.read_reg2
.eq(dec_b
.reg_out
)
873 comb
+= e
.read_reg3
.eq(dec_c
.reg_out
)
874 comb
+= e
.write_reg
.eq(dec_o
.reg_out
)
875 comb
+= e
.write_ea
.eq(dec_o2
.reg_out
)
878 comb
+= e
.read_spr1
.eq(dec_a
.spr_out
)
879 comb
+= e
.write_spr
.eq(dec_o
.spr_out
)
882 comb
+= e
.read_fast1
.eq(dec_a
.fast_out
)
883 comb
+= e
.read_fast2
.eq(dec_b
.fast_out
)
884 comb
+= e
.write_fast1
.eq(dec_o
.fast_out
)
885 comb
+= e
.write_fast2
.eq(dec_o2
.fast_out
)
887 # condition registers (CR)
888 comb
+= e
.read_cr1
.eq(self
.dec_cr_in
.cr_bitfield
)
889 comb
+= e
.read_cr2
.eq(self
.dec_cr_in
.cr_bitfield_b
)
890 comb
+= e
.read_cr3
.eq(self
.dec_cr_in
.cr_bitfield_o
)
891 comb
+= e
.write_cr
.eq(self
.dec_cr_out
.cr_bitfield
)
893 # sigh this is exactly the sort of thing for which the
894 # decoder is designed to not need. MTSPR, MFSPR and others need
895 # access to the XER bits. however setting e.oe is not appropriate
896 with m
.If(op
.internal_op
== MicrOp
.OP_MFSPR
):
897 comb
+= e
.xer_in
.eq(0b111) # SO, CA, OV
898 with m
.If(op
.internal_op
== MicrOp
.OP_CMP
):
899 comb
+= e
.xer_in
.eq(1<<XERRegs
.SO
) # SO
900 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
901 comb
+= e
.xer_out
.eq(1)
903 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
904 with m
.If(op
.internal_op
== MicrOp
.OP_TRAP
):
905 # *DO NOT* call self.trap here. that would reset absolutely
906 # everything including destroying read of RA and RB.
907 comb
+= self
.do_copy("trapaddr", 0x70) # strip first nibble
910 # ok so the instruction's been decoded, blah blah, however
911 # now we need to determine if it's actually going to go ahead...
912 # *or* if in fact it's a privileged operation, whether there's
913 # an external interrupt, etc. etc. this is a simple priority
914 # if-elif-elif sequence. decrement takes highest priority,
915 # EINT next highest, privileged operation third.
917 # check if instruction is privileged
918 is_priv_insn
= instr_is_priv(m
, op
.internal_op
, e
.do
.insn
)
920 # different IRQ conditions
921 ext_irq_ok
= Signal()
922 dec_irq_ok
= Signal()
927 comb
+= ext_irq_ok
.eq(ext_irq
& msr
[MSR
.EE
]) # v3.0B p944 (MSR.EE)
928 comb
+= dec_irq_ok
.eq(dec_spr
[63] & msr
[MSR
.EE
]) # 6.5.11 p1076
929 comb
+= priv_ok
.eq(is_priv_insn
& msr
[MSR
.PR
])
930 comb
+= illeg_ok
.eq(op
.internal_op
== MicrOp
.OP_ILLEGAL
)
932 # LD/ST exceptions. TestIssuer copies the exception info at us
933 # after a failed LD/ST.
934 with m
.If(exc
.happened
):
935 with m
.If(exc
.alignment
):
936 self
.trap(m
, TT
.PRIV
, 0x600)
937 with m
.Elif(exc
.instr_fault
):
938 with m
.If(exc
.segment_fault
):
939 self
.trap(m
, TT
.PRIV
, 0x480)
941 # pass exception info to trap to create SRR1
942 self
.trap(m
, TT
.MEMEXC
, 0x400, exc
)
944 with m
.If(exc
.segment_fault
):
945 self
.trap(m
, TT
.PRIV
, 0x380)
947 self
.trap(m
, TT
.PRIV
, 0x300)
949 # decrement counter (v3.0B p1099): TODO 32-bit version (MSR.LPCR)
950 with m
.Elif(dec_irq_ok
):
951 self
.trap(m
, TT
.DEC
, 0x900) # v3.0B 6.5 p1065
953 # external interrupt? only if MSR.EE set
954 with m
.Elif(ext_irq_ok
):
955 self
.trap(m
, TT
.EINT
, 0x500)
957 # privileged instruction trap
958 with m
.Elif(priv_ok
):
959 self
.trap(m
, TT
.PRIV
, 0x700)
961 # illegal instruction must redirect to trap. this is done by
962 # *overwriting* the decoded instruction and starting again.
963 # (note: the same goes for interrupts and for privileged operations,
964 # just with different trapaddr and traptype)
965 with m
.Elif(illeg_ok
):
966 # illegal instruction trap
967 self
.trap(m
, TT
.ILLEG
, 0x700)
969 # no exception, just copy things to the output
974 # follow-up after trap/irq to set up SRR0/1
976 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
977 # Note: OP_SC could actually be modified to just be a trap
978 with m
.If((do_out
.insn_type
== MicrOp
.OP_TRAP
) |
979 (do_out
.insn_type
== MicrOp
.OP_SC
)):
980 # TRAP write fast1 = SRR0
981 comb
+= e_out
.write_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
982 comb
+= e_out
.write_fast1
.ok
.eq(1)
983 # TRAP write fast2 = SRR1
984 comb
+= e_out
.write_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
985 comb
+= e_out
.write_fast2
.ok
.eq(1)
987 # RFID: needs to read SRR0/1
988 with m
.If(do_out
.insn_type
== MicrOp
.OP_RFID
):
989 # TRAP read fast1 = SRR0
990 comb
+= e_out
.read_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
991 comb
+= e_out
.read_fast1
.ok
.eq(1)
992 # TRAP read fast2 = SRR1
993 comb
+= e_out
.read_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
994 comb
+= e_out
.read_fast2
.ok
.eq(1)
996 # annoying simulator bug
997 if hasattr(e_out
, "asmcode") and hasattr(self
.dec
.op
, "asmcode"):
998 comb
+= e_out
.asmcode
.eq(self
.dec
.op
.asmcode
)
1002 def trap(self
, m
, traptype
, trapaddr
, exc
=None):
1003 """trap: this basically "rewrites" the decoded instruction as a trap
1006 op
, e
= self
.dec
.op
, self
.e
1007 comb
+= e
.eq(0) # reset eeeeeverything
1010 comb
+= self
.do_copy("insn", self
.dec
.opcode_in
, True)
1011 comb
+= self
.do_copy("insn_type", MicrOp
.OP_TRAP
, True)
1012 comb
+= self
.do_copy("fn_unit", Function
.TRAP
, True)
1013 comb
+= self
.do_copy("trapaddr", trapaddr
>> 4, True) # bottom 4 bits
1014 comb
+= self
.do_copy("traptype", traptype
, True) # request type
1015 comb
+= self
.do_copy("ldst_exc", exc
, True) # request type
1016 comb
+= self
.do_copy("msr", self
.state
.msr
, True) # copy of MSR "state"
1017 comb
+= self
.do_copy("cia", self
.state
.pc
, True) # copy of PC "state"
1020 def get_rdflags(e
, cu
):
1022 for idx
in range(cu
.n_src
):
1023 regfile
, regname
, _
= cu
.get_in_spec(idx
)
1024 rdflag
, read
= regspec_decode_read(e
, regfile
, regname
)
1026 print("rdflags", rdl
)
1030 if __name__
== '__main__':
1031 pdecode
= create_pdecode()
1032 dec2
= PowerDecode2(pdecode
)
1033 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
1034 with
open("dec2.il", "w") as f
: