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
.BA_BFB
):
665 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BA
[2:5])
666 comb
+= self
.cr_bitfield
.ok
.eq(1)
667 comb
+= self
.cr_bitfield_b
.data
.eq(self
.dec
.FormCRB
.BFB
)
668 comb
+= self
.cr_bitfield_b
.ok
.eq(1)
669 comb
+= self
.cr_bitfield_o
.data
.eq(self
.dec
.FormCRB
.BF
)
670 comb
+= self
.cr_bitfield_o
.ok
.eq(1)
671 with m
.Case(CRInSel
.BC
):
672 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BC
[2:5])
673 comb
+= self
.cr_bitfield
.ok
.eq(1)
674 with m
.Case(CRInSel
.WHOLE_REG
):
675 comb
+= self
.whole_reg
.ok
.eq(1)
676 move_one
= Signal(reset_less
=True)
677 comb
+= move_one
.eq(self
.insn_in
[20]) # MSB0 bit 11
678 with m
.If((op
.internal_op
== MicrOp
.OP_MFCR
) & move_one
):
679 # must one-hot the FXM field
680 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
681 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
683 # otherwise use all of it
684 comb
+= self
.whole_reg
.data
.eq(0xff)
689 class DecodeCROut(Elaboratable
):
690 """Decodes input CR from instruction
692 CR indices - insn fields - (not the data *in* the CR) require only 3
693 bits because they refer to CR0-CR7
696 def __init__(self
, dec
, op
):
699 self
.rc_in
= Signal(reset_less
=True)
700 self
.sel_in
= Signal(CROutSel
, reset_less
=True)
701 self
.insn_in
= Signal(32, reset_less
=True)
702 self
.cr_bitfield
= Data(3, "cr_bitfield")
703 self
.whole_reg
= Data(8, "cr_fxm")
704 self
.sv_override
= Signal(2, reset_less
=True) # do not do EXTRA spec
705 self
.cr_5bit
= Signal(reset_less
=True) # set True for 5-bit
706 self
.cr_2bit
= Signal(2, reset_less
=True) # get lowest 2 bits
708 def elaborate(self
, platform
):
712 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
715 comb
+= self
.cr_bitfield
.ok
.eq(0)
716 comb
+= self
.whole_reg
.ok
.eq(0)
717 comb
+= self
.sv_override
.eq(0)
718 comb
+= self
.cr_5bit
.eq(0)
720 # please note these MUST match (setting of cr_bitfield.ok) exactly
721 # with write_cr0 below in PowerDecoder2. the reason it's separated
722 # is to avoid having duplicate copies of DecodeCROut in multiple
723 # PowerDecoderSubsets. register decoding should be a one-off in
724 # PowerDecoder2. see https://bugs.libre-soc.org/show_bug.cgi?id=606
726 with m
.Switch(self
.sel_in
):
727 with m
.Case(CROutSel
.NONE
):
728 pass # No bitfield activated
729 with m
.Case(CROutSel
.CR0
):
730 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
731 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
732 comb
+= self
.sv_override
.eq(1)
733 with m
.Case(CROutSel
.CR1
):
734 comb
+= self
.cr_bitfield
.data
.eq(1) # CR1 (MSB0 numbering)
735 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
736 comb
+= self
.sv_override
.eq(2)
737 with m
.Case(CROutSel
.BF
):
738 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BF
)
739 comb
+= self
.cr_bitfield
.ok
.eq(1)
740 with m
.Case(CROutSel
.BT
):
741 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormXL
.BT
[2:5])
742 comb
+= self
.cr_bitfield
.ok
.eq(1)
743 comb
+= self
.cr_5bit
.eq(1)
744 comb
+= self
.cr_2bit
.eq(self
.dec
.FormXL
.BT
[0:2])
745 with m
.Case(CROutSel
.WHOLE_REG
):
746 comb
+= self
.whole_reg
.ok
.eq(1)
747 move_one
= Signal(reset_less
=True)
748 comb
+= move_one
.eq(self
.insn_in
[20])
749 with m
.If((op
.internal_op
== MicrOp
.OP_MTCRF
)):
751 # must one-hot the FXM field
752 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
753 with m
.If(ppick
.en_o
):
754 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
756 comb
+= self
.whole_reg
.data
.eq(0b00000001) # CR7
758 comb
+= self
.whole_reg
.data
.eq(self
.dec
.FXM
)
760 # otherwise use all of it
761 comb
+= self
.whole_reg
.data
.eq(0xff)
766 # dictionary of Input Record field names that, if they exist,
767 # will need a corresponding CSV Decoder file column (actually, PowerOp)
768 # to be decoded (this includes the single bit names)
769 record_names
= {'insn_type': 'internal_op',
770 'fn_unit': 'function_unit',
771 'SV_Ptype': 'SV_Ptype',
772 'SV_mode': 'SV_mode',
776 'imm_data': 'in2_sel',
777 'invert_in': 'inv_a',
778 'invert_out': 'inv_out',
781 'output_carry': 'cry_out',
782 'input_carry': 'cry_in',
783 'is_32bit': 'is_32b',
786 'data_len': 'ldst_len',
788 'byte_reverse': 'br',
789 'sign_extend': 'sgn_ext',
794 class PowerDecodeSubset(Elaboratable
):
795 """PowerDecodeSubset: dynamic subset decoder
797 only fields actually requested are copied over. hence, "subset" (duh).
800 def __init__(self
, dec
, opkls
=None, fn_name
=None, final
=False, state
=None,
801 svp64_en
=True, regreduce_en
=False, fp_en
=False):
803 self
.svp64_en
= svp64_en
804 self
.regreduce_en
= regreduce_en
807 self
.is_svp64_mode
= Signal() # mark decoding as SVP64 Mode
808 self
.implicit_rs
= Signal() # implicit RS/FRS
809 self
.extend_rb_maxvl
= Signal() # jumps RB by an additional MAXVL
810 self
.extend_rc_maxvl
= Signal() # jumps RS by MAXVL from RC
811 self
.sv_rm
= SVP64Rec(name
="dec_svp64") # SVP64 RM field
812 self
.rm_dec
= SVP64RMModeDecode("svp64_rm_dec")
813 # set these to the predicate mask bits needed for the ALU
814 self
.pred_sm
= Signal() # TODO expand to SIMD mask width
815 self
.pred_dm
= Signal() # TODO expand to SIMD mask width
816 self
.sv_a_nz
= Signal(1)
819 self
.fn_name
= fn_name
821 opkls
= Decode2ToOperand
822 self
.do
= opkls(fn_name
)
824 col_subset
= self
.get_col_subset(self
.do
)
825 row_subset
= self
.rowsubsetfn
830 # "conditions" for Decoders, to enable some weird and wonderful
831 # alternatives. useful for PCR (Program Compatibility Register)
832 # amongst other things
835 # XXX NO 'SVP64FFT': self.use_svp64_fft,
840 # only needed for "main" PowerDecode2
842 self
.e
= Decode2ToExecute1Type(name
=self
.fn_name
, do
=self
.do
,
843 regreduce_en
=regreduce_en
)
845 # create decoder if one not already given
847 dec
= create_pdecode(name
=fn_name
, col_subset
=col_subset
,
848 row_subset
=row_subset
,
849 conditions
=conditions
, include_fp
=fp_en
)
852 # set up a copy of the PowerOp
853 self
.op
= PowerOp
.like(self
.dec
.op
)
855 # state information needed by the Decoder
857 state
= CoreState("dec2")
860 def get_col_subset(self
, do
):
861 subset
= {'cr_in', 'cr_out', 'rc_sel'} # needed, non-optional
862 for k
, v
in record_names
.items():
865 log("get_col_subset", self
.fn_name
, do
.fields
, subset
)
868 def rowsubsetfn(self
, opcode
, row
):
869 """select per-Function-Unit subset of opcodes to be processed
871 normally this just looks at the "unit" column. MMU is different
872 in that it processes specific SPR set/get operations that the SPR
875 return (row
['unit'] == self
.fn_name
or
876 # sigh a dreadful hack: MTSPR and MFSPR need to be processed
877 # by the MMU pipeline so we direct those opcodes to MMU **AND**
878 # SPR pipelines, then selectively weed out the SPRs that should
879 # or should not not go to each pipeline, further down.
880 # really this should be done by modifying the CSV syntax
881 # to support multiple tasks (unit column multiple entries)
882 # see https://bugs.libre-soc.org/show_bug.cgi?id=310
883 (self
.fn_name
== 'MMU' and row
['unit'] == 'SPR' and
884 row
['internal op'] in ['OP_MTSPR', 'OP_MFSPR']) or
885 # urrr... and the KAIVB SPR, which must also be redirected
886 # (to the TRAP pipeline)
887 # see https://bugs.libre-soc.org/show_bug.cgi?id=859
888 (self
.fn_name
== 'TRAP' and row
['unit'] == 'SPR' and
889 row
['internal op'] in ['OP_MTSPR', 'OP_MFSPR'])
893 ports
= self
.dec
.ports() + self
.e
.ports()
895 ports
+= self
.sv_rm
.ports()
896 ports
.append(self
.is_svp64_mode
)
897 ports
.append(self
.implicit_rs
)
900 def needs_field(self
, field
, op_field
):
905 return hasattr(do
, field
) and self
.op_get(op_field
) is not None
907 def do_get(self
, field
, final
=False):
908 if final
or self
.final
:
912 return getattr(do
, field
, None)
914 def do_copy(self
, field
, val
, final
=False):
915 df
= self
.do_get(field
, final
)
916 if df
is not None and val
is not None:
920 def op_get(self
, op_field
):
921 return getattr(self
.op
, op_field
, None)
923 def elaborate(self
, platform
):
924 if self
.regreduce_en
:
931 op
, do
= self
.dec
.op
, self
.do
932 msr
, cia
, svstate
= state
.msr
, state
.pc
, state
.svstate
933 # fill in for a normal instruction (not an exception)
934 # copy over if non-exception, non-privileged etc. is detected
936 if self
.fn_name
is None:
939 name
= self
.fn_name
+ "tmp"
940 self
.e_tmp
= Decode2ToExecute1Type(name
=name
, opkls
=self
.opkls
,
941 regreduce_en
=self
.regreduce_en
)
943 # set up submodule decoders
944 m
.submodules
.dec
= dec
= self
.dec
945 m
.submodules
.dec_rc
= self
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
946 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
, op
)
949 # and SVP64 RM mode decoder
950 m
.submodules
.sv_rm_dec
= rm_dec
= self
.rm_dec
952 # copy op from decoder
953 comb
+= self
.op
.eq(self
.dec
.op
)
955 # copy instruction through...
956 for i
in [do
.insn
, dec_rc
.insn_in
, dec_oe
.insn_in
, ]:
957 comb
+= i
.eq(self
.dec
.opcode_in
)
959 # ...and subdecoders' input fields
960 comb
+= dec_rc
.sel_in
.eq(self
.op_get("rc_sel"))
961 comb
+= dec_oe
.sel_in
.eq(self
.op_get("rc_sel")) # XXX should be OE sel
964 comb
+= self
.do_copy("msr", msr
)
965 comb
+= self
.do_copy("cia", cia
)
966 comb
+= self
.do_copy("svstate", svstate
)
968 # set up instruction type
969 # no op: defaults to OP_ILLEGAL
970 internal_op
= self
.op_get("internal_op")
971 comb
+= self
.do_copy("insn_type", internal_op
)
973 # function unit for decoded instruction: requires minor redirect
975 fn
= self
.op_get("function_unit")
976 spr
= Signal(10, reset_less
=True)
977 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
979 # Microwatt doesn't implement the partition table
980 # instead has PRTBL register (SPR) to point to process table
981 # Kestrel has a KAIVB SPR to "rebase" exceptions. rebasing is normally
982 # done with Hypervisor Mode which is not implemented (yet)
984 is_mmu_spr
= Signal()
985 is_trap_spr
= Signal()
986 comb
+= is_spr_mv
.eq((internal_op
== MicrOp
.OP_MTSPR
) |
987 (internal_op
== MicrOp
.OP_MFSPR
))
988 comb
+= is_mmu_spr
.eq((spr
== SPR
.DSISR
.value
) |
989 (spr
== SPR
.DAR
.value
) |
990 (spr
== SPR
.PRTBL
.value
) |
991 (spr
== SPR
.PIDR
.value
))
992 comb
+= is_trap_spr
.eq((spr
== SPR
.KAIVB
.value
)
994 # MMU must receive MMU SPRs
995 with m
.If(is_spr_mv
& (fn
== Function
.SPR
) & is_mmu_spr
):
996 comb
+= self
.do_copy("fn_unit", Function
.MMU
)
997 comb
+= self
.do_copy("insn_type", internal_op
)
998 # TRAP must receive TRAP SPR KAIVB
999 with m
.If(is_spr_mv
& (fn
== Function
.SPR
) & is_trap_spr
):
1000 comb
+= self
.do_copy("fn_unit", Function
.TRAP
)
1001 comb
+= self
.do_copy("insn_type", internal_op
)
1002 # SPR pipe must *not* receive MMU or TRAP SPRs
1003 with m
.Elif(is_spr_mv
& ((fn
== Function
.MMU
) & ~is_mmu_spr
) &
1004 ((fn
== Function
.TRAP
) & ~is_trap_spr
)):
1005 comb
+= self
.do_copy("fn_unit", Function
.NONE
)
1006 comb
+= self
.do_copy("insn_type", MicrOp
.OP_ILLEGAL
)
1009 comb
+= self
.do_copy("fn_unit", fn
)
1012 if self
.needs_field("zero_a", "in1_sel"):
1013 m
.submodules
.dec_ai
= dec_ai
= DecodeAImm(self
.dec
)
1014 comb
+= dec_ai
.sv_nz
.eq(self
.sv_a_nz
)
1015 comb
+= dec_ai
.sel_in
.eq(self
.op_get("in1_sel"))
1016 comb
+= self
.do_copy("zero_a", dec_ai
.immz_out
) # RA==0 detected
1017 if self
.needs_field("imm_data", "in2_sel"):
1018 m
.submodules
.dec_bi
= dec_bi
= DecodeBImm(self
.dec
)
1019 comb
+= dec_bi
.sel_in
.eq(self
.op_get("in2_sel"))
1020 comb
+= self
.do_copy("imm_data", dec_bi
.imm_out
) # imm in RB
1022 # CR in/out - note: these MUST match with what happens in
1024 rc_out
= self
.dec_rc
.rc_out
.data
1025 with m
.Switch(self
.op_get("cr_out")):
1026 with m
.Case(CROutSel
.CR0
, CROutSel
.CR1
):
1027 comb
+= self
.do_copy("write_cr0", rc_out
) # only when RC=1
1028 with m
.Case(CROutSel
.BF
, CROutSel
.BT
):
1029 comb
+= self
.do_copy("write_cr0", 1)
1031 comb
+= self
.do_copy("input_cr", self
.op_get("cr_in")) # CR in
1032 comb
+= self
.do_copy("output_cr", self
.op_get("cr_out")) # CR out
1035 # connect up SVP64 RM Mode decoding. however... we need a shorter
1036 # path, for the LDST bit-reverse detection. so perform partial
1037 # decode when SVP64 is detected. then, bit-reverse mode can be
1038 # quickly determined, and the Decoder result MUXed over to
1039 # the alternative decoder, svdecldst. what a mess... *sigh*
1040 sv_ptype
= self
.op_get("SV_Ptype")
1041 sv_mode
= self
.op_get("SV_mode")
1042 fn
= self
.op_get("function_unit")
1043 comb
+= rm_dec
.sv_mode
.eq(sv_mode
) # BRANCH/CROP/LDST_IMM etc.
1044 comb
+= rm_dec
.fn_in
.eq(fn
) # decode needs to know Fn type
1045 comb
+= rm_dec
.ptype_in
.eq(sv_ptype
) # Single/Twin predicated
1046 comb
+= rm_dec
.rc_in
.eq(rc_out
) # Rc=1
1047 comb
+= rm_dec
.rm_in
.eq(self
.sv_rm
) # SVP64 RM mode
1048 if self
.needs_field("imm_data", "in2_sel"):
1049 bzero
= dec_bi
.imm_out
.ok
& ~dec_bi
.imm_out
.data
.bool()
1050 comb
+= rm_dec
.ldst_imz_in
.eq(bzero
) # B immediate is zero
1052 # main PowerDecoder2 determines if different SVP64 modes enabled
1053 # detect if SVP64 FFT mode enabled (really bad hack),
1054 # exclude fcfids and others
1055 # XXX this is a REALLY bad hack, REALLY has to be done better.
1056 # likely with a sub-decoder.
1057 # what this ultimately does is enable the 2nd implicit register
1058 # (FRS) for SVP64-decoding. all of these instructions are
1059 # 3-in 2-out but there is not enough room either in the
1060 # opcode *or* EXTRA2/3 to specify a 5th operand.
1062 comb
+= major
.eq(self
.dec
.opcode_in
[26:32])
1064 comb
+= xo
.eq(self
.dec
.opcode_in
[1:11])
1065 comb
+= self
.implicit_rs
.eq(0)
1066 comb
+= self
.extend_rb_maxvl
.eq(0)
1067 comb
+= self
.extend_rc_maxvl
.eq(0)
1068 # implicit RS for major 59
1069 with m
.If((major
== 59) & xo
.matches(
1070 '-----00100', # ffmsubs
1071 '-----00101', # ffmadds
1072 '-----00110', # ffnmsubs
1073 '-----00111', # ffnmadds
1074 '1111100000', # ffadds
1075 '-----11011', # fdmadds
1077 comb
+= self
.implicit_rs
.eq(1)
1078 comb
+= self
.extend_rb_maxvl
.eq(1) # extend RB
1080 comb
+= xo6
.eq(self
.dec
.opcode_in
[0:6])
1081 # implicit RS for major 4
1082 with m
.If((major
== 4) & xo6
.matches(
1085 '111001', # maddedus
1086 '111010', # divmod2du
1090 comb
+= self
.implicit_rs
.eq(1)
1091 comb
+= self
.extend_rc_maxvl
.eq(1) # RS=RT+MAXVL or RS=RC
1092 # implicit RS for major 22, integer maddsubrs
1093 with m
.If((major
== 22) & xo6
.matches(
1094 '-01000', # maddsubrs
1098 comb
+= self
.implicit_rs
.eq(1)
1099 comb
+= self
.extend_rb_maxvl
.eq(1) # extend RB
1102 comb
+= self
.do_copy("rc", dec_rc
.rc_out
)
1104 # OE only enabled when SVP64 not active
1105 with m
.If(~self
.is_svp64_mode
):
1106 comb
+= self
.do_copy("oe", dec_oe
.oe_out
)
1107 # RC1 overrides Rc if rc type is NONE or ONE or Rc=0, in svp64_mode
1108 # for instructions with a forced-Rc=1 (stbcx., pcdec.)
1109 # the RC1 RM bit *becomes* Rc=0/1, but for instructions
1110 # that have Rc=0/1 then when Rc=0 RC1 *becomes* (replaces) Rc.
1111 with m
.Elif((dec_rc
.sel_in
.matches(RCOE
.RC
, RCOE
.RC_ONLY
) &
1112 dec_rc
.rc_out
.data
== 0) |
1113 (dec_rc
.sel_in
== RCOE
.ONE
)):
1114 RC1
= Data(1, "RC1")
1115 comb
+= RC1
.ok
.eq(rm_dec
.RC1
)
1116 comb
+= RC1
.RC1
.eq(rm_dec
.RC1
)
1117 comb
+= self
.do_copy("rc", RC1
)
1119 comb
+= self
.do_copy("oe", dec_oe
.oe_out
)
1121 # decoded/selected instruction flags
1122 comb
+= self
.do_copy("data_len", self
.op_get("ldst_len"))
1123 comb
+= self
.do_copy("invert_in", self
.op_get("inv_a"))
1124 comb
+= self
.do_copy("invert_out", self
.op_get("inv_out"))
1125 comb
+= self
.do_copy("input_carry", self
.op_get("cry_in"))
1126 comb
+= self
.do_copy("output_carry", self
.op_get("cry_out"))
1127 comb
+= self
.do_copy("is_32bit", self
.op_get("is_32b"))
1128 comb
+= self
.do_copy("is_signed", self
.op_get("sgn"))
1129 lk
= self
.op_get("lk")
1132 comb
+= self
.do_copy("lk", self
.dec
.LK
) # XXX TODO: accessor
1134 comb
+= self
.do_copy("byte_reverse", self
.op_get("br"))
1135 comb
+= self
.do_copy("sign_extend", self
.op_get("sgn_ext"))
1136 comb
+= self
.do_copy("ldst_mode", self
.op_get("upd")) # LD/ST mode
1137 comb
+= self
.do_copy("reserve", self
.op_get("rsrv")) # atomic
1139 # copy over SVP64 input record fields (if they exist)
1141 # TODO, really do we have to do these explicitly?? sigh
1142 # for (field, _) in sv_input_record_layout:
1143 # comb += self.do_copy(field, self.rm_dec.op_get(field))
1144 comb
+= self
.do_copy("sv_saturate", self
.rm_dec
.saturate
)
1145 comb
+= self
.do_copy("sv_Ptype", self
.rm_dec
.ptype_in
)
1146 comb
+= self
.do_copy("sv_ldstmode", self
.rm_dec
.ldstmode
)
1147 # these get set up based on incoming mask bits. TODO:
1148 # pass in multiple bits (later, when SIMD backends are enabled)
1149 with m
.If(self
.rm_dec
.pred_sz
):
1150 comb
+= self
.do_copy("sv_pred_sz", ~self
.pred_sm
)
1151 with m
.If(self
.rm_dec
.pred_dz
):
1152 comb
+= self
.do_copy("sv_pred_dz", ~self
.pred_dm
)
1157 class PowerDecode2(PowerDecodeSubset
):
1158 """PowerDecode2: the main instruction decoder.
1160 whilst PowerDecode is responsible for decoding the actual opcode, this
1161 module encapsulates further specialist, sparse information and
1162 expansion of fields that is inconvenient to have in the CSV files.
1163 for example: the encoding of the immediates, which are detected
1164 and expanded out to their full value from an annotated (enum)
1167 implicit register usage is also set up, here. for example: OP_BC
1168 requires implicitly reading CTR, OP_RFID requires implicitly writing
1171 in addition, PowerDecoder2 is responsible for detecting whether
1172 instructions are illegal (or privileged) or not, and instead of
1173 just leaving at that, *replacing* the instruction to execute with
1174 a suitable alternative (trap).
1176 LDSTExceptions are done the cycle _after_ they're detected (after
1177 they come out of LDSTCompUnit). basically despite the instruction
1178 being decoded, the results of the decode are completely ignored
1179 and "exception.happened" used to set the "actual" instruction to
1180 "OP_TRAP". the LDSTException data structure gets filled in,
1181 in the CompTrapOpSubset and that's what it fills in SRR.
1183 to make this work, TestIssuer must notice "exception.happened"
1184 after the (failed) LD/ST and copies the LDSTException info from
1185 the output, into here (PowerDecoder2). without incrementing PC.
1187 also instr_fault works the same way: the instruction is "rewritten"
1188 so that the "fake" op that gets created is OP_FETCH_FAILED
1191 def __init__(self
, dec
, opkls
=None, fn_name
=None, final
=False,
1192 state
=None, svp64_en
=True, regreduce_en
=False, fp_en
=False):
1193 super().__init
__(dec
, opkls
, fn_name
, final
, state
, svp64_en
,
1194 regreduce_en
=False, fp_en
=fp_en
)
1195 self
.ldst_exc
= LDSTException("dec2_exc") # rewrites as OP_TRAP
1196 self
.instr_fault
= Signal() # rewrites instruction as OP_FETCH_FAILED
1197 self
.crout_5bit
= Signal() # CR out is 5-bit
1200 self
.cr_out_isvec
= Signal(1, name
="cr_out_isvec")
1201 self
.cr_in_isvec
= Signal(1, name
="cr_in_isvec")
1202 self
.cr_in_b_isvec
= Signal(1, name
="cr_in_b_isvec")
1203 self
.cr_in_o_isvec
= Signal(1, name
="cr_in_o_isvec")
1204 self
.in1_isvec
= Signal(1, name
="reg_a_isvec")
1205 self
.in2_isvec
= Signal(1, name
="reg_b_isvec")
1206 self
.in3_isvec
= Signal(1, name
="reg_c_isvec")
1207 self
.o_isvec
= Signal(7, name
="reg_o_isvec")
1208 self
.o2_isvec
= Signal(7, name
="reg_o2_isvec")
1209 self
.in1_step
= Signal(7, name
="reg_a_step")
1210 self
.in2_step
= Signal(7, name
="reg_b_step")
1211 self
.in3_step
= Signal(7, name
="reg_c_step")
1212 self
.o_step
= Signal(7, name
="reg_o_step")
1213 self
.o2_step
= Signal(7, name
="reg_o2_step")
1214 self
.remap_active
= Signal(5, name
="remap_active") # per reg
1215 self
.no_in_vec
= Signal(1, name
="no_in_vec") # no inputs vector
1216 self
.no_out_vec
= Signal(1, name
="no_out_vec") # no outputs vector
1217 self
.loop_continue
= Signal(1, name
="loop_continue")
1219 self
.no_in_vec
= Const(1, 1)
1220 self
.no_out_vec
= Const(1, 1)
1221 self
.loop_continue
= Const(0, 1)
1223 def get_col_subset(self
, opkls
):
1224 subset
= super().get_col_subset(opkls
)
1225 subset
.add("asmcode")
1226 subset
.add("in1_sel")
1227 subset
.add("in2_sel")
1228 subset
.add("in3_sel")
1229 subset
.add("out_sel")
1231 subset
.add("sv_in1")
1232 subset
.add("sv_in2")
1233 subset
.add("sv_in3")
1234 subset
.add("sv_out")
1235 subset
.add("sv_out2")
1236 subset
.add("sv_cr_in")
1237 subset
.add("sv_cr_out")
1238 subset
.add("SV_Etype")
1239 subset
.add("SV_Ptype")
1240 subset
.add("SV_mode")
1241 # from SVP64RMModeDecode
1242 for (field
, _
) in sv_input_record_layout
:
1245 subset
.add("internal_op")
1249 def elaborate(self
, platform
):
1250 m
= super().elaborate(platform
)
1253 op
, e_out
, do_out
= self
.op
, self
.e
, self
.e
.do
1254 dec_spr
, msr
, cia
, ext_irq
= state
.dec
, state
.msr
, state
.pc
, state
.eint
1255 rc_out
= self
.dec_rc
.rc_out
.data
1259 # fill in for a normal instruction (not an exception)
1260 # copy over if non-exception, non-privileged etc. is detected
1262 # set up submodule decoders
1263 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
, op
, self
.regreduce_en
)
1264 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
, op
)
1265 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
, op
)
1266 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
, op
, self
.regreduce_en
)
1267 m
.submodules
.dec_o2
= dec_o2
= DecodeOut2(self
.dec
, op
)
1268 m
.submodules
.dec_cr_in
= self
.dec_cr_in
= DecodeCRIn(self
.dec
, op
)
1269 m
.submodules
.dec_cr_out
= self
.dec_cr_out
= DecodeCROut(self
.dec
, op
)
1270 comb
+= dec_a
.sv_nz
.eq(self
.sv_a_nz
)
1271 comb
+= self
.crout_5bit
.eq(self
.dec_cr_out
.cr_5bit
)
1274 # and SVP64 Extra decoders
1275 m
.submodules
.crout_svdec
= crout_svdec
= SVP64CRExtra()
1276 m
.submodules
.crin_svdec
= crin_svdec
= SVP64CRExtra()
1277 m
.submodules
.crin_svdec_b
= crin_svdec_b
= SVP64CRExtra()
1278 m
.submodules
.crin_svdec_o
= crin_svdec_o
= SVP64CRExtra()
1279 m
.submodules
.in1_svdec
= in1_svdec
= SVP64RegExtra()
1280 m
.submodules
.in2_svdec
= in2_svdec
= SVP64RegExtra()
1281 m
.submodules
.in3_svdec
= in3_svdec
= SVP64RegExtra()
1282 m
.submodules
.o_svdec
= o_svdec
= SVP64RegExtra()
1283 m
.submodules
.o2_svdec
= o2_svdec
= SVP64RegExtra()
1285 # debug access to cr svdec (used in get_pdecode_cr_in/out)
1286 self
.crout_svdec
= crout_svdec
1287 self
.crin_svdec
= crin_svdec
1289 # get the 5-bit reg data before svp64-munging it into 7-bit plus isvec
1290 reg
= Signal(5, reset_less
=True)
1292 # copy instruction through...
1293 for i
in [do
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
1294 self
.dec_cr_in
.insn_in
, self
.dec_cr_out
.insn_in
,
1295 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
]:
1296 comb
+= i
.eq(self
.dec
.opcode_in
)
1299 comb
+= self
.dec_cr_in
.sel_in
.eq(self
.op_get("cr_in"))
1300 comb
+= self
.dec_cr_out
.sel_in
.eq(self
.op_get("cr_out"))
1301 comb
+= self
.dec_cr_out
.rc_in
.eq(rc_out
)
1304 comb
+= self
.do_copy("read_cr_whole", self
.dec_cr_in
.whole_reg
)
1305 comb
+= self
.do_copy("write_cr_whole", self
.dec_cr_out
.whole_reg
)
1307 # ...and subdecoders' input fields
1308 comb
+= dec_a
.sel_in
.eq(self
.op_get("in1_sel"))
1309 comb
+= dec_b
.sel_in
.eq(self
.op_get("in2_sel"))
1310 comb
+= dec_c
.sel_in
.eq(self
.op_get("in3_sel"))
1311 comb
+= dec_o
.sel_in
.eq(self
.op_get("out_sel"))
1312 comb
+= dec_o2
.sel_in
.eq(self
.op_get("out_sel"))
1314 comb
+= dec_o2
.implicit_rs
.eq(self
.implicit_rs
)
1315 comb
+= dec_o2
.implicit_from_rc
.eq(self
.extend_rc_maxvl
)
1316 if hasattr(do
, "lk"):
1317 comb
+= dec_o2
.lk
.eq(do
.lk
)
1320 # now do the SVP64 munging. op.SV_Etype and op.sv_in1 comes from
1321 # PowerDecoder which in turn comes from LDST-RM*.csv and RM-*.csv
1322 # which in turn were auto-generated by sv_analysis.py
1323 extra
= self
.sv_rm
.extra
# SVP64 extra bits 10:18
1328 comb
+= crout_svdec
.idx
.eq(self
.op_get("sv_cr_out"))
1329 comb
+= self
.cr_out_isvec
.eq(crout_svdec
.isvec
)
1332 # CR in - selection slightly different due to shared CR field sigh
1333 cr_a_idx
= Signal(SVEXTRA
)
1334 cr_b_idx
= Signal(SVEXTRA
)
1336 # these change slightly, when decoding BA/BB. really should have
1337 # their own separate CSV column: sv_cr_in1 and sv_cr_in2, but hey
1338 comb
+= cr_a_idx
.eq(self
.op_get("sv_cr_in"))
1339 comb
+= cr_b_idx
.eq(SVEXTRA
.NONE
)
1340 with m
.If(self
.op_get("sv_cr_in") == SVEXTRA
.Idx_1_2
.value
):
1341 comb
+= cr_a_idx
.eq(SVEXTRA
.Idx1
)
1342 comb
+= cr_b_idx
.eq(SVEXTRA
.Idx2
)
1344 comb
+= self
.cr_in_isvec
.eq(crin_svdec
.isvec
)
1345 comb
+= self
.cr_in_b_isvec
.eq(crin_svdec_b
.isvec
)
1346 comb
+= self
.cr_in_o_isvec
.eq(crin_svdec_o
.isvec
)
1348 # indices are slightly different, BA/BB mess sorted above
1349 comb
+= crin_svdec
.idx
.eq(cr_a_idx
) # SVP64 CR in A
1350 comb
+= crin_svdec_b
.idx
.eq(cr_b_idx
) # SVP64 CR in B
1352 comb
+= crin_svdec_o
.idx
.eq(self
.op_get("sv_cr_out"))
1354 # get SVSTATE srcstep (TODO: elwidth etc.) needed below
1355 vl
= Signal
.like(self
.state
.svstate
.vl
)
1356 maxvl
= Signal
.like(self
.state
.svstate
.maxvl
)
1357 subvl
= Signal
.like(self
.rm_dec
.rm_in
.subvl
)
1358 srcstep
= Signal
.like(self
.state
.svstate
.srcstep
)
1359 dststep
= Signal
.like(self
.state
.svstate
.dststep
)
1360 ssubstep
= Signal
.like(self
.state
.svstate
.ssubstep
)
1361 dsubstep
= Signal
.like(self
.state
.svstate
.ssubstep
)
1362 comb
+= vl
.eq(self
.state
.svstate
.vl
)
1363 comb
+= maxvl
.eq(self
.state
.svstate
.maxvl
)
1364 comb
+= subvl
.eq(self
.rm_dec
.rm_in
.subvl
)
1365 comb
+= srcstep
.eq(self
.state
.svstate
.srcstep
)
1366 comb
+= dststep
.eq(self
.state
.svstate
.dststep
)
1367 comb
+= ssubstep
.eq(self
.state
.svstate
.ssubstep
)
1368 comb
+= dsubstep
.eq(self
.state
.svstate
.dsubstep
)
1370 in1_step
, in2_step
= self
.in1_step
, self
.in2_step
1371 in3_step
= self
.in3_step
1372 o_step
, o2_step
= self
.o_step
, self
.o2_step
1374 # multiply vl by subvl - note that this is only 7 bit!
1375 # when elwidth overrides get involved this will have to go up
1377 comb
+= vmax
.eq(vl
*(subvl
+1))
1379 # registers a, b, c and out and out2 (LD/ST EA)
1380 sv_etype
= self
.op_get("SV_Etype")
1381 for i
, stuff
in enumerate((
1382 ("RA", e
.read_reg1
, dec_a
.reg_out
, in1_svdec
, in1_step
, False),
1383 ("RB", e
.read_reg2
, dec_b
.reg_out
, in2_svdec
, in2_step
, False),
1384 ("RC", e
.read_reg3
, dec_c
.reg_out
, in3_svdec
, in3_step
, False),
1385 ("RT", e
.write_reg
, dec_o
.reg_out
, o_svdec
, o_step
, True),
1386 ("EA", e
.write_ea
, dec_o2
.reg_out
, o2_svdec
, o2_step
, True))):
1387 rname
, to_reg
, fromreg
, svdec
, remapstep
, out
= stuff
1388 comb
+= svdec
.extra
.eq(extra
) # EXTRA field of SVP64 RM
1389 comb
+= svdec
.etype
.eq(sv_etype
) # EXTRA2/3 for this insn
1390 comb
+= svdec
.reg_in
.eq(fromreg
.data
) # 3-bit (CR0/BC/BFA)
1391 comb
+= to_reg
.ok
.eq(fromreg
.ok
)
1392 # *screaam* FFT mode needs an extra offset for RB
1393 # similar to FRS/FRT (below). all of this needs cleanup
1394 offs
= Signal(7, name
="offs_"+rname
, reset_less
=True)
1397 # when FFT sv.ffmadd detected, and REMAP not in use,
1398 # automagically add on an extra offset to RB.
1399 # however when REMAP is active, the FFT REMAP
1400 # schedule takes care of this offset.
1401 with m
.If(dec_o2
.reg_out
.ok
& dec_o2
.rs_en
&
1402 self
.extend_rb_maxvl
):
1403 with m
.If(~self
.remap_active
[i
]):
1404 with m
.If(svdec
.isvec
):
1405 comb
+= offs
.eq(maxvl
) # MAXVL for Vectors
1406 # detect if Vectorised: add srcstep/dststep if yes.
1407 # to_reg is 7-bits, outs get dststep added, ins get srcstep
1408 with m
.If(svdec
.isvec
):
1409 selectstep
= dststep
if out
else srcstep
1410 subselect
= dsubstep
if out
else ssubstep
1411 step
= Signal(7, name
="step_%s" % rname
.lower())
1412 with m
.If(self
.remap_active
[i
]):
1413 comb
+= step
.eq((remapstep
*(subvl
+1))+subselect
)
1415 comb
+= step
.eq((selectstep
*(subvl
+1))+subselect
)
1416 # reverse gear goes the opposite way
1417 with m
.If(self
.rm_dec
.reverse_gear
):
1418 comb
+= to_reg
.offs
.eq(offs
+(vmax
-1-step
))
1420 comb
+= to_reg
.offs
.eq(offs
+step
)
1422 comb
+= to_reg
.offs
.eq(offs
)
1423 comb
+= to_reg
.base
.eq(svdec
.reg_out
)
1424 comb
+= to_reg
.data
.eq(to_reg
.base
+ to_reg
.offs
)
1426 # SVP64 in/out fields
1427 comb
+= in1_svdec
.idx
.eq(self
.op_get("sv_in1")) # reg #1 (in1_sel)
1428 comb
+= in2_svdec
.idx
.eq(self
.op_get("sv_in2")) # reg #2 (in2_sel)
1429 comb
+= in3_svdec
.idx
.eq(self
.op_get("sv_in3")) # reg #3 (in3_sel)
1430 comb
+= o_svdec
.idx
.eq(self
.op_get("sv_out")) # output (out_sel)
1432 comb
+= o2_svdec
.idx
.eq(self
.op_get("sv_out2"))
1433 # XXX TODO - work out where this should come from. the problem is
1434 # that LD-with-update is implied (computed from "is instruction in
1435 # "update mode" rather than specified cleanly as its own CSV column
1437 # output reg-is-vectorised (and when no in/out is vectorised)
1438 comb
+= self
.in1_isvec
.eq(in1_svdec
.isvec
)
1439 comb
+= self
.in2_isvec
.eq(in2_svdec
.isvec
)
1440 comb
+= self
.in3_isvec
.eq(in3_svdec
.isvec
)
1441 comb
+= self
.o_isvec
.eq(o_svdec
.isvec
)
1442 comb
+= self
.o2_isvec
.eq(o2_svdec
.isvec
)
1444 # urrr... don't ask... the implicit register FRS in FFT mode
1445 # "tracks" FRT exactly except it's offset by MAXVL. rather than
1446 # mess up the above with if-statements, override it here.
1447 # same trick is applied to FRB, above, but it's a lot cleaner there
1448 with m
.If(dec_o2
.reg_out
.ok
& dec_o2
.rs_en
):
1449 imp_reg_out
= Signal(7)
1450 imp_isvec
= Signal(1)
1451 with m
.If(self
.extend_rc_maxvl
): # maddedu etc. from RC
1452 comb
+= imp_isvec
.eq(in3_svdec
.isvec
)
1453 comb
+= imp_reg_out
.eq(in3_svdec
.reg_out
)
1455 comb
+= imp_isvec
.eq(o_svdec
.isvec
)
1456 comb
+= imp_reg_out
.eq(o_svdec
.reg_out
)
1458 with m
.If(~self
.remap_active
[4]):
1459 with m
.If(imp_isvec
):
1460 comb
+= offs
.eq(maxvl
) # MAXVL for Vectors
1461 with m
.Elif(self
.extend_rc_maxvl
): # maddedu etc. from RC
1462 comb
+= offs
.eq(0) # keep as RC
1464 comb
+= offs
.eq(1) # add 1 if scalar
1465 with m
.If(imp_isvec
):
1466 step
= Signal(7, name
="step_%s" % rname
.lower())
1467 with m
.If(self
.remap_active
[4]):
1468 with m
.If(self
.extend_rc_maxvl
): # maddedu etc. from RC
1469 comb
+= step
.eq(in3_step
)
1471 comb
+= step
.eq(o2_step
)
1473 comb
+= step
.eq(dststep
)
1474 # reverse gear goes the opposite way
1475 with m
.If(self
.rm_dec
.reverse_gear
):
1476 roffs
= offs
+(vl
-1-step
)
1477 comb
+= e
.write_ea
.data
.eq(roffs
)
1479 comb
+= e
.write_ea
.data
.eq(offs
+step
)
1481 comb
+= e
.write_ea
.offs
.eq(offs
)
1482 comb
+= e
.write_ea
.base
.eq(imp_reg_out
)
1483 comb
+= e
.write_ea
.data
.eq(e
.write_ea
.base
+ e
.write_ea
.offs
)
1484 # ... but write to *second* output
1485 comb
+= self
.o2_isvec
.eq(imp_isvec
)
1486 comb
+= o2_svdec
.idx
.eq(self
.op_get("sv_out"))
1488 # TODO add SPRs here. must be True when *all* are scalar
1489 l
= map(lambda svdec
: svdec
.isvec
, [in1_svdec
, in2_svdec
, in3_svdec
,
1490 crin_svdec
, crin_svdec_b
,
1492 comb
+= self
.no_in_vec
.eq(~
Cat(*l
).bool()) # all input scalar
1493 l
= map(lambda svdec
: svdec
.isvec
, [
1494 o2_svdec
, o_svdec
, crout_svdec
])
1495 # in mapreduce mode, scalar out is *allowed*
1496 with m
.If(self
.rm_dec
.mode
== SVP64RMMode
.MAPREDUCE
.value
):
1497 comb
+= self
.no_out_vec
.eq(0)
1500 comb
+= self
.no_out_vec
.eq(~
Cat(*l
).bool())
1501 # now create a general-purpose "test" as to whether looping
1502 # should continue. this doesn't include predication bit-tests
1503 loop
= self
.loop_continue
1504 with m
.Switch(self
.op_get("SV_Ptype")):
1505 with m
.Case(SVPType
.P2
.value
):
1507 # TODO: *and cache-inhibited LD/ST!*
1508 comb
+= loop
.eq(~
(self
.no_in_vec | self
.no_out_vec
))
1509 with m
.Case(SVPType
.P1
.value
):
1510 # single-predication, test relies on dest only
1511 comb
+= loop
.eq(~self
.no_out_vec
)
1513 # not an SV operation, no looping
1516 # condition registers (CR)
1517 for to_reg
, cr
, name
, svdec
, out
in (
1518 (e
.read_cr1
, self
.dec_cr_in
, "cr_bitfield", crin_svdec
, 0),
1519 (e
.read_cr2
, self
.dec_cr_in
, "cr_bitfield_b", crin_svdec_b
, 0),
1520 (e
.read_cr3
, self
.dec_cr_in
, "cr_bitfield_o", crin_svdec_o
, 0),
1521 (e
.write_cr
, self
.dec_cr_out
, "cr_bitfield", crout_svdec
, 1)):
1522 fromreg
= getattr(cr
, name
)
1523 comb
+= svdec
.extra
.eq(extra
) # EXTRA field of SVP64 RM
1524 comb
+= svdec
.etype
.eq(sv_etype
) # EXTRA2/3 for this insn
1525 comb
+= svdec
.cr_in
.eq(fromreg
.data
) # 3-bit (CR0/BC/BFA)
1526 with m
.If(svdec
.isvec
):
1527 # check if this is CR0 or CR1: treated differently
1528 # (does not "listen" to EXTRA2/3 spec for a start)
1529 # also: the CRs start from completely different locations
1530 step
= dststep
if out
else srcstep
1531 with m
.If(cr
.sv_override
== 1): # CR0
1532 offs
= SVP64CROffs
.CR0
1533 comb
+= to_reg
.data
.eq(step
+offs
)
1534 with m
.Elif(cr
.sv_override
== 2): # CR1
1535 offs
= SVP64CROffs
.CR1
1536 comb
+= to_reg
.data
.eq(step
+1)
1538 comb
+= to_reg
.data
.eq(step
+svdec
.cr_out
) # 7-bit out
1540 comb
+= to_reg
.data
.eq(svdec
.cr_out
) # 7-bit output
1541 comb
+= to_reg
.ok
.eq(fromreg
.ok
)
1543 # sigh must determine if RA is nonzero (7 bit)
1544 comb
+= self
.sv_a_nz
.eq(e
.read_reg1
.data
!= Const(0, 7))
1546 # connect up to/from read/write GPRs
1547 for to_reg
, fromreg
in ((e
.read_reg1
, dec_a
.reg_out
),
1548 (e
.read_reg2
, dec_b
.reg_out
),
1549 (e
.read_reg3
, dec_c
.reg_out
),
1550 (e
.write_reg
, dec_o
.reg_out
),
1551 (e
.write_ea
, dec_o2
.reg_out
)):
1552 comb
+= to_reg
.data
.eq(fromreg
.data
)
1553 comb
+= to_reg
.ok
.eq(fromreg
.ok
)
1555 # connect up to/from read/write CRs
1556 for to_reg
, cr
, name
in (
1557 (e
.read_cr1
, self
.dec_cr_in
, "cr_bitfield", ),
1558 (e
.read_cr2
, self
.dec_cr_in
, "cr_bitfield_b", ),
1559 (e
.read_cr3
, self
.dec_cr_in
, "cr_bitfield_o", ),
1560 (e
.write_cr
, self
.dec_cr_out
, "cr_bitfield", )):
1561 fromreg
= getattr(cr
, name
)
1562 comb
+= to_reg
.data
.eq(fromreg
.data
)
1563 comb
+= to_reg
.ok
.eq(fromreg
.ok
)
1566 comb
+= self
.rm_dec
.ldst_ra_vec
.eq(self
.in1_isvec
) # RA is vector
1567 comb
+= self
.rm_dec
.cr_5bit_in
.eq(self
.crout_5bit
) # CR is 5-bit
1568 # take bottom 2 bits of CR out (CR field selector)
1569 with m
.If(self
.crout_5bit
):
1570 comb
+= self
.rm_dec
.cr_2bit_in
.eq(self
.dec_cr_out
.cr_2bit
)
1573 comb
+= e
.read_spr1
.eq(dec_a
.spr_out
)
1574 comb
+= e
.write_spr
.eq(dec_o
.spr_out
)
1576 # Fast regs out including SRR0/1/SVSRR0
1577 comb
+= e
.read_fast1
.eq(dec_a
.fast_out
)
1578 comb
+= e
.read_fast2
.eq(dec_b
.fast_out
)
1579 comb
+= e
.write_fast1
.eq(dec_o
.fast_out
) # SRR0 (OP_RFID)
1580 comb
+= e
.write_fast2
.eq(dec_o2
.fast_out
) # SRR1 (ditto)
1581 comb
+= e
.write_fast3
.eq(dec_o2
.fast_out3
) # SVSRR0 (ditto)
1582 # and State regs (DEC, TB)
1583 comb
+= e
.read_state1
.eq(dec_a
.state_out
) # DEC/TB
1584 comb
+= e
.write_state1
.eq(dec_o
.state_out
) # DEC/TB
1586 # sigh this is exactly the sort of thing for which the
1587 # decoder is designed to not need. MTSPR, MFSPR and others need
1588 # access to the XER bits. however setting e.oe is not appropriate
1589 internal_op
= self
.op_get("internal_op")
1590 with m
.If(internal_op
== MicrOp
.OP_MFSPR
):
1591 comb
+= e
.xer_in
.eq(0b111) # SO, CA, OV
1592 with m
.If(internal_op
== MicrOp
.OP_CMP
):
1593 comb
+= e
.xer_in
.eq(1 << XERRegsEnum
.SO
) # SO
1594 with m
.If(internal_op
== MicrOp
.OP_MTSPR
):
1595 comb
+= e
.xer_out
.eq(1)
1597 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
1598 with m
.If(op
.internal_op
== MicrOp
.OP_TRAP
):
1599 # *DO NOT* call self.trap here. that would reset absolutely
1600 # everything including destroying read of RA and RB.
1601 comb
+= self
.do_copy("trapaddr", 0x70) # strip first nibble
1603 ####################
1604 # ok so the instruction's been decoded, blah blah, however
1605 # now we need to determine if it's actually going to go ahead...
1606 # *or* if in fact it's a privileged operation, whether there's
1607 # an external interrupt, etc. etc. this is a simple priority
1608 # if-elif-elif sequence. decrement takes highest priority,
1609 # EINT next highest, privileged operation third.
1611 # check if instruction is privileged
1612 is_priv_insn
= instr_is_priv(m
, op
.internal_op
, e
.do
.insn
)
1614 # different IRQ conditions
1615 ext_irq_ok
= Signal()
1616 dec_irq_ok
= Signal()
1619 ldst_exc
= self
.ldst_exc
1621 comb
+= ext_irq_ok
.eq(ext_irq
& msr
[MSR
.EE
]) # v3.0B p944 (MSR.EE)
1622 comb
+= dec_irq_ok
.eq(dec_spr
[63] & msr
[MSR
.EE
]) # 6.5.11 p1076
1623 comb
+= priv_ok
.eq(is_priv_insn
& msr
[MSR
.PR
])
1624 comb
+= illeg_ok
.eq(op
.internal_op
== MicrOp
.OP_ILLEGAL
)
1626 # absolute top priority: check for an instruction failed
1627 with m
.If(self
.instr_fault
):
1628 comb
+= self
.e
.eq(0) # reset eeeeeverything
1629 comb
+= self
.do_copy("insn", self
.dec
.opcode_in
, True)
1630 comb
+= self
.do_copy("insn_type", MicrOp
.OP_FETCH_FAILED
, True)
1631 comb
+= self
.do_copy("fn_unit", Function
.MMU
, True)
1632 comb
+= self
.do_copy("cia", self
.state
.pc
, True) # PC
1633 comb
+= self
.do_copy("msr", self
.state
.msr
, True) # MSR
1634 # special override on internal_op, due to being a "fake" op
1635 comb
+= self
.dec
.op
.internal_op
.eq(MicrOp
.OP_FETCH_FAILED
)
1637 # LD/ST exceptions. TestIssuer copies the exception info at us
1638 # after a failed LD/ST.
1639 with m
.Elif(ldst_exc
.happened
):
1640 with m
.If(ldst_exc
.alignment
):
1641 self
.trap(m
, TT
.MEMEXC
, 0x600)
1642 with m
.Elif(ldst_exc
.instr_fault
):
1643 with m
.If(ldst_exc
.segment_fault
):
1644 self
.trap(m
, TT
.MEMEXC
, 0x480)
1646 # pass exception info to trap to create SRR1
1647 self
.trap(m
, TT
.MEMEXC
, 0x400, ldst_exc
)
1649 with m
.If(ldst_exc
.segment_fault
):
1650 self
.trap(m
, TT
.MEMEXC
, 0x380)
1652 self
.trap(m
, TT
.MEMEXC
, 0x300)
1654 # decrement counter (v3.0B p1099): TODO 32-bit version (MSR.LPCR)
1655 with m
.Elif(dec_irq_ok
):
1656 self
.trap(m
, TT
.DEC
, 0x900) # v3.0B 6.5 p1065
1658 # external interrupt? only if MSR.EE set
1659 with m
.Elif(ext_irq_ok
):
1660 self
.trap(m
, TT
.EINT
, 0x500)
1662 # privileged instruction trap
1663 with m
.Elif(priv_ok
):
1664 self
.trap(m
, TT
.PRIV
, 0x700)
1666 # illegal instruction must redirect to trap. this is done by
1667 # *overwriting* the decoded instruction and starting again.
1668 # (note: the same goes for interrupts and for privileged operations,
1669 # just with different trapaddr and traptype)
1670 with m
.Elif(illeg_ok
):
1671 # illegal instruction trap
1672 self
.trap(m
, TT
.ILLEG
, 0x700)
1674 # no exception, just copy things to the output
1678 ####################
1679 # follow-up after trap/irq to set up SRR0/1
1681 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
1682 # Note: OP_SC could actually be modified to just be a trap
1683 with m
.If((do_out
.insn_type
== MicrOp
.OP_TRAP
) |
1684 (do_out
.insn_type
== MicrOp
.OP_SC
)):
1685 # TRAP write fast1 = SRR0
1686 comb
+= e_out
.write_fast1
.data
.eq(FastRegsEnum
.SRR0
) # SRR0
1687 comb
+= e_out
.write_fast1
.ok
.eq(1)
1688 # TRAP write fast2 = SRR1
1689 comb
+= e_out
.write_fast2
.data
.eq(FastRegsEnum
.SRR1
) # SRR1
1690 comb
+= e_out
.write_fast2
.ok
.eq(1)
1691 # TRAP write fast2 = SRR1
1692 comb
+= e_out
.write_fast3
.data
.eq(FastRegsEnum
.SVSRR0
) # SVSRR0
1693 comb
+= e_out
.write_fast3
.ok
.eq(1)
1695 # RFID: needs to read SRR0/1
1696 with m
.If(do_out
.insn_type
== MicrOp
.OP_RFID
):
1697 # TRAP read fast1 = SRR0
1698 comb
+= e_out
.read_fast1
.data
.eq(FastRegsEnum
.SRR0
) # SRR0
1699 comb
+= e_out
.read_fast1
.ok
.eq(1)
1700 # TRAP read fast2 = SRR1
1701 comb
+= e_out
.read_fast2
.data
.eq(FastRegsEnum
.SRR1
) # SRR1
1702 comb
+= e_out
.read_fast2
.ok
.eq(1)
1703 # TRAP read fast2 = SVSRR0
1704 comb
+= e_out
.read_fast3
.data
.eq(FastRegsEnum
.SVSRR0
) # SVSRR0
1705 comb
+= e_out
.read_fast3
.ok
.eq(1)
1707 # annoying simulator bug.
1708 # asmcode may end up getting used for perfcounters?
1709 asmcode
= self
.op_get("asmcode")
1710 if hasattr(e_out
, "asmcode") and asmcode
is not None:
1711 comb
+= e_out
.asmcode
.eq(asmcode
)
1715 def trap(self
, m
, traptype
, trapaddr
, ldst_exc
=None):
1716 """trap: this basically "rewrites" the decoded instruction as a trap
1720 comb
+= e
.eq(0) # reset eeeeeverything
1723 comb
+= self
.do_copy("insn", self
.dec
.opcode_in
, True)
1724 comb
+= self
.do_copy("insn_type", MicrOp
.OP_TRAP
, True)
1725 comb
+= self
.do_copy("fn_unit", Function
.TRAP
, True)
1726 comb
+= self
.do_copy("trapaddr", trapaddr
>> 4, True) # bottom 4 bits
1727 comb
+= self
.do_copy("traptype", traptype
, True) # request type
1728 comb
+= self
.do_copy("ldst_exc", ldst_exc
, True) # request type
1729 comb
+= self
.do_copy("msr", self
.state
.msr
,
1730 True) # copy of MSR "state"
1731 comb
+= self
.do_copy("cia", self
.state
.pc
, True) # copy of PC "state"
1732 comb
+= self
.do_copy("svstate", self
.state
.svstate
, True) # SVSTATE
1735 def get_rdflags(m
, e
, cu
):
1736 """returns a sequential list of the read "ok" flags for a given FU.
1737 this list is in order of the CompUnit input specs
1740 for idx
in range(cu
.n_src
):
1741 regfile
, regname
, _
= cu
.get_in_spec(idx
)
1742 decinfo
= regspec_decode_read(m
, e
, regfile
, regname
)
1743 rdl
.append(decinfo
.okflag
)
1748 if __name__
== '__main__':
1749 pdecode
= create_pdecode()
1750 dec2
= PowerDecode2(pdecode
, svp64_en
=True)
1751 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
1752 with
open("dec2.il", "w") as f
: