83238391b1b666fcf273a17e11bd025267f65b86
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
):
150 comb
+= self
.fast_out
.data
.eq(FastRegs
.XER
)
151 comb
+= self
.fast_out
.ok
.eq(1)
153 # : map to internal SPR numbers
154 # XXX TODO: dec and tb not to go through mapping.
156 comb
+= sprmap
.spr_i
.eq(spr
)
157 comb
+= self
.spr_out
.data
.eq(sprmap
.spr_o
)
158 comb
+= self
.spr_out
.ok
.eq(1)
163 class DecodeB(Elaboratable
):
164 """DecodeB from instruction
166 decodes register RB, different forms of immediate (signed, unsigned),
167 and implicit SPRs. register B is basically "lane 2" into the CompUnits.
168 by industry-standard convention, "lane 2" is where fully-decoded
169 immediates are muxed in.
172 def __init__(self
, dec
):
174 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
175 self
.insn_in
= Signal(32, reset_less
=True)
176 self
.reg_out
= Data(5, "reg_b")
177 self
.imm_out
= Data(64, "imm_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)
193 with m
.Case(In2Sel
.CONST_UI
): # unsigned
194 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
)
195 comb
+= self
.imm_out
.ok
.eq(1)
196 with m
.Case(In2Sel
.CONST_SI
): # sign-extended 16-bit
197 si
= Signal(16, reset_less
=True)
198 comb
+= si
.eq(self
.dec
.SI
)
199 comb
+= self
.imm_out
.data
.eq(exts(si
, 16, 64))
200 comb
+= self
.imm_out
.ok
.eq(1)
201 with m
.Case(In2Sel
.CONST_SI_HI
): # sign-extended 16+16=32 bit
202 si_hi
= Signal(32, reset_less
=True)
203 comb
+= si_hi
.eq(self
.dec
.SI
<< 16)
204 comb
+= self
.imm_out
.data
.eq(exts(si_hi
, 32, 64))
205 comb
+= self
.imm_out
.ok
.eq(1)
206 with m
.Case(In2Sel
.CONST_UI_HI
): # unsigned
207 ui
= Signal(16, reset_less
=True)
208 comb
+= ui
.eq(self
.dec
.UI
)
209 comb
+= self
.imm_out
.data
.eq(ui
<< 16)
210 comb
+= self
.imm_out
.ok
.eq(1)
211 with m
.Case(In2Sel
.CONST_LI
): # sign-extend 24+2=26 bit
212 li
= Signal(26, reset_less
=True)
213 comb
+= li
.eq(self
.dec
.LI
<< 2)
214 comb
+= self
.imm_out
.data
.eq(exts(li
, 26, 64))
215 comb
+= self
.imm_out
.ok
.eq(1)
216 with m
.Case(In2Sel
.CONST_BD
): # sign-extend (14+2)=16 bit
217 bd
= Signal(16, reset_less
=True)
218 comb
+= bd
.eq(self
.dec
.BD
<< 2)
219 comb
+= self
.imm_out
.data
.eq(exts(bd
, 16, 64))
220 comb
+= self
.imm_out
.ok
.eq(1)
221 with m
.Case(In2Sel
.CONST_DS
): # sign-extended (14+2=16) bit
222 ds
= Signal(16, reset_less
=True)
223 comb
+= ds
.eq(self
.dec
.DS
<< 2)
224 comb
+= self
.imm_out
.data
.eq(exts(ds
, 16, 64))
225 comb
+= self
.imm_out
.ok
.eq(1)
226 with m
.Case(In2Sel
.CONST_M1
): # signed (-1)
227 comb
+= self
.imm_out
.data
.eq(~
Const(0, 64)) # all 1s
228 comb
+= self
.imm_out
.ok
.eq(1)
229 with m
.Case(In2Sel
.CONST_SH
): # unsigned - for shift
230 comb
+= self
.imm_out
.data
.eq(self
.dec
.sh
)
231 comb
+= self
.imm_out
.ok
.eq(1)
232 with m
.Case(In2Sel
.CONST_SH32
): # unsigned - for shift
233 comb
+= self
.imm_out
.data
.eq(self
.dec
.SH32
)
234 comb
+= self
.imm_out
.ok
.eq(1)
236 # decode SPR2 based on instruction type
238 # BCREG implicitly uses LR or TAR for 2nd reg
239 # CTR however is already in fast_spr1 *not* 2.
240 with m
.If(op
.internal_op
== MicrOp
.OP_BCREG
):
241 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
242 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
244 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
245 comb
+= self
.fast_out
.ok
.eq(1)
247 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
248 comb
+= self
.fast_out
.ok
.eq(1)
253 class DecodeC(Elaboratable
):
254 """DecodeC from instruction
256 decodes register RC. this is "lane 3" into some CompUnits (not many)
259 def __init__(self
, dec
):
261 self
.sel_in
= Signal(In3Sel
, reset_less
=True)
262 self
.insn_in
= Signal(32, reset_less
=True)
263 self
.reg_out
= Data(5, "reg_c")
265 def elaborate(self
, platform
):
269 # select Register C field
270 with m
.Switch(self
.sel_in
):
271 with m
.Case(In3Sel
.RB
):
272 # for M-Form shiftrot
273 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
)
274 comb
+= self
.reg_out
.ok
.eq(1)
275 with m
.Case(In3Sel
.RS
):
276 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
277 comb
+= self
.reg_out
.ok
.eq(1)
282 class DecodeOut(Elaboratable
):
283 """DecodeOut from instruction
285 decodes output register RA, RT or SPR
288 def __init__(self
, dec
):
290 self
.sel_in
= Signal(OutSel
, reset_less
=True)
291 self
.insn_in
= Signal(32, reset_less
=True)
292 self
.reg_out
= Data(5, "reg_o")
293 self
.spr_out
= Data(SPR
, "spr_o")
294 self
.fast_out
= Data(3, "fast_o")
296 def elaborate(self
, platform
):
299 m
.submodules
.sprmap
= sprmap
= SPRMap()
302 # select Register out field
303 with m
.Switch(self
.sel_in
):
304 with m
.Case(OutSel
.RT
):
305 comb
+= self
.reg_out
.data
.eq(self
.dec
.RT
)
306 comb
+= self
.reg_out
.ok
.eq(1)
307 with m
.Case(OutSel
.RA
):
308 comb
+= self
.reg_out
.data
.eq(self
.dec
.RA
)
309 comb
+= self
.reg_out
.ok
.eq(1)
310 with m
.Case(OutSel
.SPR
):
311 spr
= Signal(10, reset_less
=True)
312 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
313 # TODO MTSPR 1st spr (fast)
314 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
317 with m
.Case(SPR
.CTR
.value
):
318 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
319 comb
+= self
.fast_out
.ok
.eq(1)
320 with m
.Case(SPR
.LR
.value
):
321 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
322 comb
+= self
.fast_out
.ok
.eq(1)
323 with m
.Case(SPR
.TAR
.value
):
324 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
325 comb
+= self
.fast_out
.ok
.eq(1)
326 with m
.Case(SPR
.SRR0
.value
):
327 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
)
328 comb
+= self
.fast_out
.ok
.eq(1)
329 with m
.Case(SPR
.SRR1
.value
):
330 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
)
331 comb
+= self
.fast_out
.ok
.eq(1)
332 with m
.Case(SPR
.XER
.value
):
333 comb
+= self
.fast_out
.data
.eq(FastRegs
.XER
)
334 comb
+= self
.fast_out
.ok
.eq(1)
336 # : map to internal SPR numbers
337 # XXX TODO: dec and tb not to go through mapping.
339 comb
+= sprmap
.spr_i
.eq(spr
)
340 comb
+= self
.spr_out
.data
.eq(sprmap
.spr_o
)
341 comb
+= self
.spr_out
.ok
.eq(1)
343 with m
.Switch(op
.internal_op
):
345 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeA
346 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_BCREG
):
347 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
349 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
350 comb
+= self
.fast_out
.ok
.eq(1)
352 # RFID 1st spr (fast)
353 with m
.Case(MicrOp
.OP_RFID
):
354 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
355 comb
+= self
.fast_out
.ok
.eq(1)
360 class DecodeOut2(Elaboratable
):
361 """DecodeOut2 from instruction
363 decodes output registers
366 def __init__(self
, dec
):
368 self
.sel_in
= Signal(OutSel
, reset_less
=True)
369 self
.lk
= Signal(reset_less
=True)
370 self
.insn_in
= Signal(32, reset_less
=True)
371 self
.reg_out
= Data(5, "reg_o")
372 self
.fast_out
= Data(3, "fast_o")
374 def elaborate(self
, platform
):
378 # update mode LD/ST uses read-reg A also as an output
379 with m
.If(self
.dec
.op
.upd
== LDSTMode
.update
):
380 comb
+= self
.reg_out
.eq(self
.dec
.RA
)
381 comb
+= self
.reg_out
.ok
.eq(1)
383 # B, BC or BCREG: potential implicit register (LR) output
384 # these give bl, bcl, bclrl, etc.
386 with m
.Switch(op
.internal_op
):
388 # BC* implicit register (LR)
389 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_B
, MicrOp
.OP_BCREG
):
390 with m
.If(self
.lk
): # "link" mode
391 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
) # constant: LR
392 comb
+= self
.fast_out
.ok
.eq(1)
394 # RFID 2nd spr (fast)
395 with m
.Case(MicrOp
.OP_RFID
):
396 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
397 comb
+= self
.fast_out
.ok
.eq(1)
402 class DecodeRC(Elaboratable
):
403 """DecodeRc from instruction
405 decodes Record bit Rc
408 def __init__(self
, dec
):
410 self
.sel_in
= Signal(RC
, reset_less
=True)
411 self
.insn_in
= Signal(32, reset_less
=True)
412 self
.rc_out
= Data(1, "rc")
414 def elaborate(self
, platform
):
418 # select Record bit out field
419 with m
.Switch(self
.sel_in
):
421 comb
+= self
.rc_out
.data
.eq(self
.dec
.Rc
)
422 comb
+= self
.rc_out
.ok
.eq(1)
424 comb
+= self
.rc_out
.data
.eq(1)
425 comb
+= self
.rc_out
.ok
.eq(1)
426 with m
.Case(RC
.NONE
):
427 comb
+= self
.rc_out
.data
.eq(0)
428 comb
+= self
.rc_out
.ok
.eq(1)
433 class DecodeOE(Elaboratable
):
434 """DecodeOE from instruction
436 decodes OE field: uses RC decode detection which might not be good
438 -- For now, use "rc" in the decode table to decide whether oe exists.
439 -- This is not entirely correct architecturally: For mulhd and
440 -- mulhdu, the OE field is reserved. It remains to be seen what an
441 -- actual POWER9 does if we set it on those instructions, for now we
442 -- test that further down when assigning to the multiplier oe input.
445 def __init__(self
, dec
):
447 self
.sel_in
= Signal(RC
, reset_less
=True)
448 self
.insn_in
= Signal(32, reset_less
=True)
449 self
.oe_out
= Data(1, "oe")
451 def elaborate(self
, platform
):
456 with m
.Switch(op
.internal_op
):
458 # mulhw, mulhwu, mulhd, mulhdu - these *ignore* OE
460 # XXX ARGH! ignoring OE causes incompatibility with microwatt
461 # http://lists.libre-soc.org/pipermail/libre-soc-dev/2020-August/000302.html
462 with m
.Case(MicrOp
.OP_MUL_H64
, MicrOp
.OP_MUL_H32
,
463 MicrOp
.OP_EXTS
, MicrOp
.OP_CNTZ
,
464 MicrOp
.OP_SHL
, MicrOp
.OP_SHR
, MicrOp
.OP_RLC
,
465 MicrOp
.OP_LOAD
, MicrOp
.OP_STORE
,
466 MicrOp
.OP_RLCL
, MicrOp
.OP_RLCR
,
470 # all other ops decode OE field
472 # select OE bit out field
473 with m
.Switch(self
.sel_in
):
475 comb
+= self
.oe_out
.data
.eq(self
.dec
.OE
)
476 comb
+= self
.oe_out
.ok
.eq(1)
481 class DecodeCRIn(Elaboratable
):
482 """Decodes input CR from instruction
484 CR indices - insn fields - (not the data *in* the CR) require only 3
485 bits because they refer to CR0-CR7
488 def __init__(self
, dec
):
490 self
.sel_in
= Signal(CRInSel
, reset_less
=True)
491 self
.insn_in
= Signal(32, reset_less
=True)
492 self
.cr_bitfield
= Data(3, "cr_bitfield")
493 self
.cr_bitfield_b
= Data(3, "cr_bitfield_b")
494 self
.cr_bitfield_o
= Data(3, "cr_bitfield_o")
495 self
.whole_reg
= Data(8, "cr_fxm")
497 def elaborate(self
, platform
):
499 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
505 comb
+= self
.cr_bitfield
.ok
.eq(0)
506 comb
+= self
.cr_bitfield_b
.ok
.eq(0)
507 comb
+= self
.whole_reg
.ok
.eq(0)
508 with m
.Switch(self
.sel_in
):
509 with m
.Case(CRInSel
.NONE
):
510 pass # No bitfield activated
511 with m
.Case(CRInSel
.CR0
):
512 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
513 comb
+= self
.cr_bitfield
.ok
.eq(1)
514 with m
.Case(CRInSel
.BI
):
515 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BI
[2:5])
516 comb
+= self
.cr_bitfield
.ok
.eq(1)
517 with m
.Case(CRInSel
.BFA
):
518 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BFA
)
519 comb
+= self
.cr_bitfield
.ok
.eq(1)
520 with m
.Case(CRInSel
.BA_BB
):
521 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BA
[2:5])
522 comb
+= self
.cr_bitfield
.ok
.eq(1)
523 comb
+= self
.cr_bitfield_b
.data
.eq(self
.dec
.BB
[2:5])
524 comb
+= self
.cr_bitfield_b
.ok
.eq(1)
525 comb
+= self
.cr_bitfield_o
.data
.eq(self
.dec
.BT
[2:5])
526 comb
+= self
.cr_bitfield_o
.ok
.eq(1)
527 with m
.Case(CRInSel
.BC
):
528 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BC
[2:5])
529 comb
+= self
.cr_bitfield
.ok
.eq(1)
530 with m
.Case(CRInSel
.WHOLE_REG
):
531 comb
+= self
.whole_reg
.ok
.eq(1)
532 move_one
= Signal(reset_less
=True)
533 comb
+= move_one
.eq(self
.insn_in
[20]) # MSB0 bit 11
534 with m
.If((op
.internal_op
== MicrOp
.OP_MFCR
) & move_one
):
535 # must one-hot the FXM field
536 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
537 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
539 # otherwise use all of it
540 comb
+= self
.whole_reg
.data
.eq(0xff)
545 class DecodeCROut(Elaboratable
):
546 """Decodes input CR from instruction
548 CR indices - insn fields - (not the data *in* the CR) require only 3
549 bits because they refer to CR0-CR7
552 def __init__(self
, dec
):
554 self
.rc_in
= Signal(reset_less
=True)
555 self
.sel_in
= Signal(CROutSel
, reset_less
=True)
556 self
.insn_in
= Signal(32, reset_less
=True)
557 self
.cr_bitfield
= Data(3, "cr_bitfield")
558 self
.whole_reg
= Data(8, "cr_fxm")
560 def elaborate(self
, platform
):
564 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
567 comb
+= self
.cr_bitfield
.ok
.eq(0)
568 comb
+= self
.whole_reg
.ok
.eq(0)
569 with m
.Switch(self
.sel_in
):
570 with m
.Case(CROutSel
.NONE
):
571 pass # No bitfield activated
572 with m
.Case(CROutSel
.CR0
):
573 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
574 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
575 with m
.Case(CROutSel
.BF
):
576 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BF
)
577 comb
+= self
.cr_bitfield
.ok
.eq(1)
578 with m
.Case(CROutSel
.BT
):
579 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormXL
.BT
[2:5])
580 comb
+= self
.cr_bitfield
.ok
.eq(1)
581 with m
.Case(CROutSel
.WHOLE_REG
):
582 comb
+= self
.whole_reg
.ok
.eq(1)
583 move_one
= Signal(reset_less
=True)
584 comb
+= move_one
.eq(self
.insn_in
[20])
585 with m
.If((op
.internal_op
== MicrOp
.OP_MTCRF
)):
587 # must one-hot the FXM field
588 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
589 with m
.If(ppick
.en_o
):
590 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
592 comb
+= self
.whole_reg
.data
.eq(0b00000001) # CR7
594 comb
+= self
.whole_reg
.data
.eq(self
.dec
.FXM
)
596 # otherwise use all of it
597 comb
+= self
.whole_reg
.data
.eq(0xff)
602 class PowerDecode2(Elaboratable
):
603 """PowerDecode2: the main instruction decoder.
605 whilst PowerDecode is responsible for decoding the actual opcode, this
606 module encapsulates further specialist, sparse information and
607 expansion of fields that is inconvenient to have in the CSV files.
608 for example: the encoding of the immediates, which are detected
609 and expanded out to their full value from an annotated (enum)
612 implicit register usage is also set up, here. for example: OP_BC
613 requires implicitly reading CTR, OP_RFID requires implicitly writing
616 in addition, PowerDecoder2 is responsible for detecting whether
617 instructions are illegal (or privileged) or not, and instead of
618 just leaving at that, *replacing* the instruction to execute with
619 a suitable alternative (trap).
622 def __init__(self
, dec
):
625 self
.e
= Decode2ToExecute1Type()
627 # state information needed by the Decoder (TODO: this as a Record)
628 self
.state
= CoreState("dec2")
631 return self
.dec
.ports() + self
.e
.ports()
633 def elaborate(self
, platform
):
637 e_out
, op
, do_out
= self
.e
, self
.dec
.op
, self
.e
.do
638 dec_spr
, msr
, cia
, ext_irq
= state
.dec
, state
.msr
, state
.pc
, state
.eint
640 # fill in for a normal instruction (not an exception)
641 # copy over if non-exception, non-privileged etc. is detected
642 e
= Decode2ToExecute1Type()
645 # set up submodule decoders
646 m
.submodules
.dec
= self
.dec
647 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
)
648 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
)
649 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
)
650 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
)
651 m
.submodules
.dec_o2
= dec_o2
= DecodeOut2(self
.dec
)
652 m
.submodules
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
653 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
)
654 m
.submodules
.dec_cr_in
= dec_cr_in
= DecodeCRIn(self
.dec
)
655 m
.submodules
.dec_cr_out
= dec_cr_out
= DecodeCROut(self
.dec
)
657 # copy instruction through...
658 for i
in [do
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
659 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
, dec_rc
.insn_in
,
660 dec_oe
.insn_in
, dec_cr_in
.insn_in
, dec_cr_out
.insn_in
]:
661 comb
+= i
.eq(self
.dec
.opcode_in
)
663 # ...and subdecoders' input fields
664 comb
+= dec_a
.sel_in
.eq(op
.in1_sel
)
665 comb
+= dec_b
.sel_in
.eq(op
.in2_sel
)
666 comb
+= dec_c
.sel_in
.eq(op
.in3_sel
)
667 comb
+= dec_o
.sel_in
.eq(op
.out_sel
)
668 comb
+= dec_o2
.sel_in
.eq(op
.out_sel
)
669 comb
+= dec_o2
.lk
.eq(do
.lk
)
670 comb
+= dec_rc
.sel_in
.eq(op
.rc_sel
)
671 comb
+= dec_oe
.sel_in
.eq(op
.rc_sel
) # XXX should be OE sel
672 comb
+= dec_cr_in
.sel_in
.eq(op
.cr_in
)
673 comb
+= dec_cr_out
.sel_in
.eq(op
.cr_out
)
674 comb
+= dec_cr_out
.rc_in
.eq(dec_rc
.rc_out
.data
)
677 comb
+= do
.msr
.eq(msr
)
678 comb
+= do
.cia
.eq(cia
)
680 # set up instruction, pick fn unit
681 # no op: defaults to OP_ILLEGAL
682 comb
+= do
.insn_type
.eq(op
.internal_op
)
683 comb
+= do
.fn_unit
.eq(op
.function_unit
)
685 # registers a, b, c and out and out2 (LD/ST EA)
686 comb
+= e
.read_reg1
.eq(dec_a
.reg_out
)
687 comb
+= e
.read_reg2
.eq(dec_b
.reg_out
)
688 comb
+= e
.read_reg3
.eq(dec_c
.reg_out
)
689 comb
+= e
.write_reg
.eq(dec_o
.reg_out
)
690 comb
+= e
.write_ea
.eq(dec_o2
.reg_out
)
691 comb
+= do
.imm_data
.eq(dec_b
.imm_out
) # immediate in RB (usually)
692 comb
+= do
.zero_a
.eq(dec_a
.immz_out
) # RA==0 detected
695 comb
+= do
.rc
.eq(dec_rc
.rc_out
)
696 comb
+= do
.oe
.eq(dec_oe
.oe_out
)
699 comb
+= e
.read_spr1
.eq(dec_a
.spr_out
)
700 comb
+= e
.write_spr
.eq(dec_o
.spr_out
)
703 comb
+= e
.read_fast1
.eq(dec_a
.fast_out
)
704 comb
+= e
.read_fast2
.eq(dec_b
.fast_out
)
705 comb
+= e
.write_fast1
.eq(dec_o
.fast_out
)
706 comb
+= e
.write_fast2
.eq(dec_o2
.fast_out
)
708 # condition registers (CR)
709 comb
+= e
.read_cr1
.eq(dec_cr_in
.cr_bitfield
)
710 comb
+= e
.read_cr2
.eq(dec_cr_in
.cr_bitfield_b
)
711 comb
+= e
.read_cr3
.eq(dec_cr_in
.cr_bitfield_o
)
712 comb
+= e
.write_cr
.eq(dec_cr_out
.cr_bitfield
)
714 comb
+= do
.read_cr_whole
.eq(dec_cr_in
.whole_reg
)
715 comb
+= do
.write_cr_whole
.eq(dec_cr_out
.whole_reg
)
716 comb
+= do
.write_cr0
.eq(dec_cr_out
.cr_bitfield
.ok
)
718 # decoded/selected instruction flags
719 comb
+= do
.data_len
.eq(op
.ldst_len
)
720 comb
+= do
.invert_in
.eq(op
.inv_a
)
721 comb
+= do
.invert_out
.eq(op
.inv_out
)
722 comb
+= do
.input_carry
.eq(op
.cry_in
) # carry comes in
723 comb
+= do
.output_carry
.eq(op
.cry_out
) # carry goes out
724 comb
+= do
.is_32bit
.eq(op
.is_32b
)
725 comb
+= do
.is_signed
.eq(op
.sgn
)
727 comb
+= do
.lk
.eq(self
.dec
.LK
) # XXX TODO: accessor
729 comb
+= do
.byte_reverse
.eq(op
.br
)
730 comb
+= do
.sign_extend
.eq(op
.sgn_ext
)
731 comb
+= do
.ldst_mode
.eq(op
.upd
) # LD/ST mode (update, cache-inhibit)
733 # These should be removed eventually
734 comb
+= do
.input_cr
.eq(op
.cr_in
) # condition reg comes in
735 comb
+= do
.output_cr
.eq(op
.cr_out
) # condition reg goes in
737 # sigh this is exactly the sort of thing for which the
738 # decoder is designed to not need. MTSPR, MFSPR and others need
739 # access to the XER bits. however setting e.oe is not appropriate
740 with m
.If(op
.internal_op
== MicrOp
.OP_MFSPR
):
741 comb
+= e
.xer_in
.eq(0b111) # SO, CA, OV
742 with m
.If(op
.internal_op
== MicrOp
.OP_CMP
):
743 comb
+= e
.xer_in
.eq(1<<XERRegs
.SO
) # SO
744 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
745 comb
+= e
.xer_out
.eq(1)
747 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
748 with m
.If(op
.internal_op
== MicrOp
.OP_TRAP
):
749 # *DO NOT* call self.trap here. that would reset absolutely
750 # rverything including destroying read of RA and RB.
751 comb
+= do
.trapaddr
.eq(0x70) # addr=0x700 (strip first nibble)
753 # check if instruction is privileged
754 is_priv_insn
= instr_is_priv(m
, op
.internal_op
, e
.do
.insn
)
756 # external interrupt?
757 with m
.If(ext_irq
& msr
[MSR
.EE
]):
758 self
.trap(m
, TT
.EINT
, 0x500)
760 # decrement counter: TODO 32-bit version (MSR.LPCR)
761 with m
.If(dec_spr
[63] & msr
[MSR
.EE
]): # v3.0B 6.5.11 p1076
762 self
.trap(m
, TT
.DEC
, 0x900) # v3.0B 6.5 p1065
764 # privileged instruction trap
765 with m
.Elif(is_priv_insn
& msr
[MSR
.PR
]):
766 self
.trap(m
, TT
.PRIV
, 0x700)
768 # illegal instruction must redirect to trap. this is done by
769 # *overwriting* the decoded instruction and starting again.
770 # (note: the same goes for interrupts and for privileged operations,
771 # just with different trapaddr and traptype)
772 with m
.Elif(op
.internal_op
== MicrOp
.OP_ILLEGAL
):
773 # illegal instruction trap
774 self
.trap(m
, TT
.ILLEG
, 0x700)
776 # no exception, just copy things to the output
780 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
781 # Note: OP_SC could actually be modified to just be a trap
782 with m
.If((do_out
.insn_type
== MicrOp
.OP_TRAP
) |
783 (do_out
.insn_type
== MicrOp
.OP_SC
)):
784 # TRAP write fast1 = SRR0
785 comb
+= e_out
.write_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
786 comb
+= e_out
.write_fast1
.ok
.eq(1)
787 # TRAP write fast2 = SRR1
788 comb
+= e_out
.write_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
789 comb
+= e_out
.write_fast2
.ok
.eq(1)
791 # RFID: needs to read SRR0/1
792 with m
.If(do_out
.insn_type
== MicrOp
.OP_RFID
):
793 # TRAP read fast1 = SRR0
794 comb
+= e_out
.read_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
795 comb
+= e_out
.read_fast1
.ok
.eq(1)
796 # TRAP read fast2 = SRR1
797 comb
+= e_out
.read_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
798 comb
+= e_out
.read_fast2
.ok
.eq(1)
802 def trap(self
, m
, traptype
, trapaddr
):
803 """trap: this basically "rewrites" the decoded instruction as a trap
806 op
, do
, e
= self
.dec
.op
, self
.e
.do
, self
.e
807 comb
+= e
.eq(0) # reset eeeeeverything
810 comb
+= do
.insn
.eq(self
.dec
.opcode_in
)
811 comb
+= do
.insn_type
.eq(MicrOp
.OP_TRAP
)
812 comb
+= do
.fn_unit
.eq(Function
.TRAP
)
813 comb
+= do
.trapaddr
.eq(trapaddr
>> 4) # cut bottom 4 bits
814 comb
+= do
.traptype
.eq(traptype
) # request type
815 comb
+= do
.msr
.eq(self
.state
.msr
) # copy of MSR "state"
816 comb
+= do
.cia
.eq(self
.state
.pc
) # copy of PC "state"
819 def get_rdflags(e
, cu
):
821 for idx
in range(cu
.n_src
):
822 regfile
, regname
, _
= cu
.get_in_spec(idx
)
823 rdflag
, read
= regspec_decode_read(e
, regfile
, regname
)
825 print("rdflags", rdl
)
829 if __name__
== '__main__':
830 pdecode
= create_pdecode()
831 dec2
= PowerDecode2(pdecode
)
832 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
833 with
open("dec2.il", "w") as f
: