5b82bd447d1efb1a1f29d77566ebad11780edfad
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
)
23 from openpower
.sv
.svp64
import SVP64Rec
25 from openpower
.decoder
.power_regspec_map
import regspec_decode_read
26 from openpower
.decoder
.power_decoder
import create_pdecode
27 from openpower
.decoder
.power_enums
import (MicrOp
, CryIn
, Function
,
29 LdstLen
, In1Sel
, In2Sel
, In3Sel
,
30 OutSel
, SPRfull
, SPRreduced
,
32 SVEXTRA
, SVEtype
, SVPtype
)
33 from openpower
.decoder
.decode2execute1
import (Decode2ToExecute1Type
, Data
,
36 from openpower
.consts
import (MSR
, SPEC
, EXTRA2
, EXTRA3
, SVP64P
, field
,
37 SPEC_SIZE
, SPECb
, SPEC_AUG_SIZE
, SVP64CROffs
,
38 FastRegsEnum
, XERRegsEnum
, TT
)
40 from openpower
.state
import CoreState
41 from openpower
.util
import spr_to_fast
44 def decode_spr_num(spr
):
45 return Cat(spr
[5:10], spr
[0:5])
48 def instr_is_priv(m
, op
, insn
):
49 """determines if the instruction is privileged or not
52 is_priv_insn
= Signal(reset_less
=True)
54 with m
.Case(MicrOp
.OP_ATTN
, MicrOp
.OP_MFMSR
, MicrOp
.OP_MTMSRD
,
55 MicrOp
.OP_MTMSR
, MicrOp
.OP_RFID
):
56 comb
+= is_priv_insn
.eq(1)
57 with m
.Case(MicrOp
.OP_TLBIE
) : comb
+= is_priv_insn
.eq(1)
58 with m
.Case(MicrOp
.OP_MFSPR
, MicrOp
.OP_MTSPR
):
59 with m
.If(insn
[20]): # field XFX.spr[-1] i think
60 comb
+= is_priv_insn
.eq(1)
64 class SPRMap(Elaboratable
):
65 """SPRMap: maps POWER9 SPR numbers to internal enum values, fast and slow
68 def __init__(self
, regreduce_en
):
69 self
.regreduce_en
= regreduce_en
75 self
.spr_i
= Signal(10, reset_less
=True)
76 self
.spr_o
= Data(SPR
, name
="spr_o")
77 self
.fast_o
= Data(3, name
="fast_o")
79 def elaborate(self
, platform
):
85 with m
.Switch(self
.spr_i
):
86 for i
, x
in enumerate(SPR
):
88 m
.d
.comb
+= self
.spr_o
.data
.eq(i
)
89 m
.d
.comb
+= self
.spr_o
.ok
.eq(1)
90 for x
, v
in spr_to_fast
.items():
92 m
.d
.comb
+= self
.fast_o
.data
.eq(v
)
93 m
.d
.comb
+= self
.fast_o
.ok
.eq(1)
97 class DecodeA(Elaboratable
):
98 """DecodeA from instruction
100 decodes register RA, implicit and explicit CSRs
103 def __init__(self
, dec
, regreduce_en
):
104 self
.regreduce_en
= regreduce_en
105 if self
.regreduce_en
:
110 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
111 self
.insn_in
= Signal(32, reset_less
=True)
112 self
.reg_out
= Data(5, name
="reg_a")
113 self
.spr_out
= Data(SPR
, "spr_a")
114 self
.fast_out
= Data(3, "fast_a")
115 self
.sv_nz
= Signal(1)
117 def elaborate(self
, platform
):
122 m
.submodules
.sprmap
= sprmap
= SPRMap(self
.regreduce_en
)
124 # select Register A field, if *full 7 bits* are zero (2 more from SVP64)
125 ra
= Signal(5, reset_less
=True)
126 comb
+= ra
.eq(self
.dec
.RA
)
127 with m
.If((self
.sel_in
== In1Sel
.RA
) |
128 ((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
129 ((ra
!= Const(0, 5)) |
(self
.sv_nz
!= Const(0, 1))))):
130 comb
+= reg
.data
.eq(ra
)
133 # some Logic/ALU ops have RS as the 3rd arg, but no "RA".
134 # moved it to 1st position (in1_sel)... because
135 rs
= Signal(5, reset_less
=True)
136 comb
+= rs
.eq(self
.dec
.RS
)
137 with m
.If(self
.sel_in
== In1Sel
.RS
):
138 comb
+= reg
.data
.eq(rs
)
141 # decode Fast-SPR based on instruction type
142 with m
.Switch(op
.internal_op
):
144 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeOut
145 with m
.Case(MicrOp
.OP_BC
):
146 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
148 comb
+= self
.fast_out
.data
.eq(FastRegsEnum
.CTR
)
149 comb
+= self
.fast_out
.ok
.eq(1)
150 with m
.Case(MicrOp
.OP_BCREG
):
151 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
152 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
153 with m
.If(xo9
& ~xo5
):
155 comb
+= self
.fast_out
.data
.eq(FastRegsEnum
.CTR
)
156 comb
+= self
.fast_out
.ok
.eq(1)
158 # MFSPR move from SPRs
159 with m
.Case(MicrOp
.OP_MFSPR
):
160 spr
= Signal(10, reset_less
=True)
161 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
162 comb
+= sprmap
.spr_i
.eq(spr
)
163 comb
+= self
.spr_out
.eq(sprmap
.spr_o
)
164 comb
+= self
.fast_out
.eq(sprmap
.fast_o
)
169 class DecodeAImm(Elaboratable
):
170 """DecodeA immediate from instruction
172 decodes register RA, whether immediate-zero, implicit and
173 explicit CSRs. SVP64 mode requires 2 extra bits
176 def __init__(self
, dec
):
178 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
179 self
.immz_out
= Signal(reset_less
=True)
180 self
.sv_nz
= Signal(1) # EXTRA bits from SVP64
182 def elaborate(self
, platform
):
186 # zero immediate requested
187 ra
= Signal(5, reset_less
=True)
188 comb
+= ra
.eq(self
.dec
.RA
)
189 with m
.If((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
190 (ra
== Const(0, 5)) &
191 (self
.sv_nz
== Const(0, 1))):
192 comb
+= self
.immz_out
.eq(1)
197 class DecodeB(Elaboratable
):
198 """DecodeB from instruction
200 decodes register RB, different forms of immediate (signed, unsigned),
201 and implicit SPRs. register B is basically "lane 2" into the CompUnits.
202 by industry-standard convention, "lane 2" is where fully-decoded
203 immediates are muxed in.
206 def __init__(self
, dec
):
208 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
209 self
.insn_in
= Signal(32, reset_less
=True)
210 self
.reg_out
= Data(7, "reg_b")
211 self
.reg_isvec
= Signal(1, name
="reg_b_isvec") # TODO: in reg_out
212 self
.fast_out
= Data(3, "fast_b")
214 def elaborate(self
, platform
):
220 # select Register B field
221 with m
.Switch(self
.sel_in
):
222 with m
.Case(In2Sel
.RB
):
223 comb
+= reg
.data
.eq(self
.dec
.RB
)
225 with m
.Case(In2Sel
.RS
):
226 # for M-Form shiftrot
227 comb
+= reg
.data
.eq(self
.dec
.RS
)
230 # decode SPR2 based on instruction type
231 # BCREG implicitly uses LR or TAR for 2nd reg
232 # CTR however is already in fast_spr1 *not* 2.
233 with m
.If(op
.internal_op
== MicrOp
.OP_BCREG
):
234 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
235 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
237 comb
+= self
.fast_out
.data
.eq(FastRegsEnum
.LR
)
238 comb
+= self
.fast_out
.ok
.eq(1)
240 comb
+= self
.fast_out
.data
.eq(FastRegsEnum
.TAR
)
241 comb
+= self
.fast_out
.ok
.eq(1)
246 class DecodeBImm(Elaboratable
):
247 """DecodeB immediate from instruction
249 def __init__(self
, dec
):
251 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
252 self
.imm_out
= Data(64, "imm_b")
254 def elaborate(self
, platform
):
258 # select Register B Immediate
259 with m
.Switch(self
.sel_in
):
260 with m
.Case(In2Sel
.CONST_UI
): # unsigned
261 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
)
262 comb
+= self
.imm_out
.ok
.eq(1)
263 with m
.Case(In2Sel
.CONST_SI
): # sign-extended 16-bit
264 si
= Signal(16, reset_less
=True)
265 comb
+= si
.eq(self
.dec
.SI
)
266 comb
+= self
.imm_out
.data
.eq(exts(si
, 16, 64))
267 comb
+= self
.imm_out
.ok
.eq(1)
268 with m
.Case(In2Sel
.CONST_SI_HI
): # sign-extended 16+16=32 bit
269 si_hi
= Signal(32, reset_less
=True)
270 comb
+= si_hi
.eq(self
.dec
.SI
<< 16)
271 comb
+= self
.imm_out
.data
.eq(exts(si_hi
, 32, 64))
272 comb
+= self
.imm_out
.ok
.eq(1)
273 with m
.Case(In2Sel
.CONST_UI_HI
): # unsigned
274 ui
= Signal(16, reset_less
=True)
275 comb
+= ui
.eq(self
.dec
.UI
)
276 comb
+= self
.imm_out
.data
.eq(ui
<< 16)
277 comb
+= self
.imm_out
.ok
.eq(1)
278 with m
.Case(In2Sel
.CONST_LI
): # sign-extend 24+2=26 bit
279 li
= Signal(26, reset_less
=True)
280 comb
+= li
.eq(self
.dec
.LI
<< 2)
281 comb
+= self
.imm_out
.data
.eq(exts(li
, 26, 64))
282 comb
+= self
.imm_out
.ok
.eq(1)
283 with m
.Case(In2Sel
.CONST_BD
): # sign-extend (14+2)=16 bit
284 bd
= Signal(16, reset_less
=True)
285 comb
+= bd
.eq(self
.dec
.BD
<< 2)
286 comb
+= self
.imm_out
.data
.eq(exts(bd
, 16, 64))
287 comb
+= self
.imm_out
.ok
.eq(1)
288 with m
.Case(In2Sel
.CONST_DS
): # sign-extended (14+2=16) bit
289 ds
= Signal(16, reset_less
=True)
290 comb
+= ds
.eq(self
.dec
.DS
<< 2)
291 comb
+= self
.imm_out
.data
.eq(exts(ds
, 16, 64))
292 comb
+= self
.imm_out
.ok
.eq(1)
293 with m
.Case(In2Sel
.CONST_M1
): # signed (-1)
294 comb
+= self
.imm_out
.data
.eq(~
Const(0, 64)) # all 1s
295 comb
+= self
.imm_out
.ok
.eq(1)
296 with m
.Case(In2Sel
.CONST_SH
): # unsigned - for shift
297 comb
+= self
.imm_out
.data
.eq(self
.dec
.sh
)
298 comb
+= self
.imm_out
.ok
.eq(1)
299 with m
.Case(In2Sel
.CONST_SH32
): # unsigned - for shift
300 comb
+= self
.imm_out
.data
.eq(self
.dec
.SH32
)
301 comb
+= self
.imm_out
.ok
.eq(1)
306 class DecodeC(Elaboratable
):
307 """DecodeC from instruction
309 decodes register RC. this is "lane 3" into some CompUnits (not many)
312 def __init__(self
, dec
):
314 self
.sel_in
= Signal(In3Sel
, reset_less
=True)
315 self
.insn_in
= Signal(32, reset_less
=True)
316 self
.reg_out
= Data(5, "reg_c")
318 def elaborate(self
, platform
):
324 # select Register C field
325 with m
.Switch(self
.sel_in
):
326 with m
.Case(In3Sel
.RB
):
327 # for M-Form shiftrot
328 comb
+= reg
.data
.eq(self
.dec
.RB
)
330 with m
.Case(In3Sel
.RS
):
331 comb
+= reg
.data
.eq(self
.dec
.RS
)
337 class DecodeOut(Elaboratable
):
338 """DecodeOut from instruction
340 decodes output register RA, RT or SPR
343 def __init__(self
, dec
, regreduce_en
):
344 self
.regreduce_en
= regreduce_en
345 if self
.regreduce_en
:
350 self
.sel_in
= Signal(OutSel
, reset_less
=True)
351 self
.insn_in
= Signal(32, reset_less
=True)
352 self
.reg_out
= Data(5, "reg_o")
353 self
.spr_out
= Data(SPR
, "spr_o")
354 self
.fast_out
= Data(3, "fast_o")
356 def elaborate(self
, platform
):
359 m
.submodules
.sprmap
= sprmap
= SPRMap(self
.regreduce_en
)
363 # select Register out field
364 with m
.Switch(self
.sel_in
):
365 with m
.Case(OutSel
.RT
):
366 comb
+= reg
.data
.eq(self
.dec
.RT
)
368 with m
.Case(OutSel
.RA
):
369 comb
+= reg
.data
.eq(self
.dec
.RA
)
371 with m
.Case(OutSel
.SPR
):
372 spr
= Signal(10, reset_less
=True)
373 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
374 # MFSPR move to SPRs - needs mapping
375 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
376 comb
+= sprmap
.spr_i
.eq(spr
)
377 comb
+= self
.spr_out
.eq(sprmap
.spr_o
)
378 comb
+= self
.fast_out
.eq(sprmap
.fast_o
)
381 with m
.Switch(op
.internal_op
):
383 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeA
384 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_BCREG
):
385 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
387 comb
+= self
.fast_out
.data
.eq(FastRegsEnum
.CTR
)
388 comb
+= self
.fast_out
.ok
.eq(1)
390 # RFID 1st spr (fast)
391 with m
.Case(MicrOp
.OP_RFID
):
392 comb
+= self
.fast_out
.data
.eq(FastRegsEnum
.SRR0
) # SRR0
393 comb
+= self
.fast_out
.ok
.eq(1)
398 class DecodeOut2(Elaboratable
):
399 """DecodeOut2 from instruction
401 decodes output registers (2nd one). note that RA is *implicit* below,
402 which now causes problems with SVP64
404 TODO: SVP64 is a little more complex, here. svp64 allows extending
405 by one more destination by having one more EXTRA field. RA-as-src
406 is not the same as RA-as-dest. limited in that it's the same first
407 5 bits (from the v3.0B opcode), but still kinda cool. mostly used
408 for operations that have src-as-dest: mostly this is LD/ST-with-update
409 but there are others.
412 def __init__(self
, dec
):
414 self
.sel_in
= Signal(OutSel
, reset_less
=True)
415 self
.lk
= Signal(reset_less
=True)
416 self
.insn_in
= Signal(32, reset_less
=True)
417 self
.reg_out
= Data(5, "reg_o2")
418 self
.fast_out
= Data(3, "fast_o2")
419 self
.fast_out3
= Data(3, "fast_o3")
421 def elaborate(self
, platform
):
425 #m.submodules.svdec = svdec = SVP64RegExtra()
427 # get the 5-bit reg data before svp64-munging it into 7-bit plus isvec
428 #reg = Signal(5, reset_less=True)
430 if hasattr(self
.dec
.op
, "upd"):
431 # update mode LD/ST uses read-reg A also as an output
432 with m
.If(self
.dec
.op
.upd
== LDSTMode
.update
):
433 comb
+= self
.reg_out
.data
.eq(self
.dec
.RA
)
434 comb
+= self
.reg_out
.ok
.eq(1)
436 # B, BC or BCREG: potential implicit register (LR) output
437 # these give bl, bcl, bclrl, etc.
438 with m
.Switch(op
.internal_op
):
440 # BC* implicit register (LR)
441 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_B
, MicrOp
.OP_BCREG
):
442 with m
.If(self
.lk
): # "link" mode
443 comb
+= self
.fast_out
.data
.eq(FastRegsEnum
.LR
) # LR
444 comb
+= self
.fast_out
.ok
.eq(1)
446 # RFID 2nd and 3rd spr (fast)
447 with m
.Case(MicrOp
.OP_RFID
):
448 comb
+= self
.fast_out
.data
.eq(FastRegsEnum
.SRR1
) # SRR1
449 comb
+= self
.fast_out
.ok
.eq(1)
450 comb
+= self
.fast_out3
.data
.eq(FastRegsEnum
.SVSRR0
) # SVSRR0
451 comb
+= self
.fast_out3
.ok
.eq(1)
456 class DecodeRC(Elaboratable
):
457 """DecodeRc from instruction
459 decodes Record bit Rc
462 def __init__(self
, dec
):
464 self
.sel_in
= Signal(RC
, reset_less
=True)
465 self
.insn_in
= Signal(32, reset_less
=True)
466 self
.rc_out
= Data(1, "rc")
468 def elaborate(self
, platform
):
472 # select Record bit out field
473 with m
.Switch(self
.sel_in
):
475 comb
+= self
.rc_out
.data
.eq(self
.dec
.Rc
)
476 comb
+= self
.rc_out
.ok
.eq(1)
478 comb
+= self
.rc_out
.data
.eq(1)
479 comb
+= self
.rc_out
.ok
.eq(1)
480 with m
.Case(RC
.NONE
):
481 comb
+= self
.rc_out
.data
.eq(0)
482 comb
+= self
.rc_out
.ok
.eq(1)
487 class DecodeOE(Elaboratable
):
488 """DecodeOE from instruction
490 decodes OE field: uses RC decode detection which might not be good
492 -- For now, use "rc" in the decode table to decide whether oe exists.
493 -- This is not entirely correct architecturally: For mulhd and
494 -- mulhdu, the OE field is reserved. It remains to be seen what an
495 -- actual POWER9 does if we set it on those instructions, for now we
496 -- test that further down when assigning to the multiplier oe input.
499 def __init__(self
, dec
):
501 self
.sel_in
= Signal(RC
, reset_less
=True)
502 self
.insn_in
= Signal(32, reset_less
=True)
503 self
.oe_out
= Data(1, "oe")
505 def elaborate(self
, platform
):
510 with m
.Switch(op
.internal_op
):
512 # mulhw, mulhwu, mulhd, mulhdu - these *ignore* OE
514 # XXX ARGH! ignoring OE causes incompatibility with microwatt
515 # http://lists.libre-soc.org/pipermail/libre-soc-dev/2020-August/000302.html
516 with m
.Case(MicrOp
.OP_MUL_H64
, MicrOp
.OP_MUL_H32
,
517 MicrOp
.OP_EXTS
, MicrOp
.OP_CNTZ
,
518 MicrOp
.OP_SHL
, MicrOp
.OP_SHR
, MicrOp
.OP_RLC
,
519 MicrOp
.OP_LOAD
, MicrOp
.OP_STORE
,
520 MicrOp
.OP_RLCL
, MicrOp
.OP_RLCR
,
524 # all other ops decode OE field
526 # select OE bit out field
527 with m
.Switch(self
.sel_in
):
529 comb
+= self
.oe_out
.data
.eq(self
.dec
.OE
)
530 comb
+= self
.oe_out
.ok
.eq(1)
535 class DecodeCRIn(Elaboratable
):
536 """Decodes input CR from instruction
538 CR indices - insn fields - (not the data *in* the CR) require only 3
539 bits because they refer to CR0-CR7
542 def __init__(self
, dec
):
544 self
.sel_in
= Signal(CRInSel
, reset_less
=True)
545 self
.insn_in
= Signal(32, reset_less
=True)
546 self
.cr_bitfield
= Data(3, "cr_bitfield")
547 self
.cr_bitfield_b
= Data(3, "cr_bitfield_b")
548 self
.cr_bitfield_o
= Data(3, "cr_bitfield_o")
549 self
.whole_reg
= Data(8, "cr_fxm")
550 self
.sv_override
= Signal(2, reset_less
=True) # do not do EXTRA spec
552 def elaborate(self
, platform
):
556 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
559 # zero-initialisation
560 comb
+= self
.cr_bitfield
.ok
.eq(0)
561 comb
+= self
.cr_bitfield_b
.ok
.eq(0)
562 comb
+= self
.cr_bitfield_o
.ok
.eq(0)
563 comb
+= self
.whole_reg
.ok
.eq(0)
564 comb
+= self
.sv_override
.eq(0)
566 # select the relevant CR bitfields
567 with m
.Switch(self
.sel_in
):
568 with m
.Case(CRInSel
.NONE
):
569 pass # No bitfield activated
570 with m
.Case(CRInSel
.CR0
):
571 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
572 comb
+= self
.cr_bitfield
.ok
.eq(1)
573 comb
+= self
.sv_override
.eq(1)
574 with m
.Case(CRInSel
.CR1
):
575 comb
+= self
.cr_bitfield
.data
.eq(1) # CR1 (MSB0 numbering)
576 comb
+= self
.cr_bitfield
.ok
.eq(1)
577 comb
+= self
.sv_override
.eq(2)
578 with m
.Case(CRInSel
.BI
):
579 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BI
[2:5])
580 comb
+= self
.cr_bitfield
.ok
.eq(1)
581 with m
.Case(CRInSel
.BFA
):
582 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BFA
)
583 comb
+= self
.cr_bitfield
.ok
.eq(1)
584 with m
.Case(CRInSel
.BA_BB
):
585 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BA
[2:5])
586 comb
+= self
.cr_bitfield
.ok
.eq(1)
587 comb
+= self
.cr_bitfield_b
.data
.eq(self
.dec
.BB
[2:5])
588 comb
+= self
.cr_bitfield_b
.ok
.eq(1)
589 comb
+= self
.cr_bitfield_o
.data
.eq(self
.dec
.BT
[2:5])
590 comb
+= self
.cr_bitfield_o
.ok
.eq(1)
591 with m
.Case(CRInSel
.BC
):
592 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BC
[2:5])
593 comb
+= self
.cr_bitfield
.ok
.eq(1)
594 with m
.Case(CRInSel
.WHOLE_REG
):
595 comb
+= self
.whole_reg
.ok
.eq(1)
596 move_one
= Signal(reset_less
=True)
597 comb
+= move_one
.eq(self
.insn_in
[20]) # MSB0 bit 11
598 with m
.If((op
.internal_op
== MicrOp
.OP_MFCR
) & move_one
):
599 # must one-hot the FXM field
600 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
601 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
603 # otherwise use all of it
604 comb
+= self
.whole_reg
.data
.eq(0xff)
609 class DecodeCROut(Elaboratable
):
610 """Decodes input CR from instruction
612 CR indices - insn fields - (not the data *in* the CR) require only 3
613 bits because they refer to CR0-CR7
616 def __init__(self
, dec
):
618 self
.rc_in
= Signal(reset_less
=True)
619 self
.sel_in
= Signal(CROutSel
, reset_less
=True)
620 self
.insn_in
= Signal(32, reset_less
=True)
621 self
.cr_bitfield
= Data(3, "cr_bitfield")
622 self
.whole_reg
= Data(8, "cr_fxm")
623 self
.sv_override
= Signal(2, reset_less
=True) # do not do EXTRA spec
625 def elaborate(self
, platform
):
629 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
632 comb
+= self
.cr_bitfield
.ok
.eq(0)
633 comb
+= self
.whole_reg
.ok
.eq(0)
634 comb
+= self
.sv_override
.eq(0)
636 # please note these MUST match (setting of cr_bitfield.ok) exactly
637 # with write_cr0 below in PowerDecoder2. the reason it's separated
638 # is to avoid having duplicate copies of DecodeCROut in multiple
639 # PowerDecoderSubsets. register decoding should be a one-off in
640 # PowerDecoder2. see https://bugs.libre-soc.org/show_bug.cgi?id=606
642 with m
.Switch(self
.sel_in
):
643 with m
.Case(CROutSel
.NONE
):
644 pass # No bitfield activated
645 with m
.Case(CROutSel
.CR0
):
646 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
647 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
648 comb
+= self
.sv_override
.eq(1)
649 with m
.Case(CROutSel
.CR1
):
650 comb
+= self
.cr_bitfield
.data
.eq(1) # CR1 (MSB0 numbering)
651 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
652 comb
+= self
.sv_override
.eq(2)
653 with m
.Case(CROutSel
.BF
):
654 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BF
)
655 comb
+= self
.cr_bitfield
.ok
.eq(1)
656 with m
.Case(CROutSel
.BT
):
657 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormXL
.BT
[2:5])
658 comb
+= self
.cr_bitfield
.ok
.eq(1)
659 with m
.Case(CROutSel
.WHOLE_REG
):
660 comb
+= self
.whole_reg
.ok
.eq(1)
661 move_one
= Signal(reset_less
=True)
662 comb
+= move_one
.eq(self
.insn_in
[20])
663 with m
.If((op
.internal_op
== MicrOp
.OP_MTCRF
)):
665 # must one-hot the FXM field
666 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
667 with m
.If(ppick
.en_o
):
668 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
670 comb
+= self
.whole_reg
.data
.eq(0b00000001) # CR7
672 comb
+= self
.whole_reg
.data
.eq(self
.dec
.FXM
)
674 # otherwise use all of it
675 comb
+= self
.whole_reg
.data
.eq(0xff)
679 # dictionary of Input Record field names that, if they exist,
680 # will need a corresponding CSV Decoder file column (actually, PowerOp)
681 # to be decoded (this includes the single bit names)
682 record_names
= {'insn_type': 'internal_op',
683 'fn_unit': 'function_unit',
684 'SV_Ptype': 'SV_Ptype',
688 'imm_data': 'in2_sel',
689 'invert_in': 'inv_a',
690 'invert_out': 'inv_out',
693 'output_carry': 'cry_out',
694 'input_carry': 'cry_in',
695 'is_32bit': 'is_32b',
698 'data_len': 'ldst_len',
699 'byte_reverse': 'br',
700 'sign_extend': 'sgn_ext',
705 class PowerDecodeSubset(Elaboratable
):
706 """PowerDecodeSubset: dynamic subset decoder
708 only fields actually requested are copied over. hence, "subset" (duh).
710 def __init__(self
, dec
, opkls
=None, fn_name
=None, final
=False, state
=None,
711 svp64_en
=True, regreduce_en
=False):
713 self
.svp64_en
= svp64_en
714 self
.regreduce_en
= regreduce_en
716 self
.sv_rm
= SVP64Rec(name
="dec_svp64") # SVP64 RM field
717 self
.rm_dec
= SVP64RMModeDecode("svp64_rm_dec")
718 # set these to the predicate mask bits needed for the ALU
719 self
.pred_sm
= Signal() # TODO expand to SIMD mask width
720 self
.pred_dm
= Signal() # TODO expand to SIMD mask width
721 self
.sv_a_nz
= Signal(1)
724 self
.fn_name
= fn_name
726 opkls
= Decode2ToOperand
727 self
.do
= opkls(fn_name
)
728 col_subset
= self
.get_col_subset(self
.do
)
730 # only needed for "main" PowerDecode2
732 self
.e
= Decode2ToExecute1Type(name
=self
.fn_name
, do
=self
.do
,
733 regreduce_en
=regreduce_en
)
735 # create decoder if one not already given
737 dec
= create_pdecode(name
=fn_name
, col_subset
=col_subset
,
738 row_subset
=self
.rowsubsetfn
)
741 # state information needed by the Decoder
743 state
= CoreState("dec2")
746 def get_col_subset(self
, do
):
747 subset
= { 'cr_in', 'cr_out', 'rc_sel'} # needed, non-optional
748 for k
, v
in record_names
.items():
751 print ("get_col_subset", self
.fn_name
, do
.fields
, subset
)
754 def rowsubsetfn(self
, opcode
, row
):
755 """select per-Function-Unit subset of opcodes to be processed
757 normally this just looks at the "unit" column. MMU is different
758 in that it processes specific SPR set/get operations that the SPR
761 return (row
['unit'] == self
.fn_name
or
762 # sigh a dreadful hack: MTSPR and MFSPR need to be processed
763 # by the MMU pipeline so we direct those opcodes to MMU **AND**
764 # SPR pipelines, then selectively weed out the SPRs that should
765 # or should not not go to each pipeline, further down.
766 # really this should be done by modifying the CSV syntax
767 # to support multiple tasks (unit column multiple entries)
768 # see https://bugs.libre-soc.org/show_bug.cgi?id=310
769 (self
.fn_name
== 'MMU' and row
['unit'] == 'SPR' and
770 row
['internal op'] in ['OP_MTSPR', 'OP_MFSPR'])
774 ports
= self
.dec
.ports() + self
.e
.ports()
776 ports
+= self
.sv_rm
.ports()
779 def needs_field(self
, field
, op_field
):
784 return hasattr(do
, field
) and self
.op_get(op_field
) is not None
786 def do_get(self
, field
, final
=False):
787 if final
or self
.final
:
791 return getattr(do
, field
, None)
793 def do_copy(self
, field
, val
, final
=False):
794 df
= self
.do_get(field
, final
)
795 if df
is not None and val
is not None:
799 def op_get(self
, op_field
):
800 return getattr(self
.dec
.op
, op_field
, None)
802 def elaborate(self
, platform
):
803 if self
.regreduce_en
:
810 op
, do
= self
.dec
.op
, self
.do
811 msr
, cia
, svstate
= state
.msr
, state
.pc
, state
.svstate
812 # fill in for a normal instruction (not an exception)
813 # copy over if non-exception, non-privileged etc. is detected
815 if self
.fn_name
is None:
818 name
= self
.fn_name
+ "tmp"
819 self
.e_tmp
= Decode2ToExecute1Type(name
=name
, opkls
=self
.opkls
,
820 regreduce_en
=self
.regreduce_en
)
822 # set up submodule decoders
823 m
.submodules
.dec
= self
.dec
824 m
.submodules
.dec_rc
= self
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
825 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
)
828 # and SVP64 RM mode decoder
829 m
.submodules
.sv_rm_dec
= rm_dec
= self
.rm_dec
831 # copy instruction through...
832 for i
in [do
.insn
, dec_rc
.insn_in
, dec_oe
.insn_in
, ]:
833 comb
+= i
.eq(self
.dec
.opcode_in
)
835 # ...and subdecoders' input fields
836 comb
+= dec_rc
.sel_in
.eq(op
.rc_sel
)
837 comb
+= dec_oe
.sel_in
.eq(op
.rc_sel
) # XXX should be OE sel
840 comb
+= self
.do_copy("msr", msr
)
841 comb
+= self
.do_copy("cia", cia
)
842 comb
+= self
.do_copy("svstate", svstate
)
844 # set up instruction type
845 # no op: defaults to OP_ILLEGAL
846 internal_op
= self
.op_get("internal_op")
847 comb
+= self
.do_copy("insn_type", internal_op
)
849 # function unit for decoded instruction: requires minor redirect
851 fn
= self
.op_get("function_unit")
852 spr
= Signal(10, reset_less
=True)
853 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
855 # Microwatt doesn't implement the partition table
856 # instead has PRTBL register (SPR) to point to process table
858 is_mmu_spr
= Signal()
859 comb
+= is_spr_mv
.eq((internal_op
== MicrOp
.OP_MTSPR
) |
860 (internal_op
== MicrOp
.OP_MFSPR
))
861 comb
+= is_mmu_spr
.eq((spr
== SPR
.DSISR
.value
) |
862 (spr
== SPR
.DAR
.value
) |
863 (spr
== SPR
.PRTBL
.value
) |
864 (spr
== SPR
.PIDR
.value
))
865 # MMU must receive MMU SPRs
866 with m
.If(is_spr_mv
& (fn
== Function
.SPR
) & is_mmu_spr
):
867 comb
+= self
.do_copy("fn_unit", Function
.NONE
)
868 comb
+= self
.do_copy("insn_type", MicrOp
.OP_ILLEGAL
)
869 # SPR pipe must *not* receive MMU SPRs
870 with m
.Elif(is_spr_mv
& (fn
== Function
.MMU
) & ~is_mmu_spr
):
871 comb
+= self
.do_copy("fn_unit", Function
.NONE
)
872 comb
+= self
.do_copy("insn_type", MicrOp
.OP_ILLEGAL
)
875 comb
+= self
.do_copy("fn_unit", fn
)
878 if self
.needs_field("zero_a", "in1_sel"):
879 m
.submodules
.dec_ai
= dec_ai
= DecodeAImm(self
.dec
)
880 comb
+= dec_ai
.sv_nz
.eq(self
.sv_a_nz
)
881 comb
+= dec_ai
.sel_in
.eq(op
.in1_sel
)
882 comb
+= self
.do_copy("zero_a", dec_ai
.immz_out
) # RA==0 detected
883 if self
.needs_field("imm_data", "in2_sel"):
884 m
.submodules
.dec_bi
= dec_bi
= DecodeBImm(self
.dec
)
885 comb
+= dec_bi
.sel_in
.eq(op
.in2_sel
)
886 comb
+= self
.do_copy("imm_data", dec_bi
.imm_out
) # imm in RB
889 comb
+= self
.do_copy("rc", dec_rc
.rc_out
)
890 comb
+= self
.do_copy("oe", dec_oe
.oe_out
)
892 # CR in/out - note: these MUST match with what happens in
894 rc_out
= self
.dec_rc
.rc_out
.data
895 with m
.Switch(op
.cr_out
):
896 with m
.Case(CROutSel
.CR0
, CROutSel
.CR1
):
897 comb
+= self
.do_copy("write_cr0", rc_out
) # only when RC=1
898 with m
.Case(CROutSel
.BF
, CROutSel
.BT
):
899 comb
+= self
.do_copy("write_cr0", 1)
901 comb
+= self
.do_copy("input_cr", self
.op_get("cr_in")) # CR in
902 comb
+= self
.do_copy("output_cr", self
.op_get("cr_out")) # CR out
905 # connect up SVP64 RM Mode decoding
906 fn
= self
.op_get("function_unit")
907 comb
+= rm_dec
.fn_in
.eq(fn
) # decode needs to know if LD/ST type
908 comb
+= rm_dec
.ptype_in
.eq(op
.SV_Ptype
) # Single/Twin predicated
909 comb
+= rm_dec
.rc_in
.eq(rc_out
) # Rc=1
910 comb
+= rm_dec
.rm_in
.eq(self
.sv_rm
) # SVP64 RM mode
912 # decoded/selected instruction flags
913 comb
+= self
.do_copy("data_len", self
.op_get("ldst_len"))
914 comb
+= self
.do_copy("invert_in", self
.op_get("inv_a"))
915 comb
+= self
.do_copy("invert_out", self
.op_get("inv_out"))
916 comb
+= self
.do_copy("input_carry", self
.op_get("cry_in"))
917 comb
+= self
.do_copy("output_carry", self
.op_get("cry_out"))
918 comb
+= self
.do_copy("is_32bit", self
.op_get("is_32b"))
919 comb
+= self
.do_copy("is_signed", self
.op_get("sgn"))
920 lk
= self
.op_get("lk")
923 comb
+= self
.do_copy("lk", self
.dec
.LK
) # XXX TODO: accessor
925 comb
+= self
.do_copy("byte_reverse", self
.op_get("br"))
926 comb
+= self
.do_copy("sign_extend", self
.op_get("sgn_ext"))
927 comb
+= self
.do_copy("ldst_mode", self
.op_get("upd")) # LD/ST mode
929 # copy over SVP64 input record fields (if they exist)
931 # TODO, really do we have to do these explicitly?? sigh
932 #for (field, _) in sv_input_record_layout:
933 # comb += self.do_copy(field, self.rm_dec.op_get(field))
934 comb
+= self
.do_copy("sv_saturate", self
.rm_dec
.saturate
)
935 comb
+= self
.do_copy("sv_Ptype", self
.rm_dec
.ptype_in
)
936 # these get set up based on incoming mask bits. TODO:
937 # pass in multiple bits (later, when SIMD backends are enabled)
938 with m
.If(self
.rm_dec
.pred_sz
):
939 comb
+= self
.do_copy("sv_pred_sz", ~self
.pred_sm
)
940 with m
.If(self
.rm_dec
.pred_dz
):
941 comb
+= self
.do_copy("sv_pred_dz", ~self
.pred_dm
)
946 class PowerDecode2(PowerDecodeSubset
):
947 """PowerDecode2: the main instruction decoder.
949 whilst PowerDecode is responsible for decoding the actual opcode, this
950 module encapsulates further specialist, sparse information and
951 expansion of fields that is inconvenient to have in the CSV files.
952 for example: the encoding of the immediates, which are detected
953 and expanded out to their full value from an annotated (enum)
956 implicit register usage is also set up, here. for example: OP_BC
957 requires implicitly reading CTR, OP_RFID requires implicitly writing
960 in addition, PowerDecoder2 is responsible for detecting whether
961 instructions are illegal (or privileged) or not, and instead of
962 just leaving at that, *replacing* the instruction to execute with
963 a suitable alternative (trap).
965 LDSTExceptions are done the cycle _after_ they're detected (after
966 they come out of LDSTCompUnit). basically despite the instruction
967 being decoded, the results of the decode are completely ignored
968 and "exception.happened" used to set the "actual" instruction to
969 "OP_TRAP". the LDSTException data structure gets filled in,
970 in the CompTrapOpSubset and that's what it fills in SRR.
972 to make this work, TestIssuer must notice "exception.happened"
973 after the (failed) LD/ST and copies the LDSTException info from
974 the output, into here (PowerDecoder2). without incrementing PC.
977 def __init__(self
, dec
, opkls
=None, fn_name
=None, final
=False,
978 state
=None, svp64_en
=True, regreduce_en
=False):
979 super().__init
__(dec
, opkls
, fn_name
, final
, state
, svp64_en
,
981 self
.ldst_exc
= LDSTException("dec2_exc")
984 self
.cr_out_isvec
= Signal(1, name
="cr_out_isvec")
985 self
.cr_in_isvec
= Signal(1, name
="cr_in_isvec")
986 self
.cr_in_b_isvec
= Signal(1, name
="cr_in_b_isvec")
987 self
.cr_in_o_isvec
= Signal(1, name
="cr_in_o_isvec")
988 self
.in1_isvec
= Signal(1, name
="reg_a_isvec")
989 self
.in2_isvec
= Signal(1, name
="reg_b_isvec")
990 self
.in3_isvec
= Signal(1, name
="reg_c_isvec")
991 self
.o_isvec
= Signal(1, name
="reg_o_isvec")
992 self
.o2_isvec
= Signal(1, name
="reg_o2_isvec")
993 self
.no_in_vec
= Signal(1, name
="no_in_vec") # no inputs vector
994 self
.no_out_vec
= Signal(1, name
="no_out_vec") # no outputs vector
995 self
.loop_continue
= Signal(1, name
="loop_continue")
997 self
.no_in_vec
= Const(1, 1)
998 self
.no_out_vec
= Const(1, 1)
999 self
.loop_continue
= Const(0, 1)
1001 def get_col_subset(self
, opkls
):
1002 subset
= super().get_col_subset(opkls
)
1003 subset
.add("asmcode")
1004 subset
.add("in1_sel")
1005 subset
.add("in2_sel")
1006 subset
.add("in3_sel")
1007 subset
.add("out_sel")
1009 subset
.add("sv_in1")
1010 subset
.add("sv_in2")
1011 subset
.add("sv_in3")
1012 subset
.add("sv_out")
1013 subset
.add("sv_out2")
1014 subset
.add("sv_cr_in")
1015 subset
.add("sv_cr_out")
1016 subset
.add("SV_Etype")
1017 subset
.add("SV_Ptype")
1018 # from SVP64RMModeDecode
1019 for (field
, _
) in sv_input_record_layout
:
1022 subset
.add("internal_op")
1026 def elaborate(self
, platform
):
1027 m
= super().elaborate(platform
)
1030 e_out
, op
, do_out
= self
.e
, self
.dec
.op
, self
.e
.do
1031 dec_spr
, msr
, cia
, ext_irq
= state
.dec
, state
.msr
, state
.pc
, state
.eint
1032 rc_out
= self
.dec_rc
.rc_out
.data
1036 # fill in for a normal instruction (not an exception)
1037 # copy over if non-exception, non-privileged etc. is detected
1039 # set up submodule decoders
1040 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
, self
.regreduce_en
)
1041 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
)
1042 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
)
1043 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
, self
.regreduce_en
)
1044 m
.submodules
.dec_o2
= dec_o2
= DecodeOut2(self
.dec
)
1045 m
.submodules
.dec_cr_in
= self
.dec_cr_in
= DecodeCRIn(self
.dec
)
1046 m
.submodules
.dec_cr_out
= self
.dec_cr_out
= DecodeCROut(self
.dec
)
1047 comb
+= dec_a
.sv_nz
.eq(self
.sv_a_nz
)
1050 # and SVP64 Extra decoders
1051 m
.submodules
.crout_svdec
= crout_svdec
= SVP64CRExtra()
1052 m
.submodules
.crin_svdec
= crin_svdec
= SVP64CRExtra()
1053 m
.submodules
.crin_svdec_b
= crin_svdec_b
= SVP64CRExtra()
1054 m
.submodules
.crin_svdec_o
= crin_svdec_o
= SVP64CRExtra()
1055 m
.submodules
.in1_svdec
= in1_svdec
= SVP64RegExtra()
1056 m
.submodules
.in2_svdec
= in2_svdec
= SVP64RegExtra()
1057 m
.submodules
.in3_svdec
= in3_svdec
= SVP64RegExtra()
1058 m
.submodules
.o_svdec
= o_svdec
= SVP64RegExtra()
1059 m
.submodules
.o2_svdec
= o2_svdec
= SVP64RegExtra()
1061 # debug access to crout_svdec (used in get_pdecode_cr_out)
1062 self
.crout_svdec
= crout_svdec
1064 # get the 5-bit reg data before svp64-munging it into 7-bit plus isvec
1065 reg
= Signal(5, reset_less
=True)
1067 # copy instruction through...
1068 for i
in [do
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
1069 self
.dec_cr_in
.insn_in
, self
.dec_cr_out
.insn_in
,
1070 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
]:
1071 comb
+= i
.eq(self
.dec
.opcode_in
)
1074 comb
+= self
.dec_cr_in
.sel_in
.eq(op
.cr_in
)
1075 comb
+= self
.dec_cr_out
.sel_in
.eq(op
.cr_out
)
1076 comb
+= self
.dec_cr_out
.rc_in
.eq(rc_out
)
1079 comb
+= self
.do_copy("read_cr_whole", self
.dec_cr_in
.whole_reg
)
1080 comb
+= self
.do_copy("write_cr_whole", self
.dec_cr_out
.whole_reg
)
1082 # ...and subdecoders' input fields
1083 comb
+= dec_a
.sel_in
.eq(op
.in1_sel
)
1084 comb
+= dec_b
.sel_in
.eq(op
.in2_sel
)
1085 comb
+= dec_c
.sel_in
.eq(op
.in3_sel
)
1086 comb
+= dec_o
.sel_in
.eq(op
.out_sel
)
1087 comb
+= dec_o2
.sel_in
.eq(op
.out_sel
)
1088 if hasattr(do
, "lk"):
1089 comb
+= dec_o2
.lk
.eq(do
.lk
)
1092 # now do the SVP64 munging. op.SV_Etype and op.sv_in1 comes from
1093 # PowerDecoder which in turn comes from LDST-RM*.csv and RM-*.csv
1094 # which in turn were auto-generated by sv_analysis.py
1095 extra
= self
.sv_rm
.extra
# SVP64 extra bits 10:18
1099 comb
+= crout_svdec
.idx
.eq(op
.sv_cr_out
) # SVP64 CR out
1100 comb
+= self
.cr_out_isvec
.eq(crout_svdec
.isvec
)
1103 # CR in - selection slightly different due to shared CR field sigh
1104 cr_a_idx
= Signal(SVEXTRA
)
1105 cr_b_idx
= Signal(SVEXTRA
)
1107 # these change slightly, when decoding BA/BB. really should have
1108 # their own separate CSV column: sv_cr_in1 and sv_cr_in2, but hey
1109 comb
+= cr_a_idx
.eq(op
.sv_cr_in
)
1110 comb
+= cr_b_idx
.eq(SVEXTRA
.NONE
)
1111 with m
.If(op
.sv_cr_in
== SVEXTRA
.Idx_1_2
.value
):
1112 comb
+= cr_a_idx
.eq(SVEXTRA
.Idx1
)
1113 comb
+= cr_b_idx
.eq(SVEXTRA
.Idx2
)
1115 comb
+= self
.cr_in_isvec
.eq(crin_svdec
.isvec
)
1116 comb
+= self
.cr_in_b_isvec
.eq(crin_svdec_b
.isvec
)
1117 comb
+= self
.cr_in_o_isvec
.eq(crin_svdec_o
.isvec
)
1119 # indices are slightly different, BA/BB mess sorted above
1120 comb
+= crin_svdec
.idx
.eq(cr_a_idx
) # SVP64 CR in A
1121 comb
+= crin_svdec_b
.idx
.eq(cr_b_idx
) # SVP64 CR in B
1122 comb
+= crin_svdec_o
.idx
.eq(op
.sv_cr_out
) # SVP64 CR out
1124 # get SVSTATE srcstep (TODO: elwidth etc.) needed below
1125 srcstep
= Signal
.like(self
.state
.svstate
.srcstep
)
1126 dststep
= Signal
.like(self
.state
.svstate
.dststep
)
1127 comb
+= srcstep
.eq(self
.state
.svstate
.srcstep
)
1128 comb
+= dststep
.eq(self
.state
.svstate
.dststep
)
1130 # registers a, b, c and out and out2 (LD/ST EA)
1131 for to_reg
, fromreg
, svdec
, out
in (
1132 (e
.read_reg1
, dec_a
.reg_out
, in1_svdec
, False),
1133 (e
.read_reg2
, dec_b
.reg_out
, in2_svdec
, False),
1134 (e
.read_reg3
, dec_c
.reg_out
, in3_svdec
, False),
1135 (e
.write_reg
, dec_o
.reg_out
, o_svdec
, True),
1136 (e
.write_ea
, dec_o2
.reg_out
, o2_svdec
, True)):
1137 comb
+= svdec
.extra
.eq(extra
) # EXTRA field of SVP64 RM
1138 comb
+= svdec
.etype
.eq(op
.SV_Etype
) # EXTRA2/3 for this insn
1139 comb
+= svdec
.reg_in
.eq(fromreg
.data
) # 3-bit (CR0/BC/BFA)
1140 comb
+= to_reg
.ok
.eq(fromreg
.ok
)
1141 # detect if Vectorised: add srcstep/dststep if yes.
1142 # to_reg is 7-bits, outs get dststep added, ins get srcstep
1143 with m
.If(svdec
.isvec
):
1144 step
= dststep
if out
else srcstep
1145 comb
+= to_reg
.data
.eq(step
+svdec
.reg_out
)
1147 comb
+= to_reg
.data
.eq(svdec
.reg_out
)
1149 comb
+= in1_svdec
.idx
.eq(op
.sv_in1
) # SVP64 reg #1 (in1_sel)
1150 comb
+= in2_svdec
.idx
.eq(op
.sv_in2
) # SVP64 reg #2 (in2_sel)
1151 comb
+= in3_svdec
.idx
.eq(op
.sv_in3
) # SVP64 reg #3 (in3_sel)
1152 comb
+= o_svdec
.idx
.eq(op
.sv_out
) # SVP64 output (out_sel)
1153 comb
+= o2_svdec
.idx
.eq(op
.sv_out2
) # SVP64 output (implicit)
1154 # XXX TODO - work out where this should come from. the problem is
1155 # that LD-with-update is implied (computed from "is instruction in
1156 # "update mode" rather than specified cleanly as its own CSV column
1158 # output reg-is-vectorised (and when no in/out is vectorised)
1159 comb
+= self
.in1_isvec
.eq(in1_svdec
.isvec
)
1160 comb
+= self
.in2_isvec
.eq(in2_svdec
.isvec
)
1161 comb
+= self
.in3_isvec
.eq(in3_svdec
.isvec
)
1162 comb
+= self
.o_isvec
.eq(o_svdec
.isvec
)
1163 comb
+= self
.o2_isvec
.eq(o2_svdec
.isvec
)
1164 # TODO add SPRs here. must be True when *all* are scalar
1165 l
= map(lambda svdec
: svdec
.isvec
, [in1_svdec
, in2_svdec
, in3_svdec
,
1166 crin_svdec
, crin_svdec_b
, crin_svdec_o
])
1167 comb
+= self
.no_in_vec
.eq(~
Cat(*l
).bool()) # all input scalar
1168 l
= map(lambda svdec
: svdec
.isvec
, [o2_svdec
, o_svdec
, crout_svdec
])
1169 comb
+= self
.no_out_vec
.eq(~
Cat(*l
).bool()) # all output scalar
1170 # now create a general-purpose "test" as to whether looping
1171 # should continue. this doesn't include predication bit-tests
1172 loop
= self
.loop_continue
1173 with m
.Switch(op
.SV_Ptype
):
1174 with m
.Case(SVPtype
.P2
.value
):
1176 # TODO: *and cache-inhibited LD/ST!*
1177 comb
+= loop
.eq(~
(self
.no_in_vec | self
.no_out_vec
))
1178 with m
.Case(SVPtype
.P1
.value
):
1179 # single-predication, test relies on dest only
1180 comb
+= loop
.eq(~self
.no_out_vec
)
1182 # not an SV operation, no looping
1185 # condition registers (CR)
1186 for to_reg
, cr
, name
, svdec
, out
in (
1187 (e
.read_cr1
, self
.dec_cr_in
, "cr_bitfield", crin_svdec
, 0),
1188 (e
.read_cr2
, self
.dec_cr_in
, "cr_bitfield_b", crin_svdec_b
, 0),
1189 (e
.read_cr3
, self
.dec_cr_in
, "cr_bitfield_o", crin_svdec_o
, 0),
1190 (e
.write_cr
, self
.dec_cr_out
, "cr_bitfield", crout_svdec
, 1)):
1191 fromreg
= getattr(cr
, name
)
1192 comb
+= svdec
.extra
.eq(extra
) # EXTRA field of SVP64 RM
1193 comb
+= svdec
.etype
.eq(op
.SV_Etype
) # EXTRA2/3 for this insn
1194 comb
+= svdec
.cr_in
.eq(fromreg
.data
) # 3-bit (CR0/BC/BFA)
1195 with m
.If(svdec
.isvec
):
1196 # check if this is CR0 or CR1: treated differently
1197 # (does not "listen" to EXTRA2/3 spec for a start)
1198 # also: the CRs start from completely different locations
1199 step
= dststep
if out
else srcstep
1200 with m
.If(cr
.sv_override
== 1): # CR0
1201 offs
= SVP64CROffs
.CR0
1202 comb
+= to_reg
.data
.eq(step
+offs
)
1203 with m
.Elif(cr
.sv_override
== 2): # CR1
1204 offs
= SVP64CROffs
.CR1
1205 comb
+= to_reg
.data
.eq(step
+1)
1207 comb
+= to_reg
.data
.eq(step
+svdec
.cr_out
) # 7-bit out
1209 comb
+= to_reg
.data
.eq(svdec
.cr_out
) # 7-bit output
1210 comb
+= to_reg
.ok
.eq(fromreg
.ok
)
1212 # sigh must determine if RA is nonzero (7 bit)
1213 comb
+= self
.sv_a_nz
.eq(e
.read_reg1
.data
!= Const(0, 7))
1215 # connect up to/from read/write GPRs
1216 for to_reg
, fromreg
in ((e
.read_reg1
, dec_a
.reg_out
),
1217 (e
.read_reg2
, dec_b
.reg_out
),
1218 (e
.read_reg3
, dec_c
.reg_out
),
1219 (e
.write_reg
, dec_o
.reg_out
),
1220 (e
.write_ea
, dec_o2
.reg_out
)):
1221 comb
+= to_reg
.data
.eq(fromreg
.data
)
1222 comb
+= to_reg
.ok
.eq(fromreg
.ok
)
1224 # connect up to/from read/write CRs
1225 for to_reg
, cr
, name
in (
1226 (e
.read_cr1
, self
.dec_cr_in
, "cr_bitfield", ),
1227 (e
.read_cr2
, self
.dec_cr_in
, "cr_bitfield_b", ),
1228 (e
.read_cr3
, self
.dec_cr_in
, "cr_bitfield_o", ),
1229 (e
.write_cr
, self
.dec_cr_out
, "cr_bitfield", )):
1230 fromreg
= getattr(cr
, name
)
1231 comb
+= to_reg
.data
.eq(fromreg
.data
)
1232 comb
+= to_reg
.ok
.eq(fromreg
.ok
)
1235 comb
+= e
.read_spr1
.eq(dec_a
.spr_out
)
1236 comb
+= e
.write_spr
.eq(dec_o
.spr_out
)
1238 # Fast regs out including SRR0/1/SVSRR0
1239 comb
+= e
.read_fast1
.eq(dec_a
.fast_out
)
1240 comb
+= e
.read_fast2
.eq(dec_b
.fast_out
)
1241 comb
+= e
.write_fast1
.eq(dec_o
.fast_out
) # SRR0 (OP_RFID)
1242 comb
+= e
.write_fast2
.eq(dec_o2
.fast_out
) # SRR1 (ditto)
1243 comb
+= e
.write_fast3
.eq(dec_o2
.fast_out3
) # SVSRR0 (ditto)
1245 # sigh this is exactly the sort of thing for which the
1246 # decoder is designed to not need. MTSPR, MFSPR and others need
1247 # access to the XER bits. however setting e.oe is not appropriate
1248 with m
.If(op
.internal_op
== MicrOp
.OP_MFSPR
):
1249 comb
+= e
.xer_in
.eq(0b111) # SO, CA, OV
1250 with m
.If(op
.internal_op
== MicrOp
.OP_CMP
):
1251 comb
+= e
.xer_in
.eq(1<<XERRegsEnum
.SO
) # SO
1252 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
1253 comb
+= e
.xer_out
.eq(1)
1255 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
1256 with m
.If(op
.internal_op
== MicrOp
.OP_TRAP
):
1257 # *DO NOT* call self.trap here. that would reset absolutely
1258 # everything including destroying read of RA and RB.
1259 comb
+= self
.do_copy("trapaddr", 0x70) # strip first nibble
1261 ####################
1262 # ok so the instruction's been decoded, blah blah, however
1263 # now we need to determine if it's actually going to go ahead...
1264 # *or* if in fact it's a privileged operation, whether there's
1265 # an external interrupt, etc. etc. this is a simple priority
1266 # if-elif-elif sequence. decrement takes highest priority,
1267 # EINT next highest, privileged operation third.
1269 # check if instruction is privileged
1270 is_priv_insn
= instr_is_priv(m
, op
.internal_op
, e
.do
.insn
)
1272 # different IRQ conditions
1273 ext_irq_ok
= Signal()
1274 dec_irq_ok
= Signal()
1277 ldst_exc
= self
.ldst_exc
1279 comb
+= ext_irq_ok
.eq(ext_irq
& msr
[MSR
.EE
]) # v3.0B p944 (MSR.EE)
1280 comb
+= dec_irq_ok
.eq(dec_spr
[63] & msr
[MSR
.EE
]) # 6.5.11 p1076
1281 comb
+= priv_ok
.eq(is_priv_insn
& msr
[MSR
.PR
])
1282 comb
+= illeg_ok
.eq(op
.internal_op
== MicrOp
.OP_ILLEGAL
)
1284 # LD/ST exceptions. TestIssuer copies the exception info at us
1285 # after a failed LD/ST.
1286 with m
.If(ldst_exc
.happened
):
1287 with m
.If(ldst_exc
.alignment
):
1288 self
.trap(m
, TT
.PRIV
, 0x600)
1289 with m
.Elif(ldst_exc
.instr_fault
):
1290 with m
.If(ldst_exc
.segment_fault
):
1291 self
.trap(m
, TT
.PRIV
, 0x480)
1293 # pass exception info to trap to create SRR1
1294 self
.trap(m
, TT
.MEMEXC
, 0x400, ldst_exc
)
1296 with m
.If(ldst_exc
.segment_fault
):
1297 self
.trap(m
, TT
.PRIV
, 0x380)
1299 self
.trap(m
, TT
.PRIV
, 0x300)
1301 # decrement counter (v3.0B p1099): TODO 32-bit version (MSR.LPCR)
1302 with m
.Elif(dec_irq_ok
):
1303 self
.trap(m
, TT
.DEC
, 0x900) # v3.0B 6.5 p1065
1305 # external interrupt? only if MSR.EE set
1306 with m
.Elif(ext_irq_ok
):
1307 self
.trap(m
, TT
.EINT
, 0x500)
1309 # privileged instruction trap
1310 with m
.Elif(priv_ok
):
1311 self
.trap(m
, TT
.PRIV
, 0x700)
1313 # illegal instruction must redirect to trap. this is done by
1314 # *overwriting* the decoded instruction and starting again.
1315 # (note: the same goes for interrupts and for privileged operations,
1316 # just with different trapaddr and traptype)
1317 with m
.Elif(illeg_ok
):
1318 # illegal instruction trap
1319 self
.trap(m
, TT
.ILLEG
, 0x700)
1321 # no exception, just copy things to the output
1325 ####################
1326 # follow-up after trap/irq to set up SRR0/1
1328 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
1329 # Note: OP_SC could actually be modified to just be a trap
1330 with m
.If((do_out
.insn_type
== MicrOp
.OP_TRAP
) |
1331 (do_out
.insn_type
== MicrOp
.OP_SC
)):
1332 # TRAP write fast1 = SRR0
1333 comb
+= e_out
.write_fast1
.data
.eq(FastRegsEnum
.SRR0
) # SRR0
1334 comb
+= e_out
.write_fast1
.ok
.eq(1)
1335 # TRAP write fast2 = SRR1
1336 comb
+= e_out
.write_fast2
.data
.eq(FastRegsEnum
.SRR1
) # SRR1
1337 comb
+= e_out
.write_fast2
.ok
.eq(1)
1338 # TRAP write fast2 = SRR1
1339 comb
+= e_out
.write_fast3
.data
.eq(FastRegsEnum
.SVSRR0
) # SVSRR0
1340 comb
+= e_out
.write_fast3
.ok
.eq(1)
1342 # RFID: needs to read SRR0/1
1343 with m
.If(do_out
.insn_type
== MicrOp
.OP_RFID
):
1344 # TRAP read fast1 = SRR0
1345 comb
+= e_out
.read_fast1
.data
.eq(FastRegsEnum
.SRR0
) # SRR0
1346 comb
+= e_out
.read_fast1
.ok
.eq(1)
1347 # TRAP read fast2 = SRR1
1348 comb
+= e_out
.read_fast2
.data
.eq(FastRegsEnum
.SRR1
) # SRR1
1349 comb
+= e_out
.read_fast2
.ok
.eq(1)
1350 # TRAP read fast2 = SVSRR0
1351 comb
+= e_out
.read_fast3
.data
.eq(FastRegsEnum
.SVSRR0
) # SVSRR0
1352 comb
+= e_out
.read_fast3
.ok
.eq(1)
1354 # annoying simulator bug
1355 if hasattr(e_out
, "asmcode") and hasattr(self
.dec
.op
, "asmcode"):
1356 comb
+= e_out
.asmcode
.eq(self
.dec
.op
.asmcode
)
1360 def trap(self
, m
, traptype
, trapaddr
, ldst_exc
=None):
1361 """trap: this basically "rewrites" the decoded instruction as a trap
1364 op
, e
= self
.dec
.op
, self
.e
1365 comb
+= e
.eq(0) # reset eeeeeverything
1368 comb
+= self
.do_copy("insn", self
.dec
.opcode_in
, True)
1369 comb
+= self
.do_copy("insn_type", MicrOp
.OP_TRAP
, True)
1370 comb
+= self
.do_copy("fn_unit", Function
.TRAP
, True)
1371 comb
+= self
.do_copy("trapaddr", trapaddr
>> 4, True) # bottom 4 bits
1372 comb
+= self
.do_copy("traptype", traptype
, True) # request type
1373 comb
+= self
.do_copy("ldst_exc", ldst_exc
, True) # request type
1374 comb
+= self
.do_copy("msr", self
.state
.msr
, True) # copy of MSR "state"
1375 comb
+= self
.do_copy("cia", self
.state
.pc
, True) # copy of PC "state"
1376 comb
+= self
.do_copy("svstate", self
.state
.svstate
, True) # SVSTATE
1380 def get_rdflags(e
, cu
):
1382 for idx
in range(cu
.n_src
):
1383 regfile
, regname
, _
= cu
.get_in_spec(idx
)
1384 rdflag
, read
= regspec_decode_read(e
, regfile
, regname
)
1386 print("rdflags", rdl
)
1390 if __name__
== '__main__':
1391 pdecode
= create_pdecode()
1392 dec2
= PowerDecode2(pdecode
)
1393 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
1394 with
open("dec2.il", "w") as f
: