0f2a48601d2c02f42fdca87be406745180168fc0
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_SHL
, MicrOp
.OP_SHR
, MicrOp
.OP_RLC
,
459 MicrOp
.OP_RLCL
, MicrOp
.OP_RLCR
,
463 # all other ops decode OE field
465 # select OE bit out field
466 with m
.Switch(self
.sel_in
):
468 comb
+= self
.oe_out
.data
.eq(self
.dec
.OE
)
469 comb
+= self
.oe_out
.ok
.eq(1)
474 class DecodeCRIn(Elaboratable
):
475 """Decodes input CR from instruction
477 CR indices - insn fields - (not the data *in* the CR) require only 3
478 bits because they refer to CR0-CR7
481 def __init__(self
, dec
):
483 self
.sel_in
= Signal(CRInSel
, reset_less
=True)
484 self
.insn_in
= Signal(32, reset_less
=True)
485 self
.cr_bitfield
= Data(3, "cr_bitfield")
486 self
.cr_bitfield_b
= Data(3, "cr_bitfield_b")
487 self
.cr_bitfield_o
= Data(3, "cr_bitfield_o")
488 self
.whole_reg
= Data(8, "cr_fxm")
490 def elaborate(self
, platform
):
492 m
.submodules
.ppick
= ppick
= PriorityPicker(8)#reverse_i=True)
497 comb
+= self
.cr_bitfield
.ok
.eq(0)
498 comb
+= self
.cr_bitfield_b
.ok
.eq(0)
499 comb
+= self
.whole_reg
.ok
.eq(0)
500 with m
.Switch(self
.sel_in
):
501 with m
.Case(CRInSel
.NONE
):
502 pass # No bitfield activated
503 with m
.Case(CRInSel
.CR0
):
504 comb
+= self
.cr_bitfield
.data
.eq(0)
505 comb
+= self
.cr_bitfield
.ok
.eq(1)
506 with m
.Case(CRInSel
.BI
):
507 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BI
[2:5])
508 comb
+= self
.cr_bitfield
.ok
.eq(1)
509 with m
.Case(CRInSel
.BFA
):
510 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BFA
)
511 comb
+= self
.cr_bitfield
.ok
.eq(1)
512 with m
.Case(CRInSel
.BA_BB
):
513 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BA
[2:5])
514 comb
+= self
.cr_bitfield
.ok
.eq(1)
515 comb
+= self
.cr_bitfield_b
.data
.eq(self
.dec
.BB
[2:5])
516 comb
+= self
.cr_bitfield_b
.ok
.eq(1)
517 comb
+= self
.cr_bitfield_o
.data
.eq(self
.dec
.BT
[2:5])
518 comb
+= self
.cr_bitfield_o
.ok
.eq(1)
519 with m
.Case(CRInSel
.BC
):
520 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BC
[2:5])
521 comb
+= self
.cr_bitfield
.ok
.eq(1)
522 with m
.Case(CRInSel
.WHOLE_REG
):
523 comb
+= self
.whole_reg
.ok
.eq(1)
524 move_one
= Signal(reset_less
=True)
525 comb
+= move_one
.eq(self
.insn_in
[20]) # MSB0 bit 11
526 with m
.If((op
.internal_op
== MicrOp
.OP_MFCR
) & move_one
):
527 # must one-hot the FXM field
528 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
529 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
531 # otherwise use all of it
532 comb
+= self
.whole_reg
.data
.eq(0xff)
537 class DecodeCROut(Elaboratable
):
538 """Decodes input CR from instruction
540 CR indices - insn fields - (not the data *in* the CR) require only 3
541 bits because they refer to CR0-CR7
544 def __init__(self
, dec
):
546 self
.rc_in
= Signal(reset_less
=True)
547 self
.sel_in
= Signal(CROutSel
, reset_less
=True)
548 self
.insn_in
= Signal(32, reset_less
=True)
549 self
.cr_bitfield
= Data(3, "cr_bitfield")
550 self
.whole_reg
= Data(8, "cr_fxm")
552 def elaborate(self
, platform
):
556 m
.submodules
.ppick
= ppick
= PriorityPicker(8)
558 comb
+= self
.cr_bitfield
.ok
.eq(0)
559 comb
+= self
.whole_reg
.ok
.eq(0)
560 with m
.Switch(self
.sel_in
):
561 with m
.Case(CROutSel
.NONE
):
562 pass # No bitfield activated
563 with m
.Case(CROutSel
.CR0
):
564 comb
+= self
.cr_bitfield
.data
.eq(0)
565 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
566 with m
.Case(CROutSel
.BF
):
567 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BF
)
568 comb
+= self
.cr_bitfield
.ok
.eq(1)
569 with m
.Case(CROutSel
.BT
):
570 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormXL
.BT
[2:5])
571 comb
+= self
.cr_bitfield
.ok
.eq(1)
572 with m
.Case(CROutSel
.WHOLE_REG
):
573 comb
+= self
.whole_reg
.ok
.eq(1)
574 move_one
= Signal(reset_less
=True)
575 comb
+= move_one
.eq(self
.insn_in
[20])
576 with m
.If((op
.internal_op
== MicrOp
.OP_MTCRF
)):
578 # must one-hot the FXM field
579 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
580 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
582 comb
+= self
.whole_reg
.data
.eq(self
.dec
.FXM
)
584 # otherwise use all of it
585 comb
+= self
.whole_reg
.data
.eq(0xff)
590 class PowerDecode2(Elaboratable
):
591 """PowerDecode2: the main instruction decoder.
593 whilst PowerDecode is responsible for decoding the actual opcode, this
594 module encapsulates further specialist, sparse information and
595 expansion of fields that is inconvenient to have in the CSV files.
596 for example: the encoding of the immediates, which are detected
597 and expanded out to their full value from an annotated (enum)
600 implicit register usage is also set up, here. for example: OP_BC
601 requires implicitly reading CTR, OP_RFID requires implicitly writing
604 in addition, PowerDecoder2 is responsible for detecting whether
605 instructions are illegal (or privileged) or not, and instead of
606 just leaving at that, *replacing* the instruction to execute with
607 a suitable alternative (trap).
610 def __init__(self
, dec
):
613 self
.e
= Decode2ToExecute1Type()
615 # state information needed by the Decoder (TODO: this as a Record)
616 self
.state
= CoreState("dec2")
619 return self
.dec
.ports() + self
.e
.ports()
621 def elaborate(self
, platform
):
624 e_out
, op
, do_out
= self
.e
, self
.dec
.op
, self
.e
.do
625 msr
, cia
= self
.state
.msr
, self
.state
.pc
627 # fill in for a normal instruction (not an exception)
628 # copy over if non-exception, non-privileged etc. is detected
629 e
= Decode2ToExecute1Type()
632 # set up submodule decoders
633 m
.submodules
.dec
= self
.dec
634 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
)
635 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
)
636 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
)
637 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
)
638 m
.submodules
.dec_o2
= dec_o2
= DecodeOut2(self
.dec
)
639 m
.submodules
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
640 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
)
641 m
.submodules
.dec_cr_in
= dec_cr_in
= DecodeCRIn(self
.dec
)
642 m
.submodules
.dec_cr_out
= dec_cr_out
= DecodeCROut(self
.dec
)
644 # copy instruction through...
645 for i
in [do
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
646 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
, dec_rc
.insn_in
,
647 dec_oe
.insn_in
, dec_cr_in
.insn_in
, dec_cr_out
.insn_in
]:
648 comb
+= i
.eq(self
.dec
.opcode_in
)
650 # ...and subdecoders' input fields
651 comb
+= dec_a
.sel_in
.eq(op
.in1_sel
)
652 comb
+= dec_b
.sel_in
.eq(op
.in2_sel
)
653 comb
+= dec_c
.sel_in
.eq(op
.in3_sel
)
654 comb
+= dec_o
.sel_in
.eq(op
.out_sel
)
655 comb
+= dec_o2
.sel_in
.eq(op
.out_sel
)
656 comb
+= dec_o2
.lk
.eq(do
.lk
)
657 comb
+= dec_rc
.sel_in
.eq(op
.rc_sel
)
658 comb
+= dec_oe
.sel_in
.eq(op
.rc_sel
) # XXX should be OE sel
659 comb
+= dec_cr_in
.sel_in
.eq(op
.cr_in
)
660 comb
+= dec_cr_out
.sel_in
.eq(op
.cr_out
)
661 comb
+= dec_cr_out
.rc_in
.eq(dec_rc
.rc_out
.data
)
664 comb
+= do
.msr
.eq(msr
)
665 comb
+= do
.cia
.eq(cia
)
667 # set up instruction, pick fn unit
668 # no op: defaults to OP_ILLEGAL
669 comb
+= do
.insn_type
.eq(op
.internal_op
)
670 comb
+= do
.fn_unit
.eq(op
.function_unit
)
672 # registers a, b, c and out and out2 (LD/ST EA)
673 comb
+= e
.read_reg1
.eq(dec_a
.reg_out
)
674 comb
+= e
.read_reg2
.eq(dec_b
.reg_out
)
675 comb
+= e
.read_reg3
.eq(dec_c
.reg_out
)
676 comb
+= e
.write_reg
.eq(dec_o
.reg_out
)
677 comb
+= e
.write_ea
.eq(dec_o2
.reg_out
)
678 comb
+= do
.imm_data
.eq(dec_b
.imm_out
) # immediate in RB (usually)
679 comb
+= do
.zero_a
.eq(dec_a
.immz_out
) # RA==0 detected
682 comb
+= do
.rc
.eq(dec_rc
.rc_out
)
683 comb
+= do
.oe
.eq(dec_oe
.oe_out
)
686 comb
+= e
.read_spr1
.eq(dec_a
.spr_out
)
687 comb
+= e
.write_spr
.eq(dec_o
.spr_out
)
690 comb
+= e
.read_fast1
.eq(dec_a
.fast_out
)
691 comb
+= e
.read_fast2
.eq(dec_b
.fast_out
)
692 comb
+= e
.write_fast1
.eq(dec_o
.fast_out
)
693 comb
+= e
.write_fast2
.eq(dec_o2
.fast_out
)
695 # condition registers (CR)
696 comb
+= e
.read_cr1
.eq(dec_cr_in
.cr_bitfield
)
697 comb
+= e
.read_cr2
.eq(dec_cr_in
.cr_bitfield_b
)
698 comb
+= e
.read_cr3
.eq(dec_cr_in
.cr_bitfield_o
)
699 comb
+= e
.write_cr
.eq(dec_cr_out
.cr_bitfield
)
701 comb
+= do
.read_cr_whole
.eq(dec_cr_in
.whole_reg
)
702 comb
+= do
.write_cr_whole
.eq(dec_cr_out
.whole_reg
)
703 comb
+= do
.write_cr0
.eq(dec_cr_out
.cr_bitfield
.ok
)
705 # decoded/selected instruction flags
706 comb
+= do
.data_len
.eq(op
.ldst_len
)
707 comb
+= do
.invert_in
.eq(op
.inv_a
)
708 comb
+= do
.invert_out
.eq(op
.inv_out
)
709 comb
+= do
.input_carry
.eq(op
.cry_in
) # carry comes in
710 comb
+= do
.output_carry
.eq(op
.cry_out
) # carry goes out
711 comb
+= do
.is_32bit
.eq(op
.is_32b
)
712 comb
+= do
.is_signed
.eq(op
.sgn
)
714 comb
+= do
.lk
.eq(self
.dec
.LK
) # XXX TODO: accessor
716 comb
+= do
.byte_reverse
.eq(op
.br
)
717 comb
+= do
.sign_extend
.eq(op
.sgn_ext
)
718 comb
+= do
.ldst_mode
.eq(op
.upd
) # LD/ST mode (update, cache-inhibit)
720 # These should be removed eventually
721 comb
+= do
.input_cr
.eq(op
.cr_in
) # condition reg comes in
722 comb
+= do
.output_cr
.eq(op
.cr_out
) # condition reg goes in
724 # sigh this is exactly the sort of thing for which the
725 # decoder is designed to not need. MTSPR, MFSPR and others need
726 # access to the XER bits. however setting e.oe is not appropriate
727 with m
.If(op
.internal_op
== MicrOp
.OP_MFSPR
):
728 comb
+= e
.xer_in
.eq(1)
729 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
730 comb
+= e
.xer_out
.eq(1)
732 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
733 with m
.If(op
.internal_op
== MicrOp
.OP_TRAP
):
734 # *DO NOT* call self.trap here. that would reset absolutely
735 # rverything including destroying read of RA and RB.
736 comb
+= do
.trapaddr
.eq(0x70) # addr=0x700 (strip first nibble)
738 # TODO: get msr, then can do privileged instruction
739 with m
.If(instr_is_priv(m
, op
.internal_op
, e
.do
.insn
) & msr
[MSR
.PR
]):
740 # privileged instruction trap
741 self
.trap(m
, TT
.PRIV
, 0x700)
743 # illegal instruction must redirect to trap. this is done by
744 # *overwriting* the decoded instruction and starting again.
745 # (note: the same goes for interrupts and for privileged operations,
746 # just with different trapaddr and traptype)
747 with m
.Elif(op
.internal_op
== MicrOp
.OP_ILLEGAL
):
748 # illegal instruction trap
749 self
.trap(m
, TT
.ILLEG
, 0x700)
751 # no exception, just copy things to the output
755 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
756 # Note: OP_SC could actually be modified to just be a trap
757 with m
.If((do_out
.insn_type
== MicrOp
.OP_TRAP
) |
758 (do_out
.insn_type
== MicrOp
.OP_SC
)):
759 # TRAP write fast1 = SRR0
760 comb
+= e_out
.write_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
761 comb
+= e_out
.write_fast1
.ok
.eq(1)
762 # TRAP write fast2 = SRR1
763 comb
+= e_out
.write_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
764 comb
+= e_out
.write_fast2
.ok
.eq(1)
766 # RFID: needs to read SRR0/1
767 with m
.If(do_out
.insn_type
== MicrOp
.OP_RFID
):
768 # TRAP read fast1 = SRR0
769 comb
+= e_out
.read_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
770 comb
+= e_out
.read_fast1
.ok
.eq(1)
771 # TRAP read fast2 = SRR1
772 comb
+= e_out
.read_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
773 comb
+= e_out
.read_fast2
.ok
.eq(1)
777 def trap(self
, m
, traptype
, trapaddr
):
778 """trap: this basically "rewrites" the decoded instruction as a trap
781 op
, do
, e
= self
.dec
.op
, self
.e
.do
, self
.e
782 comb
+= e
.eq(0) # reset eeeeeverything
785 comb
+= do
.insn
.eq(self
.dec
.opcode_in
)
786 comb
+= do
.insn_type
.eq(MicrOp
.OP_TRAP
)
787 comb
+= do
.fn_unit
.eq(Function
.TRAP
)
788 comb
+= do
.trapaddr
.eq(trapaddr
>> 4) # cut bottom 4 bits
789 comb
+= do
.traptype
.eq(traptype
) # request type
790 comb
+= do
.msr
.eq(self
.state
.msr
) # copy of MSR "state"
791 comb
+= do
.cia
.eq(self
.state
.pc
) # copy of PC "state"
794 def get_rdflags(e
, cu
):
796 for idx
in range(cu
.n_src
):
797 regfile
, regname
, _
= cu
.get_in_spec(idx
)
798 rdflag
, read
= regspec_decode_read(e
, regfile
, regname
)
800 print("rdflags", rdl
)
804 if __name__
== '__main__':
805 pdecode
= create_pdecode()
806 dec2
= PowerDecode2(pdecode
)
807 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
808 with
open("dec2.il", "w") as f
: