1c2f504cc6c77c166c5d3e2ff6d1917aa9344c9e
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_RFID
) : comb
+= is_priv_insn
.eq(1)
48 with m
.Case(InternalOp
.OP_TLBIE
) : comb
+= is_priv_insn
.eq(1)
49 with m
.If(op
== OP_MFSPR | op
== OP_MTSPR
):
50 with m
.If(insn
[20]): # field XFX.spr[-1] i think
51 comb
+= is_priv_insn
.eq(1)
55 class SPRMap(Elaboratable
):
56 """SPRMap: maps POWER9 SPR numbers to internal enum values
59 self
.spr_i
= Signal(10, reset_less
=True)
60 self
.spr_o
= Signal(SPR
, reset_less
=True)
62 def elaborate(self
, platform
):
64 with m
.Switch(self
.spr_i
):
65 for i
, x
in enumerate(SPR
):
67 m
.d
.comb
+= self
.spr_o
.eq(i
)
71 class DecodeA(Elaboratable
):
72 """DecodeA from instruction
74 decodes register RA, whether immediate-zero, implicit and
78 def __init__(self
, dec
):
80 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
81 self
.insn_in
= Signal(32, reset_less
=True)
82 self
.reg_out
= Data(5, name
="reg_a")
83 self
.immz_out
= Signal(reset_less
=True)
84 self
.spr_out
= Data(SPR
, "spr_a")
85 self
.fast_out
= Data(3, "fast_a")
87 def elaborate(self
, platform
):
90 m
.submodules
.sprmap
= sprmap
= SPRMap()
92 # select Register A field
93 ra
= Signal(5, reset_less
=True)
94 comb
+= ra
.eq(self
.dec
.RA
)
95 with m
.If((self
.sel_in
== In1Sel
.RA
) |
96 ((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
97 (ra
!= Const(0, 5)))):
98 comb
+= self
.reg_out
.data
.eq(ra
)
99 comb
+= self
.reg_out
.ok
.eq(1)
101 # zero immediate requested
102 with m
.If((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
103 (self
.reg_out
.data
== Const(0, 5))):
104 comb
+= self
.immz_out
.eq(1)
106 # some Logic/ALU ops have RS as the 3rd arg, but no "RA".
107 with m
.If(self
.sel_in
== In1Sel
.RS
):
108 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
109 comb
+= self
.reg_out
.ok
.eq(1)
111 # decode Fast-SPR based on instruction type
113 # BC or BCREG: potential implicit register (CTR) NOTE: same in DecodeOut
114 with m
.If(op
.internal_op
== InternalOp
.OP_BC
):
115 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
116 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
) # constant: CTR
117 comb
+= self
.fast_out
.ok
.eq(1)
118 with m
.Elif(op
.internal_op
== InternalOp
.OP_BCREG
):
119 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
120 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
121 with m
.If(xo9
& ~xo5
):
122 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
) # constant: CTR
123 comb
+= self
.fast_out
.ok
.eq(1)
125 # MFSPR move from SPRs
126 with m
.If(op
.internal_op
== InternalOp
.OP_MFSPR
):
127 spr
= Signal(10, reset_less
=True)
128 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
131 with m
.Case(SPR
.CTR
.value
):
132 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
133 comb
+= self
.fast_out
.ok
.eq(1)
134 with m
.Case(SPR
.LR
.value
):
135 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
136 comb
+= self
.fast_out
.ok
.eq(1)
137 with m
.Case(SPR
.TAR
.value
):
138 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
139 comb
+= self
.fast_out
.ok
.eq(1)
140 with m
.Case(SPR
.SRR0
.value
):
141 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
)
142 comb
+= self
.fast_out
.ok
.eq(1)
143 with m
.Case(SPR
.SRR1
.value
):
144 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
)
145 comb
+= self
.fast_out
.ok
.eq(1)
146 with m
.Case(SPR
.XER
.value
):
148 # XXX TODO: map to internal SPR numbers
149 # XXX TODO: dec and tb not to go through mapping.
151 comb
+= sprmap
.spr_i
.eq(spr
)
152 comb
+= self
.spr_out
.data
.eq(sprmap
.spr_o
)
153 comb
+= self
.spr_out
.ok
.eq(1)
159 class DecodeB(Elaboratable
):
160 """DecodeB from instruction
162 decodes register RB, different forms of immediate (signed, unsigned),
163 and implicit SPRs. register B is basically "lane 2" into the CompUnits.
164 by industry-standard convention, "lane 2" is where fully-decoded
165 immediates are muxed in.
168 def __init__(self
, dec
):
170 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
171 self
.insn_in
= Signal(32, reset_less
=True)
172 self
.reg_out
= Data(5, "reg_b")
173 self
.imm_out
= Data(64, "imm_b")
174 self
.fast_out
= Data(3, "fast_b")
176 def elaborate(self
, platform
):
180 # select Register B field
181 with m
.Switch(self
.sel_in
):
182 with m
.Case(In2Sel
.RB
):
183 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
)
184 comb
+= self
.reg_out
.ok
.eq(1)
185 with m
.Case(In2Sel
.RS
):
186 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
) # for M-Form shiftrot
187 comb
+= self
.reg_out
.ok
.eq(1)
188 with m
.Case(In2Sel
.CONST_UI
):
189 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
)
190 comb
+= self
.imm_out
.ok
.eq(1)
191 with m
.Case(In2Sel
.CONST_SI
): # TODO: sign-extend here?
192 comb
+= self
.imm_out
.data
.eq(
193 exts(self
.dec
.SI
, 16, 64))
194 comb
+= self
.imm_out
.ok
.eq(1)
195 with m
.Case(In2Sel
.CONST_UI_HI
):
196 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
<<16)
197 comb
+= self
.imm_out
.ok
.eq(1)
198 with m
.Case(In2Sel
.CONST_SI_HI
): # TODO: sign-extend here?
199 comb
+= self
.imm_out
.data
.eq(self
.dec
.SI
<<16)
200 comb
+= self
.imm_out
.data
.eq(
201 exts(self
.dec
.SI
<< 16, 32, 64))
202 comb
+= self
.imm_out
.ok
.eq(1)
203 with m
.Case(In2Sel
.CONST_LI
):
204 comb
+= self
.imm_out
.data
.eq(self
.dec
.LI
<<2)
205 comb
+= self
.imm_out
.ok
.eq(1)
206 with m
.Case(In2Sel
.CONST_BD
):
207 comb
+= self
.imm_out
.data
.eq(self
.dec
.BD
<<2)
208 comb
+= self
.imm_out
.ok
.eq(1)
209 with m
.Case(In2Sel
.CONST_DS
):
210 comb
+= self
.imm_out
.data
.eq(self
.dec
.DS
<<2)
211 comb
+= self
.imm_out
.ok
.eq(1)
212 with m
.Case(In2Sel
.CONST_M1
):
213 comb
+= self
.imm_out
.data
.eq(~
Const(0, 64)) # all 1s
214 comb
+= self
.imm_out
.ok
.eq(1)
215 with m
.Case(In2Sel
.CONST_SH
):
216 comb
+= self
.imm_out
.data
.eq(self
.dec
.sh
)
217 comb
+= self
.imm_out
.ok
.eq(1)
218 with m
.Case(In2Sel
.CONST_SH32
):
219 comb
+= self
.imm_out
.data
.eq(self
.dec
.SH32
)
220 comb
+= self
.imm_out
.ok
.eq(1)
222 # decode SPR2 based on instruction type
224 # BCREG implicitly uses LR or TAR for 2nd reg
225 # CTR however is already in fast_spr1 *not* 2.
226 with m
.If(op
.internal_op
== InternalOp
.OP_BCREG
):
227 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
228 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
230 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
231 comb
+= self
.fast_out
.ok
.eq(1)
233 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
234 comb
+= self
.fast_out
.ok
.eq(1)
239 class DecodeC(Elaboratable
):
240 """DecodeC from instruction
242 decodes register RC. this is "lane 3" into some CompUnits (not many)
245 def __init__(self
, dec
):
247 self
.sel_in
= Signal(In3Sel
, reset_less
=True)
248 self
.insn_in
= Signal(32, reset_less
=True)
249 self
.reg_out
= Data(5, "reg_c")
251 def elaborate(self
, platform
):
255 # select Register C field
256 with m
.Switch(self
.sel_in
):
257 with m
.Case(In3Sel
.RB
):
258 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
) # for M-Form shiftrot
259 comb
+= self
.reg_out
.ok
.eq(1)
260 with m
.Case(In3Sel
.RS
):
261 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
262 comb
+= self
.reg_out
.ok
.eq(1)
267 class DecodeOut(Elaboratable
):
268 """DecodeOut from instruction
270 decodes output register RA, RT or SPR
273 def __init__(self
, dec
):
275 self
.sel_in
= Signal(OutSel
, reset_less
=True)
276 self
.insn_in
= Signal(32, reset_less
=True)
277 self
.reg_out
= Data(5, "reg_o")
278 self
.spr_out
= Data(SPR
, "spr_o")
279 self
.fast_out
= Data(3, "fast_o")
281 def elaborate(self
, platform
):
284 m
.submodules
.sprmap
= sprmap
= SPRMap()
287 # select Register out field
288 with m
.Switch(self
.sel_in
):
289 with m
.Case(OutSel
.RT
):
290 comb
+= self
.reg_out
.data
.eq(self
.dec
.RT
)
291 comb
+= self
.reg_out
.ok
.eq(1)
292 with m
.Case(OutSel
.RA
):
293 comb
+= self
.reg_out
.data
.eq(self
.dec
.RA
)
294 comb
+= self
.reg_out
.ok
.eq(1)
295 with m
.Case(OutSel
.SPR
):
296 spr
= Signal(10, reset_less
=True)
297 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
298 # TODO MTSPR 1st spr (fast)
299 with m
.If(op
.internal_op
== InternalOp
.OP_MTSPR
):
302 with m
.Case(SPR
.CTR
.value
):
303 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
304 comb
+= self
.fast_out
.ok
.eq(1)
305 with m
.Case(SPR
.LR
.value
):
306 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
307 comb
+= self
.fast_out
.ok
.eq(1)
308 with m
.Case(SPR
.TAR
.value
):
309 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
310 comb
+= self
.fast_out
.ok
.eq(1)
311 with m
.Case(SPR
.SRR0
.value
):
312 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
)
313 comb
+= self
.fast_out
.ok
.eq(1)
314 with m
.Case(SPR
.SRR1
.value
):
315 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
)
316 comb
+= self
.fast_out
.ok
.eq(1)
317 with m
.Case(SPR
.XER
.value
):
319 # XXX TODO: map to internal SPR numbers
320 # XXX TODO: dec and tb not to go through mapping.
322 comb
+= sprmap
.spr_i
.eq(spr
)
323 comb
+= self
.spr_out
.data
.eq(sprmap
.spr_o
)
324 comb
+= self
.spr_out
.ok
.eq(1)
326 # BC or BCREG: potential implicit register (CTR) NOTE: same in DecodeA
328 with m
.If((op
.internal_op
== InternalOp
.OP_BC
) |
329 (op
.internal_op
== InternalOp
.OP_BCREG
)):
330 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
331 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
) # constant: CTR
332 comb
+= self
.fast_out
.ok
.eq(1)
334 # RFID 1st spr (fast)
335 with m
.If(op
.internal_op
== InternalOp
.OP_RFID
):
336 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
337 comb
+= self
.fast_out
.ok
.eq(1)
342 class DecodeOut2(Elaboratable
):
343 """DecodeOut2 from instruction
345 decodes output registers
348 def __init__(self
, dec
):
350 self
.sel_in
= Signal(OutSel
, reset_less
=True)
351 self
.lk
= Signal(reset_less
=True)
352 self
.insn_in
= Signal(32, reset_less
=True)
353 self
.reg_out
= Data(5, "reg_o")
354 self
.fast_out
= Data(3, "fast_o")
356 def elaborate(self
, platform
):
360 # update mode LD/ST uses read-reg A also as an output
361 with m
.If(self
.dec
.op
.upd
):
362 comb
+= self
.reg_out
.eq(self
.dec
.RA
)
363 comb
+= self
.reg_out
.ok
.eq(1)
365 # BC or BCREG: potential implicit register (LR) output
367 with m
.If((op
.internal_op
== InternalOp
.OP_BC
) |
368 (op
.internal_op
== InternalOp
.OP_BCREG
)):
369 with m
.If(self
.lk
): # "link" mode
370 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
) # constant: LR
371 comb
+= self
.fast_out
.ok
.eq(1)
373 # RFID 2nd spr (fast)
374 with m
.If(op
.internal_op
== InternalOp
.OP_RFID
):
375 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
376 comb
+= self
.fast_out
.ok
.eq(1)
381 class DecodeRC(Elaboratable
):
382 """DecodeRc from instruction
384 decodes Record bit Rc
386 def __init__(self
, dec
):
388 self
.sel_in
= Signal(RC
, reset_less
=True)
389 self
.insn_in
= Signal(32, reset_less
=True)
390 self
.rc_out
= Data(1, "rc")
392 def elaborate(self
, platform
):
396 # select Record bit out field
397 with m
.Switch(self
.sel_in
):
399 comb
+= self
.rc_out
.data
.eq(self
.dec
.Rc
)
400 comb
+= self
.rc_out
.ok
.eq(1)
402 comb
+= self
.rc_out
.data
.eq(1)
403 comb
+= self
.rc_out
.ok
.eq(1)
404 with m
.Case(RC
.NONE
):
405 comb
+= self
.rc_out
.data
.eq(0)
406 comb
+= self
.rc_out
.ok
.eq(1)
411 class DecodeOE(Elaboratable
):
412 """DecodeOE from instruction
414 decodes OE field: uses RC decode detection which might not be good
416 -- For now, use "rc" in the decode table to decide whether oe exists.
417 -- This is not entirely correct architecturally: For mulhd and
418 -- mulhdu, the OE field is reserved. It remains to be seen what an
419 -- actual POWER9 does if we set it on those instructions, for now we
420 -- test that further down when assigning to the multiplier oe input.
422 def __init__(self
, dec
):
424 self
.sel_in
= Signal(RC
, reset_less
=True)
425 self
.insn_in
= Signal(32, reset_less
=True)
426 self
.oe_out
= Data(1, "oe")
428 def elaborate(self
, platform
):
432 # select OE bit out field
433 with m
.Switch(self
.sel_in
):
435 comb
+= self
.oe_out
.data
.eq(self
.dec
.OE
)
436 comb
+= self
.oe_out
.ok
.eq(1)
440 class DecodeCRIn(Elaboratable
):
441 """Decodes input CR from instruction
443 CR indices - insn fields - (not the data *in* the CR) require only 3
444 bits because they refer to CR0-CR7
447 def __init__(self
, dec
):
449 self
.sel_in
= Signal(CRInSel
, reset_less
=True)
450 self
.insn_in
= Signal(32, reset_less
=True)
451 self
.cr_bitfield
= Data(3, "cr_bitfield")
452 self
.cr_bitfield_b
= Data(3, "cr_bitfield_b")
453 self
.cr_bitfield_o
= Data(3, "cr_bitfield_o")
454 self
.whole_reg
= Signal(reset_less
=True)
456 def elaborate(self
, platform
):
460 comb
+= self
.cr_bitfield
.ok
.eq(0)
461 comb
+= self
.cr_bitfield_b
.ok
.eq(0)
462 comb
+= self
.whole_reg
.eq(0)
463 with m
.Switch(self
.sel_in
):
464 with m
.Case(CRInSel
.NONE
):
465 pass # No bitfield activated
466 with m
.Case(CRInSel
.CR0
):
467 comb
+= self
.cr_bitfield
.data
.eq(0)
468 comb
+= self
.cr_bitfield
.ok
.eq(1)
469 with m
.Case(CRInSel
.BI
):
470 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BI
[2:5])
471 comb
+= self
.cr_bitfield
.ok
.eq(1)
472 with m
.Case(CRInSel
.BFA
):
473 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BFA
)
474 comb
+= self
.cr_bitfield
.ok
.eq(1)
475 with m
.Case(CRInSel
.BA_BB
):
476 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BA
[2:5])
477 comb
+= self
.cr_bitfield
.ok
.eq(1)
478 comb
+= self
.cr_bitfield_b
.data
.eq(self
.dec
.BB
[2:5])
479 comb
+= self
.cr_bitfield_b
.ok
.eq(1)
480 comb
+= self
.cr_bitfield_o
.data
.eq(self
.dec
.BT
[2:5])
481 comb
+= self
.cr_bitfield_o
.ok
.eq(1)
482 with m
.Case(CRInSel
.BC
):
483 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BC
[2:5])
484 comb
+= self
.cr_bitfield
.ok
.eq(1)
485 with m
.Case(CRInSel
.WHOLE_REG
):
486 comb
+= self
.whole_reg
.eq(1)
491 class DecodeCROut(Elaboratable
):
492 """Decodes input CR from instruction
494 CR indices - insn fields - (not the data *in* the CR) require only 3
495 bits because they refer to CR0-CR7
498 def __init__(self
, dec
):
500 self
.rc_in
= Signal(reset_less
=True)
501 self
.sel_in
= Signal(CROutSel
, reset_less
=True)
502 self
.insn_in
= Signal(32, reset_less
=True)
503 self
.cr_bitfield
= Data(3, "cr_bitfield")
504 self
.whole_reg
= Signal(reset_less
=True)
506 def elaborate(self
, platform
):
510 comb
+= self
.cr_bitfield
.ok
.eq(0)
511 comb
+= self
.whole_reg
.eq(0)
512 with m
.Switch(self
.sel_in
):
513 with m
.Case(CROutSel
.NONE
):
514 pass # No bitfield activated
515 with m
.Case(CROutSel
.CR0
):
516 comb
+= self
.cr_bitfield
.data
.eq(0)
517 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
518 with m
.Case(CROutSel
.BF
):
519 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BF
)
520 comb
+= self
.cr_bitfield
.ok
.eq(1)
521 with m
.Case(CROutSel
.BT
):
522 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormXL
.BT
[2:5])
523 comb
+= self
.cr_bitfield
.ok
.eq(1)
524 with m
.Case(CROutSel
.WHOLE_REG
):
525 comb
+= self
.whole_reg
.eq(1)
532 self
.ca
= Signal(2, reset_less
=True)
533 self
.ov
= Signal(2, reset_less
=True)
534 self
.so
= Signal(reset_less
=True)
537 return [self
.ca
, self
.ov
, self
.so
]
540 class PowerDecode2(Elaboratable
):
542 def __init__(self
, dec
):
545 self
.e
= Decode2ToExecute1Type()
546 self
.valid
= Signal()
549 return self
.dec
.ports() + self
.e
.ports()
551 def elaborate(self
, platform
):
554 e
, op
, do
= self
.e
, self
.dec
.op
, self
.e
.do
556 # set up submodule decoders
557 m
.submodules
.dec
= self
.dec
558 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
)
559 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
)
560 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
)
561 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
)
562 m
.submodules
.dec_o2
= dec_o2
= DecodeOut2(self
.dec
)
563 m
.submodules
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
564 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
)
565 m
.submodules
.dec_cr_in
= dec_cr_in
= DecodeCRIn(self
.dec
)
566 m
.submodules
.dec_cr_out
= dec_cr_out
= DecodeCROut(self
.dec
)
568 # copy instruction through...
569 for i
in [do
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
570 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
, dec_rc
.insn_in
,
571 dec_oe
.insn_in
, dec_cr_in
.insn_in
, dec_cr_out
.insn_in
]:
572 comb
+= i
.eq(self
.dec
.opcode_in
)
574 # ...and subdecoders' input fields
575 comb
+= dec_a
.sel_in
.eq(op
.in1_sel
)
576 comb
+= dec_b
.sel_in
.eq(op
.in2_sel
)
577 comb
+= dec_c
.sel_in
.eq(op
.in3_sel
)
578 comb
+= dec_o
.sel_in
.eq(op
.out_sel
)
579 comb
+= dec_o2
.sel_in
.eq(op
.out_sel
)
580 comb
+= dec_o2
.lk
.eq(do
.lk
)
581 comb
+= dec_rc
.sel_in
.eq(op
.rc_sel
)
582 comb
+= dec_oe
.sel_in
.eq(op
.rc_sel
) # XXX should be OE sel
583 comb
+= dec_cr_in
.sel_in
.eq(op
.cr_in
)
584 comb
+= dec_cr_out
.sel_in
.eq(op
.cr_out
)
585 comb
+= dec_cr_out
.rc_in
.eq(dec_rc
.rc_out
.data
)
587 # set up instruction, pick fn unit
588 comb
+= e
.nia
.eq(0) # XXX TODO (or remove? not sure yet)
589 fu
= op
.function_unit
590 itype
= Mux(fu
== Function
.NONE
, InternalOp
.OP_ILLEGAL
, op
.internal_op
)
591 comb
+= do
.insn_type
.eq(itype
)
592 comb
+= do
.fn_unit
.eq(fu
)
594 # registers a, b, c and out and out2 (LD/ST EA)
595 comb
+= e
.read_reg1
.eq(dec_a
.reg_out
)
596 comb
+= e
.read_reg2
.eq(dec_b
.reg_out
)
597 comb
+= e
.read_reg3
.eq(dec_c
.reg_out
)
598 comb
+= e
.write_reg
.eq(dec_o
.reg_out
)
599 comb
+= e
.write_ea
.eq(dec_o2
.reg_out
)
600 comb
+= do
.imm_data
.eq(dec_b
.imm_out
) # immediate in RB (usually)
601 comb
+= do
.zero_a
.eq(dec_a
.immz_out
) # RA==0 detected
604 comb
+= do
.rc
.eq(dec_rc
.rc_out
)
605 comb
+= do
.oe
.eq(dec_oe
.oe_out
)
608 comb
+= e
.read_spr1
.eq(dec_a
.spr_out
)
609 comb
+= e
.write_spr
.eq(dec_o
.spr_out
)
612 comb
+= e
.read_fast1
.eq(dec_a
.fast_out
)
613 comb
+= e
.read_fast2
.eq(dec_b
.fast_out
)
614 comb
+= e
.write_fast1
.eq(dec_o
.fast_out
)
615 comb
+= e
.write_fast2
.eq(dec_o2
.fast_out
)
617 # condition registers (CR)
618 comb
+= e
.read_cr1
.eq(dec_cr_in
.cr_bitfield
)
619 comb
+= e
.read_cr2
.eq(dec_cr_in
.cr_bitfield_b
)
620 comb
+= e
.read_cr3
.eq(dec_cr_in
.cr_bitfield_o
)
621 comb
+= e
.write_cr
.eq(dec_cr_out
.cr_bitfield
)
623 comb
+= do
.read_cr_whole
.eq(dec_cr_in
.whole_reg
)
624 comb
+= do
.write_cr_whole
.eq(dec_cr_out
.whole_reg
)
625 comb
+= do
.write_cr0
.eq(dec_cr_out
.cr_bitfield
.ok
)
627 # decoded/selected instruction flags
628 comb
+= do
.data_len
.eq(op
.ldst_len
)
629 comb
+= do
.invert_a
.eq(op
.inv_a
)
630 comb
+= do
.invert_out
.eq(op
.inv_out
)
631 comb
+= do
.input_carry
.eq(op
.cry_in
) # carry comes in
632 comb
+= do
.output_carry
.eq(op
.cry_out
) # carry goes out
633 comb
+= do
.is_32bit
.eq(op
.is_32b
)
634 comb
+= do
.is_signed
.eq(op
.sgn
)
636 comb
+= do
.lk
.eq(self
.dec
.LK
) # XXX TODO: accessor
638 comb
+= do
.byte_reverse
.eq(op
.br
)
639 comb
+= do
.sign_extend
.eq(op
.sgn_ext
)
640 comb
+= do
.update
.eq(op
.upd
) # LD/ST "update" mode.
642 # These should be removed eventually
643 comb
+= do
.input_cr
.eq(op
.cr_in
) # condition reg comes in
644 comb
+= do
.output_cr
.eq(op
.cr_out
) # condition reg goes in
646 # sigh this is exactly the sort of thing for which the
647 # decoder is designed to not need. MTSPR, MFSPR and others need
648 # access to the XER bits. however setting e.oe is not appropriate
649 with m
.If(op
.internal_op
== InternalOp
.OP_MFSPR
):
650 comb
+= e
.xer_in
.eq(1)
651 with m
.If(op
.internal_op
== InternalOp
.OP_MTSPR
):
652 comb
+= e
.xer_out
.eq(1)
654 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
655 with m
.If(op
.internal_op
== InternalOp
.OP_TRAP
):
656 comb
+= do
.trapaddr
.eq(0x70) # addr=0x700 (strip first nibble)
658 # illegal instruction must redirect to trap. this is done by
659 # *overwriting* the decoded instruction and starting again.
660 # (note: the same goes for interrupts and for privileged operations,
661 # just with different trapaddr and traptype)
662 with m
.If(op
.internal_op
== InternalOp
.OP_ILLEGAL
):
663 comb
+= e
.eq(0) # reset eeeeeverything
665 comb
+= do
.insn
.eq(self
.dec
.opcode_in
)
666 comb
+= do
.insn_type
.eq(InternalOp
.OP_TRAP
)
667 comb
+= do
.fn_unit
.eq(Function
.TRAP
)
668 comb
+= do
.trapaddr
.eq(0x70) # addr=0x700 (strip first nibble)
669 comb
+= do
.traptype
.eq(TT_ILLEG
) # request illegal instruction
671 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
672 # Note: OP_SC could actually be modified to just be a trap
673 with m
.If((do
.insn_type
== InternalOp
.OP_TRAP
) |
674 (do
.insn_type
== InternalOp
.OP_SC
)):
675 # TRAP write fast1 = SRR0
676 comb
+= e
.write_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
677 comb
+= e
.write_fast1
.ok
.eq(1)
678 # TRAP write fast2 = SRR1
679 comb
+= e
.write_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
680 comb
+= e
.write_fast2
.ok
.eq(1)
682 # RFID: needs to read SRR0/1
683 with m
.If(do
.insn_type
== InternalOp
.OP_RFID
):
684 # TRAP read fast1 = SRR0
685 comb
+= e
.read_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
686 comb
+= e
.read_fast1
.ok
.eq(1)
687 # TRAP read fast2 = SRR1
688 comb
+= e
.read_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
689 comb
+= e
.read_fast2
.ok
.eq(1)
693 # TODO: get msr, then can do privileged instruction
694 with m
.If(instr_is_priv(m
, op
.internal_op
, e
.insn
) & msr
[MSR_PR
]):
695 comb
+= e
.eq(0) # reset eeeeeverything
697 comb
+= e
.insn
.eq(self
.dec
.opcode_in
)
698 comb
+= e
.insn_type
.eq(InternalOp
.OP_TRAP
)
699 comb
+= e
.fn_unit
.eq(Function
.TRAP
)
700 # privileged instruction trap
701 comb
+= e
.traptype
.eq(TT_PRIV
) # request privileged instruction
702 comb
+= e
.trapaddr
.eq(0x70) # addr=0x700 (strip first nibble)
705 def regspecmap_read(self
, regfile
, regname
):
706 """regspecmap_read: provides PowerDecode2 with an encoding relationship
707 to Function Unit port regfiles (read-enable, read regnum, write regnum)
708 regfile and regname arguments are fields 1 and 2 from a given regspec.
710 return regspec_decode_read(self
.e
, regfile
, regname
)
712 def regspecmap_write(self
, regfile
, regname
):
713 """regspecmap_write: provides PowerDecode2 with an encoding relationship
714 to Function Unit port regfiles (write port, write regnum)
715 regfile and regname arguments are fields 1 and 2 from a given regspec.
717 return regspec_decode_write(self
.e
, regfile
, regname
)
719 def rdflags(self
, cu
):
721 for idx
in range(cu
.n_src
):
722 regfile
, regname
, _
= cu
.get_in_spec(idx
)
723 rdflag
, read
= self
.regspecmap_read(regfile
, regname
)
725 print ("rdflags", rdl
)
729 if __name__
== '__main__':
730 pdecode
= create_pdecode()
731 dec2
= PowerDecode2(pdecode
)
732 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
733 with
open("dec2.il", "w") as f
: