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 soc
.regfile
.regfiles
import XERRegs
15 from nmutil
.picker
import PriorityPicker
16 from nmutil
.iocontrol
import RecordObject
17 from nmutil
.extend
import exts
19 from soc
.experiment
.mem_types
import LDSTException
21 from soc
.decoder
.power_svp64_prefix
import SVP64PrefixDecoder
22 from soc
.decoder
.power_svp64_extra
import SVP64CRExtra
, SVP64RegExtra
23 from soc
.decoder
.power_svp64_rm
import SVP64RMModeDecode
24 from soc
.decoder
.power_regspec_map
import regspec_decode_read
25 from soc
.decoder
.power_regspec_map
import regspec_decode_write
26 from soc
.decoder
.power_decoder
import create_pdecode
27 from soc
.decoder
.power_enums
import (MicrOp
, CryIn
, Function
,
29 LdstLen
, In1Sel
, In2Sel
, In3Sel
,
30 OutSel
, SPR
, RC
, LDSTMode
,
31 SVEXTRA
, SVEtype
, SVPtype
)
32 from soc
.decoder
.decode2execute1
import (Decode2ToExecute1Type
, Data
,
34 from soc
.sv
.svp64
import SVP64Rec
35 from soc
.consts
import (MSR
, SPEC
, EXTRA2
, EXTRA3
, SVP64P
, field
,
36 SPEC_SIZE
, SPECb
, SPEC_AUG_SIZE
, SVP64CROffs
)
38 from soc
.regfile
.regfiles
import FastRegs
39 from soc
.consts
import TT
40 from soc
.config
.state
import CoreState
41 from soc
.regfile
.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
69 self
.spr_i
= Signal(10, reset_less
=True)
70 self
.spr_o
= Data(SPR
, name
="spr_o")
71 self
.fast_o
= Data(3, name
="fast_o")
73 def elaborate(self
, platform
):
75 with m
.Switch(self
.spr_i
):
76 for i
, x
in enumerate(SPR
):
78 m
.d
.comb
+= self
.spr_o
.data
.eq(i
)
79 m
.d
.comb
+= self
.spr_o
.ok
.eq(1)
80 for x
, v
in spr_to_fast
.items():
82 m
.d
.comb
+= self
.fast_o
.data
.eq(v
)
83 m
.d
.comb
+= self
.fast_o
.ok
.eq(1)
87 class DecodeA(Elaboratable
):
88 """DecodeA from instruction
90 decodes register RA, implicit and explicit CSRs
93 def __init__(self
, dec
):
95 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
96 self
.insn_in
= Signal(32, reset_less
=True)
97 self
.reg_out
= Data(5, name
="reg_a")
98 self
.spr_out
= Data(SPR
, "spr_a")
99 self
.fast_out
= Data(3, "fast_a")
100 self
.sv_nz
= Signal(1)
102 def elaborate(self
, platform
):
107 m
.submodules
.sprmap
= sprmap
= SPRMap()
109 # select Register A field, if *full 7 bits* are zero (2 more from SVP64)
110 ra
= Signal(5, reset_less
=True)
111 comb
+= ra
.eq(self
.dec
.RA
)
112 with m
.If((self
.sel_in
== In1Sel
.RA
) |
113 ((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
114 ((ra
!= Const(0, 5)) |
(self
.sv_nz
!= Const(0, 1))))):
115 comb
+= reg
.data
.eq(ra
)
118 # some Logic/ALU ops have RS as the 3rd arg, but no "RA".
119 # moved it to 1st position (in1_sel)... because
120 rs
= Signal(5, reset_less
=True)
121 comb
+= rs
.eq(self
.dec
.RS
)
122 with m
.If(self
.sel_in
== In1Sel
.RS
):
123 comb
+= reg
.data
.eq(rs
)
126 # decode Fast-SPR based on instruction type
127 with m
.Switch(op
.internal_op
):
129 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeOut
130 with m
.Case(MicrOp
.OP_BC
):
131 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
133 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
134 comb
+= self
.fast_out
.ok
.eq(1)
135 with m
.Case(MicrOp
.OP_BCREG
):
136 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
137 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
138 with m
.If(xo9
& ~xo5
):
140 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
141 comb
+= self
.fast_out
.ok
.eq(1)
143 # MFSPR move from SPRs
144 with m
.Case(MicrOp
.OP_MFSPR
):
145 spr
= Signal(10, reset_less
=True)
146 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
147 comb
+= sprmap
.spr_i
.eq(spr
)
148 comb
+= self
.spr_out
.eq(sprmap
.spr_o
)
149 comb
+= self
.fast_out
.eq(sprmap
.fast_o
)
154 class DecodeAImm(Elaboratable
):
155 """DecodeA immediate from instruction
157 decodes register RA, whether immediate-zero, implicit and
158 explicit CSRs. SVP64 mode requires 2 extra bits
161 def __init__(self
, dec
):
163 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
164 self
.immz_out
= Signal(reset_less
=True)
165 self
.sv_nz
= Signal(1) # EXTRA bits from SVP64
167 def elaborate(self
, platform
):
171 # zero immediate requested
172 ra
= Signal(5, reset_less
=True)
173 comb
+= ra
.eq(self
.dec
.RA
)
174 with m
.If((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
175 (ra
== Const(0, 5)) &
176 (self
.sv_nz
== Const(0, 1))):
177 comb
+= self
.immz_out
.eq(1)
182 class DecodeB(Elaboratable
):
183 """DecodeB from instruction
185 decodes register RB, different forms of immediate (signed, unsigned),
186 and implicit SPRs. register B is basically "lane 2" into the CompUnits.
187 by industry-standard convention, "lane 2" is where fully-decoded
188 immediates are muxed in.
191 def __init__(self
, dec
):
193 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
194 self
.insn_in
= Signal(32, reset_less
=True)
195 self
.reg_out
= Data(7, "reg_b")
196 self
.reg_isvec
= Signal(1, name
="reg_b_isvec") # TODO: in reg_out
197 self
.fast_out
= Data(3, "fast_b")
199 def elaborate(self
, platform
):
205 # select Register B field
206 with m
.Switch(self
.sel_in
):
207 with m
.Case(In2Sel
.RB
):
208 comb
+= reg
.data
.eq(self
.dec
.RB
)
210 with m
.Case(In2Sel
.RS
):
211 # for M-Form shiftrot
212 comb
+= reg
.data
.eq(self
.dec
.RS
)
215 # decode SPR2 based on instruction type
216 # BCREG implicitly uses LR or TAR for 2nd reg
217 # CTR however is already in fast_spr1 *not* 2.
218 with m
.If(op
.internal_op
== MicrOp
.OP_BCREG
):
219 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
220 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
222 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
223 comb
+= self
.fast_out
.ok
.eq(1)
225 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
226 comb
+= self
.fast_out
.ok
.eq(1)
231 class DecodeBImm(Elaboratable
):
232 """DecodeB immediate from instruction
234 def __init__(self
, dec
):
236 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
237 self
.imm_out
= Data(64, "imm_b")
239 def elaborate(self
, platform
):
243 # select Register B Immediate
244 with m
.Switch(self
.sel_in
):
245 with m
.Case(In2Sel
.CONST_UI
): # unsigned
246 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
)
247 comb
+= self
.imm_out
.ok
.eq(1)
248 with m
.Case(In2Sel
.CONST_SI
): # sign-extended 16-bit
249 si
= Signal(16, reset_less
=True)
250 comb
+= si
.eq(self
.dec
.SI
)
251 comb
+= self
.imm_out
.data
.eq(exts(si
, 16, 64))
252 comb
+= self
.imm_out
.ok
.eq(1)
253 with m
.Case(In2Sel
.CONST_SI_HI
): # sign-extended 16+16=32 bit
254 si_hi
= Signal(32, reset_less
=True)
255 comb
+= si_hi
.eq(self
.dec
.SI
<< 16)
256 comb
+= self
.imm_out
.data
.eq(exts(si_hi
, 32, 64))
257 comb
+= self
.imm_out
.ok
.eq(1)
258 with m
.Case(In2Sel
.CONST_UI_HI
): # unsigned
259 ui
= Signal(16, reset_less
=True)
260 comb
+= ui
.eq(self
.dec
.UI
)
261 comb
+= self
.imm_out
.data
.eq(ui
<< 16)
262 comb
+= self
.imm_out
.ok
.eq(1)
263 with m
.Case(In2Sel
.CONST_LI
): # sign-extend 24+2=26 bit
264 li
= Signal(26, reset_less
=True)
265 comb
+= li
.eq(self
.dec
.LI
<< 2)
266 comb
+= self
.imm_out
.data
.eq(exts(li
, 26, 64))
267 comb
+= self
.imm_out
.ok
.eq(1)
268 with m
.Case(In2Sel
.CONST_BD
): # sign-extend (14+2)=16 bit
269 bd
= Signal(16, reset_less
=True)
270 comb
+= bd
.eq(self
.dec
.BD
<< 2)
271 comb
+= self
.imm_out
.data
.eq(exts(bd
, 16, 64))
272 comb
+= self
.imm_out
.ok
.eq(1)
273 with m
.Case(In2Sel
.CONST_DS
): # sign-extended (14+2=16) bit
274 ds
= Signal(16, reset_less
=True)
275 comb
+= ds
.eq(self
.dec
.DS
<< 2)
276 comb
+= self
.imm_out
.data
.eq(exts(ds
, 16, 64))
277 comb
+= self
.imm_out
.ok
.eq(1)
278 with m
.Case(In2Sel
.CONST_M1
): # signed (-1)
279 comb
+= self
.imm_out
.data
.eq(~
Const(0, 64)) # all 1s
280 comb
+= self
.imm_out
.ok
.eq(1)
281 with m
.Case(In2Sel
.CONST_SH
): # unsigned - for shift
282 comb
+= self
.imm_out
.data
.eq(self
.dec
.sh
)
283 comb
+= self
.imm_out
.ok
.eq(1)
284 with m
.Case(In2Sel
.CONST_SH32
): # unsigned - for shift
285 comb
+= self
.imm_out
.data
.eq(self
.dec
.SH32
)
286 comb
+= self
.imm_out
.ok
.eq(1)
291 class DecodeC(Elaboratable
):
292 """DecodeC from instruction
294 decodes register RC. this is "lane 3" into some CompUnits (not many)
297 def __init__(self
, dec
):
299 self
.sel_in
= Signal(In3Sel
, reset_less
=True)
300 self
.insn_in
= Signal(32, reset_less
=True)
301 self
.reg_out
= Data(5, "reg_c")
303 def elaborate(self
, platform
):
309 # select Register C field
310 with m
.Switch(self
.sel_in
):
311 with m
.Case(In3Sel
.RB
):
312 # for M-Form shiftrot
313 comb
+= reg
.data
.eq(self
.dec
.RB
)
315 with m
.Case(In3Sel
.RS
):
316 comb
+= reg
.data
.eq(self
.dec
.RS
)
322 class DecodeOut(Elaboratable
):
323 """DecodeOut from instruction
325 decodes output register RA, RT or SPR
328 def __init__(self
, dec
):
330 self
.sel_in
= Signal(OutSel
, reset_less
=True)
331 self
.insn_in
= Signal(32, reset_less
=True)
332 self
.reg_out
= Data(5, "reg_o")
333 self
.spr_out
= Data(SPR
, "spr_o")
334 self
.fast_out
= Data(3, "fast_o")
336 def elaborate(self
, platform
):
339 m
.submodules
.sprmap
= sprmap
= SPRMap()
343 # select Register out field
344 with m
.Switch(self
.sel_in
):
345 with m
.Case(OutSel
.RT
):
346 comb
+= reg
.data
.eq(self
.dec
.RT
)
348 with m
.Case(OutSel
.RA
):
349 comb
+= reg
.data
.eq(self
.dec
.RA
)
351 with m
.Case(OutSel
.SPR
):
352 spr
= Signal(10, reset_less
=True)
353 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
354 # MFSPR move to SPRs - needs mapping
355 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
356 comb
+= sprmap
.spr_i
.eq(spr
)
357 comb
+= self
.spr_out
.eq(sprmap
.spr_o
)
358 comb
+= self
.fast_out
.eq(sprmap
.fast_o
)
361 with m
.Switch(op
.internal_op
):
363 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeA
364 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_BCREG
):
365 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
367 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
368 comb
+= self
.fast_out
.ok
.eq(1)
370 # RFID 1st spr (fast)
371 with m
.Case(MicrOp
.OP_RFID
):
372 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
373 comb
+= self
.fast_out
.ok
.eq(1)
378 class DecodeOut2(Elaboratable
):
379 """DecodeOut2 from instruction
381 decodes output registers (2nd one). note that RA is *implicit* below,
382 which now causes problems with SVP64
384 TODO: SVP64 is a little more complex, here. svp64 allows extending
385 by one more destination by having one more EXTRA field. RA-as-src
386 is not the same as RA-as-dest. limited in that it's the same first
387 5 bits (from the v3.0B opcode), but still kinda cool. mostly used
388 for operations that have src-as-dest: mostly this is LD/ST-with-update
389 but there are others.
392 def __init__(self
, dec
):
394 self
.sel_in
= Signal(OutSel
, reset_less
=True)
395 self
.lk
= Signal(reset_less
=True)
396 self
.insn_in
= Signal(32, reset_less
=True)
397 self
.reg_out
= Data(5, "reg_o2")
398 self
.fast_out
= Data(3, "fast_o2")
400 def elaborate(self
, platform
):
404 #m.submodules.svdec = svdec = SVP64RegExtra()
406 # get the 5-bit reg data before svp64-munging it into 7-bit plus isvec
407 #reg = Signal(5, reset_less=True)
409 if hasattr(self
.dec
.op
, "upd"):
410 # update mode LD/ST uses read-reg A also as an output
411 with m
.If(self
.dec
.op
.upd
== LDSTMode
.update
):
412 comb
+= self
.reg_out
.data
.eq(self
.dec
.RA
)
413 comb
+= self
.reg_out
.ok
.eq(1)
415 # B, BC or BCREG: potential implicit register (LR) output
416 # these give bl, bcl, bclrl, etc.
417 with m
.Switch(op
.internal_op
):
419 # BC* implicit register (LR)
420 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_B
, MicrOp
.OP_BCREG
):
421 with m
.If(self
.lk
): # "link" mode
422 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
) # constant: LR
423 comb
+= self
.fast_out
.ok
.eq(1)
425 # RFID 2nd spr (fast)
426 with m
.Case(MicrOp
.OP_RFID
):
427 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
428 comb
+= self
.fast_out
.ok
.eq(1)
433 class DecodeRC(Elaboratable
):
434 """DecodeRc from instruction
436 decodes Record bit Rc
439 def __init__(self
, dec
):
441 self
.sel_in
= Signal(RC
, reset_less
=True)
442 self
.insn_in
= Signal(32, reset_less
=True)
443 self
.rc_out
= Data(1, "rc")
445 def elaborate(self
, platform
):
449 # select Record bit out field
450 with m
.Switch(self
.sel_in
):
452 comb
+= self
.rc_out
.data
.eq(self
.dec
.Rc
)
453 comb
+= self
.rc_out
.ok
.eq(1)
455 comb
+= self
.rc_out
.data
.eq(1)
456 comb
+= self
.rc_out
.ok
.eq(1)
457 with m
.Case(RC
.NONE
):
458 comb
+= self
.rc_out
.data
.eq(0)
459 comb
+= self
.rc_out
.ok
.eq(1)
464 class DecodeOE(Elaboratable
):
465 """DecodeOE from instruction
467 decodes OE field: uses RC decode detection which might not be good
469 -- For now, use "rc" in the decode table to decide whether oe exists.
470 -- This is not entirely correct architecturally: For mulhd and
471 -- mulhdu, the OE field is reserved. It remains to be seen what an
472 -- actual POWER9 does if we set it on those instructions, for now we
473 -- test that further down when assigning to the multiplier oe input.
476 def __init__(self
, dec
):
478 self
.sel_in
= Signal(RC
, reset_less
=True)
479 self
.insn_in
= Signal(32, reset_less
=True)
480 self
.oe_out
= Data(1, "oe")
482 def elaborate(self
, platform
):
487 with m
.Switch(op
.internal_op
):
489 # mulhw, mulhwu, mulhd, mulhdu - these *ignore* OE
491 # XXX ARGH! ignoring OE causes incompatibility with microwatt
492 # http://lists.libre-soc.org/pipermail/libre-soc-dev/2020-August/000302.html
493 with m
.Case(MicrOp
.OP_MUL_H64
, MicrOp
.OP_MUL_H32
,
494 MicrOp
.OP_EXTS
, MicrOp
.OP_CNTZ
,
495 MicrOp
.OP_SHL
, MicrOp
.OP_SHR
, MicrOp
.OP_RLC
,
496 MicrOp
.OP_LOAD
, MicrOp
.OP_STORE
,
497 MicrOp
.OP_RLCL
, MicrOp
.OP_RLCR
,
501 # all other ops decode OE field
503 # select OE bit out field
504 with m
.Switch(self
.sel_in
):
506 comb
+= self
.oe_out
.data
.eq(self
.dec
.OE
)
507 comb
+= self
.oe_out
.ok
.eq(1)
512 class DecodeCRIn(Elaboratable
):
513 """Decodes input CR from instruction
515 CR indices - insn fields - (not the data *in* the CR) require only 3
516 bits because they refer to CR0-CR7
519 def __init__(self
, dec
):
521 self
.sel_in
= Signal(CRInSel
, reset_less
=True)
522 self
.insn_in
= Signal(32, reset_less
=True)
523 self
.cr_bitfield
= Data(3, "cr_bitfield")
524 self
.cr_bitfield_b
= Data(3, "cr_bitfield_b")
525 self
.cr_bitfield_o
= Data(3, "cr_bitfield_o")
526 self
.whole_reg
= Data(8, "cr_fxm")
527 self
.sv_override
= Signal(2, reset_less
=True) # do not do EXTRA spec
529 def elaborate(self
, platform
):
533 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
536 # zero-initialisation
537 comb
+= self
.cr_bitfield
.ok
.eq(0)
538 comb
+= self
.cr_bitfield_b
.ok
.eq(0)
539 comb
+= self
.cr_bitfield_o
.ok
.eq(0)
540 comb
+= self
.whole_reg
.ok
.eq(0)
541 comb
+= self
.sv_override
.eq(0)
543 # select the relevant CR bitfields
544 with m
.Switch(self
.sel_in
):
545 with m
.Case(CRInSel
.NONE
):
546 pass # No bitfield activated
547 with m
.Case(CRInSel
.CR0
):
548 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
549 comb
+= self
.cr_bitfield
.ok
.eq(1)
550 comb
+= self
.sv_override
.eq(1)
551 with m
.Case(CRInSel
.CR1
):
552 comb
+= self
.cr_bitfield
.data
.eq(1) # CR1 (MSB0 numbering)
553 comb
+= self
.cr_bitfield
.ok
.eq(1)
554 comb
+= self
.sv_override
.eq(2)
555 with m
.Case(CRInSel
.BI
):
556 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BI
[2:5])
557 comb
+= self
.cr_bitfield
.ok
.eq(1)
558 with m
.Case(CRInSel
.BFA
):
559 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BFA
)
560 comb
+= self
.cr_bitfield
.ok
.eq(1)
561 with m
.Case(CRInSel
.BA_BB
):
562 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BA
[2:5])
563 comb
+= self
.cr_bitfield
.ok
.eq(1)
564 comb
+= self
.cr_bitfield_b
.data
.eq(self
.dec
.BB
[2:5])
565 comb
+= self
.cr_bitfield_b
.ok
.eq(1)
566 comb
+= self
.cr_bitfield_o
.data
.eq(self
.dec
.BT
[2:5])
567 comb
+= self
.cr_bitfield_o
.ok
.eq(1)
568 with m
.Case(CRInSel
.BC
):
569 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BC
[2:5])
570 comb
+= self
.cr_bitfield
.ok
.eq(1)
571 with m
.Case(CRInSel
.WHOLE_REG
):
572 comb
+= self
.whole_reg
.ok
.eq(1)
573 move_one
= Signal(reset_less
=True)
574 comb
+= move_one
.eq(self
.insn_in
[20]) # MSB0 bit 11
575 with m
.If((op
.internal_op
== MicrOp
.OP_MFCR
) & move_one
):
576 # must one-hot the FXM field
577 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
578 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
580 # otherwise use all of it
581 comb
+= self
.whole_reg
.data
.eq(0xff)
586 class DecodeCROut(Elaboratable
):
587 """Decodes input CR from instruction
589 CR indices - insn fields - (not the data *in* the CR) require only 3
590 bits because they refer to CR0-CR7
593 def __init__(self
, dec
):
595 self
.rc_in
= Signal(reset_less
=True)
596 self
.sel_in
= Signal(CROutSel
, reset_less
=True)
597 self
.insn_in
= Signal(32, reset_less
=True)
598 self
.cr_bitfield
= Data(3, "cr_bitfield")
599 self
.whole_reg
= Data(8, "cr_fxm")
600 self
.sv_override
= Signal(2, reset_less
=True) # do not do EXTRA spec
602 def elaborate(self
, platform
):
606 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
609 comb
+= self
.cr_bitfield
.ok
.eq(0)
610 comb
+= self
.whole_reg
.ok
.eq(0)
611 comb
+= self
.sv_override
.eq(0)
613 # please note these MUST match (setting of cr_bitfield.ok) exactly
614 # with write_cr0 below in PowerDecoder2. the reason it's separated
615 # is to avoid having duplicate copies of DecodeCROut in multiple
616 # PowerDecoderSubsets. register decoding should be a one-off in
617 # PowerDecoder2. see https://bugs.libre-soc.org/show_bug.cgi?id=606
619 with m
.Switch(self
.sel_in
):
620 with m
.Case(CROutSel
.NONE
):
621 pass # No bitfield activated
622 with m
.Case(CROutSel
.CR0
):
623 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
624 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
625 comb
+= self
.sv_override
.eq(1)
626 with m
.Case(CROutSel
.CR1
):
627 comb
+= self
.cr_bitfield
.data
.eq(1) # CR1 (MSB0 numbering)
628 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
629 comb
+= self
.sv_override
.eq(2)
630 with m
.Case(CROutSel
.BF
):
631 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BF
)
632 comb
+= self
.cr_bitfield
.ok
.eq(1)
633 with m
.Case(CROutSel
.BT
):
634 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormXL
.BT
[2:5])
635 comb
+= self
.cr_bitfield
.ok
.eq(1)
636 with m
.Case(CROutSel
.WHOLE_REG
):
637 comb
+= self
.whole_reg
.ok
.eq(1)
638 move_one
= Signal(reset_less
=True)
639 comb
+= move_one
.eq(self
.insn_in
[20])
640 with m
.If((op
.internal_op
== MicrOp
.OP_MTCRF
)):
642 # must one-hot the FXM field
643 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
644 with m
.If(ppick
.en_o
):
645 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
647 comb
+= self
.whole_reg
.data
.eq(0b00000001) # CR7
649 comb
+= self
.whole_reg
.data
.eq(self
.dec
.FXM
)
651 # otherwise use all of it
652 comb
+= self
.whole_reg
.data
.eq(0xff)
656 # dictionary of Input Record field names that, if they exist,
657 # will need a corresponding CSV Decoder file column (actually, PowerOp)
658 # to be decoded (this includes the single bit names)
659 record_names
= {'insn_type': 'internal_op',
660 'fn_unit': 'function_unit',
664 'imm_data': 'in2_sel',
665 'invert_in': 'inv_a',
666 'invert_out': 'inv_out',
669 'output_carry': 'cry_out',
670 'input_carry': 'cry_in',
671 'is_32bit': 'is_32b',
674 'data_len': 'ldst_len',
675 'byte_reverse': 'br',
676 'sign_extend': 'sgn_ext',
681 class PowerDecodeSubset(Elaboratable
):
682 """PowerDecodeSubset: dynamic subset decoder
684 only fields actually requested are copied over. hence, "subset" (duh).
686 def __init__(self
, dec
, opkls
=None, fn_name
=None, final
=False, state
=None,
689 self
.svp64_en
= svp64_en
691 self
.sv_rm
= SVP64Rec(name
="dec_svp64") # SVP64 RM field
692 self
.sv_a_nz
= Signal(1)
695 self
.fn_name
= fn_name
697 opkls
= Decode2ToOperand
698 self
.do
= opkls(fn_name
)
699 col_subset
= self
.get_col_subset(self
.do
)
701 # only needed for "main" PowerDecode2
703 self
.e
= Decode2ToExecute1Type(name
=self
.fn_name
, do
=self
.do
)
705 # create decoder if one not already given
707 dec
= create_pdecode(name
=fn_name
, col_subset
=col_subset
,
708 row_subset
=self
.rowsubsetfn
)
711 # state information needed by the Decoder
713 state
= CoreState("dec2")
716 def get_col_subset(self
, do
):
717 subset
= { 'cr_in', 'cr_out', 'rc_sel'} # needed, non-optional
718 for k
, v
in record_names
.items():
721 print ("get_col_subset", self
.fn_name
, do
.fields
, subset
)
724 def rowsubsetfn(self
, opcode
, row
):
725 """select per-Function-Unit subset of opcodes to be processed
727 normally this just looks at the "unit" column. MMU is different
728 in that it processes specific SPR set/get operations that the SPR
731 return (row
['unit'] == self
.fn_name
or
732 # sigh a dreadful hack: MTSPR and MFSPR need to be processed
733 # by the MMU pipeline so we direct those opcodes to MMU **AND**
734 # SPR pipelines, then selectively weed out the SPRs that should
735 # or should not not go to each pipeline, further down.
736 # really this should be done by modifying the CSV syntax
737 # to support multiple tasks (unit column multiple entries)
738 # see https://bugs.libre-soc.org/show_bug.cgi?id=310
739 (self
.fn_name
== 'MMU' and row
['unit'] == 'SPR' and
740 row
['internal op'] in ['OP_MTSPR', 'OP_MFSPR'])
744 ports
= self
.dec
.ports() + self
.e
.ports()
746 ports
+= self
.sv_rm
.ports()
749 def needs_field(self
, field
, op_field
):
754 return hasattr(do
, field
) and self
.op_get(op_field
) is not None
756 def do_copy(self
, field
, val
, final
=False):
757 if final
or self
.final
:
761 if hasattr(do
, field
) and val
is not None:
762 return getattr(do
, field
).eq(val
)
765 def op_get(self
, op_field
):
766 return getattr(self
.dec
.op
, op_field
, None)
768 def elaborate(self
, platform
):
772 op
, do
= self
.dec
.op
, self
.do
773 msr
, cia
= state
.msr
, state
.pc
774 # fill in for a normal instruction (not an exception)
775 # copy over if non-exception, non-privileged etc. is detected
777 if self
.fn_name
is None:
780 name
= self
.fn_name
+ "tmp"
781 self
.e_tmp
= Decode2ToExecute1Type(name
=name
, opkls
=self
.opkls
)
783 # set up submodule decoders
784 m
.submodules
.dec
= self
.dec
785 m
.submodules
.dec_rc
= self
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
786 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
)
788 # copy instruction through...
789 for i
in [do
.insn
, dec_rc
.insn_in
, dec_oe
.insn_in
, ]:
790 comb
+= i
.eq(self
.dec
.opcode_in
)
792 # ...and subdecoders' input fields
793 comb
+= dec_rc
.sel_in
.eq(op
.rc_sel
)
794 comb
+= dec_oe
.sel_in
.eq(op
.rc_sel
) # XXX should be OE sel
797 comb
+= self
.do_copy("msr", msr
)
798 comb
+= self
.do_copy("cia", cia
)
800 # set up instruction type
801 # no op: defaults to OP_ILLEGAL
802 internal_op
= self
.op_get("internal_op")
803 comb
+= self
.do_copy("insn_type", internal_op
)
805 # function unit for decoded instruction: requires minor redirect
807 fn
= self
.op_get("function_unit")
808 spr
= Signal(10, reset_less
=True)
809 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
811 # Microwatt doesn't implement the partition table
812 # instead has PRTBL register (SPR) to point to process table
814 is_mmu_spr
= Signal()
815 comb
+= is_spr_mv
.eq((internal_op
== MicrOp
.OP_MTSPR
) |
816 (internal_op
== MicrOp
.OP_MFSPR
))
817 comb
+= is_mmu_spr
.eq((spr
== SPR
.DSISR
.value
) |
818 (spr
== SPR
.DAR
.value
) |
819 (spr
== SPR
.PRTBL
.value
) |
820 (spr
== SPR
.PIDR
.value
))
821 # MMU must receive MMU SPRs
822 with m
.If(is_spr_mv
& (fn
== Function
.SPR
) & is_mmu_spr
):
823 comb
+= self
.do_copy("fn_unit", Function
.NONE
)
824 comb
+= self
.do_copy("insn_type", MicrOp
.OP_ILLEGAL
)
825 # SPR pipe must *not* receive MMU SPRs
826 with m
.Elif(is_spr_mv
& (fn
== Function
.MMU
) & ~is_mmu_spr
):
827 comb
+= self
.do_copy("fn_unit", Function
.NONE
)
828 comb
+= self
.do_copy("insn_type", MicrOp
.OP_ILLEGAL
)
831 comb
+= self
.do_copy("fn_unit", fn
)
834 if self
.needs_field("zero_a", "in1_sel"):
835 m
.submodules
.dec_ai
= dec_ai
= DecodeAImm(self
.dec
)
836 comb
+= dec_ai
.sv_nz
.eq(self
.sv_a_nz
)
837 comb
+= dec_ai
.sel_in
.eq(op
.in1_sel
)
838 comb
+= self
.do_copy("zero_a", dec_ai
.immz_out
) # RA==0 detected
839 if self
.needs_field("imm_data", "in2_sel"):
840 m
.submodules
.dec_bi
= dec_bi
= DecodeBImm(self
.dec
)
841 comb
+= dec_bi
.sel_in
.eq(op
.in2_sel
)
842 comb
+= self
.do_copy("imm_data", dec_bi
.imm_out
) # imm in RB
845 comb
+= self
.do_copy("rc", dec_rc
.rc_out
)
846 comb
+= self
.do_copy("oe", dec_oe
.oe_out
)
848 # CR in/out - note: these MUST match with what happens in
850 rc_out
= self
.dec_rc
.rc_out
.data
851 with m
.Switch(op
.cr_out
):
852 with m
.Case(CROutSel
.CR0
, CROutSel
.CR1
):
853 comb
+= self
.do_copy("write_cr0", rc_out
) # only when RC=1
854 with m
.Case(CROutSel
.BF
, CROutSel
.BT
):
855 comb
+= self
.do_copy("write_cr0", 1)
857 comb
+= self
.do_copy("input_cr", self
.op_get("cr_in")) # CR in
858 comb
+= self
.do_copy("output_cr", self
.op_get("cr_out")) # CR out
860 # decoded/selected instruction flags
861 comb
+= self
.do_copy("data_len", self
.op_get("ldst_len"))
862 comb
+= self
.do_copy("invert_in", self
.op_get("inv_a"))
863 comb
+= self
.do_copy("invert_out", self
.op_get("inv_out"))
864 comb
+= self
.do_copy("input_carry", self
.op_get("cry_in"))
865 comb
+= self
.do_copy("output_carry", self
.op_get("cry_out"))
866 comb
+= self
.do_copy("is_32bit", self
.op_get("is_32b"))
867 comb
+= self
.do_copy("is_signed", self
.op_get("sgn"))
868 lk
= self
.op_get("lk")
871 comb
+= self
.do_copy("lk", self
.dec
.LK
) # XXX TODO: accessor
873 comb
+= self
.do_copy("byte_reverse", self
.op_get("br"))
874 comb
+= self
.do_copy("sign_extend", self
.op_get("sgn_ext"))
875 comb
+= self
.do_copy("ldst_mode", self
.op_get("upd")) # LD/ST mode
880 class PowerDecode2(PowerDecodeSubset
):
881 """PowerDecode2: the main instruction decoder.
883 whilst PowerDecode is responsible for decoding the actual opcode, this
884 module encapsulates further specialist, sparse information and
885 expansion of fields that is inconvenient to have in the CSV files.
886 for example: the encoding of the immediates, which are detected
887 and expanded out to their full value from an annotated (enum)
890 implicit register usage is also set up, here. for example: OP_BC
891 requires implicitly reading CTR, OP_RFID requires implicitly writing
894 in addition, PowerDecoder2 is responsible for detecting whether
895 instructions are illegal (or privileged) or not, and instead of
896 just leaving at that, *replacing* the instruction to execute with
897 a suitable alternative (trap).
899 LDSTExceptions are done the cycle _after_ they're detected (after
900 they come out of LDSTCompUnit). basically despite the instruction
901 being decoded, the results of the decode are completely ignored
902 and "exception.happened" used to set the "actual" instruction to
903 "OP_TRAP". the LDSTException data structure gets filled in,
904 in the CompTrapOpSubset and that's what it fills in SRR.
906 to make this work, TestIssuer must notice "exception.happened"
907 after the (failed) LD/ST and copies the LDSTException info from
908 the output, into here (PowerDecoder2). without incrementing PC.
911 def __init__(self
, dec
, opkls
=None, fn_name
=None, final
=False,
912 state
=None, svp64_en
=True):
913 super().__init
__(dec
, opkls
, fn_name
, final
, state
, svp64_en
)
914 self
.exc
= LDSTException("dec2_exc")
917 self
.cr_out_isvec
= Signal(1, name
="cr_out_isvec")
918 self
.cr_in_isvec
= Signal(1, name
="cr_in_isvec")
919 self
.cr_in_b_isvec
= Signal(1, name
="cr_in_b_isvec")
920 self
.cr_in_o_isvec
= Signal(1, name
="cr_in_o_isvec")
921 self
.in1_isvec
= Signal(1, name
="reg_a_isvec")
922 self
.in2_isvec
= Signal(1, name
="reg_b_isvec")
923 self
.in3_isvec
= Signal(1, name
="reg_c_isvec")
924 self
.o_isvec
= Signal(1, name
="reg_o_isvec")
925 self
.o2_isvec
= Signal(1, name
="reg_o2_isvec")
926 self
.no_in_vec
= Signal(1, name
="no_in_vec") # no inputs vector
927 self
.no_out_vec
= Signal(1, name
="no_out_vec") # no outputs vector
928 self
.loop_continue
= Signal(1, name
="loop_continue")
929 self
.rm_dec
= SVP64RMModeDecode("svp64_rm_dec")
931 self
.no_in_vec
= Const(1, 1)
932 self
.no_out_vec
= Const(1, 1)
933 self
.loop_continue
= Const(0, 1)
935 def get_col_subset(self
, opkls
):
936 subset
= super().get_col_subset(opkls
)
937 subset
.add("asmcode")
938 subset
.add("in1_sel")
939 subset
.add("in2_sel")
940 subset
.add("in3_sel")
941 subset
.add("out_sel")
947 subset
.add("sv_out2")
948 subset
.add("sv_cr_in")
949 subset
.add("sv_cr_out")
950 subset
.add("SV_Etype")
951 subset
.add("SV_Ptype")
953 subset
.add("internal_op")
957 def elaborate(self
, platform
):
958 m
= super().elaborate(platform
)
961 e_out
, op
, do_out
= self
.e
, self
.dec
.op
, self
.e
.do
962 dec_spr
, msr
, cia
, ext_irq
= state
.dec
, state
.msr
, state
.pc
, state
.eint
963 rc_out
= self
.dec_rc
.rc_out
.data
967 # fill in for a normal instruction (not an exception)
968 # copy over if non-exception, non-privileged etc. is detected
970 # set up submodule decoders
971 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
)
972 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
)
973 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
)
974 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
)
975 m
.submodules
.dec_o2
= dec_o2
= DecodeOut2(self
.dec
)
976 m
.submodules
.dec_cr_in
= self
.dec_cr_in
= DecodeCRIn(self
.dec
)
977 m
.submodules
.dec_cr_out
= self
.dec_cr_out
= DecodeCROut(self
.dec
)
978 comb
+= dec_a
.sv_nz
.eq(self
.sv_a_nz
)
981 # and SVP64 Extra decoders
982 m
.submodules
.crout_svdec
= crout_svdec
= SVP64CRExtra()
983 m
.submodules
.crin_svdec
= crin_svdec
= SVP64CRExtra()
984 m
.submodules
.crin_svdec_b
= crin_svdec_b
= SVP64CRExtra()
985 m
.submodules
.crin_svdec_o
= crin_svdec_o
= SVP64CRExtra()
986 m
.submodules
.in1_svdec
= in1_svdec
= SVP64RegExtra()
987 m
.submodules
.in2_svdec
= in2_svdec
= SVP64RegExtra()
988 m
.submodules
.in3_svdec
= in3_svdec
= SVP64RegExtra()
989 m
.submodules
.o_svdec
= o_svdec
= SVP64RegExtra()
990 m
.submodules
.o2_svdec
= o2_svdec
= SVP64RegExtra()
992 # debug access to crout_svdec (used in get_pdecode_cr_out)
993 self
.crout_svdec
= crout_svdec
995 # and SVP64 RM mode decoder
996 m
.submodules
.sv_rm_dec
= rm_dec
= self
.rm_dec
998 # get the 5-bit reg data before svp64-munging it into 7-bit plus isvec
999 reg
= Signal(5, reset_less
=True)
1001 # copy instruction through...
1002 for i
in [do
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
1003 self
.dec_cr_in
.insn_in
, self
.dec_cr_out
.insn_in
,
1004 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
]:
1005 comb
+= i
.eq(self
.dec
.opcode_in
)
1008 comb
+= self
.dec_cr_in
.sel_in
.eq(op
.cr_in
)
1009 comb
+= self
.dec_cr_out
.sel_in
.eq(op
.cr_out
)
1010 comb
+= self
.dec_cr_out
.rc_in
.eq(rc_out
)
1013 comb
+= self
.do_copy("read_cr_whole", self
.dec_cr_in
.whole_reg
)
1014 comb
+= self
.do_copy("write_cr_whole", self
.dec_cr_out
.whole_reg
)
1016 # ...and subdecoders' input fields
1017 comb
+= dec_a
.sel_in
.eq(op
.in1_sel
)
1018 comb
+= dec_b
.sel_in
.eq(op
.in2_sel
)
1019 comb
+= dec_c
.sel_in
.eq(op
.in3_sel
)
1020 comb
+= dec_o
.sel_in
.eq(op
.out_sel
)
1021 comb
+= dec_o2
.sel_in
.eq(op
.out_sel
)
1022 if hasattr(do
, "lk"):
1023 comb
+= dec_o2
.lk
.eq(do
.lk
)
1026 # now do the SVP64 munging. op.SV_Etype and op.sv_in1 comes from
1027 # PowerDecoder which in turn comes from LDST-RM*.csv and RM-*.csv
1028 # which in turn were auto-generated by sv_analysis.py
1029 extra
= self
.sv_rm
.extra
# SVP64 extra bits 10:18
1033 comb
+= crout_svdec
.idx
.eq(op
.sv_cr_out
) # SVP64 CR out
1034 comb
+= self
.cr_out_isvec
.eq(crout_svdec
.isvec
)
1037 # CR in - selection slightly different due to shared CR field sigh
1038 cr_a_idx
= Signal(SVEXTRA
)
1039 cr_b_idx
= Signal(SVEXTRA
)
1041 # these change slightly, when decoding BA/BB. really should have
1042 # their own separate CSV column: sv_cr_in1 and sv_cr_in2, but hey
1043 comb
+= cr_a_idx
.eq(op
.sv_cr_in
)
1044 comb
+= cr_b_idx
.eq(SVEXTRA
.NONE
)
1045 with m
.If(op
.sv_cr_in
== SVEXTRA
.Idx_1_2
.value
):
1046 comb
+= cr_a_idx
.eq(SVEXTRA
.Idx1
)
1047 comb
+= cr_b_idx
.eq(SVEXTRA
.Idx2
)
1049 comb
+= self
.cr_in_isvec
.eq(crin_svdec
.isvec
)
1050 comb
+= self
.cr_in_b_isvec
.eq(crin_svdec_b
.isvec
)
1051 comb
+= self
.cr_in_o_isvec
.eq(crin_svdec_o
.isvec
)
1053 # indices are slightly different, BA/BB mess sorted above
1054 comb
+= crin_svdec
.idx
.eq(cr_a_idx
) # SVP64 CR in A
1055 comb
+= crin_svdec_b
.idx
.eq(cr_b_idx
) # SVP64 CR in B
1056 comb
+= crin_svdec_o
.idx
.eq(op
.sv_cr_out
) # SVP64 CR out
1058 # get SVSTATE srcstep (TODO: elwidth etc.) needed below
1059 srcstep
= Signal
.like(self
.state
.svstate
.srcstep
)
1060 dststep
= Signal
.like(self
.state
.svstate
.dststep
)
1061 comb
+= srcstep
.eq(self
.state
.svstate
.srcstep
)
1062 comb
+= dststep
.eq(self
.state
.svstate
.dststep
)
1064 # registers a, b, c and out and out2 (LD/ST EA)
1065 for to_reg
, fromreg
, svdec
, out
in (
1066 (e
.read_reg1
, dec_a
.reg_out
, in1_svdec
, False),
1067 (e
.read_reg2
, dec_b
.reg_out
, in2_svdec
, False),
1068 (e
.read_reg3
, dec_c
.reg_out
, in3_svdec
, False),
1069 (e
.write_reg
, dec_o
.reg_out
, o_svdec
, True),
1070 (e
.write_ea
, dec_o2
.reg_out
, o2_svdec
, True)):
1071 comb
+= svdec
.extra
.eq(extra
) # EXTRA field of SVP64 RM
1072 comb
+= svdec
.etype
.eq(op
.SV_Etype
) # EXTRA2/3 for this insn
1073 comb
+= svdec
.reg_in
.eq(fromreg
.data
) # 3-bit (CR0/BC/BFA)
1074 comb
+= to_reg
.ok
.eq(fromreg
.ok
)
1075 # detect if Vectorised: add srcstep/dststep if yes.
1076 # to_reg is 7-bits, outs get dststep added, ins get srcstep
1077 with m
.If(svdec
.isvec
):
1078 step
= dststep
if out
else srcstep
1079 comb
+= to_reg
.data
.eq(step
+svdec
.reg_out
)
1081 comb
+= to_reg
.data
.eq(svdec
.reg_out
)
1083 comb
+= in1_svdec
.idx
.eq(op
.sv_in1
) # SVP64 reg #1 (in1_sel)
1084 comb
+= in2_svdec
.idx
.eq(op
.sv_in2
) # SVP64 reg #2 (in2_sel)
1085 comb
+= in3_svdec
.idx
.eq(op
.sv_in3
) # SVP64 reg #3 (in3_sel)
1086 comb
+= o_svdec
.idx
.eq(op
.sv_out
) # SVP64 output (out_sel)
1087 comb
+= o2_svdec
.idx
.eq(op
.sv_out2
) # SVP64 output (implicit)
1088 # XXX TODO - work out where this should come from. the problem is
1089 # that LD-with-update is implied (computed from "is instruction in
1090 # "update mode" rather than specified cleanly as its own CSV column
1092 # output reg-is-vectorised (and when no in/out is vectorised)
1093 comb
+= self
.in1_isvec
.eq(in1_svdec
.isvec
)
1094 comb
+= self
.in2_isvec
.eq(in2_svdec
.isvec
)
1095 comb
+= self
.in3_isvec
.eq(in3_svdec
.isvec
)
1096 comb
+= self
.o_isvec
.eq(o_svdec
.isvec
)
1097 comb
+= self
.o2_isvec
.eq(o2_svdec
.isvec
)
1098 # TODO add SPRs here. must be True when *all* are scalar
1099 l
= map(lambda svdec
: svdec
.isvec
, [in1_svdec
, in2_svdec
, in3_svdec
,
1100 crin_svdec
, crin_svdec_b
, crin_svdec_o
])
1101 comb
+= self
.no_in_vec
.eq(~
Cat(*l
).bool()) # all input scalar
1102 l
= map(lambda svdec
: svdec
.isvec
, [o2_svdec
, o_svdec
, crout_svdec
])
1103 comb
+= self
.no_out_vec
.eq(~
Cat(*l
).bool()) # all output scalar
1104 # now create a general-purpose "test" as to whether looping
1105 # should continue. this doesn't include predication bit-tests
1106 loop
= self
.loop_continue
1107 with m
.Switch(op
.SV_Ptype
):
1108 with m
.Case(SVPtype
.P2
.value
):
1110 # TODO: *and cache-inhibited LD/ST!*
1111 comb
+= loop
.eq(~
(self
.no_in_vec | self
.no_out_vec
))
1112 with m
.Case(SVPtype
.P1
.value
):
1113 # single-predication, test relies on dest only
1114 comb
+= loop
.eq(~self
.no_out_vec
)
1116 # not an SV operation, no looping
1119 # condition registers (CR)
1120 for to_reg
, cr
, name
, svdec
, out
in (
1121 (e
.read_cr1
, self
.dec_cr_in
, "cr_bitfield", crin_svdec
, 0),
1122 (e
.read_cr2
, self
.dec_cr_in
, "cr_bitfield_b", crin_svdec_b
, 0),
1123 (e
.read_cr3
, self
.dec_cr_in
, "cr_bitfield_o", crin_svdec_o
, 0),
1124 (e
.write_cr
, self
.dec_cr_out
, "cr_bitfield", crout_svdec
, 1)):
1125 fromreg
= getattr(cr
, name
)
1126 comb
+= svdec
.extra
.eq(extra
) # EXTRA field of SVP64 RM
1127 comb
+= svdec
.etype
.eq(op
.SV_Etype
) # EXTRA2/3 for this insn
1128 comb
+= svdec
.cr_in
.eq(fromreg
.data
) # 3-bit (CR0/BC/BFA)
1129 with m
.If(svdec
.isvec
):
1130 # check if this is CR0 or CR1: treated differently
1131 # (does not "listen" to EXTRA2/3 spec for a start)
1132 # also: the CRs start from completely different locations
1133 step
= dststep
if out
else srcstep
1134 with m
.If(cr
.sv_override
== 1): # CR0
1135 offs
= SVP64CROffs
.CR0
1136 comb
+= to_reg
.data
.eq(step
+offs
)
1137 with m
.Elif(cr
.sv_override
== 2): # CR1
1138 offs
= SVP64CROffs
.CR1
1139 comb
+= to_reg
.data
.eq(step
+1)
1141 comb
+= to_reg
.data
.eq(step
+svdec
.cr_out
) # 7-bit out
1143 comb
+= to_reg
.data
.eq(svdec
.cr_out
) # 7-bit output
1144 comb
+= to_reg
.ok
.eq(fromreg
.ok
)
1146 # sigh must determine if RA is nonzero (7 bit)
1147 comb
+= self
.sv_a_nz
.eq(e
.read_reg1
.data
!= Const(0, 7))
1149 # connect up to/from read/write GPRs
1150 for to_reg
, fromreg
in ((e
.read_reg1
, dec_a
.reg_out
),
1151 (e
.read_reg2
, dec_b
.reg_out
),
1152 (e
.read_reg3
, dec_c
.reg_out
),
1153 (e
.write_reg
, dec_o
.reg_out
),
1154 (e
.write_ea
, dec_o2
.reg_out
)):
1155 comb
+= to_reg
.data
.eq(fromreg
.data
)
1156 comb
+= to_reg
.ok
.eq(fromreg
.ok
)
1158 # connect up to/from read/write CRs
1159 for to_reg
, cr
, name
in (
1160 (e
.read_cr1
, self
.dec_cr_in
, "cr_bitfield", ),
1161 (e
.read_cr2
, self
.dec_cr_in
, "cr_bitfield_b", ),
1162 (e
.read_cr3
, self
.dec_cr_in
, "cr_bitfield_o", ),
1163 (e
.write_cr
, self
.dec_cr_out
, "cr_bitfield", )):
1164 fromreg
= getattr(cr
, name
)
1165 comb
+= to_reg
.data
.eq(fromreg
.data
)
1166 comb
+= to_reg
.ok
.eq(fromreg
.ok
)
1169 comb
+= e
.read_spr1
.eq(dec_a
.spr_out
)
1170 comb
+= e
.write_spr
.eq(dec_o
.spr_out
)
1173 comb
+= e
.read_fast1
.eq(dec_a
.fast_out
)
1174 comb
+= e
.read_fast2
.eq(dec_b
.fast_out
)
1175 comb
+= e
.write_fast1
.eq(dec_o
.fast_out
)
1176 comb
+= e
.write_fast2
.eq(dec_o2
.fast_out
)
1179 # connect up SVP64 RM Mode decoding
1180 fn
= self
.op_get("function_unit")
1181 comb
+= rm_dec
.fn_in
.eq(fn
) # decode needs to know if LD/ST type
1182 comb
+= rm_dec
.ptype_in
.eq(op
.SV_Ptype
) # Single/Twin predicated
1183 comb
+= rm_dec
.rc_in
.eq(rc_out
) # Rc=1
1184 comb
+= rm_dec
.rm_in
.eq(self
.sv_rm
) # SVP64 RM mode
1186 # sigh this is exactly the sort of thing for which the
1187 # decoder is designed to not need. MTSPR, MFSPR and others need
1188 # access to the XER bits. however setting e.oe is not appropriate
1189 with m
.If(op
.internal_op
== MicrOp
.OP_MFSPR
):
1190 comb
+= e
.xer_in
.eq(0b111) # SO, CA, OV
1191 with m
.If(op
.internal_op
== MicrOp
.OP_CMP
):
1192 comb
+= e
.xer_in
.eq(1<<XERRegs
.SO
) # SO
1193 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
1194 comb
+= e
.xer_out
.eq(1)
1196 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
1197 with m
.If(op
.internal_op
== MicrOp
.OP_TRAP
):
1198 # *DO NOT* call self.trap here. that would reset absolutely
1199 # everything including destroying read of RA and RB.
1200 comb
+= self
.do_copy("trapaddr", 0x70) # strip first nibble
1202 ####################
1203 # ok so the instruction's been decoded, blah blah, however
1204 # now we need to determine if it's actually going to go ahead...
1205 # *or* if in fact it's a privileged operation, whether there's
1206 # an external interrupt, etc. etc. this is a simple priority
1207 # if-elif-elif sequence. decrement takes highest priority,
1208 # EINT next highest, privileged operation third.
1210 # check if instruction is privileged
1211 is_priv_insn
= instr_is_priv(m
, op
.internal_op
, e
.do
.insn
)
1213 # different IRQ conditions
1214 ext_irq_ok
= Signal()
1215 dec_irq_ok
= Signal()
1220 comb
+= ext_irq_ok
.eq(ext_irq
& msr
[MSR
.EE
]) # v3.0B p944 (MSR.EE)
1221 comb
+= dec_irq_ok
.eq(dec_spr
[63] & msr
[MSR
.EE
]) # 6.5.11 p1076
1222 comb
+= priv_ok
.eq(is_priv_insn
& msr
[MSR
.PR
])
1223 comb
+= illeg_ok
.eq(op
.internal_op
== MicrOp
.OP_ILLEGAL
)
1225 # LD/ST exceptions. TestIssuer copies the exception info at us
1226 # after a failed LD/ST.
1227 with m
.If(exc
.happened
):
1228 with m
.If(exc
.alignment
):
1229 self
.trap(m
, TT
.PRIV
, 0x600)
1230 with m
.Elif(exc
.instr_fault
):
1231 with m
.If(exc
.segment_fault
):
1232 self
.trap(m
, TT
.PRIV
, 0x480)
1234 # pass exception info to trap to create SRR1
1235 self
.trap(m
, TT
.MEMEXC
, 0x400, exc
)
1237 with m
.If(exc
.segment_fault
):
1238 self
.trap(m
, TT
.PRIV
, 0x380)
1240 self
.trap(m
, TT
.PRIV
, 0x300)
1242 # decrement counter (v3.0B p1099): TODO 32-bit version (MSR.LPCR)
1243 with m
.Elif(dec_irq_ok
):
1244 self
.trap(m
, TT
.DEC
, 0x900) # v3.0B 6.5 p1065
1246 # external interrupt? only if MSR.EE set
1247 with m
.Elif(ext_irq_ok
):
1248 self
.trap(m
, TT
.EINT
, 0x500)
1250 # privileged instruction trap
1251 with m
.Elif(priv_ok
):
1252 self
.trap(m
, TT
.PRIV
, 0x700)
1254 # illegal instruction must redirect to trap. this is done by
1255 # *overwriting* the decoded instruction and starting again.
1256 # (note: the same goes for interrupts and for privileged operations,
1257 # just with different trapaddr and traptype)
1258 with m
.Elif(illeg_ok
):
1259 # illegal instruction trap
1260 self
.trap(m
, TT
.ILLEG
, 0x700)
1262 # no exception, just copy things to the output
1266 ####################
1267 # follow-up after trap/irq to set up SRR0/1
1269 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
1270 # Note: OP_SC could actually be modified to just be a trap
1271 with m
.If((do_out
.insn_type
== MicrOp
.OP_TRAP
) |
1272 (do_out
.insn_type
== MicrOp
.OP_SC
)):
1273 # TRAP write fast1 = SRR0
1274 comb
+= e_out
.write_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
1275 comb
+= e_out
.write_fast1
.ok
.eq(1)
1276 # TRAP write fast2 = SRR1
1277 comb
+= e_out
.write_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
1278 comb
+= e_out
.write_fast2
.ok
.eq(1)
1280 # RFID: needs to read SRR0/1
1281 with m
.If(do_out
.insn_type
== MicrOp
.OP_RFID
):
1282 # TRAP read fast1 = SRR0
1283 comb
+= e_out
.read_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
1284 comb
+= e_out
.read_fast1
.ok
.eq(1)
1285 # TRAP read fast2 = SRR1
1286 comb
+= e_out
.read_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
1287 comb
+= e_out
.read_fast2
.ok
.eq(1)
1289 # annoying simulator bug
1290 if hasattr(e_out
, "asmcode") and hasattr(self
.dec
.op
, "asmcode"):
1291 comb
+= e_out
.asmcode
.eq(self
.dec
.op
.asmcode
)
1295 def trap(self
, m
, traptype
, trapaddr
, exc
=None):
1296 """trap: this basically "rewrites" the decoded instruction as a trap
1299 op
, e
= self
.dec
.op
, self
.e
1300 comb
+= e
.eq(0) # reset eeeeeverything
1303 comb
+= self
.do_copy("insn", self
.dec
.opcode_in
, True)
1304 comb
+= self
.do_copy("insn_type", MicrOp
.OP_TRAP
, True)
1305 comb
+= self
.do_copy("fn_unit", Function
.TRAP
, True)
1306 comb
+= self
.do_copy("trapaddr", trapaddr
>> 4, True) # bottom 4 bits
1307 comb
+= self
.do_copy("traptype", traptype
, True) # request type
1308 comb
+= self
.do_copy("ldst_exc", exc
, True) # request type
1309 comb
+= self
.do_copy("msr", self
.state
.msr
, True) # copy of MSR "state"
1310 comb
+= self
.do_copy("cia", self
.state
.pc
, True) # copy of PC "state"
1314 def get_rdflags(e
, cu
):
1316 for idx
in range(cu
.n_src
):
1317 regfile
, regname
, _
= cu
.get_in_spec(idx
)
1318 rdflag
, read
= regspec_decode_read(e
, regfile
, regname
)
1320 print("rdflags", rdl
)
1324 if __name__
== '__main__':
1325 pdecode
= create_pdecode()
1326 dec2
= PowerDecode2(pdecode
)
1327 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
1328 with
open("dec2.il", "w") as f
: