89c87383ce5717d333e4982faadcb57e5f277254
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
,
22 from soc
.decoder
.decode2execute1
import Decode2ToExecute1Type
, Data
24 from soc
.regfile
.regfiles
import FastRegs
26 # see traptype (and trap main_stage.py)
34 def decode_spr_num(spr
):
35 return Cat(spr
[5:10], spr
[0:5])
38 def instr_is_priv(m
, op
, insn
):
39 """determines if the instruction is privileged or not
42 Signal
= is_priv_insn(reset_less
=True)
44 with m
.Case(MicrOp
.OP_ATTN
) : comb
+= is_priv_insn
.eq(1)
45 with m
.Case(MicrOp
.OP_MFMSR
) : comb
+= is_priv_insn
.eq(1)
46 with m
.Case(MicrOp
.OP_MTMSRD
): comb
+= is_priv_insn
.eq(1)
47 with m
.Case(MicrOp
.OP_MTMSR
): comb
+= is_priv_insn
.eq(1)
48 with m
.Case(MicrOp
.OP_RFID
) : comb
+= is_priv_insn
.eq(1)
49 with m
.Case(MicrOp
.OP_TLBIE
) : comb
+= is_priv_insn
.eq(1)
50 with m
.If(op
== OP_MFSPR | op
== OP_MTSPR
):
51 with m
.If(insn
[20]): # field XFX.spr[-1] i think
52 comb
+= is_priv_insn
.eq(1)
56 class SPRMap(Elaboratable
):
57 """SPRMap: maps POWER9 SPR numbers to internal enum values
60 self
.spr_i
= Signal(10, reset_less
=True)
61 self
.spr_o
= Signal(SPR
, reset_less
=True)
63 def elaborate(self
, platform
):
65 with m
.Switch(self
.spr_i
):
66 for i
, x
in enumerate(SPR
):
68 m
.d
.comb
+= self
.spr_o
.eq(i
)
72 class DecodeA(Elaboratable
):
73 """DecodeA from instruction
75 decodes register RA, whether immediate-zero, implicit and
79 def __init__(self
, dec
):
81 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
82 self
.insn_in
= Signal(32, reset_less
=True)
83 self
.reg_out
= Data(5, name
="reg_a")
84 self
.immz_out
= Signal(reset_less
=True)
85 self
.spr_out
= Data(SPR
, "spr_a")
86 self
.fast_out
= Data(3, "fast_a")
88 def elaborate(self
, platform
):
91 m
.submodules
.sprmap
= sprmap
= SPRMap()
93 # select Register A field
94 ra
= Signal(5, reset_less
=True)
95 comb
+= ra
.eq(self
.dec
.RA
)
96 with m
.If((self
.sel_in
== In1Sel
.RA
) |
97 ((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
98 (ra
!= Const(0, 5)))):
99 comb
+= self
.reg_out
.data
.eq(ra
)
100 comb
+= self
.reg_out
.ok
.eq(1)
102 # zero immediate requested
103 with m
.If((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
104 (self
.reg_out
.data
== Const(0, 5))):
105 comb
+= self
.immz_out
.eq(1)
107 # some Logic/ALU ops have RS as the 3rd arg, but no "RA".
108 with m
.If(self
.sel_in
== In1Sel
.RS
):
109 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
110 comb
+= self
.reg_out
.ok
.eq(1)
112 # decode Fast-SPR based on instruction type
114 # BC or BCREG: potential implicit register (CTR) NOTE: same in DecodeOut
115 with m
.If(op
.internal_op
== MicrOp
.OP_BC
):
116 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
117 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
) # constant: CTR
118 comb
+= self
.fast_out
.ok
.eq(1)
119 with m
.Elif(op
.internal_op
== MicrOp
.OP_BCREG
):
120 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
121 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
122 with m
.If(xo9
& ~xo5
):
123 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
) # constant: CTR
124 comb
+= self
.fast_out
.ok
.eq(1)
126 # MFSPR move from SPRs
127 with m
.If(op
.internal_op
== MicrOp
.OP_MFSPR
):
128 spr
= Signal(10, reset_less
=True)
129 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
132 with m
.Case(SPR
.CTR
.value
):
133 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
134 comb
+= self
.fast_out
.ok
.eq(1)
135 with m
.Case(SPR
.LR
.value
):
136 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
137 comb
+= self
.fast_out
.ok
.eq(1)
138 with m
.Case(SPR
.TAR
.value
):
139 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
140 comb
+= self
.fast_out
.ok
.eq(1)
141 with m
.Case(SPR
.SRR0
.value
):
142 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
)
143 comb
+= self
.fast_out
.ok
.eq(1)
144 with m
.Case(SPR
.SRR1
.value
):
145 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
)
146 comb
+= self
.fast_out
.ok
.eq(1)
147 with m
.Case(SPR
.XER
.value
):
149 # XXX TODO: map to internal SPR numbers
150 # XXX TODO: dec and tb not to go through mapping.
152 comb
+= sprmap
.spr_i
.eq(spr
)
153 comb
+= self
.spr_out
.data
.eq(sprmap
.spr_o
)
154 comb
+= self
.spr_out
.ok
.eq(1)
160 class DecodeB(Elaboratable
):
161 """DecodeB from instruction
163 decodes register RB, different forms of immediate (signed, unsigned),
164 and implicit SPRs. register B is basically "lane 2" into the CompUnits.
165 by industry-standard convention, "lane 2" is where fully-decoded
166 immediates are muxed in.
169 def __init__(self
, dec
):
171 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
172 self
.insn_in
= Signal(32, reset_less
=True)
173 self
.reg_out
= Data(5, "reg_b")
174 self
.imm_out
= Data(64, "imm_b")
175 self
.fast_out
= Data(3, "fast_b")
177 def elaborate(self
, platform
):
181 # select Register B field
182 with m
.Switch(self
.sel_in
):
183 with m
.Case(In2Sel
.RB
):
184 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
)
185 comb
+= self
.reg_out
.ok
.eq(1)
186 with m
.Case(In2Sel
.RS
):
187 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
) # for M-Form shiftrot
188 comb
+= self
.reg_out
.ok
.eq(1)
189 with m
.Case(In2Sel
.CONST_UI
):
190 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
)
191 comb
+= self
.imm_out
.ok
.eq(1)
192 with m
.Case(In2Sel
.CONST_SI
): # TODO: sign-extend here?
193 comb
+= self
.imm_out
.data
.eq(
194 exts(self
.dec
.SI
, 16, 64))
195 comb
+= self
.imm_out
.ok
.eq(1)
196 with m
.Case(In2Sel
.CONST_UI_HI
):
197 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
<<16)
198 comb
+= self
.imm_out
.ok
.eq(1)
199 with m
.Case(In2Sel
.CONST_SI_HI
): # TODO: sign-extend here?
200 comb
+= self
.imm_out
.data
.eq(self
.dec
.SI
<<16)
201 comb
+= self
.imm_out
.data
.eq(
202 exts(self
.dec
.SI
<< 16, 32, 64))
203 comb
+= self
.imm_out
.ok
.eq(1)
204 with m
.Case(In2Sel
.CONST_LI
):
205 comb
+= self
.imm_out
.data
.eq(self
.dec
.LI
<<2)
206 comb
+= self
.imm_out
.ok
.eq(1)
207 with m
.Case(In2Sel
.CONST_BD
):
208 comb
+= self
.imm_out
.data
.eq(self
.dec
.BD
<<2)
209 comb
+= self
.imm_out
.ok
.eq(1)
210 with m
.Case(In2Sel
.CONST_DS
):
211 comb
+= self
.imm_out
.data
.eq(self
.dec
.DS
<<2)
212 comb
+= self
.imm_out
.ok
.eq(1)
213 with m
.Case(In2Sel
.CONST_M1
):
214 comb
+= self
.imm_out
.data
.eq(~
Const(0, 64)) # all 1s
215 comb
+= self
.imm_out
.ok
.eq(1)
216 with m
.Case(In2Sel
.CONST_SH
):
217 comb
+= self
.imm_out
.data
.eq(self
.dec
.sh
)
218 comb
+= self
.imm_out
.ok
.eq(1)
219 with m
.Case(In2Sel
.CONST_SH32
):
220 comb
+= self
.imm_out
.data
.eq(self
.dec
.SH32
)
221 comb
+= self
.imm_out
.ok
.eq(1)
223 # decode SPR2 based on instruction type
225 # BCREG implicitly uses LR or TAR for 2nd reg
226 # CTR however is already in fast_spr1 *not* 2.
227 with m
.If(op
.internal_op
== MicrOp
.OP_BCREG
):
228 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
229 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
231 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
232 comb
+= self
.fast_out
.ok
.eq(1)
234 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
235 comb
+= self
.fast_out
.ok
.eq(1)
240 class DecodeC(Elaboratable
):
241 """DecodeC from instruction
243 decodes register RC. this is "lane 3" into some CompUnits (not many)
246 def __init__(self
, dec
):
248 self
.sel_in
= Signal(In3Sel
, reset_less
=True)
249 self
.insn_in
= Signal(32, reset_less
=True)
250 self
.reg_out
= Data(5, "reg_c")
252 def elaborate(self
, platform
):
256 # select Register C field
257 with m
.Switch(self
.sel_in
):
258 with m
.Case(In3Sel
.RB
):
259 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
) # for M-Form shiftrot
260 comb
+= self
.reg_out
.ok
.eq(1)
261 with m
.Case(In3Sel
.RS
):
262 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
263 comb
+= self
.reg_out
.ok
.eq(1)
268 class DecodeOut(Elaboratable
):
269 """DecodeOut from instruction
271 decodes output register RA, RT or SPR
274 def __init__(self
, dec
):
276 self
.sel_in
= Signal(OutSel
, reset_less
=True)
277 self
.insn_in
= Signal(32, reset_less
=True)
278 self
.reg_out
= Data(5, "reg_o")
279 self
.spr_out
= Data(SPR
, "spr_o")
280 self
.fast_out
= Data(3, "fast_o")
282 def elaborate(self
, platform
):
285 m
.submodules
.sprmap
= sprmap
= SPRMap()
288 # select Register out field
289 with m
.Switch(self
.sel_in
):
290 with m
.Case(OutSel
.RT
):
291 comb
+= self
.reg_out
.data
.eq(self
.dec
.RT
)
292 comb
+= self
.reg_out
.ok
.eq(1)
293 with m
.Case(OutSel
.RA
):
294 comb
+= self
.reg_out
.data
.eq(self
.dec
.RA
)
295 comb
+= self
.reg_out
.ok
.eq(1)
296 with m
.Case(OutSel
.SPR
):
297 spr
= Signal(10, reset_less
=True)
298 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
299 # TODO MTSPR 1st spr (fast)
300 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
303 with m
.Case(SPR
.CTR
.value
):
304 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
305 comb
+= self
.fast_out
.ok
.eq(1)
306 with m
.Case(SPR
.LR
.value
):
307 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
308 comb
+= self
.fast_out
.ok
.eq(1)
309 with m
.Case(SPR
.TAR
.value
):
310 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
311 comb
+= self
.fast_out
.ok
.eq(1)
312 with m
.Case(SPR
.SRR0
.value
):
313 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
)
314 comb
+= self
.fast_out
.ok
.eq(1)
315 with m
.Case(SPR
.SRR1
.value
):
316 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
)
317 comb
+= self
.fast_out
.ok
.eq(1)
318 with m
.Case(SPR
.XER
.value
):
320 # XXX TODO: map to internal SPR numbers
321 # XXX TODO: dec and tb not to go through mapping.
323 comb
+= sprmap
.spr_i
.eq(spr
)
324 comb
+= self
.spr_out
.data
.eq(sprmap
.spr_o
)
325 comb
+= self
.spr_out
.ok
.eq(1)
327 # BC or BCREG: potential implicit register (CTR) NOTE: same in DecodeA
329 with m
.If((op
.internal_op
== MicrOp
.OP_BC
) |
330 (op
.internal_op
== MicrOp
.OP_BCREG
)):
331 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
332 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
) # constant: CTR
333 comb
+= self
.fast_out
.ok
.eq(1)
335 # RFID 1st spr (fast)
336 with m
.If(op
.internal_op
== MicrOp
.OP_RFID
):
337 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
338 comb
+= self
.fast_out
.ok
.eq(1)
343 class DecodeOut2(Elaboratable
):
344 """DecodeOut2 from instruction
346 decodes output registers
349 def __init__(self
, dec
):
351 self
.sel_in
= Signal(OutSel
, reset_less
=True)
352 self
.lk
= Signal(reset_less
=True)
353 self
.insn_in
= Signal(32, reset_less
=True)
354 self
.reg_out
= Data(5, "reg_o")
355 self
.fast_out
= Data(3, "fast_o")
357 def elaborate(self
, platform
):
361 # update mode LD/ST uses read-reg A also as an output
362 with m
.If(self
.dec
.op
.upd
):
363 comb
+= self
.reg_out
.eq(self
.dec
.RA
)
364 comb
+= self
.reg_out
.ok
.eq(1)
366 # B, BC or BCREG: potential implicit register (LR) output
367 # these give bl, bcl, bclrl, etc.
369 with m
.If((op
.internal_op
== MicrOp
.OP_BC
) |
370 (op
.internal_op
== MicrOp
.OP_B
) |
371 (op
.internal_op
== MicrOp
.OP_BCREG
)):
372 with m
.If(self
.lk
): # "link" mode
373 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
) # constant: LR
374 comb
+= self
.fast_out
.ok
.eq(1)
376 # RFID 2nd spr (fast)
377 with m
.If(op
.internal_op
== MicrOp
.OP_RFID
):
378 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
379 comb
+= self
.fast_out
.ok
.eq(1)
384 class DecodeRC(Elaboratable
):
385 """DecodeRc from instruction
387 decodes Record bit Rc
389 def __init__(self
, dec
):
391 self
.sel_in
= Signal(RC
, reset_less
=True)
392 self
.insn_in
= Signal(32, reset_less
=True)
393 self
.rc_out
= Data(1, "rc")
395 def elaborate(self
, platform
):
399 # select Record bit out field
400 with m
.Switch(self
.sel_in
):
402 comb
+= self
.rc_out
.data
.eq(self
.dec
.Rc
)
403 comb
+= self
.rc_out
.ok
.eq(1)
405 comb
+= self
.rc_out
.data
.eq(1)
406 comb
+= self
.rc_out
.ok
.eq(1)
407 with m
.Case(RC
.NONE
):
408 comb
+= self
.rc_out
.data
.eq(0)
409 comb
+= self
.rc_out
.ok
.eq(1)
414 class DecodeOE(Elaboratable
):
415 """DecodeOE from instruction
417 decodes OE field: uses RC decode detection which might not be good
419 -- For now, use "rc" in the decode table to decide whether oe exists.
420 -- This is not entirely correct architecturally: For mulhd and
421 -- mulhdu, the OE field is reserved. It remains to be seen what an
422 -- actual POWER9 does if we set it on those instructions, for now we
423 -- test that further down when assigning to the multiplier oe input.
425 def __init__(self
, dec
):
427 self
.sel_in
= Signal(RC
, reset_less
=True)
428 self
.insn_in
= Signal(32, reset_less
=True)
429 self
.oe_out
= Data(1, "oe")
431 def elaborate(self
, platform
):
436 with m
.If((op
.internal_op
== MicrOp
.OP_MUL_H64
) |
437 (op
.internal_op
== MicrOp
.OP_MUL_H32
)):
438 # mulhw, mulhwu, mulhd, mulhdu - these *ignore* OE
441 # select OE bit out field
442 with m
.Switch(self
.sel_in
):
444 comb
+= self
.oe_out
.data
.eq(self
.dec
.OE
)
445 comb
+= self
.oe_out
.ok
.eq(1)
449 class DecodeCRIn(Elaboratable
):
450 """Decodes input CR from instruction
452 CR indices - insn fields - (not the data *in* the CR) require only 3
453 bits because they refer to CR0-CR7
456 def __init__(self
, dec
):
458 self
.sel_in
= Signal(CRInSel
, reset_less
=True)
459 self
.insn_in
= Signal(32, reset_less
=True)
460 self
.cr_bitfield
= Data(3, "cr_bitfield")
461 self
.cr_bitfield_b
= Data(3, "cr_bitfield_b")
462 self
.cr_bitfield_o
= Data(3, "cr_bitfield_o")
463 self
.whole_reg
= Signal(reset_less
=True)
465 def elaborate(self
, platform
):
469 comb
+= self
.cr_bitfield
.ok
.eq(0)
470 comb
+= self
.cr_bitfield_b
.ok
.eq(0)
471 comb
+= self
.whole_reg
.eq(0)
472 with m
.Switch(self
.sel_in
):
473 with m
.Case(CRInSel
.NONE
):
474 pass # No bitfield activated
475 with m
.Case(CRInSel
.CR0
):
476 comb
+= self
.cr_bitfield
.data
.eq(0)
477 comb
+= self
.cr_bitfield
.ok
.eq(1)
478 with m
.Case(CRInSel
.BI
):
479 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BI
[2:5])
480 comb
+= self
.cr_bitfield
.ok
.eq(1)
481 with m
.Case(CRInSel
.BFA
):
482 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BFA
)
483 comb
+= self
.cr_bitfield
.ok
.eq(1)
484 with m
.Case(CRInSel
.BA_BB
):
485 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BA
[2:5])
486 comb
+= self
.cr_bitfield
.ok
.eq(1)
487 comb
+= self
.cr_bitfield_b
.data
.eq(self
.dec
.BB
[2:5])
488 comb
+= self
.cr_bitfield_b
.ok
.eq(1)
489 comb
+= self
.cr_bitfield_o
.data
.eq(self
.dec
.BT
[2:5])
490 comb
+= self
.cr_bitfield_o
.ok
.eq(1)
491 with m
.Case(CRInSel
.BC
):
492 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BC
[2:5])
493 comb
+= self
.cr_bitfield
.ok
.eq(1)
494 with m
.Case(CRInSel
.WHOLE_REG
):
495 comb
+= self
.whole_reg
.eq(1)
500 class DecodeCROut(Elaboratable
):
501 """Decodes input CR from instruction
503 CR indices - insn fields - (not the data *in* the CR) require only 3
504 bits because they refer to CR0-CR7
507 def __init__(self
, dec
):
509 self
.rc_in
= Signal(reset_less
=True)
510 self
.sel_in
= Signal(CROutSel
, reset_less
=True)
511 self
.insn_in
= Signal(32, reset_less
=True)
512 self
.cr_bitfield
= Data(3, "cr_bitfield")
513 self
.whole_reg
= Signal(reset_less
=True)
515 def elaborate(self
, platform
):
519 comb
+= self
.cr_bitfield
.ok
.eq(0)
520 comb
+= self
.whole_reg
.eq(0)
521 with m
.Switch(self
.sel_in
):
522 with m
.Case(CROutSel
.NONE
):
523 pass # No bitfield activated
524 with m
.Case(CROutSel
.CR0
):
525 comb
+= self
.cr_bitfield
.data
.eq(0)
526 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
527 with m
.Case(CROutSel
.BF
):
528 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BF
)
529 comb
+= self
.cr_bitfield
.ok
.eq(1)
530 with m
.Case(CROutSel
.BT
):
531 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormXL
.BT
[2:5])
532 comb
+= self
.cr_bitfield
.ok
.eq(1)
533 with m
.Case(CROutSel
.WHOLE_REG
):
534 comb
+= self
.whole_reg
.eq(1)
541 self
.ca
= Signal(2, reset_less
=True)
542 self
.ov
= Signal(2, reset_less
=True)
543 self
.so
= Signal(reset_less
=True)
546 return [self
.ca
, self
.ov
, self
.so
]
549 class PowerDecode2(Elaboratable
):
550 """PowerDecode2: the main instruction decoder.
552 whilst PowerDecode is responsible for decoding the actual opcode, this
553 module encapsulates further specialist, sparse information and
554 expansion of fields that is inconvenient to have in the CSV files.
555 for example: the encoding of the immediates, which are detected
556 and expanded out to their full value from an annotated (enum)
559 implicit register usage is also set up, here. for example: OP_BC
560 requires implicitly reading CTR, OP_RFID requires implicitly writing
563 in addition, PowerDecoder2 is responsible for detecting whether
564 instructions are illegal (or privileged) or not, and instead of
565 just leaving at that, *replacing* the instruction to execute with
566 a suitable alternative (trap).
569 def __init__(self
, dec
):
572 self
.e
= Decode2ToExecute1Type()
573 self
.valid
= Signal() # sync signal
575 # state information needed by the Decoder
576 self
.msr
= Signal(64, reset_less
=True) # copy of MSR
579 return self
.dec
.ports() + self
.e
.ports()
581 def elaborate(self
, platform
):
584 e
, op
, do
, msr
= self
.e
, self
.dec
.op
, self
.e
.do
, self
.msr
586 # set up submodule decoders
587 m
.submodules
.dec
= self
.dec
588 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
)
589 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
)
590 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
)
591 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
)
592 m
.submodules
.dec_o2
= dec_o2
= DecodeOut2(self
.dec
)
593 m
.submodules
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
594 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
)
595 m
.submodules
.dec_cr_in
= dec_cr_in
= DecodeCRIn(self
.dec
)
596 m
.submodules
.dec_cr_out
= dec_cr_out
= DecodeCROut(self
.dec
)
598 # copy instruction through...
599 for i
in [do
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
600 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
, dec_rc
.insn_in
,
601 dec_oe
.insn_in
, dec_cr_in
.insn_in
, dec_cr_out
.insn_in
]:
602 comb
+= i
.eq(self
.dec
.opcode_in
)
604 # ...and subdecoders' input fields
605 comb
+= dec_a
.sel_in
.eq(op
.in1_sel
)
606 comb
+= dec_b
.sel_in
.eq(op
.in2_sel
)
607 comb
+= dec_c
.sel_in
.eq(op
.in3_sel
)
608 comb
+= dec_o
.sel_in
.eq(op
.out_sel
)
609 comb
+= dec_o2
.sel_in
.eq(op
.out_sel
)
610 comb
+= dec_o2
.lk
.eq(do
.lk
)
611 comb
+= dec_rc
.sel_in
.eq(op
.rc_sel
)
612 comb
+= dec_oe
.sel_in
.eq(op
.rc_sel
) # XXX should be OE sel
613 comb
+= dec_cr_in
.sel_in
.eq(op
.cr_in
)
614 comb
+= dec_cr_out
.sel_in
.eq(op
.cr_out
)
615 comb
+= dec_cr_out
.rc_in
.eq(dec_rc
.rc_out
.data
)
617 # set up instruction, pick fn unit
618 comb
+= do
.insn_type
.eq(op
.internal_op
) # no op: defaults to OP_ILLEGAL
619 comb
+= do
.fn_unit
.eq(op
.function_unit
)
621 # registers a, b, c and out and out2 (LD/ST EA)
622 comb
+= e
.read_reg1
.eq(dec_a
.reg_out
)
623 comb
+= e
.read_reg2
.eq(dec_b
.reg_out
)
624 comb
+= e
.read_reg3
.eq(dec_c
.reg_out
)
625 comb
+= e
.write_reg
.eq(dec_o
.reg_out
)
626 comb
+= e
.write_ea
.eq(dec_o2
.reg_out
)
627 comb
+= do
.imm_data
.eq(dec_b
.imm_out
) # immediate in RB (usually)
628 comb
+= do
.zero_a
.eq(dec_a
.immz_out
) # RA==0 detected
631 comb
+= do
.rc
.eq(dec_rc
.rc_out
)
632 comb
+= do
.oe
.eq(dec_oe
.oe_out
)
635 comb
+= e
.read_spr1
.eq(dec_a
.spr_out
)
636 comb
+= e
.write_spr
.eq(dec_o
.spr_out
)
639 comb
+= e
.read_fast1
.eq(dec_a
.fast_out
)
640 comb
+= e
.read_fast2
.eq(dec_b
.fast_out
)
641 comb
+= e
.write_fast1
.eq(dec_o
.fast_out
)
642 comb
+= e
.write_fast2
.eq(dec_o2
.fast_out
)
644 # condition registers (CR)
645 comb
+= e
.read_cr1
.eq(dec_cr_in
.cr_bitfield
)
646 comb
+= e
.read_cr2
.eq(dec_cr_in
.cr_bitfield_b
)
647 comb
+= e
.read_cr3
.eq(dec_cr_in
.cr_bitfield_o
)
648 comb
+= e
.write_cr
.eq(dec_cr_out
.cr_bitfield
)
650 comb
+= do
.read_cr_whole
.eq(dec_cr_in
.whole_reg
)
651 comb
+= do
.write_cr_whole
.eq(dec_cr_out
.whole_reg
)
652 comb
+= do
.write_cr0
.eq(dec_cr_out
.cr_bitfield
.ok
)
654 # decoded/selected instruction flags
655 comb
+= do
.data_len
.eq(op
.ldst_len
)
656 comb
+= do
.invert_a
.eq(op
.inv_a
)
657 comb
+= do
.invert_out
.eq(op
.inv_out
)
658 comb
+= do
.input_carry
.eq(op
.cry_in
) # carry comes in
659 comb
+= do
.output_carry
.eq(op
.cry_out
) # carry goes out
660 comb
+= do
.is_32bit
.eq(op
.is_32b
)
661 comb
+= do
.is_signed
.eq(op
.sgn
)
663 comb
+= do
.lk
.eq(self
.dec
.LK
) # XXX TODO: accessor
665 comb
+= do
.byte_reverse
.eq(op
.br
)
666 comb
+= do
.sign_extend
.eq(op
.sgn_ext
)
667 comb
+= do
.ldst_mode
.eq(op
.upd
) # LD/ST mode (update, cache-inhibit)
669 # These should be removed eventually
670 comb
+= do
.input_cr
.eq(op
.cr_in
) # condition reg comes in
671 comb
+= do
.output_cr
.eq(op
.cr_out
) # condition reg goes in
673 # sigh this is exactly the sort of thing for which the
674 # decoder is designed to not need. MTSPR, MFSPR and others need
675 # access to the XER bits. however setting e.oe is not appropriate
676 with m
.If(op
.internal_op
== MicrOp
.OP_MFSPR
):
677 comb
+= e
.xer_in
.eq(1)
678 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
679 comb
+= e
.xer_out
.eq(1)
681 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
682 with m
.If(op
.internal_op
== MicrOp
.OP_TRAP
):
683 comb
+= do
.trapaddr
.eq(0x70) # addr=0x700 (strip first nibble)
685 # illegal instruction must redirect to trap. this is done by
686 # *overwriting* the decoded instruction and starting again.
687 # (note: the same goes for interrupts and for privileged operations,
688 # just with different trapaddr and traptype)
689 with m
.If(op
.internal_op
== MicrOp
.OP_ILLEGAL
):
690 # illegal instruction trap
691 self
.trap(m
, TT_ILLEG
, 0x700)
693 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
694 # Note: OP_SC could actually be modified to just be a trap
695 with m
.If((do
.insn_type
== MicrOp
.OP_TRAP
) |
696 (do
.insn_type
== MicrOp
.OP_SC
)):
697 # TRAP write fast1 = SRR0
698 comb
+= e
.write_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
699 comb
+= e
.write_fast1
.ok
.eq(1)
700 # TRAP write fast2 = SRR1
701 comb
+= e
.write_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
702 comb
+= e
.write_fast2
.ok
.eq(1)
704 # RFID: needs to read SRR0/1
705 with m
.If(do
.insn_type
== MicrOp
.OP_RFID
):
706 # TRAP read fast1 = SRR0
707 comb
+= e
.read_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
708 comb
+= e
.read_fast1
.ok
.eq(1)
709 # TRAP read fast2 = SRR1
710 comb
+= e
.read_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
711 comb
+= e
.read_fast2
.ok
.eq(1)
715 # TODO: get msr, then can do privileged instruction
716 with m
.If(instr_is_priv(m
, op
.internal_op
, e
.insn
) & msr
[MSR_PR
]):
717 # privileged instruction trap
718 self
.trap(m
, TT_PRIV
, 0x700)
721 def trap(self
, m
, traptype
, trapaddr
):
722 """trap: this basically "rewrites" the decoded instruction as a trap
725 e
, op
, do
= self
.e
, self
.dec
.op
, self
.e
.do
726 comb
+= e
.eq(0) # reset eeeeeverything
728 comb
+= do
.insn
.eq(self
.dec
.opcode_in
)
729 comb
+= do
.insn_type
.eq(MicrOp
.OP_TRAP
)
730 comb
+= do
.fn_unit
.eq(Function
.TRAP
)
731 comb
+= do
.trapaddr
.eq(trapaddr
>> 4) # cut bottom 4 bits
732 comb
+= do
.traptype
.eq(traptype
) # request type
734 def regspecmap_read(self
, regfile
, regname
):
735 """regspecmap_read: provides PowerDecode2 with an encoding relationship
736 to Function Unit port regfiles (read-enable, read regnum, write regnum)
737 regfile and regname arguments are fields 1 and 2 from a given regspec.
739 return regspec_decode_read(self
.e
, regfile
, regname
)
741 def regspecmap_write(self
, regfile
, regname
):
742 """regspecmap_write: provides PowerDecode2 with an encoding relationship
743 to Function Unit port regfiles (write port, write regnum)
744 regfile and regname arguments are fields 1 and 2 from a given regspec.
746 return regspec_decode_write(self
.e
, regfile
, regname
)
748 def rdflags(self
, cu
):
750 for idx
in range(cu
.n_src
):
751 regfile
, regname
, _
= cu
.get_in_spec(idx
)
752 rdflag
, read
= self
.regspecmap_read(regfile
, regname
)
754 print ("rdflags", rdl
)
758 if __name__
== '__main__':
759 pdecode
= create_pdecode()
760 dec2
= PowerDecode2(pdecode
)
761 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
762 with
open("dec2.il", "w") as f
: