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 # update mode LD/ST uses read-reg A also as an output
373 with m
.If(self
.dec
.op
.upd
== LDSTMode
.update
):
374 comb
+= self
.reg_out
.eq(self
.dec
.RA
)
375 comb
+= self
.reg_out
.ok
.eq(1)
377 # B, BC or BCREG: potential implicit register (LR) output
378 # these give bl, bcl, bclrl, etc.
380 with m
.Switch(op
.internal_op
):
382 # BC* implicit register (LR)
383 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_B
, MicrOp
.OP_BCREG
):
384 with m
.If(self
.lk
): # "link" mode
385 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
) # constant: LR
386 comb
+= self
.fast_out
.ok
.eq(1)
388 # RFID 2nd spr (fast)
389 with m
.Case(MicrOp
.OP_RFID
):
390 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
391 comb
+= self
.fast_out
.ok
.eq(1)
396 class DecodeRC(Elaboratable
):
397 """DecodeRc from instruction
399 decodes Record bit Rc
402 def __init__(self
, dec
):
404 self
.sel_in
= Signal(RC
, reset_less
=True)
405 self
.insn_in
= Signal(32, reset_less
=True)
406 self
.rc_out
= Data(1, "rc")
408 def elaborate(self
, platform
):
412 # select Record bit out field
413 with m
.Switch(self
.sel_in
):
415 comb
+= self
.rc_out
.data
.eq(self
.dec
.Rc
)
416 comb
+= self
.rc_out
.ok
.eq(1)
418 comb
+= self
.rc_out
.data
.eq(1)
419 comb
+= self
.rc_out
.ok
.eq(1)
420 with m
.Case(RC
.NONE
):
421 comb
+= self
.rc_out
.data
.eq(0)
422 comb
+= self
.rc_out
.ok
.eq(1)
427 class DecodeOE(Elaboratable
):
428 """DecodeOE from instruction
430 decodes OE field: uses RC decode detection which might not be good
432 -- For now, use "rc" in the decode table to decide whether oe exists.
433 -- This is not entirely correct architecturally: For mulhd and
434 -- mulhdu, the OE field is reserved. It remains to be seen what an
435 -- actual POWER9 does if we set it on those instructions, for now we
436 -- test that further down when assigning to the multiplier oe input.
439 def __init__(self
, dec
):
441 self
.sel_in
= Signal(RC
, reset_less
=True)
442 self
.insn_in
= Signal(32, reset_less
=True)
443 self
.oe_out
= Data(1, "oe")
445 def elaborate(self
, platform
):
450 with m
.Switch(op
.internal_op
):
452 # mulhw, mulhwu, mulhd, mulhdu - these *ignore* OE
454 # XXX ARGH! ignoring OE causes incompatibility with microwatt
455 # http://lists.libre-soc.org/pipermail/libre-soc-dev/2020-August/000302.html
456 with m
.Case(MicrOp
.OP_MUL_H64
, MicrOp
.OP_MUL_H32
,
457 MicrOp
.OP_EXTS
, MicrOp
.OP_CNTZ
,
458 MicrOp
.OP_SHL
, MicrOp
.OP_SHR
, MicrOp
.OP_RLC
,
459 MicrOp
.OP_LOAD
, MicrOp
.OP_STORE
,
460 MicrOp
.OP_RLCL
, MicrOp
.OP_RLCR
,
464 # all other ops decode OE field
466 # select OE bit out field
467 with m
.Switch(self
.sel_in
):
469 comb
+= self
.oe_out
.data
.eq(self
.dec
.OE
)
470 comb
+= self
.oe_out
.ok
.eq(1)
475 class DecodeCRIn(Elaboratable
):
476 """Decodes input CR from instruction
478 CR indices - insn fields - (not the data *in* the CR) require only 3
479 bits because they refer to CR0-CR7
482 def __init__(self
, dec
):
484 self
.sel_in
= Signal(CRInSel
, reset_less
=True)
485 self
.insn_in
= Signal(32, reset_less
=True)
486 self
.cr_bitfield
= Data(3, "cr_bitfield")
487 self
.cr_bitfield_b
= Data(3, "cr_bitfield_b")
488 self
.cr_bitfield_o
= Data(3, "cr_bitfield_o")
489 self
.whole_reg
= Data(8, "cr_fxm")
491 def elaborate(self
, platform
):
493 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
499 comb
+= self
.cr_bitfield
.ok
.eq(0)
500 comb
+= self
.cr_bitfield_b
.ok
.eq(0)
501 comb
+= self
.whole_reg
.ok
.eq(0)
502 with m
.Switch(self
.sel_in
):
503 with m
.Case(CRInSel
.NONE
):
504 pass # No bitfield activated
505 with m
.Case(CRInSel
.CR0
):
506 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
507 comb
+= self
.cr_bitfield
.ok
.eq(1)
508 with m
.Case(CRInSel
.BI
):
509 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BI
[2:5])
510 comb
+= self
.cr_bitfield
.ok
.eq(1)
511 with m
.Case(CRInSel
.BFA
):
512 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BFA
)
513 comb
+= self
.cr_bitfield
.ok
.eq(1)
514 with m
.Case(CRInSel
.BA_BB
):
515 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BA
[2:5])
516 comb
+= self
.cr_bitfield
.ok
.eq(1)
517 comb
+= self
.cr_bitfield_b
.data
.eq(self
.dec
.BB
[2:5])
518 comb
+= self
.cr_bitfield_b
.ok
.eq(1)
519 comb
+= self
.cr_bitfield_o
.data
.eq(self
.dec
.BT
[2:5])
520 comb
+= self
.cr_bitfield_o
.ok
.eq(1)
521 with m
.Case(CRInSel
.BC
):
522 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BC
[2:5])
523 comb
+= self
.cr_bitfield
.ok
.eq(1)
524 with m
.Case(CRInSel
.WHOLE_REG
):
525 comb
+= self
.whole_reg
.ok
.eq(1)
526 move_one
= Signal(reset_less
=True)
527 comb
+= move_one
.eq(self
.insn_in
[20]) # MSB0 bit 11
528 with m
.If((op
.internal_op
== MicrOp
.OP_MFCR
) & move_one
):
529 # must one-hot the FXM field
530 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
531 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
533 # otherwise use all of it
534 comb
+= self
.whole_reg
.data
.eq(0xff)
539 class DecodeCROut(Elaboratable
):
540 """Decodes input CR from instruction
542 CR indices - insn fields - (not the data *in* the CR) require only 3
543 bits because they refer to CR0-CR7
546 def __init__(self
, dec
):
548 self
.rc_in
= Signal(reset_less
=True)
549 self
.sel_in
= Signal(CROutSel
, reset_less
=True)
550 self
.insn_in
= Signal(32, reset_less
=True)
551 self
.cr_bitfield
= Data(3, "cr_bitfield")
552 self
.whole_reg
= Data(8, "cr_fxm")
554 def elaborate(self
, platform
):
558 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
561 comb
+= self
.cr_bitfield
.ok
.eq(0)
562 comb
+= self
.whole_reg
.ok
.eq(0)
563 with m
.Switch(self
.sel_in
):
564 with m
.Case(CROutSel
.NONE
):
565 pass # No bitfield activated
566 with m
.Case(CROutSel
.CR0
):
567 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
568 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
569 with m
.Case(CROutSel
.BF
):
570 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BF
)
571 comb
+= self
.cr_bitfield
.ok
.eq(1)
572 with m
.Case(CROutSel
.BT
):
573 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormXL
.BT
[2:5])
574 comb
+= self
.cr_bitfield
.ok
.eq(1)
575 with m
.Case(CROutSel
.WHOLE_REG
):
576 comb
+= self
.whole_reg
.ok
.eq(1)
577 move_one
= Signal(reset_less
=True)
578 comb
+= move_one
.eq(self
.insn_in
[20])
579 with m
.If((op
.internal_op
== MicrOp
.OP_MTCRF
)):
581 # must one-hot the FXM field
582 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
583 with m
.If(ppick
.en_o
):
584 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
586 comb
+= self
.whole_reg
.data
.eq(0b00000001) # CR7
588 comb
+= self
.whole_reg
.data
.eq(self
.dec
.FXM
)
590 # otherwise use all of it
591 comb
+= self
.whole_reg
.data
.eq(0xff)
596 class PowerDecodeSubset(Elaboratable
):
597 """PowerDecodeSubset: dynamic subset decoder
601 def __init__(self
, dec
, opkls
=None, fn_name
=None, col_subset
=None,
602 final
=False, state
=None):
607 self
.fn_name
= fn_name
608 self
.dec
= create_pdecode(name
=fn_name
, col_subset
=col_subset
,
609 row_subset
=self
.rowsubsetfn
)
614 self
.e
= Decode2ToExecute1Type(name
=self
.fn_name
, opkls
=self
.opkls
)
616 # state information needed by the Decoder
617 if state
is not None:
620 self
.state
= CoreState("dec2")
622 def rowsubsetfn(self
, opcode
, row
):
623 return row
['unit'] == self
.fn_name
626 return self
.dec
.ports() + self
.e
.ports()
628 def needs_field(self
, field
, op_field
):
633 return hasattr(do
, field
) and self
.op_get(op_field
) is not None
635 def do_copy(self
, field
, val
, final
=False):
636 if final
or self
.final
:
640 if hasattr(do
, field
) and val
is not None:
641 return getattr(do
, field
).eq(val
)
644 def op_get(self
, op_field
):
645 return getattr(self
.dec
.op
, op_field
, None)
647 def elaborate(self
, platform
):
651 e_out
, op
, do_out
= self
.e
, self
.dec
.op
, self
.e
.do
652 dec_spr
, msr
, cia
, ext_irq
= state
.dec
, state
.msr
, state
.pc
, state
.eint
654 # fill in for a normal instruction (not an exception)
655 # copy over if non-exception, non-privileged etc. is detected
659 if self
.fn_name
is None:
662 name
= self
.fn_name
+ "tmp"
663 self
.e_tmp
= e
= Decode2ToExecute1Type(name
=name
, opkls
=self
.opkls
)
666 # set up submodule decoders
667 m
.submodules
.dec
= self
.dec
668 m
.submodules
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
669 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
)
670 m
.submodules
.dec_cr_in
= self
.dec_cr_in
= DecodeCRIn(self
.dec
)
671 m
.submodules
.dec_cr_out
= self
.dec_cr_out
= DecodeCROut(self
.dec
)
673 # copy instruction through...
675 dec_rc
.insn_in
, dec_oe
.insn_in
,
676 self
.dec_cr_in
.insn_in
, self
.dec_cr_out
.insn_in
]:
677 comb
+= i
.eq(self
.dec
.opcode_in
)
679 # ...and subdecoders' input fields
680 comb
+= dec_rc
.sel_in
.eq(op
.rc_sel
)
681 comb
+= dec_oe
.sel_in
.eq(op
.rc_sel
) # XXX should be OE sel
682 comb
+= self
.dec_cr_in
.sel_in
.eq(op
.cr_in
)
683 comb
+= self
.dec_cr_out
.sel_in
.eq(op
.cr_out
)
684 comb
+= self
.dec_cr_out
.rc_in
.eq(dec_rc
.rc_out
.data
)
687 comb
+= self
.do_copy("msr", msr
)
688 comb
+= self
.do_copy("cia", cia
)
690 # set up instruction, pick fn unit
691 # no op: defaults to OP_ILLEGAL
692 comb
+= self
.do_copy("insn_type", self
.op_get("internal_op"))
693 comb
+= self
.do_copy("fn_unit", self
.op_get("function_unit"))
696 if self
.needs_field("zero_a", "in1_sel"):
697 m
.submodules
.dec_ai
= dec_ai
= DecodeAImm(self
.dec
)
698 comb
+= dec_ai
.sel_in
.eq(op
.in1_sel
)
699 comb
+= self
.do_copy("zero_a", dec_ai
.immz_out
) # RA==0 detected
700 if self
.needs_field("imm_data", "in2_sel"):
701 m
.submodules
.dec_bi
= dec_bi
= DecodeBImm(self
.dec
)
702 comb
+= dec_bi
.sel_in
.eq(op
.in2_sel
)
703 comb
+= self
.do_copy("imm_data", dec_bi
.imm_out
) # imm in RB
706 comb
+= self
.do_copy("rc", dec_rc
.rc_out
)
707 comb
+= self
.do_copy("oe", dec_oe
.oe_out
)
710 comb
+= self
.do_copy("read_cr_whole", self
.dec_cr_in
.whole_reg
)
711 comb
+= self
.do_copy("write_cr_whole", self
.dec_cr_out
.whole_reg
)
712 comb
+= self
.do_copy("write_cr0", self
.dec_cr_out
.cr_bitfield
.ok
)
714 comb
+= self
.do_copy("input_cr", self
.op_get("cr_in")) # CR in
715 comb
+= self
.do_copy("output_cr", self
.op_get("cr_out")) # CR out
717 # decoded/selected instruction flags
718 comb
+= self
.do_copy("data_len", self
.op_get("ldst_len"))
719 comb
+= self
.do_copy("invert_in", self
.op_get("inv_a"))
720 comb
+= self
.do_copy("invert_out", self
.op_get("inv_out"))
721 comb
+= self
.do_copy("input_carry", self
.op_get("cry_in"))
722 comb
+= self
.do_copy("output_carry", self
.op_get("cry_out"))
723 comb
+= self
.do_copy("is_32bit", self
.op_get("is_32b"))
724 comb
+= self
.do_copy("is_signed", self
.op_get("sgn"))
725 lk
= self
.op_get("lk")
728 comb
+= self
.do_copy("lk", self
.dec
.LK
) # XXX TODO: accessor
730 comb
+= self
.do_copy("byte_reverse", self
.op_get("br"))
731 comb
+= self
.do_copy("sign_extend", self
.op_get("sgn_ext"))
732 comb
+= self
.do_copy("ldst_mode", self
.op_get("upd")) # LD/ST mode
737 class PowerDecode2(PowerDecodeSubset
):
738 """PowerDecode2: the main instruction decoder.
740 whilst PowerDecode is responsible for decoding the actual opcode, this
741 module encapsulates further specialist, sparse information and
742 expansion of fields that is inconvenient to have in the CSV files.
743 for example: the encoding of the immediates, which are detected
744 and expanded out to their full value from an annotated (enum)
747 implicit register usage is also set up, here. for example: OP_BC
748 requires implicitly reading CTR, OP_RFID requires implicitly writing
751 in addition, PowerDecoder2 is responsible for detecting whether
752 instructions are illegal (or privileged) or not, and instead of
753 just leaving at that, *replacing* the instruction to execute with
754 a suitable alternative (trap).
757 def elaborate(self
, platform
):
758 m
= super().elaborate(platform
)
761 e_out
, op
, do_out
= self
.e
, self
.dec
.op
, self
.e
.do
762 dec_spr
, msr
, cia
, ext_irq
= state
.dec
, state
.msr
, state
.pc
, state
.eint
766 # fill in for a normal instruction (not an exception)
767 # copy over if non-exception, non-privileged etc. is detected
769 # set up submodule decoders
770 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
)
771 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
)
772 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
)
773 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
)
774 m
.submodules
.dec_o2
= dec_o2
= DecodeOut2(self
.dec
)
776 # copy instruction through...
777 for i
in [do
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
778 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
]:
779 comb
+= i
.eq(self
.dec
.opcode_in
)
781 # ...and subdecoders' input fields
782 comb
+= dec_a
.sel_in
.eq(op
.in1_sel
)
783 comb
+= dec_b
.sel_in
.eq(op
.in2_sel
)
784 comb
+= dec_c
.sel_in
.eq(op
.in3_sel
)
785 comb
+= dec_o
.sel_in
.eq(op
.out_sel
)
786 comb
+= dec_o2
.sel_in
.eq(op
.out_sel
)
787 if hasattr(do
, "lk"):
788 comb
+= dec_o2
.lk
.eq(do
.lk
)
790 # registers a, b, c and out and out2 (LD/ST EA)
791 comb
+= e
.read_reg1
.eq(dec_a
.reg_out
)
792 comb
+= e
.read_reg2
.eq(dec_b
.reg_out
)
793 comb
+= e
.read_reg3
.eq(dec_c
.reg_out
)
794 comb
+= e
.write_reg
.eq(dec_o
.reg_out
)
795 comb
+= e
.write_ea
.eq(dec_o2
.reg_out
)
798 comb
+= e
.read_spr1
.eq(dec_a
.spr_out
)
799 comb
+= e
.write_spr
.eq(dec_o
.spr_out
)
802 comb
+= e
.read_fast1
.eq(dec_a
.fast_out
)
803 comb
+= e
.read_fast2
.eq(dec_b
.fast_out
)
804 comb
+= e
.write_fast1
.eq(dec_o
.fast_out
)
805 comb
+= e
.write_fast2
.eq(dec_o2
.fast_out
)
807 # condition registers (CR)
808 comb
+= e
.read_cr1
.eq(self
.dec_cr_in
.cr_bitfield
)
809 comb
+= e
.read_cr2
.eq(self
.dec_cr_in
.cr_bitfield_b
)
810 comb
+= e
.read_cr3
.eq(self
.dec_cr_in
.cr_bitfield_o
)
811 comb
+= e
.write_cr
.eq(self
.dec_cr_out
.cr_bitfield
)
813 # sigh this is exactly the sort of thing for which the
814 # decoder is designed to not need. MTSPR, MFSPR and others need
815 # access to the XER bits. however setting e.oe is not appropriate
816 with m
.If(op
.internal_op
== MicrOp
.OP_MFSPR
):
817 comb
+= e
.xer_in
.eq(0b111) # SO, CA, OV
818 with m
.If(op
.internal_op
== MicrOp
.OP_CMP
):
819 comb
+= e
.xer_in
.eq(1<<XERRegs
.SO
) # SO
820 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
821 comb
+= e
.xer_out
.eq(1)
823 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
824 with m
.If(op
.internal_op
== MicrOp
.OP_TRAP
):
825 # *DO NOT* call self.trap here. that would reset absolutely
826 # everything including destroying read of RA and RB.
827 comb
+= self
.do_copy("trapaddr", 0x70) # strip first nibble
829 # check if instruction is privileged
830 is_priv_insn
= instr_is_priv(m
, op
.internal_op
, e
.do
.insn
)
832 # external interrupt? only if MSR.EE set
833 with m
.If(ext_irq
& msr
[MSR
.EE
]): # v3.0B p944 (MSR.EE)
834 self
.trap(m
, TT
.EINT
, 0x500)
836 # decrement counter (v3.0B p1099): TODO 32-bit version (MSR.LPCR)
837 with m
.If(dec_spr
[63] & msr
[MSR
.EE
]): # v3.0B 6.5.11 p1076
838 self
.trap(m
, TT
.DEC
, 0x900) # v3.0B 6.5 p1065
840 # privileged instruction trap
841 with m
.Elif(is_priv_insn
& msr
[MSR
.PR
]):
842 self
.trap(m
, TT
.PRIV
, 0x700)
844 # illegal instruction must redirect to trap. this is done by
845 # *overwriting* the decoded instruction and starting again.
846 # (note: the same goes for interrupts and for privileged operations,
847 # just with different trapaddr and traptype)
848 with m
.Elif(op
.internal_op
== MicrOp
.OP_ILLEGAL
):
849 # illegal instruction trap
850 self
.trap(m
, TT
.ILLEG
, 0x700)
852 # no exception, just copy things to the output
856 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
857 # Note: OP_SC could actually be modified to just be a trap
858 with m
.If((do_out
.insn_type
== MicrOp
.OP_TRAP
) |
859 (do_out
.insn_type
== MicrOp
.OP_SC
)):
860 # TRAP write fast1 = SRR0
861 comb
+= e_out
.write_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
862 comb
+= e_out
.write_fast1
.ok
.eq(1)
863 # TRAP write fast2 = SRR1
864 comb
+= e_out
.write_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
865 comb
+= e_out
.write_fast2
.ok
.eq(1)
867 # RFID: needs to read SRR0/1
868 with m
.If(do_out
.insn_type
== MicrOp
.OP_RFID
):
869 # TRAP read fast1 = SRR0
870 comb
+= e_out
.read_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
871 comb
+= e_out
.read_fast1
.ok
.eq(1)
872 # TRAP read fast2 = SRR1
873 comb
+= e_out
.read_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
874 comb
+= e_out
.read_fast2
.ok
.eq(1)
878 def trap(self
, m
, traptype
, trapaddr
):
879 """trap: this basically "rewrites" the decoded instruction as a trap
882 op
, e
= self
.dec
.op
, self
.e
883 comb
+= e
.eq(0) # reset eeeeeverything
886 comb
+= self
.do_copy("insn", self
.dec
.opcode_in
, True)
887 comb
+= self
.do_copy("insn_type", MicrOp
.OP_TRAP
, True)
888 comb
+= self
.do_copy("fn_unit", Function
.TRAP
, True)
889 comb
+= self
.do_copy("trapaddr", trapaddr
>> 4, True) # bottom 4 bits
890 comb
+= self
.do_copy("traptype", traptype
, True) # request type
891 comb
+= self
.do_copy("msr", self
.state
.msr
, True) # copy of MSR "state"
892 comb
+= self
.do_copy("cia", self
.state
.pc
, True) # copy of PC "state"
895 def get_rdflags(e
, cu
):
897 for idx
in range(cu
.n_src
):
898 regfile
, regname
, _
= cu
.get_in_spec(idx
)
899 rdflag
, read
= regspec_decode_read(e
, regfile
, regname
)
901 print("rdflags", rdl
)
905 if __name__
== '__main__':
906 pdecode
= create_pdecode()
907 dec2
= PowerDecode2(pdecode
)
908 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
909 with
open("dec2.il", "w") as f
: