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
) : comb
+= is_priv_insn
.eq(1)
40 with m
.Case(MicrOp
.OP_MFMSR
) : comb
+= is_priv_insn
.eq(1)
41 with m
.Case(MicrOp
.OP_MTMSRD
): comb
+= is_priv_insn
.eq(1)
42 with m
.Case(MicrOp
.OP_MTMSR
): comb
+= is_priv_insn
.eq(1)
43 with m
.Case(MicrOp
.OP_RFID
) : 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
56 self
.spr_i
= Signal(10, reset_less
=True)
57 self
.spr_o
= Signal(SPR
, reset_less
=True)
59 def elaborate(self
, platform
):
61 with m
.Switch(self
.spr_i
):
62 for i
, x
in enumerate(SPR
):
64 m
.d
.comb
+= self
.spr_o
.eq(i
)
68 class DecodeA(Elaboratable
):
69 """DecodeA from instruction
71 decodes register RA, whether immediate-zero, implicit and
75 def __init__(self
, dec
):
77 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
78 self
.insn_in
= Signal(32, reset_less
=True)
79 self
.reg_out
= Data(5, name
="reg_a")
80 self
.immz_out
= Signal(reset_less
=True)
81 self
.spr_out
= Data(SPR
, "spr_a")
82 self
.fast_out
= Data(3, "fast_a")
84 def elaborate(self
, platform
):
87 m
.submodules
.sprmap
= sprmap
= SPRMap()
89 # select Register A field
90 ra
= Signal(5, reset_less
=True)
91 comb
+= ra
.eq(self
.dec
.RA
)
92 with m
.If((self
.sel_in
== In1Sel
.RA
) |
93 ((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
94 (ra
!= Const(0, 5)))):
95 comb
+= self
.reg_out
.data
.eq(ra
)
96 comb
+= self
.reg_out
.ok
.eq(1)
98 # zero immediate requested
99 with m
.If((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
100 (self
.reg_out
.data
== Const(0, 5))):
101 comb
+= self
.immz_out
.eq(1)
103 # some Logic/ALU ops have RS as the 3rd arg, but no "RA".
104 with m
.If(self
.sel_in
== In1Sel
.RS
):
105 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
106 comb
+= self
.reg_out
.ok
.eq(1)
108 # decode Fast-SPR based on instruction type
110 with m
.Switch(op
.internal_op
):
112 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeOut
113 with m
.Case(MicrOp
.OP_BC
):
114 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
115 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
) # constant: 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
):
121 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
) # constant: CTR
122 comb
+= self
.fast_out
.ok
.eq(1)
124 # MFSPR move from SPRs
125 with m
.Case(MicrOp
.OP_MFSPR
):
126 spr
= Signal(10, reset_less
=True)
127 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
130 with m
.Case(SPR
.CTR
.value
):
131 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
132 comb
+= self
.fast_out
.ok
.eq(1)
133 with m
.Case(SPR
.LR
.value
):
134 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
135 comb
+= self
.fast_out
.ok
.eq(1)
136 with m
.Case(SPR
.TAR
.value
):
137 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
138 comb
+= self
.fast_out
.ok
.eq(1)
139 with m
.Case(SPR
.SRR0
.value
):
140 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
)
141 comb
+= self
.fast_out
.ok
.eq(1)
142 with m
.Case(SPR
.SRR1
.value
):
143 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
)
144 comb
+= self
.fast_out
.ok
.eq(1)
145 with m
.Case(SPR
.XER
.value
):
147 # : map to internal SPR numbers
148 # XXX TODO: dec and tb not to go through mapping.
150 comb
+= sprmap
.spr_i
.eq(spr
)
151 comb
+= self
.spr_out
.data
.eq(sprmap
.spr_o
)
152 comb
+= self
.spr_out
.ok
.eq(1)
157 class DecodeB(Elaboratable
):
158 """DecodeB from instruction
160 decodes register RB, different forms of immediate (signed, unsigned),
161 and implicit SPRs. register B is basically "lane 2" into the CompUnits.
162 by industry-standard convention, "lane 2" is where fully-decoded
163 immediates are muxed in.
166 def __init__(self
, dec
):
168 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
169 self
.insn_in
= Signal(32, reset_less
=True)
170 self
.reg_out
= Data(5, "reg_b")
171 self
.imm_out
= Data(64, "imm_b")
172 self
.fast_out
= Data(3, "fast_b")
174 def elaborate(self
, platform
):
178 # select Register B field
179 with m
.Switch(self
.sel_in
):
180 with m
.Case(In2Sel
.RB
):
181 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
)
182 comb
+= self
.reg_out
.ok
.eq(1)
183 with m
.Case(In2Sel
.RS
):
184 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
) # for M-Form shiftrot
185 comb
+= self
.reg_out
.ok
.eq(1)
186 with m
.Case(In2Sel
.CONST_UI
):
187 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
)
188 comb
+= self
.imm_out
.ok
.eq(1)
189 with m
.Case(In2Sel
.CONST_SI
): # TODO: sign-extend here?
190 comb
+= self
.imm_out
.data
.eq(
191 exts(self
.dec
.SI
, 16, 64))
192 comb
+= self
.imm_out
.ok
.eq(1)
193 with m
.Case(In2Sel
.CONST_UI_HI
):
194 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
<<16)
195 comb
+= self
.imm_out
.ok
.eq(1)
196 with m
.Case(In2Sel
.CONST_SI_HI
): # TODO: sign-extend here?
197 comb
+= self
.imm_out
.data
.eq(self
.dec
.SI
<<16)
198 comb
+= self
.imm_out
.data
.eq(
199 exts(self
.dec
.SI
<< 16, 32, 64))
200 comb
+= self
.imm_out
.ok
.eq(1)
201 with m
.Case(In2Sel
.CONST_LI
):
202 comb
+= self
.imm_out
.data
.eq(self
.dec
.LI
<<2)
203 comb
+= self
.imm_out
.ok
.eq(1)
204 with m
.Case(In2Sel
.CONST_BD
):
205 comb
+= self
.imm_out
.data
.eq(self
.dec
.BD
<<2)
206 comb
+= self
.imm_out
.ok
.eq(1)
207 with m
.Case(In2Sel
.CONST_DS
):
208 comb
+= self
.imm_out
.data
.eq(self
.dec
.DS
<<2)
209 comb
+= self
.imm_out
.ok
.eq(1)
210 with m
.Case(In2Sel
.CONST_M1
):
211 comb
+= self
.imm_out
.data
.eq(~
Const(0, 64)) # all 1s
212 comb
+= self
.imm_out
.ok
.eq(1)
213 with m
.Case(In2Sel
.CONST_SH
):
214 comb
+= self
.imm_out
.data
.eq(self
.dec
.sh
)
215 comb
+= self
.imm_out
.ok
.eq(1)
216 with m
.Case(In2Sel
.CONST_SH32
):
217 comb
+= self
.imm_out
.data
.eq(self
.dec
.SH32
)
218 comb
+= self
.imm_out
.ok
.eq(1)
220 # decode SPR2 based on instruction type
222 # BCREG implicitly uses LR or TAR for 2nd reg
223 # CTR however is already in fast_spr1 *not* 2.
224 with m
.If(op
.internal_op
== MicrOp
.OP_BCREG
):
225 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
226 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
228 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
229 comb
+= self
.fast_out
.ok
.eq(1)
231 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
232 comb
+= self
.fast_out
.ok
.eq(1)
237 class DecodeC(Elaboratable
):
238 """DecodeC from instruction
240 decodes register RC. this is "lane 3" into some CompUnits (not many)
243 def __init__(self
, dec
):
245 self
.sel_in
= Signal(In3Sel
, reset_less
=True)
246 self
.insn_in
= Signal(32, reset_less
=True)
247 self
.reg_out
= Data(5, "reg_c")
249 def elaborate(self
, platform
):
253 # select Register C field
254 with m
.Switch(self
.sel_in
):
255 with m
.Case(In3Sel
.RB
):
256 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
) # for M-Form shiftrot
257 comb
+= self
.reg_out
.ok
.eq(1)
258 with m
.Case(In3Sel
.RS
):
259 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
260 comb
+= self
.reg_out
.ok
.eq(1)
265 class DecodeOut(Elaboratable
):
266 """DecodeOut from instruction
268 decodes output register RA, RT or SPR
271 def __init__(self
, dec
):
273 self
.sel_in
= Signal(OutSel
, reset_less
=True)
274 self
.insn_in
= Signal(32, reset_less
=True)
275 self
.reg_out
= Data(5, "reg_o")
276 self
.spr_out
= Data(SPR
, "spr_o")
277 self
.fast_out
= Data(3, "fast_o")
279 def elaborate(self
, platform
):
282 m
.submodules
.sprmap
= sprmap
= SPRMap()
285 # select Register out field
286 with m
.Switch(self
.sel_in
):
287 with m
.Case(OutSel
.RT
):
288 comb
+= self
.reg_out
.data
.eq(self
.dec
.RT
)
289 comb
+= self
.reg_out
.ok
.eq(1)
290 with m
.Case(OutSel
.RA
):
291 comb
+= self
.reg_out
.data
.eq(self
.dec
.RA
)
292 comb
+= self
.reg_out
.ok
.eq(1)
293 with m
.Case(OutSel
.SPR
):
294 spr
= Signal(10, reset_less
=True)
295 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
296 # TODO MTSPR 1st spr (fast)
297 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
300 with m
.Case(SPR
.CTR
.value
):
301 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
302 comb
+= self
.fast_out
.ok
.eq(1)
303 with m
.Case(SPR
.LR
.value
):
304 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
305 comb
+= self
.fast_out
.ok
.eq(1)
306 with m
.Case(SPR
.TAR
.value
):
307 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
308 comb
+= self
.fast_out
.ok
.eq(1)
309 with m
.Case(SPR
.SRR0
.value
):
310 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
)
311 comb
+= self
.fast_out
.ok
.eq(1)
312 with m
.Case(SPR
.SRR1
.value
):
313 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
)
314 comb
+= self
.fast_out
.ok
.eq(1)
315 with m
.Case(SPR
.XER
.value
):
317 # : map to internal SPR numbers
318 # XXX TODO: dec and tb not to go through mapping.
320 comb
+= sprmap
.spr_i
.eq(spr
)
321 comb
+= self
.spr_out
.data
.eq(sprmap
.spr_o
)
322 comb
+= self
.spr_out
.ok
.eq(1)
324 with m
.Switch(op
.internal_op
):
326 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeA
327 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_BCREG
):
328 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
329 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
) # constant: CTR
330 comb
+= self
.fast_out
.ok
.eq(1)
332 # RFID 1st spr (fast)
333 with m
.Case(MicrOp
.OP_RFID
):
334 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
335 comb
+= self
.fast_out
.ok
.eq(1)
340 class DecodeOut2(Elaboratable
):
341 """DecodeOut2 from instruction
343 decodes output registers
346 def __init__(self
, dec
):
348 self
.sel_in
= Signal(OutSel
, reset_less
=True)
349 self
.lk
= Signal(reset_less
=True)
350 self
.insn_in
= Signal(32, reset_less
=True)
351 self
.reg_out
= Data(5, "reg_o")
352 self
.fast_out
= Data(3, "fast_o")
354 def elaborate(self
, platform
):
358 # update mode LD/ST uses read-reg A also as an output
359 with m
.If(self
.dec
.op
.upd
== LDSTMode
.update
):
360 comb
+= self
.reg_out
.eq(self
.dec
.RA
)
361 comb
+= self
.reg_out
.ok
.eq(1)
363 # B, BC or BCREG: potential implicit register (LR) output
364 # these give bl, bcl, bclrl, etc.
366 with m
.Switch(op
.internal_op
):
368 # BC* implicit register (LR)
369 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_B
, MicrOp
.OP_BCREG
):
370 with m
.If(self
.lk
): # "link" mode
371 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
) # constant: LR
372 comb
+= self
.fast_out
.ok
.eq(1)
374 # RFID 2nd spr (fast)
375 with m
.Case(MicrOp
.OP_RFID
):
376 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
377 comb
+= self
.fast_out
.ok
.eq(1)
382 class DecodeRC(Elaboratable
):
383 """DecodeRc from instruction
385 decodes Record bit Rc
387 def __init__(self
, dec
):
389 self
.sel_in
= Signal(RC
, reset_less
=True)
390 self
.insn_in
= Signal(32, reset_less
=True)
391 self
.rc_out
= Data(1, "rc")
393 def elaborate(self
, platform
):
397 # select Record bit out field
398 with m
.Switch(self
.sel_in
):
400 comb
+= self
.rc_out
.data
.eq(self
.dec
.Rc
)
401 comb
+= self
.rc_out
.ok
.eq(1)
403 comb
+= self
.rc_out
.data
.eq(1)
404 comb
+= self
.rc_out
.ok
.eq(1)
405 with m
.Case(RC
.NONE
):
406 comb
+= self
.rc_out
.data
.eq(0)
407 comb
+= self
.rc_out
.ok
.eq(1)
412 class DecodeOE(Elaboratable
):
413 """DecodeOE from instruction
415 decodes OE field: uses RC decode detection which might not be good
417 -- For now, use "rc" in the decode table to decide whether oe exists.
418 -- This is not entirely correct architecturally: For mulhd and
419 -- mulhdu, the OE field is reserved. It remains to be seen what an
420 -- actual POWER9 does if we set it on those instructions, for now we
421 -- test that further down when assigning to the multiplier oe input.
423 def __init__(self
, dec
):
425 self
.sel_in
= Signal(RC
, reset_less
=True)
426 self
.insn_in
= Signal(32, reset_less
=True)
427 self
.oe_out
= Data(1, "oe")
429 def elaborate(self
, platform
):
434 with m
.Switch(op
.internal_op
):
436 # mulhw, mulhwu, mulhd, mulhdu - these *ignore* OE
437 with m
.Case(MicrOp
.OP_MUL_H64
, MicrOp
.OP_MUL_H32
):
440 # all other ops decode OE field
442 # select OE bit out field
443 with m
.Switch(self
.sel_in
):
445 comb
+= self
.oe_out
.data
.eq(self
.dec
.OE
)
446 comb
+= self
.oe_out
.ok
.eq(1)
450 class DecodeCRIn(Elaboratable
):
451 """Decodes input CR from instruction
453 CR indices - insn fields - (not the data *in* the CR) require only 3
454 bits because they refer to CR0-CR7
457 def __init__(self
, dec
):
459 self
.sel_in
= Signal(CRInSel
, reset_less
=True)
460 self
.insn_in
= Signal(32, reset_less
=True)
461 self
.cr_bitfield
= Data(3, "cr_bitfield")
462 self
.cr_bitfield_b
= Data(3, "cr_bitfield_b")
463 self
.cr_bitfield_o
= Data(3, "cr_bitfield_o")
464 self
.whole_reg
= Signal(reset_less
=True)
466 def elaborate(self
, platform
):
470 comb
+= self
.cr_bitfield
.ok
.eq(0)
471 comb
+= self
.cr_bitfield_b
.ok
.eq(0)
472 comb
+= self
.whole_reg
.eq(0)
473 with m
.Switch(self
.sel_in
):
474 with m
.Case(CRInSel
.NONE
):
475 pass # No bitfield activated
476 with m
.Case(CRInSel
.CR0
):
477 comb
+= self
.cr_bitfield
.data
.eq(0)
478 comb
+= self
.cr_bitfield
.ok
.eq(1)
479 with m
.Case(CRInSel
.BI
):
480 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BI
[2:5])
481 comb
+= self
.cr_bitfield
.ok
.eq(1)
482 with m
.Case(CRInSel
.BFA
):
483 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BFA
)
484 comb
+= self
.cr_bitfield
.ok
.eq(1)
485 with m
.Case(CRInSel
.BA_BB
):
486 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BA
[2:5])
487 comb
+= self
.cr_bitfield
.ok
.eq(1)
488 comb
+= self
.cr_bitfield_b
.data
.eq(self
.dec
.BB
[2:5])
489 comb
+= self
.cr_bitfield_b
.ok
.eq(1)
490 comb
+= self
.cr_bitfield_o
.data
.eq(self
.dec
.BT
[2:5])
491 comb
+= self
.cr_bitfield_o
.ok
.eq(1)
492 with m
.Case(CRInSel
.BC
):
493 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BC
[2:5])
494 comb
+= self
.cr_bitfield
.ok
.eq(1)
495 with m
.Case(CRInSel
.WHOLE_REG
):
496 comb
+= self
.whole_reg
.eq(1)
501 class DecodeCROut(Elaboratable
):
502 """Decodes input CR from instruction
504 CR indices - insn fields - (not the data *in* the CR) require only 3
505 bits because they refer to CR0-CR7
508 def __init__(self
, dec
):
510 self
.rc_in
= Signal(reset_less
=True)
511 self
.sel_in
= Signal(CROutSel
, reset_less
=True)
512 self
.insn_in
= Signal(32, reset_less
=True)
513 self
.cr_bitfield
= Data(3, "cr_bitfield")
514 self
.whole_reg
= Signal(reset_less
=True)
516 def elaborate(self
, platform
):
520 comb
+= self
.cr_bitfield
.ok
.eq(0)
521 comb
+= self
.whole_reg
.eq(0)
522 with m
.Switch(self
.sel_in
):
523 with m
.Case(CROutSel
.NONE
):
524 pass # No bitfield activated
525 with m
.Case(CROutSel
.CR0
):
526 comb
+= self
.cr_bitfield
.data
.eq(0)
527 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
528 with m
.Case(CROutSel
.BF
):
529 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BF
)
530 comb
+= self
.cr_bitfield
.ok
.eq(1)
531 with m
.Case(CROutSel
.BT
):
532 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormXL
.BT
[2:5])
533 comb
+= self
.cr_bitfield
.ok
.eq(1)
534 with m
.Case(CROutSel
.WHOLE_REG
):
535 comb
+= self
.whole_reg
.eq(1)
540 class PowerDecode2(Elaboratable
):
541 """PowerDecode2: the main instruction decoder.
543 whilst PowerDecode is responsible for decoding the actual opcode, this
544 module encapsulates further specialist, sparse information and
545 expansion of fields that is inconvenient to have in the CSV files.
546 for example: the encoding of the immediates, which are detected
547 and expanded out to their full value from an annotated (enum)
550 implicit register usage is also set up, here. for example: OP_BC
551 requires implicitly reading CTR, OP_RFID requires implicitly writing
554 in addition, PowerDecoder2 is responsible for detecting whether
555 instructions are illegal (or privileged) or not, and instead of
556 just leaving at that, *replacing* the instruction to execute with
557 a suitable alternative (trap).
560 def __init__(self
, dec
):
563 self
.e
= Decode2ToExecute1Type()
564 self
.valid
= Signal() # sync signal
566 # state information needed by the Decoder
567 self
.msr
= Signal(64, reset_less
=True) # copy of MSR
570 return self
.dec
.ports() + self
.e
.ports()
572 def elaborate(self
, platform
):
575 e
, op
, do
, msr
= self
.e
, self
.dec
.op
, self
.e
.do
, self
.msr
577 # set up submodule decoders
578 m
.submodules
.dec
= self
.dec
579 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
)
580 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
)
581 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
)
582 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
)
583 m
.submodules
.dec_o2
= dec_o2
= DecodeOut2(self
.dec
)
584 m
.submodules
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
585 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
)
586 m
.submodules
.dec_cr_in
= dec_cr_in
= DecodeCRIn(self
.dec
)
587 m
.submodules
.dec_cr_out
= dec_cr_out
= DecodeCROut(self
.dec
)
589 # copy instruction through...
590 for i
in [do
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
591 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
, dec_rc
.insn_in
,
592 dec_oe
.insn_in
, dec_cr_in
.insn_in
, dec_cr_out
.insn_in
]:
593 comb
+= i
.eq(self
.dec
.opcode_in
)
595 # ...and subdecoders' input fields
596 comb
+= dec_a
.sel_in
.eq(op
.in1_sel
)
597 comb
+= dec_b
.sel_in
.eq(op
.in2_sel
)
598 comb
+= dec_c
.sel_in
.eq(op
.in3_sel
)
599 comb
+= dec_o
.sel_in
.eq(op
.out_sel
)
600 comb
+= dec_o2
.sel_in
.eq(op
.out_sel
)
601 comb
+= dec_o2
.lk
.eq(do
.lk
)
602 comb
+= dec_rc
.sel_in
.eq(op
.rc_sel
)
603 comb
+= dec_oe
.sel_in
.eq(op
.rc_sel
) # XXX should be OE sel
604 comb
+= dec_cr_in
.sel_in
.eq(op
.cr_in
)
605 comb
+= dec_cr_out
.sel_in
.eq(op
.cr_out
)
606 comb
+= dec_cr_out
.rc_in
.eq(dec_rc
.rc_out
.data
)
608 # set up instruction, pick fn unit
609 comb
+= do
.insn_type
.eq(op
.internal_op
) # no op: defaults to OP_ILLEGAL
610 comb
+= do
.fn_unit
.eq(op
.function_unit
)
612 # registers a, b, c and out and out2 (LD/ST EA)
613 comb
+= e
.read_reg1
.eq(dec_a
.reg_out
)
614 comb
+= e
.read_reg2
.eq(dec_b
.reg_out
)
615 comb
+= e
.read_reg3
.eq(dec_c
.reg_out
)
616 comb
+= e
.write_reg
.eq(dec_o
.reg_out
)
617 comb
+= e
.write_ea
.eq(dec_o2
.reg_out
)
618 comb
+= do
.imm_data
.eq(dec_b
.imm_out
) # immediate in RB (usually)
619 comb
+= do
.zero_a
.eq(dec_a
.immz_out
) # RA==0 detected
622 comb
+= do
.rc
.eq(dec_rc
.rc_out
)
623 comb
+= do
.oe
.eq(dec_oe
.oe_out
)
626 comb
+= e
.read_spr1
.eq(dec_a
.spr_out
)
627 comb
+= e
.write_spr
.eq(dec_o
.spr_out
)
630 comb
+= e
.read_fast1
.eq(dec_a
.fast_out
)
631 comb
+= e
.read_fast2
.eq(dec_b
.fast_out
)
632 comb
+= e
.write_fast1
.eq(dec_o
.fast_out
)
633 comb
+= e
.write_fast2
.eq(dec_o2
.fast_out
)
635 # condition registers (CR)
636 comb
+= e
.read_cr1
.eq(dec_cr_in
.cr_bitfield
)
637 comb
+= e
.read_cr2
.eq(dec_cr_in
.cr_bitfield_b
)
638 comb
+= e
.read_cr3
.eq(dec_cr_in
.cr_bitfield_o
)
639 comb
+= e
.write_cr
.eq(dec_cr_out
.cr_bitfield
)
641 comb
+= do
.read_cr_whole
.eq(dec_cr_in
.whole_reg
)
642 comb
+= do
.write_cr_whole
.eq(dec_cr_out
.whole_reg
)
643 comb
+= do
.write_cr0
.eq(dec_cr_out
.cr_bitfield
.ok
)
645 # decoded/selected instruction flags
646 comb
+= do
.data_len
.eq(op
.ldst_len
)
647 comb
+= do
.invert_a
.eq(op
.inv_a
)
648 comb
+= do
.invert_out
.eq(op
.inv_out
)
649 comb
+= do
.input_carry
.eq(op
.cry_in
) # carry comes in
650 comb
+= do
.output_carry
.eq(op
.cry_out
) # carry goes out
651 comb
+= do
.is_32bit
.eq(op
.is_32b
)
652 comb
+= do
.is_signed
.eq(op
.sgn
)
654 comb
+= do
.lk
.eq(self
.dec
.LK
) # XXX TODO: accessor
656 comb
+= do
.byte_reverse
.eq(op
.br
)
657 comb
+= do
.sign_extend
.eq(op
.sgn_ext
)
658 comb
+= do
.ldst_mode
.eq(op
.upd
) # LD/ST mode (update, cache-inhibit)
660 # These should be removed eventually
661 comb
+= do
.input_cr
.eq(op
.cr_in
) # condition reg comes in
662 comb
+= do
.output_cr
.eq(op
.cr_out
) # condition reg goes in
664 # sigh this is exactly the sort of thing for which the
665 # decoder is designed to not need. MTSPR, MFSPR and others need
666 # access to the XER bits. however setting e.oe is not appropriate
667 with m
.If(op
.internal_op
== MicrOp
.OP_MFSPR
):
668 comb
+= e
.xer_in
.eq(1)
669 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
670 comb
+= e
.xer_out
.eq(1)
672 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
673 with m
.If(op
.internal_op
== MicrOp
.OP_TRAP
):
674 comb
+= do
.trapaddr
.eq(0x70) # addr=0x700 (strip first nibble)
676 # TODO: get msr, then can do privileged instruction
677 with m
.If(instr_is_priv(m
, op
.internal_op
, e
.do
.insn
) & msr
[MSR
.PR
]):
678 # privileged instruction trap
679 self
.trap(m
, TT
.PRIV
, 0x700)
681 # illegal instruction must redirect to trap. this is done by
682 # *overwriting* the decoded instruction and starting again.
683 # (note: the same goes for interrupts and for privileged operations,
684 # just with different trapaddr and traptype)
685 with m
.Elif(op
.internal_op
== MicrOp
.OP_ILLEGAL
):
686 # illegal instruction trap
687 self
.trap(m
, TT
.ILLEG
, 0x700)
689 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
690 # Note: OP_SC could actually be modified to just be a trap
691 with m
.If((do
.insn_type
== MicrOp
.OP_TRAP
) |
692 (do
.insn_type
== MicrOp
.OP_SC
)):
693 # TRAP write fast1 = SRR0
694 comb
+= e
.write_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
695 comb
+= e
.write_fast1
.ok
.eq(1)
696 # TRAP write fast2 = SRR1
697 comb
+= e
.write_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
698 comb
+= e
.write_fast2
.ok
.eq(1)
700 # RFID: needs to read SRR0/1
701 with m
.If(do
.insn_type
== MicrOp
.OP_RFID
):
702 # TRAP read fast1 = SRR0
703 comb
+= e
.read_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
704 comb
+= e
.read_fast1
.ok
.eq(1)
705 # TRAP read fast2 = SRR1
706 comb
+= e
.read_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
707 comb
+= e
.read_fast2
.ok
.eq(1)
711 def trap(self
, m
, traptype
, trapaddr
):
712 """trap: this basically "rewrites" the decoded instruction as a trap
715 e
, op
, do
= self
.e
, self
.dec
.op
, self
.e
.do
716 comb
+= e
.eq(0) # reset eeeeeverything
718 comb
+= do
.insn
.eq(self
.dec
.opcode_in
)
719 comb
+= do
.insn_type
.eq(MicrOp
.OP_TRAP
)
720 comb
+= do
.fn_unit
.eq(Function
.TRAP
)
721 comb
+= do
.trapaddr
.eq(trapaddr
>> 4) # cut bottom 4 bits
722 comb
+= do
.traptype
.eq(traptype
) # request type
724 def regspecmap_read(self
, regfile
, regname
):
725 """regspecmap_read: provides PowerDecode2 with an encoding relationship
726 to Function Unit port regfiles (read-enable, read regnum, write regnum)
727 regfile and regname arguments are fields 1 and 2 from a given regspec.
729 return regspec_decode_read(self
.e
, regfile
, regname
)
731 def regspecmap_write(self
, regfile
, regname
):
732 """regspecmap_write: provides PowerDecode2 with an encoding relationship
733 to Function Unit port regfiles (write port, write regnum)
734 regfile and regname arguments are fields 1 and 2 from a given regspec.
736 return regspec_decode_write(self
.e
, regfile
, regname
)
738 def rdflags(self
, cu
):
740 for idx
in range(cu
.n_src
):
741 regfile
, regname
, _
= cu
.get_in_spec(idx
)
742 rdflag
, read
= self
.regspecmap_read(regfile
, regname
)
744 print ("rdflags", rdl
)
748 if __name__
== '__main__':
749 pdecode
= create_pdecode()
750 dec2
= PowerDecode2(pdecode
)
751 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
752 with
open("dec2.il", "w") as f
: