1 """Power ISA Decoder second stage
3 based on Anton Blanchard microwatt decode2.vhdl
5 Note: OP_TRAP is used for exceptions and interrupts (micro-code style) by
6 over-riding the internal opcode when an exception is needed.
9 from nmigen
import Module
, Elaboratable
, Signal
, Mux
, Const
, Cat
, Repl
, Record
10 from nmigen
.cli
import rtlil
11 from nmutil
.util
import sel
13 from nmutil
.picker
import PriorityPicker
14 from nmutil
.iocontrol
import RecordObject
15 from nmutil
.extend
import exts
17 from openpower
.exceptions
import LDSTException
19 from openpower
.decoder
.power_svp64_prefix
import SVP64PrefixDecoder
20 from openpower
.decoder
.power_svp64_extra
import SVP64CRExtra
, SVP64RegExtra
21 from openpower
.decoder
.power_svp64_rm
import (SVP64RMModeDecode
,
22 sv_input_record_layout
,
24 from openpower
.sv
.svp64
import SVP64Rec
26 from openpower
.decoder
.power_regspec_map
import regspec_decode_read
27 from openpower
.decoder
.power_decoder
import (create_pdecode
,
28 create_pdecode_svp64_ldst
,
30 from openpower
.decoder
.power_enums
import (MicrOp
, CryIn
, Function
,
32 LdstLen
, In1Sel
, In2Sel
, In3Sel
,
33 OutSel
, SPRfull
, SPRreduced
,
34 RCOE
, SVP64LDSTmode
, LDSTMode
,
35 SVEXTRA
, SVEType
, SVPType
)
36 from openpower
.decoder
.decode2execute1
import (Decode2ToExecute1Type
, Data
,
39 from openpower
.consts
import (MSR
, SPEC
, EXTRA2
, EXTRA3
, SVP64P
, field
,
40 SPEC_SIZE
, SPECb
, SPEC_AUG_SIZE
, SVP64CROffs
,
41 FastRegsEnum
, XERRegsEnum
, TT
)
43 from openpower
.state
import CoreState
44 from openpower
.util
import (spr_to_fast
, spr_to_state
, log
)
47 def decode_spr_num(spr
):
48 return Cat(spr
[5:10], spr
[0:5])
51 def instr_is_priv(m
, op
, insn
):
52 """determines if the instruction is privileged or not
55 is_priv_insn
= Signal(reset_less
=True)
57 with m
.Case(MicrOp
.OP_ATTN
, MicrOp
.OP_MFMSR
, MicrOp
.OP_MTMSRD
,
58 MicrOp
.OP_MTMSR
, MicrOp
.OP_RFID
):
59 comb
+= is_priv_insn
.eq(1)
60 with m
.Case(MicrOp
.OP_TLBIE
):
61 comb
+= is_priv_insn
.eq(1)
62 with m
.Case(MicrOp
.OP_MFSPR
, MicrOp
.OP_MTSPR
):
63 with m
.If(insn
[20]): # field XFX.spr[-1] i think
64 comb
+= is_priv_insn
.eq(1)
68 class SPRMap(Elaboratable
):
69 """SPRMap: maps POWER9 SPR numbers to internal enum values, fast and slow
72 def __init__(self
, regreduce_en
):
73 self
.regreduce_en
= regreduce_en
79 self
.spr_i
= Signal(10, reset_less
=True)
80 self
.spr_o
= Data(SPR
, name
="spr_o")
81 self
.fast_o
= Data(4, name
="fast_o")
82 self
.state_o
= Data(3, name
="state_o")
84 def elaborate(self
, platform
):
90 with m
.Switch(self
.spr_i
):
91 for i
, x
in enumerate(SPR
):
93 m
.d
.comb
+= self
.spr_o
.data
.eq(i
)
94 m
.d
.comb
+= self
.spr_o
.ok
.eq(1)
95 for x
, v
in spr_to_fast
.items():
97 m
.d
.comb
+= self
.fast_o
.data
.eq(v
)
98 m
.d
.comb
+= self
.fast_o
.ok
.eq(1)
99 for x
, v
in spr_to_state
.items():
100 with m
.Case(x
.value
):
101 m
.d
.comb
+= self
.state_o
.data
.eq(v
)
102 m
.d
.comb
+= self
.state_o
.ok
.eq(1)
106 class DecodeA(Elaboratable
):
107 """DecodeA from instruction
109 decodes register RA, implicit and explicit CSRs
112 def __init__(self
, dec
, op
, regreduce_en
):
113 self
.regreduce_en
= regreduce_en
114 if self
.regreduce_en
:
120 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
121 self
.insn_in
= Signal(32, reset_less
=True)
122 self
.reg_out
= Data(5, name
="reg_a")
123 self
.spr_out
= Data(SPR
, "spr_a")
124 self
.fast_out
= Data(4, "fast_a")
125 self
.state_out
= Data(3, "state_a")
126 self
.sv_nz
= Signal(1)
128 def elaborate(self
, platform
):
133 m
.submodules
.sprmap
= sprmap
= SPRMap(self
.regreduce_en
)
135 # select Register A field, if *full 7 bits* are zero (2 more from SVP64)
136 ra
= Signal(5, reset_less
=True)
137 comb
+= ra
.eq(self
.dec
.RA
)
138 with m
.If((self
.sel_in
== In1Sel
.RA
) |
139 ((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
140 ((ra
!= Const(0, 5)) |
(self
.sv_nz
!= Const(0, 1))))):
141 comb
+= reg
.data
.eq(ra
)
144 # some Logic/ALU ops have RS as the 3rd arg, but no "RA".
145 # moved it to 1st position (in1_sel)... because
146 rs
= Signal(5, reset_less
=True)
147 comb
+= rs
.eq(self
.dec
.RS
)
148 with m
.If(self
.sel_in
== In1Sel
.RS
):
149 comb
+= reg
.data
.eq(rs
)
152 # select Register FRA field,
153 fra
= Signal(5, reset_less
=True)
154 comb
+= fra
.eq(self
.dec
.FRA
)
155 with m
.If(self
.sel_in
== In1Sel
.FRA
):
156 comb
+= reg
.data
.eq(fra
)
159 # select Register FRS field,
160 frs
= Signal(5, reset_less
=True)
161 comb
+= frs
.eq(self
.dec
.FRS
)
162 with m
.If(self
.sel_in
== In1Sel
.FRS
):
163 comb
+= reg
.data
.eq(frs
)
166 # select Register FRT field,
167 frt
= Signal(5, reset_less
=True)
168 comb
+= frt
.eq(self
.dec
.FRT
)
169 with m
.If(self
.sel_in
== In1Sel
.FRT
):
170 comb
+= reg
.data
.eq(frt
)
173 # decode Fast-SPR based on instruction type
174 with m
.Switch(op
.internal_op
):
176 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeOut
177 with m
.Case(MicrOp
.OP_BC
):
178 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
180 comb
+= self
.fast_out
.data
.eq(FastRegsEnum
.CTR
)
181 comb
+= self
.fast_out
.ok
.eq(1)
182 with m
.Case(MicrOp
.OP_BCREG
):
183 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
184 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
185 with m
.If(xo9
& ~xo5
):
187 comb
+= self
.fast_out
.data
.eq(FastRegsEnum
.CTR
)
188 comb
+= self
.fast_out
.ok
.eq(1)
190 # MFSPR move from SPRs
191 with m
.Case(MicrOp
.OP_MFSPR
):
192 spr
= Signal(10, reset_less
=True)
193 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
194 comb
+= sprmap
.spr_i
.eq(spr
)
195 comb
+= self
.spr_out
.eq(sprmap
.spr_o
)
196 comb
+= self
.fast_out
.eq(sprmap
.fast_o
)
197 comb
+= self
.state_out
.eq(sprmap
.state_o
)
202 class DecodeAImm(Elaboratable
):
203 """DecodeA immediate from instruction
205 decodes register RA, whether immediate-zero, implicit and
206 explicit CSRs. SVP64 mode requires 2 extra bits
209 def __init__(self
, dec
):
211 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
212 self
.immz_out
= Signal(reset_less
=True)
213 self
.sv_nz
= Signal(1) # EXTRA bits from SVP64
215 def elaborate(self
, platform
):
219 # zero immediate requested
220 ra
= Signal(5, reset_less
=True)
221 comb
+= ra
.eq(self
.dec
.RA
)
222 with m
.If((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
223 (ra
== Const(0, 5)) &
224 (self
.sv_nz
== Const(0, 1))):
225 comb
+= self
.immz_out
.eq(1)
230 class DecodeB(Elaboratable
):
231 """DecodeB from instruction
233 decodes register RB, different forms of immediate (signed, unsigned),
234 and implicit SPRs. register B is basically "lane 2" into the CompUnits.
235 by industry-standard convention, "lane 2" is where fully-decoded
236 immediates are muxed in.
239 def __init__(self
, dec
, op
):
242 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
243 self
.insn_in
= Signal(32, reset_less
=True)
244 self
.reg_out
= Data(7, "reg_b")
245 self
.reg_isvec
= Signal(1, name
="reg_b_isvec") # TODO: in reg_out
246 self
.fast_out
= Data(4, "fast_b")
248 def elaborate(self
, platform
):
254 # select Register B field
255 with m
.Switch(self
.sel_in
):
256 with m
.Case(In2Sel
.FRB
):
257 comb
+= reg
.data
.eq(self
.dec
.FRB
)
259 with m
.Case(In2Sel
.RB
):
260 comb
+= reg
.data
.eq(self
.dec
.RB
)
262 with m
.Case(In2Sel
.RS
):
263 # for M-Form shiftrot
264 comb
+= reg
.data
.eq(self
.dec
.RS
)
267 # decode SPR2 based on instruction type
268 # BCREG implicitly uses LR or TAR for 2nd reg
269 # CTR however is already in fast_spr1 *not* 2.
270 with m
.If(op
.internal_op
== MicrOp
.OP_BCREG
):
271 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
272 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
274 comb
+= self
.fast_out
.data
.eq(FastRegsEnum
.LR
)
275 comb
+= self
.fast_out
.ok
.eq(1)
277 comb
+= self
.fast_out
.data
.eq(FastRegsEnum
.TAR
)
278 comb
+= self
.fast_out
.ok
.eq(1)
283 class DecodeBImm(Elaboratable
):
284 """DecodeB immediate from instruction
287 def __init__(self
, dec
):
289 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
290 self
.imm_out
= Data(64, "imm_b")
292 def elaborate(self
, platform
):
296 # select Register B Immediate
297 with m
.Switch(self
.sel_in
):
298 with m
.Case(In2Sel
.CONST_UI
): # unsigned
299 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
)
300 comb
+= self
.imm_out
.ok
.eq(1)
301 with m
.Case(In2Sel
.CONST_SI
): # sign-extended 16-bit
302 si
= Signal(16, reset_less
=True)
303 comb
+= si
.eq(self
.dec
.SI
)
304 comb
+= self
.imm_out
.data
.eq(exts(si
, 16, 64))
305 comb
+= self
.imm_out
.ok
.eq(1)
306 with m
.Case(In2Sel
.CONST_SI_HI
): # sign-extended 16+16=32 bit
307 si_hi
= Signal(32, reset_less
=True)
308 comb
+= si_hi
.eq(self
.dec
.SI
<< 16)
309 comb
+= self
.imm_out
.data
.eq(exts(si_hi
, 32, 64))
310 comb
+= self
.imm_out
.ok
.eq(1)
311 with m
.Case(In2Sel
.CONST_UI_HI
): # unsigned
312 ui
= Signal(16, reset_less
=True)
313 comb
+= ui
.eq(self
.dec
.UI
)
314 comb
+= self
.imm_out
.data
.eq(ui
<< 16)
315 comb
+= self
.imm_out
.ok
.eq(1)
316 with m
.Case(In2Sel
.CONST_LI
): # sign-extend 24+2=26 bit
317 li
= Signal(26, reset_less
=True)
318 comb
+= li
.eq(self
.dec
.LI
<< 2)
319 comb
+= self
.imm_out
.data
.eq(exts(li
, 26, 64))
320 comb
+= self
.imm_out
.ok
.eq(1)
321 with m
.Case(In2Sel
.CONST_BD
): # sign-extend (14+2)=16 bit
322 bd
= Signal(16, reset_less
=True)
323 comb
+= bd
.eq(self
.dec
.BD
<< 2)
324 comb
+= self
.imm_out
.data
.eq(exts(bd
, 16, 64))
325 comb
+= self
.imm_out
.ok
.eq(1)
326 with m
.Case(In2Sel
.CONST_DS
): # sign-extended (14+2=16) bit
327 ds
= Signal(16, reset_less
=True)
328 comb
+= ds
.eq(self
.dec
.DS
<< 2)
329 comb
+= self
.imm_out
.data
.eq(exts(ds
, 16, 64))
330 comb
+= self
.imm_out
.ok
.eq(1)
331 with m
.Case(In2Sel
.CONST_M1
): # signed (-1)
332 comb
+= self
.imm_out
.data
.eq(~
Const(0, 64)) # all 1s
333 comb
+= self
.imm_out
.ok
.eq(1)
334 with m
.Case(In2Sel
.CONST_SH
): # unsigned - for shift
335 comb
+= self
.imm_out
.data
.eq(self
.dec
.sh
)
336 comb
+= self
.imm_out
.ok
.eq(1)
337 with m
.Case(In2Sel
.CONST_SH32
): # unsigned - for shift
338 comb
+= self
.imm_out
.data
.eq(self
.dec
.SH32
)
339 comb
+= self
.imm_out
.ok
.eq(1)
344 class DecodeC(Elaboratable
):
345 """DecodeC from instruction
347 decodes register RC. this is "lane 3" into some CompUnits (not many)
350 def __init__(self
, dec
, op
):
353 self
.sel_in
= Signal(In3Sel
, reset_less
=True)
354 self
.insn_in
= Signal(32, reset_less
=True)
355 self
.reg_out
= Data(5, "reg_c")
357 def elaborate(self
, platform
):
363 # select Register C field
364 with m
.Switch(self
.sel_in
):
365 with m
.Case(In3Sel
.RB
):
366 # for M-Form shiftrot
367 comb
+= reg
.data
.eq(self
.dec
.RB
)
369 with m
.Case(In3Sel
.FRS
):
370 comb
+= reg
.data
.eq(self
.dec
.FRS
)
372 with m
.Case(In3Sel
.FRA
):
373 comb
+= reg
.data
.eq(self
.dec
.FRA
)
375 with m
.Case(In3Sel
.FRC
):
376 comb
+= reg
.data
.eq(self
.dec
.FRC
)
378 with m
.Case(In3Sel
.RS
):
379 comb
+= reg
.data
.eq(self
.dec
.RS
)
381 with m
.Case(In3Sel
.RC
):
382 comb
+= reg
.data
.eq(self
.dec
.RC
)
384 with m
.Case(In3Sel
.RT
):
385 # for TLI-form ternlogi
386 comb
+= reg
.data
.eq(self
.dec
.RT
)
392 class DecodeOut(Elaboratable
):
393 """DecodeOut from instruction
395 decodes output register RA, RT, FRS, FRT, or SPR
398 def __init__(self
, dec
, op
, regreduce_en
):
399 self
.regreduce_en
= regreduce_en
400 if self
.regreduce_en
:
406 self
.sel_in
= Signal(OutSel
, reset_less
=True)
407 self
.insn_in
= Signal(32, reset_less
=True)
408 self
.reg_out
= Data(5, "reg_o")
409 self
.spr_out
= Data(SPR
, "spr_o")
410 self
.fast_out
= Data(4, "fast_o")
411 self
.state_out
= Data(3, "state_o")
413 def elaborate(self
, platform
):
416 m
.submodules
.sprmap
= sprmap
= SPRMap(self
.regreduce_en
)
420 # select Register out field
421 with m
.Switch(self
.sel_in
):
422 with m
.Case(OutSel
.FRS
):
423 comb
+= reg
.data
.eq(self
.dec
.FRS
)
425 with m
.Case(OutSel
.FRA
):
426 comb
+= reg
.data
.eq(self
.dec
.FRA
)
428 with m
.Case(OutSel
.FRT
):
429 comb
+= reg
.data
.eq(self
.dec
.FRT
)
431 with m
.Case(OutSel
.RT
):
432 comb
+= reg
.data
.eq(self
.dec
.RT
)
434 with m
.Case(OutSel
.RA
):
435 comb
+= reg
.data
.eq(self
.dec
.RA
)
437 with m
.Case(OutSel
.SPR
):
438 spr
= Signal(10, reset_less
=True)
439 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
440 # MFSPR move to SPRs - needs mapping
441 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
442 comb
+= sprmap
.spr_i
.eq(spr
)
443 comb
+= self
.spr_out
.eq(sprmap
.spr_o
)
444 comb
+= self
.fast_out
.eq(sprmap
.fast_o
)
445 comb
+= self
.state_out
.eq(sprmap
.state_o
)
448 with m
.Switch(op
.internal_op
):
450 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeA
451 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_BCREG
):
452 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
454 comb
+= self
.fast_out
.data
.eq(FastRegsEnum
.CTR
)
455 comb
+= self
.fast_out
.ok
.eq(1)
457 # RFID 1st spr (fast)
458 with m
.Case(MicrOp
.OP_RFID
):
459 comb
+= self
.fast_out
.data
.eq(FastRegsEnum
.SRR0
) # SRR0
460 comb
+= self
.fast_out
.ok
.eq(1)
465 class DecodeOut2(Elaboratable
):
466 """DecodeOut2 from instruction
468 decodes output registers (2nd one). note that RA is *implicit* below,
469 which now causes problems with SVP64
471 TODO: SVP64 is a little more complex, here. svp64 allows extending
472 by one more destination by having one more EXTRA field. RA-as-src
473 is not the same as RA-as-dest. limited in that it's the same first
474 5 bits (from the v3.0B opcode), but still kinda cool. mostly used
475 for operations that have src-as-dest: mostly this is LD/ST-with-update
476 but there are others.
479 def __init__(self
, dec
, op
):
482 self
.sel_in
= Signal(OutSel
, reset_less
=True)
483 self
.implicit_rs
= Signal(reset_less
=True) # SVP64 implicit RS/FRS
484 self
.implicit_from_rc
= Signal(reset_less
=True)# implicit RS from RC
485 self
.lk
= Signal(reset_less
=True)
486 self
.insn_in
= Signal(32, reset_less
=True)
487 self
.reg_out
= Data(5, "reg_o2")
488 self
.rs_en
= Signal(reset_less
=True) # FFT instruction detected
489 self
.fast_out
= Data(4, "fast_o2")
490 self
.fast_out3
= Data(4, "fast_o3")
492 def elaborate(self
, platform
):
496 #m.submodules.svdec = svdec = SVP64RegExtra()
498 # get the 5-bit reg data before svp64-munging it into 7-bit plus isvec
499 #reg = Signal(5, reset_less=True)
501 if hasattr(op
, "upd"):
502 # update mode LD/ST uses read-reg A also as an output
503 with m
.If(op
.upd
== LDSTMode
.update
):
504 comb
+= self
.reg_out
.data
.eq(self
.dec
.RA
)
505 comb
+= self
.reg_out
.ok
.eq(1)
507 # B, BC or BCREG: potential implicit register (LR) output
508 # these give bl, bcl, bclrl, etc.
509 with m
.Switch(op
.internal_op
):
511 # BC* implicit register (LR)
512 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_B
, MicrOp
.OP_BCREG
):
513 with m
.If(self
.lk
): # "link" mode
514 comb
+= self
.fast_out
.data
.eq(FastRegsEnum
.LR
) # LR
515 comb
+= self
.fast_out
.ok
.eq(1)
517 # RFID 2nd and 3rd spr (fast)
518 with m
.Case(MicrOp
.OP_RFID
):
519 comb
+= self
.fast_out
.data
.eq(FastRegsEnum
.SRR1
) # SRR1
520 comb
+= self
.fast_out
.ok
.eq(1)
521 comb
+= self
.fast_out3
.data
.eq(FastRegsEnum
.SVSRR0
) # SVSRR0
522 comb
+= self
.fast_out3
.ok
.eq(1)
524 # SVP64 FFT mode, FP mul-add: 2nd output reg (FRS) same as FRT
525 # will be offset by VL in hardware
526 # with m.Case(MicrOp.OP_FP_MADD):
527 with m
.If(self
.implicit_rs
):
528 with m
.If(self
.implicit_from_rc
):
529 comb
+= self
.reg_out
.data
.eq(self
.dec
.FRC
) # same as RC
531 comb
+= self
.reg_out
.data
.eq(self
.dec
.FRT
) # same as RT
532 comb
+= self
.reg_out
.ok
.eq(1)
533 comb
+= self
.rs_en
.eq(1)
538 class DecodeRC(Elaboratable
):
539 """DecodeRc from instruction
541 decodes Record bit Rc
544 def __init__(self
, dec
):
546 self
.sel_in
= Signal(RCOE
, reset_less
=True)
547 self
.insn_in
= Signal(32, reset_less
=True)
548 self
.rc_out
= Data(1, "rc")
550 def elaborate(self
, platform
):
554 # select Record bit out field
555 with m
.Switch(self
.sel_in
):
556 with m
.Case(RCOE
.RC
, RCOE
.RC_ONLY
):
557 comb
+= self
.rc_out
.data
.eq(self
.dec
.Rc
)
558 comb
+= self
.rc_out
.ok
.eq(1)
559 with m
.Case(RCOE
.ONE
):
560 comb
+= self
.rc_out
.data
.eq(1)
561 comb
+= self
.rc_out
.ok
.eq(1)
562 with m
.Case(RCOE
.NONE
):
563 comb
+= self
.rc_out
.data
.eq(0)
564 comb
+= self
.rc_out
.ok
.eq(1)
569 class DecodeOE(Elaboratable
):
570 """DecodeOE from instruction
572 decodes OE field: uses RC decode detection which has now been
573 updated to separate out RC_ONLY. all cases RC_ONLY are *NOT*
574 listening to the OE field, here.
577 def __init__(self
, dec
, op
):
580 self
.sel_in
= Signal(RCOE
, reset_less
=True)
581 self
.insn_in
= Signal(32, reset_less
=True)
582 self
.oe_out
= Data(1, "oe")
584 def elaborate(self
, platform
):
588 with m
.Switch(self
.sel_in
):
589 with m
.Case(RCOE
.RC
):
590 comb
+= self
.oe_out
.data
.eq(self
.dec
.OE
)
591 comb
+= self
.oe_out
.ok
.eq(1)
594 comb
+= self
.oe_out
.data
.eq(0)
595 comb
+= self
.oe_out
.ok
.eq(0)
600 class DecodeCRIn(Elaboratable
):
601 """Decodes input CR from instruction
603 CR indices - insn fields - (not the data *in* the CR) require only 3
604 bits because they refer to CR0-CR7
607 def __init__(self
, dec
, op
):
610 self
.sel_in
= Signal(CRInSel
, reset_less
=True)
611 self
.insn_in
= Signal(32, reset_less
=True)
612 self
.cr_bitfield
= Data(3, "cr_bitfield")
613 self
.cr_bitfield_b
= Data(3, "cr_bitfield_b")
614 self
.cr_bitfield_o
= Data(3, "cr_bitfield_o")
615 self
.whole_reg
= Data(8, "cr_fxm")
616 self
.sv_override
= Signal(2, reset_less
=True) # do not do EXTRA spec
618 def elaborate(self
, platform
):
622 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
625 # zero-initialisation
626 comb
+= self
.cr_bitfield
.ok
.eq(0)
627 comb
+= self
.cr_bitfield_b
.ok
.eq(0)
628 comb
+= self
.cr_bitfield_o
.ok
.eq(0)
629 comb
+= self
.whole_reg
.ok
.eq(0)
630 comb
+= self
.sv_override
.eq(0)
632 # select the relevant CR bitfields
633 with m
.Switch(self
.sel_in
):
634 with m
.Case(CRInSel
.NONE
):
635 pass # No bitfield activated
636 with m
.Case(CRInSel
.CR0
):
637 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
638 comb
+= self
.cr_bitfield
.ok
.eq(1)
639 comb
+= self
.sv_override
.eq(1)
640 with m
.Case(CRInSel
.CR1
):
641 comb
+= self
.cr_bitfield
.data
.eq(1) # CR1 (MSB0 numbering)
642 comb
+= self
.cr_bitfield
.ok
.eq(1)
643 comb
+= self
.sv_override
.eq(2)
644 with m
.Case(CRInSel
.BI
):
645 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BI
[2:5])
646 comb
+= self
.cr_bitfield
.ok
.eq(1)
647 with m
.Case(CRInSel
.BFA
):
648 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BFA
)
649 comb
+= self
.cr_bitfield
.ok
.eq(1)
650 with m
.Case(CRInSel
.BA_BB
):
651 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BA
[2:5])
652 comb
+= self
.cr_bitfield
.ok
.eq(1)
653 comb
+= self
.cr_bitfield_b
.data
.eq(self
.dec
.BB
[2:5])
654 comb
+= self
.cr_bitfield_b
.ok
.eq(1)
655 comb
+= self
.cr_bitfield_o
.data
.eq(self
.dec
.BT
[2:5])
656 comb
+= self
.cr_bitfield_o
.ok
.eq(1)
657 with m
.Case(CRInSel
.BFA_BFB_BF
):
658 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormCRB
.BFA
)
659 comb
+= self
.cr_bitfield
.ok
.eq(1)
660 comb
+= self
.cr_bitfield_b
.data
.eq(self
.dec
.FormCRB
.BFB
)
661 comb
+= self
.cr_bitfield_b
.ok
.eq(1)
662 comb
+= self
.cr_bitfield_o
.data
.eq(self
.dec
.FormCRB
.BF
)
663 comb
+= self
.cr_bitfield_o
.ok
.eq(1)
664 with m
.Case(CRInSel
.BC
):
665 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BC
[2:5])
666 comb
+= self
.cr_bitfield
.ok
.eq(1)
667 with m
.Case(CRInSel
.WHOLE_REG
):
668 comb
+= self
.whole_reg
.ok
.eq(1)
669 move_one
= Signal(reset_less
=True)
670 comb
+= move_one
.eq(self
.insn_in
[20]) # MSB0 bit 11
671 with m
.If((op
.internal_op
== MicrOp
.OP_MFCR
) & move_one
):
672 # must one-hot the FXM field
673 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
674 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
676 # otherwise use all of it
677 comb
+= self
.whole_reg
.data
.eq(0xff)
682 class DecodeCROut(Elaboratable
):
683 """Decodes input CR from instruction
685 CR indices - insn fields - (not the data *in* the CR) require only 3
686 bits because they refer to CR0-CR7
689 def __init__(self
, dec
, op
):
692 self
.rc_in
= Signal(reset_less
=True)
693 self
.sel_in
= Signal(CROutSel
, reset_less
=True)
694 self
.insn_in
= Signal(32, reset_less
=True)
695 self
.cr_bitfield
= Data(3, "cr_bitfield")
696 self
.whole_reg
= Data(8, "cr_fxm")
697 self
.sv_override
= Signal(2, reset_less
=True) # do not do EXTRA spec
698 self
.cr_5bit
= Signal(reset_less
=True) # set True for 5-bit
699 self
.cr_2bit
= Signal(2, reset_less
=True) # get lowest 2 bits
701 def elaborate(self
, platform
):
705 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
708 comb
+= self
.cr_bitfield
.ok
.eq(0)
709 comb
+= self
.whole_reg
.ok
.eq(0)
710 comb
+= self
.sv_override
.eq(0)
711 comb
+= self
.cr_5bit
.eq(0)
713 # please note these MUST match (setting of cr_bitfield.ok) exactly
714 # with write_cr0 below in PowerDecoder2. the reason it's separated
715 # is to avoid having duplicate copies of DecodeCROut in multiple
716 # PowerDecoderSubsets. register decoding should be a one-off in
717 # PowerDecoder2. see https://bugs.libre-soc.org/show_bug.cgi?id=606
719 with m
.Switch(self
.sel_in
):
720 with m
.Case(CROutSel
.NONE
):
721 pass # No bitfield activated
722 with m
.Case(CROutSel
.CR0
):
723 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
724 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
725 comb
+= self
.sv_override
.eq(1)
726 with m
.Case(CROutSel
.CR1
):
727 comb
+= self
.cr_bitfield
.data
.eq(1) # CR1 (MSB0 numbering)
728 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
729 comb
+= self
.sv_override
.eq(2)
730 with m
.Case(CROutSel
.BF
):
731 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BF
)
732 comb
+= self
.cr_bitfield
.ok
.eq(1)
733 with m
.Case(CROutSel
.BT
):
734 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormXL
.BT
[2:5])
735 comb
+= self
.cr_bitfield
.ok
.eq(1)
736 comb
+= self
.cr_5bit
.eq(1)
737 comb
+= self
.cr_2bit
.eq(self
.dec
.FormXL
.BT
[0:2])
738 with m
.Case(CROutSel
.WHOLE_REG
):
739 comb
+= self
.whole_reg
.ok
.eq(1)
740 move_one
= Signal(reset_less
=True)
741 comb
+= move_one
.eq(self
.insn_in
[20])
742 with m
.If((op
.internal_op
== MicrOp
.OP_MTCRF
)):
744 # must one-hot the FXM field
745 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
746 with m
.If(ppick
.en_o
):
747 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
749 comb
+= self
.whole_reg
.data
.eq(0b00000001) # CR7
751 comb
+= self
.whole_reg
.data
.eq(self
.dec
.FXM
)
753 # otherwise use all of it
754 comb
+= self
.whole_reg
.data
.eq(0xff)
759 # dictionary of Input Record field names that, if they exist,
760 # will need a corresponding CSV Decoder file column (actually, PowerOp)
761 # to be decoded (this includes the single bit names)
762 record_names
= {'insn_type': 'internal_op',
763 'fn_unit': 'function_unit',
764 'SV_Ptype': 'SV_Ptype',
765 'SV_mode': 'SV_mode',
769 'imm_data': 'in2_sel',
770 'invert_in': 'inv_a',
771 'invert_out': 'inv_out',
774 'output_carry': 'cry_out',
775 'input_carry': 'cry_in',
776 'is_32bit': 'is_32b',
779 'data_len': 'ldst_len',
781 'byte_reverse': 'br',
782 'sign_extend': 'sgn_ext',
787 class PowerDecodeSubset(Elaboratable
):
788 """PowerDecodeSubset: dynamic subset decoder
790 only fields actually requested are copied over. hence, "subset" (duh).
793 def __init__(self
, dec
, opkls
=None, fn_name
=None, final
=False, state
=None,
794 svp64_en
=True, regreduce_en
=False, fp_en
=False):
796 self
.svp64_en
= svp64_en
797 self
.regreduce_en
= regreduce_en
800 self
.is_svp64_mode
= Signal() # mark decoding as SVP64 Mode
801 self
.implicit_rs
= Signal() # implicit RS/FRS
802 self
.extend_rb_maxvl
= Signal() # jumps RB by an additional MAXVL
803 self
.extend_rc_maxvl
= Signal() # jumps RS by MAXVL from RC
804 self
.sv_rm
= SVP64Rec(name
="dec_svp64") # SVP64 RM field
805 self
.rm_dec
= SVP64RMModeDecode("svp64_rm_dec")
806 # set these to the predicate mask bits needed for the ALU
807 self
.pred_sm
= Signal() # TODO expand to SIMD mask width
808 self
.pred_dm
= Signal() # TODO expand to SIMD mask width
809 self
.sv_a_nz
= Signal(1)
812 self
.fn_name
= fn_name
814 opkls
= Decode2ToOperand
815 self
.do
= opkls(fn_name
)
817 col_subset
= self
.get_col_subset(self
.do
)
818 row_subset
= self
.rowsubsetfn
823 # "conditions" for Decoders, to enable some weird and wonderful
824 # alternatives. useful for PCR (Program Compatibility Register)
825 # amongst other things
828 # XXX NO 'SVP64FFT': self.use_svp64_fft,
833 # only needed for "main" PowerDecode2
835 self
.e
= Decode2ToExecute1Type(name
=self
.fn_name
, do
=self
.do
,
836 regreduce_en
=regreduce_en
)
838 # create decoder if one not already given
840 dec
= create_pdecode(name
=fn_name
, col_subset
=col_subset
,
841 row_subset
=row_subset
,
842 conditions
=conditions
, include_fp
=fp_en
)
845 # set up a copy of the PowerOp
846 self
.op
= PowerOp
.like(self
.dec
.op
)
848 # state information needed by the Decoder
850 state
= CoreState("dec2")
853 def get_col_subset(self
, do
):
854 subset
= {'cr_in', 'cr_out', 'rc_sel'} # needed, non-optional
855 for k
, v
in record_names
.items():
858 log("get_col_subset", self
.fn_name
, do
.fields
, subset
)
861 def rowsubsetfn(self
, opcode
, row
):
862 """select per-Function-Unit subset of opcodes to be processed
864 normally this just looks at the "unit" column. MMU is different
865 in that it processes specific SPR set/get operations that the SPR
868 return (row
['unit'] == self
.fn_name
or
869 # sigh a dreadful hack: MTSPR and MFSPR need to be processed
870 # by the MMU pipeline so we direct those opcodes to MMU **AND**
871 # SPR pipelines, then selectively weed out the SPRs that should
872 # or should not not go to each pipeline, further down.
873 # really this should be done by modifying the CSV syntax
874 # to support multiple tasks (unit column multiple entries)
875 # see https://bugs.libre-soc.org/show_bug.cgi?id=310
876 (self
.fn_name
== 'MMU' and row
['unit'] == 'SPR' and
877 row
['internal op'] in ['OP_MTSPR', 'OP_MFSPR']) or
878 # urrr... and the KAIVB SPR, which must also be redirected
879 # (to the TRAP pipeline)
880 # see https://bugs.libre-soc.org/show_bug.cgi?id=859
881 (self
.fn_name
== 'TRAP' and row
['unit'] == 'SPR' and
882 row
['internal op'] in ['OP_MTSPR', 'OP_MFSPR'])
886 ports
= self
.dec
.ports() + self
.e
.ports()
888 ports
+= self
.sv_rm
.ports()
889 ports
.append(self
.is_svp64_mode
)
890 ports
.append(self
.implicit_rs
)
893 def needs_field(self
, field
, op_field
):
898 return hasattr(do
, field
) and self
.op_get(op_field
) is not None
900 def do_get(self
, field
, final
=False):
901 if final
or self
.final
:
905 return getattr(do
, field
, None)
907 def do_copy(self
, field
, val
, final
=False):
908 df
= self
.do_get(field
, final
)
909 if df
is not None and val
is not None:
913 def op_get(self
, op_field
):
914 return getattr(self
.op
, op_field
, None)
916 def elaborate(self
, platform
):
917 if self
.regreduce_en
:
924 op
, do
= self
.dec
.op
, self
.do
925 msr
, cia
, svstate
= state
.msr
, state
.pc
, state
.svstate
926 # fill in for a normal instruction (not an exception)
927 # copy over if non-exception, non-privileged etc. is detected
929 if self
.fn_name
is None:
932 name
= self
.fn_name
+ "tmp"
933 self
.e_tmp
= Decode2ToExecute1Type(name
=name
, opkls
=self
.opkls
,
934 regreduce_en
=self
.regreduce_en
)
936 # set up submodule decoders
937 m
.submodules
.dec
= dec
= self
.dec
938 m
.submodules
.dec_rc
= self
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
939 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
, op
)
942 # and SVP64 RM mode decoder
943 m
.submodules
.sv_rm_dec
= rm_dec
= self
.rm_dec
945 # copy op from decoder
946 comb
+= self
.op
.eq(self
.dec
.op
)
948 # copy instruction through...
949 for i
in [do
.insn
, dec_rc
.insn_in
, dec_oe
.insn_in
, ]:
950 comb
+= i
.eq(self
.dec
.opcode_in
)
952 # ...and subdecoders' input fields
953 comb
+= dec_rc
.sel_in
.eq(self
.op_get("rc_sel"))
954 comb
+= dec_oe
.sel_in
.eq(self
.op_get("rc_sel")) # XXX should be OE sel
957 comb
+= self
.do_copy("msr", msr
)
958 comb
+= self
.do_copy("cia", cia
)
959 comb
+= self
.do_copy("svstate", svstate
)
961 # set up instruction type
962 # no op: defaults to OP_ILLEGAL
963 internal_op
= self
.op_get("internal_op")
964 comb
+= self
.do_copy("insn_type", internal_op
)
966 # function unit for decoded instruction: requires minor redirect
968 fn
= self
.op_get("function_unit")
969 spr
= Signal(10, reset_less
=True)
970 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
972 # Microwatt doesn't implement the partition table
973 # instead has PRTBL register (SPR) to point to process table
974 # Kestrel has a KAIVB SPR to "rebase" exceptions. rebasing is normally
975 # done with Hypervisor Mode which is not implemented (yet)
977 is_mmu_spr
= Signal()
978 is_trap_spr
= Signal()
979 comb
+= is_spr_mv
.eq((internal_op
== MicrOp
.OP_MTSPR
) |
980 (internal_op
== MicrOp
.OP_MFSPR
))
981 comb
+= is_mmu_spr
.eq((spr
== SPR
.DSISR
.value
) |
982 (spr
== SPR
.DAR
.value
) |
983 (spr
== SPR
.PRTBL
.value
) |
984 (spr
== SPR
.PIDR
.value
))
985 comb
+= is_trap_spr
.eq((spr
== SPR
.KAIVB
.value
)
987 # MMU must receive MMU SPRs
988 with m
.If(is_spr_mv
& (fn
== Function
.SPR
) & is_mmu_spr
):
989 comb
+= self
.do_copy("fn_unit", Function
.MMU
)
990 comb
+= self
.do_copy("insn_type", internal_op
)
991 # TRAP must receive TRAP SPR KAIVB
992 with m
.If(is_spr_mv
& (fn
== Function
.SPR
) & is_trap_spr
):
993 comb
+= self
.do_copy("fn_unit", Function
.TRAP
)
994 comb
+= self
.do_copy("insn_type", internal_op
)
995 # SPR pipe must *not* receive MMU or TRAP SPRs
996 with m
.Elif(is_spr_mv
& ((fn
== Function
.MMU
) & ~is_mmu_spr
) &
997 ((fn
== Function
.TRAP
) & ~is_trap_spr
)):
998 comb
+= self
.do_copy("fn_unit", Function
.NONE
)
999 comb
+= self
.do_copy("insn_type", MicrOp
.OP_ILLEGAL
)
1002 comb
+= self
.do_copy("fn_unit", fn
)
1005 if self
.needs_field("zero_a", "in1_sel"):
1006 m
.submodules
.dec_ai
= dec_ai
= DecodeAImm(self
.dec
)
1007 comb
+= dec_ai
.sv_nz
.eq(self
.sv_a_nz
)
1008 comb
+= dec_ai
.sel_in
.eq(self
.op_get("in1_sel"))
1009 comb
+= self
.do_copy("zero_a", dec_ai
.immz_out
) # RA==0 detected
1010 if self
.needs_field("imm_data", "in2_sel"):
1011 m
.submodules
.dec_bi
= dec_bi
= DecodeBImm(self
.dec
)
1012 comb
+= dec_bi
.sel_in
.eq(self
.op_get("in2_sel"))
1013 comb
+= self
.do_copy("imm_data", dec_bi
.imm_out
) # imm in RB
1015 # CR in/out - note: these MUST match with what happens in
1017 rc_out
= self
.dec_rc
.rc_out
.data
1018 with m
.Switch(self
.op_get("cr_out")):
1019 with m
.Case(CROutSel
.CR0
, CROutSel
.CR1
):
1020 comb
+= self
.do_copy("write_cr0", rc_out
) # only when RC=1
1021 with m
.Case(CROutSel
.BF
, CROutSel
.BT
):
1022 comb
+= self
.do_copy("write_cr0", 1)
1024 comb
+= self
.do_copy("input_cr", self
.op_get("cr_in")) # CR in
1025 comb
+= self
.do_copy("output_cr", self
.op_get("cr_out")) # CR out
1028 # connect up SVP64 RM Mode decoding. however... we need a shorter
1029 # path, for the LDST bit-reverse detection. so perform partial
1030 # decode when SVP64 is detected. then, bit-reverse mode can be
1031 # quickly determined, and the Decoder result MUXed over to
1032 # the alternative decoder, svdecldst. what a mess... *sigh*
1033 sv_ptype
= self
.op_get("SV_Ptype")
1034 sv_mode
= self
.op_get("SV_mode")
1035 fn
= self
.op_get("function_unit")
1036 comb
+= rm_dec
.sv_mode
.eq(sv_mode
) # BRANCH/CROP/LDST_IMM etc.
1037 comb
+= rm_dec
.fn_in
.eq(fn
) # decode needs to know Fn type
1038 comb
+= rm_dec
.ptype_in
.eq(sv_ptype
) # Single/Twin predicated
1039 comb
+= rm_dec
.rc_in
.eq(rc_out
) # Rc=1
1040 comb
+= rm_dec
.rm_in
.eq(self
.sv_rm
) # SVP64 RM mode
1041 if self
.needs_field("imm_data", "in2_sel"):
1042 bzero
= dec_bi
.imm_out
.ok
& ~dec_bi
.imm_out
.data
.bool()
1043 comb
+= rm_dec
.ldst_imz_in
.eq(bzero
) # B immediate is zero
1045 # main PowerDecoder2 determines if different SVP64 modes enabled
1046 # detect if SVP64 FFT mode enabled (really bad hack),
1047 # exclude fcfids and others
1048 # XXX this is a REALLY bad hack, REALLY has to be done better.
1049 # likely with a sub-decoder.
1050 # what this ultimately does is enable the 2nd implicit register
1051 # (FRS) for SVP64-decoding. all of these instructions are
1052 # 3-in 2-out but there is not enough room either in the
1053 # opcode *or* EXTRA2/3 to specify a 5th operand.
1055 comb
+= major
.eq(self
.dec
.opcode_in
[26:32])
1057 comb
+= xo
.eq(self
.dec
.opcode_in
[1:11])
1058 comb
+= self
.implicit_rs
.eq(0)
1059 comb
+= self
.extend_rb_maxvl
.eq(0)
1060 comb
+= self
.extend_rc_maxvl
.eq(0)
1061 # implicit RS for major 59
1062 with m
.If((major
== 59) & xo
.matches(
1063 '-----00100', # ffmsubs
1064 '-----00101', # ffmadds
1065 '-----00110', # ffnmsubs
1066 '-----00111', # ffnmadds
1067 '1111100000', # ffadds
1068 '-----11011', # fdmadds
1070 comb
+= self
.implicit_rs
.eq(1)
1071 comb
+= self
.extend_rb_maxvl
.eq(1) # extend RB
1073 comb
+= xo6
.eq(self
.dec
.opcode_in
[0:6])
1074 # implicit RS for major 4
1075 with m
.If((major
== 4) & xo6
.matches(
1078 '111001', # maddedus
1079 '111010', # divmod2du
1083 comb
+= self
.implicit_rs
.eq(1)
1084 comb
+= self
.extend_rc_maxvl
.eq(1) # RS=RT+MAXVL or RS=RC
1085 # implicit RS for major 22, integer maddsubrs
1086 with m
.If((major
== 22) & xo6
.matches(
1087 '-01000', # maddsubrs
1091 comb
+= self
.implicit_rs
.eq(1)
1092 comb
+= self
.extend_rb_maxvl
.eq(1) # extend RB
1095 comb
+= self
.do_copy("rc", dec_rc
.rc_out
)
1097 # OE only enabled when SVP64 not active
1098 with m
.If(~self
.is_svp64_mode
):
1099 comb
+= self
.do_copy("oe", dec_oe
.oe_out
)
1100 # RC1 overrides Rc if rc type is NONE or ONE or Rc=0, in svp64_mode
1101 # for instructions with a forced-Rc=1 (stbcx., pcdec.)
1102 # the RC1 RM bit *becomes* Rc=0/1, but for instructions
1103 # that have Rc=0/1 then when Rc=0 RC1 *becomes* (replaces) Rc.
1104 with m
.Elif((dec_rc
.sel_in
.matches(RCOE
.RC
, RCOE
.RC_ONLY
) &
1105 dec_rc
.rc_out
.data
== 0) |
1106 (dec_rc
.sel_in
== RCOE
.ONE
)):
1107 RC1
= Data(1, "RC1")
1108 comb
+= RC1
.ok
.eq(rm_dec
.RC1
)
1109 comb
+= RC1
.RC1
.eq(rm_dec
.RC1
)
1110 comb
+= self
.do_copy("rc", RC1
)
1112 comb
+= self
.do_copy("oe", dec_oe
.oe_out
)
1114 # decoded/selected instruction flags
1115 comb
+= self
.do_copy("data_len", self
.op_get("ldst_len"))
1116 comb
+= self
.do_copy("invert_in", self
.op_get("inv_a"))
1117 comb
+= self
.do_copy("invert_out", self
.op_get("inv_out"))
1118 comb
+= self
.do_copy("input_carry", self
.op_get("cry_in"))
1119 comb
+= self
.do_copy("output_carry", self
.op_get("cry_out"))
1120 comb
+= self
.do_copy("is_32bit", self
.op_get("is_32b"))
1121 comb
+= self
.do_copy("is_signed", self
.op_get("sgn"))
1122 lk
= self
.op_get("lk")
1125 comb
+= self
.do_copy("lk", self
.dec
.LK
) # XXX TODO: accessor
1127 comb
+= self
.do_copy("byte_reverse", self
.op_get("br"))
1128 comb
+= self
.do_copy("sign_extend", self
.op_get("sgn_ext"))
1129 comb
+= self
.do_copy("ldst_mode", self
.op_get("upd")) # LD/ST mode
1130 comb
+= self
.do_copy("reserve", self
.op_get("rsrv")) # atomic
1132 # copy over SVP64 input record fields (if they exist)
1134 # TODO, really do we have to do these explicitly?? sigh
1135 # for (field, _) in sv_input_record_layout:
1136 # comb += self.do_copy(field, self.rm_dec.op_get(field))
1137 comb
+= self
.do_copy("sv_saturate", self
.rm_dec
.saturate
)
1138 comb
+= self
.do_copy("sv_Ptype", self
.rm_dec
.ptype_in
)
1139 comb
+= self
.do_copy("sv_ldstmode", self
.rm_dec
.ldstmode
)
1140 # these get set up based on incoming mask bits. TODO:
1141 # pass in multiple bits (later, when SIMD backends are enabled)
1142 with m
.If(self
.rm_dec
.pred_sz
):
1143 comb
+= self
.do_copy("sv_pred_sz", ~self
.pred_sm
)
1144 with m
.If(self
.rm_dec
.pred_dz
):
1145 comb
+= self
.do_copy("sv_pred_dz", ~self
.pred_dm
)
1150 class PowerDecode2(PowerDecodeSubset
):
1151 """PowerDecode2: the main instruction decoder.
1153 whilst PowerDecode is responsible for decoding the actual opcode, this
1154 module encapsulates further specialist, sparse information and
1155 expansion of fields that is inconvenient to have in the CSV files.
1156 for example: the encoding of the immediates, which are detected
1157 and expanded out to their full value from an annotated (enum)
1160 implicit register usage is also set up, here. for example: OP_BC
1161 requires implicitly reading CTR, OP_RFID requires implicitly writing
1164 in addition, PowerDecoder2 is responsible for detecting whether
1165 instructions are illegal (or privileged) or not, and instead of
1166 just leaving at that, *replacing* the instruction to execute with
1167 a suitable alternative (trap).
1169 LDSTExceptions are done the cycle _after_ they're detected (after
1170 they come out of LDSTCompUnit). basically despite the instruction
1171 being decoded, the results of the decode are completely ignored
1172 and "exception.happened" used to set the "actual" instruction to
1173 "OP_TRAP". the LDSTException data structure gets filled in,
1174 in the CompTrapOpSubset and that's what it fills in SRR.
1176 to make this work, TestIssuer must notice "exception.happened"
1177 after the (failed) LD/ST and copies the LDSTException info from
1178 the output, into here (PowerDecoder2). without incrementing PC.
1180 also instr_fault works the same way: the instruction is "rewritten"
1181 so that the "fake" op that gets created is OP_FETCH_FAILED
1184 def __init__(self
, dec
, opkls
=None, fn_name
=None, final
=False,
1185 state
=None, svp64_en
=True, regreduce_en
=False, fp_en
=False):
1186 super().__init
__(dec
, opkls
, fn_name
, final
, state
, svp64_en
,
1187 regreduce_en
=False, fp_en
=fp_en
)
1188 self
.ldst_exc
= LDSTException("dec2_exc") # rewrites as OP_TRAP
1189 self
.instr_fault
= Signal() # rewrites instruction as OP_FETCH_FAILED
1190 self
.crout_5bit
= Signal() # CR out is 5-bit
1193 self
.cr_out_isvec
= Signal(1, name
="cr_out_isvec")
1194 self
.cr_in_isvec
= Signal(1, name
="cr_in_isvec")
1195 self
.cr_in_b_isvec
= Signal(1, name
="cr_in_b_isvec")
1196 self
.cr_in_o_isvec
= Signal(1, name
="cr_in_o_isvec")
1197 self
.in1_isvec
= Signal(1, name
="reg_a_isvec")
1198 self
.in2_isvec
= Signal(1, name
="reg_b_isvec")
1199 self
.in3_isvec
= Signal(1, name
="reg_c_isvec")
1200 self
.o_isvec
= Signal(7, name
="reg_o_isvec")
1201 self
.o2_isvec
= Signal(7, name
="reg_o2_isvec")
1202 self
.in1_step
= Signal(7, name
="reg_a_step")
1203 self
.in2_step
= Signal(7, name
="reg_b_step")
1204 self
.in3_step
= Signal(7, name
="reg_c_step")
1205 self
.o_step
= Signal(7, name
="reg_o_step")
1206 self
.o2_step
= Signal(7, name
="reg_o2_step")
1207 self
.remap_active
= Signal(5, name
="remap_active") # per reg
1208 self
.no_in_vec
= Signal(1, name
="no_in_vec") # no inputs vector
1209 self
.no_out_vec
= Signal(1, name
="no_out_vec") # no outputs vector
1210 self
.loop_continue
= Signal(1, name
="loop_continue")
1212 self
.no_in_vec
= Const(1, 1)
1213 self
.no_out_vec
= Const(1, 1)
1214 self
.loop_continue
= Const(0, 1)
1216 def get_col_subset(self
, opkls
):
1217 subset
= super().get_col_subset(opkls
)
1218 subset
.add("asmcode")
1219 subset
.add("in1_sel")
1220 subset
.add("in2_sel")
1221 subset
.add("in3_sel")
1222 subset
.add("out_sel")
1224 subset
.add("sv_in1")
1225 subset
.add("sv_in2")
1226 subset
.add("sv_in3")
1227 subset
.add("sv_out")
1228 subset
.add("sv_out2")
1229 subset
.add("sv_cr_in")
1230 subset
.add("sv_cr_out")
1231 subset
.add("SV_Etype")
1232 subset
.add("SV_Ptype")
1233 subset
.add("SV_mode")
1234 # from SVP64RMModeDecode
1235 for (field
, _
) in sv_input_record_layout
:
1238 subset
.add("internal_op")
1242 def elaborate(self
, platform
):
1243 m
= super().elaborate(platform
)
1246 op
, e_out
, do_out
= self
.op
, self
.e
, self
.e
.do
1247 dec_spr
, msr
, cia
, ext_irq
= state
.dec
, state
.msr
, state
.pc
, state
.eint
1248 rc_out
= self
.dec_rc
.rc_out
.data
1252 # fill in for a normal instruction (not an exception)
1253 # copy over if non-exception, non-privileged etc. is detected
1255 # set up submodule decoders
1256 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
, op
, self
.regreduce_en
)
1257 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
, op
)
1258 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
, op
)
1259 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
, op
, self
.regreduce_en
)
1260 m
.submodules
.dec_o2
= dec_o2
= DecodeOut2(self
.dec
, op
)
1261 m
.submodules
.dec_cr_in
= self
.dec_cr_in
= DecodeCRIn(self
.dec
, op
)
1262 m
.submodules
.dec_cr_out
= self
.dec_cr_out
= DecodeCROut(self
.dec
, op
)
1263 comb
+= dec_a
.sv_nz
.eq(self
.sv_a_nz
)
1264 comb
+= self
.crout_5bit
.eq(self
.dec_cr_out
.cr_5bit
)
1267 # and SVP64 Extra decoders
1268 m
.submodules
.crout_svdec
= crout_svdec
= SVP64CRExtra()
1269 m
.submodules
.crin_svdec
= crin_svdec
= SVP64CRExtra()
1270 m
.submodules
.crin_svdec_b
= crin_svdec_b
= SVP64CRExtra()
1271 m
.submodules
.crin_svdec_o
= crin_svdec_o
= SVP64CRExtra()
1272 m
.submodules
.in1_svdec
= in1_svdec
= SVP64RegExtra()
1273 m
.submodules
.in2_svdec
= in2_svdec
= SVP64RegExtra()
1274 m
.submodules
.in3_svdec
= in3_svdec
= SVP64RegExtra()
1275 m
.submodules
.o_svdec
= o_svdec
= SVP64RegExtra()
1276 m
.submodules
.o2_svdec
= o2_svdec
= SVP64RegExtra()
1278 # debug access to cr svdec (used in get_pdecode_cr_in/out)
1279 self
.crout_svdec
= crout_svdec
1280 self
.crin_svdec
= crin_svdec
1282 # get the 5-bit reg data before svp64-munging it into 7-bit plus isvec
1283 reg
= Signal(5, reset_less
=True)
1285 # copy instruction through...
1286 for i
in [do
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
1287 self
.dec_cr_in
.insn_in
, self
.dec_cr_out
.insn_in
,
1288 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
]:
1289 comb
+= i
.eq(self
.dec
.opcode_in
)
1292 comb
+= self
.dec_cr_in
.sel_in
.eq(self
.op_get("cr_in"))
1293 comb
+= self
.dec_cr_out
.sel_in
.eq(self
.op_get("cr_out"))
1294 comb
+= self
.dec_cr_out
.rc_in
.eq(rc_out
)
1297 comb
+= self
.do_copy("read_cr_whole", self
.dec_cr_in
.whole_reg
)
1298 comb
+= self
.do_copy("write_cr_whole", self
.dec_cr_out
.whole_reg
)
1300 # ...and subdecoders' input fields
1301 comb
+= dec_a
.sel_in
.eq(self
.op_get("in1_sel"))
1302 comb
+= dec_b
.sel_in
.eq(self
.op_get("in2_sel"))
1303 comb
+= dec_c
.sel_in
.eq(self
.op_get("in3_sel"))
1304 comb
+= dec_o
.sel_in
.eq(self
.op_get("out_sel"))
1305 comb
+= dec_o2
.sel_in
.eq(self
.op_get("out_sel"))
1307 comb
+= dec_o2
.implicit_rs
.eq(self
.implicit_rs
)
1308 comb
+= dec_o2
.implicit_from_rc
.eq(self
.extend_rc_maxvl
)
1309 if hasattr(do
, "lk"):
1310 comb
+= dec_o2
.lk
.eq(do
.lk
)
1313 # now do the SVP64 munging. op.SV_Etype and op.sv_in1 comes from
1314 # PowerDecoder which in turn comes from LDST-RM*.csv and RM-*.csv
1315 # which in turn were auto-generated by sv_analysis.py
1316 extra
= self
.sv_rm
.extra
# SVP64 extra bits 10:18
1321 comb
+= crout_svdec
.idx
.eq(self
.op_get("sv_cr_out"))
1322 comb
+= self
.cr_out_isvec
.eq(crout_svdec
.isvec
)
1325 # CR in - selection slightly different due to shared CR field sigh
1326 cr_a_idx
= Signal(SVEXTRA
)
1327 cr_b_idx
= Signal(SVEXTRA
)
1329 # these change slightly, when decoding BA/BB. really should have
1330 # their own separate CSV column: sv_cr_in1 and sv_cr_in2, but hey
1331 comb
+= cr_a_idx
.eq(self
.op_get("sv_cr_in"))
1332 comb
+= cr_b_idx
.eq(SVEXTRA
.NONE
)
1333 with m
.If(self
.op_get("sv_cr_in") == SVEXTRA
.Idx_1_2
.value
):
1334 comb
+= cr_a_idx
.eq(SVEXTRA
.Idx1
)
1335 comb
+= cr_b_idx
.eq(SVEXTRA
.Idx2
)
1337 comb
+= self
.cr_in_isvec
.eq(crin_svdec
.isvec
)
1338 comb
+= self
.cr_in_b_isvec
.eq(crin_svdec_b
.isvec
)
1339 comb
+= self
.cr_in_o_isvec
.eq(crin_svdec_o
.isvec
)
1341 # indices are slightly different, BA/BB mess sorted above
1342 comb
+= crin_svdec
.idx
.eq(cr_a_idx
) # SVP64 CR in A
1343 comb
+= crin_svdec_b
.idx
.eq(cr_b_idx
) # SVP64 CR in B
1345 comb
+= crin_svdec_o
.idx
.eq(self
.op_get("sv_cr_out"))
1347 # get SVSTATE srcstep (TODO: elwidth etc.) needed below
1348 vl
= Signal
.like(self
.state
.svstate
.vl
)
1349 maxvl
= Signal
.like(self
.state
.svstate
.maxvl
)
1350 subvl
= Signal
.like(self
.rm_dec
.rm_in
.subvl
)
1351 srcstep
= Signal
.like(self
.state
.svstate
.srcstep
)
1352 dststep
= Signal
.like(self
.state
.svstate
.dststep
)
1353 ssubstep
= Signal
.like(self
.state
.svstate
.ssubstep
)
1354 dsubstep
= Signal
.like(self
.state
.svstate
.ssubstep
)
1355 comb
+= vl
.eq(self
.state
.svstate
.vl
)
1356 comb
+= maxvl
.eq(self
.state
.svstate
.maxvl
)
1357 comb
+= subvl
.eq(self
.rm_dec
.rm_in
.subvl
)
1358 comb
+= srcstep
.eq(self
.state
.svstate
.srcstep
)
1359 comb
+= dststep
.eq(self
.state
.svstate
.dststep
)
1360 comb
+= ssubstep
.eq(self
.state
.svstate
.ssubstep
)
1361 comb
+= dsubstep
.eq(self
.state
.svstate
.dsubstep
)
1363 in1_step
, in2_step
= self
.in1_step
, self
.in2_step
1364 in3_step
= self
.in3_step
1365 o_step
, o2_step
= self
.o_step
, self
.o2_step
1367 # multiply vl by subvl - note that this is only 7 bit!
1368 # when elwidth overrides get involved this will have to go up
1370 comb
+= vmax
.eq(vl
*(subvl
+1))
1372 # registers a, b, c and out and out2 (LD/ST EA)
1373 sv_etype
= self
.op_get("SV_Etype")
1374 for i
, stuff
in enumerate((
1375 ("RA", e
.read_reg1
, dec_a
.reg_out
, in1_svdec
, in1_step
, False),
1376 ("RB", e
.read_reg2
, dec_b
.reg_out
, in2_svdec
, in2_step
, False),
1377 ("RC", e
.read_reg3
, dec_c
.reg_out
, in3_svdec
, in3_step
, False),
1378 ("RT", e
.write_reg
, dec_o
.reg_out
, o_svdec
, o_step
, True),
1379 ("EA", e
.write_ea
, dec_o2
.reg_out
, o2_svdec
, o2_step
, True))):
1380 rname
, to_reg
, fromreg
, svdec
, remapstep
, out
= stuff
1381 comb
+= svdec
.extra
.eq(extra
) # EXTRA field of SVP64 RM
1382 comb
+= svdec
.etype
.eq(sv_etype
) # EXTRA2/3 for this insn
1383 comb
+= svdec
.reg_in
.eq(fromreg
.data
) # 3-bit (CR0/BC/BFA)
1384 comb
+= to_reg
.ok
.eq(fromreg
.ok
)
1385 # *screaam* FFT mode needs an extra offset for RB
1386 # similar to FRS/FRT (below). all of this needs cleanup
1387 offs
= Signal(7, name
="offs_"+rname
, reset_less
=True)
1390 # when FFT sv.ffmadd detected, and REMAP not in use,
1391 # automagically add on an extra offset to RB.
1392 # however when REMAP is active, the FFT REMAP
1393 # schedule takes care of this offset.
1394 with m
.If(dec_o2
.reg_out
.ok
& dec_o2
.rs_en
&
1395 self
.extend_rb_maxvl
):
1396 with m
.If(~self
.remap_active
[i
]):
1397 with m
.If(svdec
.isvec
):
1398 comb
+= offs
.eq(maxvl
) # MAXVL for Vectors
1399 # detect if Vectorised: add srcstep/dststep if yes.
1400 # to_reg is 7-bits, outs get dststep added, ins get srcstep
1401 with m
.If(svdec
.isvec
):
1402 selectstep
= dststep
if out
else srcstep
1403 subselect
= dsubstep
if out
else ssubstep
1404 step
= Signal(7, name
="step_%s" % rname
.lower())
1405 with m
.If(self
.remap_active
[i
]):
1406 comb
+= step
.eq((remapstep
*(subvl
+1))+subselect
)
1408 comb
+= step
.eq((selectstep
*(subvl
+1))+subselect
)
1409 # reverse gear goes the opposite way
1410 with m
.If(self
.rm_dec
.reverse_gear
):
1411 comb
+= to_reg
.offs
.eq(offs
+(vmax
-1-step
))
1413 comb
+= to_reg
.offs
.eq(offs
+step
)
1415 comb
+= to_reg
.offs
.eq(offs
)
1416 comb
+= to_reg
.base
.eq(svdec
.reg_out
)
1417 comb
+= to_reg
.data
.eq(to_reg
.base
+ to_reg
.offs
)
1419 # SVP64 in/out fields
1420 comb
+= in1_svdec
.idx
.eq(self
.op_get("sv_in1")) # reg #1 (in1_sel)
1421 comb
+= in2_svdec
.idx
.eq(self
.op_get("sv_in2")) # reg #2 (in2_sel)
1422 comb
+= in3_svdec
.idx
.eq(self
.op_get("sv_in3")) # reg #3 (in3_sel)
1423 comb
+= o_svdec
.idx
.eq(self
.op_get("sv_out")) # output (out_sel)
1425 comb
+= o2_svdec
.idx
.eq(self
.op_get("sv_out2"))
1426 # XXX TODO - work out where this should come from. the problem is
1427 # that LD-with-update is implied (computed from "is instruction in
1428 # "update mode" rather than specified cleanly as its own CSV column
1430 # output reg-is-vectorised (and when no in/out is vectorised)
1431 comb
+= self
.in1_isvec
.eq(in1_svdec
.isvec
)
1432 comb
+= self
.in2_isvec
.eq(in2_svdec
.isvec
)
1433 comb
+= self
.in3_isvec
.eq(in3_svdec
.isvec
)
1434 comb
+= self
.o_isvec
.eq(o_svdec
.isvec
)
1435 comb
+= self
.o2_isvec
.eq(o2_svdec
.isvec
)
1437 # urrr... don't ask... the implicit register FRS in FFT mode
1438 # "tracks" FRT exactly except it's offset by MAXVL. rather than
1439 # mess up the above with if-statements, override it here.
1440 # same trick is applied to FRB, above, but it's a lot cleaner there
1441 with m
.If(dec_o2
.reg_out
.ok
& dec_o2
.rs_en
):
1442 imp_reg_out
= Signal(7)
1443 imp_isvec
= Signal(1)
1444 with m
.If(self
.extend_rc_maxvl
): # maddedu etc. from RC
1445 comb
+= imp_isvec
.eq(in3_svdec
.isvec
)
1446 comb
+= imp_reg_out
.eq(in3_svdec
.reg_out
)
1448 comb
+= imp_isvec
.eq(o_svdec
.isvec
)
1449 comb
+= imp_reg_out
.eq(o_svdec
.reg_out
)
1451 with m
.If(~self
.remap_active
[4]):
1452 with m
.If(imp_isvec
):
1453 comb
+= offs
.eq(maxvl
) # MAXVL for Vectors
1454 with m
.Elif(self
.extend_rc_maxvl
): # maddedu etc. from RC
1455 comb
+= offs
.eq(0) # keep as RC
1457 comb
+= offs
.eq(1) # add 1 if scalar
1458 with m
.If(imp_isvec
):
1459 step
= Signal(7, name
="step_%s" % rname
.lower())
1460 with m
.If(self
.remap_active
[4]):
1461 with m
.If(self
.extend_rc_maxvl
): # maddedu etc. from RC
1462 comb
+= step
.eq(in3_step
)
1464 comb
+= step
.eq(o2_step
)
1466 comb
+= step
.eq(dststep
)
1467 # reverse gear goes the opposite way
1468 with m
.If(self
.rm_dec
.reverse_gear
):
1469 roffs
= offs
+(vl
-1-step
)
1470 comb
+= e
.write_ea
.data
.eq(roffs
)
1472 comb
+= e
.write_ea
.data
.eq(offs
+step
)
1474 comb
+= e
.write_ea
.offs
.eq(offs
)
1475 comb
+= e
.write_ea
.base
.eq(imp_reg_out
)
1476 comb
+= e
.write_ea
.data
.eq(e
.write_ea
.base
+ e
.write_ea
.offs
)
1477 # ... but write to *second* output
1478 comb
+= self
.o2_isvec
.eq(imp_isvec
)
1479 comb
+= o2_svdec
.idx
.eq(self
.op_get("sv_out"))
1481 # TODO add SPRs here. must be True when *all* are scalar
1482 l
= map(lambda svdec
: svdec
.isvec
, [in1_svdec
, in2_svdec
, in3_svdec
,
1483 crin_svdec
, crin_svdec_b
,
1485 comb
+= self
.no_in_vec
.eq(~
Cat(*l
).bool()) # all input scalar
1486 l
= map(lambda svdec
: svdec
.isvec
, [
1487 o2_svdec
, o_svdec
, crout_svdec
])
1488 # in mapreduce mode, scalar out is *allowed*
1489 with m
.If(self
.rm_dec
.mode
== SVP64RMMode
.MAPREDUCE
.value
):
1490 comb
+= self
.no_out_vec
.eq(0)
1493 comb
+= self
.no_out_vec
.eq(~
Cat(*l
).bool())
1494 # now create a general-purpose "test" as to whether looping
1495 # should continue. this doesn't include predication bit-tests
1496 loop
= self
.loop_continue
1497 with m
.Switch(self
.op_get("SV_Ptype")):
1498 with m
.Case(SVPType
.P2
.value
):
1500 # TODO: *and cache-inhibited LD/ST!*
1501 comb
+= loop
.eq(~
(self
.no_in_vec | self
.no_out_vec
))
1502 with m
.Case(SVPType
.P1
.value
):
1503 # single-predication, test relies on dest only
1504 comb
+= loop
.eq(~self
.no_out_vec
)
1506 # not an SV operation, no looping
1509 # condition registers (CR)
1510 for to_reg
, cr
, name
, svdec
, out
in (
1511 (e
.read_cr1
, self
.dec_cr_in
, "cr_bitfield", crin_svdec
, 0),
1512 (e
.read_cr2
, self
.dec_cr_in
, "cr_bitfield_b", crin_svdec_b
, 0),
1513 (e
.read_cr3
, self
.dec_cr_in
, "cr_bitfield_o", crin_svdec_o
, 0),
1514 (e
.write_cr
, self
.dec_cr_out
, "cr_bitfield", crout_svdec
, 1)):
1515 fromreg
= getattr(cr
, name
)
1516 comb
+= svdec
.extra
.eq(extra
) # EXTRA field of SVP64 RM
1517 comb
+= svdec
.etype
.eq(sv_etype
) # EXTRA2/3 for this insn
1518 comb
+= svdec
.cr_in
.eq(fromreg
.data
) # 3-bit (CR0/BC/BFA)
1519 with m
.If(svdec
.isvec
):
1520 # check if this is CR0 or CR1: treated differently
1521 # (does not "listen" to EXTRA2/3 spec for a start)
1522 # also: the CRs start from completely different locations
1523 step
= dststep
if out
else srcstep
1524 with m
.If(cr
.sv_override
== 1): # CR0
1525 offs
= SVP64CROffs
.CR0
1526 comb
+= to_reg
.data
.eq(step
+offs
)
1527 with m
.Elif(cr
.sv_override
== 2): # CR1
1528 offs
= SVP64CROffs
.CR1
1529 comb
+= to_reg
.data
.eq(step
+1)
1531 comb
+= to_reg
.data
.eq(step
+svdec
.cr_out
) # 7-bit out
1533 comb
+= to_reg
.data
.eq(svdec
.cr_out
) # 7-bit output
1534 comb
+= to_reg
.ok
.eq(fromreg
.ok
)
1536 # sigh must determine if RA is nonzero (7 bit)
1537 comb
+= self
.sv_a_nz
.eq(e
.read_reg1
.data
!= Const(0, 7))
1539 # connect up to/from read/write GPRs
1540 for to_reg
, fromreg
in ((e
.read_reg1
, dec_a
.reg_out
),
1541 (e
.read_reg2
, dec_b
.reg_out
),
1542 (e
.read_reg3
, dec_c
.reg_out
),
1543 (e
.write_reg
, dec_o
.reg_out
),
1544 (e
.write_ea
, dec_o2
.reg_out
)):
1545 comb
+= to_reg
.data
.eq(fromreg
.data
)
1546 comb
+= to_reg
.ok
.eq(fromreg
.ok
)
1548 # connect up to/from read/write CRs
1549 for to_reg
, cr
, name
in (
1550 (e
.read_cr1
, self
.dec_cr_in
, "cr_bitfield", ),
1551 (e
.read_cr2
, self
.dec_cr_in
, "cr_bitfield_b", ),
1552 (e
.read_cr3
, self
.dec_cr_in
, "cr_bitfield_o", ),
1553 (e
.write_cr
, self
.dec_cr_out
, "cr_bitfield", )):
1554 fromreg
= getattr(cr
, name
)
1555 comb
+= to_reg
.data
.eq(fromreg
.data
)
1556 comb
+= to_reg
.ok
.eq(fromreg
.ok
)
1559 comb
+= self
.rm_dec
.ldst_ra_vec
.eq(self
.in1_isvec
) # RA is vector
1560 comb
+= self
.rm_dec
.cr_5bit_in
.eq(self
.crout_5bit
) # CR is 5-bit
1561 # take bottom 2 bits of CR out (CR field selector)
1562 with m
.If(self
.crout_5bit
):
1563 comb
+= self
.rm_dec
.cr_2bit_in
.eq(self
.dec_cr_out
.cr_2bit
)
1566 comb
+= e
.read_spr1
.eq(dec_a
.spr_out
)
1567 comb
+= e
.write_spr
.eq(dec_o
.spr_out
)
1569 # Fast regs out including SRR0/1/SVSRR0
1570 comb
+= e
.read_fast1
.eq(dec_a
.fast_out
)
1571 comb
+= e
.read_fast2
.eq(dec_b
.fast_out
)
1572 comb
+= e
.write_fast1
.eq(dec_o
.fast_out
) # SRR0 (OP_RFID)
1573 comb
+= e
.write_fast2
.eq(dec_o2
.fast_out
) # SRR1 (ditto)
1574 comb
+= e
.write_fast3
.eq(dec_o2
.fast_out3
) # SVSRR0 (ditto)
1575 # and State regs (DEC, TB)
1576 comb
+= e
.read_state1
.eq(dec_a
.state_out
) # DEC/TB
1577 comb
+= e
.write_state1
.eq(dec_o
.state_out
) # DEC/TB
1579 # sigh this is exactly the sort of thing for which the
1580 # decoder is designed to not need. MTSPR, MFSPR and others need
1581 # access to the XER bits. however setting e.oe is not appropriate
1582 internal_op
= self
.op_get("internal_op")
1583 with m
.If(internal_op
== MicrOp
.OP_MFSPR
):
1584 comb
+= e
.xer_in
.eq(0b111) # SO, CA, OV
1585 with m
.If(internal_op
== MicrOp
.OP_CMP
):
1586 comb
+= e
.xer_in
.eq(1 << XERRegsEnum
.SO
) # SO
1587 with m
.If(internal_op
== MicrOp
.OP_MTSPR
):
1588 comb
+= e
.xer_out
.eq(1)
1590 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
1591 with m
.If(op
.internal_op
== MicrOp
.OP_TRAP
):
1592 # *DO NOT* call self.trap here. that would reset absolutely
1593 # everything including destroying read of RA and RB.
1594 comb
+= self
.do_copy("trapaddr", 0x70) # strip first nibble
1596 ####################
1597 # ok so the instruction's been decoded, blah blah, however
1598 # now we need to determine if it's actually going to go ahead...
1599 # *or* if in fact it's a privileged operation, whether there's
1600 # an external interrupt, etc. etc. this is a simple priority
1601 # if-elif-elif sequence. decrement takes highest priority,
1602 # EINT next highest, privileged operation third.
1604 # check if instruction is privileged
1605 is_priv_insn
= instr_is_priv(m
, op
.internal_op
, e
.do
.insn
)
1607 # different IRQ conditions
1608 ext_irq_ok
= Signal()
1609 dec_irq_ok
= Signal()
1612 ldst_exc
= self
.ldst_exc
1614 comb
+= ext_irq_ok
.eq(ext_irq
& msr
[MSR
.EE
]) # v3.0B p944 (MSR.EE)
1615 comb
+= dec_irq_ok
.eq(dec_spr
[63] & msr
[MSR
.EE
]) # 6.5.11 p1076
1616 comb
+= priv_ok
.eq(is_priv_insn
& msr
[MSR
.PR
])
1617 comb
+= illeg_ok
.eq(op
.internal_op
== MicrOp
.OP_ILLEGAL
)
1619 # absolute top priority: check for an instruction failed
1620 with m
.If(self
.instr_fault
):
1621 comb
+= self
.e
.eq(0) # reset eeeeeverything
1622 comb
+= self
.do_copy("insn", self
.dec
.opcode_in
, True)
1623 comb
+= self
.do_copy("insn_type", MicrOp
.OP_FETCH_FAILED
, True)
1624 comb
+= self
.do_copy("fn_unit", Function
.MMU
, True)
1625 comb
+= self
.do_copy("cia", self
.state
.pc
, True) # PC
1626 comb
+= self
.do_copy("msr", self
.state
.msr
, True) # MSR
1627 # special override on internal_op, due to being a "fake" op
1628 comb
+= self
.dec
.op
.internal_op
.eq(MicrOp
.OP_FETCH_FAILED
)
1630 # LD/ST exceptions. TestIssuer copies the exception info at us
1631 # after a failed LD/ST.
1632 with m
.Elif(ldst_exc
.happened
):
1633 with m
.If(ldst_exc
.alignment
):
1634 self
.trap(m
, TT
.MEMEXC
, 0x600)
1635 with m
.Elif(ldst_exc
.instr_fault
):
1636 with m
.If(ldst_exc
.segment_fault
):
1637 self
.trap(m
, TT
.MEMEXC
, 0x480)
1639 # pass exception info to trap to create SRR1
1640 self
.trap(m
, TT
.MEMEXC
, 0x400, ldst_exc
)
1642 with m
.If(ldst_exc
.segment_fault
):
1643 self
.trap(m
, TT
.MEMEXC
, 0x380)
1645 self
.trap(m
, TT
.MEMEXC
, 0x300)
1647 # decrement counter (v3.0B p1099): TODO 32-bit version (MSR.LPCR)
1648 with m
.Elif(dec_irq_ok
):
1649 self
.trap(m
, TT
.DEC
, 0x900) # v3.0B 6.5 p1065
1651 # external interrupt? only if MSR.EE set
1652 with m
.Elif(ext_irq_ok
):
1653 self
.trap(m
, TT
.EINT
, 0x500)
1655 # privileged instruction trap
1656 with m
.Elif(priv_ok
):
1657 self
.trap(m
, TT
.PRIV
, 0x700)
1659 # illegal instruction must redirect to trap. this is done by
1660 # *overwriting* the decoded instruction and starting again.
1661 # (note: the same goes for interrupts and for privileged operations,
1662 # just with different trapaddr and traptype)
1663 with m
.Elif(illeg_ok
):
1664 # illegal instruction trap
1665 self
.trap(m
, TT
.ILLEG
, 0x700)
1667 # no exception, just copy things to the output
1671 ####################
1672 # follow-up after trap/irq to set up SRR0/1
1674 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
1675 # Note: OP_SC could actually be modified to just be a trap
1676 with m
.If((do_out
.insn_type
== MicrOp
.OP_TRAP
) |
1677 (do_out
.insn_type
== MicrOp
.OP_SC
)):
1678 # TRAP write fast1 = SRR0
1679 comb
+= e_out
.write_fast1
.data
.eq(FastRegsEnum
.SRR0
) # SRR0
1680 comb
+= e_out
.write_fast1
.ok
.eq(1)
1681 # TRAP write fast2 = SRR1
1682 comb
+= e_out
.write_fast2
.data
.eq(FastRegsEnum
.SRR1
) # SRR1
1683 comb
+= e_out
.write_fast2
.ok
.eq(1)
1684 # TRAP write fast2 = SRR1
1685 comb
+= e_out
.write_fast3
.data
.eq(FastRegsEnum
.SVSRR0
) # SVSRR0
1686 comb
+= e_out
.write_fast3
.ok
.eq(1)
1688 # RFID: needs to read SRR0/1
1689 with m
.If(do_out
.insn_type
== MicrOp
.OP_RFID
):
1690 # TRAP read fast1 = SRR0
1691 comb
+= e_out
.read_fast1
.data
.eq(FastRegsEnum
.SRR0
) # SRR0
1692 comb
+= e_out
.read_fast1
.ok
.eq(1)
1693 # TRAP read fast2 = SRR1
1694 comb
+= e_out
.read_fast2
.data
.eq(FastRegsEnum
.SRR1
) # SRR1
1695 comb
+= e_out
.read_fast2
.ok
.eq(1)
1696 # TRAP read fast2 = SVSRR0
1697 comb
+= e_out
.read_fast3
.data
.eq(FastRegsEnum
.SVSRR0
) # SVSRR0
1698 comb
+= e_out
.read_fast3
.ok
.eq(1)
1700 # annoying simulator bug.
1701 # asmcode may end up getting used for perfcounters?
1702 asmcode
= self
.op_get("asmcode")
1703 if hasattr(e_out
, "asmcode") and asmcode
is not None:
1704 comb
+= e_out
.asmcode
.eq(asmcode
)
1708 def trap(self
, m
, traptype
, trapaddr
, ldst_exc
=None):
1709 """trap: this basically "rewrites" the decoded instruction as a trap
1713 comb
+= e
.eq(0) # reset eeeeeverything
1716 comb
+= self
.do_copy("insn", self
.dec
.opcode_in
, True)
1717 comb
+= self
.do_copy("insn_type", MicrOp
.OP_TRAP
, True)
1718 comb
+= self
.do_copy("fn_unit", Function
.TRAP
, True)
1719 comb
+= self
.do_copy("trapaddr", trapaddr
>> 4, True) # bottom 4 bits
1720 comb
+= self
.do_copy("traptype", traptype
, True) # request type
1721 comb
+= self
.do_copy("ldst_exc", ldst_exc
, True) # request type
1722 comb
+= self
.do_copy("msr", self
.state
.msr
,
1723 True) # copy of MSR "state"
1724 comb
+= self
.do_copy("cia", self
.state
.pc
, True) # copy of PC "state"
1725 comb
+= self
.do_copy("svstate", self
.state
.svstate
, True) # SVSTATE
1728 def get_rdflags(m
, e
, cu
):
1729 """returns a sequential list of the read "ok" flags for a given FU.
1730 this list is in order of the CompUnit input specs
1733 for idx
in range(cu
.n_src
):
1734 regfile
, regname
, _
= cu
.get_in_spec(idx
)
1735 decinfo
= regspec_decode_read(m
, e
, regfile
, regname
)
1736 rdl
.append(decinfo
.okflag
)
1741 if __name__
== '__main__':
1742 pdecode
= create_pdecode()
1743 dec2
= PowerDecode2(pdecode
, svp64_en
=True)
1744 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
1745 with
open("dec2.il", "w") as f
: