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
54 self
.spr_i
= Signal(10, reset_less
=True)
55 self
.spr_o
= Signal(SPR
, reset_less
=True)
57 def elaborate(self
, platform
):
59 with m
.Switch(self
.spr_i
):
60 for i
, x
in enumerate(SPR
):
62 m
.d
.comb
+= self
.spr_o
.eq(i
)
66 class DecodeA(Elaboratable
):
67 """DecodeA from instruction
69 decodes register RA, whether immediate-zero, implicit and
73 def __init__(self
, dec
):
75 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
76 self
.insn_in
= Signal(32, reset_less
=True)
77 self
.reg_out
= Data(5, name
="reg_a")
78 self
.immz_out
= Signal(reset_less
=True)
79 self
.spr_out
= Data(SPR
, "spr_a")
80 self
.fast_out
= Data(3, "fast_a")
82 def elaborate(self
, platform
):
85 m
.submodules
.sprmap
= sprmap
= SPRMap()
87 # select Register A field
88 ra
= Signal(5, reset_less
=True)
89 comb
+= ra
.eq(self
.dec
.RA
)
90 with m
.If((self
.sel_in
== In1Sel
.RA
) |
91 ((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
92 (ra
!= Const(0, 5)))):
93 comb
+= self
.reg_out
.data
.eq(ra
)
94 comb
+= self
.reg_out
.ok
.eq(1)
96 # zero immediate requested
97 with m
.If((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
98 (self
.reg_out
.data
== Const(0, 5))):
99 comb
+= self
.immz_out
.eq(1)
101 # some Logic/ALU ops have RS as the 3rd arg, but no "RA".
102 with m
.If(self
.sel_in
== In1Sel
.RS
):
103 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
104 comb
+= self
.reg_out
.ok
.eq(1)
106 # decode Fast-SPR based on instruction type
108 with m
.Switch(op
.internal_op
):
110 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeOut
111 with m
.Case(MicrOp
.OP_BC
):
112 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
113 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
) # constant: CTR
114 comb
+= self
.fast_out
.ok
.eq(1)
115 with m
.Case(MicrOp
.OP_BCREG
):
116 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
117 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
118 with m
.If(xo9
& ~xo5
):
119 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
) # constant: CTR
120 comb
+= self
.fast_out
.ok
.eq(1)
122 # MFSPR move from SPRs
123 with m
.Case(MicrOp
.OP_MFSPR
):
124 spr
= Signal(10, reset_less
=True)
125 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
128 with m
.Case(SPR
.CTR
.value
):
129 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
130 comb
+= self
.fast_out
.ok
.eq(1)
131 with m
.Case(SPR
.LR
.value
):
132 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
133 comb
+= self
.fast_out
.ok
.eq(1)
134 with m
.Case(SPR
.TAR
.value
):
135 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
136 comb
+= self
.fast_out
.ok
.eq(1)
137 with m
.Case(SPR
.SRR0
.value
):
138 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
)
139 comb
+= self
.fast_out
.ok
.eq(1)
140 with m
.Case(SPR
.SRR1
.value
):
141 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
)
142 comb
+= self
.fast_out
.ok
.eq(1)
143 with m
.Case(SPR
.XER
.value
):
145 # : map to internal SPR numbers
146 # XXX TODO: dec and tb not to go through mapping.
148 comb
+= sprmap
.spr_i
.eq(spr
)
149 comb
+= self
.spr_out
.data
.eq(sprmap
.spr_o
)
150 comb
+= self
.spr_out
.ok
.eq(1)
155 class DecodeB(Elaboratable
):
156 """DecodeB from instruction
158 decodes register RB, different forms of immediate (signed, unsigned),
159 and implicit SPRs. register B is basically "lane 2" into the CompUnits.
160 by industry-standard convention, "lane 2" is where fully-decoded
161 immediates are muxed in.
164 def __init__(self
, dec
):
166 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
167 self
.insn_in
= Signal(32, reset_less
=True)
168 self
.reg_out
= Data(5, "reg_b")
169 self
.imm_out
= Data(64, "imm_b")
170 self
.fast_out
= Data(3, "fast_b")
172 def elaborate(self
, platform
):
176 # select Register B field
177 with m
.Switch(self
.sel_in
):
178 with m
.Case(In2Sel
.RB
):
179 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
)
180 comb
+= self
.reg_out
.ok
.eq(1)
181 with m
.Case(In2Sel
.RS
):
182 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
) # for M-Form shiftrot
183 comb
+= self
.reg_out
.ok
.eq(1)
184 with m
.Case(In2Sel
.CONST_UI
):
185 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
)
186 comb
+= self
.imm_out
.ok
.eq(1)
187 with m
.Case(In2Sel
.CONST_SI
): # TODO: sign-extend here?
188 comb
+= self
.imm_out
.data
.eq(
189 exts(self
.dec
.SI
, 16, 64))
190 comb
+= self
.imm_out
.ok
.eq(1)
191 with m
.Case(In2Sel
.CONST_UI_HI
):
192 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
<<16)
193 comb
+= self
.imm_out
.ok
.eq(1)
194 with m
.Case(In2Sel
.CONST_SI_HI
): # TODO: sign-extend here?
195 comb
+= self
.imm_out
.data
.eq(self
.dec
.SI
<<16)
196 comb
+= self
.imm_out
.data
.eq(
197 exts(self
.dec
.SI
<< 16, 32, 64))
198 comb
+= self
.imm_out
.ok
.eq(1)
199 with m
.Case(In2Sel
.CONST_LI
):
200 comb
+= self
.imm_out
.data
.eq(self
.dec
.LI
<<2)
201 comb
+= self
.imm_out
.ok
.eq(1)
202 with m
.Case(In2Sel
.CONST_BD
):
203 comb
+= self
.imm_out
.data
.eq(self
.dec
.BD
<<2)
204 comb
+= self
.imm_out
.ok
.eq(1)
205 with m
.Case(In2Sel
.CONST_DS
):
206 comb
+= self
.imm_out
.data
.eq(self
.dec
.DS
<<2)
207 comb
+= self
.imm_out
.ok
.eq(1)
208 with m
.Case(In2Sel
.CONST_M1
):
209 comb
+= self
.imm_out
.data
.eq(~
Const(0, 64)) # all 1s
210 comb
+= self
.imm_out
.ok
.eq(1)
211 with m
.Case(In2Sel
.CONST_SH
):
212 comb
+= self
.imm_out
.data
.eq(self
.dec
.sh
)
213 comb
+= self
.imm_out
.ok
.eq(1)
214 with m
.Case(In2Sel
.CONST_SH32
):
215 comb
+= self
.imm_out
.data
.eq(self
.dec
.SH32
)
216 comb
+= self
.imm_out
.ok
.eq(1)
218 # decode SPR2 based on instruction type
220 # BCREG implicitly uses LR or TAR for 2nd reg
221 # CTR however is already in fast_spr1 *not* 2.
222 with m
.If(op
.internal_op
== MicrOp
.OP_BCREG
):
223 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
224 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
226 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
227 comb
+= self
.fast_out
.ok
.eq(1)
229 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
230 comb
+= self
.fast_out
.ok
.eq(1)
235 class DecodeC(Elaboratable
):
236 """DecodeC from instruction
238 decodes register RC. this is "lane 3" into some CompUnits (not many)
241 def __init__(self
, dec
):
243 self
.sel_in
= Signal(In3Sel
, reset_less
=True)
244 self
.insn_in
= Signal(32, reset_less
=True)
245 self
.reg_out
= Data(5, "reg_c")
247 def elaborate(self
, platform
):
251 # select Register C field
252 with m
.Switch(self
.sel_in
):
253 with m
.Case(In3Sel
.RB
):
254 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
) # for M-Form shiftrot
255 comb
+= self
.reg_out
.ok
.eq(1)
256 with m
.Case(In3Sel
.RS
):
257 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
258 comb
+= self
.reg_out
.ok
.eq(1)
263 class DecodeOut(Elaboratable
):
264 """DecodeOut from instruction
266 decodes output register RA, RT or SPR
269 def __init__(self
, dec
):
271 self
.sel_in
= Signal(OutSel
, reset_less
=True)
272 self
.insn_in
= Signal(32, reset_less
=True)
273 self
.reg_out
= Data(5, "reg_o")
274 self
.spr_out
= Data(SPR
, "spr_o")
275 self
.fast_out
= Data(3, "fast_o")
277 def elaborate(self
, platform
):
280 m
.submodules
.sprmap
= sprmap
= SPRMap()
283 # select Register out field
284 with m
.Switch(self
.sel_in
):
285 with m
.Case(OutSel
.RT
):
286 comb
+= self
.reg_out
.data
.eq(self
.dec
.RT
)
287 comb
+= self
.reg_out
.ok
.eq(1)
288 with m
.Case(OutSel
.RA
):
289 comb
+= self
.reg_out
.data
.eq(self
.dec
.RA
)
290 comb
+= self
.reg_out
.ok
.eq(1)
291 with m
.Case(OutSel
.SPR
):
292 spr
= Signal(10, reset_less
=True)
293 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
294 # TODO MTSPR 1st spr (fast)
295 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
298 with m
.Case(SPR
.CTR
.value
):
299 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
300 comb
+= self
.fast_out
.ok
.eq(1)
301 with m
.Case(SPR
.LR
.value
):
302 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
303 comb
+= self
.fast_out
.ok
.eq(1)
304 with m
.Case(SPR
.TAR
.value
):
305 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
306 comb
+= self
.fast_out
.ok
.eq(1)
307 with m
.Case(SPR
.SRR0
.value
):
308 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
)
309 comb
+= self
.fast_out
.ok
.eq(1)
310 with m
.Case(SPR
.SRR1
.value
):
311 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
)
312 comb
+= self
.fast_out
.ok
.eq(1)
313 with m
.Case(SPR
.XER
.value
):
315 # : map to internal SPR numbers
316 # XXX TODO: dec and tb not to go through mapping.
318 comb
+= sprmap
.spr_i
.eq(spr
)
319 comb
+= self
.spr_out
.data
.eq(sprmap
.spr_o
)
320 comb
+= self
.spr_out
.ok
.eq(1)
322 with m
.Switch(op
.internal_op
):
324 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeA
325 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_BCREG
):
326 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
327 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
) # constant: CTR
328 comb
+= self
.fast_out
.ok
.eq(1)
330 # RFID 1st spr (fast)
331 with m
.Case(MicrOp
.OP_RFID
):
332 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
333 comb
+= self
.fast_out
.ok
.eq(1)
338 class DecodeOut2(Elaboratable
):
339 """DecodeOut2 from instruction
341 decodes output registers
344 def __init__(self
, dec
):
346 self
.sel_in
= Signal(OutSel
, reset_less
=True)
347 self
.lk
= Signal(reset_less
=True)
348 self
.insn_in
= Signal(32, reset_less
=True)
349 self
.reg_out
= Data(5, "reg_o")
350 self
.fast_out
= Data(3, "fast_o")
352 def elaborate(self
, platform
):
356 # update mode LD/ST uses read-reg A also as an output
357 with m
.If(self
.dec
.op
.upd
== LDSTMode
.update
):
358 comb
+= self
.reg_out
.eq(self
.dec
.RA
)
359 comb
+= self
.reg_out
.ok
.eq(1)
361 # B, BC or BCREG: potential implicit register (LR) output
362 # these give bl, bcl, bclrl, etc.
364 with m
.Switch(op
.internal_op
):
366 # BC* implicit register (LR)
367 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_B
, MicrOp
.OP_BCREG
):
368 with m
.If(self
.lk
): # "link" mode
369 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
) # constant: LR
370 comb
+= self
.fast_out
.ok
.eq(1)
372 # RFID 2nd spr (fast)
373 with m
.Case(MicrOp
.OP_RFID
):
374 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
375 comb
+= self
.fast_out
.ok
.eq(1)
380 class DecodeRC(Elaboratable
):
381 """DecodeRc from instruction
383 decodes Record bit Rc
385 def __init__(self
, dec
):
387 self
.sel_in
= Signal(RC
, reset_less
=True)
388 self
.insn_in
= Signal(32, reset_less
=True)
389 self
.rc_out
= Data(1, "rc")
391 def elaborate(self
, platform
):
395 # select Record bit out field
396 with m
.Switch(self
.sel_in
):
398 comb
+= self
.rc_out
.data
.eq(self
.dec
.Rc
)
399 comb
+= self
.rc_out
.ok
.eq(1)
401 comb
+= self
.rc_out
.data
.eq(1)
402 comb
+= self
.rc_out
.ok
.eq(1)
403 with m
.Case(RC
.NONE
):
404 comb
+= self
.rc_out
.data
.eq(0)
405 comb
+= self
.rc_out
.ok
.eq(1)
410 class DecodeOE(Elaboratable
):
411 """DecodeOE from instruction
413 decodes OE field: uses RC decode detection which might not be good
415 -- For now, use "rc" in the decode table to decide whether oe exists.
416 -- This is not entirely correct architecturally: For mulhd and
417 -- mulhdu, the OE field is reserved. It remains to be seen what an
418 -- actual POWER9 does if we set it on those instructions, for now we
419 -- test that further down when assigning to the multiplier oe input.
421 def __init__(self
, dec
):
423 self
.sel_in
= Signal(RC
, reset_less
=True)
424 self
.insn_in
= Signal(32, reset_less
=True)
425 self
.oe_out
= Data(1, "oe")
427 def elaborate(self
, platform
):
432 with m
.Switch(op
.internal_op
):
434 # mulhw, mulhwu, mulhd, mulhdu - these *ignore* OE
435 with m
.Case(MicrOp
.OP_MUL_H64
, MicrOp
.OP_MUL_H32
):
438 # all other ops decode OE field
440 # select OE bit out field
441 with m
.Switch(self
.sel_in
):
443 comb
+= self
.oe_out
.data
.eq(self
.dec
.OE
)
444 comb
+= self
.oe_out
.ok
.eq(1)
448 class DecodeCRIn(Elaboratable
):
449 """Decodes input CR from instruction
451 CR indices - insn fields - (not the data *in* the CR) require only 3
452 bits because they refer to CR0-CR7
455 def __init__(self
, dec
):
457 self
.sel_in
= Signal(CRInSel
, reset_less
=True)
458 self
.insn_in
= Signal(32, reset_less
=True)
459 self
.cr_bitfield
= Data(3, "cr_bitfield")
460 self
.cr_bitfield_b
= Data(3, "cr_bitfield_b")
461 self
.cr_bitfield_o
= Data(3, "cr_bitfield_o")
462 self
.whole_reg
= Signal(reset_less
=True)
464 def elaborate(self
, platform
):
468 comb
+= self
.cr_bitfield
.ok
.eq(0)
469 comb
+= self
.cr_bitfield_b
.ok
.eq(0)
470 comb
+= self
.whole_reg
.eq(0)
471 with m
.Switch(self
.sel_in
):
472 with m
.Case(CRInSel
.NONE
):
473 pass # No bitfield activated
474 with m
.Case(CRInSel
.CR0
):
475 comb
+= self
.cr_bitfield
.data
.eq(0)
476 comb
+= self
.cr_bitfield
.ok
.eq(1)
477 with m
.Case(CRInSel
.BI
):
478 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BI
[2:5])
479 comb
+= self
.cr_bitfield
.ok
.eq(1)
480 with m
.Case(CRInSel
.BFA
):
481 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BFA
)
482 comb
+= self
.cr_bitfield
.ok
.eq(1)
483 with m
.Case(CRInSel
.BA_BB
):
484 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BA
[2:5])
485 comb
+= self
.cr_bitfield
.ok
.eq(1)
486 comb
+= self
.cr_bitfield_b
.data
.eq(self
.dec
.BB
[2:5])
487 comb
+= self
.cr_bitfield_b
.ok
.eq(1)
488 comb
+= self
.cr_bitfield_o
.data
.eq(self
.dec
.BT
[2:5])
489 comb
+= self
.cr_bitfield_o
.ok
.eq(1)
490 with m
.Case(CRInSel
.BC
):
491 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BC
[2:5])
492 comb
+= self
.cr_bitfield
.ok
.eq(1)
493 with m
.Case(CRInSel
.WHOLE_REG
):
494 comb
+= self
.whole_reg
.eq(1)
499 class DecodeCROut(Elaboratable
):
500 """Decodes input CR from instruction
502 CR indices - insn fields - (not the data *in* the CR) require only 3
503 bits because they refer to CR0-CR7
506 def __init__(self
, dec
):
508 self
.rc_in
= Signal(reset_less
=True)
509 self
.sel_in
= Signal(CROutSel
, reset_less
=True)
510 self
.insn_in
= Signal(32, reset_less
=True)
511 self
.cr_bitfield
= Data(3, "cr_bitfield")
512 self
.whole_reg
= Signal(reset_less
=True)
514 def elaborate(self
, platform
):
518 comb
+= self
.cr_bitfield
.ok
.eq(0)
519 comb
+= self
.whole_reg
.eq(0)
520 with m
.Switch(self
.sel_in
):
521 with m
.Case(CROutSel
.NONE
):
522 pass # No bitfield activated
523 with m
.Case(CROutSel
.CR0
):
524 comb
+= self
.cr_bitfield
.data
.eq(0)
525 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
526 with m
.Case(CROutSel
.BF
):
527 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BF
)
528 comb
+= self
.cr_bitfield
.ok
.eq(1)
529 with m
.Case(CROutSel
.BT
):
530 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormXL
.BT
[2:5])
531 comb
+= self
.cr_bitfield
.ok
.eq(1)
532 with m
.Case(CROutSel
.WHOLE_REG
):
533 comb
+= self
.whole_reg
.eq(1)
538 class PowerDecode2(Elaboratable
):
539 """PowerDecode2: the main instruction decoder.
541 whilst PowerDecode is responsible for decoding the actual opcode, this
542 module encapsulates further specialist, sparse information and
543 expansion of fields that is inconvenient to have in the CSV files.
544 for example: the encoding of the immediates, which are detected
545 and expanded out to their full value from an annotated (enum)
548 implicit register usage is also set up, here. for example: OP_BC
549 requires implicitly reading CTR, OP_RFID requires implicitly writing
552 in addition, PowerDecoder2 is responsible for detecting whether
553 instructions are illegal (or privileged) or not, and instead of
554 just leaving at that, *replacing* the instruction to execute with
555 a suitable alternative (trap).
558 def __init__(self
, dec
):
561 self
.e
= Decode2ToExecute1Type()
562 self
.valid
= Signal() # sync signal
564 # state information needed by the Decoder (TODO: this as a Record)
565 self
.msr
= Signal(64, reset_less
=True) # copy of MSR
566 self
.cia
= Signal(64, reset_less
=True) # copy of Program Counter
569 return self
.dec
.ports() + self
.e
.ports()
571 def elaborate(self
, platform
):
574 e
, op
, do
, msr
, cia
= self
.e
, self
.dec
.op
, self
.e
.do
, self
.msr
, self
.cia
576 # set up submodule decoders
577 m
.submodules
.dec
= self
.dec
578 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
)
579 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
)
580 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
)
581 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
)
582 m
.submodules
.dec_o2
= dec_o2
= DecodeOut2(self
.dec
)
583 m
.submodules
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
584 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
)
585 m
.submodules
.dec_cr_in
= dec_cr_in
= DecodeCRIn(self
.dec
)
586 m
.submodules
.dec_cr_out
= dec_cr_out
= DecodeCROut(self
.dec
)
588 # copy instruction through...
589 for i
in [do
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
590 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
, dec_rc
.insn_in
,
591 dec_oe
.insn_in
, dec_cr_in
.insn_in
, dec_cr_out
.insn_in
]:
592 comb
+= i
.eq(self
.dec
.opcode_in
)
594 # ...and subdecoders' input fields
595 comb
+= dec_a
.sel_in
.eq(op
.in1_sel
)
596 comb
+= dec_b
.sel_in
.eq(op
.in2_sel
)
597 comb
+= dec_c
.sel_in
.eq(op
.in3_sel
)
598 comb
+= dec_o
.sel_in
.eq(op
.out_sel
)
599 comb
+= dec_o2
.sel_in
.eq(op
.out_sel
)
600 comb
+= dec_o2
.lk
.eq(do
.lk
)
601 comb
+= dec_rc
.sel_in
.eq(op
.rc_sel
)
602 comb
+= dec_oe
.sel_in
.eq(op
.rc_sel
) # XXX should be OE sel
603 comb
+= dec_cr_in
.sel_in
.eq(op
.cr_in
)
604 comb
+= dec_cr_out
.sel_in
.eq(op
.cr_out
)
605 comb
+= dec_cr_out
.rc_in
.eq(dec_rc
.rc_out
.data
)
608 comb
+= do
.msr
.eq(self
.msr
)
609 comb
+= do
.cia
.eq(self
.cia
)
611 # set up instruction, pick fn unit
612 comb
+= do
.insn_type
.eq(op
.internal_op
) # no op: defaults to OP_ILLEGAL
613 comb
+= do
.fn_unit
.eq(op
.function_unit
)
615 # registers a, b, c and out and out2 (LD/ST EA)
616 comb
+= e
.read_reg1
.eq(dec_a
.reg_out
)
617 comb
+= e
.read_reg2
.eq(dec_b
.reg_out
)
618 comb
+= e
.read_reg3
.eq(dec_c
.reg_out
)
619 comb
+= e
.write_reg
.eq(dec_o
.reg_out
)
620 comb
+= e
.write_ea
.eq(dec_o2
.reg_out
)
621 comb
+= do
.imm_data
.eq(dec_b
.imm_out
) # immediate in RB (usually)
622 comb
+= do
.zero_a
.eq(dec_a
.immz_out
) # RA==0 detected
625 comb
+= do
.rc
.eq(dec_rc
.rc_out
)
626 comb
+= do
.oe
.eq(dec_oe
.oe_out
)
629 comb
+= e
.read_spr1
.eq(dec_a
.spr_out
)
630 comb
+= e
.write_spr
.eq(dec_o
.spr_out
)
633 comb
+= e
.read_fast1
.eq(dec_a
.fast_out
)
634 comb
+= e
.read_fast2
.eq(dec_b
.fast_out
)
635 comb
+= e
.write_fast1
.eq(dec_o
.fast_out
)
636 comb
+= e
.write_fast2
.eq(dec_o2
.fast_out
)
638 # condition registers (CR)
639 comb
+= e
.read_cr1
.eq(dec_cr_in
.cr_bitfield
)
640 comb
+= e
.read_cr2
.eq(dec_cr_in
.cr_bitfield_b
)
641 comb
+= e
.read_cr3
.eq(dec_cr_in
.cr_bitfield_o
)
642 comb
+= e
.write_cr
.eq(dec_cr_out
.cr_bitfield
)
644 comb
+= do
.read_cr_whole
.eq(dec_cr_in
.whole_reg
)
645 comb
+= do
.write_cr_whole
.eq(dec_cr_out
.whole_reg
)
646 comb
+= do
.write_cr0
.eq(dec_cr_out
.cr_bitfield
.ok
)
648 # decoded/selected instruction flags
649 comb
+= do
.data_len
.eq(op
.ldst_len
)
650 comb
+= do
.invert_a
.eq(op
.inv_a
)
651 comb
+= do
.invert_out
.eq(op
.inv_out
)
652 comb
+= do
.input_carry
.eq(op
.cry_in
) # carry comes in
653 comb
+= do
.output_carry
.eq(op
.cry_out
) # carry goes out
654 comb
+= do
.is_32bit
.eq(op
.is_32b
)
655 comb
+= do
.is_signed
.eq(op
.sgn
)
657 comb
+= do
.lk
.eq(self
.dec
.LK
) # XXX TODO: accessor
659 comb
+= do
.byte_reverse
.eq(op
.br
)
660 comb
+= do
.sign_extend
.eq(op
.sgn_ext
)
661 comb
+= do
.ldst_mode
.eq(op
.upd
) # LD/ST mode (update, cache-inhibit)
663 # These should be removed eventually
664 comb
+= do
.input_cr
.eq(op
.cr_in
) # condition reg comes in
665 comb
+= do
.output_cr
.eq(op
.cr_out
) # condition reg goes in
667 # sigh this is exactly the sort of thing for which the
668 # decoder is designed to not need. MTSPR, MFSPR and others need
669 # access to the XER bits. however setting e.oe is not appropriate
670 with m
.If(op
.internal_op
== MicrOp
.OP_MFSPR
):
671 comb
+= e
.xer_in
.eq(1)
672 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
673 comb
+= e
.xer_out
.eq(1)
675 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
676 with m
.If(op
.internal_op
== MicrOp
.OP_TRAP
):
677 # *DO NOT* call self.trap here. that would reset absolutely
678 # rverything including destroying read of RA and RB.
679 comb
+= do
.trapaddr
.eq(0x70) # addr=0x700 (strip first nibble)
681 # TODO: get msr, then can do privileged instruction
682 with m
.If(instr_is_priv(m
, op
.internal_op
, e
.do
.insn
) & msr
[MSR
.PR
]):
683 # privileged instruction trap
684 self
.trap(m
, TT
.PRIV
, 0x700)
686 # illegal instruction must redirect to trap. this is done by
687 # *overwriting* the decoded instruction and starting again.
688 # (note: the same goes for interrupts and for privileged operations,
689 # just with different trapaddr and traptype)
690 with m
.Elif(op
.internal_op
== MicrOp
.OP_ILLEGAL
):
691 # illegal instruction trap
692 self
.trap(m
, TT
.ILLEG
, 0x700)
694 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
695 # Note: OP_SC could actually be modified to just be a trap
696 with m
.If((do
.insn_type
== MicrOp
.OP_TRAP
) |
697 (do
.insn_type
== MicrOp
.OP_SC
)):
698 # TRAP write fast1 = SRR0
699 comb
+= e
.write_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
700 comb
+= e
.write_fast1
.ok
.eq(1)
701 # TRAP write fast2 = SRR1
702 comb
+= e
.write_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
703 comb
+= e
.write_fast2
.ok
.eq(1)
705 # RFID: needs to read SRR0/1
706 with m
.If(do
.insn_type
== MicrOp
.OP_RFID
):
707 # TRAP read fast1 = SRR0
708 comb
+= e
.read_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
709 comb
+= e
.read_fast1
.ok
.eq(1)
710 # TRAP read fast2 = SRR1
711 comb
+= e
.read_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
712 comb
+= e
.read_fast2
.ok
.eq(1)
716 def trap(self
, m
, traptype
, trapaddr
):
717 """trap: this basically "rewrites" the decoded instruction as a trap
720 e
, op
, do
= self
.e
, self
.dec
.op
, self
.e
.do
721 comb
+= e
.eq(0) # reset eeeeeverything
723 comb
+= do
.insn
.eq(self
.dec
.opcode_in
)
724 comb
+= do
.insn_type
.eq(MicrOp
.OP_TRAP
)
725 comb
+= do
.fn_unit
.eq(Function
.TRAP
)
726 comb
+= do
.trapaddr
.eq(trapaddr
>> 4) # cut bottom 4 bits
727 comb
+= do
.traptype
.eq(traptype
) # request type
728 comb
+= do
.msr
.eq(self
.msr
) # copy of MSR "state"
729 comb
+= do
.cia
.eq(self
.cia
) # copy of PC "state"
731 def regspecmap_read(self
, regfile
, regname
):
732 """regspecmap_read: provides PowerDecode2 with an encoding relationship
733 to Function Unit port regfiles (read-enable, read regnum, write regnum)
734 regfile and regname arguments are fields 1 and 2 from a given regspec.
736 return regspec_decode_read(self
.e
, regfile
, regname
)
738 def regspecmap_write(self
, regfile
, regname
):
739 """regspecmap_write: provides PowerDecode2 with an encoding relationship
740 to Function Unit port regfiles (write port, write regnum)
741 regfile and regname arguments are fields 1 and 2 from a given regspec.
743 return regspec_decode_write(self
.e
, regfile
, regname
)
745 def rdflags(self
, cu
):
747 for idx
in range(cu
.n_src
):
748 regfile
, regname
, _
= cu
.get_in_spec(idx
)
749 rdflag
, read
= self
.regspecmap_read(regfile
, regname
)
751 print ("rdflags", rdl
)
755 if __name__
== '__main__':
756 pdecode
= create_pdecode()
757 dec2
= PowerDecode2(pdecode
)
758 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
759 with
open("dec2.il", "w") as f
: