615f78f7e10bf2cb9421fdedbd71ef4586324018
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 (InternalOp
, 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(InternalOp
.OP_ATTN
) : comb
+= is_priv_insn
.eq(1)
45 with m
.Case(InternalOp
.OP_MFMSR
) : comb
+= is_priv_insn
.eq(1)
46 with m
.Case(InternalOp
.OP_MTMSRD
): comb
+= is_priv_insn
.eq(1)
47 with m
.Case(InternalOp
.OP_MTMSR
): comb
+= is_priv_insn
.eq(1)
48 with m
.Case(InternalOp
.OP_RFID
) : comb
+= is_priv_insn
.eq(1)
49 with m
.Case(InternalOp
.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
== InternalOp
.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
== InternalOp
.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
== InternalOp
.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
== InternalOp
.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
== InternalOp
.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
== InternalOp
.OP_BC
) |
330 (op
.internal_op
== InternalOp
.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
== InternalOp
.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
== InternalOp
.OP_BC
) |
370 (op
.internal_op
== InternalOp
.OP_B
) |
371 (op
.internal_op
== InternalOp
.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
== InternalOp
.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
== InternalOp
.OP_MUL_H64
) |
437 (op
.internal_op
== InternalOp
.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
):
551 def __init__(self
, dec
):
554 self
.e
= Decode2ToExecute1Type()
555 self
.valid
= Signal() # sync signal
558 return self
.dec
.ports() + self
.e
.ports()
560 def elaborate(self
, platform
):
563 e
, op
, do
= self
.e
, self
.dec
.op
, self
.e
.do
565 # set up submodule decoders
566 m
.submodules
.dec
= self
.dec
567 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
)
568 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
)
569 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
)
570 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
)
571 m
.submodules
.dec_o2
= dec_o2
= DecodeOut2(self
.dec
)
572 m
.submodules
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
573 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
)
574 m
.submodules
.dec_cr_in
= dec_cr_in
= DecodeCRIn(self
.dec
)
575 m
.submodules
.dec_cr_out
= dec_cr_out
= DecodeCROut(self
.dec
)
577 # copy instruction through...
578 for i
in [do
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
579 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
, dec_rc
.insn_in
,
580 dec_oe
.insn_in
, dec_cr_in
.insn_in
, dec_cr_out
.insn_in
]:
581 comb
+= i
.eq(self
.dec
.opcode_in
)
583 # ...and subdecoders' input fields
584 comb
+= dec_a
.sel_in
.eq(op
.in1_sel
)
585 comb
+= dec_b
.sel_in
.eq(op
.in2_sel
)
586 comb
+= dec_c
.sel_in
.eq(op
.in3_sel
)
587 comb
+= dec_o
.sel_in
.eq(op
.out_sel
)
588 comb
+= dec_o2
.sel_in
.eq(op
.out_sel
)
589 comb
+= dec_o2
.lk
.eq(do
.lk
)
590 comb
+= dec_rc
.sel_in
.eq(op
.rc_sel
)
591 comb
+= dec_oe
.sel_in
.eq(op
.rc_sel
) # XXX should be OE sel
592 comb
+= dec_cr_in
.sel_in
.eq(op
.cr_in
)
593 comb
+= dec_cr_out
.sel_in
.eq(op
.cr_out
)
594 comb
+= dec_cr_out
.rc_in
.eq(dec_rc
.rc_out
.data
)
596 # set up instruction, pick fn unit
597 comb
+= e
.nia
.eq(0) # XXX TODO (or remove? not sure yet)
598 comb
+= do
.insn_type
.eq(op
.internal_op
) # no op: defaults to OP_ILLEGAL
599 comb
+= do
.fn_unit
.eq(op
.function_unit
)
601 # registers a, b, c and out and out2 (LD/ST EA)
602 comb
+= e
.read_reg1
.eq(dec_a
.reg_out
)
603 comb
+= e
.read_reg2
.eq(dec_b
.reg_out
)
604 comb
+= e
.read_reg3
.eq(dec_c
.reg_out
)
605 comb
+= e
.write_reg
.eq(dec_o
.reg_out
)
606 comb
+= e
.write_ea
.eq(dec_o2
.reg_out
)
607 comb
+= do
.imm_data
.eq(dec_b
.imm_out
) # immediate in RB (usually)
608 comb
+= do
.zero_a
.eq(dec_a
.immz_out
) # RA==0 detected
611 comb
+= do
.rc
.eq(dec_rc
.rc_out
)
612 comb
+= do
.oe
.eq(dec_oe
.oe_out
)
615 comb
+= e
.read_spr1
.eq(dec_a
.spr_out
)
616 comb
+= e
.write_spr
.eq(dec_o
.spr_out
)
619 comb
+= e
.read_fast1
.eq(dec_a
.fast_out
)
620 comb
+= e
.read_fast2
.eq(dec_b
.fast_out
)
621 comb
+= e
.write_fast1
.eq(dec_o
.fast_out
)
622 comb
+= e
.write_fast2
.eq(dec_o2
.fast_out
)
624 # condition registers (CR)
625 comb
+= e
.read_cr1
.eq(dec_cr_in
.cr_bitfield
)
626 comb
+= e
.read_cr2
.eq(dec_cr_in
.cr_bitfield_b
)
627 comb
+= e
.read_cr3
.eq(dec_cr_in
.cr_bitfield_o
)
628 comb
+= e
.write_cr
.eq(dec_cr_out
.cr_bitfield
)
630 comb
+= do
.read_cr_whole
.eq(dec_cr_in
.whole_reg
)
631 comb
+= do
.write_cr_whole
.eq(dec_cr_out
.whole_reg
)
632 comb
+= do
.write_cr0
.eq(dec_cr_out
.cr_bitfield
.ok
)
634 # decoded/selected instruction flags
635 comb
+= do
.data_len
.eq(op
.ldst_len
)
636 comb
+= do
.invert_a
.eq(op
.inv_a
)
637 comb
+= do
.invert_out
.eq(op
.inv_out
)
638 comb
+= do
.input_carry
.eq(op
.cry_in
) # carry comes in
639 comb
+= do
.output_carry
.eq(op
.cry_out
) # carry goes out
640 comb
+= do
.is_32bit
.eq(op
.is_32b
)
641 comb
+= do
.is_signed
.eq(op
.sgn
)
643 comb
+= do
.lk
.eq(self
.dec
.LK
) # XXX TODO: accessor
645 comb
+= do
.byte_reverse
.eq(op
.br
)
646 comb
+= do
.sign_extend
.eq(op
.sgn_ext
)
647 comb
+= do
.ldst_mode
.eq(op
.upd
) # LD/ST mode (update, cache-inhibit)
649 # These should be removed eventually
650 comb
+= do
.input_cr
.eq(op
.cr_in
) # condition reg comes in
651 comb
+= do
.output_cr
.eq(op
.cr_out
) # condition reg goes in
653 # sigh this is exactly the sort of thing for which the
654 # decoder is designed to not need. MTSPR, MFSPR and others need
655 # access to the XER bits. however setting e.oe is not appropriate
656 with m
.If(op
.internal_op
== InternalOp
.OP_MFSPR
):
657 comb
+= e
.xer_in
.eq(1)
658 with m
.If(op
.internal_op
== InternalOp
.OP_MTSPR
):
659 comb
+= e
.xer_out
.eq(1)
661 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
662 with m
.If(op
.internal_op
== InternalOp
.OP_TRAP
):
663 comb
+= do
.trapaddr
.eq(0x70) # addr=0x700 (strip first nibble)
665 # illegal instruction must redirect to trap. this is done by
666 # *overwriting* the decoded instruction and starting again.
667 # (note: the same goes for interrupts and for privileged operations,
668 # just with different trapaddr and traptype)
669 with m
.If(op
.internal_op
== InternalOp
.OP_ILLEGAL
):
670 # illegal instruction trap
671 self
.trap(m
, TT_ILLEG
, 0x700)
673 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
674 # Note: OP_SC could actually be modified to just be a trap
675 with m
.If((do
.insn_type
== InternalOp
.OP_TRAP
) |
676 (do
.insn_type
== InternalOp
.OP_SC
)):
677 # TRAP write fast1 = SRR0
678 comb
+= e
.write_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
679 comb
+= e
.write_fast1
.ok
.eq(1)
680 # TRAP write fast2 = SRR1
681 comb
+= e
.write_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
682 comb
+= e
.write_fast2
.ok
.eq(1)
684 # RFID: needs to read SRR0/1
685 with m
.If(do
.insn_type
== InternalOp
.OP_RFID
):
686 # TRAP read fast1 = SRR0
687 comb
+= e
.read_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
688 comb
+= e
.read_fast1
.ok
.eq(1)
689 # TRAP read fast2 = SRR1
690 comb
+= e
.read_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
691 comb
+= e
.read_fast2
.ok
.eq(1)
695 # TODO: get msr, then can do privileged instruction
696 with m
.If(instr_is_priv(m
, op
.internal_op
, e
.insn
) & msr
[MSR_PR
]):
697 # privileged instruction trap
698 self
.trap(m
, TT_PRIV
, 0x700)
701 def trap(self
, m
, traptype
, trapaddr
):
702 """trap: this basically "rewrites" the decoded instruction as a trap
705 e
, op
, do
= self
.e
, self
.dec
.op
, self
.e
.do
706 comb
+= e
.eq(0) # reset eeeeeverything
708 comb
+= do
.insn
.eq(self
.dec
.opcode_in
)
709 comb
+= do
.insn_type
.eq(InternalOp
.OP_TRAP
)
710 comb
+= do
.fn_unit
.eq(Function
.TRAP
)
711 comb
+= do
.trapaddr
.eq(trapaddr
>> 4) # cut bottom 4 bits
712 comb
+= do
.traptype
.eq(traptype
) # request type
714 def regspecmap_read(self
, regfile
, regname
):
715 """regspecmap_read: provides PowerDecode2 with an encoding relationship
716 to Function Unit port regfiles (read-enable, read regnum, write regnum)
717 regfile and regname arguments are fields 1 and 2 from a given regspec.
719 return regspec_decode_read(self
.e
, regfile
, regname
)
721 def regspecmap_write(self
, regfile
, regname
):
722 """regspecmap_write: provides PowerDecode2 with an encoding relationship
723 to Function Unit port regfiles (write port, write regnum)
724 regfile and regname arguments are fields 1 and 2 from a given regspec.
726 return regspec_decode_write(self
.e
, regfile
, regname
)
728 def rdflags(self
, cu
):
730 for idx
in range(cu
.n_src
):
731 regfile
, regname
, _
= cu
.get_in_spec(idx
)
732 rdflag
, read
= self
.regspecmap_read(regfile
, regname
)
734 print ("rdflags", rdl
)
738 if __name__
== '__main__':
739 pdecode
= create_pdecode()
740 dec2
= PowerDecode2(pdecode
)
741 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
742 with
open("dec2.il", "w") as f
: