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
.iocontrol
import RecordObject
13 from nmutil
.extend
import exts
15 from soc
.decoder
.power_regspec_map
import regspec_decode_read
16 from soc
.decoder
.power_regspec_map
import regspec_decode_write
17 from soc
.decoder
.power_decoder
import create_pdecode
18 from soc
.decoder
.power_enums
import (MicrOp
, CryIn
, Function
,
20 LdstLen
, In1Sel
, In2Sel
, In3Sel
,
21 OutSel
, SPR
, RC
, LDSTMode
)
22 from soc
.decoder
.decode2execute1
import Decode2ToExecute1Type
, Data
23 from soc
.consts
import MSR
25 from soc
.regfile
.regfiles
import FastRegs
26 from soc
.consts
import TT
29 def decode_spr_num(spr
):
30 return Cat(spr
[5:10], spr
[0:5])
33 def instr_is_priv(m
, op
, insn
):
34 """determines if the instruction is privileged or not
37 is_priv_insn
= Signal(reset_less
=True)
39 with m
.Case(MicrOp
.OP_ATTN
, MicrOp
.OP_MFMSR
, MicrOp
.OP_MTMSRD
,
40 MicrOp
.OP_MTMSR
, MicrOp
.OP_RFID
):
41 comb
+= is_priv_insn
.eq(1)
43 #with m.Case(MicrOp.OP_TLBIE) : comb += is_priv_insn.eq(1)
44 with m
.Case(MicrOp
.OP_MFSPR
, MicrOp
.OP_MTSPR
):
45 with m
.If(insn
[20]): # field XFX.spr[-1] i think
46 comb
+= is_priv_insn
.eq(1)
50 class SPRMap(Elaboratable
):
51 """SPRMap: maps POWER9 SPR numbers to internal enum values
55 self
.spr_i
= Signal(10, reset_less
=True)
56 self
.spr_o
= Signal(SPR
, reset_less
=True)
58 def elaborate(self
, platform
):
60 with m
.Switch(self
.spr_i
):
61 for i
, x
in enumerate(SPR
):
63 m
.d
.comb
+= self
.spr_o
.eq(i
)
67 class DecodeA(Elaboratable
):
68 """DecodeA from instruction
70 decodes register RA, whether immediate-zero, implicit and
74 def __init__(self
, dec
):
76 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
77 self
.insn_in
= Signal(32, reset_less
=True)
78 self
.reg_out
= Data(5, name
="reg_a")
79 self
.immz_out
= Signal(reset_less
=True)
80 self
.spr_out
= Data(SPR
, "spr_a")
81 self
.fast_out
= Data(3, "fast_a")
83 def elaborate(self
, platform
):
86 m
.submodules
.sprmap
= sprmap
= SPRMap()
88 # select Register A field
89 ra
= Signal(5, reset_less
=True)
90 comb
+= ra
.eq(self
.dec
.RA
)
91 with m
.If((self
.sel_in
== In1Sel
.RA
) |
92 ((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
93 (ra
!= Const(0, 5)))):
94 comb
+= self
.reg_out
.data
.eq(ra
)
95 comb
+= self
.reg_out
.ok
.eq(1)
97 # zero immediate requested
98 with m
.If((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
99 (self
.reg_out
.data
== Const(0, 5))):
100 comb
+= self
.immz_out
.eq(1)
102 # some Logic/ALU ops have RS as the 3rd arg, but no "RA".
103 with m
.If(self
.sel_in
== In1Sel
.RS
):
104 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
105 comb
+= self
.reg_out
.ok
.eq(1)
107 # decode Fast-SPR based on instruction type
109 with m
.Switch(op
.internal_op
):
111 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeOut
112 with m
.Case(MicrOp
.OP_BC
):
113 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
115 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
116 comb
+= self
.fast_out
.ok
.eq(1)
117 with m
.Case(MicrOp
.OP_BCREG
):
118 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
119 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
120 with m
.If(xo9
& ~xo5
):
122 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
123 comb
+= self
.fast_out
.ok
.eq(1)
125 # MFSPR move from SPRs
126 with m
.Case(MicrOp
.OP_MFSPR
):
127 spr
= Signal(10, reset_less
=True)
128 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
131 with m
.Case(SPR
.CTR
.value
):
132 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
133 comb
+= self
.fast_out
.ok
.eq(1)
134 with m
.Case(SPR
.LR
.value
):
135 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
136 comb
+= self
.fast_out
.ok
.eq(1)
137 with m
.Case(SPR
.TAR
.value
):
138 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
139 comb
+= self
.fast_out
.ok
.eq(1)
140 with m
.Case(SPR
.SRR0
.value
):
141 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
)
142 comb
+= self
.fast_out
.ok
.eq(1)
143 with m
.Case(SPR
.SRR1
.value
):
144 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
)
145 comb
+= self
.fast_out
.ok
.eq(1)
146 with m
.Case(SPR
.XER
.value
):
148 # : map to internal SPR numbers
149 # XXX TODO: dec and tb not to go through mapping.
151 comb
+= sprmap
.spr_i
.eq(spr
)
152 comb
+= self
.spr_out
.data
.eq(sprmap
.spr_o
)
153 comb
+= self
.spr_out
.ok
.eq(1)
158 class DecodeB(Elaboratable
):
159 """DecodeB from instruction
161 decodes register RB, different forms of immediate (signed, unsigned),
162 and implicit SPRs. register B is basically "lane 2" into the CompUnits.
163 by industry-standard convention, "lane 2" is where fully-decoded
164 immediates are muxed in.
167 def __init__(self
, dec
):
169 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
170 self
.insn_in
= Signal(32, reset_less
=True)
171 self
.reg_out
= Data(5, "reg_b")
172 self
.imm_out
= Data(64, "imm_b")
173 self
.fast_out
= Data(3, "fast_b")
175 def elaborate(self
, platform
):
179 # select Register B field
180 with m
.Switch(self
.sel_in
):
181 with m
.Case(In2Sel
.RB
):
182 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
)
183 comb
+= self
.reg_out
.ok
.eq(1)
184 with m
.Case(In2Sel
.RS
):
185 # for M-Form shiftrot
186 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
187 comb
+= self
.reg_out
.ok
.eq(1)
188 with m
.Case(In2Sel
.CONST_UI
): # unsigned
189 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
)
190 comb
+= self
.imm_out
.ok
.eq(1)
191 with m
.Case(In2Sel
.CONST_SI
): # sign-extended 16-bit
192 si
= Signal(16, reset_less
=True)
193 comb
+= si
.eq(self
.dec
.SI
)
194 comb
+= self
.imm_out
.data
.eq(exts(si
, 16, 64))
195 comb
+= self
.imm_out
.ok
.eq(1)
196 with m
.Case(In2Sel
.CONST_SI_HI
): # sign-extended 16+16=32 bit
197 si_hi
= Signal(32, reset_less
=True)
198 comb
+= si_hi
.eq(self
.dec
.SI
<< 16)
199 comb
+= self
.imm_out
.data
.eq(exts(si_hi
, 32, 64))
200 comb
+= self
.imm_out
.ok
.eq(1)
201 with m
.Case(In2Sel
.CONST_UI_HI
): # unsigned
202 ui
= Signal(16, reset_less
=True)
203 comb
+= ui
.eq(self
.dec
.UI
)
204 comb
+= self
.imm_out
.data
.eq(ui
<< 16)
205 comb
+= self
.imm_out
.ok
.eq(1)
206 with m
.Case(In2Sel
.CONST_LI
): # sign-extend 24+2=26 bit
207 li
= Signal(26, reset_less
=True)
208 comb
+= li
.eq(self
.dec
.LI
<< 2)
209 comb
+= self
.imm_out
.data
.eq(exts(li
, 26, 64))
210 comb
+= self
.imm_out
.ok
.eq(1)
211 with m
.Case(In2Sel
.CONST_BD
): # sign-extend (14+2)=16 bit
212 bd
= Signal(16, reset_less
=True)
213 comb
+= bd
.eq(self
.dec
.BD
<< 2)
214 comb
+= self
.imm_out
.data
.eq(exts(bd
, 16, 64))
215 comb
+= self
.imm_out
.ok
.eq(1)
216 with m
.Case(In2Sel
.CONST_DS
): # sign-extended (14+2=16) bit
217 ds
= Signal(16, reset_less
=True)
218 comb
+= ds
.eq(self
.dec
.DS
<< 2)
219 comb
+= self
.imm_out
.data
.eq(exts(ds
, 16, 64))
220 comb
+= self
.imm_out
.ok
.eq(1)
221 with m
.Case(In2Sel
.CONST_M1
): # signed (-1)
222 comb
+= self
.imm_out
.data
.eq(~
Const(0, 64)) # all 1s
223 comb
+= self
.imm_out
.ok
.eq(1)
224 with m
.Case(In2Sel
.CONST_SH
): # unsigned - for shift
225 comb
+= self
.imm_out
.data
.eq(self
.dec
.sh
)
226 comb
+= self
.imm_out
.ok
.eq(1)
227 with m
.Case(In2Sel
.CONST_SH32
): # unsigned - for shift
228 comb
+= self
.imm_out
.data
.eq(self
.dec
.SH32
)
229 comb
+= self
.imm_out
.ok
.eq(1)
231 # decode SPR2 based on instruction type
233 # BCREG implicitly uses LR or TAR for 2nd reg
234 # CTR however is already in fast_spr1 *not* 2.
235 with m
.If(op
.internal_op
== MicrOp
.OP_BCREG
):
236 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
237 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
239 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
240 comb
+= self
.fast_out
.ok
.eq(1)
242 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
243 comb
+= self
.fast_out
.ok
.eq(1)
248 class DecodeC(Elaboratable
):
249 """DecodeC from instruction
251 decodes register RC. this is "lane 3" into some CompUnits (not many)
254 def __init__(self
, dec
):
256 self
.sel_in
= Signal(In3Sel
, reset_less
=True)
257 self
.insn_in
= Signal(32, reset_less
=True)
258 self
.reg_out
= Data(5, "reg_c")
260 def elaborate(self
, platform
):
264 # select Register C field
265 with m
.Switch(self
.sel_in
):
266 with m
.Case(In3Sel
.RB
):
267 # for M-Form shiftrot
268 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
)
269 comb
+= self
.reg_out
.ok
.eq(1)
270 with m
.Case(In3Sel
.RS
):
271 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
272 comb
+= self
.reg_out
.ok
.eq(1)
277 class DecodeOut(Elaboratable
):
278 """DecodeOut from instruction
280 decodes output register RA, RT or SPR
283 def __init__(self
, dec
):
285 self
.sel_in
= Signal(OutSel
, reset_less
=True)
286 self
.insn_in
= Signal(32, reset_less
=True)
287 self
.reg_out
= Data(5, "reg_o")
288 self
.spr_out
= Data(SPR
, "spr_o")
289 self
.fast_out
= Data(3, "fast_o")
291 def elaborate(self
, platform
):
294 m
.submodules
.sprmap
= sprmap
= SPRMap()
297 # select Register out field
298 with m
.Switch(self
.sel_in
):
299 with m
.Case(OutSel
.RT
):
300 comb
+= self
.reg_out
.data
.eq(self
.dec
.RT
)
301 comb
+= self
.reg_out
.ok
.eq(1)
302 with m
.Case(OutSel
.RA
):
303 comb
+= self
.reg_out
.data
.eq(self
.dec
.RA
)
304 comb
+= self
.reg_out
.ok
.eq(1)
305 with m
.Case(OutSel
.SPR
):
306 spr
= Signal(10, reset_less
=True)
307 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
308 # TODO MTSPR 1st spr (fast)
309 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
312 with m
.Case(SPR
.CTR
.value
):
313 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
314 comb
+= self
.fast_out
.ok
.eq(1)
315 with m
.Case(SPR
.LR
.value
):
316 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
317 comb
+= self
.fast_out
.ok
.eq(1)
318 with m
.Case(SPR
.TAR
.value
):
319 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
320 comb
+= self
.fast_out
.ok
.eq(1)
321 with m
.Case(SPR
.SRR0
.value
):
322 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
)
323 comb
+= self
.fast_out
.ok
.eq(1)
324 with m
.Case(SPR
.SRR1
.value
):
325 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
)
326 comb
+= self
.fast_out
.ok
.eq(1)
327 with m
.Case(SPR
.XER
.value
):
329 # : map to internal SPR numbers
330 # XXX TODO: dec and tb not to go through mapping.
332 comb
+= sprmap
.spr_i
.eq(spr
)
333 comb
+= self
.spr_out
.data
.eq(sprmap
.spr_o
)
334 comb
+= self
.spr_out
.ok
.eq(1)
336 with m
.Switch(op
.internal_op
):
338 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeA
339 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_BCREG
):
340 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
342 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
343 comb
+= self
.fast_out
.ok
.eq(1)
345 # RFID 1st spr (fast)
346 with m
.Case(MicrOp
.OP_RFID
):
347 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
348 comb
+= self
.fast_out
.ok
.eq(1)
353 class DecodeOut2(Elaboratable
):
354 """DecodeOut2 from instruction
356 decodes output registers
359 def __init__(self
, dec
):
361 self
.sel_in
= Signal(OutSel
, reset_less
=True)
362 self
.lk
= Signal(reset_less
=True)
363 self
.insn_in
= Signal(32, reset_less
=True)
364 self
.reg_out
= Data(5, "reg_o")
365 self
.fast_out
= Data(3, "fast_o")
367 def elaborate(self
, platform
):
371 # update mode LD/ST uses read-reg A also as an output
372 with m
.If(self
.dec
.op
.upd
== LDSTMode
.update
):
373 comb
+= self
.reg_out
.eq(self
.dec
.RA
)
374 comb
+= self
.reg_out
.ok
.eq(1)
376 # B, BC or BCREG: potential implicit register (LR) output
377 # these give bl, bcl, bclrl, etc.
379 with m
.Switch(op
.internal_op
):
381 # BC* implicit register (LR)
382 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_B
, MicrOp
.OP_BCREG
):
383 with m
.If(self
.lk
): # "link" mode
384 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
) # constant: LR
385 comb
+= self
.fast_out
.ok
.eq(1)
387 # RFID 2nd spr (fast)
388 with m
.Case(MicrOp
.OP_RFID
):
389 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
390 comb
+= self
.fast_out
.ok
.eq(1)
395 class DecodeRC(Elaboratable
):
396 """DecodeRc from instruction
398 decodes Record bit Rc
401 def __init__(self
, dec
):
403 self
.sel_in
= Signal(RC
, reset_less
=True)
404 self
.insn_in
= Signal(32, reset_less
=True)
405 self
.rc_out
= Data(1, "rc")
407 def elaborate(self
, platform
):
411 # select Record bit out field
412 with m
.Switch(self
.sel_in
):
414 comb
+= self
.rc_out
.data
.eq(self
.dec
.Rc
)
415 comb
+= self
.rc_out
.ok
.eq(1)
417 comb
+= self
.rc_out
.data
.eq(1)
418 comb
+= self
.rc_out
.ok
.eq(1)
419 with m
.Case(RC
.NONE
):
420 comb
+= self
.rc_out
.data
.eq(0)
421 comb
+= self
.rc_out
.ok
.eq(1)
426 class DecodeOE(Elaboratable
):
427 """DecodeOE from instruction
429 decodes OE field: uses RC decode detection which might not be good
431 -- For now, use "rc" in the decode table to decide whether oe exists.
432 -- This is not entirely correct architecturally: For mulhd and
433 -- mulhdu, the OE field is reserved. It remains to be seen what an
434 -- actual POWER9 does if we set it on those instructions, for now we
435 -- test that further down when assigning to the multiplier oe input.
438 def __init__(self
, dec
):
440 self
.sel_in
= Signal(RC
, reset_less
=True)
441 self
.insn_in
= Signal(32, reset_less
=True)
442 self
.oe_out
= Data(1, "oe")
444 def elaborate(self
, platform
):
449 with m
.Switch(op
.internal_op
):
451 # mulhw, mulhwu, mulhd, mulhdu - these *ignore* OE
452 with m
.Case(MicrOp
.OP_MUL_H64
, MicrOp
.OP_MUL_H32
):
455 # all other ops decode OE field
457 # select OE bit out field
458 with m
.Switch(self
.sel_in
):
460 comb
+= self
.oe_out
.data
.eq(self
.dec
.OE
)
461 comb
+= self
.oe_out
.ok
.eq(1)
466 class DecodeCRIn(Elaboratable
):
467 """Decodes input CR from instruction
469 CR indices - insn fields - (not the data *in* the CR) require only 3
470 bits because they refer to CR0-CR7
473 def __init__(self
, dec
):
475 self
.sel_in
= Signal(CRInSel
, reset_less
=True)
476 self
.insn_in
= Signal(32, reset_less
=True)
477 self
.cr_bitfield
= Data(3, "cr_bitfield")
478 self
.cr_bitfield_b
= Data(3, "cr_bitfield_b")
479 self
.cr_bitfield_o
= Data(3, "cr_bitfield_o")
480 self
.whole_reg
= Signal(reset_less
=True)
482 def elaborate(self
, platform
):
486 comb
+= self
.cr_bitfield
.ok
.eq(0)
487 comb
+= self
.cr_bitfield_b
.ok
.eq(0)
488 comb
+= self
.whole_reg
.eq(0)
489 with m
.Switch(self
.sel_in
):
490 with m
.Case(CRInSel
.NONE
):
491 pass # No bitfield activated
492 with m
.Case(CRInSel
.CR0
):
493 comb
+= self
.cr_bitfield
.data
.eq(0)
494 comb
+= self
.cr_bitfield
.ok
.eq(1)
495 with m
.Case(CRInSel
.BI
):
496 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BI
[2:5])
497 comb
+= self
.cr_bitfield
.ok
.eq(1)
498 with m
.Case(CRInSel
.BFA
):
499 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BFA
)
500 comb
+= self
.cr_bitfield
.ok
.eq(1)
501 with m
.Case(CRInSel
.BA_BB
):
502 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BA
[2:5])
503 comb
+= self
.cr_bitfield
.ok
.eq(1)
504 comb
+= self
.cr_bitfield_b
.data
.eq(self
.dec
.BB
[2:5])
505 comb
+= self
.cr_bitfield_b
.ok
.eq(1)
506 comb
+= self
.cr_bitfield_o
.data
.eq(self
.dec
.BT
[2:5])
507 comb
+= self
.cr_bitfield_o
.ok
.eq(1)
508 with m
.Case(CRInSel
.BC
):
509 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BC
[2:5])
510 comb
+= self
.cr_bitfield
.ok
.eq(1)
511 with m
.Case(CRInSel
.WHOLE_REG
):
512 comb
+= self
.whole_reg
.eq(1)
517 class DecodeCROut(Elaboratable
):
518 """Decodes input CR from instruction
520 CR indices - insn fields - (not the data *in* the CR) require only 3
521 bits because they refer to CR0-CR7
524 def __init__(self
, dec
):
526 self
.rc_in
= Signal(reset_less
=True)
527 self
.sel_in
= Signal(CROutSel
, reset_less
=True)
528 self
.insn_in
= Signal(32, reset_less
=True)
529 self
.cr_bitfield
= Data(3, "cr_bitfield")
530 self
.whole_reg
= Signal(reset_less
=True)
532 def elaborate(self
, platform
):
536 comb
+= self
.cr_bitfield
.ok
.eq(0)
537 comb
+= self
.whole_reg
.eq(0)
538 with m
.Switch(self
.sel_in
):
539 with m
.Case(CROutSel
.NONE
):
540 pass # No bitfield activated
541 with m
.Case(CROutSel
.CR0
):
542 comb
+= self
.cr_bitfield
.data
.eq(0)
543 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
544 with m
.Case(CROutSel
.BF
):
545 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BF
)
546 comb
+= self
.cr_bitfield
.ok
.eq(1)
547 with m
.Case(CROutSel
.BT
):
548 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormXL
.BT
[2:5])
549 comb
+= self
.cr_bitfield
.ok
.eq(1)
550 with m
.Case(CROutSel
.WHOLE_REG
):
551 comb
+= self
.whole_reg
.eq(1)
556 class PowerDecode2(Elaboratable
):
557 """PowerDecode2: the main instruction decoder.
559 whilst PowerDecode is responsible for decoding the actual opcode, this
560 module encapsulates further specialist, sparse information and
561 expansion of fields that is inconvenient to have in the CSV files.
562 for example: the encoding of the immediates, which are detected
563 and expanded out to their full value from an annotated (enum)
566 implicit register usage is also set up, here. for example: OP_BC
567 requires implicitly reading CTR, OP_RFID requires implicitly writing
570 in addition, PowerDecoder2 is responsible for detecting whether
571 instructions are illegal (or privileged) or not, and instead of
572 just leaving at that, *replacing* the instruction to execute with
573 a suitable alternative (trap).
576 def __init__(self
, dec
):
579 self
.e
= Decode2ToExecute1Type()
580 self
.valid
= Signal() # sync signal
582 # state information needed by the Decoder (TODO: this as a Record)
583 self
.msr
= Signal(64, reset_less
=True) # copy of MSR
584 self
.cia
= Signal(64, reset_less
=True) # copy of Program Counter
587 return self
.dec
.ports() + self
.e
.ports()
589 def elaborate(self
, platform
):
592 e
, op
, do
, msr
, cia
= self
.e
, self
.dec
.op
, self
.e
.do
, self
.msr
, self
.cia
594 # set up submodule decoders
595 m
.submodules
.dec
= self
.dec
596 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
)
597 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
)
598 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
)
599 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
)
600 m
.submodules
.dec_o2
= dec_o2
= DecodeOut2(self
.dec
)
601 m
.submodules
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
602 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
)
603 m
.submodules
.dec_cr_in
= dec_cr_in
= DecodeCRIn(self
.dec
)
604 m
.submodules
.dec_cr_out
= dec_cr_out
= DecodeCROut(self
.dec
)
606 # copy instruction through...
607 for i
in [do
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
608 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
, dec_rc
.insn_in
,
609 dec_oe
.insn_in
, dec_cr_in
.insn_in
, dec_cr_out
.insn_in
]:
610 comb
+= i
.eq(self
.dec
.opcode_in
)
612 # ...and subdecoders' input fields
613 comb
+= dec_a
.sel_in
.eq(op
.in1_sel
)
614 comb
+= dec_b
.sel_in
.eq(op
.in2_sel
)
615 comb
+= dec_c
.sel_in
.eq(op
.in3_sel
)
616 comb
+= dec_o
.sel_in
.eq(op
.out_sel
)
617 comb
+= dec_o2
.sel_in
.eq(op
.out_sel
)
618 comb
+= dec_o2
.lk
.eq(do
.lk
)
619 comb
+= dec_rc
.sel_in
.eq(op
.rc_sel
)
620 comb
+= dec_oe
.sel_in
.eq(op
.rc_sel
) # XXX should be OE sel
621 comb
+= dec_cr_in
.sel_in
.eq(op
.cr_in
)
622 comb
+= dec_cr_out
.sel_in
.eq(op
.cr_out
)
623 comb
+= dec_cr_out
.rc_in
.eq(dec_rc
.rc_out
.data
)
626 comb
+= do
.msr
.eq(self
.msr
)
627 comb
+= do
.cia
.eq(self
.cia
)
629 # set up instruction, pick fn unit
630 # no op: defaults to OP_ILLEGAL
631 comb
+= do
.insn_type
.eq(op
.internal_op
)
632 comb
+= do
.fn_unit
.eq(op
.function_unit
)
634 # registers a, b, c and out and out2 (LD/ST EA)
635 comb
+= e
.read_reg1
.eq(dec_a
.reg_out
)
636 comb
+= e
.read_reg2
.eq(dec_b
.reg_out
)
637 comb
+= e
.read_reg3
.eq(dec_c
.reg_out
)
638 comb
+= e
.write_reg
.eq(dec_o
.reg_out
)
639 comb
+= e
.write_ea
.eq(dec_o2
.reg_out
)
640 comb
+= do
.imm_data
.eq(dec_b
.imm_out
) # immediate in RB (usually)
641 comb
+= do
.zero_a
.eq(dec_a
.immz_out
) # RA==0 detected
644 comb
+= do
.rc
.eq(dec_rc
.rc_out
)
645 comb
+= do
.oe
.eq(dec_oe
.oe_out
)
648 comb
+= e
.read_spr1
.eq(dec_a
.spr_out
)
649 comb
+= e
.write_spr
.eq(dec_o
.spr_out
)
652 comb
+= e
.read_fast1
.eq(dec_a
.fast_out
)
653 comb
+= e
.read_fast2
.eq(dec_b
.fast_out
)
654 comb
+= e
.write_fast1
.eq(dec_o
.fast_out
)
655 comb
+= e
.write_fast2
.eq(dec_o2
.fast_out
)
657 # condition registers (CR)
658 comb
+= e
.read_cr1
.eq(dec_cr_in
.cr_bitfield
)
659 comb
+= e
.read_cr2
.eq(dec_cr_in
.cr_bitfield_b
)
660 comb
+= e
.read_cr3
.eq(dec_cr_in
.cr_bitfield_o
)
661 comb
+= e
.write_cr
.eq(dec_cr_out
.cr_bitfield
)
663 comb
+= do
.read_cr_whole
.eq(dec_cr_in
.whole_reg
)
664 comb
+= do
.write_cr_whole
.eq(dec_cr_out
.whole_reg
)
665 comb
+= do
.write_cr0
.eq(dec_cr_out
.cr_bitfield
.ok
)
667 # decoded/selected instruction flags
668 comb
+= do
.data_len
.eq(op
.ldst_len
)
669 comb
+= do
.invert_a
.eq(op
.inv_a
)
670 comb
+= do
.invert_out
.eq(op
.inv_out
)
671 comb
+= do
.input_carry
.eq(op
.cry_in
) # carry comes in
672 comb
+= do
.output_carry
.eq(op
.cry_out
) # carry goes out
673 comb
+= do
.is_32bit
.eq(op
.is_32b
)
674 comb
+= do
.is_signed
.eq(op
.sgn
)
676 comb
+= do
.lk
.eq(self
.dec
.LK
) # XXX TODO: accessor
678 comb
+= do
.byte_reverse
.eq(op
.br
)
679 comb
+= do
.sign_extend
.eq(op
.sgn_ext
)
680 comb
+= do
.ldst_mode
.eq(op
.upd
) # LD/ST mode (update, cache-inhibit)
682 # These should be removed eventually
683 comb
+= do
.input_cr
.eq(op
.cr_in
) # condition reg comes in
684 comb
+= do
.output_cr
.eq(op
.cr_out
) # condition reg goes in
686 # sigh this is exactly the sort of thing for which the
687 # decoder is designed to not need. MTSPR, MFSPR and others need
688 # access to the XER bits. however setting e.oe is not appropriate
689 with m
.If(op
.internal_op
== MicrOp
.OP_MFSPR
):
690 comb
+= e
.xer_in
.eq(1)
691 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
692 comb
+= e
.xer_out
.eq(1)
694 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
695 with m
.If(op
.internal_op
== MicrOp
.OP_TRAP
):
696 # *DO NOT* call self.trap here. that would reset absolutely
697 # rverything including destroying read of RA and RB.
698 comb
+= do
.trapaddr
.eq(0x70) # addr=0x700 (strip first nibble)
700 # TODO: get msr, then can do privileged instruction
701 with m
.If(instr_is_priv(m
, op
.internal_op
, e
.do
.insn
) & msr
[MSR
.PR
]):
702 # privileged instruction trap
703 self
.trap(m
, TT
.PRIV
, 0x700)
705 # illegal instruction must redirect to trap. this is done by
706 # *overwriting* the decoded instruction and starting again.
707 # (note: the same goes for interrupts and for privileged operations,
708 # just with different trapaddr and traptype)
709 with m
.Elif(op
.internal_op
== MicrOp
.OP_ILLEGAL
):
710 # illegal instruction trap
711 self
.trap(m
, TT
.ILLEG
, 0x700)
713 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
714 # Note: OP_SC could actually be modified to just be a trap
715 with m
.If((do
.insn_type
== MicrOp
.OP_TRAP
) |
716 (do
.insn_type
== MicrOp
.OP_SC
)):
717 # TRAP write fast1 = SRR0
718 comb
+= e
.write_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
719 comb
+= e
.write_fast1
.ok
.eq(1)
720 # TRAP write fast2 = SRR1
721 comb
+= e
.write_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
722 comb
+= e
.write_fast2
.ok
.eq(1)
724 # RFID: needs to read SRR0/1
725 with m
.If(do
.insn_type
== MicrOp
.OP_RFID
):
726 # TRAP read fast1 = SRR0
727 comb
+= e
.read_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
728 comb
+= e
.read_fast1
.ok
.eq(1)
729 # TRAP read fast2 = SRR1
730 comb
+= e
.read_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
731 comb
+= e
.read_fast2
.ok
.eq(1)
735 def trap(self
, m
, traptype
, trapaddr
):
736 """trap: this basically "rewrites" the decoded instruction as a trap
739 e
, op
, do
= self
.e
, self
.dec
.op
, self
.e
.do
740 comb
+= e
.eq(0) # reset eeeeeverything
742 comb
+= do
.insn
.eq(self
.dec
.opcode_in
)
743 comb
+= do
.insn_type
.eq(MicrOp
.OP_TRAP
)
744 comb
+= do
.fn_unit
.eq(Function
.TRAP
)
745 comb
+= do
.trapaddr
.eq(trapaddr
>> 4) # cut bottom 4 bits
746 comb
+= do
.traptype
.eq(traptype
) # request type
747 comb
+= do
.msr
.eq(self
.msr
) # copy of MSR "state"
748 comb
+= do
.cia
.eq(self
.cia
) # copy of PC "state"
750 def regspecmap_read(self
, regfile
, regname
):
751 """regspecmap_read: provides PowerDecode2 with an encoding relationship
752 to Function Unit port regfiles (read-enable, read regnum, write regnum)
753 regfile and regname arguments are fields 1 and 2 from a given regspec.
755 return regspec_decode_read(self
.e
, regfile
, regname
)
757 def regspecmap_write(self
, regfile
, regname
):
758 """regspecmap_write: provides PowerDecode2 with an encoding relationship
759 to Function Unit port regfiles (write port, write regnum)
760 regfile and regname arguments are fields 1 and 2 from a given regspec.
762 return regspec_decode_write(self
.e
, regfile
, regname
)
764 def rdflags(self
, cu
):
766 for idx
in range(cu
.n_src
):
767 regfile
, regname
, _
= cu
.get_in_spec(idx
)
768 rdflag
, read
= self
.regspecmap_read(regfile
, regname
)
770 print("rdflags", rdl
)
774 if __name__
== '__main__':
775 pdecode
= create_pdecode()
776 dec2
= PowerDecode2(pdecode
)
777 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
778 with
open("dec2.il", "w") as f
: