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
32 def decode_spr_num(spr
):
33 return Cat(spr
[5:10], spr
[0:5])
36 def instr_is_priv(m
, op
, insn
):
37 """determines if the instruction is privileged or not
40 is_priv_insn
= Signal(reset_less
=True)
42 with m
.Case(MicrOp
.OP_ATTN
, MicrOp
.OP_MFMSR
, MicrOp
.OP_MTMSRD
,
43 MicrOp
.OP_MTMSR
, MicrOp
.OP_RFID
):
44 comb
+= is_priv_insn
.eq(1)
46 #with m.Case(MicrOp.OP_TLBIE) : comb += is_priv_insn.eq(1)
47 with m
.Case(MicrOp
.OP_MFSPR
, MicrOp
.OP_MTSPR
):
48 with m
.If(insn
[20]): # field XFX.spr[-1] i think
49 comb
+= is_priv_insn
.eq(1)
53 class SPRMap(Elaboratable
):
54 """SPRMap: maps POWER9 SPR numbers to internal enum values
58 self
.spr_i
= Signal(10, reset_less
=True)
59 self
.spr_o
= Signal(SPR
, reset_less
=True)
61 def elaborate(self
, platform
):
63 with m
.Switch(self
.spr_i
):
64 for i
, x
in enumerate(SPR
):
66 m
.d
.comb
+= self
.spr_o
.eq(i
)
70 class DecodeA(Elaboratable
):
71 """DecodeA from instruction
73 decodes register RA, whether immediate-zero, implicit and
77 def __init__(self
, dec
):
79 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
80 self
.insn_in
= Signal(32, reset_less
=True)
81 self
.reg_out
= Data(5, name
="reg_a")
82 self
.immz_out
= Signal(reset_less
=True)
83 self
.spr_out
= Data(SPR
, "spr_a")
84 self
.fast_out
= Data(3, "fast_a")
86 def elaborate(self
, platform
):
89 m
.submodules
.sprmap
= sprmap
= SPRMap()
91 # select Register A field
92 ra
= Signal(5, reset_less
=True)
93 comb
+= ra
.eq(self
.dec
.RA
)
94 with m
.If((self
.sel_in
== In1Sel
.RA
) |
95 ((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
96 (ra
!= Const(0, 5)))):
97 comb
+= self
.reg_out
.data
.eq(ra
)
98 comb
+= self
.reg_out
.ok
.eq(1)
100 # zero immediate requested
101 with m
.If((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
102 (self
.reg_out
.data
== Const(0, 5))):
103 comb
+= self
.immz_out
.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
134 with m
.Case(SPR
.CTR
.value
):
135 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
136 comb
+= self
.fast_out
.ok
.eq(1)
137 with m
.Case(SPR
.LR
.value
):
138 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
139 comb
+= self
.fast_out
.ok
.eq(1)
140 with m
.Case(SPR
.TAR
.value
):
141 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
142 comb
+= self
.fast_out
.ok
.eq(1)
143 with m
.Case(SPR
.SRR0
.value
):
144 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
)
145 comb
+= self
.fast_out
.ok
.eq(1)
146 with m
.Case(SPR
.SRR1
.value
):
147 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
)
148 comb
+= self
.fast_out
.ok
.eq(1)
149 with m
.Case(SPR
.XER
.value
):
151 # : map to internal SPR numbers
152 # XXX TODO: dec and tb not to go through mapping.
154 comb
+= sprmap
.spr_i
.eq(spr
)
155 comb
+= self
.spr_out
.data
.eq(sprmap
.spr_o
)
156 comb
+= self
.spr_out
.ok
.eq(1)
161 class DecodeB(Elaboratable
):
162 """DecodeB from instruction
164 decodes register RB, different forms of immediate (signed, unsigned),
165 and implicit SPRs. register B is basically "lane 2" into the CompUnits.
166 by industry-standard convention, "lane 2" is where fully-decoded
167 immediates are muxed in.
170 def __init__(self
, dec
):
172 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
173 self
.insn_in
= Signal(32, reset_less
=True)
174 self
.reg_out
= Data(5, "reg_b")
175 self
.imm_out
= Data(64, "imm_b")
176 self
.fast_out
= Data(3, "fast_b")
178 def elaborate(self
, platform
):
182 # select Register B field
183 with m
.Switch(self
.sel_in
):
184 with m
.Case(In2Sel
.RB
):
185 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
)
186 comb
+= self
.reg_out
.ok
.eq(1)
187 with m
.Case(In2Sel
.RS
):
188 # for M-Form shiftrot
189 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
190 comb
+= self
.reg_out
.ok
.eq(1)
191 with m
.Case(In2Sel
.CONST_UI
): # unsigned
192 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
)
193 comb
+= self
.imm_out
.ok
.eq(1)
194 with m
.Case(In2Sel
.CONST_SI
): # sign-extended 16-bit
195 si
= Signal(16, reset_less
=True)
196 comb
+= si
.eq(self
.dec
.SI
)
197 comb
+= self
.imm_out
.data
.eq(exts(si
, 16, 64))
198 comb
+= self
.imm_out
.ok
.eq(1)
199 with m
.Case(In2Sel
.CONST_SI_HI
): # sign-extended 16+16=32 bit
200 si_hi
= Signal(32, reset_less
=True)
201 comb
+= si_hi
.eq(self
.dec
.SI
<< 16)
202 comb
+= self
.imm_out
.data
.eq(exts(si_hi
, 32, 64))
203 comb
+= self
.imm_out
.ok
.eq(1)
204 with m
.Case(In2Sel
.CONST_UI_HI
): # unsigned
205 ui
= Signal(16, reset_less
=True)
206 comb
+= ui
.eq(self
.dec
.UI
)
207 comb
+= self
.imm_out
.data
.eq(ui
<< 16)
208 comb
+= self
.imm_out
.ok
.eq(1)
209 with m
.Case(In2Sel
.CONST_LI
): # sign-extend 24+2=26 bit
210 li
= Signal(26, reset_less
=True)
211 comb
+= li
.eq(self
.dec
.LI
<< 2)
212 comb
+= self
.imm_out
.data
.eq(exts(li
, 26, 64))
213 comb
+= self
.imm_out
.ok
.eq(1)
214 with m
.Case(In2Sel
.CONST_BD
): # sign-extend (14+2)=16 bit
215 bd
= Signal(16, reset_less
=True)
216 comb
+= bd
.eq(self
.dec
.BD
<< 2)
217 comb
+= self
.imm_out
.data
.eq(exts(bd
, 16, 64))
218 comb
+= self
.imm_out
.ok
.eq(1)
219 with m
.Case(In2Sel
.CONST_DS
): # sign-extended (14+2=16) bit
220 ds
= Signal(16, reset_less
=True)
221 comb
+= ds
.eq(self
.dec
.DS
<< 2)
222 comb
+= self
.imm_out
.data
.eq(exts(ds
, 16, 64))
223 comb
+= self
.imm_out
.ok
.eq(1)
224 with m
.Case(In2Sel
.CONST_M1
): # signed (-1)
225 comb
+= self
.imm_out
.data
.eq(~
Const(0, 64)) # all 1s
226 comb
+= self
.imm_out
.ok
.eq(1)
227 with m
.Case(In2Sel
.CONST_SH
): # unsigned - for shift
228 comb
+= self
.imm_out
.data
.eq(self
.dec
.sh
)
229 comb
+= self
.imm_out
.ok
.eq(1)
230 with m
.Case(In2Sel
.CONST_SH32
): # unsigned - for shift
231 comb
+= self
.imm_out
.data
.eq(self
.dec
.SH32
)
232 comb
+= self
.imm_out
.ok
.eq(1)
234 # decode SPR2 based on instruction type
236 # BCREG implicitly uses LR or TAR for 2nd reg
237 # CTR however is already in fast_spr1 *not* 2.
238 with m
.If(op
.internal_op
== MicrOp
.OP_BCREG
):
239 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
240 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
242 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
243 comb
+= self
.fast_out
.ok
.eq(1)
245 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
246 comb
+= self
.fast_out
.ok
.eq(1)
251 class DecodeC(Elaboratable
):
252 """DecodeC from instruction
254 decodes register RC. this is "lane 3" into some CompUnits (not many)
257 def __init__(self
, dec
):
259 self
.sel_in
= Signal(In3Sel
, reset_less
=True)
260 self
.insn_in
= Signal(32, reset_less
=True)
261 self
.reg_out
= Data(5, "reg_c")
263 def elaborate(self
, platform
):
267 # select Register C field
268 with m
.Switch(self
.sel_in
):
269 with m
.Case(In3Sel
.RB
):
270 # for M-Form shiftrot
271 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
)
272 comb
+= self
.reg_out
.ok
.eq(1)
273 with m
.Case(In3Sel
.RS
):
274 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
275 comb
+= self
.reg_out
.ok
.eq(1)
280 class DecodeOut(Elaboratable
):
281 """DecodeOut from instruction
283 decodes output register RA, RT or SPR
286 def __init__(self
, dec
):
288 self
.sel_in
= Signal(OutSel
, reset_less
=True)
289 self
.insn_in
= Signal(32, reset_less
=True)
290 self
.reg_out
= Data(5, "reg_o")
291 self
.spr_out
= Data(SPR
, "spr_o")
292 self
.fast_out
= Data(3, "fast_o")
294 def elaborate(self
, platform
):
297 m
.submodules
.sprmap
= sprmap
= SPRMap()
300 # select Register out field
301 with m
.Switch(self
.sel_in
):
302 with m
.Case(OutSel
.RT
):
303 comb
+= self
.reg_out
.data
.eq(self
.dec
.RT
)
304 comb
+= self
.reg_out
.ok
.eq(1)
305 with m
.Case(OutSel
.RA
):
306 comb
+= self
.reg_out
.data
.eq(self
.dec
.RA
)
307 comb
+= self
.reg_out
.ok
.eq(1)
308 with m
.Case(OutSel
.SPR
):
309 spr
= Signal(10, reset_less
=True)
310 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
311 # TODO MTSPR 1st spr (fast)
312 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
315 with m
.Case(SPR
.CTR
.value
):
316 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
317 comb
+= self
.fast_out
.ok
.eq(1)
318 with m
.Case(SPR
.LR
.value
):
319 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
320 comb
+= self
.fast_out
.ok
.eq(1)
321 with m
.Case(SPR
.TAR
.value
):
322 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
323 comb
+= self
.fast_out
.ok
.eq(1)
324 with m
.Case(SPR
.SRR0
.value
):
325 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
)
326 comb
+= self
.fast_out
.ok
.eq(1)
327 with m
.Case(SPR
.SRR1
.value
):
328 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
)
329 comb
+= self
.fast_out
.ok
.eq(1)
330 with m
.Case(SPR
.XER
.value
):
332 # : map to internal SPR numbers
333 # XXX TODO: dec and tb not to go through mapping.
335 comb
+= sprmap
.spr_i
.eq(spr
)
336 comb
+= self
.spr_out
.data
.eq(sprmap
.spr_o
)
337 comb
+= self
.spr_out
.ok
.eq(1)
339 with m
.Switch(op
.internal_op
):
341 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeA
342 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_BCREG
):
343 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
345 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
346 comb
+= self
.fast_out
.ok
.eq(1)
348 # RFID 1st spr (fast)
349 with m
.Case(MicrOp
.OP_RFID
):
350 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
351 comb
+= self
.fast_out
.ok
.eq(1)
356 class DecodeOut2(Elaboratable
):
357 """DecodeOut2 from instruction
359 decodes output registers
362 def __init__(self
, dec
):
364 self
.sel_in
= Signal(OutSel
, reset_less
=True)
365 self
.lk
= Signal(reset_less
=True)
366 self
.insn_in
= Signal(32, reset_less
=True)
367 self
.reg_out
= Data(5, "reg_o")
368 self
.fast_out
= Data(3, "fast_o")
370 def elaborate(self
, platform
):
374 # update mode LD/ST uses read-reg A also as an output
375 with m
.If(self
.dec
.op
.upd
== LDSTMode
.update
):
376 comb
+= self
.reg_out
.eq(self
.dec
.RA
)
377 comb
+= self
.reg_out
.ok
.eq(1)
379 # B, BC or BCREG: potential implicit register (LR) output
380 # these give bl, bcl, bclrl, etc.
382 with m
.Switch(op
.internal_op
):
384 # BC* implicit register (LR)
385 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_B
, MicrOp
.OP_BCREG
):
386 with m
.If(self
.lk
): # "link" mode
387 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
) # constant: LR
388 comb
+= self
.fast_out
.ok
.eq(1)
390 # RFID 2nd spr (fast)
391 with m
.Case(MicrOp
.OP_RFID
):
392 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
393 comb
+= self
.fast_out
.ok
.eq(1)
398 class DecodeRC(Elaboratable
):
399 """DecodeRc from instruction
401 decodes Record bit Rc
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
.rc_out
= Data(1, "rc")
410 def elaborate(self
, platform
):
414 # select Record bit out field
415 with m
.Switch(self
.sel_in
):
417 comb
+= self
.rc_out
.data
.eq(self
.dec
.Rc
)
418 comb
+= self
.rc_out
.ok
.eq(1)
420 comb
+= self
.rc_out
.data
.eq(1)
421 comb
+= self
.rc_out
.ok
.eq(1)
422 with m
.Case(RC
.NONE
):
423 comb
+= self
.rc_out
.data
.eq(0)
424 comb
+= self
.rc_out
.ok
.eq(1)
429 class DecodeOE(Elaboratable
):
430 """DecodeOE from instruction
432 decodes OE field: uses RC decode detection which might not be good
434 -- For now, use "rc" in the decode table to decide whether oe exists.
435 -- This is not entirely correct architecturally: For mulhd and
436 -- mulhdu, the OE field is reserved. It remains to be seen what an
437 -- actual POWER9 does if we set it on those instructions, for now we
438 -- test that further down when assigning to the multiplier oe input.
441 def __init__(self
, dec
):
443 self
.sel_in
= Signal(RC
, reset_less
=True)
444 self
.insn_in
= Signal(32, reset_less
=True)
445 self
.oe_out
= Data(1, "oe")
447 def elaborate(self
, platform
):
452 with m
.Switch(op
.internal_op
):
454 # mulhw, mulhwu, mulhd, mulhdu - these *ignore* OE
456 # XXX ARGH! ignoring OE causes incompatibility with microwatt
457 # http://lists.libre-soc.org/pipermail/libre-soc-dev/2020-August/000302.html
458 with m
.Case(MicrOp
.OP_MUL_H64
, MicrOp
.OP_MUL_H32
,
459 MicrOp
.OP_EXTS
, MicrOp
.OP_CNTZ
,
460 MicrOp
.OP_SHL
, MicrOp
.OP_SHR
, MicrOp
.OP_RLC
,
461 MicrOp
.OP_LOAD
, MicrOp
.OP_STORE
,
462 MicrOp
.OP_RLCL
, MicrOp
.OP_RLCR
,
466 # all other ops decode OE field
468 # select OE bit out field
469 with m
.Switch(self
.sel_in
):
471 comb
+= self
.oe_out
.data
.eq(self
.dec
.OE
)
472 comb
+= self
.oe_out
.ok
.eq(1)
477 class DecodeCRIn(Elaboratable
):
478 """Decodes input CR from instruction
480 CR indices - insn fields - (not the data *in* the CR) require only 3
481 bits because they refer to CR0-CR7
484 def __init__(self
, dec
):
486 self
.sel_in
= Signal(CRInSel
, reset_less
=True)
487 self
.insn_in
= Signal(32, reset_less
=True)
488 self
.cr_bitfield
= Data(3, "cr_bitfield")
489 self
.cr_bitfield_b
= Data(3, "cr_bitfield_b")
490 self
.cr_bitfield_o
= Data(3, "cr_bitfield_o")
491 self
.whole_reg
= Data(8, "cr_fxm")
493 def elaborate(self
, platform
):
495 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
501 comb
+= self
.cr_bitfield
.ok
.eq(0)
502 comb
+= self
.cr_bitfield_b
.ok
.eq(0)
503 comb
+= self
.whole_reg
.ok
.eq(0)
504 with m
.Switch(self
.sel_in
):
505 with m
.Case(CRInSel
.NONE
):
506 pass # No bitfield activated
507 with m
.Case(CRInSel
.CR0
):
508 comb
+= self
.cr_bitfield
.data
.eq(0)
509 comb
+= self
.cr_bitfield
.ok
.eq(1)
510 with m
.Case(CRInSel
.BI
):
511 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BI
[2:5])
512 comb
+= self
.cr_bitfield
.ok
.eq(1)
513 with m
.Case(CRInSel
.BFA
):
514 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BFA
)
515 comb
+= self
.cr_bitfield
.ok
.eq(1)
516 with m
.Case(CRInSel
.BA_BB
):
517 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BA
[2:5])
518 comb
+= self
.cr_bitfield
.ok
.eq(1)
519 comb
+= self
.cr_bitfield_b
.data
.eq(self
.dec
.BB
[2:5])
520 comb
+= self
.cr_bitfield_b
.ok
.eq(1)
521 comb
+= self
.cr_bitfield_o
.data
.eq(self
.dec
.BT
[2:5])
522 comb
+= self
.cr_bitfield_o
.ok
.eq(1)
523 with m
.Case(CRInSel
.BC
):
524 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BC
[2:5])
525 comb
+= self
.cr_bitfield
.ok
.eq(1)
526 with m
.Case(CRInSel
.WHOLE_REG
):
527 comb
+= self
.whole_reg
.ok
.eq(1)
528 move_one
= Signal(reset_less
=True)
529 comb
+= move_one
.eq(self
.insn_in
[20]) # MSB0 bit 11
530 with m
.If((op
.internal_op
== MicrOp
.OP_MFCR
) & move_one
):
531 # must one-hot the FXM field
532 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
533 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
535 # otherwise use all of it
536 comb
+= self
.whole_reg
.data
.eq(0xff)
541 class DecodeCROut(Elaboratable
):
542 """Decodes input CR from instruction
544 CR indices - insn fields - (not the data *in* the CR) require only 3
545 bits because they refer to CR0-CR7
548 def __init__(self
, dec
):
550 self
.rc_in
= Signal(reset_less
=True)
551 self
.sel_in
= Signal(CROutSel
, reset_less
=True)
552 self
.insn_in
= Signal(32, reset_less
=True)
553 self
.cr_bitfield
= Data(3, "cr_bitfield")
554 self
.whole_reg
= Data(8, "cr_fxm")
556 def elaborate(self
, platform
):
560 m
.submodules
.ppick
= ppick
= PriorityPicker(8)
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)
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 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
586 comb
+= self
.whole_reg
.data
.eq(self
.dec
.FXM
)
588 # otherwise use all of it
589 comb
+= self
.whole_reg
.data
.eq(0xff)
594 class PowerDecode2(Elaboratable
):
595 """PowerDecode2: the main instruction decoder.
597 whilst PowerDecode is responsible for decoding the actual opcode, this
598 module encapsulates further specialist, sparse information and
599 expansion of fields that is inconvenient to have in the CSV files.
600 for example: the encoding of the immediates, which are detected
601 and expanded out to their full value from an annotated (enum)
604 implicit register usage is also set up, here. for example: OP_BC
605 requires implicitly reading CTR, OP_RFID requires implicitly writing
608 in addition, PowerDecoder2 is responsible for detecting whether
609 instructions are illegal (or privileged) or not, and instead of
610 just leaving at that, *replacing* the instruction to execute with
611 a suitable alternative (trap).
614 def __init__(self
, dec
):
617 self
.e
= Decode2ToExecute1Type()
619 # state information needed by the Decoder (TODO: this as a Record)
620 self
.state
= CoreState("dec2")
623 return self
.dec
.ports() + self
.e
.ports()
625 def elaborate(self
, platform
):
628 e_out
, op
, do_out
= self
.e
, self
.dec
.op
, self
.e
.do
629 msr
, cia
= self
.state
.msr
, self
.state
.pc
631 # fill in for a normal instruction (not an exception)
632 # copy over if non-exception, non-privileged etc. is detected
633 e
= Decode2ToExecute1Type()
636 # set up submodule decoders
637 m
.submodules
.dec
= self
.dec
638 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
)
639 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
)
640 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
)
641 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
)
642 m
.submodules
.dec_o2
= dec_o2
= DecodeOut2(self
.dec
)
643 m
.submodules
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
644 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
)
645 m
.submodules
.dec_cr_in
= dec_cr_in
= DecodeCRIn(self
.dec
)
646 m
.submodules
.dec_cr_out
= dec_cr_out
= DecodeCROut(self
.dec
)
648 # copy instruction through...
649 for i
in [do
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
650 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
, dec_rc
.insn_in
,
651 dec_oe
.insn_in
, dec_cr_in
.insn_in
, dec_cr_out
.insn_in
]:
652 comb
+= i
.eq(self
.dec
.opcode_in
)
654 # ...and subdecoders' input fields
655 comb
+= dec_a
.sel_in
.eq(op
.in1_sel
)
656 comb
+= dec_b
.sel_in
.eq(op
.in2_sel
)
657 comb
+= dec_c
.sel_in
.eq(op
.in3_sel
)
658 comb
+= dec_o
.sel_in
.eq(op
.out_sel
)
659 comb
+= dec_o2
.sel_in
.eq(op
.out_sel
)
660 comb
+= dec_o2
.lk
.eq(do
.lk
)
661 comb
+= dec_rc
.sel_in
.eq(op
.rc_sel
)
662 comb
+= dec_oe
.sel_in
.eq(op
.rc_sel
) # XXX should be OE sel
663 comb
+= dec_cr_in
.sel_in
.eq(op
.cr_in
)
664 comb
+= dec_cr_out
.sel_in
.eq(op
.cr_out
)
665 comb
+= dec_cr_out
.rc_in
.eq(dec_rc
.rc_out
.data
)
668 comb
+= do
.msr
.eq(msr
)
669 comb
+= do
.cia
.eq(cia
)
671 # set up instruction, pick fn unit
672 # no op: defaults to OP_ILLEGAL
673 comb
+= do
.insn_type
.eq(op
.internal_op
)
674 comb
+= do
.fn_unit
.eq(op
.function_unit
)
676 # registers a, b, c and out and out2 (LD/ST EA)
677 comb
+= e
.read_reg1
.eq(dec_a
.reg_out
)
678 comb
+= e
.read_reg2
.eq(dec_b
.reg_out
)
679 comb
+= e
.read_reg3
.eq(dec_c
.reg_out
)
680 comb
+= e
.write_reg
.eq(dec_o
.reg_out
)
681 comb
+= e
.write_ea
.eq(dec_o2
.reg_out
)
682 comb
+= do
.imm_data
.eq(dec_b
.imm_out
) # immediate in RB (usually)
683 comb
+= do
.zero_a
.eq(dec_a
.immz_out
) # RA==0 detected
686 comb
+= do
.rc
.eq(dec_rc
.rc_out
)
687 comb
+= do
.oe
.eq(dec_oe
.oe_out
)
690 comb
+= e
.read_spr1
.eq(dec_a
.spr_out
)
691 comb
+= e
.write_spr
.eq(dec_o
.spr_out
)
694 comb
+= e
.read_fast1
.eq(dec_a
.fast_out
)
695 comb
+= e
.read_fast2
.eq(dec_b
.fast_out
)
696 comb
+= e
.write_fast1
.eq(dec_o
.fast_out
)
697 comb
+= e
.write_fast2
.eq(dec_o2
.fast_out
)
699 # condition registers (CR)
700 comb
+= e
.read_cr1
.eq(dec_cr_in
.cr_bitfield
)
701 comb
+= e
.read_cr2
.eq(dec_cr_in
.cr_bitfield_b
)
702 comb
+= e
.read_cr3
.eq(dec_cr_in
.cr_bitfield_o
)
703 comb
+= e
.write_cr
.eq(dec_cr_out
.cr_bitfield
)
705 comb
+= do
.read_cr_whole
.eq(dec_cr_in
.whole_reg
)
706 comb
+= do
.write_cr_whole
.eq(dec_cr_out
.whole_reg
)
707 comb
+= do
.write_cr0
.eq(dec_cr_out
.cr_bitfield
.ok
)
709 # decoded/selected instruction flags
710 comb
+= do
.data_len
.eq(op
.ldst_len
)
711 comb
+= do
.invert_in
.eq(op
.inv_a
)
712 comb
+= do
.invert_out
.eq(op
.inv_out
)
713 comb
+= do
.input_carry
.eq(op
.cry_in
) # carry comes in
714 comb
+= do
.output_carry
.eq(op
.cry_out
) # carry goes out
715 comb
+= do
.is_32bit
.eq(op
.is_32b
)
716 comb
+= do
.is_signed
.eq(op
.sgn
)
718 comb
+= do
.lk
.eq(self
.dec
.LK
) # XXX TODO: accessor
720 comb
+= do
.byte_reverse
.eq(op
.br
)
721 comb
+= do
.sign_extend
.eq(op
.sgn_ext
)
722 comb
+= do
.ldst_mode
.eq(op
.upd
) # LD/ST mode (update, cache-inhibit)
724 # These should be removed eventually
725 comb
+= do
.input_cr
.eq(op
.cr_in
) # condition reg comes in
726 comb
+= do
.output_cr
.eq(op
.cr_out
) # condition reg goes in
728 # sigh this is exactly the sort of thing for which the
729 # decoder is designed to not need. MTSPR, MFSPR and others need
730 # access to the XER bits. however setting e.oe is not appropriate
731 with m
.If(op
.internal_op
== MicrOp
.OP_MFSPR
):
732 comb
+= e
.xer_in
.eq(0b111) # SO, CA, OV
733 with m
.If(op
.internal_op
== MicrOp
.OP_CMP
):
734 comb
+= e
.xer_in
.eq(1<<XERRegs
.SO
) # SO
735 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
736 comb
+= e
.xer_out
.eq(1)
738 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
739 with m
.If(op
.internal_op
== MicrOp
.OP_TRAP
):
740 # *DO NOT* call self.trap here. that would reset absolutely
741 # rverything including destroying read of RA and RB.
742 comb
+= do
.trapaddr
.eq(0x70) # addr=0x700 (strip first nibble)
744 # TODO: get msr, then can do privileged instruction
745 with m
.If(instr_is_priv(m
, op
.internal_op
, e
.do
.insn
) & msr
[MSR
.PR
]):
746 # privileged instruction trap
747 self
.trap(m
, TT
.PRIV
, 0x700)
749 # illegal instruction must redirect to trap. this is done by
750 # *overwriting* the decoded instruction and starting again.
751 # (note: the same goes for interrupts and for privileged operations,
752 # just with different trapaddr and traptype)
753 with m
.Elif(op
.internal_op
== MicrOp
.OP_ILLEGAL
):
754 # illegal instruction trap
755 self
.trap(m
, TT
.ILLEG
, 0x700)
757 # no exception, just copy things to the output
761 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
762 # Note: OP_SC could actually be modified to just be a trap
763 with m
.If((do_out
.insn_type
== MicrOp
.OP_TRAP
) |
764 (do_out
.insn_type
== MicrOp
.OP_SC
)):
765 # TRAP write fast1 = SRR0
766 comb
+= e_out
.write_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
767 comb
+= e_out
.write_fast1
.ok
.eq(1)
768 # TRAP write fast2 = SRR1
769 comb
+= e_out
.write_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
770 comb
+= e_out
.write_fast2
.ok
.eq(1)
772 # RFID: needs to read SRR0/1
773 with m
.If(do_out
.insn_type
== MicrOp
.OP_RFID
):
774 # TRAP read fast1 = SRR0
775 comb
+= e_out
.read_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
776 comb
+= e_out
.read_fast1
.ok
.eq(1)
777 # TRAP read fast2 = SRR1
778 comb
+= e_out
.read_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
779 comb
+= e_out
.read_fast2
.ok
.eq(1)
783 def trap(self
, m
, traptype
, trapaddr
):
784 """trap: this basically "rewrites" the decoded instruction as a trap
787 op
, do
, e
= self
.dec
.op
, self
.e
.do
, self
.e
788 comb
+= e
.eq(0) # reset eeeeeverything
791 comb
+= do
.insn
.eq(self
.dec
.opcode_in
)
792 comb
+= do
.insn_type
.eq(MicrOp
.OP_TRAP
)
793 comb
+= do
.fn_unit
.eq(Function
.TRAP
)
794 comb
+= do
.trapaddr
.eq(trapaddr
>> 4) # cut bottom 4 bits
795 comb
+= do
.traptype
.eq(traptype
) # request type
796 comb
+= do
.msr
.eq(self
.state
.msr
) # copy of MSR "state"
797 comb
+= do
.cia
.eq(self
.state
.pc
) # copy of PC "state"
800 def get_rdflags(e
, cu
):
802 for idx
in range(cu
.n_src
):
803 regfile
, regname
, _
= cu
.get_in_spec(idx
)
804 rdflag
, read
= regspec_decode_read(e
, regfile
, regname
)
806 print("rdflags", rdl
)
810 if __name__
== '__main__':
811 pdecode
= create_pdecode()
812 dec2
= PowerDecode2(pdecode
)
813 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
814 with
open("dec2.il", "w") as f
: