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
, SPRfull
, SPRreduced
,
32 SVEXTRA
, SVEtype
, SVPtype
)
33 from soc
.decoder
.decode2execute1
import (Decode2ToExecute1Type
, Data
,
35 from soc
.sv
.svp64
import SVP64Rec
36 from soc
.consts
import (MSR
, SPEC
, EXTRA2
, EXTRA3
, SVP64P
, field
,
37 SPEC_SIZE
, SPECb
, SPEC_AUG_SIZE
, SVP64CROffs
)
39 from soc
.regfile
.regfiles
import FastRegs
40 from soc
.consts
import TT
41 from soc
.config
.state
import CoreState
42 from soc
.regfile
.util
import spr_to_fast
45 def decode_spr_num(spr
):
46 return Cat(spr
[5:10], spr
[0:5])
49 def instr_is_priv(m
, op
, insn
):
50 """determines if the instruction is privileged or not
53 is_priv_insn
= Signal(reset_less
=True)
55 with m
.Case(MicrOp
.OP_ATTN
, MicrOp
.OP_MFMSR
, MicrOp
.OP_MTMSRD
,
56 MicrOp
.OP_MTMSR
, MicrOp
.OP_RFID
):
57 comb
+= is_priv_insn
.eq(1)
58 with m
.Case(MicrOp
.OP_TLBIE
) : comb
+= is_priv_insn
.eq(1)
59 with m
.Case(MicrOp
.OP_MFSPR
, MicrOp
.OP_MTSPR
):
60 with m
.If(insn
[20]): # field XFX.spr[-1] i think
61 comb
+= is_priv_insn
.eq(1)
65 class SPRMap(Elaboratable
):
66 """SPRMap: maps POWER9 SPR numbers to internal enum values, fast and slow
69 def __init__(self
, regreduce_en
):
70 self
.regreduce_en
= regreduce_en
76 self
.spr_i
= Signal(10, reset_less
=True)
77 self
.spr_o
= Data(SPR
, name
="spr_o")
78 self
.fast_o
= Data(3, name
="fast_o")
80 def elaborate(self
, platform
):
86 with m
.Switch(self
.spr_i
):
87 for i
, x
in enumerate(SPR
):
89 m
.d
.comb
+= self
.spr_o
.data
.eq(i
)
90 m
.d
.comb
+= self
.spr_o
.ok
.eq(1)
91 for x
, v
in spr_to_fast
.items():
93 m
.d
.comb
+= self
.fast_o
.data
.eq(v
)
94 m
.d
.comb
+= self
.fast_o
.ok
.eq(1)
98 class DecodeA(Elaboratable
):
99 """DecodeA from instruction
101 decodes register RA, implicit and explicit CSRs
104 def __init__(self
, dec
, regreduce_en
):
105 self
.regreduce_en
= regreduce_en
106 if self
.regreduce_en
:
111 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
112 self
.insn_in
= Signal(32, reset_less
=True)
113 self
.reg_out
= Data(5, name
="reg_a")
114 self
.spr_out
= Data(SPR
, "spr_a")
115 self
.fast_out
= Data(3, "fast_a")
116 self
.sv_nz
= Signal(1)
118 def elaborate(self
, platform
):
123 m
.submodules
.sprmap
= sprmap
= SPRMap(self
.regreduce_en
)
125 # select Register A field, if *full 7 bits* are zero (2 more from SVP64)
126 ra
= Signal(5, reset_less
=True)
127 comb
+= ra
.eq(self
.dec
.RA
)
128 with m
.If((self
.sel_in
== In1Sel
.RA
) |
129 ((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
130 ((ra
!= Const(0, 5)) |
(self
.sv_nz
!= Const(0, 1))))):
131 comb
+= reg
.data
.eq(ra
)
134 # some Logic/ALU ops have RS as the 3rd arg, but no "RA".
135 # moved it to 1st position (in1_sel)... because
136 rs
= Signal(5, reset_less
=True)
137 comb
+= rs
.eq(self
.dec
.RS
)
138 with m
.If(self
.sel_in
== In1Sel
.RS
):
139 comb
+= reg
.data
.eq(rs
)
142 # decode Fast-SPR based on instruction type
143 with m
.Switch(op
.internal_op
):
145 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeOut
146 with m
.Case(MicrOp
.OP_BC
):
147 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
149 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
150 comb
+= self
.fast_out
.ok
.eq(1)
151 with m
.Case(MicrOp
.OP_BCREG
):
152 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
153 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
154 with m
.If(xo9
& ~xo5
):
156 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
157 comb
+= self
.fast_out
.ok
.eq(1)
159 # MFSPR move from SPRs
160 with m
.Case(MicrOp
.OP_MFSPR
):
161 spr
= Signal(10, reset_less
=True)
162 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
163 comb
+= sprmap
.spr_i
.eq(spr
)
164 comb
+= self
.spr_out
.eq(sprmap
.spr_o
)
165 comb
+= self
.fast_out
.eq(sprmap
.fast_o
)
170 class DecodeAImm(Elaboratable
):
171 """DecodeA immediate from instruction
173 decodes register RA, whether immediate-zero, implicit and
174 explicit CSRs. SVP64 mode requires 2 extra bits
177 def __init__(self
, dec
):
179 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
180 self
.immz_out
= Signal(reset_less
=True)
181 self
.sv_nz
= Signal(1) # EXTRA bits from SVP64
183 def elaborate(self
, platform
):
187 # zero immediate requested
188 ra
= Signal(5, reset_less
=True)
189 comb
+= ra
.eq(self
.dec
.RA
)
190 with m
.If((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
191 (ra
== Const(0, 5)) &
192 (self
.sv_nz
== Const(0, 1))):
193 comb
+= self
.immz_out
.eq(1)
198 class DecodeB(Elaboratable
):
199 """DecodeB from instruction
201 decodes register RB, different forms of immediate (signed, unsigned),
202 and implicit SPRs. register B is basically "lane 2" into the CompUnits.
203 by industry-standard convention, "lane 2" is where fully-decoded
204 immediates are muxed in.
207 def __init__(self
, dec
):
209 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
210 self
.insn_in
= Signal(32, reset_less
=True)
211 self
.reg_out
= Data(7, "reg_b")
212 self
.reg_isvec
= Signal(1, name
="reg_b_isvec") # TODO: in reg_out
213 self
.fast_out
= Data(3, "fast_b")
215 def elaborate(self
, platform
):
221 # select Register B field
222 with m
.Switch(self
.sel_in
):
223 with m
.Case(In2Sel
.RB
):
224 comb
+= reg
.data
.eq(self
.dec
.RB
)
226 with m
.Case(In2Sel
.RS
):
227 # for M-Form shiftrot
228 comb
+= reg
.data
.eq(self
.dec
.RS
)
231 # decode SPR2 based on instruction type
232 # BCREG implicitly uses LR or TAR for 2nd reg
233 # CTR however is already in fast_spr1 *not* 2.
234 with m
.If(op
.internal_op
== MicrOp
.OP_BCREG
):
235 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
236 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
238 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
239 comb
+= self
.fast_out
.ok
.eq(1)
241 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
242 comb
+= self
.fast_out
.ok
.eq(1)
247 class DecodeBImm(Elaboratable
):
248 """DecodeB immediate from instruction
250 def __init__(self
, dec
):
252 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
253 self
.imm_out
= Data(64, "imm_b")
255 def elaborate(self
, platform
):
259 # select Register B Immediate
260 with m
.Switch(self
.sel_in
):
261 with m
.Case(In2Sel
.CONST_UI
): # unsigned
262 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
)
263 comb
+= self
.imm_out
.ok
.eq(1)
264 with m
.Case(In2Sel
.CONST_SI
): # sign-extended 16-bit
265 si
= Signal(16, reset_less
=True)
266 comb
+= si
.eq(self
.dec
.SI
)
267 comb
+= self
.imm_out
.data
.eq(exts(si
, 16, 64))
268 comb
+= self
.imm_out
.ok
.eq(1)
269 with m
.Case(In2Sel
.CONST_SI_HI
): # sign-extended 16+16=32 bit
270 si_hi
= Signal(32, reset_less
=True)
271 comb
+= si_hi
.eq(self
.dec
.SI
<< 16)
272 comb
+= self
.imm_out
.data
.eq(exts(si_hi
, 32, 64))
273 comb
+= self
.imm_out
.ok
.eq(1)
274 with m
.Case(In2Sel
.CONST_UI_HI
): # unsigned
275 ui
= Signal(16, reset_less
=True)
276 comb
+= ui
.eq(self
.dec
.UI
)
277 comb
+= self
.imm_out
.data
.eq(ui
<< 16)
278 comb
+= self
.imm_out
.ok
.eq(1)
279 with m
.Case(In2Sel
.CONST_LI
): # sign-extend 24+2=26 bit
280 li
= Signal(26, reset_less
=True)
281 comb
+= li
.eq(self
.dec
.LI
<< 2)
282 comb
+= self
.imm_out
.data
.eq(exts(li
, 26, 64))
283 comb
+= self
.imm_out
.ok
.eq(1)
284 with m
.Case(In2Sel
.CONST_BD
): # sign-extend (14+2)=16 bit
285 bd
= Signal(16, reset_less
=True)
286 comb
+= bd
.eq(self
.dec
.BD
<< 2)
287 comb
+= self
.imm_out
.data
.eq(exts(bd
, 16, 64))
288 comb
+= self
.imm_out
.ok
.eq(1)
289 with m
.Case(In2Sel
.CONST_DS
): # sign-extended (14+2=16) bit
290 ds
= Signal(16, reset_less
=True)
291 comb
+= ds
.eq(self
.dec
.DS
<< 2)
292 comb
+= self
.imm_out
.data
.eq(exts(ds
, 16, 64))
293 comb
+= self
.imm_out
.ok
.eq(1)
294 with m
.Case(In2Sel
.CONST_M1
): # signed (-1)
295 comb
+= self
.imm_out
.data
.eq(~
Const(0, 64)) # all 1s
296 comb
+= self
.imm_out
.ok
.eq(1)
297 with m
.Case(In2Sel
.CONST_SH
): # unsigned - for shift
298 comb
+= self
.imm_out
.data
.eq(self
.dec
.sh
)
299 comb
+= self
.imm_out
.ok
.eq(1)
300 with m
.Case(In2Sel
.CONST_SH32
): # unsigned - for shift
301 comb
+= self
.imm_out
.data
.eq(self
.dec
.SH32
)
302 comb
+= self
.imm_out
.ok
.eq(1)
307 class DecodeC(Elaboratable
):
308 """DecodeC from instruction
310 decodes register RC. this is "lane 3" into some CompUnits (not many)
313 def __init__(self
, dec
):
315 self
.sel_in
= Signal(In3Sel
, reset_less
=True)
316 self
.insn_in
= Signal(32, reset_less
=True)
317 self
.reg_out
= Data(5, "reg_c")
319 def elaborate(self
, platform
):
325 # select Register C field
326 with m
.Switch(self
.sel_in
):
327 with m
.Case(In3Sel
.RB
):
328 # for M-Form shiftrot
329 comb
+= reg
.data
.eq(self
.dec
.RB
)
331 with m
.Case(In3Sel
.RS
):
332 comb
+= reg
.data
.eq(self
.dec
.RS
)
338 class DecodeOut(Elaboratable
):
339 """DecodeOut from instruction
341 decodes output register RA, RT or SPR
344 def __init__(self
, dec
, regreduce_en
):
345 self
.regreduce_en
= regreduce_en
346 if self
.regreduce_en
:
351 self
.sel_in
= Signal(OutSel
, reset_less
=True)
352 self
.insn_in
= Signal(32, reset_less
=True)
353 self
.reg_out
= Data(5, "reg_o")
354 self
.spr_out
= Data(SPR
, "spr_o")
355 self
.fast_out
= Data(3, "fast_o")
357 def elaborate(self
, platform
):
360 m
.submodules
.sprmap
= sprmap
= SPRMap(self
.regreduce_en
)
364 # select Register out field
365 with m
.Switch(self
.sel_in
):
366 with m
.Case(OutSel
.RT
):
367 comb
+= reg
.data
.eq(self
.dec
.RT
)
369 with m
.Case(OutSel
.RA
):
370 comb
+= reg
.data
.eq(self
.dec
.RA
)
372 with m
.Case(OutSel
.SPR
):
373 spr
= Signal(10, reset_less
=True)
374 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
375 # MFSPR move to SPRs - needs mapping
376 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
377 comb
+= sprmap
.spr_i
.eq(spr
)
378 comb
+= self
.spr_out
.eq(sprmap
.spr_o
)
379 comb
+= self
.fast_out
.eq(sprmap
.fast_o
)
382 with m
.Switch(op
.internal_op
):
384 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeA
385 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_BCREG
):
386 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
388 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
389 comb
+= self
.fast_out
.ok
.eq(1)
391 # RFID 1st spr (fast)
392 with m
.Case(MicrOp
.OP_RFID
):
393 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
394 comb
+= self
.fast_out
.ok
.eq(1)
399 class DecodeOut2(Elaboratable
):
400 """DecodeOut2 from instruction
402 decodes output registers (2nd one). note that RA is *implicit* below,
403 which now causes problems with SVP64
405 TODO: SVP64 is a little more complex, here. svp64 allows extending
406 by one more destination by having one more EXTRA field. RA-as-src
407 is not the same as RA-as-dest. limited in that it's the same first
408 5 bits (from the v3.0B opcode), but still kinda cool. mostly used
409 for operations that have src-as-dest: mostly this is LD/ST-with-update
410 but there are others.
413 def __init__(self
, dec
):
415 self
.sel_in
= Signal(OutSel
, reset_less
=True)
416 self
.lk
= Signal(reset_less
=True)
417 self
.insn_in
= Signal(32, reset_less
=True)
418 self
.reg_out
= Data(5, "reg_o2")
419 self
.fast_out
= Data(3, "fast_o2")
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(FastRegs
.LR
) # constant: LR
444 comb
+= self
.fast_out
.ok
.eq(1)
446 # RFID 2nd spr (fast)
447 with m
.Case(MicrOp
.OP_RFID
):
448 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
449 comb
+= self
.fast_out
.ok
.eq(1)
454 class DecodeRC(Elaboratable
):
455 """DecodeRc from instruction
457 decodes Record bit Rc
460 def __init__(self
, dec
):
462 self
.sel_in
= Signal(RC
, reset_less
=True)
463 self
.insn_in
= Signal(32, reset_less
=True)
464 self
.rc_out
= Data(1, "rc")
466 def elaborate(self
, platform
):
470 # select Record bit out field
471 with m
.Switch(self
.sel_in
):
473 comb
+= self
.rc_out
.data
.eq(self
.dec
.Rc
)
474 comb
+= self
.rc_out
.ok
.eq(1)
476 comb
+= self
.rc_out
.data
.eq(1)
477 comb
+= self
.rc_out
.ok
.eq(1)
478 with m
.Case(RC
.NONE
):
479 comb
+= self
.rc_out
.data
.eq(0)
480 comb
+= self
.rc_out
.ok
.eq(1)
485 class DecodeOE(Elaboratable
):
486 """DecodeOE from instruction
488 decodes OE field: uses RC decode detection which might not be good
490 -- For now, use "rc" in the decode table to decide whether oe exists.
491 -- This is not entirely correct architecturally: For mulhd and
492 -- mulhdu, the OE field is reserved. It remains to be seen what an
493 -- actual POWER9 does if we set it on those instructions, for now we
494 -- test that further down when assigning to the multiplier oe input.
497 def __init__(self
, dec
):
499 self
.sel_in
= Signal(RC
, reset_less
=True)
500 self
.insn_in
= Signal(32, reset_less
=True)
501 self
.oe_out
= Data(1, "oe")
503 def elaborate(self
, platform
):
508 with m
.Switch(op
.internal_op
):
510 # mulhw, mulhwu, mulhd, mulhdu - these *ignore* OE
512 # XXX ARGH! ignoring OE causes incompatibility with microwatt
513 # http://lists.libre-soc.org/pipermail/libre-soc-dev/2020-August/000302.html
514 with m
.Case(MicrOp
.OP_MUL_H64
, MicrOp
.OP_MUL_H32
,
515 MicrOp
.OP_EXTS
, MicrOp
.OP_CNTZ
,
516 MicrOp
.OP_SHL
, MicrOp
.OP_SHR
, MicrOp
.OP_RLC
,
517 MicrOp
.OP_LOAD
, MicrOp
.OP_STORE
,
518 MicrOp
.OP_RLCL
, MicrOp
.OP_RLCR
,
522 # all other ops decode OE field
524 # select OE bit out field
525 with m
.Switch(self
.sel_in
):
527 comb
+= self
.oe_out
.data
.eq(self
.dec
.OE
)
528 comb
+= self
.oe_out
.ok
.eq(1)
533 class DecodeCRIn(Elaboratable
):
534 """Decodes input CR from instruction
536 CR indices - insn fields - (not the data *in* the CR) require only 3
537 bits because they refer to CR0-CR7
540 def __init__(self
, dec
):
542 self
.sel_in
= Signal(CRInSel
, reset_less
=True)
543 self
.insn_in
= Signal(32, reset_less
=True)
544 self
.cr_bitfield
= Data(3, "cr_bitfield")
545 self
.cr_bitfield_b
= Data(3, "cr_bitfield_b")
546 self
.cr_bitfield_o
= Data(3, "cr_bitfield_o")
547 self
.whole_reg
= Data(8, "cr_fxm")
548 self
.sv_override
= Signal(2, reset_less
=True) # do not do EXTRA spec
550 def elaborate(self
, platform
):
554 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
557 # zero-initialisation
558 comb
+= self
.cr_bitfield
.ok
.eq(0)
559 comb
+= self
.cr_bitfield_b
.ok
.eq(0)
560 comb
+= self
.cr_bitfield_o
.ok
.eq(0)
561 comb
+= self
.whole_reg
.ok
.eq(0)
562 comb
+= self
.sv_override
.eq(0)
564 # select the relevant CR bitfields
565 with m
.Switch(self
.sel_in
):
566 with m
.Case(CRInSel
.NONE
):
567 pass # No bitfield activated
568 with m
.Case(CRInSel
.CR0
):
569 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
570 comb
+= self
.cr_bitfield
.ok
.eq(1)
571 comb
+= self
.sv_override
.eq(1)
572 with m
.Case(CRInSel
.CR1
):
573 comb
+= self
.cr_bitfield
.data
.eq(1) # CR1 (MSB0 numbering)
574 comb
+= self
.cr_bitfield
.ok
.eq(1)
575 comb
+= self
.sv_override
.eq(2)
576 with m
.Case(CRInSel
.BI
):
577 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BI
[2:5])
578 comb
+= self
.cr_bitfield
.ok
.eq(1)
579 with m
.Case(CRInSel
.BFA
):
580 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BFA
)
581 comb
+= self
.cr_bitfield
.ok
.eq(1)
582 with m
.Case(CRInSel
.BA_BB
):
583 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BA
[2:5])
584 comb
+= self
.cr_bitfield
.ok
.eq(1)
585 comb
+= self
.cr_bitfield_b
.data
.eq(self
.dec
.BB
[2:5])
586 comb
+= self
.cr_bitfield_b
.ok
.eq(1)
587 comb
+= self
.cr_bitfield_o
.data
.eq(self
.dec
.BT
[2:5])
588 comb
+= self
.cr_bitfield_o
.ok
.eq(1)
589 with m
.Case(CRInSel
.BC
):
590 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BC
[2:5])
591 comb
+= self
.cr_bitfield
.ok
.eq(1)
592 with m
.Case(CRInSel
.WHOLE_REG
):
593 comb
+= self
.whole_reg
.ok
.eq(1)
594 move_one
= Signal(reset_less
=True)
595 comb
+= move_one
.eq(self
.insn_in
[20]) # MSB0 bit 11
596 with m
.If((op
.internal_op
== MicrOp
.OP_MFCR
) & move_one
):
597 # must one-hot the FXM field
598 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
599 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
601 # otherwise use all of it
602 comb
+= self
.whole_reg
.data
.eq(0xff)
607 class DecodeCROut(Elaboratable
):
608 """Decodes input CR from instruction
610 CR indices - insn fields - (not the data *in* the CR) require only 3
611 bits because they refer to CR0-CR7
614 def __init__(self
, dec
):
616 self
.rc_in
= Signal(reset_less
=True)
617 self
.sel_in
= Signal(CROutSel
, reset_less
=True)
618 self
.insn_in
= Signal(32, reset_less
=True)
619 self
.cr_bitfield
= Data(3, "cr_bitfield")
620 self
.whole_reg
= Data(8, "cr_fxm")
621 self
.sv_override
= Signal(2, reset_less
=True) # do not do EXTRA spec
623 def elaborate(self
, platform
):
627 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
630 comb
+= self
.cr_bitfield
.ok
.eq(0)
631 comb
+= self
.whole_reg
.ok
.eq(0)
632 comb
+= self
.sv_override
.eq(0)
634 # please note these MUST match (setting of cr_bitfield.ok) exactly
635 # with write_cr0 below in PowerDecoder2. the reason it's separated
636 # is to avoid having duplicate copies of DecodeCROut in multiple
637 # PowerDecoderSubsets. register decoding should be a one-off in
638 # PowerDecoder2. see https://bugs.libre-soc.org/show_bug.cgi?id=606
640 with m
.Switch(self
.sel_in
):
641 with m
.Case(CROutSel
.NONE
):
642 pass # No bitfield activated
643 with m
.Case(CROutSel
.CR0
):
644 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
645 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
646 comb
+= self
.sv_override
.eq(1)
647 with m
.Case(CROutSel
.CR1
):
648 comb
+= self
.cr_bitfield
.data
.eq(1) # CR1 (MSB0 numbering)
649 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
650 comb
+= self
.sv_override
.eq(2)
651 with m
.Case(CROutSel
.BF
):
652 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BF
)
653 comb
+= self
.cr_bitfield
.ok
.eq(1)
654 with m
.Case(CROutSel
.BT
):
655 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormXL
.BT
[2:5])
656 comb
+= self
.cr_bitfield
.ok
.eq(1)
657 with m
.Case(CROutSel
.WHOLE_REG
):
658 comb
+= self
.whole_reg
.ok
.eq(1)
659 move_one
= Signal(reset_less
=True)
660 comb
+= move_one
.eq(self
.insn_in
[20])
661 with m
.If((op
.internal_op
== MicrOp
.OP_MTCRF
)):
663 # must one-hot the FXM field
664 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
665 with m
.If(ppick
.en_o
):
666 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
668 comb
+= self
.whole_reg
.data
.eq(0b00000001) # CR7
670 comb
+= self
.whole_reg
.data
.eq(self
.dec
.FXM
)
672 # otherwise use all of it
673 comb
+= self
.whole_reg
.data
.eq(0xff)
677 # dictionary of Input Record field names that, if they exist,
678 # will need a corresponding CSV Decoder file column (actually, PowerOp)
679 # to be decoded (this includes the single bit names)
680 record_names
= {'insn_type': 'internal_op',
681 'fn_unit': 'function_unit',
685 'imm_data': 'in2_sel',
686 'invert_in': 'inv_a',
687 'invert_out': 'inv_out',
690 'output_carry': 'cry_out',
691 'input_carry': 'cry_in',
692 'is_32bit': 'is_32b',
695 'data_len': 'ldst_len',
696 'byte_reverse': 'br',
697 'sign_extend': 'sgn_ext',
702 class PowerDecodeSubset(Elaboratable
):
703 """PowerDecodeSubset: dynamic subset decoder
705 only fields actually requested are copied over. hence, "subset" (duh).
707 def __init__(self
, dec
, opkls
=None, fn_name
=None, final
=False, state
=None,
708 svp64_en
=True, regreduce_en
=False):
710 self
.svp64_en
= svp64_en
711 self
.regreduce_en
= regreduce_en
713 self
.sv_rm
= SVP64Rec(name
="dec_svp64") # SVP64 RM field
714 self
.sv_a_nz
= Signal(1)
717 self
.fn_name
= fn_name
719 opkls
= Decode2ToOperand
720 self
.do
= opkls(fn_name
)
721 col_subset
= self
.get_col_subset(self
.do
)
723 # only needed for "main" PowerDecode2
725 self
.e
= Decode2ToExecute1Type(name
=self
.fn_name
, do
=self
.do
,
726 regreduce_en
=regreduce_en
)
728 # create decoder if one not already given
730 dec
= create_pdecode(name
=fn_name
, col_subset
=col_subset
,
731 row_subset
=self
.rowsubsetfn
)
734 # state information needed by the Decoder
736 state
= CoreState("dec2")
739 def get_col_subset(self
, do
):
740 subset
= { 'cr_in', 'cr_out', 'rc_sel'} # needed, non-optional
741 for k
, v
in record_names
.items():
744 print ("get_col_subset", self
.fn_name
, do
.fields
, subset
)
747 def rowsubsetfn(self
, opcode
, row
):
748 """select per-Function-Unit subset of opcodes to be processed
750 normally this just looks at the "unit" column. MMU is different
751 in that it processes specific SPR set/get operations that the SPR
754 return (row
['unit'] == self
.fn_name
or
755 # sigh a dreadful hack: MTSPR and MFSPR need to be processed
756 # by the MMU pipeline so we direct those opcodes to MMU **AND**
757 # SPR pipelines, then selectively weed out the SPRs that should
758 # or should not not go to each pipeline, further down.
759 # really this should be done by modifying the CSV syntax
760 # to support multiple tasks (unit column multiple entries)
761 # see https://bugs.libre-soc.org/show_bug.cgi?id=310
762 (self
.fn_name
== 'MMU' and row
['unit'] == 'SPR' and
763 row
['internal op'] in ['OP_MTSPR', 'OP_MFSPR'])
767 ports
= self
.dec
.ports() + self
.e
.ports()
769 ports
+= self
.sv_rm
.ports()
772 def needs_field(self
, field
, op_field
):
777 return hasattr(do
, field
) and self
.op_get(op_field
) is not None
779 def do_copy(self
, field
, val
, final
=False):
780 if final
or self
.final
:
784 if hasattr(do
, field
) and val
is not None:
785 return getattr(do
, field
).eq(val
)
788 def op_get(self
, op_field
):
789 return getattr(self
.dec
.op
, op_field
, None)
791 def elaborate(self
, platform
):
792 if self
.regreduce_en
:
799 op
, do
= self
.dec
.op
, self
.do
800 msr
, cia
= state
.msr
, state
.pc
801 # fill in for a normal instruction (not an exception)
802 # copy over if non-exception, non-privileged etc. is detected
804 if self
.fn_name
is None:
807 name
= self
.fn_name
+ "tmp"
808 self
.e_tmp
= Decode2ToExecute1Type(name
=name
, opkls
=self
.opkls
,
809 regreduce_en
=self
.regreduce_en
)
811 # set up submodule decoders
812 m
.submodules
.dec
= self
.dec
813 m
.submodules
.dec_rc
= self
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
814 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
)
816 # copy instruction through...
817 for i
in [do
.insn
, dec_rc
.insn_in
, dec_oe
.insn_in
, ]:
818 comb
+= i
.eq(self
.dec
.opcode_in
)
820 # ...and subdecoders' input fields
821 comb
+= dec_rc
.sel_in
.eq(op
.rc_sel
)
822 comb
+= dec_oe
.sel_in
.eq(op
.rc_sel
) # XXX should be OE sel
825 comb
+= self
.do_copy("msr", msr
)
826 comb
+= self
.do_copy("cia", cia
)
828 # set up instruction type
829 # no op: defaults to OP_ILLEGAL
830 internal_op
= self
.op_get("internal_op")
831 comb
+= self
.do_copy("insn_type", internal_op
)
833 # function unit for decoded instruction: requires minor redirect
835 fn
= self
.op_get("function_unit")
836 spr
= Signal(10, reset_less
=True)
837 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
839 # Microwatt doesn't implement the partition table
840 # instead has PRTBL register (SPR) to point to process table
842 is_mmu_spr
= Signal()
843 comb
+= is_spr_mv
.eq((internal_op
== MicrOp
.OP_MTSPR
) |
844 (internal_op
== MicrOp
.OP_MFSPR
))
845 comb
+= is_mmu_spr
.eq((spr
== SPR
.DSISR
.value
) |
846 (spr
== SPR
.DAR
.value
) |
847 (spr
== SPR
.PRTBL
.value
) |
848 (spr
== SPR
.PIDR
.value
))
849 # MMU must receive MMU SPRs
850 with m
.If(is_spr_mv
& (fn
== Function
.SPR
) & is_mmu_spr
):
851 comb
+= self
.do_copy("fn_unit", Function
.NONE
)
852 comb
+= self
.do_copy("insn_type", MicrOp
.OP_ILLEGAL
)
853 # SPR pipe must *not* receive MMU SPRs
854 with m
.Elif(is_spr_mv
& (fn
== Function
.MMU
) & ~is_mmu_spr
):
855 comb
+= self
.do_copy("fn_unit", Function
.NONE
)
856 comb
+= self
.do_copy("insn_type", MicrOp
.OP_ILLEGAL
)
859 comb
+= self
.do_copy("fn_unit", fn
)
862 if self
.needs_field("zero_a", "in1_sel"):
863 m
.submodules
.dec_ai
= dec_ai
= DecodeAImm(self
.dec
)
864 comb
+= dec_ai
.sv_nz
.eq(self
.sv_a_nz
)
865 comb
+= dec_ai
.sel_in
.eq(op
.in1_sel
)
866 comb
+= self
.do_copy("zero_a", dec_ai
.immz_out
) # RA==0 detected
867 if self
.needs_field("imm_data", "in2_sel"):
868 m
.submodules
.dec_bi
= dec_bi
= DecodeBImm(self
.dec
)
869 comb
+= dec_bi
.sel_in
.eq(op
.in2_sel
)
870 comb
+= self
.do_copy("imm_data", dec_bi
.imm_out
) # imm in RB
873 comb
+= self
.do_copy("rc", dec_rc
.rc_out
)
874 comb
+= self
.do_copy("oe", dec_oe
.oe_out
)
876 # CR in/out - note: these MUST match with what happens in
878 rc_out
= self
.dec_rc
.rc_out
.data
879 with m
.Switch(op
.cr_out
):
880 with m
.Case(CROutSel
.CR0
, CROutSel
.CR1
):
881 comb
+= self
.do_copy("write_cr0", rc_out
) # only when RC=1
882 with m
.Case(CROutSel
.BF
, CROutSel
.BT
):
883 comb
+= self
.do_copy("write_cr0", 1)
885 comb
+= self
.do_copy("input_cr", self
.op_get("cr_in")) # CR in
886 comb
+= self
.do_copy("output_cr", self
.op_get("cr_out")) # CR out
888 # decoded/selected instruction flags
889 comb
+= self
.do_copy("data_len", self
.op_get("ldst_len"))
890 comb
+= self
.do_copy("invert_in", self
.op_get("inv_a"))
891 comb
+= self
.do_copy("invert_out", self
.op_get("inv_out"))
892 comb
+= self
.do_copy("input_carry", self
.op_get("cry_in"))
893 comb
+= self
.do_copy("output_carry", self
.op_get("cry_out"))
894 comb
+= self
.do_copy("is_32bit", self
.op_get("is_32b"))
895 comb
+= self
.do_copy("is_signed", self
.op_get("sgn"))
896 lk
= self
.op_get("lk")
899 comb
+= self
.do_copy("lk", self
.dec
.LK
) # XXX TODO: accessor
901 comb
+= self
.do_copy("byte_reverse", self
.op_get("br"))
902 comb
+= self
.do_copy("sign_extend", self
.op_get("sgn_ext"))
903 comb
+= self
.do_copy("ldst_mode", self
.op_get("upd")) # LD/ST mode
908 class PowerDecode2(PowerDecodeSubset
):
909 """PowerDecode2: the main instruction decoder.
911 whilst PowerDecode is responsible for decoding the actual opcode, this
912 module encapsulates further specialist, sparse information and
913 expansion of fields that is inconvenient to have in the CSV files.
914 for example: the encoding of the immediates, which are detected
915 and expanded out to their full value from an annotated (enum)
918 implicit register usage is also set up, here. for example: OP_BC
919 requires implicitly reading CTR, OP_RFID requires implicitly writing
922 in addition, PowerDecoder2 is responsible for detecting whether
923 instructions are illegal (or privileged) or not, and instead of
924 just leaving at that, *replacing* the instruction to execute with
925 a suitable alternative (trap).
927 LDSTExceptions are done the cycle _after_ they're detected (after
928 they come out of LDSTCompUnit). basically despite the instruction
929 being decoded, the results of the decode are completely ignored
930 and "exception.happened" used to set the "actual" instruction to
931 "OP_TRAP". the LDSTException data structure gets filled in,
932 in the CompTrapOpSubset and that's what it fills in SRR.
934 to make this work, TestIssuer must notice "exception.happened"
935 after the (failed) LD/ST and copies the LDSTException info from
936 the output, into here (PowerDecoder2). without incrementing PC.
939 def __init__(self
, dec
, opkls
=None, fn_name
=None, final
=False,
940 state
=None, svp64_en
=True, regreduce_en
=False):
941 super().__init
__(dec
, opkls
, fn_name
, final
, state
, svp64_en
,
943 self
.exc
= LDSTException("dec2_exc")
946 self
.cr_out_isvec
= Signal(1, name
="cr_out_isvec")
947 self
.cr_in_isvec
= Signal(1, name
="cr_in_isvec")
948 self
.cr_in_b_isvec
= Signal(1, name
="cr_in_b_isvec")
949 self
.cr_in_o_isvec
= Signal(1, name
="cr_in_o_isvec")
950 self
.in1_isvec
= Signal(1, name
="reg_a_isvec")
951 self
.in2_isvec
= Signal(1, name
="reg_b_isvec")
952 self
.in3_isvec
= Signal(1, name
="reg_c_isvec")
953 self
.o_isvec
= Signal(1, name
="reg_o_isvec")
954 self
.o2_isvec
= Signal(1, name
="reg_o2_isvec")
955 self
.no_in_vec
= Signal(1, name
="no_in_vec") # no inputs vector
956 self
.no_out_vec
= Signal(1, name
="no_out_vec") # no outputs vector
957 self
.loop_continue
= Signal(1, name
="loop_continue")
958 self
.rm_dec
= SVP64RMModeDecode("svp64_rm_dec")
960 self
.no_in_vec
= Const(1, 1)
961 self
.no_out_vec
= Const(1, 1)
962 self
.loop_continue
= Const(0, 1)
964 def get_col_subset(self
, opkls
):
965 subset
= super().get_col_subset(opkls
)
966 subset
.add("asmcode")
967 subset
.add("in1_sel")
968 subset
.add("in2_sel")
969 subset
.add("in3_sel")
970 subset
.add("out_sel")
976 subset
.add("sv_out2")
977 subset
.add("sv_cr_in")
978 subset
.add("sv_cr_out")
979 subset
.add("SV_Etype")
980 subset
.add("SV_Ptype")
982 subset
.add("internal_op")
986 def elaborate(self
, platform
):
987 m
= super().elaborate(platform
)
990 e_out
, op
, do_out
= self
.e
, self
.dec
.op
, self
.e
.do
991 dec_spr
, msr
, cia
, ext_irq
= state
.dec
, state
.msr
, state
.pc
, state
.eint
992 rc_out
= self
.dec_rc
.rc_out
.data
996 # fill in for a normal instruction (not an exception)
997 # copy over if non-exception, non-privileged etc. is detected
999 # set up submodule decoders
1000 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
, self
.regreduce_en
)
1001 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
)
1002 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
)
1003 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
, self
.regreduce_en
)
1004 m
.submodules
.dec_o2
= dec_o2
= DecodeOut2(self
.dec
)
1005 m
.submodules
.dec_cr_in
= self
.dec_cr_in
= DecodeCRIn(self
.dec
)
1006 m
.submodules
.dec_cr_out
= self
.dec_cr_out
= DecodeCROut(self
.dec
)
1007 comb
+= dec_a
.sv_nz
.eq(self
.sv_a_nz
)
1010 # and SVP64 Extra decoders
1011 m
.submodules
.crout_svdec
= crout_svdec
= SVP64CRExtra()
1012 m
.submodules
.crin_svdec
= crin_svdec
= SVP64CRExtra()
1013 m
.submodules
.crin_svdec_b
= crin_svdec_b
= SVP64CRExtra()
1014 m
.submodules
.crin_svdec_o
= crin_svdec_o
= SVP64CRExtra()
1015 m
.submodules
.in1_svdec
= in1_svdec
= SVP64RegExtra()
1016 m
.submodules
.in2_svdec
= in2_svdec
= SVP64RegExtra()
1017 m
.submodules
.in3_svdec
= in3_svdec
= SVP64RegExtra()
1018 m
.submodules
.o_svdec
= o_svdec
= SVP64RegExtra()
1019 m
.submodules
.o2_svdec
= o2_svdec
= SVP64RegExtra()
1021 # debug access to crout_svdec (used in get_pdecode_cr_out)
1022 self
.crout_svdec
= crout_svdec
1024 # and SVP64 RM mode decoder
1025 m
.submodules
.sv_rm_dec
= rm_dec
= self
.rm_dec
1027 # get the 5-bit reg data before svp64-munging it into 7-bit plus isvec
1028 reg
= Signal(5, reset_less
=True)
1030 # copy instruction through...
1031 for i
in [do
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
1032 self
.dec_cr_in
.insn_in
, self
.dec_cr_out
.insn_in
,
1033 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
]:
1034 comb
+= i
.eq(self
.dec
.opcode_in
)
1037 comb
+= self
.dec_cr_in
.sel_in
.eq(op
.cr_in
)
1038 comb
+= self
.dec_cr_out
.sel_in
.eq(op
.cr_out
)
1039 comb
+= self
.dec_cr_out
.rc_in
.eq(rc_out
)
1042 comb
+= self
.do_copy("read_cr_whole", self
.dec_cr_in
.whole_reg
)
1043 comb
+= self
.do_copy("write_cr_whole", self
.dec_cr_out
.whole_reg
)
1045 # ...and subdecoders' input fields
1046 comb
+= dec_a
.sel_in
.eq(op
.in1_sel
)
1047 comb
+= dec_b
.sel_in
.eq(op
.in2_sel
)
1048 comb
+= dec_c
.sel_in
.eq(op
.in3_sel
)
1049 comb
+= dec_o
.sel_in
.eq(op
.out_sel
)
1050 comb
+= dec_o2
.sel_in
.eq(op
.out_sel
)
1051 if hasattr(do
, "lk"):
1052 comb
+= dec_o2
.lk
.eq(do
.lk
)
1055 # now do the SVP64 munging. op.SV_Etype and op.sv_in1 comes from
1056 # PowerDecoder which in turn comes from LDST-RM*.csv and RM-*.csv
1057 # which in turn were auto-generated by sv_analysis.py
1058 extra
= self
.sv_rm
.extra
# SVP64 extra bits 10:18
1062 comb
+= crout_svdec
.idx
.eq(op
.sv_cr_out
) # SVP64 CR out
1063 comb
+= self
.cr_out_isvec
.eq(crout_svdec
.isvec
)
1066 # CR in - selection slightly different due to shared CR field sigh
1067 cr_a_idx
= Signal(SVEXTRA
)
1068 cr_b_idx
= Signal(SVEXTRA
)
1070 # these change slightly, when decoding BA/BB. really should have
1071 # their own separate CSV column: sv_cr_in1 and sv_cr_in2, but hey
1072 comb
+= cr_a_idx
.eq(op
.sv_cr_in
)
1073 comb
+= cr_b_idx
.eq(SVEXTRA
.NONE
)
1074 with m
.If(op
.sv_cr_in
== SVEXTRA
.Idx_1_2
.value
):
1075 comb
+= cr_a_idx
.eq(SVEXTRA
.Idx1
)
1076 comb
+= cr_b_idx
.eq(SVEXTRA
.Idx2
)
1078 comb
+= self
.cr_in_isvec
.eq(crin_svdec
.isvec
)
1079 comb
+= self
.cr_in_b_isvec
.eq(crin_svdec_b
.isvec
)
1080 comb
+= self
.cr_in_o_isvec
.eq(crin_svdec_o
.isvec
)
1082 # indices are slightly different, BA/BB mess sorted above
1083 comb
+= crin_svdec
.idx
.eq(cr_a_idx
) # SVP64 CR in A
1084 comb
+= crin_svdec_b
.idx
.eq(cr_b_idx
) # SVP64 CR in B
1085 comb
+= crin_svdec_o
.idx
.eq(op
.sv_cr_out
) # SVP64 CR out
1087 # get SVSTATE srcstep (TODO: elwidth etc.) needed below
1088 srcstep
= Signal
.like(self
.state
.svstate
.srcstep
)
1089 dststep
= Signal
.like(self
.state
.svstate
.dststep
)
1090 comb
+= srcstep
.eq(self
.state
.svstate
.srcstep
)
1091 comb
+= dststep
.eq(self
.state
.svstate
.dststep
)
1093 # registers a, b, c and out and out2 (LD/ST EA)
1094 for to_reg
, fromreg
, svdec
, out
in (
1095 (e
.read_reg1
, dec_a
.reg_out
, in1_svdec
, False),
1096 (e
.read_reg2
, dec_b
.reg_out
, in2_svdec
, False),
1097 (e
.read_reg3
, dec_c
.reg_out
, in3_svdec
, False),
1098 (e
.write_reg
, dec_o
.reg_out
, o_svdec
, True),
1099 (e
.write_ea
, dec_o2
.reg_out
, o2_svdec
, True)):
1100 comb
+= svdec
.extra
.eq(extra
) # EXTRA field of SVP64 RM
1101 comb
+= svdec
.etype
.eq(op
.SV_Etype
) # EXTRA2/3 for this insn
1102 comb
+= svdec
.reg_in
.eq(fromreg
.data
) # 3-bit (CR0/BC/BFA)
1103 comb
+= to_reg
.ok
.eq(fromreg
.ok
)
1104 # detect if Vectorised: add srcstep/dststep if yes.
1105 # to_reg is 7-bits, outs get dststep added, ins get srcstep
1106 with m
.If(svdec
.isvec
):
1107 step
= dststep
if out
else srcstep
1108 comb
+= to_reg
.data
.eq(step
+svdec
.reg_out
)
1110 comb
+= to_reg
.data
.eq(svdec
.reg_out
)
1112 comb
+= in1_svdec
.idx
.eq(op
.sv_in1
) # SVP64 reg #1 (in1_sel)
1113 comb
+= in2_svdec
.idx
.eq(op
.sv_in2
) # SVP64 reg #2 (in2_sel)
1114 comb
+= in3_svdec
.idx
.eq(op
.sv_in3
) # SVP64 reg #3 (in3_sel)
1115 comb
+= o_svdec
.idx
.eq(op
.sv_out
) # SVP64 output (out_sel)
1116 comb
+= o2_svdec
.idx
.eq(op
.sv_out2
) # SVP64 output (implicit)
1117 # XXX TODO - work out where this should come from. the problem is
1118 # that LD-with-update is implied (computed from "is instruction in
1119 # "update mode" rather than specified cleanly as its own CSV column
1121 # output reg-is-vectorised (and when no in/out is vectorised)
1122 comb
+= self
.in1_isvec
.eq(in1_svdec
.isvec
)
1123 comb
+= self
.in2_isvec
.eq(in2_svdec
.isvec
)
1124 comb
+= self
.in3_isvec
.eq(in3_svdec
.isvec
)
1125 comb
+= self
.o_isvec
.eq(o_svdec
.isvec
)
1126 comb
+= self
.o2_isvec
.eq(o2_svdec
.isvec
)
1127 # TODO add SPRs here. must be True when *all* are scalar
1128 l
= map(lambda svdec
: svdec
.isvec
, [in1_svdec
, in2_svdec
, in3_svdec
,
1129 crin_svdec
, crin_svdec_b
, crin_svdec_o
])
1130 comb
+= self
.no_in_vec
.eq(~
Cat(*l
).bool()) # all input scalar
1131 l
= map(lambda svdec
: svdec
.isvec
, [o2_svdec
, o_svdec
, crout_svdec
])
1132 comb
+= self
.no_out_vec
.eq(~
Cat(*l
).bool()) # all output scalar
1133 # now create a general-purpose "test" as to whether looping
1134 # should continue. this doesn't include predication bit-tests
1135 loop
= self
.loop_continue
1136 with m
.Switch(op
.SV_Ptype
):
1137 with m
.Case(SVPtype
.P2
.value
):
1139 # TODO: *and cache-inhibited LD/ST!*
1140 comb
+= loop
.eq(~
(self
.no_in_vec | self
.no_out_vec
))
1141 with m
.Case(SVPtype
.P1
.value
):
1142 # single-predication, test relies on dest only
1143 comb
+= loop
.eq(~self
.no_out_vec
)
1145 # not an SV operation, no looping
1148 # condition registers (CR)
1149 for to_reg
, cr
, name
, svdec
, out
in (
1150 (e
.read_cr1
, self
.dec_cr_in
, "cr_bitfield", crin_svdec
, 0),
1151 (e
.read_cr2
, self
.dec_cr_in
, "cr_bitfield_b", crin_svdec_b
, 0),
1152 (e
.read_cr3
, self
.dec_cr_in
, "cr_bitfield_o", crin_svdec_o
, 0),
1153 (e
.write_cr
, self
.dec_cr_out
, "cr_bitfield", crout_svdec
, 1)):
1154 fromreg
= getattr(cr
, name
)
1155 comb
+= svdec
.extra
.eq(extra
) # EXTRA field of SVP64 RM
1156 comb
+= svdec
.etype
.eq(op
.SV_Etype
) # EXTRA2/3 for this insn
1157 comb
+= svdec
.cr_in
.eq(fromreg
.data
) # 3-bit (CR0/BC/BFA)
1158 with m
.If(svdec
.isvec
):
1159 # check if this is CR0 or CR1: treated differently
1160 # (does not "listen" to EXTRA2/3 spec for a start)
1161 # also: the CRs start from completely different locations
1162 step
= dststep
if out
else srcstep
1163 with m
.If(cr
.sv_override
== 1): # CR0
1164 offs
= SVP64CROffs
.CR0
1165 comb
+= to_reg
.data
.eq(step
+offs
)
1166 with m
.Elif(cr
.sv_override
== 2): # CR1
1167 offs
= SVP64CROffs
.CR1
1168 comb
+= to_reg
.data
.eq(step
+1)
1170 comb
+= to_reg
.data
.eq(step
+svdec
.cr_out
) # 7-bit out
1172 comb
+= to_reg
.data
.eq(svdec
.cr_out
) # 7-bit output
1173 comb
+= to_reg
.ok
.eq(fromreg
.ok
)
1175 # sigh must determine if RA is nonzero (7 bit)
1176 comb
+= self
.sv_a_nz
.eq(e
.read_reg1
.data
!= Const(0, 7))
1178 # connect up to/from read/write GPRs
1179 for to_reg
, fromreg
in ((e
.read_reg1
, dec_a
.reg_out
),
1180 (e
.read_reg2
, dec_b
.reg_out
),
1181 (e
.read_reg3
, dec_c
.reg_out
),
1182 (e
.write_reg
, dec_o
.reg_out
),
1183 (e
.write_ea
, dec_o2
.reg_out
)):
1184 comb
+= to_reg
.data
.eq(fromreg
.data
)
1185 comb
+= to_reg
.ok
.eq(fromreg
.ok
)
1187 # connect up to/from read/write CRs
1188 for to_reg
, cr
, name
in (
1189 (e
.read_cr1
, self
.dec_cr_in
, "cr_bitfield", ),
1190 (e
.read_cr2
, self
.dec_cr_in
, "cr_bitfield_b", ),
1191 (e
.read_cr3
, self
.dec_cr_in
, "cr_bitfield_o", ),
1192 (e
.write_cr
, self
.dec_cr_out
, "cr_bitfield", )):
1193 fromreg
= getattr(cr
, name
)
1194 comb
+= to_reg
.data
.eq(fromreg
.data
)
1195 comb
+= to_reg
.ok
.eq(fromreg
.ok
)
1198 comb
+= e
.read_spr1
.eq(dec_a
.spr_out
)
1199 comb
+= e
.write_spr
.eq(dec_o
.spr_out
)
1202 comb
+= e
.read_fast1
.eq(dec_a
.fast_out
)
1203 comb
+= e
.read_fast2
.eq(dec_b
.fast_out
)
1204 comb
+= e
.write_fast1
.eq(dec_o
.fast_out
)
1205 comb
+= e
.write_fast2
.eq(dec_o2
.fast_out
)
1208 # connect up SVP64 RM Mode decoding
1209 fn
= self
.op_get("function_unit")
1210 comb
+= rm_dec
.fn_in
.eq(fn
) # decode needs to know if LD/ST type
1211 comb
+= rm_dec
.ptype_in
.eq(op
.SV_Ptype
) # Single/Twin predicated
1212 comb
+= rm_dec
.rc_in
.eq(rc_out
) # Rc=1
1213 comb
+= rm_dec
.rm_in
.eq(self
.sv_rm
) # SVP64 RM mode
1215 # sigh this is exactly the sort of thing for which the
1216 # decoder is designed to not need. MTSPR, MFSPR and others need
1217 # access to the XER bits. however setting e.oe is not appropriate
1218 with m
.If(op
.internal_op
== MicrOp
.OP_MFSPR
):
1219 comb
+= e
.xer_in
.eq(0b111) # SO, CA, OV
1220 with m
.If(op
.internal_op
== MicrOp
.OP_CMP
):
1221 comb
+= e
.xer_in
.eq(1<<XERRegs
.SO
) # SO
1222 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
1223 comb
+= e
.xer_out
.eq(1)
1225 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
1226 with m
.If(op
.internal_op
== MicrOp
.OP_TRAP
):
1227 # *DO NOT* call self.trap here. that would reset absolutely
1228 # everything including destroying read of RA and RB.
1229 comb
+= self
.do_copy("trapaddr", 0x70) # strip first nibble
1231 ####################
1232 # ok so the instruction's been decoded, blah blah, however
1233 # now we need to determine if it's actually going to go ahead...
1234 # *or* if in fact it's a privileged operation, whether there's
1235 # an external interrupt, etc. etc. this is a simple priority
1236 # if-elif-elif sequence. decrement takes highest priority,
1237 # EINT next highest, privileged operation third.
1239 # check if instruction is privileged
1240 is_priv_insn
= instr_is_priv(m
, op
.internal_op
, e
.do
.insn
)
1242 # different IRQ conditions
1243 ext_irq_ok
= Signal()
1244 dec_irq_ok
= Signal()
1249 comb
+= ext_irq_ok
.eq(ext_irq
& msr
[MSR
.EE
]) # v3.0B p944 (MSR.EE)
1250 comb
+= dec_irq_ok
.eq(dec_spr
[63] & msr
[MSR
.EE
]) # 6.5.11 p1076
1251 comb
+= priv_ok
.eq(is_priv_insn
& msr
[MSR
.PR
])
1252 comb
+= illeg_ok
.eq(op
.internal_op
== MicrOp
.OP_ILLEGAL
)
1254 # LD/ST exceptions. TestIssuer copies the exception info at us
1255 # after a failed LD/ST.
1256 with m
.If(exc
.happened
):
1257 with m
.If(exc
.alignment
):
1258 self
.trap(m
, TT
.PRIV
, 0x600)
1259 with m
.Elif(exc
.instr_fault
):
1260 with m
.If(exc
.segment_fault
):
1261 self
.trap(m
, TT
.PRIV
, 0x480)
1263 # pass exception info to trap to create SRR1
1264 self
.trap(m
, TT
.MEMEXC
, 0x400, exc
)
1266 with m
.If(exc
.segment_fault
):
1267 self
.trap(m
, TT
.PRIV
, 0x380)
1269 self
.trap(m
, TT
.PRIV
, 0x300)
1271 # decrement counter (v3.0B p1099): TODO 32-bit version (MSR.LPCR)
1272 with m
.Elif(dec_irq_ok
):
1273 self
.trap(m
, TT
.DEC
, 0x900) # v3.0B 6.5 p1065
1275 # external interrupt? only if MSR.EE set
1276 with m
.Elif(ext_irq_ok
):
1277 self
.trap(m
, TT
.EINT
, 0x500)
1279 # privileged instruction trap
1280 with m
.Elif(priv_ok
):
1281 self
.trap(m
, TT
.PRIV
, 0x700)
1283 # illegal instruction must redirect to trap. this is done by
1284 # *overwriting* the decoded instruction and starting again.
1285 # (note: the same goes for interrupts and for privileged operations,
1286 # just with different trapaddr and traptype)
1287 with m
.Elif(illeg_ok
):
1288 # illegal instruction trap
1289 self
.trap(m
, TT
.ILLEG
, 0x700)
1291 # no exception, just copy things to the output
1295 ####################
1296 # follow-up after trap/irq to set up SRR0/1
1298 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
1299 # Note: OP_SC could actually be modified to just be a trap
1300 with m
.If((do_out
.insn_type
== MicrOp
.OP_TRAP
) |
1301 (do_out
.insn_type
== MicrOp
.OP_SC
)):
1302 # TRAP write fast1 = SRR0
1303 comb
+= e_out
.write_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
1304 comb
+= e_out
.write_fast1
.ok
.eq(1)
1305 # TRAP write fast2 = SRR1
1306 comb
+= e_out
.write_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
1307 comb
+= e_out
.write_fast2
.ok
.eq(1)
1309 # RFID: needs to read SRR0/1
1310 with m
.If(do_out
.insn_type
== MicrOp
.OP_RFID
):
1311 # TRAP read fast1 = SRR0
1312 comb
+= e_out
.read_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
1313 comb
+= e_out
.read_fast1
.ok
.eq(1)
1314 # TRAP read fast2 = SRR1
1315 comb
+= e_out
.read_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
1316 comb
+= e_out
.read_fast2
.ok
.eq(1)
1318 # annoying simulator bug
1319 if hasattr(e_out
, "asmcode") and hasattr(self
.dec
.op
, "asmcode"):
1320 comb
+= e_out
.asmcode
.eq(self
.dec
.op
.asmcode
)
1324 def trap(self
, m
, traptype
, trapaddr
, exc
=None):
1325 """trap: this basically "rewrites" the decoded instruction as a trap
1328 op
, e
= self
.dec
.op
, self
.e
1329 comb
+= e
.eq(0) # reset eeeeeverything
1332 comb
+= self
.do_copy("insn", self
.dec
.opcode_in
, True)
1333 comb
+= self
.do_copy("insn_type", MicrOp
.OP_TRAP
, True)
1334 comb
+= self
.do_copy("fn_unit", Function
.TRAP
, True)
1335 comb
+= self
.do_copy("trapaddr", trapaddr
>> 4, True) # bottom 4 bits
1336 comb
+= self
.do_copy("traptype", traptype
, True) # request type
1337 comb
+= self
.do_copy("ldst_exc", exc
, True) # request type
1338 comb
+= self
.do_copy("msr", self
.state
.msr
, True) # copy of MSR "state"
1339 comb
+= self
.do_copy("cia", self
.state
.pc
, True) # copy of PC "state"
1343 def get_rdflags(e
, cu
):
1345 for idx
in range(cu
.n_src
):
1346 regfile
, regname
, _
= cu
.get_in_spec(idx
)
1347 rdflag
, read
= regspec_decode_read(e
, regfile
, regname
)
1349 print("rdflags", rdl
)
1353 if __name__
== '__main__':
1354 pdecode
= create_pdecode()
1355 dec2
= PowerDecode2(pdecode
)
1356 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
1357 with
open("dec2.il", "w") as f
: