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
.sv
.svp64
import SVP64Rec
29 from soc
.consts
import MSR
31 from soc
.regfile
.regfiles
import FastRegs
32 from soc
.consts
import TT
33 from soc
.config
.state
import CoreState
34 from soc
.regfile
.util
import spr_to_fast
37 def decode_spr_num(spr
):
38 return Cat(spr
[5:10], spr
[0:5])
41 def instr_is_priv(m
, op
, insn
):
42 """determines if the instruction is privileged or not
45 is_priv_insn
= Signal(reset_less
=True)
47 with m
.Case(MicrOp
.OP_ATTN
, MicrOp
.OP_MFMSR
, MicrOp
.OP_MTMSRD
,
48 MicrOp
.OP_MTMSR
, MicrOp
.OP_RFID
):
49 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, fast and slow
63 self
.spr_i
= Signal(10, reset_less
=True)
64 self
.spr_o
= Data(SPR
, name
="spr_o")
65 self
.fast_o
= Data(3, name
="fast_o")
67 def elaborate(self
, platform
):
69 with m
.Switch(self
.spr_i
):
70 for i
, x
in enumerate(SPR
):
72 m
.d
.comb
+= self
.spr_o
.data
.eq(i
)
73 m
.d
.comb
+= self
.spr_o
.ok
.eq(1)
74 for x
, v
in spr_to_fast
.items():
76 m
.d
.comb
+= self
.fast_o
.data
.eq(v
)
77 m
.d
.comb
+= self
.fast_o
.ok
.eq(1)
81 class DecodeA(Elaboratable
):
82 """DecodeA from instruction
84 decodes register RA, implicit and explicit CSRs
87 def __init__(self
, dec
):
89 self
.sv_rm
= SVP64Rec() # SVP64 RM field
90 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
91 self
.insn_in
= Signal(32, reset_less
=True)
92 self
.reg_out
= Data(7, name
="reg_a")
93 self
.spr_out
= Data(SPR
, "spr_a")
94 self
.fast_out
= Data(3, "fast_a")
96 def elaborate(self
, platform
):
99 m
.submodules
.sprmap
= sprmap
= SPRMap()
101 # select Register A field
102 ra
= Signal(5, reset_less
=True)
103 comb
+= ra
.eq(self
.dec
.RA
)
104 with m
.If((self
.sel_in
== In1Sel
.RA
) |
105 ((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
106 (ra
!= Const(0, 5)))):
107 comb
+= self
.reg_out
.data
.eq(ra
)
108 comb
+= self
.reg_out
.ok
.eq(1)
110 # some Logic/ALU ops have RS as the 3rd arg, but no "RA".
111 with m
.If(self
.sel_in
== In1Sel
.RS
):
112 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
113 comb
+= self
.reg_out
.ok
.eq(1)
115 # decode Fast-SPR based on instruction type
117 with m
.Switch(op
.internal_op
):
119 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeOut
120 with m
.Case(MicrOp
.OP_BC
):
121 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
123 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
124 comb
+= self
.fast_out
.ok
.eq(1)
125 with m
.Case(MicrOp
.OP_BCREG
):
126 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
127 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
128 with m
.If(xo9
& ~xo5
):
130 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
131 comb
+= self
.fast_out
.ok
.eq(1)
133 # MFSPR move from SPRs
134 with m
.Case(MicrOp
.OP_MFSPR
):
135 spr
= Signal(10, reset_less
=True)
136 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
137 comb
+= sprmap
.spr_i
.eq(spr
)
138 comb
+= self
.spr_out
.eq(sprmap
.spr_o
)
139 comb
+= self
.fast_out
.eq(sprmap
.fast_o
)
144 class DecodeAImm(Elaboratable
):
145 """DecodeA immediate from instruction
147 decodes register RA, whether immediate-zero, implicit and
151 def __init__(self
, dec
):
153 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
154 self
.immz_out
= Signal(reset_less
=True)
156 def elaborate(self
, platform
):
160 # zero immediate requested
161 ra
= Signal(5, reset_less
=True)
162 comb
+= ra
.eq(self
.dec
.RA
)
163 with m
.If((self
.sel_in
== In1Sel
.RA_OR_ZERO
) & (ra
== Const(0, 5))):
164 comb
+= self
.immz_out
.eq(1)
169 class DecodeB(Elaboratable
):
170 """DecodeB from instruction
172 decodes register RB, different forms of immediate (signed, unsigned),
173 and implicit SPRs. register B is basically "lane 2" into the CompUnits.
174 by industry-standard convention, "lane 2" is where fully-decoded
175 immediates are muxed in.
178 def __init__(self
, dec
):
180 self
.sv_rm
= SVP64Rec() # SVP64 RM field
181 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
182 self
.insn_in
= Signal(32, reset_less
=True)
183 self
.reg_out
= Data(5, "reg_b")
184 self
.fast_out
= Data(3, "fast_b")
186 def elaborate(self
, platform
):
190 # select Register B field
191 with m
.Switch(self
.sel_in
):
192 with m
.Case(In2Sel
.RB
):
193 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
)
194 comb
+= self
.reg_out
.ok
.eq(1)
195 with m
.Case(In2Sel
.RS
):
196 # for M-Form shiftrot
197 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
198 comb
+= self
.reg_out
.ok
.eq(1)
200 # decode SPR2 based on instruction type
202 # BCREG implicitly uses LR or TAR for 2nd reg
203 # CTR however is already in fast_spr1 *not* 2.
204 with m
.If(op
.internal_op
== MicrOp
.OP_BCREG
):
205 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
206 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
208 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
209 comb
+= self
.fast_out
.ok
.eq(1)
211 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
212 comb
+= self
.fast_out
.ok
.eq(1)
217 class DecodeBImm(Elaboratable
):
218 """DecodeB immediate from instruction
220 def __init__(self
, dec
):
222 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
223 self
.imm_out
= Data(64, "imm_b")
225 def elaborate(self
, platform
):
229 # select Register B Immediate
230 with m
.Switch(self
.sel_in
):
231 with m
.Case(In2Sel
.CONST_UI
): # unsigned
232 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
)
233 comb
+= self
.imm_out
.ok
.eq(1)
234 with m
.Case(In2Sel
.CONST_SI
): # sign-extended 16-bit
235 si
= Signal(16, reset_less
=True)
236 comb
+= si
.eq(self
.dec
.SI
)
237 comb
+= self
.imm_out
.data
.eq(exts(si
, 16, 64))
238 comb
+= self
.imm_out
.ok
.eq(1)
239 with m
.Case(In2Sel
.CONST_SI_HI
): # sign-extended 16+16=32 bit
240 si_hi
= Signal(32, reset_less
=True)
241 comb
+= si_hi
.eq(self
.dec
.SI
<< 16)
242 comb
+= self
.imm_out
.data
.eq(exts(si_hi
, 32, 64))
243 comb
+= self
.imm_out
.ok
.eq(1)
244 with m
.Case(In2Sel
.CONST_UI_HI
): # unsigned
245 ui
= Signal(16, reset_less
=True)
246 comb
+= ui
.eq(self
.dec
.UI
)
247 comb
+= self
.imm_out
.data
.eq(ui
<< 16)
248 comb
+= self
.imm_out
.ok
.eq(1)
249 with m
.Case(In2Sel
.CONST_LI
): # sign-extend 24+2=26 bit
250 li
= Signal(26, reset_less
=True)
251 comb
+= li
.eq(self
.dec
.LI
<< 2)
252 comb
+= self
.imm_out
.data
.eq(exts(li
, 26, 64))
253 comb
+= self
.imm_out
.ok
.eq(1)
254 with m
.Case(In2Sel
.CONST_BD
): # sign-extend (14+2)=16 bit
255 bd
= Signal(16, reset_less
=True)
256 comb
+= bd
.eq(self
.dec
.BD
<< 2)
257 comb
+= self
.imm_out
.data
.eq(exts(bd
, 16, 64))
258 comb
+= self
.imm_out
.ok
.eq(1)
259 with m
.Case(In2Sel
.CONST_DS
): # sign-extended (14+2=16) bit
260 ds
= Signal(16, reset_less
=True)
261 comb
+= ds
.eq(self
.dec
.DS
<< 2)
262 comb
+= self
.imm_out
.data
.eq(exts(ds
, 16, 64))
263 comb
+= self
.imm_out
.ok
.eq(1)
264 with m
.Case(In2Sel
.CONST_M1
): # signed (-1)
265 comb
+= self
.imm_out
.data
.eq(~
Const(0, 64)) # all 1s
266 comb
+= self
.imm_out
.ok
.eq(1)
267 with m
.Case(In2Sel
.CONST_SH
): # unsigned - for shift
268 comb
+= self
.imm_out
.data
.eq(self
.dec
.sh
)
269 comb
+= self
.imm_out
.ok
.eq(1)
270 with m
.Case(In2Sel
.CONST_SH32
): # unsigned - for shift
271 comb
+= self
.imm_out
.data
.eq(self
.dec
.SH32
)
272 comb
+= self
.imm_out
.ok
.eq(1)
277 class DecodeC(Elaboratable
):
278 """DecodeC from instruction
280 decodes register RC. this is "lane 3" into some CompUnits (not many)
283 def __init__(self
, dec
):
285 self
.sv_rm
= SVP64Rec() # SVP64 RM field
286 self
.sel_in
= Signal(In3Sel
, reset_less
=True)
287 self
.insn_in
= Signal(32, reset_less
=True)
288 self
.reg_out
= Data(5, "reg_c")
290 def elaborate(self
, platform
):
294 # select Register C field
295 with m
.Switch(self
.sel_in
):
296 with m
.Case(In3Sel
.RB
):
297 # for M-Form shiftrot
298 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
)
299 comb
+= self
.reg_out
.ok
.eq(1)
300 with m
.Case(In3Sel
.RS
):
301 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
302 comb
+= self
.reg_out
.ok
.eq(1)
307 class DecodeOut(Elaboratable
):
308 """DecodeOut from instruction
310 decodes output register RA, RT or SPR
313 def __init__(self
, dec
):
315 self
.sv_rm
= SVP64Rec() # SVP64 RM field
316 self
.sel_in
= Signal(OutSel
, reset_less
=True)
317 self
.insn_in
= Signal(32, reset_less
=True)
318 self
.reg_out
= Data(5, "reg_o")
319 self
.spr_out
= Data(SPR
, "spr_o")
320 self
.fast_out
= Data(3, "fast_o")
322 def elaborate(self
, platform
):
325 m
.submodules
.sprmap
= sprmap
= SPRMap()
328 # select Register out field
329 with m
.Switch(self
.sel_in
):
330 with m
.Case(OutSel
.RT
):
331 comb
+= self
.reg_out
.data
.eq(self
.dec
.RT
)
332 comb
+= self
.reg_out
.ok
.eq(1)
333 with m
.Case(OutSel
.RA
):
334 comb
+= self
.reg_out
.data
.eq(self
.dec
.RA
)
335 comb
+= self
.reg_out
.ok
.eq(1)
336 with m
.Case(OutSel
.SPR
):
337 spr
= Signal(10, reset_less
=True)
338 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
339 # MFSPR move to SPRs - needs mapping
340 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
341 comb
+= sprmap
.spr_i
.eq(spr
)
342 comb
+= self
.spr_out
.eq(sprmap
.spr_o
)
343 comb
+= self
.fast_out
.eq(sprmap
.fast_o
)
345 with m
.Switch(op
.internal_op
):
347 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeA
348 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_BCREG
):
349 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
351 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
352 comb
+= self
.fast_out
.ok
.eq(1)
354 # RFID 1st spr (fast)
355 with m
.Case(MicrOp
.OP_RFID
):
356 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
357 comb
+= self
.fast_out
.ok
.eq(1)
362 class DecodeOut2(Elaboratable
):
363 """DecodeOut2 from instruction
365 decodes output registers
368 def __init__(self
, dec
):
370 self
.sv_rm
= SVP64Rec() # SVP64 RM field
371 self
.sel_in
= Signal(OutSel
, reset_less
=True)
372 self
.lk
= Signal(reset_less
=True)
373 self
.insn_in
= Signal(32, reset_less
=True)
374 self
.reg_out
= Data(5, "reg_o")
375 self
.fast_out
= Data(3, "fast_o")
377 def elaborate(self
, platform
):
381 if hasattr(self
.dec
.op
, "upd"):
382 # update mode LD/ST uses read-reg A also as an output
383 with m
.If(self
.dec
.op
.upd
== LDSTMode
.update
):
384 comb
+= self
.reg_out
.eq(self
.dec
.RA
)
385 comb
+= self
.reg_out
.ok
.eq(1)
387 # B, BC or BCREG: potential implicit register (LR) output
388 # these give bl, bcl, bclrl, etc.
390 with m
.Switch(op
.internal_op
):
392 # BC* implicit register (LR)
393 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_B
, MicrOp
.OP_BCREG
):
394 with m
.If(self
.lk
): # "link" mode
395 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
) # constant: LR
396 comb
+= self
.fast_out
.ok
.eq(1)
398 # RFID 2nd spr (fast)
399 with m
.Case(MicrOp
.OP_RFID
):
400 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
401 comb
+= self
.fast_out
.ok
.eq(1)
406 class DecodeRC(Elaboratable
):
407 """DecodeRc from instruction
409 decodes Record bit Rc
412 def __init__(self
, dec
):
414 self
.sel_in
= Signal(RC
, reset_less
=True)
415 self
.insn_in
= Signal(32, reset_less
=True)
416 self
.rc_out
= Data(1, "rc")
418 def elaborate(self
, platform
):
422 # select Record bit out field
423 with m
.Switch(self
.sel_in
):
425 comb
+= self
.rc_out
.data
.eq(self
.dec
.Rc
)
426 comb
+= self
.rc_out
.ok
.eq(1)
428 comb
+= self
.rc_out
.data
.eq(1)
429 comb
+= self
.rc_out
.ok
.eq(1)
430 with m
.Case(RC
.NONE
):
431 comb
+= self
.rc_out
.data
.eq(0)
432 comb
+= self
.rc_out
.ok
.eq(1)
437 class DecodeOE(Elaboratable
):
438 """DecodeOE from instruction
440 decodes OE field: uses RC decode detection which might not be good
442 -- For now, use "rc" in the decode table to decide whether oe exists.
443 -- This is not entirely correct architecturally: For mulhd and
444 -- mulhdu, the OE field is reserved. It remains to be seen what an
445 -- actual POWER9 does if we set it on those instructions, for now we
446 -- test that further down when assigning to the multiplier oe input.
449 def __init__(self
, dec
):
451 self
.sel_in
= Signal(RC
, reset_less
=True)
452 self
.insn_in
= Signal(32, reset_less
=True)
453 self
.oe_out
= Data(1, "oe")
455 def elaborate(self
, platform
):
460 with m
.Switch(op
.internal_op
):
462 # mulhw, mulhwu, mulhd, mulhdu - these *ignore* OE
464 # XXX ARGH! ignoring OE causes incompatibility with microwatt
465 # http://lists.libre-soc.org/pipermail/libre-soc-dev/2020-August/000302.html
466 with m
.Case(MicrOp
.OP_MUL_H64
, MicrOp
.OP_MUL_H32
,
467 MicrOp
.OP_EXTS
, MicrOp
.OP_CNTZ
,
468 MicrOp
.OP_SHL
, MicrOp
.OP_SHR
, MicrOp
.OP_RLC
,
469 MicrOp
.OP_LOAD
, MicrOp
.OP_STORE
,
470 MicrOp
.OP_RLCL
, MicrOp
.OP_RLCR
,
474 # all other ops decode OE field
476 # select OE bit out field
477 with m
.Switch(self
.sel_in
):
479 comb
+= self
.oe_out
.data
.eq(self
.dec
.OE
)
480 comb
+= self
.oe_out
.ok
.eq(1)
485 class DecodeCRIn(Elaboratable
):
486 """Decodes input CR from instruction
488 CR indices - insn fields - (not the data *in* the CR) require only 3
489 bits because they refer to CR0-CR7
492 def __init__(self
, dec
):
494 self
.sv_rm
= SVP64Rec() # SVP64 RM field
495 self
.sel_in
= Signal(CRInSel
, reset_less
=True)
496 self
.insn_in
= Signal(32, reset_less
=True)
497 self
.cr_bitfield
= Data(3, "cr_bitfield")
498 self
.cr_bitfield_b
= Data(3, "cr_bitfield_b")
499 self
.cr_bitfield_o
= Data(3, "cr_bitfield_o")
500 self
.whole_reg
= Data(8, "cr_fxm")
502 def elaborate(self
, platform
):
504 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
510 comb
+= self
.cr_bitfield
.ok
.eq(0)
511 comb
+= self
.cr_bitfield_b
.ok
.eq(0)
512 comb
+= self
.whole_reg
.ok
.eq(0)
513 with m
.Switch(self
.sel_in
):
514 with m
.Case(CRInSel
.NONE
):
515 pass # No bitfield activated
516 with m
.Case(CRInSel
.CR0
):
517 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
518 comb
+= self
.cr_bitfield
.ok
.eq(1)
519 with m
.Case(CRInSel
.BI
):
520 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BI
[2:5])
521 comb
+= self
.cr_bitfield
.ok
.eq(1)
522 with m
.Case(CRInSel
.BFA
):
523 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BFA
)
524 comb
+= self
.cr_bitfield
.ok
.eq(1)
525 with m
.Case(CRInSel
.BA_BB
):
526 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BA
[2:5])
527 comb
+= self
.cr_bitfield
.ok
.eq(1)
528 comb
+= self
.cr_bitfield_b
.data
.eq(self
.dec
.BB
[2:5])
529 comb
+= self
.cr_bitfield_b
.ok
.eq(1)
530 comb
+= self
.cr_bitfield_o
.data
.eq(self
.dec
.BT
[2:5])
531 comb
+= self
.cr_bitfield_o
.ok
.eq(1)
532 with m
.Case(CRInSel
.BC
):
533 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BC
[2:5])
534 comb
+= self
.cr_bitfield
.ok
.eq(1)
535 with m
.Case(CRInSel
.WHOLE_REG
):
536 comb
+= self
.whole_reg
.ok
.eq(1)
537 move_one
= Signal(reset_less
=True)
538 comb
+= move_one
.eq(self
.insn_in
[20]) # MSB0 bit 11
539 with m
.If((op
.internal_op
== MicrOp
.OP_MFCR
) & move_one
):
540 # must one-hot the FXM field
541 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
542 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
544 # otherwise use all of it
545 comb
+= self
.whole_reg
.data
.eq(0xff)
550 class DecodeCROut(Elaboratable
):
551 """Decodes input CR from instruction
553 CR indices - insn fields - (not the data *in* the CR) require only 3
554 bits because they refer to CR0-CR7
557 def __init__(self
, dec
):
559 self
.sv_rm
= SVP64Rec() # SVP64 RM field
560 self
.rc_in
= Signal(reset_less
=True)
561 self
.sel_in
= Signal(CROutSel
, reset_less
=True)
562 self
.insn_in
= Signal(32, reset_less
=True)
563 self
.cr_bitfield
= Data(3, "cr_bitfield")
564 self
.whole_reg
= Data(8, "cr_fxm")
566 def elaborate(self
, platform
):
570 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
573 comb
+= self
.cr_bitfield
.ok
.eq(0)
574 comb
+= self
.whole_reg
.ok
.eq(0)
575 with m
.Switch(self
.sel_in
):
576 with m
.Case(CROutSel
.NONE
):
577 pass # No bitfield activated
578 with m
.Case(CROutSel
.CR0
):
579 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
580 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
581 with m
.Case(CROutSel
.BF
):
582 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BF
)
583 comb
+= self
.cr_bitfield
.ok
.eq(1)
584 with m
.Case(CROutSel
.BT
):
585 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormXL
.BT
[2:5])
586 comb
+= self
.cr_bitfield
.ok
.eq(1)
587 with m
.Case(CROutSel
.WHOLE_REG
):
588 comb
+= self
.whole_reg
.ok
.eq(1)
589 move_one
= Signal(reset_less
=True)
590 comb
+= move_one
.eq(self
.insn_in
[20])
591 with m
.If((op
.internal_op
== MicrOp
.OP_MTCRF
)):
593 # must one-hot the FXM field
594 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
595 with m
.If(ppick
.en_o
):
596 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
598 comb
+= self
.whole_reg
.data
.eq(0b00000001) # CR7
600 comb
+= self
.whole_reg
.data
.eq(self
.dec
.FXM
)
602 # otherwise use all of it
603 comb
+= self
.whole_reg
.data
.eq(0xff)
607 # dictionary of Input Record field names that, if they exist,
608 # will need a corresponding CSV Decoder file column (actually, PowerOp)
609 # to be decoded (this includes the single bit names)
610 record_names
= {'insn_type': 'internal_op',
611 'fn_unit': 'function_unit',
615 'imm_data': 'in2_sel',
616 'invert_in': 'inv_a',
617 'invert_out': 'inv_out',
620 'output_carry': 'cry_out',
621 'input_carry': 'cry_in',
622 'is_32bit': 'is_32b',
625 'data_len': 'ldst_len',
626 'byte_reverse': 'br',
627 'sign_extend': 'sgn_ext',
632 class PowerDecodeSubset(Elaboratable
):
633 """PowerDecodeSubset: dynamic subset decoder
635 only fields actually requested are copied over. hence, "subset" (duh).
637 def __init__(self
, dec
, opkls
=None, fn_name
=None, final
=False, state
=None):
639 self
.sv_rm
= SVP64Rec(name
="dec_svp64") # SVP64 RM field
642 self
.fn_name
= fn_name
644 opkls
= Decode2ToOperand
645 self
.do
= opkls(fn_name
)
646 col_subset
= self
.get_col_subset(self
.do
)
648 # only needed for "main" PowerDecode2
650 self
.e
= Decode2ToExecute1Type(name
=self
.fn_name
, do
=self
.do
)
652 # create decoder if one not already given
654 dec
= create_pdecode(name
=fn_name
, col_subset
=col_subset
,
655 row_subset
=self
.rowsubsetfn
)
658 # state information needed by the Decoder
660 state
= CoreState("dec2")
663 def get_col_subset(self
, do
):
664 subset
= {'cr_in', 'cr_out', 'rc_sel'} # needed, non-optional
665 for k
, v
in record_names
.items():
668 print ("get_col_subset", self
.fn_name
, do
.fields
, subset
)
671 def rowsubsetfn(self
, opcode
, row
):
672 return row
['unit'] == self
.fn_name
675 return self
.dec
.ports() + self
.e
.ports() + self
.sv_rm
.ports()
677 def needs_field(self
, field
, op_field
):
682 return hasattr(do
, field
) and self
.op_get(op_field
) is not None
684 def do_copy(self
, field
, val
, final
=False):
685 if final
or self
.final
:
689 if hasattr(do
, field
) and val
is not None:
690 return getattr(do
, field
).eq(val
)
693 def op_get(self
, op_field
):
694 return getattr(self
.dec
.op
, op_field
, None)
696 def elaborate(self
, platform
):
700 op
, do
= self
.dec
.op
, self
.do
701 msr
, cia
= state
.msr
, state
.pc
703 # fill in for a normal instruction (not an exception)
704 # copy over if non-exception, non-privileged etc. is detected
706 if self
.fn_name
is None:
709 name
= self
.fn_name
+ "tmp"
710 self
.e_tmp
= Decode2ToExecute1Type(name
=name
, opkls
=self
.opkls
)
712 # set up submodule decoders
713 m
.submodules
.dec
= self
.dec
714 m
.submodules
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
715 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
)
716 m
.submodules
.dec_cr_in
= self
.dec_cr_in
= DecodeCRIn(self
.dec
)
717 m
.submodules
.dec_cr_out
= self
.dec_cr_out
= DecodeCROut(self
.dec
)
719 # copy instruction through...
721 dec_rc
.insn_in
, dec_oe
.insn_in
,
722 self
.dec_cr_in
.insn_in
, self
.dec_cr_out
.insn_in
]:
723 comb
+= i
.eq(self
.dec
.opcode_in
)
725 # ...and subdecoders' input fields
726 comb
+= dec_rc
.sel_in
.eq(op
.rc_sel
)
727 comb
+= dec_oe
.sel_in
.eq(op
.rc_sel
) # XXX should be OE sel
728 comb
+= self
.dec_cr_in
.sel_in
.eq(op
.cr_in
)
729 comb
+= self
.dec_cr_in
.sv_rm
.eq(self
.sv_rm
)
730 comb
+= self
.dec_cr_out
.sv_rm
.eq(self
.sv_rm
)
731 comb
+= self
.dec_cr_out
.sel_in
.eq(op
.cr_out
)
732 comb
+= self
.dec_cr_out
.rc_in
.eq(dec_rc
.rc_out
.data
)
735 comb
+= self
.do_copy("msr", msr
)
736 comb
+= self
.do_copy("cia", cia
)
738 # set up instruction type
739 # no op: defaults to OP_ILLEGAL
740 comb
+= self
.do_copy("insn_type", self
.op_get("internal_op"))
742 # function unit for decoded instruction: requires minor redirect
744 fn
= self
.op_get("function_unit")
745 spr
= Signal(10, reset_less
=True)
746 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
748 # for first test only forward SPRs 18 and 19 to MMU, when
749 # operation is MTSPR or MFSPR. TODO: add other MMU SPRs
750 with m
.If(((self
.dec
.op
.internal_op
== MicrOp
.OP_MTSPR
) |
751 (self
.dec
.op
.internal_op
== MicrOp
.OP_MFSPR
)) &
752 ((spr
== SPR
.DSISR
) |
(spr
== SPR
.DAR
))):
753 comb
+= self
.do_copy("fn_unit", Function
.MMU
)
755 comb
+= self
.do_copy("fn_unit",fn
)
758 if self
.needs_field("zero_a", "in1_sel"):
759 m
.submodules
.dec_ai
= dec_ai
= DecodeAImm(self
.dec
)
760 comb
+= dec_ai
.sel_in
.eq(op
.in1_sel
)
761 comb
+= self
.do_copy("zero_a", dec_ai
.immz_out
) # RA==0 detected
762 if self
.needs_field("imm_data", "in2_sel"):
763 m
.submodules
.dec_bi
= dec_bi
= DecodeBImm(self
.dec
)
764 comb
+= dec_bi
.sel_in
.eq(op
.in2_sel
)
765 comb
+= self
.do_copy("imm_data", dec_bi
.imm_out
) # imm in RB
768 comb
+= self
.do_copy("rc", dec_rc
.rc_out
)
769 comb
+= self
.do_copy("oe", dec_oe
.oe_out
)
772 comb
+= self
.do_copy("read_cr_whole", self
.dec_cr_in
.whole_reg
)
773 comb
+= self
.do_copy("write_cr_whole", self
.dec_cr_out
.whole_reg
)
774 comb
+= self
.do_copy("write_cr0", self
.dec_cr_out
.cr_bitfield
.ok
)
776 comb
+= self
.do_copy("input_cr", self
.op_get("cr_in")) # CR in
777 comb
+= self
.do_copy("output_cr", self
.op_get("cr_out")) # CR out
779 # decoded/selected instruction flags
780 comb
+= self
.do_copy("data_len", self
.op_get("ldst_len"))
781 comb
+= self
.do_copy("invert_in", self
.op_get("inv_a"))
782 comb
+= self
.do_copy("invert_out", self
.op_get("inv_out"))
783 comb
+= self
.do_copy("input_carry", self
.op_get("cry_in"))
784 comb
+= self
.do_copy("output_carry", self
.op_get("cry_out"))
785 comb
+= self
.do_copy("is_32bit", self
.op_get("is_32b"))
786 comb
+= self
.do_copy("is_signed", self
.op_get("sgn"))
787 lk
= self
.op_get("lk")
790 comb
+= self
.do_copy("lk", self
.dec
.LK
) # XXX TODO: accessor
792 comb
+= self
.do_copy("byte_reverse", self
.op_get("br"))
793 comb
+= self
.do_copy("sign_extend", self
.op_get("sgn_ext"))
794 comb
+= self
.do_copy("ldst_mode", self
.op_get("upd")) # LD/ST mode
799 class PowerDecode2(PowerDecodeSubset
):
800 """PowerDecode2: the main instruction decoder.
802 whilst PowerDecode is responsible for decoding the actual opcode, this
803 module encapsulates further specialist, sparse information and
804 expansion of fields that is inconvenient to have in the CSV files.
805 for example: the encoding of the immediates, which are detected
806 and expanded out to their full value from an annotated (enum)
809 implicit register usage is also set up, here. for example: OP_BC
810 requires implicitly reading CTR, OP_RFID requires implicitly writing
813 in addition, PowerDecoder2 is responsible for detecting whether
814 instructions are illegal (or privileged) or not, and instead of
815 just leaving at that, *replacing* the instruction to execute with
816 a suitable alternative (trap).
818 LDSTExceptions are done the cycle _after_ they're detected (after
819 they come out of LDSTCompUnit). basically despite the instruction
820 being decoded, the results of the decode are completely ignored
821 and "exception.happened" used to set the "actual" instruction to
822 "OP_TRAP". the LDSTException data structure gets filled in,
823 in the CompTrapOpSubset and that's what it fills in SRR.
825 to make this work, TestIssuer must notice "exception.happened"
826 after the (failed) LD/ST and copies the LDSTException info from
827 the output, into here (PowerDecoder2). without incrementing PC.
830 def __init__(self
, dec
, opkls
=None, fn_name
=None, final
=False, state
=None):
831 super().__init
__(dec
, opkls
, fn_name
, final
, state
)
832 self
.exc
= LDSTException("dec2_exc")
834 def get_col_subset(self
, opkls
):
835 subset
= super().get_col_subset(opkls
)
836 subset
.add("in1_sel")
837 subset
.add("asmcode")
838 subset
.add("in2_sel")
839 subset
.add("in3_sel")
840 subset
.add("out_sel")
842 subset
.add("internal_op")
846 def elaborate(self
, platform
):
847 m
= super().elaborate(platform
)
850 e_out
, op
, do_out
= self
.e
, self
.dec
.op
, self
.e
.do
851 dec_spr
, msr
, cia
, ext_irq
= state
.dec
, state
.msr
, state
.pc
, state
.eint
855 # fill in for a normal instruction (not an exception)
856 # copy over if non-exception, non-privileged etc. is detected
858 # set up submodule decoders
859 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
)
860 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
)
861 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
)
862 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
)
863 m
.submodules
.dec_o2
= dec_o2
= DecodeOut2(self
.dec
)
865 # copy instruction through...
866 for i
in [do
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
867 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
]:
868 comb
+= i
.eq(self
.dec
.opcode_in
)
871 for i
in [dec_a
.insn_in
, dec_b
.insn_in
,
872 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
]:
873 comb
+= i
.eq(self
.sv_rm
)
875 # ...and subdecoders' input fields
876 comb
+= dec_a
.sel_in
.eq(op
.in1_sel
)
877 comb
+= dec_b
.sel_in
.eq(op
.in2_sel
)
878 comb
+= dec_c
.sel_in
.eq(op
.in3_sel
)
879 comb
+= dec_o
.sel_in
.eq(op
.out_sel
)
880 comb
+= dec_o2
.sel_in
.eq(op
.out_sel
)
881 if hasattr(do
, "lk"):
882 comb
+= dec_o2
.lk
.eq(do
.lk
)
884 # registers a, b, c and out and out2 (LD/ST EA)
885 for to_reg
, fromreg
in (
886 (e
.read_reg1
, dec_a
.reg_out
),
887 (e
.read_reg2
, dec_b
.reg_out
),
888 (e
.read_reg3
, dec_c
.reg_out
),
889 (e
.write_reg
, dec_o
.reg_out
),
890 (e
.write_ea
, dec_o2
.reg_out
)):
891 comb
+= to_reg
.data
.eq(fromreg
.data
)
892 comb
+= to_reg
.ok
.eq(fromreg
.ok
)
895 comb
+= e
.read_spr1
.eq(dec_a
.spr_out
)
896 comb
+= e
.write_spr
.eq(dec_o
.spr_out
)
899 comb
+= e
.read_fast1
.eq(dec_a
.fast_out
)
900 comb
+= e
.read_fast2
.eq(dec_b
.fast_out
)
901 comb
+= e
.write_fast1
.eq(dec_o
.fast_out
)
902 comb
+= e
.write_fast2
.eq(dec_o2
.fast_out
)
904 # condition registers (CR)
905 comb
+= e
.read_cr1
.eq(self
.dec_cr_in
.cr_bitfield
)
906 comb
+= e
.read_cr2
.eq(self
.dec_cr_in
.cr_bitfield_b
)
907 comb
+= e
.read_cr3
.eq(self
.dec_cr_in
.cr_bitfield_o
)
908 comb
+= e
.write_cr
.eq(self
.dec_cr_out
.cr_bitfield
)
910 # sigh this is exactly the sort of thing for which the
911 # decoder is designed to not need. MTSPR, MFSPR and others need
912 # access to the XER bits. however setting e.oe is not appropriate
913 with m
.If(op
.internal_op
== MicrOp
.OP_MFSPR
):
914 comb
+= e
.xer_in
.eq(0b111) # SO, CA, OV
915 with m
.If(op
.internal_op
== MicrOp
.OP_CMP
):
916 comb
+= e
.xer_in
.eq(1<<XERRegs
.SO
) # SO
917 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
918 comb
+= e
.xer_out
.eq(1)
920 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
921 with m
.If(op
.internal_op
== MicrOp
.OP_TRAP
):
922 # *DO NOT* call self.trap here. that would reset absolutely
923 # everything including destroying read of RA and RB.
924 comb
+= self
.do_copy("trapaddr", 0x70) # strip first nibble
927 # ok so the instruction's been decoded, blah blah, however
928 # now we need to determine if it's actually going to go ahead...
929 # *or* if in fact it's a privileged operation, whether there's
930 # an external interrupt, etc. etc. this is a simple priority
931 # if-elif-elif sequence. decrement takes highest priority,
932 # EINT next highest, privileged operation third.
934 # check if instruction is privileged
935 is_priv_insn
= instr_is_priv(m
, op
.internal_op
, e
.do
.insn
)
937 # different IRQ conditions
938 ext_irq_ok
= Signal()
939 dec_irq_ok
= Signal()
944 comb
+= ext_irq_ok
.eq(ext_irq
& msr
[MSR
.EE
]) # v3.0B p944 (MSR.EE)
945 comb
+= dec_irq_ok
.eq(dec_spr
[63] & msr
[MSR
.EE
]) # 6.5.11 p1076
946 comb
+= priv_ok
.eq(is_priv_insn
& msr
[MSR
.PR
])
947 comb
+= illeg_ok
.eq(op
.internal_op
== MicrOp
.OP_ILLEGAL
)
949 # LD/ST exceptions. TestIssuer copies the exception info at us
950 # after a failed LD/ST.
951 with m
.If(exc
.happened
):
952 with m
.If(exc
.alignment
):
953 self
.trap(m
, TT
.PRIV
, 0x600)
954 with m
.Elif(exc
.instr_fault
):
955 with m
.If(exc
.segment_fault
):
956 self
.trap(m
, TT
.PRIV
, 0x480)
958 # pass exception info to trap to create SRR1
959 self
.trap(m
, TT
.MEMEXC
, 0x400, exc
)
961 with m
.If(exc
.segment_fault
):
962 self
.trap(m
, TT
.PRIV
, 0x380)
964 self
.trap(m
, TT
.PRIV
, 0x300)
966 # decrement counter (v3.0B p1099): TODO 32-bit version (MSR.LPCR)
967 with m
.Elif(dec_irq_ok
):
968 self
.trap(m
, TT
.DEC
, 0x900) # v3.0B 6.5 p1065
970 # external interrupt? only if MSR.EE set
971 with m
.Elif(ext_irq_ok
):
972 self
.trap(m
, TT
.EINT
, 0x500)
974 # privileged instruction trap
975 with m
.Elif(priv_ok
):
976 self
.trap(m
, TT
.PRIV
, 0x700)
978 # illegal instruction must redirect to trap. this is done by
979 # *overwriting* the decoded instruction and starting again.
980 # (note: the same goes for interrupts and for privileged operations,
981 # just with different trapaddr and traptype)
982 with m
.Elif(illeg_ok
):
983 # illegal instruction trap
984 self
.trap(m
, TT
.ILLEG
, 0x700)
986 # no exception, just copy things to the output
991 # follow-up after trap/irq to set up SRR0/1
993 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
994 # Note: OP_SC could actually be modified to just be a trap
995 with m
.If((do_out
.insn_type
== MicrOp
.OP_TRAP
) |
996 (do_out
.insn_type
== MicrOp
.OP_SC
)):
997 # TRAP write fast1 = SRR0
998 comb
+= e_out
.write_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
999 comb
+= e_out
.write_fast1
.ok
.eq(1)
1000 # TRAP write fast2 = SRR1
1001 comb
+= e_out
.write_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
1002 comb
+= e_out
.write_fast2
.ok
.eq(1)
1004 # RFID: needs to read SRR0/1
1005 with m
.If(do_out
.insn_type
== MicrOp
.OP_RFID
):
1006 # TRAP read fast1 = SRR0
1007 comb
+= e_out
.read_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
1008 comb
+= e_out
.read_fast1
.ok
.eq(1)
1009 # TRAP read fast2 = SRR1
1010 comb
+= e_out
.read_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
1011 comb
+= e_out
.read_fast2
.ok
.eq(1)
1013 # annoying simulator bug
1014 if hasattr(e_out
, "asmcode") and hasattr(self
.dec
.op
, "asmcode"):
1015 comb
+= e_out
.asmcode
.eq(self
.dec
.op
.asmcode
)
1019 def trap(self
, m
, traptype
, trapaddr
, exc
=None):
1020 """trap: this basically "rewrites" the decoded instruction as a trap
1023 op
, e
= self
.dec
.op
, self
.e
1024 comb
+= e
.eq(0) # reset eeeeeverything
1027 comb
+= self
.do_copy("insn", self
.dec
.opcode_in
, True)
1028 comb
+= self
.do_copy("insn_type", MicrOp
.OP_TRAP
, True)
1029 comb
+= self
.do_copy("fn_unit", Function
.TRAP
, True)
1030 comb
+= self
.do_copy("trapaddr", trapaddr
>> 4, True) # bottom 4 bits
1031 comb
+= self
.do_copy("traptype", traptype
, True) # request type
1032 comb
+= self
.do_copy("ldst_exc", exc
, True) # request type
1033 comb
+= self
.do_copy("msr", self
.state
.msr
, True) # copy of MSR "state"
1034 comb
+= self
.do_copy("cia", self
.state
.pc
, True) # copy of PC "state"
1037 def get_rdflags(e
, cu
):
1039 for idx
in range(cu
.n_src
):
1040 regfile
, regname
, _
= cu
.get_in_spec(idx
)
1041 rdflag
, read
= regspec_decode_read(e
, regfile
, regname
)
1043 print("rdflags", rdl
)
1047 if __name__
== '__main__':
1048 pdecode
= create_pdecode()
1049 dec2
= PowerDecode2(pdecode
)
1050 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
1051 with
open("dec2.il", "w") as f
: