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 DecodeA(Elaboratable
):
56 """DecodeA from instruction
58 decodes register RA, whether immediate-zero, implicit and
62 def __init__(self
, dec
):
64 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
65 self
.insn_in
= Signal(32, reset_less
=True)
66 self
.reg_out
= Data(5, name
="reg_a")
67 self
.immz_out
= Signal(reset_less
=True)
68 self
.spr_out
= Data(10, "spr_a")
69 self
.fast_out
= Data(3, "fast_a")
71 def elaborate(self
, platform
):
75 # select Register A field
76 ra
= Signal(5, reset_less
=True)
77 comb
+= ra
.eq(self
.dec
.RA
)
78 with m
.If((self
.sel_in
== In1Sel
.RA
) |
79 ((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
80 (ra
!= Const(0, 5)))):
81 comb
+= self
.reg_out
.data
.eq(ra
)
82 comb
+= self
.reg_out
.ok
.eq(1)
84 # zero immediate requested
85 with m
.If((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
86 (self
.reg_out
.data
== Const(0, 5))):
87 comb
+= self
.immz_out
.eq(1)
89 # some Logic/ALU ops have RS as the 3rd arg, but no "RA".
90 with m
.If(self
.sel_in
== In1Sel
.RS
):
91 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
92 comb
+= self
.reg_out
.ok
.eq(1)
94 # decode Fast-SPR based on instruction type
96 # BC or BCREG: potential implicit register (CTR) NOTE: same in DecodeOut
97 with m
.If(op
.internal_op
== InternalOp
.OP_BC
):
98 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
99 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
) # constant: CTR
100 comb
+= self
.fast_out
.ok
.eq(1)
101 with m
.Elif(op
.internal_op
== InternalOp
.OP_BCREG
):
102 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
103 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
104 with m
.If(xo9
& ~xo5
):
105 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
) # constant: CTR
106 comb
+= self
.fast_out
.ok
.eq(1)
108 # MFSPR move from SPRs
109 with m
.If(op
.internal_op
== InternalOp
.OP_MFSPR
):
110 spr
= Signal(10, reset_less
=True)
111 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
114 with m
.Case(SPR
.CTR
.value
):
115 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
116 comb
+= self
.fast_out
.ok
.eq(1)
117 with m
.Case(SPR
.LR
.value
):
118 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
119 comb
+= self
.fast_out
.ok
.eq(1)
120 with m
.Case(SPR
.TAR
.value
):
121 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
122 comb
+= self
.fast_out
.ok
.eq(1)
123 with m
.Case(SPR
.SRR0
.value
):
124 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
)
125 comb
+= self
.fast_out
.ok
.eq(1)
126 with m
.Case(SPR
.SRR1
.value
):
127 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
)
128 comb
+= self
.fast_out
.ok
.eq(1)
129 with m
.Case(SPR
.XER
.value
):
131 # XXX TODO: map to internal SPR numbers
132 # XXX TODO: dec and tb not to go through mapping.
134 comb
+= self
.spr_out
.data
.eq(spr
)
135 comb
+= self
.spr_out
.ok
.eq(1)
141 class DecodeB(Elaboratable
):
142 """DecodeB from instruction
144 decodes register RB, different forms of immediate (signed, unsigned),
145 and implicit SPRs. register B is basically "lane 2" into the CompUnits.
146 by industry-standard convention, "lane 2" is where fully-decoded
147 immediates are muxed in.
150 def __init__(self
, dec
):
152 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
153 self
.insn_in
= Signal(32, reset_less
=True)
154 self
.reg_out
= Data(5, "reg_b")
155 self
.imm_out
= Data(64, "imm_b")
156 self
.fast_out
= Data(3, "fast_b")
158 def elaborate(self
, platform
):
162 # select Register B field
163 with m
.Switch(self
.sel_in
):
164 with m
.Case(In2Sel
.RB
):
165 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
)
166 comb
+= self
.reg_out
.ok
.eq(1)
167 with m
.Case(In2Sel
.RS
):
168 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
) # for M-Form shiftrot
169 comb
+= self
.reg_out
.ok
.eq(1)
170 with m
.Case(In2Sel
.CONST_UI
):
171 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
)
172 comb
+= self
.imm_out
.ok
.eq(1)
173 with m
.Case(In2Sel
.CONST_SI
): # TODO: sign-extend here?
174 comb
+= self
.imm_out
.data
.eq(
175 exts(self
.dec
.SI
, 16, 64))
176 comb
+= self
.imm_out
.ok
.eq(1)
177 with m
.Case(In2Sel
.CONST_UI_HI
):
178 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
<<16)
179 comb
+= self
.imm_out
.ok
.eq(1)
180 with m
.Case(In2Sel
.CONST_SI_HI
): # TODO: sign-extend here?
181 comb
+= self
.imm_out
.data
.eq(self
.dec
.SI
<<16)
182 comb
+= self
.imm_out
.data
.eq(
183 exts(self
.dec
.SI
<< 16, 32, 64))
184 comb
+= self
.imm_out
.ok
.eq(1)
185 with m
.Case(In2Sel
.CONST_LI
):
186 comb
+= self
.imm_out
.data
.eq(self
.dec
.LI
<<2)
187 comb
+= self
.imm_out
.ok
.eq(1)
188 with m
.Case(In2Sel
.CONST_BD
):
189 comb
+= self
.imm_out
.data
.eq(self
.dec
.BD
<<2)
190 comb
+= self
.imm_out
.ok
.eq(1)
191 with m
.Case(In2Sel
.CONST_DS
):
192 comb
+= self
.imm_out
.data
.eq(self
.dec
.DS
<<2)
193 comb
+= self
.imm_out
.ok
.eq(1)
194 with m
.Case(In2Sel
.CONST_M1
):
195 comb
+= self
.imm_out
.data
.eq(~
Const(0, 64)) # all 1s
196 comb
+= self
.imm_out
.ok
.eq(1)
197 with m
.Case(In2Sel
.CONST_SH
):
198 comb
+= self
.imm_out
.data
.eq(self
.dec
.sh
)
199 comb
+= self
.imm_out
.ok
.eq(1)
200 with m
.Case(In2Sel
.CONST_SH32
):
201 comb
+= self
.imm_out
.data
.eq(self
.dec
.SH32
)
202 comb
+= self
.imm_out
.ok
.eq(1)
204 # decode SPR2 based on instruction type
206 # BCREG implicitly uses LR or TAR for 2nd reg
207 # CTR however is already in fast_spr1 *not* 2.
208 with m
.If(op
.internal_op
== InternalOp
.OP_BCREG
):
209 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
210 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
212 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
213 comb
+= self
.fast_out
.ok
.eq(1)
215 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
216 comb
+= self
.fast_out
.ok
.eq(1)
221 class DecodeC(Elaboratable
):
222 """DecodeC from instruction
224 decodes register RC. this is "lane 3" into some CompUnits (not many)
227 def __init__(self
, dec
):
229 self
.sel_in
= Signal(In3Sel
, reset_less
=True)
230 self
.insn_in
= Signal(32, reset_less
=True)
231 self
.reg_out
= Data(5, "reg_c")
233 def elaborate(self
, platform
):
237 # select Register C field
238 with m
.Switch(self
.sel_in
):
239 with m
.Case(In3Sel
.RB
):
240 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
) # for M-Form shiftrot
241 comb
+= self
.reg_out
.ok
.eq(1)
242 with m
.Case(In3Sel
.RS
):
243 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
244 comb
+= self
.reg_out
.ok
.eq(1)
249 class DecodeOut(Elaboratable
):
250 """DecodeOut from instruction
252 decodes output register RA, RT or SPR
255 def __init__(self
, dec
):
257 self
.sel_in
= Signal(OutSel
, reset_less
=True)
258 self
.insn_in
= Signal(32, reset_less
=True)
259 self
.reg_out
= Data(5, "reg_o")
260 self
.spr_out
= Data(10, "spr_o")
261 self
.fast_out
= Data(3, "fast_o")
263 def elaborate(self
, platform
):
268 # select Register out field
269 with m
.Switch(self
.sel_in
):
270 with m
.Case(OutSel
.RT
):
271 comb
+= self
.reg_out
.data
.eq(self
.dec
.RT
)
272 comb
+= self
.reg_out
.ok
.eq(1)
273 with m
.Case(OutSel
.RA
):
274 comb
+= self
.reg_out
.data
.eq(self
.dec
.RA
)
275 comb
+= self
.reg_out
.ok
.eq(1)
276 with m
.Case(OutSel
.SPR
):
277 spr
= Signal(10, reset_less
=True)
278 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
279 # TODO MTSPR 1st spr (fast)
280 with m
.If(op
.internal_op
== InternalOp
.OP_MTSPR
):
283 with m
.Case(SPR
.CTR
.value
):
284 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
285 comb
+= self
.fast_out
.ok
.eq(1)
286 with m
.Case(SPR
.LR
.value
):
287 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
288 comb
+= self
.fast_out
.ok
.eq(1)
289 with m
.Case(SPR
.TAR
.value
):
290 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
291 comb
+= self
.fast_out
.ok
.eq(1)
292 with m
.Case(SPR
.SRR0
.value
):
293 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
)
294 comb
+= self
.fast_out
.ok
.eq(1)
295 with m
.Case(SPR
.SRR1
.value
):
296 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
)
297 comb
+= self
.fast_out
.ok
.eq(1)
298 with m
.Case(SPR
.XER
.value
):
300 # XXX TODO: map to internal SPR numbers
301 # XXX TODO: dec and tb not to go through mapping.
303 comb
+= self
.spr_out
.data
.eq(spr
)
304 comb
+= self
.spr_out
.ok
.eq(1)
306 # BC or BCREG: potential implicit register (CTR) NOTE: same in DecodeA
308 with m
.If((op
.internal_op
== InternalOp
.OP_BC
) |
309 (op
.internal_op
== InternalOp
.OP_BCREG
)):
310 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
311 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
) # constant: CTR
312 comb
+= self
.fast_out
.ok
.eq(1)
314 # RFID 1st spr (fast)
315 with m
.If(op
.internal_op
== InternalOp
.OP_RFID
):
316 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
317 comb
+= self
.fast_out
.ok
.eq(1)
322 class DecodeOut2(Elaboratable
):
323 """DecodeOut2 from instruction
325 decodes output registers
328 def __init__(self
, dec
):
330 self
.sel_in
= Signal(OutSel
, reset_less
=True)
331 self
.lk
= Signal(reset_less
=True)
332 self
.insn_in
= Signal(32, reset_less
=True)
333 self
.reg_out
= Data(5, "reg_o")
334 self
.fast_out
= Data(3, "fast_o")
336 def elaborate(self
, platform
):
340 # update mode LD/ST uses read-reg A also as an output
341 with m
.If(self
.dec
.op
.upd
):
342 comb
+= self
.reg_out
.eq(self
.dec
.RA
)
343 comb
+= self
.reg_out
.ok
.eq(1)
345 # BC or BCREG: potential implicit register (LR) output
347 with m
.If((op
.internal_op
== InternalOp
.OP_BC
) |
348 (op
.internal_op
== InternalOp
.OP_BCREG
)):
349 with m
.If(self
.lk
): # "link" mode
350 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
) # constant: LR
351 comb
+= self
.fast_out
.ok
.eq(1)
353 # RFID 2nd spr (fast)
354 with m
.If(op
.internal_op
== InternalOp
.OP_RFID
):
355 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
356 comb
+= self
.fast_out
.ok
.eq(1)
361 class DecodeRC(Elaboratable
):
362 """DecodeRc from instruction
364 decodes Record bit Rc
366 def __init__(self
, dec
):
368 self
.sel_in
= Signal(RC
, reset_less
=True)
369 self
.insn_in
= Signal(32, reset_less
=True)
370 self
.rc_out
= Data(1, "rc")
372 def elaborate(self
, platform
):
376 # select Record bit out field
377 with m
.Switch(self
.sel_in
):
379 comb
+= self
.rc_out
.data
.eq(self
.dec
.Rc
)
380 comb
+= self
.rc_out
.ok
.eq(1)
382 comb
+= self
.rc_out
.data
.eq(1)
383 comb
+= self
.rc_out
.ok
.eq(1)
384 with m
.Case(RC
.NONE
):
385 comb
+= self
.rc_out
.data
.eq(0)
386 comb
+= self
.rc_out
.ok
.eq(1)
391 class DecodeOE(Elaboratable
):
392 """DecodeOE from instruction
394 decodes OE field: uses RC decode detection which might not be good
396 -- For now, use "rc" in the decode table to decide whether oe exists.
397 -- This is not entirely correct architecturally: For mulhd and
398 -- mulhdu, the OE field is reserved. It remains to be seen what an
399 -- actual POWER9 does if we set it on those instructions, for now we
400 -- test that further down when assigning to the multiplier oe input.
402 def __init__(self
, dec
):
404 self
.sel_in
= Signal(RC
, reset_less
=True)
405 self
.insn_in
= Signal(32, reset_less
=True)
406 self
.oe_out
= Data(1, "oe")
408 def elaborate(self
, platform
):
412 # select OE bit out field
413 with m
.Switch(self
.sel_in
):
415 comb
+= self
.oe_out
.data
.eq(self
.dec
.OE
)
416 comb
+= self
.oe_out
.ok
.eq(1)
420 class DecodeCRIn(Elaboratable
):
421 """Decodes input CR from instruction
423 CR indices - insn fields - (not the data *in* the CR) require only 3
424 bits because they refer to CR0-CR7
427 def __init__(self
, dec
):
429 self
.sel_in
= Signal(CRInSel
, reset_less
=True)
430 self
.insn_in
= Signal(32, reset_less
=True)
431 self
.cr_bitfield
= Data(3, "cr_bitfield")
432 self
.cr_bitfield_b
= Data(3, "cr_bitfield_b")
433 self
.cr_bitfield_o
= Data(3, "cr_bitfield_o")
434 self
.whole_reg
= Signal(reset_less
=True)
436 def elaborate(self
, platform
):
440 comb
+= self
.cr_bitfield
.ok
.eq(0)
441 comb
+= self
.cr_bitfield_b
.ok
.eq(0)
442 comb
+= self
.whole_reg
.eq(0)
443 with m
.Switch(self
.sel_in
):
444 with m
.Case(CRInSel
.NONE
):
445 pass # No bitfield activated
446 with m
.Case(CRInSel
.CR0
):
447 comb
+= self
.cr_bitfield
.data
.eq(0)
448 comb
+= self
.cr_bitfield
.ok
.eq(1)
449 with m
.Case(CRInSel
.BI
):
450 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BI
[2:5])
451 comb
+= self
.cr_bitfield
.ok
.eq(1)
452 with m
.Case(CRInSel
.BFA
):
453 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BFA
)
454 comb
+= self
.cr_bitfield
.ok
.eq(1)
455 with m
.Case(CRInSel
.BA_BB
):
456 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BA
[2:5])
457 comb
+= self
.cr_bitfield
.ok
.eq(1)
458 comb
+= self
.cr_bitfield_b
.data
.eq(self
.dec
.BB
[2:5])
459 comb
+= self
.cr_bitfield_b
.ok
.eq(1)
460 comb
+= self
.cr_bitfield_o
.data
.eq(self
.dec
.BT
[2:5])
461 comb
+= self
.cr_bitfield_o
.ok
.eq(1)
462 with m
.Case(CRInSel
.BC
):
463 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BC
[2:5])
464 comb
+= self
.cr_bitfield
.ok
.eq(1)
465 with m
.Case(CRInSel
.WHOLE_REG
):
466 comb
+= self
.whole_reg
.eq(1)
471 class DecodeCROut(Elaboratable
):
472 """Decodes input CR from instruction
474 CR indices - insn fields - (not the data *in* the CR) require only 3
475 bits because they refer to CR0-CR7
478 def __init__(self
, dec
):
480 self
.rc_in
= Signal(reset_less
=True)
481 self
.sel_in
= Signal(CROutSel
, reset_less
=True)
482 self
.insn_in
= Signal(32, reset_less
=True)
483 self
.cr_bitfield
= Data(3, "cr_bitfield")
484 self
.whole_reg
= Signal(reset_less
=True)
486 def elaborate(self
, platform
):
490 comb
+= self
.cr_bitfield
.ok
.eq(0)
491 comb
+= self
.whole_reg
.eq(0)
492 with m
.Switch(self
.sel_in
):
493 with m
.Case(CROutSel
.NONE
):
494 pass # No bitfield activated
495 with m
.Case(CROutSel
.CR0
):
496 comb
+= self
.cr_bitfield
.data
.eq(0)
497 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
498 with m
.Case(CROutSel
.BF
):
499 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BF
)
500 comb
+= self
.cr_bitfield
.ok
.eq(1)
501 with m
.Case(CROutSel
.BT
):
502 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormXL
.BT
[2:5])
503 comb
+= self
.cr_bitfield
.ok
.eq(1)
504 with m
.Case(CROutSel
.WHOLE_REG
):
505 comb
+= self
.whole_reg
.eq(1)
512 self
.ca
= Signal(2, reset_less
=True)
513 self
.ov
= Signal(2, reset_less
=True)
514 self
.so
= Signal(reset_less
=True)
517 return [self
.ca
, self
.ov
, self
.so
]
520 class PowerDecode2(Elaboratable
):
522 def __init__(self
, dec
):
525 self
.e
= Decode2ToExecute1Type()
528 return self
.dec
.ports() + self
.e
.ports()
530 def elaborate(self
, platform
):
533 e
, op
= self
.e
, self
.dec
.op
535 # set up submodule decoders
536 m
.submodules
.dec
= self
.dec
537 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
)
538 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
)
539 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
)
540 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
)
541 m
.submodules
.dec_o2
= dec_o2
= DecodeOut2(self
.dec
)
542 m
.submodules
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
543 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
)
544 m
.submodules
.dec_cr_in
= dec_cr_in
= DecodeCRIn(self
.dec
)
545 m
.submodules
.dec_cr_out
= dec_cr_out
= DecodeCROut(self
.dec
)
547 # copy instruction through...
548 for i
in [e
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
549 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
, dec_rc
.insn_in
,
550 dec_oe
.insn_in
, dec_cr_in
.insn_in
, dec_cr_out
.insn_in
]:
551 comb
+= i
.eq(self
.dec
.opcode_in
)
553 # ...and subdecoders' input fields
554 comb
+= dec_a
.sel_in
.eq(op
.in1_sel
)
555 comb
+= dec_b
.sel_in
.eq(op
.in2_sel
)
556 comb
+= dec_c
.sel_in
.eq(op
.in3_sel
)
557 comb
+= dec_o
.sel_in
.eq(op
.out_sel
)
558 comb
+= dec_o2
.sel_in
.eq(op
.out_sel
)
559 comb
+= dec_o2
.lk
.eq(e
.lk
)
560 comb
+= dec_rc
.sel_in
.eq(op
.rc_sel
)
561 comb
+= dec_oe
.sel_in
.eq(op
.rc_sel
) # XXX should be OE sel
562 comb
+= dec_cr_in
.sel_in
.eq(op
.cr_in
)
563 comb
+= dec_cr_out
.sel_in
.eq(op
.cr_out
)
564 comb
+= dec_cr_out
.rc_in
.eq(dec_rc
.rc_out
.data
)
567 comb
+= e
.nia
.eq(0) # XXX TODO (or remove? not sure yet)
568 fu
= op
.function_unit
569 itype
= Mux(fu
== Function
.NONE
, InternalOp
.OP_ILLEGAL
, op
.internal_op
)
570 comb
+= e
.insn_type
.eq(itype
)
571 comb
+= e
.fn_unit
.eq(fu
)
573 # registers a, b, c and out and out2 (LD/ST EA)
574 comb
+= e
.read_reg1
.eq(dec_a
.reg_out
)
575 comb
+= e
.read_reg2
.eq(dec_b
.reg_out
)
576 comb
+= e
.read_reg3
.eq(dec_c
.reg_out
)
577 comb
+= e
.write_reg
.eq(dec_o
.reg_out
)
578 comb
+= e
.write_ea
.eq(dec_o2
.reg_out
)
579 comb
+= e
.imm_data
.eq(dec_b
.imm_out
) # immediate in RB (usually)
580 comb
+= e
.zero_a
.eq(dec_a
.immz_out
) # RA==0 detected
583 comb
+= e
.rc
.eq(dec_rc
.rc_out
)
584 comb
+= e
.oe
.eq(dec_oe
.oe_out
)
587 comb
+= e
.read_spr1
.eq(dec_a
.spr_out
)
588 comb
+= e
.write_spr
.eq(dec_o
.spr_out
)
591 comb
+= e
.read_fast1
.eq(dec_a
.fast_out
)
592 comb
+= e
.read_fast2
.eq(dec_b
.fast_out
)
593 comb
+= e
.write_fast1
.eq(dec_o
.fast_out
)
594 comb
+= e
.write_fast2
.eq(dec_o2
.fast_out
)
596 comb
+= e
.read_cr1
.eq(dec_cr_in
.cr_bitfield
)
597 comb
+= e
.read_cr2
.eq(dec_cr_in
.cr_bitfield_b
)
598 comb
+= e
.read_cr3
.eq(dec_cr_in
.cr_bitfield_o
)
599 comb
+= e
.read_cr_whole
.eq(dec_cr_in
.whole_reg
)
601 comb
+= e
.write_cr
.eq(dec_cr_out
.cr_bitfield
)
602 comb
+= e
.write_cr_whole
.eq(dec_cr_out
.whole_reg
)
604 # decoded/selected instruction flags
605 comb
+= e
.data_len
.eq(op
.ldst_len
)
606 comb
+= e
.invert_a
.eq(op
.inv_a
)
607 comb
+= e
.invert_out
.eq(op
.inv_out
)
608 comb
+= e
.input_carry
.eq(op
.cry_in
) # carry comes in
609 comb
+= e
.output_carry
.eq(op
.cry_out
) # carry goes out
610 comb
+= e
.is_32bit
.eq(op
.is_32b
)
611 comb
+= e
.is_signed
.eq(op
.sgn
)
613 comb
+= e
.lk
.eq(self
.dec
.LK
) # XXX TODO: accessor
615 comb
+= e
.byte_reverse
.eq(op
.br
)
616 comb
+= e
.sign_extend
.eq(op
.sgn_ext
)
617 comb
+= e
.update
.eq(op
.upd
) # LD/ST "update" mode.
620 # These should be removed eventually
621 comb
+= e
.input_cr
.eq(op
.cr_in
) # condition reg comes in
622 comb
+= e
.output_cr
.eq(op
.cr_out
) # condition reg goes in
624 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
625 with m
.If(op
.internal_op
== InternalOp
.OP_TRAP
):
626 comb
+= e
.trapaddr
.eq(0x70) # addr=0x700 (strip first nibble)
628 # illegal instruction must redirect to trap. this is done by
629 # *overwriting* the decoded instruction and starting again.
630 with m
.If(op
.internal_op
== InternalOp
.OP_ILLEGAL
):
631 comb
+= e
.eq(0) # reset eeeeeverything
633 comb
+= e
.insn
.eq(self
.dec
.opcode_in
)
634 comb
+= e
.insn_type
.eq(InternalOp
.OP_TRAP
)
635 comb
+= e
.fn_unit
.eq(Function
.TRAP
)
636 comb
+= e
.trapaddr
.eq(0x70) # addr=0x700 (strip first nibble)
637 comb
+= e
.traptype
.eq(TT_ILLEG
) # request illegal instruction
639 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
640 with m
.If(e
.insn_type
== InternalOp
.OP_TRAP
):
641 # TRAP write fast1 = SRR0
642 comb
+= e
.write_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
643 comb
+= e
.write_fast1
.ok
.eq(1)
644 # TRAP write fast2 = SRR1
645 comb
+= e
.write_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
646 comb
+= e
.write_fast2
.ok
.eq(1)
650 # TODO: get msr, then can do privileged instruction
651 with m
.If(instr_is_priv(m
, op
.internal_op
, e
.insn
) & msr
[MSR_PR
]):
652 # privileged instruction trap
653 comb
+= op
.insn_type
.eq(InternalOp
.OP_TRAP
)
654 comb
+= e
.traptype
.eq(TT_PRIV
) # request privileged instruction
655 comb
+= e
.trapaddr
.eq(0x70) # addr=0x700 (strip first nibble)
658 def regspecmap_read(self
, regfile
, regname
):
659 """regspecmap_read: provides PowerDecode2 with an encoding relationship
660 to Function Unit port regfiles (read-enable, read regnum, write regnum)
661 regfile and regname arguments are fields 1 and 2 from a given regspec.
663 return regspec_decode_read(self
.e
, regfile
, regname
)
665 def regspecmap_write(self
, regfile
, regname
):
666 """regspecmap_write: provides PowerDecode2 with an encoding relationship
667 to Function Unit port regfiles (write port, write regnum)
668 regfile and regname arguments are fields 1 and 2 from a given regspec.
670 return regspec_decode_write(self
.e
, regfile
, regname
)
672 def rdflags(self
, cu
):
674 for idx
in range(cu
.n_src
):
675 regfile
, regname
, _
= cu
.get_in_spec(idx
)
676 rdflag
, read
= self
.regspecmap_read(regfile
, regname
)
678 print ("rdflags", rdl
)
682 if __name__
== '__main__':
683 pdecode
= create_pdecode()
684 dec2
= PowerDecode2(pdecode
)
685 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
686 with
open("dec2.il", "w") as f
: