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
27 from soc
.consts
import MSR
29 from soc
.regfile
.regfiles
import FastRegs
30 from soc
.consts
import TT
31 from soc
.config
.state
import CoreState
32 from soc
.regfile
.util
import spr_to_fast
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
, MicrOp
.OP_MFMSR
, MicrOp
.OP_MTMSRD
,
46 MicrOp
.OP_MTMSR
, MicrOp
.OP_RFID
):
47 comb
+= is_priv_insn
.eq(1)
49 #with m.Case(MicrOp.OP_TLBIE) : comb += is_priv_insn.eq(1)
50 with m
.Case(MicrOp
.OP_MFSPR
, MicrOp
.OP_MTSPR
):
51 with m
.If(insn
[20]): # field XFX.spr[-1] i think
52 comb
+= is_priv_insn
.eq(1)
56 class SPRMap(Elaboratable
):
57 """SPRMap: maps POWER9 SPR numbers to internal enum values, fast and slow
61 self
.spr_i
= Signal(10, reset_less
=True)
62 self
.spr_o
= Data(SPR
, name
="spr_o")
63 self
.fast_o
= Data(3, name
="fast_o")
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
.data
.eq(i
)
71 m
.d
.comb
+= self
.spr_o
.ok
.eq(1)
72 for x
, v
in spr_to_fast
.items():
74 m
.d
.comb
+= self
.fast_o
.data
.eq(v
)
75 m
.d
.comb
+= self
.fast_o
.ok
.eq(1)
79 class DecodeA(Elaboratable
):
80 """DecodeA from instruction
82 decodes register RA, implicit and explicit CSRs
85 def __init__(self
, dec
):
87 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
88 self
.insn_in
= Signal(32, reset_less
=True)
89 self
.reg_out
= Data(5, name
="reg_a")
90 self
.spr_out
= Data(SPR
, "spr_a")
91 self
.fast_out
= Data(3, "fast_a")
93 def elaborate(self
, platform
):
96 m
.submodules
.sprmap
= sprmap
= SPRMap()
98 # select Register A field
99 ra
= Signal(5, reset_less
=True)
100 comb
+= ra
.eq(self
.dec
.RA
)
101 with m
.If((self
.sel_in
== In1Sel
.RA
) |
102 ((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
103 (ra
!= Const(0, 5)))):
104 comb
+= self
.reg_out
.data
.eq(ra
)
105 comb
+= self
.reg_out
.ok
.eq(1)
107 # some Logic/ALU ops have RS as the 3rd arg, but no "RA".
108 with m
.If(self
.sel_in
== In1Sel
.RS
):
109 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
110 comb
+= self
.reg_out
.ok
.eq(1)
112 # decode Fast-SPR based on instruction type
114 with m
.Switch(op
.internal_op
):
116 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeOut
117 with m
.Case(MicrOp
.OP_BC
):
118 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
120 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
121 comb
+= self
.fast_out
.ok
.eq(1)
122 with m
.Case(MicrOp
.OP_BCREG
):
123 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
124 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
125 with m
.If(xo9
& ~xo5
):
127 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
128 comb
+= self
.fast_out
.ok
.eq(1)
130 # MFSPR move from SPRs
131 with m
.Case(MicrOp
.OP_MFSPR
):
132 spr
= Signal(10, reset_less
=True)
133 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
134 comb
+= sprmap
.spr_i
.eq(spr
)
135 comb
+= self
.spr_out
.eq(sprmap
.spr_o
)
136 comb
+= self
.fast_out
.eq(sprmap
.fast_o
)
141 class DecodeAImm(Elaboratable
):
142 """DecodeA immediate from instruction
144 decodes register RA, whether immediate-zero, implicit and
148 def __init__(self
, dec
):
150 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
151 self
.immz_out
= Signal(reset_less
=True)
153 def elaborate(self
, platform
):
157 # zero immediate requested
158 ra
= Signal(5, reset_less
=True)
159 comb
+= ra
.eq(self
.dec
.RA
)
160 with m
.If((self
.sel_in
== In1Sel
.RA_OR_ZERO
) & (ra
== Const(0, 5))):
161 comb
+= self
.immz_out
.eq(1)
166 class DecodeB(Elaboratable
):
167 """DecodeB from instruction
169 decodes register RB, different forms of immediate (signed, unsigned),
170 and implicit SPRs. register B is basically "lane 2" into the CompUnits.
171 by industry-standard convention, "lane 2" is where fully-decoded
172 immediates are muxed in.
175 def __init__(self
, dec
):
177 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
178 self
.insn_in
= Signal(32, reset_less
=True)
179 self
.reg_out
= Data(5, "reg_b")
180 self
.fast_out
= Data(3, "fast_b")
182 def elaborate(self
, platform
):
186 # select Register B field
187 with m
.Switch(self
.sel_in
):
188 with m
.Case(In2Sel
.RB
):
189 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
)
190 comb
+= self
.reg_out
.ok
.eq(1)
191 with m
.Case(In2Sel
.RS
):
192 # for M-Form shiftrot
193 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
194 comb
+= self
.reg_out
.ok
.eq(1)
196 # decode SPR2 based on instruction type
198 # BCREG implicitly uses LR or TAR for 2nd reg
199 # CTR however is already in fast_spr1 *not* 2.
200 with m
.If(op
.internal_op
== MicrOp
.OP_BCREG
):
201 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
202 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
204 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
205 comb
+= self
.fast_out
.ok
.eq(1)
207 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
208 comb
+= self
.fast_out
.ok
.eq(1)
213 class DecodeBImm(Elaboratable
):
214 """DecodeB immediate from instruction
216 def __init__(self
, dec
):
218 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
219 self
.imm_out
= Data(64, "imm_b")
221 def elaborate(self
, platform
):
225 # select Register B Immediate
226 with m
.Switch(self
.sel_in
):
227 with m
.Case(In2Sel
.CONST_UI
): # unsigned
228 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
)
229 comb
+= self
.imm_out
.ok
.eq(1)
230 with m
.Case(In2Sel
.CONST_SI
): # sign-extended 16-bit
231 si
= Signal(16, reset_less
=True)
232 comb
+= si
.eq(self
.dec
.SI
)
233 comb
+= self
.imm_out
.data
.eq(exts(si
, 16, 64))
234 comb
+= self
.imm_out
.ok
.eq(1)
235 with m
.Case(In2Sel
.CONST_SI_HI
): # sign-extended 16+16=32 bit
236 si_hi
= Signal(32, reset_less
=True)
237 comb
+= si_hi
.eq(self
.dec
.SI
<< 16)
238 comb
+= self
.imm_out
.data
.eq(exts(si_hi
, 32, 64))
239 comb
+= self
.imm_out
.ok
.eq(1)
240 with m
.Case(In2Sel
.CONST_UI_HI
): # unsigned
241 ui
= Signal(16, reset_less
=True)
242 comb
+= ui
.eq(self
.dec
.UI
)
243 comb
+= self
.imm_out
.data
.eq(ui
<< 16)
244 comb
+= self
.imm_out
.ok
.eq(1)
245 with m
.Case(In2Sel
.CONST_LI
): # sign-extend 24+2=26 bit
246 li
= Signal(26, reset_less
=True)
247 comb
+= li
.eq(self
.dec
.LI
<< 2)
248 comb
+= self
.imm_out
.data
.eq(exts(li
, 26, 64))
249 comb
+= self
.imm_out
.ok
.eq(1)
250 with m
.Case(In2Sel
.CONST_BD
): # sign-extend (14+2)=16 bit
251 bd
= Signal(16, reset_less
=True)
252 comb
+= bd
.eq(self
.dec
.BD
<< 2)
253 comb
+= self
.imm_out
.data
.eq(exts(bd
, 16, 64))
254 comb
+= self
.imm_out
.ok
.eq(1)
255 with m
.Case(In2Sel
.CONST_DS
): # sign-extended (14+2=16) bit
256 ds
= Signal(16, reset_less
=True)
257 comb
+= ds
.eq(self
.dec
.DS
<< 2)
258 comb
+= self
.imm_out
.data
.eq(exts(ds
, 16, 64))
259 comb
+= self
.imm_out
.ok
.eq(1)
260 with m
.Case(In2Sel
.CONST_M1
): # signed (-1)
261 comb
+= self
.imm_out
.data
.eq(~
Const(0, 64)) # all 1s
262 comb
+= self
.imm_out
.ok
.eq(1)
263 with m
.Case(In2Sel
.CONST_SH
): # unsigned - for shift
264 comb
+= self
.imm_out
.data
.eq(self
.dec
.sh
)
265 comb
+= self
.imm_out
.ok
.eq(1)
266 with m
.Case(In2Sel
.CONST_SH32
): # unsigned - for shift
267 comb
+= self
.imm_out
.data
.eq(self
.dec
.SH32
)
268 comb
+= self
.imm_out
.ok
.eq(1)
273 class DecodeC(Elaboratable
):
274 """DecodeC from instruction
276 decodes register RC. this is "lane 3" into some CompUnits (not many)
279 def __init__(self
, dec
):
281 self
.sel_in
= Signal(In3Sel
, reset_less
=True)
282 self
.insn_in
= Signal(32, reset_less
=True)
283 self
.reg_out
= Data(5, "reg_c")
285 def elaborate(self
, platform
):
289 # select Register C field
290 with m
.Switch(self
.sel_in
):
291 with m
.Case(In3Sel
.RB
):
292 # for M-Form shiftrot
293 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
)
294 comb
+= self
.reg_out
.ok
.eq(1)
295 with m
.Case(In3Sel
.RS
):
296 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
297 comb
+= self
.reg_out
.ok
.eq(1)
302 class DecodeOut(Elaboratable
):
303 """DecodeOut from instruction
305 decodes output register RA, RT or SPR
308 def __init__(self
, dec
):
310 self
.sel_in
= Signal(OutSel
, reset_less
=True)
311 self
.insn_in
= Signal(32, reset_less
=True)
312 self
.reg_out
= Data(5, "reg_o")
313 self
.spr_out
= Data(SPR
, "spr_o")
314 self
.fast_out
= Data(3, "fast_o")
316 def elaborate(self
, platform
):
319 m
.submodules
.sprmap
= sprmap
= SPRMap()
322 # select Register out field
323 with m
.Switch(self
.sel_in
):
324 with m
.Case(OutSel
.RT
):
325 comb
+= self
.reg_out
.data
.eq(self
.dec
.RT
)
326 comb
+= self
.reg_out
.ok
.eq(1)
327 with m
.Case(OutSel
.RA
):
328 comb
+= self
.reg_out
.data
.eq(self
.dec
.RA
)
329 comb
+= self
.reg_out
.ok
.eq(1)
330 with m
.Case(OutSel
.SPR
):
331 spr
= Signal(10, reset_less
=True)
332 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
333 # MFSPR move to SPRs - needs mapping
334 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
335 comb
+= sprmap
.spr_i
.eq(spr
)
336 comb
+= self
.spr_out
.eq(sprmap
.spr_o
)
337 comb
+= self
.fast_out
.eq(sprmap
.fast_o
)
339 with m
.Switch(op
.internal_op
):
341 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeA
342 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_BCREG
):
343 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
345 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
346 comb
+= self
.fast_out
.ok
.eq(1)
348 # RFID 1st spr (fast)
349 with m
.Case(MicrOp
.OP_RFID
):
350 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
351 comb
+= self
.fast_out
.ok
.eq(1)
356 class DecodeOut2(Elaboratable
):
357 """DecodeOut2 from instruction
359 decodes output registers
362 def __init__(self
, dec
):
364 self
.sel_in
= Signal(OutSel
, reset_less
=True)
365 self
.lk
= Signal(reset_less
=True)
366 self
.insn_in
= Signal(32, reset_less
=True)
367 self
.reg_out
= Data(5, "reg_o")
368 self
.fast_out
= Data(3, "fast_o")
370 def elaborate(self
, platform
):
374 if hasattr(self
.dec
.op
, "upd"):
375 # update mode LD/ST uses read-reg A also as an output
376 with m
.If(self
.dec
.op
.upd
== LDSTMode
.update
):
377 comb
+= self
.reg_out
.eq(self
.dec
.RA
)
378 comb
+= self
.reg_out
.ok
.eq(1)
380 # B, BC or BCREG: potential implicit register (LR) output
381 # these give bl, bcl, bclrl, etc.
383 with m
.Switch(op
.internal_op
):
385 # BC* implicit register (LR)
386 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_B
, MicrOp
.OP_BCREG
):
387 with m
.If(self
.lk
): # "link" mode
388 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
) # constant: LR
389 comb
+= self
.fast_out
.ok
.eq(1)
391 # RFID 2nd spr (fast)
392 with m
.Case(MicrOp
.OP_RFID
):
393 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
394 comb
+= self
.fast_out
.ok
.eq(1)
399 class DecodeRC(Elaboratable
):
400 """DecodeRc from instruction
402 decodes Record bit Rc
405 def __init__(self
, dec
):
407 self
.sel_in
= Signal(RC
, reset_less
=True)
408 self
.insn_in
= Signal(32, reset_less
=True)
409 self
.rc_out
= Data(1, "rc")
411 def elaborate(self
, platform
):
415 # select Record bit out field
416 with m
.Switch(self
.sel_in
):
418 comb
+= self
.rc_out
.data
.eq(self
.dec
.Rc
)
419 comb
+= self
.rc_out
.ok
.eq(1)
421 comb
+= self
.rc_out
.data
.eq(1)
422 comb
+= self
.rc_out
.ok
.eq(1)
423 with m
.Case(RC
.NONE
):
424 comb
+= self
.rc_out
.data
.eq(0)
425 comb
+= self
.rc_out
.ok
.eq(1)
430 class DecodeOE(Elaboratable
):
431 """DecodeOE from instruction
433 decodes OE field: uses RC decode detection which might not be good
435 -- For now, use "rc" in the decode table to decide whether oe exists.
436 -- This is not entirely correct architecturally: For mulhd and
437 -- mulhdu, the OE field is reserved. It remains to be seen what an
438 -- actual POWER9 does if we set it on those instructions, for now we
439 -- test that further down when assigning to the multiplier oe input.
442 def __init__(self
, dec
):
444 self
.sel_in
= Signal(RC
, reset_less
=True)
445 self
.insn_in
= Signal(32, reset_less
=True)
446 self
.oe_out
= Data(1, "oe")
448 def elaborate(self
, platform
):
453 with m
.Switch(op
.internal_op
):
455 # mulhw, mulhwu, mulhd, mulhdu - these *ignore* OE
457 # XXX ARGH! ignoring OE causes incompatibility with microwatt
458 # http://lists.libre-soc.org/pipermail/libre-soc-dev/2020-August/000302.html
459 with m
.Case(MicrOp
.OP_MUL_H64
, MicrOp
.OP_MUL_H32
,
460 MicrOp
.OP_EXTS
, MicrOp
.OP_CNTZ
,
461 MicrOp
.OP_SHL
, MicrOp
.OP_SHR
, MicrOp
.OP_RLC
,
462 MicrOp
.OP_LOAD
, MicrOp
.OP_STORE
,
463 MicrOp
.OP_RLCL
, MicrOp
.OP_RLCR
,
467 # all other ops decode OE field
469 # select OE bit out field
470 with m
.Switch(self
.sel_in
):
472 comb
+= self
.oe_out
.data
.eq(self
.dec
.OE
)
473 comb
+= self
.oe_out
.ok
.eq(1)
478 class DecodeCRIn(Elaboratable
):
479 """Decodes input CR from instruction
481 CR indices - insn fields - (not the data *in* the CR) require only 3
482 bits because they refer to CR0-CR7
485 def __init__(self
, dec
):
487 self
.sel_in
= Signal(CRInSel
, reset_less
=True)
488 self
.insn_in
= Signal(32, reset_less
=True)
489 self
.cr_bitfield
= Data(3, "cr_bitfield")
490 self
.cr_bitfield_b
= Data(3, "cr_bitfield_b")
491 self
.cr_bitfield_o
= Data(3, "cr_bitfield_o")
492 self
.whole_reg
= Data(8, "cr_fxm")
494 def elaborate(self
, platform
):
496 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
502 comb
+= self
.cr_bitfield
.ok
.eq(0)
503 comb
+= self
.cr_bitfield_b
.ok
.eq(0)
504 comb
+= self
.whole_reg
.ok
.eq(0)
505 with m
.Switch(self
.sel_in
):
506 with m
.Case(CRInSel
.NONE
):
507 pass # No bitfield activated
508 with m
.Case(CRInSel
.CR0
):
509 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
510 comb
+= self
.cr_bitfield
.ok
.eq(1)
511 with m
.Case(CRInSel
.BI
):
512 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BI
[2:5])
513 comb
+= self
.cr_bitfield
.ok
.eq(1)
514 with m
.Case(CRInSel
.BFA
):
515 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BFA
)
516 comb
+= self
.cr_bitfield
.ok
.eq(1)
517 with m
.Case(CRInSel
.BA_BB
):
518 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BA
[2:5])
519 comb
+= self
.cr_bitfield
.ok
.eq(1)
520 comb
+= self
.cr_bitfield_b
.data
.eq(self
.dec
.BB
[2:5])
521 comb
+= self
.cr_bitfield_b
.ok
.eq(1)
522 comb
+= self
.cr_bitfield_o
.data
.eq(self
.dec
.BT
[2:5])
523 comb
+= self
.cr_bitfield_o
.ok
.eq(1)
524 with m
.Case(CRInSel
.BC
):
525 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BC
[2:5])
526 comb
+= self
.cr_bitfield
.ok
.eq(1)
527 with m
.Case(CRInSel
.WHOLE_REG
):
528 comb
+= self
.whole_reg
.ok
.eq(1)
529 move_one
= Signal(reset_less
=True)
530 comb
+= move_one
.eq(self
.insn_in
[20]) # MSB0 bit 11
531 with m
.If((op
.internal_op
== MicrOp
.OP_MFCR
) & move_one
):
532 # must one-hot the FXM field
533 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
534 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
536 # otherwise use all of it
537 comb
+= self
.whole_reg
.data
.eq(0xff)
542 class DecodeCROut(Elaboratable
):
543 """Decodes input CR from instruction
545 CR indices - insn fields - (not the data *in* the CR) require only 3
546 bits because they refer to CR0-CR7
549 def __init__(self
, dec
):
551 self
.rc_in
= Signal(reset_less
=True)
552 self
.sel_in
= Signal(CROutSel
, reset_less
=True)
553 self
.insn_in
= Signal(32, reset_less
=True)
554 self
.cr_bitfield
= Data(3, "cr_bitfield")
555 self
.whole_reg
= Data(8, "cr_fxm")
557 def elaborate(self
, platform
):
561 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
564 comb
+= self
.cr_bitfield
.ok
.eq(0)
565 comb
+= self
.whole_reg
.ok
.eq(0)
566 with m
.Switch(self
.sel_in
):
567 with m
.Case(CROutSel
.NONE
):
568 pass # No bitfield activated
569 with m
.Case(CROutSel
.CR0
):
570 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
571 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
572 with m
.Case(CROutSel
.BF
):
573 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BF
)
574 comb
+= self
.cr_bitfield
.ok
.eq(1)
575 with m
.Case(CROutSel
.BT
):
576 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormXL
.BT
[2:5])
577 comb
+= self
.cr_bitfield
.ok
.eq(1)
578 with m
.Case(CROutSel
.WHOLE_REG
):
579 comb
+= self
.whole_reg
.ok
.eq(1)
580 move_one
= Signal(reset_less
=True)
581 comb
+= move_one
.eq(self
.insn_in
[20])
582 with m
.If((op
.internal_op
== MicrOp
.OP_MTCRF
)):
584 # must one-hot the FXM field
585 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
586 with m
.If(ppick
.en_o
):
587 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
589 comb
+= self
.whole_reg
.data
.eq(0b00000001) # CR7
591 comb
+= self
.whole_reg
.data
.eq(self
.dec
.FXM
)
593 # otherwise use all of it
594 comb
+= self
.whole_reg
.data
.eq(0xff)
598 # dictionary of Input Record field names that, if they exist,
599 # will need a corresponding CSV Decoder file column (actually, PowerOp)
600 # to be decoded (this includes the single bit names)
601 record_names
= {'insn_type': 'internal_op',
602 'fn_unit': 'function_unit',
606 'imm_data': 'in2_sel',
607 'invert_in': 'inv_a',
608 'invert_out': 'inv_out',
611 'output_carry': 'cry_out',
612 'input_carry': 'cry_in',
613 'is_32bit': 'is_32b',
616 'data_len': 'ldst_len',
617 'byte_reverse': 'br',
618 'sign_extend': 'sgn_ext',
623 class PowerDecodeSubset(Elaboratable
):
624 """PowerDecodeSubset: dynamic subset decoder
626 def __init__(self
, dec
, opkls
=None, fn_name
=None, final
=False, state
=None):
630 self
.fn_name
= fn_name
631 self
.e
= Decode2ToExecute1Type(name
=self
.fn_name
, opkls
=self
.opkls
)
632 col_subset
= self
.get_col_subset(self
.e
.do
)
634 # create decoder if one not already given
636 dec
= create_pdecode(name
=fn_name
, col_subset
=col_subset
,
637 row_subset
=self
.rowsubsetfn
)
640 # state information needed by the Decoder
642 state
= CoreState("dec2")
645 def get_col_subset(self
, do
):
646 subset
= {'cr_in', 'cr_out', 'rc_sel'} # needed, non-optional
647 for k
, v
in record_names
.items():
650 print ("get_col_subset", self
.fn_name
, do
.fields
, subset
)
653 def rowsubsetfn(self
, opcode
, row
):
654 return row
['unit'] == self
.fn_name
657 return self
.dec
.ports() + self
.e
.ports()
659 def needs_field(self
, field
, op_field
):
664 return hasattr(do
, field
) and self
.op_get(op_field
) is not None
666 def do_copy(self
, field
, val
, final
=False):
667 if final
or self
.final
:
671 if hasattr(do
, field
) and val
is not None:
672 return getattr(do
, field
).eq(val
)
675 def op_get(self
, op_field
):
676 return getattr(self
.dec
.op
, op_field
, None)
678 def elaborate(self
, platform
):
682 e_out
, op
, do_out
= self
.e
, self
.dec
.op
, self
.e
.do
683 msr
, cia
= state
.msr
, state
.pc
685 # fill in for a normal instruction (not an exception)
686 # copy over if non-exception, non-privileged etc. is detected
690 if self
.fn_name
is None:
693 name
= self
.fn_name
+ "tmp"
694 self
.e_tmp
= e
= Decode2ToExecute1Type(name
=name
, opkls
=self
.opkls
)
697 # set up submodule decoders
698 m
.submodules
.dec
= self
.dec
699 m
.submodules
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
700 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
)
701 m
.submodules
.dec_cr_in
= self
.dec_cr_in
= DecodeCRIn(self
.dec
)
702 m
.submodules
.dec_cr_out
= self
.dec_cr_out
= DecodeCROut(self
.dec
)
704 # copy instruction through...
706 dec_rc
.insn_in
, dec_oe
.insn_in
,
707 self
.dec_cr_in
.insn_in
, self
.dec_cr_out
.insn_in
]:
708 comb
+= i
.eq(self
.dec
.opcode_in
)
710 # ...and subdecoders' input fields
711 comb
+= dec_rc
.sel_in
.eq(op
.rc_sel
)
712 comb
+= dec_oe
.sel_in
.eq(op
.rc_sel
) # XXX should be OE sel
713 comb
+= self
.dec_cr_in
.sel_in
.eq(op
.cr_in
)
714 comb
+= self
.dec_cr_out
.sel_in
.eq(op
.cr_out
)
715 comb
+= self
.dec_cr_out
.rc_in
.eq(dec_rc
.rc_out
.data
)
718 comb
+= self
.do_copy("msr", msr
)
719 comb
+= self
.do_copy("cia", cia
)
721 # set up instruction, pick fn unit
722 # no op: defaults to OP_ILLEGAL
723 comb
+= self
.do_copy("insn_type", self
.op_get("internal_op"))
724 comb
+= self
.do_copy("fn_unit", self
.op_get("function_unit"))
727 if self
.needs_field("zero_a", "in1_sel"):
728 m
.submodules
.dec_ai
= dec_ai
= DecodeAImm(self
.dec
)
729 comb
+= dec_ai
.sel_in
.eq(op
.in1_sel
)
730 comb
+= self
.do_copy("zero_a", dec_ai
.immz_out
) # RA==0 detected
731 if self
.needs_field("imm_data", "in2_sel"):
732 m
.submodules
.dec_bi
= dec_bi
= DecodeBImm(self
.dec
)
733 comb
+= dec_bi
.sel_in
.eq(op
.in2_sel
)
734 comb
+= self
.do_copy("imm_data", dec_bi
.imm_out
) # imm in RB
737 comb
+= self
.do_copy("rc", dec_rc
.rc_out
)
738 comb
+= self
.do_copy("oe", dec_oe
.oe_out
)
741 comb
+= self
.do_copy("read_cr_whole", self
.dec_cr_in
.whole_reg
)
742 comb
+= self
.do_copy("write_cr_whole", self
.dec_cr_out
.whole_reg
)
743 comb
+= self
.do_copy("write_cr0", self
.dec_cr_out
.cr_bitfield
.ok
)
745 comb
+= self
.do_copy("input_cr", self
.op_get("cr_in")) # CR in
746 comb
+= self
.do_copy("output_cr", self
.op_get("cr_out")) # CR out
748 # decoded/selected instruction flags
749 comb
+= self
.do_copy("data_len", self
.op_get("ldst_len"))
750 comb
+= self
.do_copy("invert_in", self
.op_get("inv_a"))
751 comb
+= self
.do_copy("invert_out", self
.op_get("inv_out"))
752 comb
+= self
.do_copy("input_carry", self
.op_get("cry_in"))
753 comb
+= self
.do_copy("output_carry", self
.op_get("cry_out"))
754 comb
+= self
.do_copy("is_32bit", self
.op_get("is_32b"))
755 comb
+= self
.do_copy("is_signed", self
.op_get("sgn"))
756 lk
= self
.op_get("lk")
759 comb
+= self
.do_copy("lk", self
.dec
.LK
) # XXX TODO: accessor
761 comb
+= self
.do_copy("byte_reverse", self
.op_get("br"))
762 comb
+= self
.do_copy("sign_extend", self
.op_get("sgn_ext"))
763 comb
+= self
.do_copy("ldst_mode", self
.op_get("upd")) # LD/ST mode
768 class PowerDecode2(PowerDecodeSubset
):
769 """PowerDecode2: the main instruction decoder.
771 whilst PowerDecode is responsible for decoding the actual opcode, this
772 module encapsulates further specialist, sparse information and
773 expansion of fields that is inconvenient to have in the CSV files.
774 for example: the encoding of the immediates, which are detected
775 and expanded out to their full value from an annotated (enum)
778 implicit register usage is also set up, here. for example: OP_BC
779 requires implicitly reading CTR, OP_RFID requires implicitly writing
782 in addition, PowerDecoder2 is responsible for detecting whether
783 instructions are illegal (or privileged) or not, and instead of
784 just leaving at that, *replacing* the instruction to execute with
785 a suitable alternative (trap).
787 LDSTExceptions are done the cycle _after_ they're detected (after
788 they come out of LDSTCompUnit). basically despite the instruction
789 being decoded, the results of the decode are completely ignored
790 and "exception.happened" used to set the "actual" instruction to
791 "OP_TRAP". the LDSTException data structure gets filled in,
792 in the CompTrapOpSubset and that's what it fills in SRR.
794 to make this work, TestIssuer must notice "exception.happened"
795 after the (failed) LD/ST and copies the LDSTException info from
796 the output, into here (PowerDecoder2). without incrementing PC.
799 def __init__(self
, dec
, opkls
=None, fn_name
=None, final
=False, state
=None):
800 super().__init
__(dec
, opkls
, fn_name
, final
, state
)
801 self
.exc
= LDSTException("dec2_exc")
803 def get_col_subset(self
, opkls
):
804 subset
= super().get_col_subset(opkls
)
805 subset
.add("in1_sel")
806 subset
.add("asmcode")
807 subset
.add("in2_sel")
808 subset
.add("in3_sel")
809 subset
.add("out_sel")
811 subset
.add("internal_op")
815 def elaborate(self
, platform
):
816 m
= super().elaborate(platform
)
819 e_out
, op
, do_out
= self
.e
, self
.dec
.op
, self
.e
.do
820 dec_spr
, msr
, cia
, ext_irq
= state
.dec
, state
.msr
, state
.pc
, state
.eint
824 # fill in for a normal instruction (not an exception)
825 # copy over if non-exception, non-privileged etc. is detected
827 # set up submodule decoders
828 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
)
829 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
)
830 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
)
831 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
)
832 m
.submodules
.dec_o2
= dec_o2
= DecodeOut2(self
.dec
)
834 # copy instruction through...
835 for i
in [do
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
836 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
]:
837 comb
+= i
.eq(self
.dec
.opcode_in
)
839 # ...and subdecoders' input fields
840 comb
+= dec_a
.sel_in
.eq(op
.in1_sel
)
841 comb
+= dec_b
.sel_in
.eq(op
.in2_sel
)
842 comb
+= dec_c
.sel_in
.eq(op
.in3_sel
)
843 comb
+= dec_o
.sel_in
.eq(op
.out_sel
)
844 comb
+= dec_o2
.sel_in
.eq(op
.out_sel
)
845 if hasattr(do
, "lk"):
846 comb
+= dec_o2
.lk
.eq(do
.lk
)
848 # registers a, b, c and out and out2 (LD/ST EA)
849 comb
+= e
.read_reg1
.eq(dec_a
.reg_out
)
850 comb
+= e
.read_reg2
.eq(dec_b
.reg_out
)
851 comb
+= e
.read_reg3
.eq(dec_c
.reg_out
)
852 comb
+= e
.write_reg
.eq(dec_o
.reg_out
)
853 comb
+= e
.write_ea
.eq(dec_o2
.reg_out
)
856 comb
+= e
.read_spr1
.eq(dec_a
.spr_out
)
857 comb
+= e
.write_spr
.eq(dec_o
.spr_out
)
860 comb
+= e
.read_fast1
.eq(dec_a
.fast_out
)
861 comb
+= e
.read_fast2
.eq(dec_b
.fast_out
)
862 comb
+= e
.write_fast1
.eq(dec_o
.fast_out
)
863 comb
+= e
.write_fast2
.eq(dec_o2
.fast_out
)
865 # condition registers (CR)
866 comb
+= e
.read_cr1
.eq(self
.dec_cr_in
.cr_bitfield
)
867 comb
+= e
.read_cr2
.eq(self
.dec_cr_in
.cr_bitfield_b
)
868 comb
+= e
.read_cr3
.eq(self
.dec_cr_in
.cr_bitfield_o
)
869 comb
+= e
.write_cr
.eq(self
.dec_cr_out
.cr_bitfield
)
871 # sigh this is exactly the sort of thing for which the
872 # decoder is designed to not need. MTSPR, MFSPR and others need
873 # access to the XER bits. however setting e.oe is not appropriate
874 with m
.If(op
.internal_op
== MicrOp
.OP_MFSPR
):
875 comb
+= e
.xer_in
.eq(0b111) # SO, CA, OV
876 with m
.If(op
.internal_op
== MicrOp
.OP_CMP
):
877 comb
+= e
.xer_in
.eq(1<<XERRegs
.SO
) # SO
878 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
879 comb
+= e
.xer_out
.eq(1)
881 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
882 with m
.If(op
.internal_op
== MicrOp
.OP_TRAP
):
883 # *DO NOT* call self.trap here. that would reset absolutely
884 # everything including destroying read of RA and RB.
885 comb
+= self
.do_copy("trapaddr", 0x70) # strip first nibble
888 # ok so the instruction's been decoded, blah blah, however
889 # now we need to determine if it's actually going to go ahead...
890 # *or* if in fact it's a privileged operation, whether there's
891 # an external interrupt, etc. etc. this is a simple priority
892 # if-elif-elif sequence. decrement takes highest priority,
893 # EINT next highest, privileged operation third.
895 # check if instruction is privileged
896 is_priv_insn
= instr_is_priv(m
, op
.internal_op
, e
.do
.insn
)
898 # different IRQ conditions
899 ext_irq_ok
= Signal()
900 dec_irq_ok
= Signal()
905 comb
+= ext_irq_ok
.eq(ext_irq
& msr
[MSR
.EE
]) # v3.0B p944 (MSR.EE)
906 comb
+= dec_irq_ok
.eq(dec_spr
[63] & msr
[MSR
.EE
]) # 6.5.11 p1076
907 comb
+= priv_ok
.eq(is_priv_insn
& msr
[MSR
.PR
])
908 comb
+= illeg_ok
.eq(op
.internal_op
== MicrOp
.OP_ILLEGAL
)
910 # LD/ST exceptions. TestIssuer copies the exception info at us
911 # after a failed LD/ST.
912 with m
.If(exc
.happened
):
913 with m
.If(exc
.alignment
):
914 self
.trap(m
, TT
.PRIV
, 0x600)
915 with m
.Elif(exc
.instr_fault
):
916 with m
.If(exc
.segment_fault
):
917 self
.trap(m
, TT
.PRIV
, 0x480)
919 #spass exception info to trap to create SRR1
920 self
.trap(m
, TT
.MEMEXC
, 0x400, exc
)
922 with m
.If(exc
.segment_fault
):
923 self
.trap(m
, TT
.PRIV
, 0x380)
925 self
.trap(m
, TT
.PRIV
, 0x300)
927 # decrement counter (v3.0B p1099): TODO 32-bit version (MSR.LPCR)
928 with m
.Elif(dec_irq_ok
):
929 self
.trap(m
, TT
.DEC
, 0x900) # v3.0B 6.5 p1065
931 # external interrupt? only if MSR.EE set
932 with m
.Elif(ext_irq_ok
):
933 self
.trap(m
, TT
.EINT
, 0x500)
935 # privileged instruction trap
936 with m
.Elif(priv_ok
):
937 self
.trap(m
, TT
.PRIV
, 0x700)
939 # illegal instruction must redirect to trap. this is done by
940 # *overwriting* the decoded instruction and starting again.
941 # (note: the same goes for interrupts and for privileged operations,
942 # just with different trapaddr and traptype)
943 with m
.Elif(illeg_ok
):
944 # illegal instruction trap
945 self
.trap(m
, TT
.ILLEG
, 0x700)
947 # no exception, just copy things to the output
952 # follow-up after trap/irq to set up SRR0/1
954 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
955 # Note: OP_SC could actually be modified to just be a trap
956 with m
.If((do_out
.insn_type
== MicrOp
.OP_TRAP
) |
957 (do_out
.insn_type
== MicrOp
.OP_SC
)):
958 # TRAP write fast1 = SRR0
959 comb
+= e_out
.write_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
960 comb
+= e_out
.write_fast1
.ok
.eq(1)
961 # TRAP write fast2 = SRR1
962 comb
+= e_out
.write_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
963 comb
+= e_out
.write_fast2
.ok
.eq(1)
965 # RFID: needs to read SRR0/1
966 with m
.If(do_out
.insn_type
== MicrOp
.OP_RFID
):
967 # TRAP read fast1 = SRR0
968 comb
+= e_out
.read_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
969 comb
+= e_out
.read_fast1
.ok
.eq(1)
970 # TRAP read fast2 = SRR1
971 comb
+= e_out
.read_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
972 comb
+= e_out
.read_fast2
.ok
.eq(1)
974 # annoying simulator bug
975 if hasattr(e_out
, "asmcode") and hasattr(self
.dec
.op
, "asmcode"):
976 comb
+= e_out
.asmcode
.eq(self
.dec
.op
.asmcode
)
980 def trap(self
, m
, traptype
, trapaddr
, exc
=None):
981 """trap: this basically "rewrites" the decoded instruction as a trap
984 op
, e
= self
.dec
.op
, self
.e
985 comb
+= e
.eq(0) # reset eeeeeverything
988 comb
+= self
.do_copy("insn", self
.dec
.opcode_in
, True)
989 comb
+= self
.do_copy("insn_type", MicrOp
.OP_TRAP
, True)
990 comb
+= self
.do_copy("fn_unit", Function
.TRAP
, True)
991 comb
+= self
.do_copy("trapaddr", trapaddr
>> 4, True) # bottom 4 bits
992 comb
+= self
.do_copy("traptype", traptype
, True) # request type
993 comb
+= self
.do_copy("ldst_exc", exc
, True) # request type
994 comb
+= self
.do_copy("msr", self
.state
.msr
, True) # copy of MSR "state"
995 comb
+= self
.do_copy("cia", self
.state
.pc
, True) # copy of PC "state"
998 def get_rdflags(e
, cu
):
1000 for idx
in range(cu
.n_src
):
1001 regfile
, regname
, _
= cu
.get_in_spec(idx
)
1002 rdflag
, read
= regspec_decode_read(e
, regfile
, regname
)
1004 print("rdflags", rdl
)
1008 if __name__
== '__main__':
1009 pdecode
= create_pdecode()
1010 dec2
= PowerDecode2(pdecode
)
1011 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
1012 with
open("dec2.il", "w") as f
: