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, whether immediate-zero, implicit and
84 def __init__(self
, dec
):
86 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
87 self
.insn_in
= Signal(32, reset_less
=True)
88 self
.reg_out
= Data(5, name
="reg_a")
89 self
.immz_out
= Signal(reset_less
=True)
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 # zero immediate requested
108 with m
.If((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
109 (self
.reg_out
.data
== Const(0, 5))):
110 comb
+= self
.immz_out
.eq(1)
112 # some Logic/ALU ops have RS as the 3rd arg, but no "RA".
113 with m
.If(self
.sel_in
== In1Sel
.RS
):
114 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
115 comb
+= self
.reg_out
.ok
.eq(1)
117 # decode Fast-SPR based on instruction type
119 with m
.Switch(op
.internal_op
):
121 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeOut
122 with m
.Case(MicrOp
.OP_BC
):
123 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
125 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
126 comb
+= self
.fast_out
.ok
.eq(1)
127 with m
.Case(MicrOp
.OP_BCREG
):
128 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
129 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
130 with m
.If(xo9
& ~xo5
):
132 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
133 comb
+= self
.fast_out
.ok
.eq(1)
135 # MFSPR move from SPRs
136 with m
.Case(MicrOp
.OP_MFSPR
):
137 spr
= Signal(10, reset_less
=True)
138 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
139 comb
+= sprmap
.spr_i
.eq(spr
)
140 comb
+= self
.spr_out
.eq(sprmap
.spr_o
)
141 comb
+= self
.fast_out
.eq(sprmap
.fast_o
)
146 class DecodeB(Elaboratable
):
147 """DecodeB from instruction
149 decodes register RB, different forms of immediate (signed, unsigned),
150 and implicit SPRs. register B is basically "lane 2" into the CompUnits.
151 by industry-standard convention, "lane 2" is where fully-decoded
152 immediates are muxed in.
155 def __init__(self
, dec
):
157 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
158 self
.insn_in
= Signal(32, reset_less
=True)
159 self
.reg_out
= Data(5, "reg_b")
160 self
.imm_out
= Data(64, "imm_b")
161 self
.fast_out
= Data(3, "fast_b")
163 def elaborate(self
, platform
):
167 # select Register B field
168 with m
.Switch(self
.sel_in
):
169 with m
.Case(In2Sel
.RB
):
170 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
)
171 comb
+= self
.reg_out
.ok
.eq(1)
172 with m
.Case(In2Sel
.RS
):
173 # for M-Form shiftrot
174 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
175 comb
+= self
.reg_out
.ok
.eq(1)
176 with m
.Case(In2Sel
.CONST_UI
): # unsigned
177 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
)
178 comb
+= self
.imm_out
.ok
.eq(1)
179 with m
.Case(In2Sel
.CONST_SI
): # sign-extended 16-bit
180 si
= Signal(16, reset_less
=True)
181 comb
+= si
.eq(self
.dec
.SI
)
182 comb
+= self
.imm_out
.data
.eq(exts(si
, 16, 64))
183 comb
+= self
.imm_out
.ok
.eq(1)
184 with m
.Case(In2Sel
.CONST_SI_HI
): # sign-extended 16+16=32 bit
185 si_hi
= Signal(32, reset_less
=True)
186 comb
+= si_hi
.eq(self
.dec
.SI
<< 16)
187 comb
+= self
.imm_out
.data
.eq(exts(si_hi
, 32, 64))
188 comb
+= self
.imm_out
.ok
.eq(1)
189 with m
.Case(In2Sel
.CONST_UI_HI
): # unsigned
190 ui
= Signal(16, reset_less
=True)
191 comb
+= ui
.eq(self
.dec
.UI
)
192 comb
+= self
.imm_out
.data
.eq(ui
<< 16)
193 comb
+= self
.imm_out
.ok
.eq(1)
194 with m
.Case(In2Sel
.CONST_LI
): # sign-extend 24+2=26 bit
195 li
= Signal(26, reset_less
=True)
196 comb
+= li
.eq(self
.dec
.LI
<< 2)
197 comb
+= self
.imm_out
.data
.eq(exts(li
, 26, 64))
198 comb
+= self
.imm_out
.ok
.eq(1)
199 with m
.Case(In2Sel
.CONST_BD
): # sign-extend (14+2)=16 bit
200 bd
= Signal(16, reset_less
=True)
201 comb
+= bd
.eq(self
.dec
.BD
<< 2)
202 comb
+= self
.imm_out
.data
.eq(exts(bd
, 16, 64))
203 comb
+= self
.imm_out
.ok
.eq(1)
204 with m
.Case(In2Sel
.CONST_DS
): # sign-extended (14+2=16) bit
205 ds
= Signal(16, reset_less
=True)
206 comb
+= ds
.eq(self
.dec
.DS
<< 2)
207 comb
+= self
.imm_out
.data
.eq(exts(ds
, 16, 64))
208 comb
+= self
.imm_out
.ok
.eq(1)
209 with m
.Case(In2Sel
.CONST_M1
): # signed (-1)
210 comb
+= self
.imm_out
.data
.eq(~
Const(0, 64)) # all 1s
211 comb
+= self
.imm_out
.ok
.eq(1)
212 with m
.Case(In2Sel
.CONST_SH
): # unsigned - for shift
213 comb
+= self
.imm_out
.data
.eq(self
.dec
.sh
)
214 comb
+= self
.imm_out
.ok
.eq(1)
215 with m
.Case(In2Sel
.CONST_SH32
): # unsigned - for shift
216 comb
+= self
.imm_out
.data
.eq(self
.dec
.SH32
)
217 comb
+= self
.imm_out
.ok
.eq(1)
219 # decode SPR2 based on instruction type
221 # BCREG implicitly uses LR or TAR for 2nd reg
222 # CTR however is already in fast_spr1 *not* 2.
223 with m
.If(op
.internal_op
== MicrOp
.OP_BCREG
):
224 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
225 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
227 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
228 comb
+= self
.fast_out
.ok
.eq(1)
230 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
231 comb
+= self
.fast_out
.ok
.eq(1)
236 class DecodeC(Elaboratable
):
237 """DecodeC from instruction
239 decodes register RC. this is "lane 3" into some CompUnits (not many)
242 def __init__(self
, dec
):
244 self
.sel_in
= Signal(In3Sel
, reset_less
=True)
245 self
.insn_in
= Signal(32, reset_less
=True)
246 self
.reg_out
= Data(5, "reg_c")
248 def elaborate(self
, platform
):
252 # select Register C field
253 with m
.Switch(self
.sel_in
):
254 with m
.Case(In3Sel
.RB
):
255 # for M-Form shiftrot
256 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
)
257 comb
+= self
.reg_out
.ok
.eq(1)
258 with m
.Case(In3Sel
.RS
):
259 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
260 comb
+= self
.reg_out
.ok
.eq(1)
265 class DecodeOut(Elaboratable
):
266 """DecodeOut from instruction
268 decodes output register RA, RT or SPR
271 def __init__(self
, dec
):
273 self
.sel_in
= Signal(OutSel
, reset_less
=True)
274 self
.insn_in
= Signal(32, reset_less
=True)
275 self
.reg_out
= Data(5, "reg_o")
276 self
.spr_out
= Data(SPR
, "spr_o")
277 self
.fast_out
= Data(3, "fast_o")
279 def elaborate(self
, platform
):
282 m
.submodules
.sprmap
= sprmap
= SPRMap()
285 # select Register out field
286 with m
.Switch(self
.sel_in
):
287 with m
.Case(OutSel
.RT
):
288 comb
+= self
.reg_out
.data
.eq(self
.dec
.RT
)
289 comb
+= self
.reg_out
.ok
.eq(1)
290 with m
.Case(OutSel
.RA
):
291 comb
+= self
.reg_out
.data
.eq(self
.dec
.RA
)
292 comb
+= self
.reg_out
.ok
.eq(1)
293 with m
.Case(OutSel
.SPR
):
294 spr
= Signal(10, reset_less
=True)
295 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
296 # MFSPR move to SPRs - needs mapping
297 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
298 comb
+= sprmap
.spr_i
.eq(spr
)
299 comb
+= self
.spr_out
.eq(sprmap
.spr_o
)
300 comb
+= self
.fast_out
.eq(sprmap
.fast_o
)
302 with m
.Switch(op
.internal_op
):
304 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeA
305 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_BCREG
):
306 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
308 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
309 comb
+= self
.fast_out
.ok
.eq(1)
311 # RFID 1st spr (fast)
312 with m
.Case(MicrOp
.OP_RFID
):
313 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
314 comb
+= self
.fast_out
.ok
.eq(1)
319 class DecodeOut2(Elaboratable
):
320 """DecodeOut2 from instruction
322 decodes output registers
325 def __init__(self
, dec
):
327 self
.sel_in
= Signal(OutSel
, reset_less
=True)
328 self
.lk
= Signal(reset_less
=True)
329 self
.insn_in
= Signal(32, reset_less
=True)
330 self
.reg_out
= Data(5, "reg_o")
331 self
.fast_out
= Data(3, "fast_o")
333 def elaborate(self
, platform
):
337 # update mode LD/ST uses read-reg A also as an output
338 with m
.If(self
.dec
.op
.upd
== LDSTMode
.update
):
339 comb
+= self
.reg_out
.eq(self
.dec
.RA
)
340 comb
+= self
.reg_out
.ok
.eq(1)
342 # B, BC or BCREG: potential implicit register (LR) output
343 # these give bl, bcl, bclrl, etc.
345 with m
.Switch(op
.internal_op
):
347 # BC* implicit register (LR)
348 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_B
, MicrOp
.OP_BCREG
):
349 with m
.If(self
.lk
): # "link" mode
350 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
) # constant: LR
351 comb
+= self
.fast_out
.ok
.eq(1)
353 # RFID 2nd spr (fast)
354 with m
.Case(MicrOp
.OP_RFID
):
355 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
356 comb
+= self
.fast_out
.ok
.eq(1)
361 class DecodeRC(Elaboratable
):
362 """DecodeRc from instruction
364 decodes Record bit Rc
367 def __init__(self
, dec
):
369 self
.sel_in
= Signal(RC
, reset_less
=True)
370 self
.insn_in
= Signal(32, reset_less
=True)
371 self
.rc_out
= Data(1, "rc")
373 def elaborate(self
, platform
):
377 # select Record bit out field
378 with m
.Switch(self
.sel_in
):
380 comb
+= self
.rc_out
.data
.eq(self
.dec
.Rc
)
381 comb
+= self
.rc_out
.ok
.eq(1)
383 comb
+= self
.rc_out
.data
.eq(1)
384 comb
+= self
.rc_out
.ok
.eq(1)
385 with m
.Case(RC
.NONE
):
386 comb
+= self
.rc_out
.data
.eq(0)
387 comb
+= self
.rc_out
.ok
.eq(1)
392 class DecodeOE(Elaboratable
):
393 """DecodeOE from instruction
395 decodes OE field: uses RC decode detection which might not be good
397 -- For now, use "rc" in the decode table to decide whether oe exists.
398 -- This is not entirely correct architecturally: For mulhd and
399 -- mulhdu, the OE field is reserved. It remains to be seen what an
400 -- actual POWER9 does if we set it on those instructions, for now we
401 -- test that further down when assigning to the multiplier oe input.
404 def __init__(self
, dec
):
406 self
.sel_in
= Signal(RC
, reset_less
=True)
407 self
.insn_in
= Signal(32, reset_less
=True)
408 self
.oe_out
= Data(1, "oe")
410 def elaborate(self
, platform
):
415 with m
.Switch(op
.internal_op
):
417 # mulhw, mulhwu, mulhd, mulhdu - these *ignore* OE
419 # XXX ARGH! ignoring OE causes incompatibility with microwatt
420 # http://lists.libre-soc.org/pipermail/libre-soc-dev/2020-August/000302.html
421 with m
.Case(MicrOp
.OP_MUL_H64
, MicrOp
.OP_MUL_H32
,
422 MicrOp
.OP_EXTS
, MicrOp
.OP_CNTZ
,
423 MicrOp
.OP_SHL
, MicrOp
.OP_SHR
, MicrOp
.OP_RLC
,
424 MicrOp
.OP_LOAD
, MicrOp
.OP_STORE
,
425 MicrOp
.OP_RLCL
, MicrOp
.OP_RLCR
,
429 # all other ops decode OE field
431 # select OE bit out field
432 with m
.Switch(self
.sel_in
):
434 comb
+= self
.oe_out
.data
.eq(self
.dec
.OE
)
435 comb
+= self
.oe_out
.ok
.eq(1)
440 class DecodeCRIn(Elaboratable
):
441 """Decodes input CR from instruction
443 CR indices - insn fields - (not the data *in* the CR) require only 3
444 bits because they refer to CR0-CR7
447 def __init__(self
, dec
):
449 self
.sel_in
= Signal(CRInSel
, reset_less
=True)
450 self
.insn_in
= Signal(32, reset_less
=True)
451 self
.cr_bitfield
= Data(3, "cr_bitfield")
452 self
.cr_bitfield_b
= Data(3, "cr_bitfield_b")
453 self
.cr_bitfield_o
= Data(3, "cr_bitfield_o")
454 self
.whole_reg
= Data(8, "cr_fxm")
456 def elaborate(self
, platform
):
458 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
464 comb
+= self
.cr_bitfield
.ok
.eq(0)
465 comb
+= self
.cr_bitfield_b
.ok
.eq(0)
466 comb
+= self
.whole_reg
.ok
.eq(0)
467 with m
.Switch(self
.sel_in
):
468 with m
.Case(CRInSel
.NONE
):
469 pass # No bitfield activated
470 with m
.Case(CRInSel
.CR0
):
471 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
472 comb
+= self
.cr_bitfield
.ok
.eq(1)
473 with m
.Case(CRInSel
.BI
):
474 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BI
[2:5])
475 comb
+= self
.cr_bitfield
.ok
.eq(1)
476 with m
.Case(CRInSel
.BFA
):
477 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BFA
)
478 comb
+= self
.cr_bitfield
.ok
.eq(1)
479 with m
.Case(CRInSel
.BA_BB
):
480 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BA
[2:5])
481 comb
+= self
.cr_bitfield
.ok
.eq(1)
482 comb
+= self
.cr_bitfield_b
.data
.eq(self
.dec
.BB
[2:5])
483 comb
+= self
.cr_bitfield_b
.ok
.eq(1)
484 comb
+= self
.cr_bitfield_o
.data
.eq(self
.dec
.BT
[2:5])
485 comb
+= self
.cr_bitfield_o
.ok
.eq(1)
486 with m
.Case(CRInSel
.BC
):
487 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BC
[2:5])
488 comb
+= self
.cr_bitfield
.ok
.eq(1)
489 with m
.Case(CRInSel
.WHOLE_REG
):
490 comb
+= self
.whole_reg
.ok
.eq(1)
491 move_one
= Signal(reset_less
=True)
492 comb
+= move_one
.eq(self
.insn_in
[20]) # MSB0 bit 11
493 with m
.If((op
.internal_op
== MicrOp
.OP_MFCR
) & move_one
):
494 # must one-hot the FXM field
495 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
496 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
498 # otherwise use all of it
499 comb
+= self
.whole_reg
.data
.eq(0xff)
504 class DecodeCROut(Elaboratable
):
505 """Decodes input CR from instruction
507 CR indices - insn fields - (not the data *in* the CR) require only 3
508 bits because they refer to CR0-CR7
511 def __init__(self
, dec
):
513 self
.rc_in
= Signal(reset_less
=True)
514 self
.sel_in
= Signal(CROutSel
, reset_less
=True)
515 self
.insn_in
= Signal(32, reset_less
=True)
516 self
.cr_bitfield
= Data(3, "cr_bitfield")
517 self
.whole_reg
= Data(8, "cr_fxm")
519 def elaborate(self
, platform
):
523 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
526 comb
+= self
.cr_bitfield
.ok
.eq(0)
527 comb
+= self
.whole_reg
.ok
.eq(0)
528 with m
.Switch(self
.sel_in
):
529 with m
.Case(CROutSel
.NONE
):
530 pass # No bitfield activated
531 with m
.Case(CROutSel
.CR0
):
532 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
533 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
534 with m
.Case(CROutSel
.BF
):
535 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BF
)
536 comb
+= self
.cr_bitfield
.ok
.eq(1)
537 with m
.Case(CROutSel
.BT
):
538 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormXL
.BT
[2:5])
539 comb
+= self
.cr_bitfield
.ok
.eq(1)
540 with m
.Case(CROutSel
.WHOLE_REG
):
541 comb
+= self
.whole_reg
.ok
.eq(1)
542 move_one
= Signal(reset_less
=True)
543 comb
+= move_one
.eq(self
.insn_in
[20])
544 with m
.If((op
.internal_op
== MicrOp
.OP_MTCRF
)):
546 # must one-hot the FXM field
547 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
548 with m
.If(ppick
.en_o
):
549 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
551 comb
+= self
.whole_reg
.data
.eq(0b00000001) # CR7
553 comb
+= self
.whole_reg
.data
.eq(self
.dec
.FXM
)
555 # otherwise use all of it
556 comb
+= self
.whole_reg
.data
.eq(0xff)
561 class PowerDecode2(Elaboratable
):
562 """PowerDecode2: the main instruction decoder.
564 whilst PowerDecode is responsible for decoding the actual opcode, this
565 module encapsulates further specialist, sparse information and
566 expansion of fields that is inconvenient to have in the CSV files.
567 for example: the encoding of the immediates, which are detected
568 and expanded out to their full value from an annotated (enum)
571 implicit register usage is also set up, here. for example: OP_BC
572 requires implicitly reading CTR, OP_RFID requires implicitly writing
575 in addition, PowerDecoder2 is responsible for detecting whether
576 instructions are illegal (or privileged) or not, and instead of
577 just leaving at that, *replacing* the instruction to execute with
578 a suitable alternative (trap).
581 def __init__(self
, dec
):
584 self
.e
= Decode2ToExecute1Type()
586 # state information needed by the Decoder (TODO: this as a Record)
587 self
.state
= CoreState("dec2")
590 return self
.dec
.ports() + self
.e
.ports()
592 def elaborate(self
, platform
):
596 e_out
, op
, do_out
= self
.e
, self
.dec
.op
, self
.e
.do
597 dec_spr
, msr
, cia
, ext_irq
= state
.dec
, state
.msr
, state
.pc
, state
.eint
599 # fill in for a normal instruction (not an exception)
600 # copy over if non-exception, non-privileged etc. is detected
601 e
= Decode2ToExecute1Type()
604 # set up submodule decoders
605 m
.submodules
.dec
= self
.dec
606 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
)
607 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
)
608 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
)
609 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
)
610 m
.submodules
.dec_o2
= dec_o2
= DecodeOut2(self
.dec
)
611 m
.submodules
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
612 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
)
613 m
.submodules
.dec_cr_in
= dec_cr_in
= DecodeCRIn(self
.dec
)
614 m
.submodules
.dec_cr_out
= dec_cr_out
= DecodeCROut(self
.dec
)
616 # copy instruction through...
617 for i
in [do
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
618 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
, dec_rc
.insn_in
,
619 dec_oe
.insn_in
, dec_cr_in
.insn_in
, dec_cr_out
.insn_in
]:
620 comb
+= i
.eq(self
.dec
.opcode_in
)
622 # ...and subdecoders' input fields
623 comb
+= dec_a
.sel_in
.eq(op
.in1_sel
)
624 comb
+= dec_b
.sel_in
.eq(op
.in2_sel
)
625 comb
+= dec_c
.sel_in
.eq(op
.in3_sel
)
626 comb
+= dec_o
.sel_in
.eq(op
.out_sel
)
627 comb
+= dec_o2
.sel_in
.eq(op
.out_sel
)
628 comb
+= dec_o2
.lk
.eq(do
.lk
)
629 comb
+= dec_rc
.sel_in
.eq(op
.rc_sel
)
630 comb
+= dec_oe
.sel_in
.eq(op
.rc_sel
) # XXX should be OE sel
631 comb
+= dec_cr_in
.sel_in
.eq(op
.cr_in
)
632 comb
+= dec_cr_out
.sel_in
.eq(op
.cr_out
)
633 comb
+= dec_cr_out
.rc_in
.eq(dec_rc
.rc_out
.data
)
636 comb
+= do
.msr
.eq(msr
)
637 comb
+= do
.cia
.eq(cia
)
639 # set up instruction, pick fn unit
640 # no op: defaults to OP_ILLEGAL
641 comb
+= do
.insn_type
.eq(op
.internal_op
)
642 comb
+= do
.fn_unit
.eq(op
.function_unit
)
644 # registers a, b, c and out and out2 (LD/ST EA)
645 comb
+= e
.read_reg1
.eq(dec_a
.reg_out
)
646 comb
+= e
.read_reg2
.eq(dec_b
.reg_out
)
647 comb
+= e
.read_reg3
.eq(dec_c
.reg_out
)
648 comb
+= e
.write_reg
.eq(dec_o
.reg_out
)
649 comb
+= e
.write_ea
.eq(dec_o2
.reg_out
)
650 comb
+= do
.imm_data
.eq(dec_b
.imm_out
) # immediate in RB (usually)
651 comb
+= do
.zero_a
.eq(dec_a
.immz_out
) # RA==0 detected
654 comb
+= do
.rc
.eq(dec_rc
.rc_out
)
655 comb
+= do
.oe
.eq(dec_oe
.oe_out
)
658 comb
+= e
.read_spr1
.eq(dec_a
.spr_out
)
659 comb
+= e
.write_spr
.eq(dec_o
.spr_out
)
662 comb
+= e
.read_fast1
.eq(dec_a
.fast_out
)
663 comb
+= e
.read_fast2
.eq(dec_b
.fast_out
)
664 comb
+= e
.write_fast1
.eq(dec_o
.fast_out
)
665 comb
+= e
.write_fast2
.eq(dec_o2
.fast_out
)
667 # condition registers (CR)
668 comb
+= e
.read_cr1
.eq(dec_cr_in
.cr_bitfield
)
669 comb
+= e
.read_cr2
.eq(dec_cr_in
.cr_bitfield_b
)
670 comb
+= e
.read_cr3
.eq(dec_cr_in
.cr_bitfield_o
)
671 comb
+= e
.write_cr
.eq(dec_cr_out
.cr_bitfield
)
673 comb
+= do
.read_cr_whole
.eq(dec_cr_in
.whole_reg
)
674 comb
+= do
.write_cr_whole
.eq(dec_cr_out
.whole_reg
)
675 comb
+= do
.write_cr0
.eq(dec_cr_out
.cr_bitfield
.ok
)
677 # decoded/selected instruction flags
678 comb
+= do
.data_len
.eq(op
.ldst_len
)
679 comb
+= do
.invert_in
.eq(op
.inv_a
)
680 comb
+= do
.invert_out
.eq(op
.inv_out
)
681 comb
+= do
.input_carry
.eq(op
.cry_in
) # carry comes in
682 comb
+= do
.output_carry
.eq(op
.cry_out
) # carry goes out
683 comb
+= do
.is_32bit
.eq(op
.is_32b
)
684 comb
+= do
.is_signed
.eq(op
.sgn
)
686 comb
+= do
.lk
.eq(self
.dec
.LK
) # XXX TODO: accessor
688 comb
+= do
.byte_reverse
.eq(op
.br
)
689 comb
+= do
.sign_extend
.eq(op
.sgn_ext
)
690 comb
+= do
.ldst_mode
.eq(op
.upd
) # LD/ST mode (update, cache-inhibit)
692 # These should be removed eventually
693 comb
+= do
.input_cr
.eq(op
.cr_in
) # condition reg comes in
694 comb
+= do
.output_cr
.eq(op
.cr_out
) # condition reg goes in
696 # sigh this is exactly the sort of thing for which the
697 # decoder is designed to not need. MTSPR, MFSPR and others need
698 # access to the XER bits. however setting e.oe is not appropriate
699 with m
.If(op
.internal_op
== MicrOp
.OP_MFSPR
):
700 comb
+= e
.xer_in
.eq(0b111) # SO, CA, OV
701 with m
.If(op
.internal_op
== MicrOp
.OP_CMP
):
702 comb
+= e
.xer_in
.eq(1<<XERRegs
.SO
) # SO
703 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
704 comb
+= e
.xer_out
.eq(1)
706 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
707 with m
.If(op
.internal_op
== MicrOp
.OP_TRAP
):
708 # *DO NOT* call self.trap here. that would reset absolutely
709 # rverything including destroying read of RA and RB.
710 comb
+= do
.trapaddr
.eq(0x70) # addr=0x700 (strip first nibble)
712 # check if instruction is privileged
713 is_priv_insn
= instr_is_priv(m
, op
.internal_op
, e
.do
.insn
)
715 # external interrupt? only if MSR.EE set
716 with m
.If(ext_irq
& msr
[MSR
.EE
]): # v3.0B p944 (MSR.EE)
717 self
.trap(m
, TT
.EINT
, 0x500)
719 # decrement counter (v3.0B p1099): TODO 32-bit version (MSR.LPCR)
720 with m
.If(dec_spr
[63] & msr
[MSR
.EE
]): # v3.0B 6.5.11 p1076
721 self
.trap(m
, TT
.DEC
, 0x900) # v3.0B 6.5 p1065
723 # privileged instruction trap
724 with m
.Elif(is_priv_insn
& msr
[MSR
.PR
]):
725 self
.trap(m
, TT
.PRIV
, 0x700)
727 # illegal instruction must redirect to trap. this is done by
728 # *overwriting* the decoded instruction and starting again.
729 # (note: the same goes for interrupts and for privileged operations,
730 # just with different trapaddr and traptype)
731 with m
.Elif(op
.internal_op
== MicrOp
.OP_ILLEGAL
):
732 # illegal instruction trap
733 self
.trap(m
, TT
.ILLEG
, 0x700)
735 # no exception, just copy things to the output
739 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
740 # Note: OP_SC could actually be modified to just be a trap
741 with m
.If((do_out
.insn_type
== MicrOp
.OP_TRAP
) |
742 (do_out
.insn_type
== MicrOp
.OP_SC
)):
743 # TRAP write fast1 = SRR0
744 comb
+= e_out
.write_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
745 comb
+= e_out
.write_fast1
.ok
.eq(1)
746 # TRAP write fast2 = SRR1
747 comb
+= e_out
.write_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
748 comb
+= e_out
.write_fast2
.ok
.eq(1)
750 # RFID: needs to read SRR0/1
751 with m
.If(do_out
.insn_type
== MicrOp
.OP_RFID
):
752 # TRAP read fast1 = SRR0
753 comb
+= e_out
.read_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
754 comb
+= e_out
.read_fast1
.ok
.eq(1)
755 # TRAP read fast2 = SRR1
756 comb
+= e_out
.read_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
757 comb
+= e_out
.read_fast2
.ok
.eq(1)
761 def trap(self
, m
, traptype
, trapaddr
):
762 """trap: this basically "rewrites" the decoded instruction as a trap
765 op
, do
, e
= self
.dec
.op
, self
.e
.do
, self
.e
766 comb
+= e
.eq(0) # reset eeeeeverything
769 comb
+= do
.insn
.eq(self
.dec
.opcode_in
)
770 comb
+= do
.insn_type
.eq(MicrOp
.OP_TRAP
)
771 comb
+= do
.fn_unit
.eq(Function
.TRAP
)
772 comb
+= do
.trapaddr
.eq(trapaddr
>> 4) # cut bottom 4 bits
773 comb
+= do
.traptype
.eq(traptype
) # request type
774 comb
+= do
.msr
.eq(self
.state
.msr
) # copy of MSR "state"
775 comb
+= do
.cia
.eq(self
.state
.pc
) # copy of PC "state"
778 def get_rdflags(e
, cu
):
780 for idx
in range(cu
.n_src
):
781 regfile
, regname
, _
= cu
.get_in_spec(idx
)
782 rdflag
, read
= regspec_decode_read(e
, regfile
, regname
)
784 print("rdflags", rdl
)
788 if __name__
== '__main__':
789 pdecode
= create_pdecode()
790 dec2
= PowerDecode2(pdecode
)
791 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
792 with
open("dec2.il", "w") as f
: