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
27 # see traptype (and trap main_stage.py)
35 def decode_spr_num(spr
):
36 return Cat(spr
[5:10], spr
[0:5])
39 def instr_is_priv(m
, op
, insn
):
40 """determines if the instruction is privileged or not
43 is_priv_insn
= Signal(reset_less
=True)
45 with m
.Case(MicrOp
.OP_ATTN
) : comb
+= is_priv_insn
.eq(1)
46 with m
.Case(MicrOp
.OP_MFMSR
) : comb
+= is_priv_insn
.eq(1)
47 with m
.Case(MicrOp
.OP_MTMSRD
): comb
+= is_priv_insn
.eq(1)
48 with m
.Case(MicrOp
.OP_MTMSR
): comb
+= is_priv_insn
.eq(1)
49 with m
.Case(MicrOp
.OP_RFID
) : comb
+= is_priv_insn
.eq(1)
51 #with m.Case(MicrOp.OP_TLBIE) : comb += is_priv_insn.eq(1)
52 with m
.Case(MicrOp
.OP_MFSPR
, MicrOp
.OP_MTSPR
):
53 with m
.If(insn
[20]): # field XFX.spr[-1] i think
54 comb
+= is_priv_insn
.eq(1)
58 class SPRMap(Elaboratable
):
59 """SPRMap: maps POWER9 SPR numbers to internal enum values
62 self
.spr_i
= Signal(10, reset_less
=True)
63 self
.spr_o
= Signal(SPR
, reset_less
=True)
65 def elaborate(self
, platform
):
67 with m
.Switch(self
.spr_i
):
68 for i
, x
in enumerate(SPR
):
70 m
.d
.comb
+= self
.spr_o
.eq(i
)
74 class DecodeA(Elaboratable
):
75 """DecodeA from instruction
77 decodes register RA, whether immediate-zero, implicit and
81 def __init__(self
, dec
):
83 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
84 self
.insn_in
= Signal(32, reset_less
=True)
85 self
.reg_out
= Data(5, name
="reg_a")
86 self
.immz_out
= Signal(reset_less
=True)
87 self
.spr_out
= Data(SPR
, "spr_a")
88 self
.fast_out
= Data(3, "fast_a")
90 def elaborate(self
, platform
):
93 m
.submodules
.sprmap
= sprmap
= SPRMap()
95 # select Register A field
96 ra
= Signal(5, reset_less
=True)
97 comb
+= ra
.eq(self
.dec
.RA
)
98 with m
.If((self
.sel_in
== In1Sel
.RA
) |
99 ((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
100 (ra
!= Const(0, 5)))):
101 comb
+= self
.reg_out
.data
.eq(ra
)
102 comb
+= self
.reg_out
.ok
.eq(1)
104 # zero immediate requested
105 with m
.If((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
106 (self
.reg_out
.data
== Const(0, 5))):
107 comb
+= self
.immz_out
.eq(1)
109 # some Logic/ALU ops have RS as the 3rd arg, but no "RA".
110 with m
.If(self
.sel_in
== In1Sel
.RS
):
111 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
112 comb
+= self
.reg_out
.ok
.eq(1)
114 # decode Fast-SPR based on instruction type
116 with m
.Switch(op
.internal_op
):
118 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeOut
119 with m
.Case(MicrOp
.OP_BC
):
120 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
121 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
) # constant: CTR
122 comb
+= self
.fast_out
.ok
.eq(1)
123 with m
.Case(MicrOp
.OP_BCREG
):
124 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
125 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
126 with m
.If(xo9
& ~xo5
):
127 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
) # constant: CTR
128 comb
+= self
.fast_out
.ok
.eq(1)
130 # MFSPR move from SPRs
131 with m
.Case(MicrOp
.OP_MFSPR
):
132 spr
= Signal(10, reset_less
=True)
133 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
136 with m
.Case(SPR
.CTR
.value
):
137 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
138 comb
+= self
.fast_out
.ok
.eq(1)
139 with m
.Case(SPR
.LR
.value
):
140 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
141 comb
+= self
.fast_out
.ok
.eq(1)
142 with m
.Case(SPR
.TAR
.value
):
143 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
144 comb
+= self
.fast_out
.ok
.eq(1)
145 with m
.Case(SPR
.SRR0
.value
):
146 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
)
147 comb
+= self
.fast_out
.ok
.eq(1)
148 with m
.Case(SPR
.SRR1
.value
):
149 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
)
150 comb
+= self
.fast_out
.ok
.eq(1)
151 with m
.Case(SPR
.XER
.value
):
153 # : map to internal SPR numbers
154 # XXX TODO: dec and tb not to go through mapping.
156 comb
+= sprmap
.spr_i
.eq(spr
)
157 comb
+= self
.spr_out
.data
.eq(sprmap
.spr_o
)
158 comb
+= self
.spr_out
.ok
.eq(1)
163 class DecodeB(Elaboratable
):
164 """DecodeB from instruction
166 decodes register RB, different forms of immediate (signed, unsigned),
167 and implicit SPRs. register B is basically "lane 2" into the CompUnits.
168 by industry-standard convention, "lane 2" is where fully-decoded
169 immediates are muxed in.
172 def __init__(self
, dec
):
174 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
175 self
.insn_in
= Signal(32, reset_less
=True)
176 self
.reg_out
= Data(5, "reg_b")
177 self
.imm_out
= Data(64, "imm_b")
178 self
.fast_out
= Data(3, "fast_b")
180 def elaborate(self
, platform
):
184 # select Register B field
185 with m
.Switch(self
.sel_in
):
186 with m
.Case(In2Sel
.RB
):
187 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
)
188 comb
+= self
.reg_out
.ok
.eq(1)
189 with m
.Case(In2Sel
.RS
):
190 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
) # for M-Form shiftrot
191 comb
+= self
.reg_out
.ok
.eq(1)
192 with m
.Case(In2Sel
.CONST_UI
):
193 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
)
194 comb
+= self
.imm_out
.ok
.eq(1)
195 with m
.Case(In2Sel
.CONST_SI
): # TODO: sign-extend here?
196 comb
+= self
.imm_out
.data
.eq(
197 exts(self
.dec
.SI
, 16, 64))
198 comb
+= self
.imm_out
.ok
.eq(1)
199 with m
.Case(In2Sel
.CONST_UI_HI
):
200 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
<<16)
201 comb
+= self
.imm_out
.ok
.eq(1)
202 with m
.Case(In2Sel
.CONST_SI_HI
): # TODO: sign-extend here?
203 comb
+= self
.imm_out
.data
.eq(self
.dec
.SI
<<16)
204 comb
+= self
.imm_out
.data
.eq(
205 exts(self
.dec
.SI
<< 16, 32, 64))
206 comb
+= self
.imm_out
.ok
.eq(1)
207 with m
.Case(In2Sel
.CONST_LI
):
208 comb
+= self
.imm_out
.data
.eq(self
.dec
.LI
<<2)
209 comb
+= self
.imm_out
.ok
.eq(1)
210 with m
.Case(In2Sel
.CONST_BD
):
211 comb
+= self
.imm_out
.data
.eq(self
.dec
.BD
<<2)
212 comb
+= self
.imm_out
.ok
.eq(1)
213 with m
.Case(In2Sel
.CONST_DS
):
214 comb
+= self
.imm_out
.data
.eq(self
.dec
.DS
<<2)
215 comb
+= self
.imm_out
.ok
.eq(1)
216 with m
.Case(In2Sel
.CONST_M1
):
217 comb
+= self
.imm_out
.data
.eq(~
Const(0, 64)) # all 1s
218 comb
+= self
.imm_out
.ok
.eq(1)
219 with m
.Case(In2Sel
.CONST_SH
):
220 comb
+= self
.imm_out
.data
.eq(self
.dec
.sh
)
221 comb
+= self
.imm_out
.ok
.eq(1)
222 with m
.Case(In2Sel
.CONST_SH32
):
223 comb
+= self
.imm_out
.data
.eq(self
.dec
.SH32
)
224 comb
+= self
.imm_out
.ok
.eq(1)
226 # decode SPR2 based on instruction type
228 # BCREG implicitly uses LR or TAR for 2nd reg
229 # CTR however is already in fast_spr1 *not* 2.
230 with m
.If(op
.internal_op
== MicrOp
.OP_BCREG
):
231 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
232 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
234 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
235 comb
+= self
.fast_out
.ok
.eq(1)
237 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
238 comb
+= self
.fast_out
.ok
.eq(1)
243 class DecodeC(Elaboratable
):
244 """DecodeC from instruction
246 decodes register RC. this is "lane 3" into some CompUnits (not many)
249 def __init__(self
, dec
):
251 self
.sel_in
= Signal(In3Sel
, reset_less
=True)
252 self
.insn_in
= Signal(32, reset_less
=True)
253 self
.reg_out
= Data(5, "reg_c")
255 def elaborate(self
, platform
):
259 # select Register C field
260 with m
.Switch(self
.sel_in
):
261 with m
.Case(In3Sel
.RB
):
262 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
) # for M-Form shiftrot
263 comb
+= self
.reg_out
.ok
.eq(1)
264 with m
.Case(In3Sel
.RS
):
265 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
266 comb
+= self
.reg_out
.ok
.eq(1)
271 class DecodeOut(Elaboratable
):
272 """DecodeOut from instruction
274 decodes output register RA, RT or SPR
277 def __init__(self
, dec
):
279 self
.sel_in
= Signal(OutSel
, reset_less
=True)
280 self
.insn_in
= Signal(32, reset_less
=True)
281 self
.reg_out
= Data(5, "reg_o")
282 self
.spr_out
= Data(SPR
, "spr_o")
283 self
.fast_out
= Data(3, "fast_o")
285 def elaborate(self
, platform
):
288 m
.submodules
.sprmap
= sprmap
= SPRMap()
291 # select Register out field
292 with m
.Switch(self
.sel_in
):
293 with m
.Case(OutSel
.RT
):
294 comb
+= self
.reg_out
.data
.eq(self
.dec
.RT
)
295 comb
+= self
.reg_out
.ok
.eq(1)
296 with m
.Case(OutSel
.RA
):
297 comb
+= self
.reg_out
.data
.eq(self
.dec
.RA
)
298 comb
+= self
.reg_out
.ok
.eq(1)
299 with m
.Case(OutSel
.SPR
):
300 spr
= Signal(10, reset_less
=True)
301 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
302 # TODO MTSPR 1st spr (fast)
303 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
306 with m
.Case(SPR
.CTR
.value
):
307 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
308 comb
+= self
.fast_out
.ok
.eq(1)
309 with m
.Case(SPR
.LR
.value
):
310 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
311 comb
+= self
.fast_out
.ok
.eq(1)
312 with m
.Case(SPR
.TAR
.value
):
313 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
314 comb
+= self
.fast_out
.ok
.eq(1)
315 with m
.Case(SPR
.SRR0
.value
):
316 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
)
317 comb
+= self
.fast_out
.ok
.eq(1)
318 with m
.Case(SPR
.SRR1
.value
):
319 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
)
320 comb
+= self
.fast_out
.ok
.eq(1)
321 with m
.Case(SPR
.XER
.value
):
323 # : map to internal SPR numbers
324 # XXX TODO: dec and tb not to go through mapping.
326 comb
+= sprmap
.spr_i
.eq(spr
)
327 comb
+= self
.spr_out
.data
.eq(sprmap
.spr_o
)
328 comb
+= self
.spr_out
.ok
.eq(1)
330 with m
.Switch(op
.internal_op
):
332 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeA
333 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_BCREG
):
334 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
335 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
) # constant: CTR
336 comb
+= self
.fast_out
.ok
.eq(1)
338 # RFID 1st spr (fast)
339 with m
.Case(MicrOp
.OP_RFID
):
340 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
341 comb
+= self
.fast_out
.ok
.eq(1)
346 class DecodeOut2(Elaboratable
):
347 """DecodeOut2 from instruction
349 decodes output registers
352 def __init__(self
, dec
):
354 self
.sel_in
= Signal(OutSel
, reset_less
=True)
355 self
.lk
= Signal(reset_less
=True)
356 self
.insn_in
= Signal(32, reset_less
=True)
357 self
.reg_out
= Data(5, "reg_o")
358 self
.fast_out
= Data(3, "fast_o")
360 def elaborate(self
, platform
):
364 # update mode LD/ST uses read-reg A also as an output
365 with m
.If(self
.dec
.op
.upd
== LDSTMode
.update
):
366 comb
+= self
.reg_out
.eq(self
.dec
.RA
)
367 comb
+= self
.reg_out
.ok
.eq(1)
369 # B, BC or BCREG: potential implicit register (LR) output
370 # these give bl, bcl, bclrl, etc.
372 with m
.Switch(op
.internal_op
):
374 # BC* implicit register (LR)
375 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_B
, MicrOp
.OP_BCREG
):
376 with m
.If(self
.lk
): # "link" mode
377 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
) # constant: LR
378 comb
+= self
.fast_out
.ok
.eq(1)
380 # RFID 2nd spr (fast)
381 with m
.Case(MicrOp
.OP_RFID
):
382 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
383 comb
+= self
.fast_out
.ok
.eq(1)
388 class DecodeRC(Elaboratable
):
389 """DecodeRc from instruction
391 decodes Record bit Rc
393 def __init__(self
, dec
):
395 self
.sel_in
= Signal(RC
, reset_less
=True)
396 self
.insn_in
= Signal(32, reset_less
=True)
397 self
.rc_out
= Data(1, "rc")
399 def elaborate(self
, platform
):
403 # select Record bit out field
404 with m
.Switch(self
.sel_in
):
406 comb
+= self
.rc_out
.data
.eq(self
.dec
.Rc
)
407 comb
+= self
.rc_out
.ok
.eq(1)
409 comb
+= self
.rc_out
.data
.eq(1)
410 comb
+= self
.rc_out
.ok
.eq(1)
411 with m
.Case(RC
.NONE
):
412 comb
+= self
.rc_out
.data
.eq(0)
413 comb
+= self
.rc_out
.ok
.eq(1)
418 class DecodeOE(Elaboratable
):
419 """DecodeOE from instruction
421 decodes OE field: uses RC decode detection which might not be good
423 -- For now, use "rc" in the decode table to decide whether oe exists.
424 -- This is not entirely correct architecturally: For mulhd and
425 -- mulhdu, the OE field is reserved. It remains to be seen what an
426 -- actual POWER9 does if we set it on those instructions, for now we
427 -- test that further down when assigning to the multiplier oe input.
429 def __init__(self
, dec
):
431 self
.sel_in
= Signal(RC
, reset_less
=True)
432 self
.insn_in
= Signal(32, reset_less
=True)
433 self
.oe_out
= Data(1, "oe")
435 def elaborate(self
, platform
):
440 with m
.Switch(op
.internal_op
):
442 # mulhw, mulhwu, mulhd, mulhdu - these *ignore* OE
443 with m
.Case(MicrOp
.OP_MUL_H64
, MicrOp
.OP_MUL_H32
):
446 # all other ops decode OE field
448 # select OE bit out field
449 with m
.Switch(self
.sel_in
):
451 comb
+= self
.oe_out
.data
.eq(self
.dec
.OE
)
452 comb
+= self
.oe_out
.ok
.eq(1)
456 class DecodeCRIn(Elaboratable
):
457 """Decodes input CR from instruction
459 CR indices - insn fields - (not the data *in* the CR) require only 3
460 bits because they refer to CR0-CR7
463 def __init__(self
, dec
):
465 self
.sel_in
= Signal(CRInSel
, reset_less
=True)
466 self
.insn_in
= Signal(32, reset_less
=True)
467 self
.cr_bitfield
= Data(3, "cr_bitfield")
468 self
.cr_bitfield_b
= Data(3, "cr_bitfield_b")
469 self
.cr_bitfield_o
= Data(3, "cr_bitfield_o")
470 self
.whole_reg
= Signal(reset_less
=True)
472 def elaborate(self
, platform
):
476 comb
+= self
.cr_bitfield
.ok
.eq(0)
477 comb
+= self
.cr_bitfield_b
.ok
.eq(0)
478 comb
+= self
.whole_reg
.eq(0)
479 with m
.Switch(self
.sel_in
):
480 with m
.Case(CRInSel
.NONE
):
481 pass # No bitfield activated
482 with m
.Case(CRInSel
.CR0
):
483 comb
+= self
.cr_bitfield
.data
.eq(0)
484 comb
+= self
.cr_bitfield
.ok
.eq(1)
485 with m
.Case(CRInSel
.BI
):
486 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BI
[2:5])
487 comb
+= self
.cr_bitfield
.ok
.eq(1)
488 with m
.Case(CRInSel
.BFA
):
489 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BFA
)
490 comb
+= self
.cr_bitfield
.ok
.eq(1)
491 with m
.Case(CRInSel
.BA_BB
):
492 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BA
[2:5])
493 comb
+= self
.cr_bitfield
.ok
.eq(1)
494 comb
+= self
.cr_bitfield_b
.data
.eq(self
.dec
.BB
[2:5])
495 comb
+= self
.cr_bitfield_b
.ok
.eq(1)
496 comb
+= self
.cr_bitfield_o
.data
.eq(self
.dec
.BT
[2:5])
497 comb
+= self
.cr_bitfield_o
.ok
.eq(1)
498 with m
.Case(CRInSel
.BC
):
499 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BC
[2:5])
500 comb
+= self
.cr_bitfield
.ok
.eq(1)
501 with m
.Case(CRInSel
.WHOLE_REG
):
502 comb
+= self
.whole_reg
.eq(1)
507 class DecodeCROut(Elaboratable
):
508 """Decodes input CR from instruction
510 CR indices - insn fields - (not the data *in* the CR) require only 3
511 bits because they refer to CR0-CR7
514 def __init__(self
, dec
):
516 self
.rc_in
= Signal(reset_less
=True)
517 self
.sel_in
= Signal(CROutSel
, reset_less
=True)
518 self
.insn_in
= Signal(32, reset_less
=True)
519 self
.cr_bitfield
= Data(3, "cr_bitfield")
520 self
.whole_reg
= Signal(reset_less
=True)
522 def elaborate(self
, platform
):
526 comb
+= self
.cr_bitfield
.ok
.eq(0)
527 comb
+= self
.whole_reg
.eq(0)
528 with m
.Switch(self
.sel_in
):
529 with m
.Case(CROutSel
.NONE
):
530 pass # No bitfield activated
531 with m
.Case(CROutSel
.CR0
):
532 comb
+= self
.cr_bitfield
.data
.eq(0)
533 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
534 with m
.Case(CROutSel
.BF
):
535 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BF
)
536 comb
+= self
.cr_bitfield
.ok
.eq(1)
537 with m
.Case(CROutSel
.BT
):
538 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormXL
.BT
[2:5])
539 comb
+= self
.cr_bitfield
.ok
.eq(1)
540 with m
.Case(CROutSel
.WHOLE_REG
):
541 comb
+= self
.whole_reg
.eq(1)
546 class PowerDecode2(Elaboratable
):
547 """PowerDecode2: the main instruction decoder.
549 whilst PowerDecode is responsible for decoding the actual opcode, this
550 module encapsulates further specialist, sparse information and
551 expansion of fields that is inconvenient to have in the CSV files.
552 for example: the encoding of the immediates, which are detected
553 and expanded out to their full value from an annotated (enum)
556 implicit register usage is also set up, here. for example: OP_BC
557 requires implicitly reading CTR, OP_RFID requires implicitly writing
560 in addition, PowerDecoder2 is responsible for detecting whether
561 instructions are illegal (or privileged) or not, and instead of
562 just leaving at that, *replacing* the instruction to execute with
563 a suitable alternative (trap).
566 def __init__(self
, dec
):
569 self
.e
= Decode2ToExecute1Type()
570 self
.valid
= Signal() # sync signal
572 # state information needed by the Decoder
573 self
.msr
= Signal(64, reset_less
=True) # copy of MSR
576 return self
.dec
.ports() + self
.e
.ports()
578 def elaborate(self
, platform
):
581 e
, op
, do
, msr
= self
.e
, self
.dec
.op
, self
.e
.do
, self
.msr
583 # set up submodule decoders
584 m
.submodules
.dec
= self
.dec
585 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
)
586 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
)
587 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
)
588 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
)
589 m
.submodules
.dec_o2
= dec_o2
= DecodeOut2(self
.dec
)
590 m
.submodules
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
591 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
)
592 m
.submodules
.dec_cr_in
= dec_cr_in
= DecodeCRIn(self
.dec
)
593 m
.submodules
.dec_cr_out
= dec_cr_out
= DecodeCROut(self
.dec
)
595 # copy instruction through...
596 for i
in [do
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
597 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
, dec_rc
.insn_in
,
598 dec_oe
.insn_in
, dec_cr_in
.insn_in
, dec_cr_out
.insn_in
]:
599 comb
+= i
.eq(self
.dec
.opcode_in
)
601 # ...and subdecoders' input fields
602 comb
+= dec_a
.sel_in
.eq(op
.in1_sel
)
603 comb
+= dec_b
.sel_in
.eq(op
.in2_sel
)
604 comb
+= dec_c
.sel_in
.eq(op
.in3_sel
)
605 comb
+= dec_o
.sel_in
.eq(op
.out_sel
)
606 comb
+= dec_o2
.sel_in
.eq(op
.out_sel
)
607 comb
+= dec_o2
.lk
.eq(do
.lk
)
608 comb
+= dec_rc
.sel_in
.eq(op
.rc_sel
)
609 comb
+= dec_oe
.sel_in
.eq(op
.rc_sel
) # XXX should be OE sel
610 comb
+= dec_cr_in
.sel_in
.eq(op
.cr_in
)
611 comb
+= dec_cr_out
.sel_in
.eq(op
.cr_out
)
612 comb
+= dec_cr_out
.rc_in
.eq(dec_rc
.rc_out
.data
)
614 # set up instruction, pick fn unit
615 comb
+= do
.insn_type
.eq(op
.internal_op
) # no op: defaults to OP_ILLEGAL
616 comb
+= do
.fn_unit
.eq(op
.function_unit
)
618 # registers a, b, c and out and out2 (LD/ST EA)
619 comb
+= e
.read_reg1
.eq(dec_a
.reg_out
)
620 comb
+= e
.read_reg2
.eq(dec_b
.reg_out
)
621 comb
+= e
.read_reg3
.eq(dec_c
.reg_out
)
622 comb
+= e
.write_reg
.eq(dec_o
.reg_out
)
623 comb
+= e
.write_ea
.eq(dec_o2
.reg_out
)
624 comb
+= do
.imm_data
.eq(dec_b
.imm_out
) # immediate in RB (usually)
625 comb
+= do
.zero_a
.eq(dec_a
.immz_out
) # RA==0 detected
628 comb
+= do
.rc
.eq(dec_rc
.rc_out
)
629 comb
+= do
.oe
.eq(dec_oe
.oe_out
)
632 comb
+= e
.read_spr1
.eq(dec_a
.spr_out
)
633 comb
+= e
.write_spr
.eq(dec_o
.spr_out
)
636 comb
+= e
.read_fast1
.eq(dec_a
.fast_out
)
637 comb
+= e
.read_fast2
.eq(dec_b
.fast_out
)
638 comb
+= e
.write_fast1
.eq(dec_o
.fast_out
)
639 comb
+= e
.write_fast2
.eq(dec_o2
.fast_out
)
641 # condition registers (CR)
642 comb
+= e
.read_cr1
.eq(dec_cr_in
.cr_bitfield
)
643 comb
+= e
.read_cr2
.eq(dec_cr_in
.cr_bitfield_b
)
644 comb
+= e
.read_cr3
.eq(dec_cr_in
.cr_bitfield_o
)
645 comb
+= e
.write_cr
.eq(dec_cr_out
.cr_bitfield
)
647 comb
+= do
.read_cr_whole
.eq(dec_cr_in
.whole_reg
)
648 comb
+= do
.write_cr_whole
.eq(dec_cr_out
.whole_reg
)
649 comb
+= do
.write_cr0
.eq(dec_cr_out
.cr_bitfield
.ok
)
651 # decoded/selected instruction flags
652 comb
+= do
.data_len
.eq(op
.ldst_len
)
653 comb
+= do
.invert_a
.eq(op
.inv_a
)
654 comb
+= do
.invert_out
.eq(op
.inv_out
)
655 comb
+= do
.input_carry
.eq(op
.cry_in
) # carry comes in
656 comb
+= do
.output_carry
.eq(op
.cry_out
) # carry goes out
657 comb
+= do
.is_32bit
.eq(op
.is_32b
)
658 comb
+= do
.is_signed
.eq(op
.sgn
)
660 comb
+= do
.lk
.eq(self
.dec
.LK
) # XXX TODO: accessor
662 comb
+= do
.byte_reverse
.eq(op
.br
)
663 comb
+= do
.sign_extend
.eq(op
.sgn_ext
)
664 comb
+= do
.ldst_mode
.eq(op
.upd
) # LD/ST mode (update, cache-inhibit)
666 # These should be removed eventually
667 comb
+= do
.input_cr
.eq(op
.cr_in
) # condition reg comes in
668 comb
+= do
.output_cr
.eq(op
.cr_out
) # condition reg goes in
670 # sigh this is exactly the sort of thing for which the
671 # decoder is designed to not need. MTSPR, MFSPR and others need
672 # access to the XER bits. however setting e.oe is not appropriate
673 with m
.If(op
.internal_op
== MicrOp
.OP_MFSPR
):
674 comb
+= e
.xer_in
.eq(1)
675 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
676 comb
+= e
.xer_out
.eq(1)
678 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
679 with m
.If(op
.internal_op
== MicrOp
.OP_TRAP
):
680 comb
+= do
.trapaddr
.eq(0x70) # addr=0x700 (strip first nibble)
682 # illegal instruction must redirect to trap. this is done by
683 # *overwriting* the decoded instruction and starting again.
684 # (note: the same goes for interrupts and for privileged operations,
685 # just with different trapaddr and traptype)
686 with m
.If(op
.internal_op
== MicrOp
.OP_ILLEGAL
):
687 # illegal instruction trap
688 self
.trap(m
, TT_ILLEG
, 0x700)
690 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
691 # Note: OP_SC could actually be modified to just be a trap
692 with m
.If((do
.insn_type
== MicrOp
.OP_TRAP
) |
693 (do
.insn_type
== MicrOp
.OP_SC
)):
694 # TRAP write fast1 = SRR0
695 comb
+= e
.write_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
696 comb
+= e
.write_fast1
.ok
.eq(1)
697 # TRAP write fast2 = SRR1
698 comb
+= e
.write_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
699 comb
+= e
.write_fast2
.ok
.eq(1)
701 # RFID: needs to read SRR0/1
702 with m
.If(do
.insn_type
== MicrOp
.OP_RFID
):
703 # TRAP read fast1 = SRR0
704 comb
+= e
.read_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
705 comb
+= e
.read_fast1
.ok
.eq(1)
706 # TRAP read fast2 = SRR1
707 comb
+= e
.read_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
708 comb
+= e
.read_fast2
.ok
.eq(1)
710 # TODO: get msr, then can do privileged instruction
711 with m
.If(instr_is_priv(m
, op
.internal_op
, e
.do
.insn
) & msr
[MSR
.PR
]):
712 # privileged instruction trap
713 self
.trap(m
, TT_PRIV
, 0x700)
717 def trap(self
, m
, traptype
, trapaddr
):
718 """trap: this basically "rewrites" the decoded instruction as a trap
721 e
, op
, do
= self
.e
, self
.dec
.op
, self
.e
.do
722 comb
+= e
.eq(0) # reset eeeeeverything
724 comb
+= do
.insn
.eq(self
.dec
.opcode_in
)
725 comb
+= do
.insn_type
.eq(MicrOp
.OP_TRAP
)
726 comb
+= do
.fn_unit
.eq(Function
.TRAP
)
727 comb
+= do
.trapaddr
.eq(trapaddr
>> 4) # cut bottom 4 bits
728 comb
+= do
.traptype
.eq(traptype
) # request type
730 def regspecmap_read(self
, regfile
, regname
):
731 """regspecmap_read: provides PowerDecode2 with an encoding relationship
732 to Function Unit port regfiles (read-enable, read regnum, write regnum)
733 regfile and regname arguments are fields 1 and 2 from a given regspec.
735 return regspec_decode_read(self
.e
, regfile
, regname
)
737 def regspecmap_write(self
, regfile
, regname
):
738 """regspecmap_write: provides PowerDecode2 with an encoding relationship
739 to Function Unit port regfiles (write port, write regnum)
740 regfile and regname arguments are fields 1 and 2 from a given regspec.
742 return regspec_decode_write(self
.e
, regfile
, regname
)
744 def rdflags(self
, cu
):
746 for idx
in range(cu
.n_src
):
747 regfile
, regname
, _
= cu
.get_in_spec(idx
)
748 rdflag
, read
= self
.regspecmap_read(regfile
, regname
)
750 print ("rdflags", rdl
)
754 if __name__
== '__main__':
755 pdecode
= create_pdecode()
756 dec2
= PowerDecode2(pdecode
)
757 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
758 with
open("dec2.il", "w") as f
: