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
11 from nmutil
.util
import sel
13 from nmutil
.picker
import PriorityPicker
14 from nmutil
.iocontrol
import RecordObject
15 from nmutil
.extend
import exts
17 from openpower
.exceptions
import LDSTException
19 from openpower
.decoder
.power_svp64_prefix
import SVP64PrefixDecoder
20 from openpower
.decoder
.power_svp64_extra
import SVP64CRExtra
, SVP64RegExtra
21 from openpower
.decoder
.power_svp64_rm
import (SVP64RMModeDecode
,
22 sv_input_record_layout
,
24 from openpower
.sv
.svp64
import SVP64Rec
26 from openpower
.decoder
.power_regspec_map
import regspec_decode_read
27 from openpower
.decoder
.power_decoder
import (create_pdecode
,
28 create_pdecode_svp64_ldst
,
30 from openpower
.decoder
.power_enums
import (MicrOp
, CryIn
, Function
,
32 LdstLen
, In1Sel
, In2Sel
, In3Sel
,
33 OutSel
, SPRfull
, SPRreduced
,
34 RC
, SVP64LDSTmode
, LDSTMode
,
35 SVEXTRA
, SVEtype
, SVPtype
)
36 from openpower
.decoder
.decode2execute1
import (Decode2ToExecute1Type
, Data
,
39 from openpower
.consts
import (MSR
, SPEC
, EXTRA2
, EXTRA3
, SVP64P
, field
,
40 SPEC_SIZE
, SPECb
, SPEC_AUG_SIZE
, SVP64CROffs
,
41 FastRegsEnum
, XERRegsEnum
, TT
)
43 from openpower
.state
import CoreState
44 from openpower
.util
import (spr_to_fast
, log
)
47 def decode_spr_num(spr
):
48 return Cat(spr
[5:10], spr
[0:5])
51 def instr_is_priv(m
, op
, insn
):
52 """determines if the instruction is privileged or not
55 is_priv_insn
= Signal(reset_less
=True)
57 with m
.Case(MicrOp
.OP_ATTN
, MicrOp
.OP_MFMSR
, MicrOp
.OP_MTMSRD
,
58 MicrOp
.OP_MTMSR
, MicrOp
.OP_RFID
):
59 comb
+= is_priv_insn
.eq(1)
60 with m
.Case(MicrOp
.OP_TLBIE
) : comb
+= is_priv_insn
.eq(1)
61 with m
.Case(MicrOp
.OP_MFSPR
, MicrOp
.OP_MTSPR
):
62 with m
.If(insn
[20]): # field XFX.spr[-1] i think
63 comb
+= is_priv_insn
.eq(1)
67 class SPRMap(Elaboratable
):
68 """SPRMap: maps POWER9 SPR numbers to internal enum values, fast and slow
71 def __init__(self
, regreduce_en
):
72 self
.regreduce_en
= regreduce_en
78 self
.spr_i
= Signal(10, reset_less
=True)
79 self
.spr_o
= Data(SPR
, name
="spr_o")
80 self
.fast_o
= Data(3, name
="fast_o")
82 def elaborate(self
, platform
):
88 with m
.Switch(self
.spr_i
):
89 for i
, x
in enumerate(SPR
):
91 m
.d
.comb
+= self
.spr_o
.data
.eq(i
)
92 m
.d
.comb
+= self
.spr_o
.ok
.eq(1)
93 for x
, v
in spr_to_fast
.items():
95 m
.d
.comb
+= self
.fast_o
.data
.eq(v
)
96 m
.d
.comb
+= self
.fast_o
.ok
.eq(1)
100 class DecodeA(Elaboratable
):
101 """DecodeA from instruction
103 decodes register RA, implicit and explicit CSRs
106 def __init__(self
, dec
, op
, regreduce_en
):
107 self
.regreduce_en
= regreduce_en
108 if self
.regreduce_en
:
114 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
115 self
.insn_in
= Signal(32, reset_less
=True)
116 self
.reg_out
= Data(5, name
="reg_a")
117 self
.spr_out
= Data(SPR
, "spr_a")
118 self
.fast_out
= Data(3, "fast_a")
119 self
.sv_nz
= Signal(1)
121 def elaborate(self
, platform
):
126 m
.submodules
.sprmap
= sprmap
= SPRMap(self
.regreduce_en
)
128 # select Register A field, if *full 7 bits* are zero (2 more from SVP64)
129 ra
= Signal(5, reset_less
=True)
130 comb
+= ra
.eq(self
.dec
.RA
)
131 with m
.If((self
.sel_in
== In1Sel
.RA
) |
132 ((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
133 ((ra
!= Const(0, 5)) |
(self
.sv_nz
!= Const(0, 1))))):
134 comb
+= reg
.data
.eq(ra
)
137 # some Logic/ALU ops have RS as the 3rd arg, but no "RA".
138 # moved it to 1st position (in1_sel)... because
139 rs
= Signal(5, reset_less
=True)
140 comb
+= rs
.eq(self
.dec
.RS
)
141 with m
.If(self
.sel_in
== In1Sel
.RS
):
142 comb
+= reg
.data
.eq(rs
)
145 # select Register FRA field,
146 fra
= Signal(5, reset_less
=True)
147 comb
+= fra
.eq(self
.dec
.FRA
)
148 with m
.If(self
.sel_in
== In1Sel
.FRA
):
149 comb
+= reg
.data
.eq(fra
)
152 # select Register FRS field,
153 frs
= Signal(5, reset_less
=True)
154 comb
+= frs
.eq(self
.dec
.FRS
)
155 with m
.If(self
.sel_in
== In1Sel
.FRS
):
156 comb
+= reg
.data
.eq(frs
)
159 # decode Fast-SPR based on instruction type
160 with m
.Switch(op
.internal_op
):
162 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeOut
163 with m
.Case(MicrOp
.OP_BC
):
164 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
166 comb
+= self
.fast_out
.data
.eq(FastRegsEnum
.CTR
)
167 comb
+= self
.fast_out
.ok
.eq(1)
168 with m
.Case(MicrOp
.OP_BCREG
):
169 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
170 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
171 with m
.If(xo9
& ~xo5
):
173 comb
+= self
.fast_out
.data
.eq(FastRegsEnum
.CTR
)
174 comb
+= self
.fast_out
.ok
.eq(1)
176 # MFSPR move from SPRs
177 with m
.Case(MicrOp
.OP_MFSPR
):
178 spr
= Signal(10, reset_less
=True)
179 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
180 comb
+= sprmap
.spr_i
.eq(spr
)
181 comb
+= self
.spr_out
.eq(sprmap
.spr_o
)
182 comb
+= self
.fast_out
.eq(sprmap
.fast_o
)
187 class DecodeAImm(Elaboratable
):
188 """DecodeA immediate from instruction
190 decodes register RA, whether immediate-zero, implicit and
191 explicit CSRs. SVP64 mode requires 2 extra bits
194 def __init__(self
, dec
):
196 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
197 self
.immz_out
= Signal(reset_less
=True)
198 self
.sv_nz
= Signal(1) # EXTRA bits from SVP64
200 def elaborate(self
, platform
):
204 # zero immediate requested
205 ra
= Signal(5, reset_less
=True)
206 comb
+= ra
.eq(self
.dec
.RA
)
207 with m
.If((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
208 (ra
== Const(0, 5)) &
209 (self
.sv_nz
== Const(0, 1))):
210 comb
+= self
.immz_out
.eq(1)
215 class DecodeB(Elaboratable
):
216 """DecodeB from instruction
218 decodes register RB, different forms of immediate (signed, unsigned),
219 and implicit SPRs. register B is basically "lane 2" into the CompUnits.
220 by industry-standard convention, "lane 2" is where fully-decoded
221 immediates are muxed in.
224 def __init__(self
, dec
, op
):
227 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
228 self
.insn_in
= Signal(32, reset_less
=True)
229 self
.reg_out
= Data(7, "reg_b")
230 self
.reg_isvec
= Signal(1, name
="reg_b_isvec") # TODO: in reg_out
231 self
.fast_out
= Data(3, "fast_b")
233 def elaborate(self
, platform
):
239 # select Register B field
240 with m
.Switch(self
.sel_in
):
241 with m
.Case(In2Sel
.FRB
):
242 comb
+= reg
.data
.eq(self
.dec
.FRB
)
244 with m
.Case(In2Sel
.RB
):
245 comb
+= reg
.data
.eq(self
.dec
.RB
)
247 with m
.Case(In2Sel
.RS
):
248 # for M-Form shiftrot
249 comb
+= reg
.data
.eq(self
.dec
.RS
)
252 # decode SPR2 based on instruction type
253 # BCREG implicitly uses LR or TAR for 2nd reg
254 # CTR however is already in fast_spr1 *not* 2.
255 with m
.If(op
.internal_op
== MicrOp
.OP_BCREG
):
256 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
257 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
259 comb
+= self
.fast_out
.data
.eq(FastRegsEnum
.LR
)
260 comb
+= self
.fast_out
.ok
.eq(1)
262 comb
+= self
.fast_out
.data
.eq(FastRegsEnum
.TAR
)
263 comb
+= self
.fast_out
.ok
.eq(1)
268 class DecodeBImm(Elaboratable
):
269 """DecodeB immediate from instruction
271 def __init__(self
, dec
):
273 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
274 self
.imm_out
= Data(64, "imm_b")
276 def elaborate(self
, platform
):
280 # select Register B Immediate
281 with m
.Switch(self
.sel_in
):
282 with m
.Case(In2Sel
.CONST_UI
): # unsigned
283 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
)
284 comb
+= self
.imm_out
.ok
.eq(1)
285 with m
.Case(In2Sel
.CONST_SI
): # sign-extended 16-bit
286 si
= Signal(16, reset_less
=True)
287 comb
+= si
.eq(self
.dec
.SI
)
288 comb
+= self
.imm_out
.data
.eq(exts(si
, 16, 64))
289 comb
+= self
.imm_out
.ok
.eq(1)
290 with m
.Case(In2Sel
.CONST_SI_HI
): # sign-extended 16+16=32 bit
291 si_hi
= Signal(32, reset_less
=True)
292 comb
+= si_hi
.eq(self
.dec
.SI
<< 16)
293 comb
+= self
.imm_out
.data
.eq(exts(si_hi
, 32, 64))
294 comb
+= self
.imm_out
.ok
.eq(1)
295 with m
.Case(In2Sel
.CONST_UI_HI
): # unsigned
296 ui
= Signal(16, reset_less
=True)
297 comb
+= ui
.eq(self
.dec
.UI
)
298 comb
+= self
.imm_out
.data
.eq(ui
<< 16)
299 comb
+= self
.imm_out
.ok
.eq(1)
300 with m
.Case(In2Sel
.CONST_LI
): # sign-extend 24+2=26 bit
301 li
= Signal(26, reset_less
=True)
302 comb
+= li
.eq(self
.dec
.LI
<< 2)
303 comb
+= self
.imm_out
.data
.eq(exts(li
, 26, 64))
304 comb
+= self
.imm_out
.ok
.eq(1)
305 with m
.Case(In2Sel
.CONST_BD
): # sign-extend (14+2)=16 bit
306 bd
= Signal(16, reset_less
=True)
307 comb
+= bd
.eq(self
.dec
.BD
<< 2)
308 comb
+= self
.imm_out
.data
.eq(exts(bd
, 16, 64))
309 comb
+= self
.imm_out
.ok
.eq(1)
310 with m
.Case(In2Sel
.CONST_DS
): # sign-extended (14+2=16) bit
311 ds
= Signal(16, reset_less
=True)
312 comb
+= ds
.eq(self
.dec
.DS
<< 2)
313 comb
+= self
.imm_out
.data
.eq(exts(ds
, 16, 64))
314 comb
+= self
.imm_out
.ok
.eq(1)
315 with m
.Case(In2Sel
.CONST_M1
): # signed (-1)
316 comb
+= self
.imm_out
.data
.eq(~
Const(0, 64)) # all 1s
317 comb
+= self
.imm_out
.ok
.eq(1)
318 with m
.Case(In2Sel
.CONST_SH
): # unsigned - for shift
319 comb
+= self
.imm_out
.data
.eq(self
.dec
.sh
)
320 comb
+= self
.imm_out
.ok
.eq(1)
321 with m
.Case(In2Sel
.CONST_SH32
): # unsigned - for shift
322 comb
+= self
.imm_out
.data
.eq(self
.dec
.SH32
)
323 comb
+= self
.imm_out
.ok
.eq(1)
328 class DecodeC(Elaboratable
):
329 """DecodeC from instruction
331 decodes register RC. this is "lane 3" into some CompUnits (not many)
334 def __init__(self
, dec
, op
):
337 self
.sel_in
= Signal(In3Sel
, reset_less
=True)
338 self
.insn_in
= Signal(32, reset_less
=True)
339 self
.reg_out
= Data(5, "reg_c")
341 def elaborate(self
, platform
):
347 # select Register C field
348 with m
.Switch(self
.sel_in
):
349 with m
.Case(In3Sel
.RB
):
350 # for M-Form shiftrot
351 comb
+= reg
.data
.eq(self
.dec
.RB
)
353 with m
.Case(In3Sel
.FRS
):
354 comb
+= reg
.data
.eq(self
.dec
.FRS
)
356 with m
.Case(In3Sel
.FRC
):
357 comb
+= reg
.data
.eq(self
.dec
.FRC
)
359 with m
.Case(In3Sel
.RS
):
360 comb
+= reg
.data
.eq(self
.dec
.RS
)
362 with m
.Case(In3Sel
.RC
):
363 comb
+= reg
.data
.eq(self
.dec
.RC
)
365 with m
.Case(In3Sel
.RT
):
366 # for TII-form ternary
367 comb
+= reg
.data
.eq(self
.dec
.RT
)
373 class DecodeOut(Elaboratable
):
374 """DecodeOut from instruction
376 decodes output register RA, RT or SPR
379 def __init__(self
, dec
, op
, regreduce_en
):
380 self
.regreduce_en
= regreduce_en
381 if self
.regreduce_en
:
387 self
.sel_in
= Signal(OutSel
, reset_less
=True)
388 self
.insn_in
= Signal(32, reset_less
=True)
389 self
.reg_out
= Data(5, "reg_o")
390 self
.spr_out
= Data(SPR
, "spr_o")
391 self
.fast_out
= Data(3, "fast_o")
393 def elaborate(self
, platform
):
396 m
.submodules
.sprmap
= sprmap
= SPRMap(self
.regreduce_en
)
400 # select Register out field
401 with m
.Switch(self
.sel_in
):
402 with m
.Case(OutSel
.FRT
):
403 comb
+= reg
.data
.eq(self
.dec
.FRT
)
405 with m
.Case(OutSel
.RT
):
406 comb
+= reg
.data
.eq(self
.dec
.RT
)
408 with m
.Case(OutSel
.RA
):
409 comb
+= reg
.data
.eq(self
.dec
.RA
)
411 with m
.Case(OutSel
.SPR
):
412 spr
= Signal(10, reset_less
=True)
413 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
414 # MFSPR move to SPRs - needs mapping
415 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
416 comb
+= sprmap
.spr_i
.eq(spr
)
417 comb
+= self
.spr_out
.eq(sprmap
.spr_o
)
418 comb
+= self
.fast_out
.eq(sprmap
.fast_o
)
421 with m
.Switch(op
.internal_op
):
423 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeA
424 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_BCREG
):
425 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
427 comb
+= self
.fast_out
.data
.eq(FastRegsEnum
.CTR
)
428 comb
+= self
.fast_out
.ok
.eq(1)
430 # RFID 1st spr (fast)
431 with m
.Case(MicrOp
.OP_RFID
):
432 comb
+= self
.fast_out
.data
.eq(FastRegsEnum
.SRR0
) # SRR0
433 comb
+= self
.fast_out
.ok
.eq(1)
438 class DecodeOut2(Elaboratable
):
439 """DecodeOut2 from instruction
441 decodes output registers (2nd one). note that RA is *implicit* below,
442 which now causes problems with SVP64
444 TODO: SVP64 is a little more complex, here. svp64 allows extending
445 by one more destination by having one more EXTRA field. RA-as-src
446 is not the same as RA-as-dest. limited in that it's the same first
447 5 bits (from the v3.0B opcode), but still kinda cool. mostly used
448 for operations that have src-as-dest: mostly this is LD/ST-with-update
449 but there are others.
452 def __init__(self
, dec
, op
):
455 self
.sel_in
= Signal(OutSel
, reset_less
=True)
456 self
.svp64_fft_mode
= Signal(reset_less
=True) # SVP64 FFT mode
457 self
.lk
= Signal(reset_less
=True)
458 self
.insn_in
= Signal(32, reset_less
=True)
459 self
.reg_out
= Data(5, "reg_o2")
460 self
.fp_madd_en
= Signal(reset_less
=True) # FFT instruction detected
461 self
.fast_out
= Data(3, "fast_o2")
462 self
.fast_out3
= Data(3, "fast_o3")
464 def elaborate(self
, platform
):
468 #m.submodules.svdec = svdec = SVP64RegExtra()
470 # get the 5-bit reg data before svp64-munging it into 7-bit plus isvec
471 #reg = Signal(5, reset_less=True)
473 if hasattr(op
, "upd"):
474 # update mode LD/ST uses read-reg A also as an output
475 with m
.If(op
.upd
== LDSTMode
.update
):
476 comb
+= self
.reg_out
.data
.eq(self
.dec
.RA
)
477 comb
+= self
.reg_out
.ok
.eq(1)
479 # B, BC or BCREG: potential implicit register (LR) output
480 # these give bl, bcl, bclrl, etc.
481 with m
.Switch(op
.internal_op
):
483 # BC* implicit register (LR)
484 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_B
, MicrOp
.OP_BCREG
):
485 with m
.If(self
.lk
): # "link" mode
486 comb
+= self
.fast_out
.data
.eq(FastRegsEnum
.LR
) # LR
487 comb
+= self
.fast_out
.ok
.eq(1)
489 # RFID 2nd and 3rd spr (fast)
490 with m
.Case(MicrOp
.OP_RFID
):
491 comb
+= self
.fast_out
.data
.eq(FastRegsEnum
.SRR1
) # SRR1
492 comb
+= self
.fast_out
.ok
.eq(1)
493 comb
+= self
.fast_out3
.data
.eq(FastRegsEnum
.SVSRR0
) # SVSRR0
494 comb
+= self
.fast_out3
.ok
.eq(1)
496 # SVP64 FFT mode, FP mul-add: 2nd output reg (FRS) same as FRT
497 # will be offset by VL in hardware
498 #with m.Case(MicrOp.OP_FP_MADD):
499 with m
.If(self
.svp64_fft_mode
):
500 comb
+= self
.reg_out
.data
.eq(self
.dec
.FRT
)
501 comb
+= self
.reg_out
.ok
.eq(1)
502 comb
+= self
.fp_madd_en
.eq(1)
507 class DecodeRC(Elaboratable
):
508 """DecodeRc from instruction
510 decodes Record bit Rc
513 def __init__(self
, dec
):
515 self
.sel_in
= Signal(RC
, reset_less
=True)
516 self
.insn_in
= Signal(32, reset_less
=True)
517 self
.rc_out
= Data(1, "rc")
519 def elaborate(self
, platform
):
523 # select Record bit out field
524 with m
.Switch(self
.sel_in
):
526 comb
+= self
.rc_out
.data
.eq(self
.dec
.Rc
)
527 comb
+= self
.rc_out
.ok
.eq(1)
529 comb
+= self
.rc_out
.data
.eq(1)
530 comb
+= self
.rc_out
.ok
.eq(1)
531 with m
.Case(RC
.NONE
):
532 comb
+= self
.rc_out
.data
.eq(0)
533 comb
+= self
.rc_out
.ok
.eq(1)
538 class DecodeOE(Elaboratable
):
539 """DecodeOE from instruction
541 decodes OE field: uses RC decode detection which might not be good
543 -- For now, use "rc" in the decode table to decide whether oe exists.
544 -- This is not entirely correct architecturally: For mulhd and
545 -- mulhdu, the OE field is reserved. It remains to be seen what an
546 -- actual POWER9 does if we set it on those instructions, for now we
547 -- test that further down when assigning to the multiplier oe input.
550 def __init__(self
, dec
, op
):
553 self
.sel_in
= Signal(RC
, reset_less
=True)
554 self
.insn_in
= Signal(32, reset_less
=True)
555 self
.oe_out
= Data(1, "oe")
557 def elaborate(self
, platform
):
562 with m
.Switch(op
.internal_op
):
564 # mulhw, mulhwu, mulhd, mulhdu - these *ignore* OE
566 # XXX ARGH! ignoring OE causes incompatibility with microwatt
567 # http://lists.libre-soc.org/pipermail/libre-soc-dev/2020-August/000302.html
568 with m
.Case(MicrOp
.OP_MUL_H64
, MicrOp
.OP_MUL_H32
,
569 MicrOp
.OP_EXTS
, MicrOp
.OP_CNTZ
,
570 MicrOp
.OP_SHL
, MicrOp
.OP_SHR
, MicrOp
.OP_RLC
,
571 MicrOp
.OP_LOAD
, MicrOp
.OP_STORE
,
572 MicrOp
.OP_RLCL
, MicrOp
.OP_RLCR
,
576 # all other ops decode OE field
578 # select OE bit out field
579 with m
.Switch(self
.sel_in
):
581 comb
+= self
.oe_out
.data
.eq(self
.dec
.OE
)
582 comb
+= self
.oe_out
.ok
.eq(1)
587 class DecodeCRIn(Elaboratable
):
588 """Decodes input CR from instruction
590 CR indices - insn fields - (not the data *in* the CR) require only 3
591 bits because they refer to CR0-CR7
594 def __init__(self
, dec
, op
):
597 self
.sel_in
= Signal(CRInSel
, reset_less
=True)
598 self
.insn_in
= Signal(32, reset_less
=True)
599 self
.cr_bitfield
= Data(3, "cr_bitfield")
600 self
.cr_bitfield_b
= Data(3, "cr_bitfield_b")
601 self
.cr_bitfield_o
= Data(3, "cr_bitfield_o")
602 self
.whole_reg
= Data(8, "cr_fxm")
603 self
.sv_override
= Signal(2, reset_less
=True) # do not do EXTRA spec
605 def elaborate(self
, platform
):
609 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
612 # zero-initialisation
613 comb
+= self
.cr_bitfield
.ok
.eq(0)
614 comb
+= self
.cr_bitfield_b
.ok
.eq(0)
615 comb
+= self
.cr_bitfield_o
.ok
.eq(0)
616 comb
+= self
.whole_reg
.ok
.eq(0)
617 comb
+= self
.sv_override
.eq(0)
619 # select the relevant CR bitfields
620 with m
.Switch(self
.sel_in
):
621 with m
.Case(CRInSel
.NONE
):
622 pass # No bitfield activated
623 with m
.Case(CRInSel
.CR0
):
624 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
625 comb
+= self
.cr_bitfield
.ok
.eq(1)
626 comb
+= self
.sv_override
.eq(1)
627 with m
.Case(CRInSel
.CR1
):
628 comb
+= self
.cr_bitfield
.data
.eq(1) # CR1 (MSB0 numbering)
629 comb
+= self
.cr_bitfield
.ok
.eq(1)
630 comb
+= self
.sv_override
.eq(2)
631 with m
.Case(CRInSel
.BI
):
632 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BI
[2:5])
633 comb
+= self
.cr_bitfield
.ok
.eq(1)
634 with m
.Case(CRInSel
.BFA
):
635 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BFA
)
636 comb
+= self
.cr_bitfield
.ok
.eq(1)
637 with m
.Case(CRInSel
.BA_BB
):
638 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BA
[2:5])
639 comb
+= self
.cr_bitfield
.ok
.eq(1)
640 comb
+= self
.cr_bitfield_b
.data
.eq(self
.dec
.BB
[2:5])
641 comb
+= self
.cr_bitfield_b
.ok
.eq(1)
642 comb
+= self
.cr_bitfield_o
.data
.eq(self
.dec
.BT
[2:5])
643 comb
+= self
.cr_bitfield_o
.ok
.eq(1)
644 with m
.Case(CRInSel
.BC
):
645 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BC
[2:5])
646 comb
+= self
.cr_bitfield
.ok
.eq(1)
647 with m
.Case(CRInSel
.WHOLE_REG
):
648 comb
+= self
.whole_reg
.ok
.eq(1)
649 move_one
= Signal(reset_less
=True)
650 comb
+= move_one
.eq(self
.insn_in
[20]) # MSB0 bit 11
651 with m
.If((op
.internal_op
== MicrOp
.OP_MFCR
) & move_one
):
652 # must one-hot the FXM field
653 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
654 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
656 # otherwise use all of it
657 comb
+= self
.whole_reg
.data
.eq(0xff)
662 class DecodeCROut(Elaboratable
):
663 """Decodes input CR from instruction
665 CR indices - insn fields - (not the data *in* the CR) require only 3
666 bits because they refer to CR0-CR7
669 def __init__(self
, dec
, op
):
672 self
.rc_in
= Signal(reset_less
=True)
673 self
.sel_in
= Signal(CROutSel
, reset_less
=True)
674 self
.insn_in
= Signal(32, reset_less
=True)
675 self
.cr_bitfield
= Data(3, "cr_bitfield")
676 self
.whole_reg
= Data(8, "cr_fxm")
677 self
.sv_override
= Signal(2, reset_less
=True) # do not do EXTRA spec
679 def elaborate(self
, platform
):
683 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
686 comb
+= self
.cr_bitfield
.ok
.eq(0)
687 comb
+= self
.whole_reg
.ok
.eq(0)
688 comb
+= self
.sv_override
.eq(0)
690 # please note these MUST match (setting of cr_bitfield.ok) exactly
691 # with write_cr0 below in PowerDecoder2. the reason it's separated
692 # is to avoid having duplicate copies of DecodeCROut in multiple
693 # PowerDecoderSubsets. register decoding should be a one-off in
694 # PowerDecoder2. see https://bugs.libre-soc.org/show_bug.cgi?id=606
696 with m
.Switch(self
.sel_in
):
697 with m
.Case(CROutSel
.NONE
):
698 pass # No bitfield activated
699 with m
.Case(CROutSel
.CR0
):
700 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
701 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
702 comb
+= self
.sv_override
.eq(1)
703 with m
.Case(CROutSel
.CR1
):
704 comb
+= self
.cr_bitfield
.data
.eq(1) # CR1 (MSB0 numbering)
705 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
706 comb
+= self
.sv_override
.eq(2)
707 with m
.Case(CROutSel
.BF
):
708 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BF
)
709 comb
+= self
.cr_bitfield
.ok
.eq(1)
710 with m
.Case(CROutSel
.BT
):
711 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormXL
.BT
[2:5])
712 comb
+= self
.cr_bitfield
.ok
.eq(1)
713 with m
.Case(CROutSel
.WHOLE_REG
):
714 comb
+= self
.whole_reg
.ok
.eq(1)
715 move_one
= Signal(reset_less
=True)
716 comb
+= move_one
.eq(self
.insn_in
[20])
717 with m
.If((op
.internal_op
== MicrOp
.OP_MTCRF
)):
719 # must one-hot the FXM field
720 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
721 with m
.If(ppick
.en_o
):
722 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
724 comb
+= self
.whole_reg
.data
.eq(0b00000001) # CR7
726 comb
+= self
.whole_reg
.data
.eq(self
.dec
.FXM
)
728 # otherwise use all of it
729 comb
+= self
.whole_reg
.data
.eq(0xff)
733 # dictionary of Input Record field names that, if they exist,
734 # will need a corresponding CSV Decoder file column (actually, PowerOp)
735 # to be decoded (this includes the single bit names)
736 record_names
= {'insn_type': 'internal_op',
737 'fn_unit': 'function_unit',
738 'SV_Ptype': 'SV_Ptype',
742 'imm_data': 'in2_sel',
743 'invert_in': 'inv_a',
744 'invert_out': 'inv_out',
747 'output_carry': 'cry_out',
748 'input_carry': 'cry_in',
749 'is_32bit': 'is_32b',
752 'data_len': 'ldst_len',
753 'byte_reverse': 'br',
754 'sign_extend': 'sgn_ext',
759 class PowerDecodeSubset(Elaboratable
):
760 """PowerDecodeSubset: dynamic subset decoder
762 only fields actually requested are copied over. hence, "subset" (duh).
764 def __init__(self
, dec
, opkls
=None, fn_name
=None, final
=False, state
=None,
765 svp64_en
=True, regreduce_en
=False):
767 self
.svp64_en
= svp64_en
768 self
.regreduce_en
= regreduce_en
770 self
.is_svp64_mode
= Signal() # mark decoding as SVP64 Mode
771 self
.use_svp64_ldst_dec
= Signal() # must use LDST decoder
772 self
.use_svp64_fft
= Signal() # FFT Mode
773 self
.sv_rm
= SVP64Rec(name
="dec_svp64") # SVP64 RM field
774 self
.rm_dec
= SVP64RMModeDecode("svp64_rm_dec")
775 # set these to the predicate mask bits needed for the ALU
776 self
.pred_sm
= Signal() # TODO expand to SIMD mask width
777 self
.pred_dm
= Signal() # TODO expand to SIMD mask width
778 self
.sv_a_nz
= Signal(1)
781 self
.fn_name
= fn_name
783 opkls
= Decode2ToOperand
784 self
.do
= opkls(fn_name
)
786 col_subset
= self
.get_col_subset(self
.do
)
787 row_subset
= self
.rowsubsetfn
792 # "conditions" for Decoders, to enable some weird and wonderful
793 # alternatives. useful for PCR (Program Compatibility Register)
794 # amongst other things
796 conditions
= {'SVP64BREV': self
.use_svp64_ldst_dec
,
797 'SVP64FFT': self
.use_svp64_fft
,
802 # only needed for "main" PowerDecode2
804 self
.e
= Decode2ToExecute1Type(name
=self
.fn_name
, do
=self
.do
,
805 regreduce_en
=regreduce_en
)
807 # create decoder if one not already given
809 dec
= create_pdecode(name
=fn_name
, col_subset
=col_subset
,
810 row_subset
=row_subset
,
811 conditions
=conditions
)
814 # set up a copy of the PowerOp
815 self
.op
= PowerOp
.like(self
.dec
.op
)
817 # state information needed by the Decoder
819 state
= CoreState("dec2")
822 def get_col_subset(self
, do
):
823 subset
= { 'cr_in', 'cr_out', 'rc_sel'} # needed, non-optional
824 for k
, v
in record_names
.items():
827 log ("get_col_subset", self
.fn_name
, do
.fields
, subset
)
830 def rowsubsetfn(self
, opcode
, row
):
831 """select per-Function-Unit subset of opcodes to be processed
833 normally this just looks at the "unit" column. MMU is different
834 in that it processes specific SPR set/get operations that the SPR
837 return (row
['unit'] == self
.fn_name
or
838 # sigh a dreadful hack: MTSPR and MFSPR need to be processed
839 # by the MMU pipeline so we direct those opcodes to MMU **AND**
840 # SPR pipelines, then selectively weed out the SPRs that should
841 # or should not not go to each pipeline, further down.
842 # really this should be done by modifying the CSV syntax
843 # to support multiple tasks (unit column multiple entries)
844 # see https://bugs.libre-soc.org/show_bug.cgi?id=310
845 (self
.fn_name
== 'MMU' and row
['unit'] == 'SPR' and
846 row
['internal op'] in ['OP_MTSPR', 'OP_MFSPR'])
850 ports
= self
.dec
.ports() + self
.e
.ports()
852 ports
+= self
.sv_rm
.ports()
853 ports
.append(self
.is_svp64_mode
)
854 ports
.append(self
.use_svp64_ldst_dec
)
855 ports
.append(self
.use_svp64_fft
)
858 def needs_field(self
, field
, op_field
):
863 return hasattr(do
, field
) and self
.op_get(op_field
) is not None
865 def do_get(self
, field
, final
=False):
866 if final
or self
.final
:
870 return getattr(do
, field
, None)
872 def do_copy(self
, field
, val
, final
=False):
873 df
= self
.do_get(field
, final
)
874 if df
is not None and val
is not None:
878 def op_get(self
, op_field
):
879 return getattr(self
.op
, op_field
, None)
881 def elaborate(self
, platform
):
882 if self
.regreduce_en
:
889 op
, do
= self
.dec
.op
, self
.do
890 msr
, cia
, svstate
= state
.msr
, state
.pc
, state
.svstate
891 # fill in for a normal instruction (not an exception)
892 # copy over if non-exception, non-privileged etc. is detected
894 if self
.fn_name
is None:
897 name
= self
.fn_name
+ "tmp"
898 self
.e_tmp
= Decode2ToExecute1Type(name
=name
, opkls
=self
.opkls
,
899 regreduce_en
=self
.regreduce_en
)
901 # set up submodule decoders
902 m
.submodules
.dec
= dec
= self
.dec
903 m
.submodules
.dec_rc
= self
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
904 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
, op
)
907 # and SVP64 RM mode decoder
908 m
.submodules
.sv_rm_dec
= rm_dec
= self
.rm_dec
910 # copy op from decoder
911 comb
+= self
.op
.eq(self
.dec
.op
)
913 # copy instruction through...
914 for i
in [do
.insn
, dec_rc
.insn_in
, dec_oe
.insn_in
, ]:
915 comb
+= i
.eq(self
.dec
.opcode_in
)
917 # ...and subdecoders' input fields
918 comb
+= dec_rc
.sel_in
.eq(self
.op_get("rc_sel"))
919 comb
+= dec_oe
.sel_in
.eq(self
.op_get("rc_sel")) # XXX should be OE sel
922 comb
+= self
.do_copy("msr", msr
)
923 comb
+= self
.do_copy("cia", cia
)
924 comb
+= self
.do_copy("svstate", svstate
)
926 # set up instruction type
927 # no op: defaults to OP_ILLEGAL
928 internal_op
= self
.op_get("internal_op")
929 comb
+= self
.do_copy("insn_type", internal_op
)
931 # function unit for decoded instruction: requires minor redirect
933 fn
= self
.op_get("function_unit")
934 spr
= Signal(10, reset_less
=True)
935 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
937 # Microwatt doesn't implement the partition table
938 # instead has PRTBL register (SPR) to point to process table
940 is_mmu_spr
= Signal()
941 comb
+= is_spr_mv
.eq((internal_op
== MicrOp
.OP_MTSPR
) |
942 (internal_op
== MicrOp
.OP_MFSPR
))
943 comb
+= is_mmu_spr
.eq((spr
== SPR
.DSISR
.value
) |
944 (spr
== SPR
.DAR
.value
) |
945 (spr
== SPR
.PRTBL
.value
) |
946 (spr
== SPR
.PIDR
.value
))
947 # MMU must receive MMU SPRs
948 with m
.If(is_spr_mv
& (fn
== Function
.SPR
) & is_mmu_spr
):
949 comb
+= self
.do_copy("fn_unit", Function
.MMU
)
950 comb
+= self
.do_copy("insn_type", internal_op
)
951 # SPR pipe must *not* receive MMU SPRs
952 with m
.Elif(is_spr_mv
& (fn
== Function
.MMU
) & ~is_mmu_spr
):
953 comb
+= self
.do_copy("fn_unit", Function
.NONE
)
954 comb
+= self
.do_copy("insn_type", MicrOp
.OP_ILLEGAL
)
957 comb
+= self
.do_copy("fn_unit", fn
)
960 if self
.needs_field("zero_a", "in1_sel"):
961 m
.submodules
.dec_ai
= dec_ai
= DecodeAImm(self
.dec
)
962 comb
+= dec_ai
.sv_nz
.eq(self
.sv_a_nz
)
963 comb
+= dec_ai
.sel_in
.eq(self
.op_get("in1_sel"))
964 comb
+= self
.do_copy("zero_a", dec_ai
.immz_out
) # RA==0 detected
965 if self
.needs_field("imm_data", "in2_sel"):
966 m
.submodules
.dec_bi
= dec_bi
= DecodeBImm(self
.dec
)
967 comb
+= dec_bi
.sel_in
.eq(self
.op_get("in2_sel"))
968 comb
+= self
.do_copy("imm_data", dec_bi
.imm_out
) # imm in RB
971 comb
+= self
.do_copy("rc", dec_rc
.rc_out
)
973 # OE only enabled when SVP64 not active
974 with m
.If(~self
.is_svp64_mode
):
975 comb
+= self
.do_copy("oe", dec_oe
.oe_out
)
977 comb
+= self
.do_copy("oe", dec_oe
.oe_out
)
979 # CR in/out - note: these MUST match with what happens in
981 rc_out
= self
.dec_rc
.rc_out
.data
982 with m
.Switch(self
.op_get("cr_out")):
983 with m
.Case(CROutSel
.CR0
, CROutSel
.CR1
):
984 comb
+= self
.do_copy("write_cr0", rc_out
) # only when RC=1
985 with m
.Case(CROutSel
.BF
, CROutSel
.BT
):
986 comb
+= self
.do_copy("write_cr0", 1)
988 comb
+= self
.do_copy("input_cr", self
.op_get("cr_in")) # CR in
989 comb
+= self
.do_copy("output_cr", self
.op_get("cr_out")) # CR out
992 # connect up SVP64 RM Mode decoding. however... we need a shorter
993 # path, for the LDST bit-reverse detection. so perform partial
994 # decode when SVP64 is detected. then, bit-reverse mode can be
995 # quickly determined, and the Decoder result MUXed over to
996 # the alternative decoder, svdecldst. what a mess... *sigh*
997 sv_ptype
= self
.op_get("SV_Ptype")
998 fn
= self
.op_get("function_unit")
999 # detect major opcode for LDs: include 58 here. from CSV files.
1000 # BLECH! TODO: these should be done using "mini decoders",
1001 # using row and column subsets
1002 is_major_ld
= Signal()
1003 major
= Signal(6) # bits... errr... MSB0 0..5 which is 26:32 python
1004 comb
+= major
.eq(self
.dec
.opcode_in
[26:32])
1005 comb
+= is_major_ld
.eq((major
== 34) |
(major
== 35) |
1006 (major
== 50) |
(major
== 51) |
1007 (major
== 48) |
(major
== 49) |
1008 (major
== 42) |
(major
== 43) |
1009 (major
== 40) |
(major
== 41) |
1010 (major
== 32) |
(major
== 33) |
1012 with m
.If(self
.is_svp64_mode
& is_major_ld
):
1013 # straight-up: "it's a LD". this gives enough info
1014 # for SVP64 RM Mode decoding to detect LD/ST, and
1015 # consequently detect the SHIFT mode. sigh
1016 comb
+= rm_dec
.fn_in
.eq(Function
.LDST
)
1018 comb
+= rm_dec
.fn_in
.eq(fn
) # decode needs to know Fn type
1019 comb
+= rm_dec
.ptype_in
.eq(sv_ptype
) # Single/Twin predicated
1020 comb
+= rm_dec
.rc_in
.eq(rc_out
) # Rc=1
1021 comb
+= rm_dec
.rm_in
.eq(self
.sv_rm
) # SVP64 RM mode
1022 if self
.needs_field("imm_data", "in2_sel"):
1023 bzero
= dec_bi
.imm_out
.ok
& ~dec_bi
.imm_out
.data
.bool()
1024 comb
+= rm_dec
.ldst_imz_in
.eq(bzero
) # B immediate is zero
1026 # main PowerDecoder2 determines if different SVP64 modes enabled
1028 # if shift mode requested
1029 shiftmode
= rm_dec
.ldstmode
== SVP64LDSTmode
.SHIFT
1030 comb
+= self
.use_svp64_ldst_dec
.eq(shiftmode
)
1031 # detect if SVP64 FFT mode enabled (really bad hack),
1032 # exclude fcfids and others
1033 # XXX this is a REALLY bad hack, REALLY has to be done better.
1034 # likely with a sub-decoder.
1035 xo5
= Signal(1) # 1 bit from Minor 59 XO field == 0b0XXXX
1036 comb
+= xo5
.eq(self
.dec
.opcode_in
[5])
1037 xo
= Signal(5) # 5 bits from Minor 59 fcfids == 0b01110
1038 comb
+= xo
.eq(self
.dec
.opcode_in
[1:6])
1039 comb
+= self
.use_svp64_fft
.eq((major
== 59) & (xo5
== 0b0) &
1042 # decoded/selected instruction flags
1043 comb
+= self
.do_copy("data_len", self
.op_get("ldst_len"))
1044 comb
+= self
.do_copy("invert_in", self
.op_get("inv_a"))
1045 comb
+= self
.do_copy("invert_out", self
.op_get("inv_out"))
1046 comb
+= self
.do_copy("input_carry", self
.op_get("cry_in"))
1047 comb
+= self
.do_copy("output_carry", self
.op_get("cry_out"))
1048 comb
+= self
.do_copy("is_32bit", self
.op_get("is_32b"))
1049 comb
+= self
.do_copy("is_signed", self
.op_get("sgn"))
1050 lk
= self
.op_get("lk")
1053 comb
+= self
.do_copy("lk", self
.dec
.LK
) # XXX TODO: accessor
1055 comb
+= self
.do_copy("byte_reverse", self
.op_get("br"))
1056 comb
+= self
.do_copy("sign_extend", self
.op_get("sgn_ext"))
1057 comb
+= self
.do_copy("ldst_mode", self
.op_get("upd")) # LD/ST mode
1059 # copy over SVP64 input record fields (if they exist)
1061 # TODO, really do we have to do these explicitly?? sigh
1062 #for (field, _) in sv_input_record_layout:
1063 # comb += self.do_copy(field, self.rm_dec.op_get(field))
1064 comb
+= self
.do_copy("sv_saturate", self
.rm_dec
.saturate
)
1065 comb
+= self
.do_copy("sv_Ptype", self
.rm_dec
.ptype_in
)
1066 comb
+= self
.do_copy("sv_ldstmode", self
.rm_dec
.ldstmode
)
1067 # these get set up based on incoming mask bits. TODO:
1068 # pass in multiple bits (later, when SIMD backends are enabled)
1069 with m
.If(self
.rm_dec
.pred_sz
):
1070 comb
+= self
.do_copy("sv_pred_sz", ~self
.pred_sm
)
1071 with m
.If(self
.rm_dec
.pred_dz
):
1072 comb
+= self
.do_copy("sv_pred_dz", ~self
.pred_dm
)
1077 class PowerDecode2(PowerDecodeSubset
):
1078 """PowerDecode2: the main instruction decoder.
1080 whilst PowerDecode is responsible for decoding the actual opcode, this
1081 module encapsulates further specialist, sparse information and
1082 expansion of fields that is inconvenient to have in the CSV files.
1083 for example: the encoding of the immediates, which are detected
1084 and expanded out to their full value from an annotated (enum)
1087 implicit register usage is also set up, here. for example: OP_BC
1088 requires implicitly reading CTR, OP_RFID requires implicitly writing
1091 in addition, PowerDecoder2 is responsible for detecting whether
1092 instructions are illegal (or privileged) or not, and instead of
1093 just leaving at that, *replacing* the instruction to execute with
1094 a suitable alternative (trap).
1096 LDSTExceptions are done the cycle _after_ they're detected (after
1097 they come out of LDSTCompUnit). basically despite the instruction
1098 being decoded, the results of the decode are completely ignored
1099 and "exception.happened" used to set the "actual" instruction to
1100 "OP_TRAP". the LDSTException data structure gets filled in,
1101 in the CompTrapOpSubset and that's what it fills in SRR.
1103 to make this work, TestIssuer must notice "exception.happened"
1104 after the (failed) LD/ST and copies the LDSTException info from
1105 the output, into here (PowerDecoder2). without incrementing PC.
1108 def __init__(self
, dec
, opkls
=None, fn_name
=None, final
=False,
1109 state
=None, svp64_en
=True, regreduce_en
=False):
1110 super().__init
__(dec
, opkls
, fn_name
, final
, state
, svp64_en
,
1112 self
.ldst_exc
= LDSTException("dec2_exc")
1115 self
.cr_out_isvec
= Signal(1, name
="cr_out_isvec")
1116 self
.cr_in_isvec
= Signal(1, name
="cr_in_isvec")
1117 self
.cr_in_b_isvec
= Signal(1, name
="cr_in_b_isvec")
1118 self
.cr_in_o_isvec
= Signal(1, name
="cr_in_o_isvec")
1119 self
.in1_isvec
= Signal(1, name
="reg_a_isvec")
1120 self
.in2_isvec
= Signal(1, name
="reg_b_isvec")
1121 self
.in3_isvec
= Signal(1, name
="reg_c_isvec")
1122 self
.o_isvec
= Signal(7, name
="reg_o_isvec")
1123 self
.o2_isvec
= Signal(7, name
="reg_o2_isvec")
1124 self
.in1_step
= Signal(7, name
="reg_a_step")
1125 self
.in2_step
= Signal(7, name
="reg_b_step")
1126 self
.in3_step
= Signal(7, name
="reg_c_step")
1127 self
.o_step
= Signal(7, name
="reg_o_step")
1128 self
.o2_step
= Signal(7, name
="reg_o2_step")
1129 self
.remap_active
= Signal(5, name
="remap_active") # per reg
1130 self
.no_in_vec
= Signal(1, name
="no_in_vec") # no inputs vector
1131 self
.no_out_vec
= Signal(1, name
="no_out_vec") # no outputs vector
1132 self
.loop_continue
= Signal(1, name
="loop_continue")
1134 self
.no_in_vec
= Const(1, 1)
1135 self
.no_out_vec
= Const(1, 1)
1136 self
.loop_continue
= Const(0, 1)
1138 def get_col_subset(self
, opkls
):
1139 subset
= super().get_col_subset(opkls
)
1140 subset
.add("asmcode")
1141 subset
.add("in1_sel")
1142 subset
.add("in2_sel")
1143 subset
.add("in3_sel")
1144 subset
.add("out_sel")
1146 subset
.add("sv_in1")
1147 subset
.add("sv_in2")
1148 subset
.add("sv_in3")
1149 subset
.add("sv_out")
1150 subset
.add("sv_out2")
1151 subset
.add("sv_cr_in")
1152 subset
.add("sv_cr_out")
1153 subset
.add("SV_Etype")
1154 subset
.add("SV_Ptype")
1155 # from SVP64RMModeDecode
1156 for (field
, _
) in sv_input_record_layout
:
1159 subset
.add("internal_op")
1163 def elaborate(self
, platform
):
1164 m
= super().elaborate(platform
)
1167 op
, e_out
, do_out
= self
.op
, self
.e
, self
.e
.do
1168 dec_spr
, msr
, cia
, ext_irq
= state
.dec
, state
.msr
, state
.pc
, state
.eint
1169 rc_out
= self
.dec_rc
.rc_out
.data
1173 # fill in for a normal instruction (not an exception)
1174 # copy over if non-exception, non-privileged etc. is detected
1176 # set up submodule decoders
1177 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
, op
, self
.regreduce_en
)
1178 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
, op
)
1179 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
, op
)
1180 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
, op
, self
.regreduce_en
)
1181 m
.submodules
.dec_o2
= dec_o2
= DecodeOut2(self
.dec
, op
)
1182 m
.submodules
.dec_cr_in
= self
.dec_cr_in
= DecodeCRIn(self
.dec
, op
)
1183 m
.submodules
.dec_cr_out
= self
.dec_cr_out
= DecodeCROut(self
.dec
, op
)
1184 comb
+= dec_a
.sv_nz
.eq(self
.sv_a_nz
)
1187 # and SVP64 Extra decoders
1188 m
.submodules
.crout_svdec
= crout_svdec
= SVP64CRExtra()
1189 m
.submodules
.crin_svdec
= crin_svdec
= SVP64CRExtra()
1190 m
.submodules
.crin_svdec_b
= crin_svdec_b
= SVP64CRExtra()
1191 m
.submodules
.crin_svdec_o
= crin_svdec_o
= SVP64CRExtra()
1192 m
.submodules
.in1_svdec
= in1_svdec
= SVP64RegExtra()
1193 m
.submodules
.in2_svdec
= in2_svdec
= SVP64RegExtra()
1194 m
.submodules
.in3_svdec
= in3_svdec
= SVP64RegExtra()
1195 m
.submodules
.o_svdec
= o_svdec
= SVP64RegExtra()
1196 m
.submodules
.o2_svdec
= o2_svdec
= SVP64RegExtra()
1198 # debug access to cr svdec (used in get_pdecode_cr_in/out)
1199 self
.crout_svdec
= crout_svdec
1200 self
.crin_svdec
= crin_svdec
1202 # get the 5-bit reg data before svp64-munging it into 7-bit plus isvec
1203 reg
= Signal(5, reset_less
=True)
1205 # copy instruction through...
1206 for i
in [do
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
1207 self
.dec_cr_in
.insn_in
, self
.dec_cr_out
.insn_in
,
1208 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
]:
1209 comb
+= i
.eq(self
.dec
.opcode_in
)
1212 comb
+= self
.dec_cr_in
.sel_in
.eq(self
.op_get("cr_in"))
1213 comb
+= self
.dec_cr_out
.sel_in
.eq(self
.op_get("cr_out"))
1214 comb
+= self
.dec_cr_out
.rc_in
.eq(rc_out
)
1217 comb
+= self
.do_copy("read_cr_whole", self
.dec_cr_in
.whole_reg
)
1218 comb
+= self
.do_copy("write_cr_whole", self
.dec_cr_out
.whole_reg
)
1220 # ...and subdecoders' input fields
1221 comb
+= dec_a
.sel_in
.eq(self
.op_get("in1_sel"))
1222 comb
+= dec_b
.sel_in
.eq(self
.op_get("in2_sel"))
1223 comb
+= dec_c
.sel_in
.eq(self
.op_get("in3_sel"))
1224 comb
+= dec_o
.sel_in
.eq(self
.op_get("out_sel"))
1225 comb
+= dec_o2
.sel_in
.eq(self
.op_get("out_sel"))
1227 comb
+= dec_o2
.svp64_fft_mode
.eq(self
.use_svp64_fft
)
1228 if hasattr(do
, "lk"):
1229 comb
+= dec_o2
.lk
.eq(do
.lk
)
1232 # now do the SVP64 munging. op.SV_Etype and op.sv_in1 comes from
1233 # PowerDecoder which in turn comes from LDST-RM*.csv and RM-*.csv
1234 # which in turn were auto-generated by sv_analysis.py
1235 extra
= self
.sv_rm
.extra
# SVP64 extra bits 10:18
1239 comb
+= crout_svdec
.idx
.eq(self
.op_get("sv_cr_out")) # SVP64 CR out
1240 comb
+= self
.cr_out_isvec
.eq(crout_svdec
.isvec
)
1243 # CR in - selection slightly different due to shared CR field sigh
1244 cr_a_idx
= Signal(SVEXTRA
)
1245 cr_b_idx
= Signal(SVEXTRA
)
1247 # these change slightly, when decoding BA/BB. really should have
1248 # their own separate CSV column: sv_cr_in1 and sv_cr_in2, but hey
1249 comb
+= cr_a_idx
.eq(self
.op_get("sv_cr_in"))
1250 comb
+= cr_b_idx
.eq(SVEXTRA
.NONE
)
1251 with m
.If(self
.op_get("sv_cr_in") == SVEXTRA
.Idx_1_2
.value
):
1252 comb
+= cr_a_idx
.eq(SVEXTRA
.Idx1
)
1253 comb
+= cr_b_idx
.eq(SVEXTRA
.Idx2
)
1255 comb
+= self
.cr_in_isvec
.eq(crin_svdec
.isvec
)
1256 comb
+= self
.cr_in_b_isvec
.eq(crin_svdec_b
.isvec
)
1257 comb
+= self
.cr_in_o_isvec
.eq(crin_svdec_o
.isvec
)
1259 # indices are slightly different, BA/BB mess sorted above
1260 comb
+= crin_svdec
.idx
.eq(cr_a_idx
) # SVP64 CR in A
1261 comb
+= crin_svdec_b
.idx
.eq(cr_b_idx
) # SVP64 CR in B
1262 comb
+= crin_svdec_o
.idx
.eq(self
.op_get("sv_cr_out")) # SVP64 CR out
1264 # get SVSTATE srcstep (TODO: elwidth etc.) needed below
1265 vl
= Signal
.like(self
.state
.svstate
.vl
)
1266 srcstep
= Signal
.like(self
.state
.svstate
.srcstep
)
1267 dststep
= Signal
.like(self
.state
.svstate
.dststep
)
1268 comb
+= vl
.eq(self
.state
.svstate
.vl
)
1269 comb
+= srcstep
.eq(self
.state
.svstate
.srcstep
)
1270 comb
+= dststep
.eq(self
.state
.svstate
.dststep
)
1272 in1_step
, in2_step
= self
.in1_step
, self
.in2_step
1273 in3_step
= self
.in3_step
1274 o_step
, o2_step
= self
.o_step
, self
.o2_step
1276 # registers a, b, c and out and out2 (LD/ST EA)
1277 sv_etype
= self
.op_get("SV_Etype")
1278 for i
, stuff
in enumerate((
1279 ("RA", e
.read_reg1
, dec_a
.reg_out
, in1_svdec
, in1_step
, False),
1280 ("RB", e
.read_reg2
, dec_b
.reg_out
, in2_svdec
, in2_step
, False),
1281 ("RC", e
.read_reg3
, dec_c
.reg_out
, in3_svdec
, in3_step
, False),
1282 ("RT", e
.write_reg
, dec_o
.reg_out
, o_svdec
, o_step
, True),
1283 ("EA", e
.write_ea
, dec_o2
.reg_out
, o2_svdec
, o2_step
, True))):
1284 rname
, to_reg
, fromreg
, svdec
, remapstep
, out
= stuff
1285 comb
+= svdec
.extra
.eq(extra
) # EXTRA field of SVP64 RM
1286 comb
+= svdec
.etype
.eq(sv_etype
) # EXTRA2/3 for this insn
1287 comb
+= svdec
.reg_in
.eq(fromreg
.data
) # 3-bit (CR0/BC/BFA)
1288 comb
+= to_reg
.ok
.eq(fromreg
.ok
)
1289 # *screaam* FFT mode needs an extra offset for RB
1290 # similar to FRS/FRT (below). all of this needs cleanup
1291 offs
= Signal(7, name
="offs_"+rname
, reset_less
=True)
1294 # when FFT sv.ffmadd detected, and REMAP not in use,
1295 # automagically add on an extra offset to RB.
1296 # however when REMAP is active, the FFT REMAP
1297 # schedule takes care of this offset.
1298 with m
.If(dec_o2
.reg_out
.ok
& dec_o2
.fp_madd_en
):
1299 with m
.If(~self
.remap_active
[i
]):
1300 with m
.If(svdec
.isvec
):
1301 comb
+= offs
.eq(vl
) # VL for Vectors
1302 # detect if Vectorised: add srcstep/dststep if yes.
1303 # to_reg is 7-bits, outs get dststep added, ins get srcstep
1304 with m
.If(svdec
.isvec
):
1305 selectstep
= dststep
if out
else srcstep
1306 step
= Signal(7, name
="step_%s" % rname
.lower())
1307 with m
.If(self
.remap_active
[i
]):
1308 comb
+= step
.eq(remapstep
)
1310 comb
+= step
.eq(selectstep
)
1311 # reverse gear goes the opposite way
1312 with m
.If(self
.rm_dec
.reverse_gear
):
1313 comb
+= to_reg
.data
.eq(offs
+svdec
.reg_out
+(vl
-1-step
))
1315 comb
+= to_reg
.data
.eq(offs
+step
+svdec
.reg_out
)
1317 comb
+= to_reg
.data
.eq(offs
+svdec
.reg_out
)
1319 # SVP64 in/out fields
1320 comb
+= in1_svdec
.idx
.eq(self
.op_get("sv_in1")) # reg #1 (in1_sel)
1321 comb
+= in2_svdec
.idx
.eq(self
.op_get("sv_in2")) # reg #2 (in2_sel)
1322 comb
+= in3_svdec
.idx
.eq(self
.op_get("sv_in3")) # reg #3 (in3_sel)
1323 comb
+= o_svdec
.idx
.eq(self
.op_get("sv_out")) # output (out_sel)
1324 comb
+= o2_svdec
.idx
.eq(self
.op_get("sv_out2")) # output (implicit)
1325 # XXX TODO - work out where this should come from. the problem is
1326 # that LD-with-update is implied (computed from "is instruction in
1327 # "update mode" rather than specified cleanly as its own CSV column
1329 # output reg-is-vectorised (and when no in/out is vectorised)
1330 comb
+= self
.in1_isvec
.eq(in1_svdec
.isvec
)
1331 comb
+= self
.in2_isvec
.eq(in2_svdec
.isvec
)
1332 comb
+= self
.in3_isvec
.eq(in3_svdec
.isvec
)
1333 comb
+= self
.o_isvec
.eq(o_svdec
.isvec
)
1334 comb
+= self
.o2_isvec
.eq(o2_svdec
.isvec
)
1336 # urrr... don't ask... the implicit register FRS in FFT mode
1337 # "tracks" FRT exactly except it's offset by VL. rather than
1338 # mess up the above with if-statements, override it here.
1339 # same trick is applied to FRA, above, but it's a lot cleaner, there
1340 with m
.If(dec_o2
.reg_out
.ok
& dec_o2
.fp_madd_en
):
1342 with m
.If(~self
.remap_active
[4]):
1343 with m
.If(o2_svdec
.isvec
):
1344 comb
+= offs
.eq(vl
) # VL for Vectors
1346 comb
+= offs
.eq(1) # add 1 if scalar
1347 svdec
= o_svdec
# yes take source as o_svdec...
1348 with m
.If(svdec
.isvec
):
1349 step
= Signal(7, name
="step_%s" % rname
.lower())
1350 with m
.If(self
.remap_active
[4]):
1351 comb
+= step
.eq(o2_step
)
1353 comb
+= step
.eq(dststep
)
1354 # reverse gear goes the opposite way
1355 with m
.If(self
.rm_dec
.reverse_gear
):
1356 roffs
= offs
+(vl
-1-step
)
1357 comb
+= to_reg
.data
.eq(roffs
+svdec
.reg_out
)
1359 comb
+= to_reg
.data
.eq(offs
+step
+svdec
.reg_out
)
1361 comb
+= to_reg
.data
.eq(offs
+svdec
.reg_out
)
1362 # ... but write to *second* output
1363 comb
+= self
.o2_isvec
.eq(svdec
.isvec
)
1364 comb
+= o2_svdec
.idx
.eq(self
.op_get("sv_out"))
1366 # TODO add SPRs here. must be True when *all* are scalar
1367 l
= map(lambda svdec
: svdec
.isvec
, [in1_svdec
, in2_svdec
, in3_svdec
,
1368 crin_svdec
, crin_svdec_b
, crin_svdec_o
])
1369 comb
+= self
.no_in_vec
.eq(~
Cat(*l
).bool()) # all input scalar
1370 l
= map(lambda svdec
: svdec
.isvec
, [o2_svdec
, o_svdec
, crout_svdec
])
1371 # in mapreduce mode, scalar out is *allowed*
1372 with m
.If(self
.rm_dec
.mode
== SVP64RMMode
.MAPREDUCE
.value
):
1373 comb
+= self
.no_out_vec
.eq(0)
1375 comb
+= self
.no_out_vec
.eq(~
Cat(*l
).bool()) # all output scalar
1376 # now create a general-purpose "test" as to whether looping
1377 # should continue. this doesn't include predication bit-tests
1378 loop
= self
.loop_continue
1379 with m
.Switch(self
.op_get("SV_Ptype")):
1380 with m
.Case(SVPtype
.P2
.value
):
1382 # TODO: *and cache-inhibited LD/ST!*
1383 comb
+= loop
.eq(~
(self
.no_in_vec | self
.no_out_vec
))
1384 with m
.Case(SVPtype
.P1
.value
):
1385 # single-predication, test relies on dest only
1386 comb
+= loop
.eq(~self
.no_out_vec
)
1388 # not an SV operation, no looping
1391 # condition registers (CR)
1392 for to_reg
, cr
, name
, svdec
, out
in (
1393 (e
.read_cr1
, self
.dec_cr_in
, "cr_bitfield", crin_svdec
, 0),
1394 (e
.read_cr2
, self
.dec_cr_in
, "cr_bitfield_b", crin_svdec_b
, 0),
1395 (e
.read_cr3
, self
.dec_cr_in
, "cr_bitfield_o", crin_svdec_o
, 0),
1396 (e
.write_cr
, self
.dec_cr_out
, "cr_bitfield", crout_svdec
, 1)):
1397 fromreg
= getattr(cr
, name
)
1398 comb
+= svdec
.extra
.eq(extra
) # EXTRA field of SVP64 RM
1399 comb
+= svdec
.etype
.eq(sv_etype
) # EXTRA2/3 for this insn
1400 comb
+= svdec
.cr_in
.eq(fromreg
.data
) # 3-bit (CR0/BC/BFA)
1401 with m
.If(svdec
.isvec
):
1402 # check if this is CR0 or CR1: treated differently
1403 # (does not "listen" to EXTRA2/3 spec for a start)
1404 # also: the CRs start from completely different locations
1405 step
= dststep
if out
else srcstep
1406 with m
.If(cr
.sv_override
== 1): # CR0
1407 offs
= SVP64CROffs
.CR0
1408 comb
+= to_reg
.data
.eq(step
+offs
)
1409 with m
.Elif(cr
.sv_override
== 2): # CR1
1410 offs
= SVP64CROffs
.CR1
1411 comb
+= to_reg
.data
.eq(step
+1)
1413 comb
+= to_reg
.data
.eq(step
+svdec
.cr_out
) # 7-bit out
1415 comb
+= to_reg
.data
.eq(svdec
.cr_out
) # 7-bit output
1416 comb
+= to_reg
.ok
.eq(fromreg
.ok
)
1418 # sigh must determine if RA is nonzero (7 bit)
1419 comb
+= self
.sv_a_nz
.eq(e
.read_reg1
.data
!= Const(0, 7))
1421 # connect up to/from read/write GPRs
1422 for to_reg
, fromreg
in ((e
.read_reg1
, dec_a
.reg_out
),
1423 (e
.read_reg2
, dec_b
.reg_out
),
1424 (e
.read_reg3
, dec_c
.reg_out
),
1425 (e
.write_reg
, dec_o
.reg_out
),
1426 (e
.write_ea
, dec_o2
.reg_out
)):
1427 comb
+= to_reg
.data
.eq(fromreg
.data
)
1428 comb
+= to_reg
.ok
.eq(fromreg
.ok
)
1430 # connect up to/from read/write CRs
1431 for to_reg
, cr
, name
in (
1432 (e
.read_cr1
, self
.dec_cr_in
, "cr_bitfield", ),
1433 (e
.read_cr2
, self
.dec_cr_in
, "cr_bitfield_b", ),
1434 (e
.read_cr3
, self
.dec_cr_in
, "cr_bitfield_o", ),
1435 (e
.write_cr
, self
.dec_cr_out
, "cr_bitfield", )):
1436 fromreg
= getattr(cr
, name
)
1437 comb
+= to_reg
.data
.eq(fromreg
.data
)
1438 comb
+= to_reg
.ok
.eq(fromreg
.ok
)
1441 comb
+= self
.rm_dec
.ldst_ra_vec
.eq(self
.in1_isvec
) # RA is vector
1444 comb
+= e
.read_spr1
.eq(dec_a
.spr_out
)
1445 comb
+= e
.write_spr
.eq(dec_o
.spr_out
)
1447 # Fast regs out including SRR0/1/SVSRR0
1448 comb
+= e
.read_fast1
.eq(dec_a
.fast_out
)
1449 comb
+= e
.read_fast2
.eq(dec_b
.fast_out
)
1450 comb
+= e
.write_fast1
.eq(dec_o
.fast_out
) # SRR0 (OP_RFID)
1451 comb
+= e
.write_fast2
.eq(dec_o2
.fast_out
) # SRR1 (ditto)
1452 comb
+= e
.write_fast3
.eq(dec_o2
.fast_out3
) # SVSRR0 (ditto)
1454 # sigh this is exactly the sort of thing for which the
1455 # decoder is designed to not need. MTSPR, MFSPR and others need
1456 # access to the XER bits. however setting e.oe is not appropriate
1457 internal_op
= self
.op_get("internal_op")
1458 with m
.If(internal_op
== MicrOp
.OP_MFSPR
):
1459 comb
+= e
.xer_in
.eq(0b111) # SO, CA, OV
1460 with m
.If(internal_op
== MicrOp
.OP_CMP
):
1461 comb
+= e
.xer_in
.eq(1<<XERRegsEnum
.SO
) # SO
1462 with m
.If(internal_op
== MicrOp
.OP_MTSPR
):
1463 comb
+= e
.xer_out
.eq(1)
1465 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
1466 with m
.If(op
.internal_op
== MicrOp
.OP_TRAP
):
1467 # *DO NOT* call self.trap here. that would reset absolutely
1468 # everything including destroying read of RA and RB.
1469 comb
+= self
.do_copy("trapaddr", 0x70) # strip first nibble
1471 ####################
1472 # ok so the instruction's been decoded, blah blah, however
1473 # now we need to determine if it's actually going to go ahead...
1474 # *or* if in fact it's a privileged operation, whether there's
1475 # an external interrupt, etc. etc. this is a simple priority
1476 # if-elif-elif sequence. decrement takes highest priority,
1477 # EINT next highest, privileged operation third.
1479 # check if instruction is privileged
1480 is_priv_insn
= instr_is_priv(m
, op
.internal_op
, e
.do
.insn
)
1482 # different IRQ conditions
1483 ext_irq_ok
= Signal()
1484 dec_irq_ok
= Signal()
1487 ldst_exc
= self
.ldst_exc
1489 comb
+= ext_irq_ok
.eq(ext_irq
& msr
[MSR
.EE
]) # v3.0B p944 (MSR.EE)
1490 comb
+= dec_irq_ok
.eq(dec_spr
[63] & msr
[MSR
.EE
]) # 6.5.11 p1076
1491 comb
+= priv_ok
.eq(is_priv_insn
& msr
[MSR
.PR
])
1492 comb
+= illeg_ok
.eq(op
.internal_op
== MicrOp
.OP_ILLEGAL
)
1494 # LD/ST exceptions. TestIssuer copies the exception info at us
1495 # after a failed LD/ST.
1496 with m
.If(ldst_exc
.happened
):
1497 with m
.If(ldst_exc
.alignment
):
1498 self
.trap(m
, TT
.PRIV
, 0x600)
1499 with m
.Elif(ldst_exc
.instr_fault
):
1500 with m
.If(ldst_exc
.segment_fault
):
1501 self
.trap(m
, TT
.PRIV
, 0x480)
1503 # pass exception info to trap to create SRR1
1504 self
.trap(m
, TT
.MEMEXC
, 0x400, ldst_exc
)
1506 with m
.If(ldst_exc
.segment_fault
):
1507 self
.trap(m
, TT
.PRIV
, 0x380)
1509 self
.trap(m
, TT
.PRIV
, 0x300)
1511 # decrement counter (v3.0B p1099): TODO 32-bit version (MSR.LPCR)
1512 with m
.Elif(dec_irq_ok
):
1513 self
.trap(m
, TT
.DEC
, 0x900) # v3.0B 6.5 p1065
1515 # external interrupt? only if MSR.EE set
1516 with m
.Elif(ext_irq_ok
):
1517 self
.trap(m
, TT
.EINT
, 0x500)
1519 # privileged instruction trap
1520 with m
.Elif(priv_ok
):
1521 self
.trap(m
, TT
.PRIV
, 0x700)
1523 # illegal instruction must redirect to trap. this is done by
1524 # *overwriting* the decoded instruction and starting again.
1525 # (note: the same goes for interrupts and for privileged operations,
1526 # just with different trapaddr and traptype)
1527 with m
.Elif(illeg_ok
):
1528 # illegal instruction trap
1529 self
.trap(m
, TT
.ILLEG
, 0x700)
1531 # no exception, just copy things to the output
1535 ####################
1536 # follow-up after trap/irq to set up SRR0/1
1538 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
1539 # Note: OP_SC could actually be modified to just be a trap
1540 with m
.If((do_out
.insn_type
== MicrOp
.OP_TRAP
) |
1541 (do_out
.insn_type
== MicrOp
.OP_SC
)):
1542 # TRAP write fast1 = SRR0
1543 comb
+= e_out
.write_fast1
.data
.eq(FastRegsEnum
.SRR0
) # SRR0
1544 comb
+= e_out
.write_fast1
.ok
.eq(1)
1545 # TRAP write fast2 = SRR1
1546 comb
+= e_out
.write_fast2
.data
.eq(FastRegsEnum
.SRR1
) # SRR1
1547 comb
+= e_out
.write_fast2
.ok
.eq(1)
1548 # TRAP write fast2 = SRR1
1549 comb
+= e_out
.write_fast3
.data
.eq(FastRegsEnum
.SVSRR0
) # SVSRR0
1550 comb
+= e_out
.write_fast3
.ok
.eq(1)
1552 # RFID: needs to read SRR0/1
1553 with m
.If(do_out
.insn_type
== MicrOp
.OP_RFID
):
1554 # TRAP read fast1 = SRR0
1555 comb
+= e_out
.read_fast1
.data
.eq(FastRegsEnum
.SRR0
) # SRR0
1556 comb
+= e_out
.read_fast1
.ok
.eq(1)
1557 # TRAP read fast2 = SRR1
1558 comb
+= e_out
.read_fast2
.data
.eq(FastRegsEnum
.SRR1
) # SRR1
1559 comb
+= e_out
.read_fast2
.ok
.eq(1)
1560 # TRAP read fast2 = SVSRR0
1561 comb
+= e_out
.read_fast3
.data
.eq(FastRegsEnum
.SVSRR0
) # SVSRR0
1562 comb
+= e_out
.read_fast3
.ok
.eq(1)
1564 # annoying simulator bug.
1565 # asmcode may end up getting used for perfcounters?
1566 asmcode
= self
.op_get("asmcode")
1567 if hasattr(e_out
, "asmcode") and asmcode
is not None:
1568 comb
+= e_out
.asmcode
.eq(asmcode
)
1572 def trap(self
, m
, traptype
, trapaddr
, ldst_exc
=None):
1573 """trap: this basically "rewrites" the decoded instruction as a trap
1577 comb
+= e
.eq(0) # reset eeeeeverything
1580 comb
+= self
.do_copy("insn", self
.dec
.opcode_in
, True)
1581 comb
+= self
.do_copy("insn_type", MicrOp
.OP_TRAP
, True)
1582 comb
+= self
.do_copy("fn_unit", Function
.TRAP
, True)
1583 comb
+= self
.do_copy("trapaddr", trapaddr
>> 4, True) # bottom 4 bits
1584 comb
+= self
.do_copy("traptype", traptype
, True) # request type
1585 comb
+= self
.do_copy("ldst_exc", ldst_exc
, True) # request type
1586 comb
+= self
.do_copy("msr", self
.state
.msr
, True) # copy of MSR "state"
1587 comb
+= self
.do_copy("cia", self
.state
.pc
, True) # copy of PC "state"
1588 comb
+= self
.do_copy("svstate", self
.state
.svstate
, True) # SVSTATE
1592 def get_rdflags(e
, cu
):
1594 for idx
in range(cu
.n_src
):
1595 regfile
, regname
, _
= cu
.get_in_spec(idx
)
1596 rdflag
, read
= regspec_decode_read(e
, regfile
, regname
)
1602 if __name__
== '__main__':
1603 pdecode
= create_pdecode()
1604 dec2
= PowerDecode2(pdecode
, svp64_en
=True)
1605 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
1606 with
open("dec2.il", "w") as f
: