e24de8a30e2d2f766828b5b535a64bbeba442548
1 """Power ISA Decoder second stage
3 based on Anton Blanchard microwatt decode2.vhdl
5 Note: OP_TRAP is used for exceptions and interrupts (micro-code style) by
6 over-riding the internal opcode when an exception is needed.
9 from nmigen
import Module
, Elaboratable
, Signal
, Mux
, Const
, Cat
, Repl
, Record
10 from nmigen
.cli
import rtlil
11 from soc
.regfile
.regfiles
import XERRegs
13 from nmutil
.picker
import PriorityPicker
14 from nmutil
.iocontrol
import RecordObject
15 from nmutil
.extend
import exts
17 from soc
.decoder
.power_regspec_map
import regspec_decode_read
18 from soc
.decoder
.power_regspec_map
import regspec_decode_write
19 from soc
.decoder
.power_decoder
import create_pdecode
20 from soc
.decoder
.power_enums
import (MicrOp
, CryIn
, Function
,
22 LdstLen
, In1Sel
, In2Sel
, In3Sel
,
23 OutSel
, SPR
, RC
, LDSTMode
)
24 from soc
.decoder
.decode2execute1
import Decode2ToExecute1Type
, Data
25 from soc
.consts
import MSR
27 from soc
.regfile
.regfiles
import FastRegs
28 from soc
.consts
import TT
29 from soc
.config
.state
import CoreState
30 from soc
.regfile
.util
import spr_to_fast
33 def decode_spr_num(spr
):
34 return Cat(spr
[5:10], spr
[0:5])
37 def instr_is_priv(m
, op
, insn
):
38 """determines if the instruction is privileged or not
41 is_priv_insn
= Signal(reset_less
=True)
43 with m
.Case(MicrOp
.OP_ATTN
, MicrOp
.OP_MFMSR
, MicrOp
.OP_MTMSRD
,
44 MicrOp
.OP_MTMSR
, MicrOp
.OP_RFID
):
45 comb
+= is_priv_insn
.eq(1)
47 #with m.Case(MicrOp.OP_TLBIE) : comb += is_priv_insn.eq(1)
48 with m
.Case(MicrOp
.OP_MFSPR
, MicrOp
.OP_MTSPR
):
49 with m
.If(insn
[20]): # field XFX.spr[-1] i think
50 comb
+= is_priv_insn
.eq(1)
54 class SPRMap(Elaboratable
):
55 """SPRMap: maps POWER9 SPR numbers to internal enum values, fast and slow
59 self
.spr_i
= Signal(10, reset_less
=True)
60 self
.spr_o
= Data(SPR
, name
="spr_o")
61 self
.fast_o
= Data(3, name
="fast_o")
63 def elaborate(self
, platform
):
65 with m
.Switch(self
.spr_i
):
66 for i
, x
in enumerate(SPR
):
68 m
.d
.comb
+= self
.spr_o
.data
.eq(i
)
69 m
.d
.comb
+= self
.spr_o
.ok
.eq(1)
70 for x
, v
in spr_to_fast
.items():
72 m
.d
.comb
+= self
.fast_o
.data
.eq(v
)
73 m
.d
.comb
+= self
.fast_o
.ok
.eq(1)
77 class DecodeA(Elaboratable
):
78 """DecodeA from instruction
80 decodes register RA, implicit and explicit CSRs
83 def __init__(self
, dec
):
85 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
86 self
.insn_in
= Signal(32, reset_less
=True)
87 self
.reg_out
= Data(5, name
="reg_a")
88 self
.spr_out
= Data(SPR
, "spr_a")
89 self
.fast_out
= Data(3, "fast_a")
91 def elaborate(self
, platform
):
94 m
.submodules
.sprmap
= sprmap
= SPRMap()
96 # select Register A field
97 ra
= Signal(5, reset_less
=True)
98 comb
+= ra
.eq(self
.dec
.RA
)
99 with m
.If((self
.sel_in
== In1Sel
.RA
) |
100 ((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
101 (ra
!= Const(0, 5)))):
102 comb
+= self
.reg_out
.data
.eq(ra
)
103 comb
+= self
.reg_out
.ok
.eq(1)
105 # some Logic/ALU ops have RS as the 3rd arg, but no "RA".
106 with m
.If(self
.sel_in
== In1Sel
.RS
):
107 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
108 comb
+= self
.reg_out
.ok
.eq(1)
110 # decode Fast-SPR based on instruction type
112 with m
.Switch(op
.internal_op
):
114 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeOut
115 with m
.Case(MicrOp
.OP_BC
):
116 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
118 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
119 comb
+= self
.fast_out
.ok
.eq(1)
120 with m
.Case(MicrOp
.OP_BCREG
):
121 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
122 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
123 with m
.If(xo9
& ~xo5
):
125 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
126 comb
+= self
.fast_out
.ok
.eq(1)
128 # MFSPR move from SPRs
129 with m
.Case(MicrOp
.OP_MFSPR
):
130 spr
= Signal(10, reset_less
=True)
131 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
132 comb
+= sprmap
.spr_i
.eq(spr
)
133 comb
+= self
.spr_out
.eq(sprmap
.spr_o
)
134 comb
+= self
.fast_out
.eq(sprmap
.fast_o
)
139 class DecodeAImm(Elaboratable
):
140 """DecodeA immediate from instruction
142 decodes register RA, whether immediate-zero, implicit and
146 def __init__(self
, dec
):
148 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
149 self
.immz_out
= Signal(reset_less
=True)
151 def elaborate(self
, platform
):
155 # zero immediate requested
156 ra
= Signal(5, reset_less
=True)
157 comb
+= ra
.eq(self
.dec
.RA
)
158 with m
.If((self
.sel_in
== In1Sel
.RA_OR_ZERO
) & (ra
== Const(0, 5))):
159 comb
+= self
.immz_out
.eq(1)
164 class DecodeB(Elaboratable
):
165 """DecodeB from instruction
167 decodes register RB, different forms of immediate (signed, unsigned),
168 and implicit SPRs. register B is basically "lane 2" into the CompUnits.
169 by industry-standard convention, "lane 2" is where fully-decoded
170 immediates are muxed in.
173 def __init__(self
, dec
):
175 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
176 self
.insn_in
= Signal(32, reset_less
=True)
177 self
.reg_out
= Data(5, "reg_b")
178 self
.fast_out
= Data(3, "fast_b")
180 def elaborate(self
, platform
):
184 # select Register B field
185 with m
.Switch(self
.sel_in
):
186 with m
.Case(In2Sel
.RB
):
187 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
)
188 comb
+= self
.reg_out
.ok
.eq(1)
189 with m
.Case(In2Sel
.RS
):
190 # for M-Form shiftrot
191 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
192 comb
+= self
.reg_out
.ok
.eq(1)
194 # decode SPR2 based on instruction type
196 # BCREG implicitly uses LR or TAR for 2nd reg
197 # CTR however is already in fast_spr1 *not* 2.
198 with m
.If(op
.internal_op
== MicrOp
.OP_BCREG
):
199 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
200 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
202 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
203 comb
+= self
.fast_out
.ok
.eq(1)
205 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
206 comb
+= self
.fast_out
.ok
.eq(1)
211 class DecodeBImm(Elaboratable
):
212 """DecodeB immediate from instruction
214 def __init__(self
, dec
):
216 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
217 self
.imm_out
= Data(64, "imm_b")
219 def elaborate(self
, platform
):
223 # select Register B Immediate
224 with m
.Switch(self
.sel_in
):
225 with m
.Case(In2Sel
.CONST_UI
): # unsigned
226 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
)
227 comb
+= self
.imm_out
.ok
.eq(1)
228 with m
.Case(In2Sel
.CONST_SI
): # sign-extended 16-bit
229 si
= Signal(16, reset_less
=True)
230 comb
+= si
.eq(self
.dec
.SI
)
231 comb
+= self
.imm_out
.data
.eq(exts(si
, 16, 64))
232 comb
+= self
.imm_out
.ok
.eq(1)
233 with m
.Case(In2Sel
.CONST_SI_HI
): # sign-extended 16+16=32 bit
234 si_hi
= Signal(32, reset_less
=True)
235 comb
+= si_hi
.eq(self
.dec
.SI
<< 16)
236 comb
+= self
.imm_out
.data
.eq(exts(si_hi
, 32, 64))
237 comb
+= self
.imm_out
.ok
.eq(1)
238 with m
.Case(In2Sel
.CONST_UI_HI
): # unsigned
239 ui
= Signal(16, reset_less
=True)
240 comb
+= ui
.eq(self
.dec
.UI
)
241 comb
+= self
.imm_out
.data
.eq(ui
<< 16)
242 comb
+= self
.imm_out
.ok
.eq(1)
243 with m
.Case(In2Sel
.CONST_LI
): # sign-extend 24+2=26 bit
244 li
= Signal(26, reset_less
=True)
245 comb
+= li
.eq(self
.dec
.LI
<< 2)
246 comb
+= self
.imm_out
.data
.eq(exts(li
, 26, 64))
247 comb
+= self
.imm_out
.ok
.eq(1)
248 with m
.Case(In2Sel
.CONST_BD
): # sign-extend (14+2)=16 bit
249 bd
= Signal(16, reset_less
=True)
250 comb
+= bd
.eq(self
.dec
.BD
<< 2)
251 comb
+= self
.imm_out
.data
.eq(exts(bd
, 16, 64))
252 comb
+= self
.imm_out
.ok
.eq(1)
253 with m
.Case(In2Sel
.CONST_DS
): # sign-extended (14+2=16) bit
254 ds
= Signal(16, reset_less
=True)
255 comb
+= ds
.eq(self
.dec
.DS
<< 2)
256 comb
+= self
.imm_out
.data
.eq(exts(ds
, 16, 64))
257 comb
+= self
.imm_out
.ok
.eq(1)
258 with m
.Case(In2Sel
.CONST_M1
): # signed (-1)
259 comb
+= self
.imm_out
.data
.eq(~
Const(0, 64)) # all 1s
260 comb
+= self
.imm_out
.ok
.eq(1)
261 with m
.Case(In2Sel
.CONST_SH
): # unsigned - for shift
262 comb
+= self
.imm_out
.data
.eq(self
.dec
.sh
)
263 comb
+= self
.imm_out
.ok
.eq(1)
264 with m
.Case(In2Sel
.CONST_SH32
): # unsigned - for shift
265 comb
+= self
.imm_out
.data
.eq(self
.dec
.SH32
)
266 comb
+= self
.imm_out
.ok
.eq(1)
271 class DecodeC(Elaboratable
):
272 """DecodeC from instruction
274 decodes register RC. this is "lane 3" into some CompUnits (not many)
277 def __init__(self
, dec
):
279 self
.sel_in
= Signal(In3Sel
, reset_less
=True)
280 self
.insn_in
= Signal(32, reset_less
=True)
281 self
.reg_out
= Data(5, "reg_c")
283 def elaborate(self
, platform
):
287 # select Register C field
288 with m
.Switch(self
.sel_in
):
289 with m
.Case(In3Sel
.RB
):
290 # for M-Form shiftrot
291 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
)
292 comb
+= self
.reg_out
.ok
.eq(1)
293 with m
.Case(In3Sel
.RS
):
294 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
295 comb
+= self
.reg_out
.ok
.eq(1)
300 class DecodeOut(Elaboratable
):
301 """DecodeOut from instruction
303 decodes output register RA, RT or SPR
306 def __init__(self
, dec
):
308 self
.sel_in
= Signal(OutSel
, reset_less
=True)
309 self
.insn_in
= Signal(32, reset_less
=True)
310 self
.reg_out
= Data(5, "reg_o")
311 self
.spr_out
= Data(SPR
, "spr_o")
312 self
.fast_out
= Data(3, "fast_o")
314 def elaborate(self
, platform
):
317 m
.submodules
.sprmap
= sprmap
= SPRMap()
320 # select Register out field
321 with m
.Switch(self
.sel_in
):
322 with m
.Case(OutSel
.RT
):
323 comb
+= self
.reg_out
.data
.eq(self
.dec
.RT
)
324 comb
+= self
.reg_out
.ok
.eq(1)
325 with m
.Case(OutSel
.RA
):
326 comb
+= self
.reg_out
.data
.eq(self
.dec
.RA
)
327 comb
+= self
.reg_out
.ok
.eq(1)
328 with m
.Case(OutSel
.SPR
):
329 spr
= Signal(10, reset_less
=True)
330 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
331 # MFSPR move to SPRs - needs mapping
332 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
333 comb
+= sprmap
.spr_i
.eq(spr
)
334 comb
+= self
.spr_out
.eq(sprmap
.spr_o
)
335 comb
+= self
.fast_out
.eq(sprmap
.fast_o
)
337 with m
.Switch(op
.internal_op
):
339 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeA
340 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_BCREG
):
341 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
343 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
344 comb
+= self
.fast_out
.ok
.eq(1)
346 # RFID 1st spr (fast)
347 with m
.Case(MicrOp
.OP_RFID
):
348 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
349 comb
+= self
.fast_out
.ok
.eq(1)
354 class DecodeOut2(Elaboratable
):
355 """DecodeOut2 from instruction
357 decodes output registers
360 def __init__(self
, dec
):
362 self
.sel_in
= Signal(OutSel
, reset_less
=True)
363 self
.lk
= Signal(reset_less
=True)
364 self
.insn_in
= Signal(32, reset_less
=True)
365 self
.reg_out
= Data(5, "reg_o")
366 self
.fast_out
= Data(3, "fast_o")
368 def elaborate(self
, platform
):
372 if hasattr(self
.dec
.op
, "upd"):
373 # update mode LD/ST uses read-reg A also as an output
374 with m
.If(self
.dec
.op
.upd
== LDSTMode
.update
):
375 comb
+= self
.reg_out
.eq(self
.dec
.RA
)
376 comb
+= self
.reg_out
.ok
.eq(1)
378 # B, BC or BCREG: potential implicit register (LR) output
379 # these give bl, bcl, bclrl, etc.
381 with m
.Switch(op
.internal_op
):
383 # BC* implicit register (LR)
384 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_B
, MicrOp
.OP_BCREG
):
385 with m
.If(self
.lk
): # "link" mode
386 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
) # constant: LR
387 comb
+= self
.fast_out
.ok
.eq(1)
389 # RFID 2nd spr (fast)
390 with m
.Case(MicrOp
.OP_RFID
):
391 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
392 comb
+= self
.fast_out
.ok
.eq(1)
397 class DecodeRC(Elaboratable
):
398 """DecodeRc from instruction
400 decodes Record bit Rc
403 def __init__(self
, dec
):
405 self
.sel_in
= Signal(RC
, reset_less
=True)
406 self
.insn_in
= Signal(32, reset_less
=True)
407 self
.rc_out
= Data(1, "rc")
409 def elaborate(self
, platform
):
413 # select Record bit out field
414 with m
.Switch(self
.sel_in
):
416 comb
+= self
.rc_out
.data
.eq(self
.dec
.Rc
)
417 comb
+= self
.rc_out
.ok
.eq(1)
419 comb
+= self
.rc_out
.data
.eq(1)
420 comb
+= self
.rc_out
.ok
.eq(1)
421 with m
.Case(RC
.NONE
):
422 comb
+= self
.rc_out
.data
.eq(0)
423 comb
+= self
.rc_out
.ok
.eq(1)
428 class DecodeOE(Elaboratable
):
429 """DecodeOE from instruction
431 decodes OE field: uses RC decode detection which might not be good
433 -- For now, use "rc" in the decode table to decide whether oe exists.
434 -- This is not entirely correct architecturally: For mulhd and
435 -- mulhdu, the OE field is reserved. It remains to be seen what an
436 -- actual POWER9 does if we set it on those instructions, for now we
437 -- test that further down when assigning to the multiplier oe input.
440 def __init__(self
, dec
):
442 self
.sel_in
= Signal(RC
, reset_less
=True)
443 self
.insn_in
= Signal(32, reset_less
=True)
444 self
.oe_out
= Data(1, "oe")
446 def elaborate(self
, platform
):
451 with m
.Switch(op
.internal_op
):
453 # mulhw, mulhwu, mulhd, mulhdu - these *ignore* OE
455 # XXX ARGH! ignoring OE causes incompatibility with microwatt
456 # http://lists.libre-soc.org/pipermail/libre-soc-dev/2020-August/000302.html
457 with m
.Case(MicrOp
.OP_MUL_H64
, MicrOp
.OP_MUL_H32
,
458 MicrOp
.OP_EXTS
, MicrOp
.OP_CNTZ
,
459 MicrOp
.OP_SHL
, MicrOp
.OP_SHR
, MicrOp
.OP_RLC
,
460 MicrOp
.OP_LOAD
, MicrOp
.OP_STORE
,
461 MicrOp
.OP_RLCL
, MicrOp
.OP_RLCR
,
465 # all other ops decode OE field
467 # select OE bit out field
468 with m
.Switch(self
.sel_in
):
470 comb
+= self
.oe_out
.data
.eq(self
.dec
.OE
)
471 comb
+= self
.oe_out
.ok
.eq(1)
476 class DecodeCRIn(Elaboratable
):
477 """Decodes input CR from instruction
479 CR indices - insn fields - (not the data *in* the CR) require only 3
480 bits because they refer to CR0-CR7
483 def __init__(self
, dec
):
485 self
.sel_in
= Signal(CRInSel
, reset_less
=True)
486 self
.insn_in
= Signal(32, reset_less
=True)
487 self
.cr_bitfield
= Data(3, "cr_bitfield")
488 self
.cr_bitfield_b
= Data(3, "cr_bitfield_b")
489 self
.cr_bitfield_o
= Data(3, "cr_bitfield_o")
490 self
.whole_reg
= Data(8, "cr_fxm")
492 def elaborate(self
, platform
):
494 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
500 comb
+= self
.cr_bitfield
.ok
.eq(0)
501 comb
+= self
.cr_bitfield_b
.ok
.eq(0)
502 comb
+= self
.whole_reg
.ok
.eq(0)
503 with m
.Switch(self
.sel_in
):
504 with m
.Case(CRInSel
.NONE
):
505 pass # No bitfield activated
506 with m
.Case(CRInSel
.CR0
):
507 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
508 comb
+= self
.cr_bitfield
.ok
.eq(1)
509 with m
.Case(CRInSel
.BI
):
510 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BI
[2:5])
511 comb
+= self
.cr_bitfield
.ok
.eq(1)
512 with m
.Case(CRInSel
.BFA
):
513 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BFA
)
514 comb
+= self
.cr_bitfield
.ok
.eq(1)
515 with m
.Case(CRInSel
.BA_BB
):
516 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BA
[2:5])
517 comb
+= self
.cr_bitfield
.ok
.eq(1)
518 comb
+= self
.cr_bitfield_b
.data
.eq(self
.dec
.BB
[2:5])
519 comb
+= self
.cr_bitfield_b
.ok
.eq(1)
520 comb
+= self
.cr_bitfield_o
.data
.eq(self
.dec
.BT
[2:5])
521 comb
+= self
.cr_bitfield_o
.ok
.eq(1)
522 with m
.Case(CRInSel
.BC
):
523 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BC
[2:5])
524 comb
+= self
.cr_bitfield
.ok
.eq(1)
525 with m
.Case(CRInSel
.WHOLE_REG
):
526 comb
+= self
.whole_reg
.ok
.eq(1)
527 move_one
= Signal(reset_less
=True)
528 comb
+= move_one
.eq(self
.insn_in
[20]) # MSB0 bit 11
529 with m
.If((op
.internal_op
== MicrOp
.OP_MFCR
) & move_one
):
530 # must one-hot the FXM field
531 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
532 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
534 # otherwise use all of it
535 comb
+= self
.whole_reg
.data
.eq(0xff)
540 class DecodeCROut(Elaboratable
):
541 """Decodes input CR from instruction
543 CR indices - insn fields - (not the data *in* the CR) require only 3
544 bits because they refer to CR0-CR7
547 def __init__(self
, dec
):
549 self
.rc_in
= Signal(reset_less
=True)
550 self
.sel_in
= Signal(CROutSel
, reset_less
=True)
551 self
.insn_in
= Signal(32, reset_less
=True)
552 self
.cr_bitfield
= Data(3, "cr_bitfield")
553 self
.whole_reg
= Data(8, "cr_fxm")
555 def elaborate(self
, platform
):
559 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
562 comb
+= self
.cr_bitfield
.ok
.eq(0)
563 comb
+= self
.whole_reg
.ok
.eq(0)
564 with m
.Switch(self
.sel_in
):
565 with m
.Case(CROutSel
.NONE
):
566 pass # No bitfield activated
567 with m
.Case(CROutSel
.CR0
):
568 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
569 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
570 with m
.Case(CROutSel
.BF
):
571 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BF
)
572 comb
+= self
.cr_bitfield
.ok
.eq(1)
573 with m
.Case(CROutSel
.BT
):
574 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormXL
.BT
[2:5])
575 comb
+= self
.cr_bitfield
.ok
.eq(1)
576 with m
.Case(CROutSel
.WHOLE_REG
):
577 comb
+= self
.whole_reg
.ok
.eq(1)
578 move_one
= Signal(reset_less
=True)
579 comb
+= move_one
.eq(self
.insn_in
[20])
580 with m
.If((op
.internal_op
== MicrOp
.OP_MTCRF
)):
582 # must one-hot the FXM field
583 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
584 with m
.If(ppick
.en_o
):
585 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
587 comb
+= self
.whole_reg
.data
.eq(0b00000001) # CR7
589 comb
+= self
.whole_reg
.data
.eq(self
.dec
.FXM
)
591 # otherwise use all of it
592 comb
+= self
.whole_reg
.data
.eq(0xff)
596 # dictionary of Input Record field names that, if they exist,
597 # will need a corresponding CSV Decoder file column (actually, PowerOp)
598 # to be decoded (this includes the single bit names)
599 record_names
= {'insn_type': 'internal_op',
600 'fn_unit': 'function_unit',
604 'imm_data': 'in2_sel',
605 'invert_in': 'inv_a',
606 'invert_out': 'inv_out',
609 'output_carry': 'cry_out',
610 'input_carry': 'cry_in',
611 'is_32bit': 'is_32b',
614 'data_len': 'ldst_len',
615 'byte_reverse': 'br',
616 'sign_extend': 'sgn_ext',
620 class PowerDecodeSubset(Elaboratable
):
621 """PowerDecodeSubset: dynamic subset decoder
625 def __init__(self
, dec
, opkls
=None, fn_name
=None,
626 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
)
635 dec
= create_pdecode(name
=fn_name
, col_subset
=col_subset
,
636 row_subset
=self
.rowsubsetfn
)
639 # state information needed by the Decoder
641 state
= CoreState("dec2")
644 def get_col_subset(self
, do
):
645 subset
= {'cr_in', 'cr_out', 'rc_sel'} # needed, non-optional
646 for k
, v
in record_names
.items():
649 print ("get_col_subset", self
.fn_name
, do
.fields
, subset
)
652 def rowsubsetfn(self
, opcode
, row
):
653 return row
['unit'] == self
.fn_name
656 return self
.dec
.ports() + self
.e
.ports()
658 def needs_field(self
, field
, op_field
):
663 return hasattr(do
, field
) and self
.op_get(op_field
) is not None
665 def do_copy(self
, field
, val
, final
=False):
666 if final
or self
.final
:
670 if hasattr(do
, field
) and val
is not None:
671 return getattr(do
, field
).eq(val
)
674 def op_get(self
, op_field
):
675 return getattr(self
.dec
.op
, op_field
, None)
677 def elaborate(self
, platform
):
681 e_out
, op
, do_out
= self
.e
, self
.dec
.op
, self
.e
.do
682 msr
, cia
= state
.msr
, state
.pc
684 # fill in for a normal instruction (not an exception)
685 # copy over if non-exception, non-privileged etc. is detected
689 if self
.fn_name
is None:
692 name
= self
.fn_name
+ "tmp"
693 self
.e_tmp
= e
= Decode2ToExecute1Type(name
=name
, opkls
=self
.opkls
)
696 # set up submodule decoders
697 m
.submodules
.dec
= self
.dec
698 m
.submodules
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
699 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
)
700 m
.submodules
.dec_cr_in
= self
.dec_cr_in
= DecodeCRIn(self
.dec
)
701 m
.submodules
.dec_cr_out
= self
.dec_cr_out
= DecodeCROut(self
.dec
)
703 # copy instruction through...
705 dec_rc
.insn_in
, dec_oe
.insn_in
,
706 self
.dec_cr_in
.insn_in
, self
.dec_cr_out
.insn_in
]:
707 comb
+= i
.eq(self
.dec
.opcode_in
)
709 # ...and subdecoders' input fields
710 comb
+= dec_rc
.sel_in
.eq(op
.rc_sel
)
711 comb
+= dec_oe
.sel_in
.eq(op
.rc_sel
) # XXX should be OE sel
712 comb
+= self
.dec_cr_in
.sel_in
.eq(op
.cr_in
)
713 comb
+= self
.dec_cr_out
.sel_in
.eq(op
.cr_out
)
714 comb
+= self
.dec_cr_out
.rc_in
.eq(dec_rc
.rc_out
.data
)
717 comb
+= self
.do_copy("msr", msr
)
718 comb
+= self
.do_copy("cia", cia
)
720 # set up instruction, pick fn unit
721 # no op: defaults to OP_ILLEGAL
722 comb
+= self
.do_copy("insn_type", self
.op_get("internal_op"))
723 comb
+= self
.do_copy("fn_unit", self
.op_get("function_unit"))
726 if self
.needs_field("zero_a", "in1_sel"):
727 m
.submodules
.dec_ai
= dec_ai
= DecodeAImm(self
.dec
)
728 comb
+= dec_ai
.sel_in
.eq(op
.in1_sel
)
729 comb
+= self
.do_copy("zero_a", dec_ai
.immz_out
) # RA==0 detected
730 if self
.needs_field("imm_data", "in2_sel"):
731 m
.submodules
.dec_bi
= dec_bi
= DecodeBImm(self
.dec
)
732 comb
+= dec_bi
.sel_in
.eq(op
.in2_sel
)
733 comb
+= self
.do_copy("imm_data", dec_bi
.imm_out
) # imm in RB
736 comb
+= self
.do_copy("rc", dec_rc
.rc_out
)
737 comb
+= self
.do_copy("oe", dec_oe
.oe_out
)
740 comb
+= self
.do_copy("read_cr_whole", self
.dec_cr_in
.whole_reg
)
741 comb
+= self
.do_copy("write_cr_whole", self
.dec_cr_out
.whole_reg
)
742 comb
+= self
.do_copy("write_cr0", self
.dec_cr_out
.cr_bitfield
.ok
)
744 comb
+= self
.do_copy("input_cr", self
.op_get("cr_in")) # CR in
745 comb
+= self
.do_copy("output_cr", self
.op_get("cr_out")) # CR out
747 # decoded/selected instruction flags
748 comb
+= self
.do_copy("data_len", self
.op_get("ldst_len"))
749 comb
+= self
.do_copy("invert_in", self
.op_get("inv_a"))
750 comb
+= self
.do_copy("invert_out", self
.op_get("inv_out"))
751 comb
+= self
.do_copy("input_carry", self
.op_get("cry_in"))
752 comb
+= self
.do_copy("output_carry", self
.op_get("cry_out"))
753 comb
+= self
.do_copy("is_32bit", self
.op_get("is_32b"))
754 comb
+= self
.do_copy("is_signed", self
.op_get("sgn"))
755 lk
= self
.op_get("lk")
758 comb
+= self
.do_copy("lk", self
.dec
.LK
) # XXX TODO: accessor
760 comb
+= self
.do_copy("byte_reverse", self
.op_get("br"))
761 comb
+= self
.do_copy("sign_extend", self
.op_get("sgn_ext"))
762 comb
+= self
.do_copy("ldst_mode", self
.op_get("upd")) # LD/ST mode
767 class PowerDecode2(PowerDecodeSubset
):
768 """PowerDecode2: the main instruction decoder.
770 whilst PowerDecode is responsible for decoding the actual opcode, this
771 module encapsulates further specialist, sparse information and
772 expansion of fields that is inconvenient to have in the CSV files.
773 for example: the encoding of the immediates, which are detected
774 and expanded out to their full value from an annotated (enum)
777 implicit register usage is also set up, here. for example: OP_BC
778 requires implicitly reading CTR, OP_RFID requires implicitly writing
781 in addition, PowerDecoder2 is responsible for detecting whether
782 instructions are illegal (or privileged) or not, and instead of
783 just leaving at that, *replacing* the instruction to execute with
784 a suitable alternative (trap).
787 def get_col_subset(self
, opkls
):
788 subset
= super().get_col_subset(opkls
)
789 subset
.add("in1_sel")
790 subset
.add("in2_sel")
791 subset
.add("in3_sel")
792 subset
.add("out_sel")
794 subset
.add("internal_op")
798 def elaborate(self
, platform
):
799 m
= super().elaborate(platform
)
802 e_out
, op
, do_out
= self
.e
, self
.dec
.op
, self
.e
.do
803 dec_spr
, msr
, cia
, ext_irq
= state
.dec
, state
.msr
, state
.pc
, state
.eint
807 # fill in for a normal instruction (not an exception)
808 # copy over if non-exception, non-privileged etc. is detected
810 # set up submodule decoders
811 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
)
812 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
)
813 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
)
814 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
)
815 m
.submodules
.dec_o2
= dec_o2
= DecodeOut2(self
.dec
)
817 # copy instruction through...
818 for i
in [do
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
819 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
]:
820 comb
+= i
.eq(self
.dec
.opcode_in
)
822 # ...and subdecoders' input fields
823 comb
+= dec_a
.sel_in
.eq(op
.in1_sel
)
824 comb
+= dec_b
.sel_in
.eq(op
.in2_sel
)
825 comb
+= dec_c
.sel_in
.eq(op
.in3_sel
)
826 comb
+= dec_o
.sel_in
.eq(op
.out_sel
)
827 comb
+= dec_o2
.sel_in
.eq(op
.out_sel
)
828 if hasattr(do
, "lk"):
829 comb
+= dec_o2
.lk
.eq(do
.lk
)
831 # registers a, b, c and out and out2 (LD/ST EA)
832 comb
+= e
.read_reg1
.eq(dec_a
.reg_out
)
833 comb
+= e
.read_reg2
.eq(dec_b
.reg_out
)
834 comb
+= e
.read_reg3
.eq(dec_c
.reg_out
)
835 comb
+= e
.write_reg
.eq(dec_o
.reg_out
)
836 comb
+= e
.write_ea
.eq(dec_o2
.reg_out
)
839 comb
+= e
.read_spr1
.eq(dec_a
.spr_out
)
840 comb
+= e
.write_spr
.eq(dec_o
.spr_out
)
843 comb
+= e
.read_fast1
.eq(dec_a
.fast_out
)
844 comb
+= e
.read_fast2
.eq(dec_b
.fast_out
)
845 comb
+= e
.write_fast1
.eq(dec_o
.fast_out
)
846 comb
+= e
.write_fast2
.eq(dec_o2
.fast_out
)
848 # condition registers (CR)
849 comb
+= e
.read_cr1
.eq(self
.dec_cr_in
.cr_bitfield
)
850 comb
+= e
.read_cr2
.eq(self
.dec_cr_in
.cr_bitfield_b
)
851 comb
+= e
.read_cr3
.eq(self
.dec_cr_in
.cr_bitfield_o
)
852 comb
+= e
.write_cr
.eq(self
.dec_cr_out
.cr_bitfield
)
854 # sigh this is exactly the sort of thing for which the
855 # decoder is designed to not need. MTSPR, MFSPR and others need
856 # access to the XER bits. however setting e.oe is not appropriate
857 with m
.If(op
.internal_op
== MicrOp
.OP_MFSPR
):
858 comb
+= e
.xer_in
.eq(0b111) # SO, CA, OV
859 with m
.If(op
.internal_op
== MicrOp
.OP_CMP
):
860 comb
+= e
.xer_in
.eq(1<<XERRegs
.SO
) # SO
861 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
862 comb
+= e
.xer_out
.eq(1)
864 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
865 with m
.If(op
.internal_op
== MicrOp
.OP_TRAP
):
866 # *DO NOT* call self.trap here. that would reset absolutely
867 # everything including destroying read of RA and RB.
868 comb
+= self
.do_copy("trapaddr", 0x70) # strip first nibble
871 # ok so the instruction's been decoded, blah blah, however
872 # now we need to determine if it's actually going to go ahead...
873 # *or* if in fact it's a privileged operation, whether there's
874 # an external interrupt, etc. etc. this is a simple priority
875 # if-elif-elif sequence. decrement takes highest priority,
876 # EINT next highest, privileged operation third.
878 # check if instruction is privileged
879 is_priv_insn
= instr_is_priv(m
, op
.internal_op
, e
.do
.insn
)
881 # different IRQ conditions
882 ext_irq_ok
= Signal()
883 dec_irq_ok
= Signal()
887 comb
+= ext_irq_ok
.eq(ext_irq
& msr
[MSR
.EE
]) # v3.0B p944 (MSR.EE)
888 comb
+= dec_irq_ok
.eq(dec_spr
[63] & msr
[MSR
.EE
]) # v3.0B 6.5.11 p1076
889 comb
+= priv_ok
.eq(is_priv_insn
& msr
[MSR
.PR
])
890 comb
+= illeg_ok
.eq(op
.internal_op
== MicrOp
.OP_ILLEGAL
)
892 # decrement counter (v3.0B p1099): TODO 32-bit version (MSR.LPCR)
893 with m
.If(dec_irq_ok
):
894 self
.trap(m
, TT
.DEC
, 0x900) # v3.0B 6.5 p1065
896 # external interrupt? only if MSR.EE set
897 with m
.Elif(ext_irq_ok
):
898 self
.trap(m
, TT
.EINT
, 0x500)
900 # privileged instruction trap
901 with m
.Elif(priv_ok
):
902 self
.trap(m
, TT
.PRIV
, 0x700)
904 # illegal instruction must redirect to trap. this is done by
905 # *overwriting* the decoded instruction and starting again.
906 # (note: the same goes for interrupts and for privileged operations,
907 # just with different trapaddr and traptype)
908 with m
.Elif(illeg_ok
):
909 # illegal instruction trap
910 self
.trap(m
, TT
.ILLEG
, 0x700)
912 # no exception, just copy things to the output
917 # follow-up after trap/irq to set up SRR0/1
919 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
920 # Note: OP_SC could actually be modified to just be a trap
921 with m
.If((do_out
.insn_type
== MicrOp
.OP_TRAP
) |
922 (do_out
.insn_type
== MicrOp
.OP_SC
)):
923 # TRAP write fast1 = SRR0
924 comb
+= e_out
.write_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
925 comb
+= e_out
.write_fast1
.ok
.eq(1)
926 # TRAP write fast2 = SRR1
927 comb
+= e_out
.write_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
928 comb
+= e_out
.write_fast2
.ok
.eq(1)
930 # RFID: needs to read SRR0/1
931 with m
.If(do_out
.insn_type
== MicrOp
.OP_RFID
):
932 # TRAP read fast1 = SRR0
933 comb
+= e_out
.read_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
934 comb
+= e_out
.read_fast1
.ok
.eq(1)
935 # TRAP read fast2 = SRR1
936 comb
+= e_out
.read_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
937 comb
+= e_out
.read_fast2
.ok
.eq(1)
941 def trap(self
, m
, traptype
, trapaddr
):
942 """trap: this basically "rewrites" the decoded instruction as a trap
945 op
, e
= self
.dec
.op
, self
.e
946 comb
+= e
.eq(0) # reset eeeeeverything
949 comb
+= self
.do_copy("insn", self
.dec
.opcode_in
, True)
950 comb
+= self
.do_copy("insn_type", MicrOp
.OP_TRAP
, True)
951 comb
+= self
.do_copy("fn_unit", Function
.TRAP
, True)
952 comb
+= self
.do_copy("trapaddr", trapaddr
>> 4, True) # bottom 4 bits
953 comb
+= self
.do_copy("traptype", traptype
, True) # request type
954 comb
+= self
.do_copy("msr", self
.state
.msr
, True) # copy of MSR "state"
955 comb
+= self
.do_copy("cia", self
.state
.pc
, True) # copy of PC "state"
958 def get_rdflags(e
, cu
):
960 for idx
in range(cu
.n_src
):
961 regfile
, regname
, _
= cu
.get_in_spec(idx
)
962 rdflag
, read
= regspec_decode_read(e
, regfile
, regname
)
964 print("rdflags", rdl
)
968 if __name__
== '__main__':
969 pdecode
= create_pdecode()
970 dec2
= PowerDecode2(pdecode
)
971 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
972 with
open("dec2.il", "w") as f
: