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
12 from nmutil
.picker
import PriorityPicker
13 from nmutil
.iocontrol
import RecordObject
14 from nmutil
.extend
import exts
16 from soc
.decoder
.power_regspec_map
import regspec_decode_read
17 from soc
.decoder
.power_regspec_map
import regspec_decode_write
18 from soc
.decoder
.power_decoder
import create_pdecode
19 from soc
.decoder
.power_enums
import (MicrOp
, CryIn
, Function
,
21 LdstLen
, In1Sel
, In2Sel
, In3Sel
,
22 OutSel
, SPR
, RC
, LDSTMode
)
23 from soc
.decoder
.decode2execute1
import Decode2ToExecute1Type
, Data
24 from soc
.consts
import MSR
26 from soc
.regfile
.regfiles
import FastRegs
27 from soc
.consts
import TT
28 from soc
.config
.state
import CoreState
31 def decode_spr_num(spr
):
32 return Cat(spr
[5:10], spr
[0:5])
35 def instr_is_priv(m
, op
, insn
):
36 """determines if the instruction is privileged or not
39 is_priv_insn
= Signal(reset_less
=True)
41 with m
.Case(MicrOp
.OP_ATTN
, MicrOp
.OP_MFMSR
, MicrOp
.OP_MTMSRD
,
42 MicrOp
.OP_MTMSR
, MicrOp
.OP_RFID
):
43 comb
+= is_priv_insn
.eq(1)
45 #with m.Case(MicrOp.OP_TLBIE) : comb += is_priv_insn.eq(1)
46 with m
.Case(MicrOp
.OP_MFSPR
, MicrOp
.OP_MTSPR
):
47 with m
.If(insn
[20]): # field XFX.spr[-1] i think
48 comb
+= is_priv_insn
.eq(1)
52 class SPRMap(Elaboratable
):
53 """SPRMap: maps POWER9 SPR numbers to internal enum values
57 self
.spr_i
= Signal(10, reset_less
=True)
58 self
.spr_o
= Signal(SPR
, reset_less
=True)
60 def elaborate(self
, platform
):
62 with m
.Switch(self
.spr_i
):
63 for i
, x
in enumerate(SPR
):
65 m
.d
.comb
+= self
.spr_o
.eq(i
)
69 class DecodeA(Elaboratable
):
70 """DecodeA from instruction
72 decodes register RA, whether immediate-zero, implicit and
76 def __init__(self
, dec
):
78 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
79 self
.insn_in
= Signal(32, reset_less
=True)
80 self
.reg_out
= Data(5, name
="reg_a")
81 self
.immz_out
= Signal(reset_less
=True)
82 self
.spr_out
= Data(SPR
, "spr_a")
83 self
.fast_out
= Data(3, "fast_a")
85 def elaborate(self
, platform
):
88 m
.submodules
.sprmap
= sprmap
= SPRMap()
90 # select Register A field
91 ra
= Signal(5, reset_less
=True)
92 comb
+= ra
.eq(self
.dec
.RA
)
93 with m
.If((self
.sel_in
== In1Sel
.RA
) |
94 ((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
95 (ra
!= Const(0, 5)))):
96 comb
+= self
.reg_out
.data
.eq(ra
)
97 comb
+= self
.reg_out
.ok
.eq(1)
99 # zero immediate requested
100 with m
.If((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
101 (self
.reg_out
.data
== Const(0, 5))):
102 comb
+= self
.immz_out
.eq(1)
104 # some Logic/ALU ops have RS as the 3rd arg, but no "RA".
105 with m
.If(self
.sel_in
== In1Sel
.RS
):
106 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
107 comb
+= self
.reg_out
.ok
.eq(1)
109 # decode Fast-SPR based on instruction type
111 with m
.Switch(op
.internal_op
):
113 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeOut
114 with m
.Case(MicrOp
.OP_BC
):
115 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
117 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
118 comb
+= self
.fast_out
.ok
.eq(1)
119 with m
.Case(MicrOp
.OP_BCREG
):
120 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
121 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
122 with m
.If(xo9
& ~xo5
):
124 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
125 comb
+= self
.fast_out
.ok
.eq(1)
127 # MFSPR move from SPRs
128 with m
.Case(MicrOp
.OP_MFSPR
):
129 spr
= Signal(10, reset_less
=True)
130 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
133 with m
.Case(SPR
.CTR
.value
):
134 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
135 comb
+= self
.fast_out
.ok
.eq(1)
136 with m
.Case(SPR
.LR
.value
):
137 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
138 comb
+= self
.fast_out
.ok
.eq(1)
139 with m
.Case(SPR
.TAR
.value
):
140 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
141 comb
+= self
.fast_out
.ok
.eq(1)
142 with m
.Case(SPR
.SRR0
.value
):
143 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
)
144 comb
+= self
.fast_out
.ok
.eq(1)
145 with m
.Case(SPR
.SRR1
.value
):
146 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
)
147 comb
+= self
.fast_out
.ok
.eq(1)
148 with m
.Case(SPR
.XER
.value
):
150 # : map to internal SPR numbers
151 # XXX TODO: dec and tb not to go through mapping.
153 comb
+= sprmap
.spr_i
.eq(spr
)
154 comb
+= self
.spr_out
.data
.eq(sprmap
.spr_o
)
155 comb
+= self
.spr_out
.ok
.eq(1)
160 class DecodeB(Elaboratable
):
161 """DecodeB from instruction
163 decodes register RB, different forms of immediate (signed, unsigned),
164 and implicit SPRs. register B is basically "lane 2" into the CompUnits.
165 by industry-standard convention, "lane 2" is where fully-decoded
166 immediates are muxed in.
169 def __init__(self
, dec
):
171 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
172 self
.insn_in
= Signal(32, reset_less
=True)
173 self
.reg_out
= Data(5, "reg_b")
174 self
.imm_out
= Data(64, "imm_b")
175 self
.fast_out
= Data(3, "fast_b")
177 def elaborate(self
, platform
):
181 # select Register B field
182 with m
.Switch(self
.sel_in
):
183 with m
.Case(In2Sel
.RB
):
184 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
)
185 comb
+= self
.reg_out
.ok
.eq(1)
186 with m
.Case(In2Sel
.RS
):
187 # for M-Form shiftrot
188 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
189 comb
+= self
.reg_out
.ok
.eq(1)
190 with m
.Case(In2Sel
.CONST_UI
): # unsigned
191 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
)
192 comb
+= self
.imm_out
.ok
.eq(1)
193 with m
.Case(In2Sel
.CONST_SI
): # sign-extended 16-bit
194 si
= Signal(16, reset_less
=True)
195 comb
+= si
.eq(self
.dec
.SI
)
196 comb
+= self
.imm_out
.data
.eq(exts(si
, 16, 64))
197 comb
+= self
.imm_out
.ok
.eq(1)
198 with m
.Case(In2Sel
.CONST_SI_HI
): # sign-extended 16+16=32 bit
199 si_hi
= Signal(32, reset_less
=True)
200 comb
+= si_hi
.eq(self
.dec
.SI
<< 16)
201 comb
+= self
.imm_out
.data
.eq(exts(si_hi
, 32, 64))
202 comb
+= self
.imm_out
.ok
.eq(1)
203 with m
.Case(In2Sel
.CONST_UI_HI
): # unsigned
204 ui
= Signal(16, reset_less
=True)
205 comb
+= ui
.eq(self
.dec
.UI
)
206 comb
+= self
.imm_out
.data
.eq(ui
<< 16)
207 comb
+= self
.imm_out
.ok
.eq(1)
208 with m
.Case(In2Sel
.CONST_LI
): # sign-extend 24+2=26 bit
209 li
= Signal(26, reset_less
=True)
210 comb
+= li
.eq(self
.dec
.LI
<< 2)
211 comb
+= self
.imm_out
.data
.eq(exts(li
, 26, 64))
212 comb
+= self
.imm_out
.ok
.eq(1)
213 with m
.Case(In2Sel
.CONST_BD
): # sign-extend (14+2)=16 bit
214 bd
= Signal(16, reset_less
=True)
215 comb
+= bd
.eq(self
.dec
.BD
<< 2)
216 comb
+= self
.imm_out
.data
.eq(exts(bd
, 16, 64))
217 comb
+= self
.imm_out
.ok
.eq(1)
218 with m
.Case(In2Sel
.CONST_DS
): # sign-extended (14+2=16) bit
219 ds
= Signal(16, reset_less
=True)
220 comb
+= ds
.eq(self
.dec
.DS
<< 2)
221 comb
+= self
.imm_out
.data
.eq(exts(ds
, 16, 64))
222 comb
+= self
.imm_out
.ok
.eq(1)
223 with m
.Case(In2Sel
.CONST_M1
): # signed (-1)
224 comb
+= self
.imm_out
.data
.eq(~
Const(0, 64)) # all 1s
225 comb
+= self
.imm_out
.ok
.eq(1)
226 with m
.Case(In2Sel
.CONST_SH
): # unsigned - for shift
227 comb
+= self
.imm_out
.data
.eq(self
.dec
.sh
)
228 comb
+= self
.imm_out
.ok
.eq(1)
229 with m
.Case(In2Sel
.CONST_SH32
): # unsigned - for shift
230 comb
+= self
.imm_out
.data
.eq(self
.dec
.SH32
)
231 comb
+= self
.imm_out
.ok
.eq(1)
233 # decode SPR2 based on instruction type
235 # BCREG implicitly uses LR or TAR for 2nd reg
236 # CTR however is already in fast_spr1 *not* 2.
237 with m
.If(op
.internal_op
== MicrOp
.OP_BCREG
):
238 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
239 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
241 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
242 comb
+= self
.fast_out
.ok
.eq(1)
244 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
245 comb
+= self
.fast_out
.ok
.eq(1)
250 class DecodeC(Elaboratable
):
251 """DecodeC from instruction
253 decodes register RC. this is "lane 3" into some CompUnits (not many)
256 def __init__(self
, dec
):
258 self
.sel_in
= Signal(In3Sel
, reset_less
=True)
259 self
.insn_in
= Signal(32, reset_less
=True)
260 self
.reg_out
= Data(5, "reg_c")
262 def elaborate(self
, platform
):
266 # select Register C field
267 with m
.Switch(self
.sel_in
):
268 with m
.Case(In3Sel
.RB
):
269 # for M-Form shiftrot
270 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
)
271 comb
+= self
.reg_out
.ok
.eq(1)
272 with m
.Case(In3Sel
.RS
):
273 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
274 comb
+= self
.reg_out
.ok
.eq(1)
279 class DecodeOut(Elaboratable
):
280 """DecodeOut from instruction
282 decodes output register RA, RT or SPR
285 def __init__(self
, dec
):
287 self
.sel_in
= Signal(OutSel
, reset_less
=True)
288 self
.insn_in
= Signal(32, reset_less
=True)
289 self
.reg_out
= Data(5, "reg_o")
290 self
.spr_out
= Data(SPR
, "spr_o")
291 self
.fast_out
= Data(3, "fast_o")
293 def elaborate(self
, platform
):
296 m
.submodules
.sprmap
= sprmap
= SPRMap()
299 # select Register out field
300 with m
.Switch(self
.sel_in
):
301 with m
.Case(OutSel
.RT
):
302 comb
+= self
.reg_out
.data
.eq(self
.dec
.RT
)
303 comb
+= self
.reg_out
.ok
.eq(1)
304 with m
.Case(OutSel
.RA
):
305 comb
+= self
.reg_out
.data
.eq(self
.dec
.RA
)
306 comb
+= self
.reg_out
.ok
.eq(1)
307 with m
.Case(OutSel
.SPR
):
308 spr
= Signal(10, reset_less
=True)
309 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
310 # TODO MTSPR 1st spr (fast)
311 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
314 with m
.Case(SPR
.CTR
.value
):
315 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
316 comb
+= self
.fast_out
.ok
.eq(1)
317 with m
.Case(SPR
.LR
.value
):
318 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
319 comb
+= self
.fast_out
.ok
.eq(1)
320 with m
.Case(SPR
.TAR
.value
):
321 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
322 comb
+= self
.fast_out
.ok
.eq(1)
323 with m
.Case(SPR
.SRR0
.value
):
324 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
)
325 comb
+= self
.fast_out
.ok
.eq(1)
326 with m
.Case(SPR
.SRR1
.value
):
327 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
)
328 comb
+= self
.fast_out
.ok
.eq(1)
329 with m
.Case(SPR
.XER
.value
):
331 # : map to internal SPR numbers
332 # XXX TODO: dec and tb not to go through mapping.
334 comb
+= sprmap
.spr_i
.eq(spr
)
335 comb
+= self
.spr_out
.data
.eq(sprmap
.spr_o
)
336 comb
+= self
.spr_out
.ok
.eq(1)
338 with m
.Switch(op
.internal_op
):
340 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeA
341 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_BCREG
):
342 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
344 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
345 comb
+= self
.fast_out
.ok
.eq(1)
347 # RFID 1st spr (fast)
348 with m
.Case(MicrOp
.OP_RFID
):
349 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
350 comb
+= self
.fast_out
.ok
.eq(1)
355 class DecodeOut2(Elaboratable
):
356 """DecodeOut2 from instruction
358 decodes output registers
361 def __init__(self
, dec
):
363 self
.sel_in
= Signal(OutSel
, reset_less
=True)
364 self
.lk
= Signal(reset_less
=True)
365 self
.insn_in
= Signal(32, reset_less
=True)
366 self
.reg_out
= Data(5, "reg_o")
367 self
.fast_out
= Data(3, "fast_o")
369 def elaborate(self
, platform
):
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_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)
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)
560 comb
+= self
.cr_bitfield
.ok
.eq(0)
561 comb
+= self
.whole_reg
.ok
.eq(0)
562 with m
.Switch(self
.sel_in
):
563 with m
.Case(CROutSel
.NONE
):
564 pass # No bitfield activated
565 with m
.Case(CROutSel
.CR0
):
566 comb
+= self
.cr_bitfield
.data
.eq(0)
567 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
568 with m
.Case(CROutSel
.BF
):
569 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BF
)
570 comb
+= self
.cr_bitfield
.ok
.eq(1)
571 with m
.Case(CROutSel
.BT
):
572 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormXL
.BT
[2:5])
573 comb
+= self
.cr_bitfield
.ok
.eq(1)
574 with m
.Case(CROutSel
.WHOLE_REG
):
575 comb
+= self
.whole_reg
.ok
.eq(1)
576 move_one
= Signal(reset_less
=True)
577 comb
+= move_one
.eq(self
.insn_in
[20])
578 with m
.If((op
.internal_op
== MicrOp
.OP_MTCRF
)):
580 # must one-hot the FXM field
581 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
582 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
584 comb
+= self
.whole_reg
.data
.eq(self
.dec
.FXM
)
586 # otherwise use all of it
587 comb
+= self
.whole_reg
.data
.eq(0xff)
592 class PowerDecode2(Elaboratable
):
593 """PowerDecode2: the main instruction decoder.
595 whilst PowerDecode is responsible for decoding the actual opcode, this
596 module encapsulates further specialist, sparse information and
597 expansion of fields that is inconvenient to have in the CSV files.
598 for example: the encoding of the immediates, which are detected
599 and expanded out to their full value from an annotated (enum)
602 implicit register usage is also set up, here. for example: OP_BC
603 requires implicitly reading CTR, OP_RFID requires implicitly writing
606 in addition, PowerDecoder2 is responsible for detecting whether
607 instructions are illegal (or privileged) or not, and instead of
608 just leaving at that, *replacing* the instruction to execute with
609 a suitable alternative (trap).
612 def __init__(self
, dec
):
615 self
.e
= Decode2ToExecute1Type()
617 # state information needed by the Decoder (TODO: this as a Record)
618 self
.state
= CoreState("dec2")
621 return self
.dec
.ports() + self
.e
.ports()
623 def elaborate(self
, platform
):
626 e_out
, op
, do_out
= self
.e
, self
.dec
.op
, self
.e
.do
627 msr
, cia
= self
.state
.msr
, self
.state
.pc
629 # fill in for a normal instruction (not an exception)
630 # copy over if non-exception, non-privileged etc. is detected
631 e
= Decode2ToExecute1Type()
634 # set up submodule decoders
635 m
.submodules
.dec
= self
.dec
636 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
)
637 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
)
638 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
)
639 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
)
640 m
.submodules
.dec_o2
= dec_o2
= DecodeOut2(self
.dec
)
641 m
.submodules
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
642 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
)
643 m
.submodules
.dec_cr_in
= dec_cr_in
= DecodeCRIn(self
.dec
)
644 m
.submodules
.dec_cr_out
= dec_cr_out
= DecodeCROut(self
.dec
)
646 # copy instruction through...
647 for i
in [do
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
648 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
, dec_rc
.insn_in
,
649 dec_oe
.insn_in
, dec_cr_in
.insn_in
, dec_cr_out
.insn_in
]:
650 comb
+= i
.eq(self
.dec
.opcode_in
)
652 # ...and subdecoders' input fields
653 comb
+= dec_a
.sel_in
.eq(op
.in1_sel
)
654 comb
+= dec_b
.sel_in
.eq(op
.in2_sel
)
655 comb
+= dec_c
.sel_in
.eq(op
.in3_sel
)
656 comb
+= dec_o
.sel_in
.eq(op
.out_sel
)
657 comb
+= dec_o2
.sel_in
.eq(op
.out_sel
)
658 comb
+= dec_o2
.lk
.eq(do
.lk
)
659 comb
+= dec_rc
.sel_in
.eq(op
.rc_sel
)
660 comb
+= dec_oe
.sel_in
.eq(op
.rc_sel
) # XXX should be OE sel
661 comb
+= dec_cr_in
.sel_in
.eq(op
.cr_in
)
662 comb
+= dec_cr_out
.sel_in
.eq(op
.cr_out
)
663 comb
+= dec_cr_out
.rc_in
.eq(dec_rc
.rc_out
.data
)
666 comb
+= do
.msr
.eq(msr
)
667 comb
+= do
.cia
.eq(cia
)
669 # set up instruction, pick fn unit
670 # no op: defaults to OP_ILLEGAL
671 comb
+= do
.insn_type
.eq(op
.internal_op
)
672 comb
+= do
.fn_unit
.eq(op
.function_unit
)
674 # registers a, b, c and out and out2 (LD/ST EA)
675 comb
+= e
.read_reg1
.eq(dec_a
.reg_out
)
676 comb
+= e
.read_reg2
.eq(dec_b
.reg_out
)
677 comb
+= e
.read_reg3
.eq(dec_c
.reg_out
)
678 comb
+= e
.write_reg
.eq(dec_o
.reg_out
)
679 comb
+= e
.write_ea
.eq(dec_o2
.reg_out
)
680 comb
+= do
.imm_data
.eq(dec_b
.imm_out
) # immediate in RB (usually)
681 comb
+= do
.zero_a
.eq(dec_a
.immz_out
) # RA==0 detected
684 comb
+= do
.rc
.eq(dec_rc
.rc_out
)
685 comb
+= do
.oe
.eq(dec_oe
.oe_out
)
688 comb
+= e
.read_spr1
.eq(dec_a
.spr_out
)
689 comb
+= e
.write_spr
.eq(dec_o
.spr_out
)
692 comb
+= e
.read_fast1
.eq(dec_a
.fast_out
)
693 comb
+= e
.read_fast2
.eq(dec_b
.fast_out
)
694 comb
+= e
.write_fast1
.eq(dec_o
.fast_out
)
695 comb
+= e
.write_fast2
.eq(dec_o2
.fast_out
)
697 # condition registers (CR)
698 comb
+= e
.read_cr1
.eq(dec_cr_in
.cr_bitfield
)
699 comb
+= e
.read_cr2
.eq(dec_cr_in
.cr_bitfield_b
)
700 comb
+= e
.read_cr3
.eq(dec_cr_in
.cr_bitfield_o
)
701 comb
+= e
.write_cr
.eq(dec_cr_out
.cr_bitfield
)
703 comb
+= do
.read_cr_whole
.eq(dec_cr_in
.whole_reg
)
704 comb
+= do
.write_cr_whole
.eq(dec_cr_out
.whole_reg
)
705 comb
+= do
.write_cr0
.eq(dec_cr_out
.cr_bitfield
.ok
)
707 # decoded/selected instruction flags
708 comb
+= do
.data_len
.eq(op
.ldst_len
)
709 comb
+= do
.invert_in
.eq(op
.inv_a
)
710 comb
+= do
.invert_out
.eq(op
.inv_out
)
711 comb
+= do
.input_carry
.eq(op
.cry_in
) # carry comes in
712 comb
+= do
.output_carry
.eq(op
.cry_out
) # carry goes out
713 comb
+= do
.is_32bit
.eq(op
.is_32b
)
714 comb
+= do
.is_signed
.eq(op
.sgn
)
716 comb
+= do
.lk
.eq(self
.dec
.LK
) # XXX TODO: accessor
718 comb
+= do
.byte_reverse
.eq(op
.br
)
719 comb
+= do
.sign_extend
.eq(op
.sgn_ext
)
720 comb
+= do
.ldst_mode
.eq(op
.upd
) # LD/ST mode (update, cache-inhibit)
722 # These should be removed eventually
723 comb
+= do
.input_cr
.eq(op
.cr_in
) # condition reg comes in
724 comb
+= do
.output_cr
.eq(op
.cr_out
) # condition reg goes in
726 # sigh this is exactly the sort of thing for which the
727 # decoder is designed to not need. MTSPR, MFSPR and others need
728 # access to the XER bits. however setting e.oe is not appropriate
729 with m
.If(op
.internal_op
== MicrOp
.OP_MFSPR
):
730 comb
+= e
.xer_in
.eq(1)
731 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
732 comb
+= e
.xer_out
.eq(1)
734 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
735 with m
.If(op
.internal_op
== MicrOp
.OP_TRAP
):
736 # *DO NOT* call self.trap here. that would reset absolutely
737 # rverything including destroying read of RA and RB.
738 comb
+= do
.trapaddr
.eq(0x70) # addr=0x700 (strip first nibble)
740 # TODO: get msr, then can do privileged instruction
741 with m
.If(instr_is_priv(m
, op
.internal_op
, e
.do
.insn
) & msr
[MSR
.PR
]):
742 # privileged instruction trap
743 self
.trap(m
, TT
.PRIV
, 0x700)
745 # illegal instruction must redirect to trap. this is done by
746 # *overwriting* the decoded instruction and starting again.
747 # (note: the same goes for interrupts and for privileged operations,
748 # just with different trapaddr and traptype)
749 with m
.Elif(op
.internal_op
== MicrOp
.OP_ILLEGAL
):
750 # illegal instruction trap
751 self
.trap(m
, TT
.ILLEG
, 0x700)
753 # no exception, just copy things to the output
757 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
758 # Note: OP_SC could actually be modified to just be a trap
759 with m
.If((do_out
.insn_type
== MicrOp
.OP_TRAP
) |
760 (do_out
.insn_type
== MicrOp
.OP_SC
)):
761 # TRAP write fast1 = SRR0
762 comb
+= e_out
.write_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
763 comb
+= e_out
.write_fast1
.ok
.eq(1)
764 # TRAP write fast2 = SRR1
765 comb
+= e_out
.write_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
766 comb
+= e_out
.write_fast2
.ok
.eq(1)
768 # RFID: needs to read SRR0/1
769 with m
.If(do_out
.insn_type
== MicrOp
.OP_RFID
):
770 # TRAP read fast1 = SRR0
771 comb
+= e_out
.read_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
772 comb
+= e_out
.read_fast1
.ok
.eq(1)
773 # TRAP read fast2 = SRR1
774 comb
+= e_out
.read_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
775 comb
+= e_out
.read_fast2
.ok
.eq(1)
779 def trap(self
, m
, traptype
, trapaddr
):
780 """trap: this basically "rewrites" the decoded instruction as a trap
783 op
, do
, e
= self
.dec
.op
, self
.e
.do
, self
.e
784 comb
+= e
.eq(0) # reset eeeeeverything
787 comb
+= do
.insn
.eq(self
.dec
.opcode_in
)
788 comb
+= do
.insn_type
.eq(MicrOp
.OP_TRAP
)
789 comb
+= do
.fn_unit
.eq(Function
.TRAP
)
790 comb
+= do
.trapaddr
.eq(trapaddr
>> 4) # cut bottom 4 bits
791 comb
+= do
.traptype
.eq(traptype
) # request type
792 comb
+= do
.msr
.eq(self
.state
.msr
) # copy of MSR "state"
793 comb
+= do
.cia
.eq(self
.state
.pc
) # copy of PC "state"
796 def get_rdflags(e
, cu
):
798 for idx
in range(cu
.n_src
):
799 regfile
, regname
, _
= cu
.get_in_spec(idx
)
800 rdflag
, read
= regspec_decode_read(e
, regfile
, regname
)
802 print("rdflags", rdl
)
806 if __name__
== '__main__':
807 pdecode
= create_pdecode()
808 dec2
= PowerDecode2(pdecode
)
809 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
810 with
open("dec2.il", "w") as f
: