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 soc
.regfile
.regfiles
import XERRegs
13 from nmutil
.picker
import PriorityPicker
14 from nmutil
.iocontrol
import RecordObject
15 from nmutil
.extend
import exts
17 from soc
.experiment
.mem_types
import LDSTException
19 from soc
.decoder
.power_regspec_map
import regspec_decode_read
20 from soc
.decoder
.power_regspec_map
import regspec_decode_write
21 from soc
.decoder
.power_decoder
import create_pdecode
22 from soc
.decoder
.power_enums
import (MicrOp
, CryIn
, Function
,
24 LdstLen
, In1Sel
, In2Sel
, In3Sel
,
25 OutSel
, SPR
, RC
, LDSTMode
,
27 from soc
.decoder
.decode2execute1
import (Decode2ToExecute1Type
, Data
,
29 from soc
.sv
.svp64
import SVP64Rec
30 from soc
.consts
import MSR
32 from soc
.regfile
.regfiles
import FastRegs
33 from soc
.consts
import TT
34 from soc
.config
.state
import CoreState
35 from soc
.regfile
.util
import spr_to_fast
38 def decode_spr_num(spr
):
39 return Cat(spr
[5:10], spr
[0:5])
42 def instr_is_priv(m
, op
, insn
):
43 """determines if the instruction is privileged or not
46 is_priv_insn
= Signal(reset_less
=True)
48 with m
.Case(MicrOp
.OP_ATTN
, MicrOp
.OP_MFMSR
, MicrOp
.OP_MTMSRD
,
49 MicrOp
.OP_MTMSR
, MicrOp
.OP_RFID
):
50 comb
+= is_priv_insn
.eq(1)
52 #with m.Case(MicrOp.OP_TLBIE) : comb += is_priv_insn.eq(1)
53 with m
.Case(MicrOp
.OP_MFSPR
, MicrOp
.OP_MTSPR
):
54 with m
.If(insn
[20]): # field XFX.spr[-1] i think
55 comb
+= is_priv_insn
.eq(1)
59 class SPRMap(Elaboratable
):
60 """SPRMap: maps POWER9 SPR numbers to internal enum values, fast and slow
64 self
.spr_i
= Signal(10, reset_less
=True)
65 self
.spr_o
= Data(SPR
, name
="spr_o")
66 self
.fast_o
= Data(3, name
="fast_o")
68 def elaborate(self
, platform
):
70 with m
.Switch(self
.spr_i
):
71 for i
, x
in enumerate(SPR
):
73 m
.d
.comb
+= self
.spr_o
.data
.eq(i
)
74 m
.d
.comb
+= self
.spr_o
.ok
.eq(1)
75 for x
, v
in spr_to_fast
.items():
77 m
.d
.comb
+= self
.fast_o
.data
.eq(v
)
78 m
.d
.comb
+= self
.fast_o
.ok
.eq(1)
82 class SVP64ExtraSpec(Elaboratable
):
83 """SVP64ExtraSpec - decodes SVP64 Extra specification.
85 selects the required EXTRA2/3 field.
87 see https://libre-soc.org/openpower/sv/svp64/
90 self
.extra
= Signal(10, reset_less
=True)
91 self
.etype
= Signal(SVEtype
, reset_less
=True) # 2 or 3 bits
92 self
.idx
= Signal(SVEXTRA
, reset_less
=True) # which part of extra
93 self
.spec
= Signal(3) # EXTRA spec for the register
95 def elaborate(self
, platform
):
100 # back in the LDSTRM-* and RM-* files generated by sv_analysis.py
101 # we marked every op with an Etype: EXTRA2 or EXTRA3, and also said
102 # which of the 4 (or 3 for EXTRA3) sub-fields of bits 10:18 contain
103 # the register-extension information. extract those how
104 with m
.Switch(self
.etype
):
105 # 2-bit index selection mode
106 with m
.Case(SVEtype
.EXTRA2
):
107 with m
.Switch(self
.idx
):
108 with m
.Case(SVEXTRA
.Idx0
): # 1st 2 bits
109 comb
+= spec
[1:3].eq(self
.extra
[0:2])
110 with m
.Case(SVEXTRA
.Idx1
): # 2nd 2 bits
111 comb
+= spec
[1:3].eq(self
.extra
[2:4])
112 with m
.Case(SVEXTRA
.Idx2
): # 3rd 2 bits
113 comb
+= spec
[1:3].eq(self
.extra
[4:6])
114 with m
.Case(SVEXTRA
.Idx3
): # 4th 2 bits
115 comb
+= spec
[1:3].eq(self
.extra
[6:8])
116 # 3-bit index selection mode
117 with m
.Case(SVEtype
.EXTRA3
):
118 with m
.Switch(self
.idx
):
119 with m
.Case(SVEXTRA
.Idx0
): # 1st 3 bits
120 comb
+= spec
.eq(self
.extra
[0:3])
121 with m
.Case(SVEXTRA
.Idx1
): # 2nd 3 bits
122 comb
+= spec
.eq(self
.extra
[3:6])
123 with m
.Case(SVEXTRA
.Idx2
): # 3rd 3 bits
124 comb
+= spec
.eq(self
.extra
[6:9])
125 # cannot fit more than 9 bits so there is no 4th thing
130 class SVP64RegExtra(SVP64ExtraSpec
):
131 """SVP64RegExtra - decodes SVP64 Extra fields to determine reg extension
133 incoming 5-bit GPR/FP is turned into a 7-bit and marked as scalar/vector
134 depending on info in one of the positions in the EXTRA field.
136 designed so that "no change" to the 5-bit register number occurs if
137 SV either does not apply or the relevant EXTRA2/3 field bits are zero.
139 see https://libre-soc.org/openpower/sv/svp64/
142 SVP64ExtraSpec
.__init
__(self
)
143 self
.reg_in
= Signal(5) # incoming reg number (5 bits, RA, RB)
144 self
.reg_out
= Signal(7) # extra-augmented output (7 bits)
145 self
.isvec
= Signal(1) # reg is marked as vector if true
147 def elaborate(self
, platform
):
148 m
= super().elaborate(platform
)
151 # first get the spec. if not changed it's "scalar identity behaviour"
152 # which is zero which is ok.
155 # now decode it. bit 2 is "scalar/vector". note that spec could be zero
156 # from above, which (by design) has the effect of "no change", below.
158 # simple: isvec is top bit of spec
159 comb
+= self
.isvec
.eq(spec
[2])
161 # decode vector differently from scalar
162 with m
.If(self
.isvec
):
163 # Vector: shifted up, extra in LSBs (RA << 2) | spec[0:1]
164 comb
+= self
.reg_out
.eq(Cat(spec
[:2], self
.reg_in
))
166 # Scalar: not shifted up, extra in MSBs RA | (spec[0:1] << 5)
167 comb
+= self
.reg_out
.eq(Cat(self
.reg_in
, spec
[:2]))
172 class DecodeA(Elaboratable
):
173 """DecodeA from instruction
175 decodes register RA, implicit and explicit CSRs
178 def __init__(self
, dec
):
180 self
.sv_rm
= SVP64Rec() # SVP64 RM field
181 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
182 self
.insn_in
= Signal(32, reset_less
=True)
183 self
.reg_out
= Data(7, name
="reg_a")
184 self
.reg_isvec
= Signal(1, name
="reg_a_isvec") # TODO: in reg_out
185 self
.spr_out
= Data(SPR
, "spr_a")
186 self
.fast_out
= Data(3, "fast_a")
188 def elaborate(self
, platform
):
192 m
.submodules
.sprmap
= sprmap
= SPRMap()
193 m
.submodules
.svdec
= svdec
= SVP64RegExtra()
195 # get the 5-bit reg data before svp64-munging it into 7-bit plus isvec
196 reg
= Signal(5, reset_less
=True)
198 # select Register A field
199 ra
= Signal(5, reset_less
=True)
200 comb
+= ra
.eq(self
.dec
.RA
)
201 with m
.If((self
.sel_in
== In1Sel
.RA
) |
202 ((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
203 (ra
!= Const(0, 5)))):
205 comb
+= self
.reg_out
.ok
.eq(1)
207 # some Logic/ALU ops have RS as the 3rd arg, but no "RA".
208 # moved it to 1st position (in1_sel)... because
209 rs
= Signal(5, reset_less
=True)
210 comb
+= rs
.eq(self
.dec
.RS
)
211 with m
.If(self
.sel_in
== In1Sel
.RS
):
213 comb
+= self
.reg_out
.ok
.eq(1)
215 # now do the SVP64 munging. op.SV_Etype and op.sv_in1 comes from
216 # PowerDecoder which in turn comes from LDST-RM*.csv and RM-*.csv
217 # which in turn were auto-generated by sv_analysis.py
219 extra
= self
.sv_rm
.extra
# SVP64 extra bits 10:18
220 comb
+= svdec
.extra
.eq(extra
) # EXTRA field of SVP64 RM
221 comb
+= svdec
.etype
.eq(op
.SV_Etype
) # EXTRA2/3 for this insn
222 comb
+= svdec
.idx
.eq(op
.sv_in1
) # SVP64 reg #1 (matches in1_sel)
223 comb
+= svdec
.reg_in
.eq(reg
) # 5-bit (RA, RS)
225 # outputs: 7-bit reg number and whether it's vectorised
226 comb
+= self
.reg_out
.data
.eq(svdec
.reg_out
)
227 comb
+= self
.reg_isvec
.eq(svdec
.isvec
)
229 # decode Fast-SPR based on instruction type
230 with m
.Switch(op
.internal_op
):
232 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeOut
233 with m
.Case(MicrOp
.OP_BC
):
234 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
236 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
237 comb
+= self
.fast_out
.ok
.eq(1)
238 with m
.Case(MicrOp
.OP_BCREG
):
239 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
240 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
241 with m
.If(xo9
& ~xo5
):
243 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
244 comb
+= self
.fast_out
.ok
.eq(1)
246 # MFSPR move from SPRs
247 with m
.Case(MicrOp
.OP_MFSPR
):
248 spr
= Signal(10, reset_less
=True)
249 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
250 comb
+= sprmap
.spr_i
.eq(spr
)
251 comb
+= self
.spr_out
.eq(sprmap
.spr_o
)
252 comb
+= self
.fast_out
.eq(sprmap
.fast_o
)
257 class DecodeAImm(Elaboratable
):
258 """DecodeA immediate from instruction
260 decodes register RA, whether immediate-zero, implicit and
264 def __init__(self
, dec
):
266 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
267 self
.immz_out
= Signal(reset_less
=True)
269 def elaborate(self
, platform
):
273 # zero immediate requested
274 ra
= Signal(5, reset_less
=True)
275 comb
+= ra
.eq(self
.dec
.RA
)
276 with m
.If((self
.sel_in
== In1Sel
.RA_OR_ZERO
) & (ra
== Const(0, 5))):
277 comb
+= self
.immz_out
.eq(1)
282 class DecodeB(Elaboratable
):
283 """DecodeB from instruction
285 decodes register RB, different forms of immediate (signed, unsigned),
286 and implicit SPRs. register B is basically "lane 2" into the CompUnits.
287 by industry-standard convention, "lane 2" is where fully-decoded
288 immediates are muxed in.
291 def __init__(self
, dec
):
293 self
.sv_rm
= SVP64Rec() # SVP64 RM field
294 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
295 self
.insn_in
= Signal(32, reset_less
=True)
296 self
.reg_out
= Data(7, "reg_b")
297 self
.reg_isvec
= Signal(1, name
="reg_b_isvec") # TODO: in reg_out
298 self
.fast_out
= Data(3, "fast_b")
300 def elaborate(self
, platform
):
304 m
.submodules
.svdec
= svdec
= SVP64RegExtra()
306 # get the 5-bit reg data before svp64-munging it into 7-bit plus isvec
307 reg
= Signal(5, reset_less
=True)
309 # select Register B field
310 with m
.Switch(self
.sel_in
):
311 with m
.Case(In2Sel
.RB
):
312 comb
+= reg
.eq(self
.dec
.RB
)
313 comb
+= self
.reg_out
.ok
.eq(1)
314 with m
.Case(In2Sel
.RS
):
315 # for M-Form shiftrot
316 comb
+= reg
.eq(self
.dec
.RS
)
317 comb
+= self
.reg_out
.ok
.eq(1)
319 # now do the SVP64 munging. different from DecodeA only by sv_in2
321 extra
= self
.sv_rm
.extra
# SVP64 extra bits 10:18
322 comb
+= svdec
.extra
.eq(extra
) # EXTRA field of SVP64 RM
323 comb
+= svdec
.etype
.eq(op
.SV_Etype
) # EXTRA2/3 for this insn
324 comb
+= svdec
.idx
.eq(op
.sv_in2
) # SVP64 reg #2 (matches in2_sel)
325 comb
+= svdec
.reg_in
.eq(reg
) # 5-bit (RA, RS)
327 # outputs: 7-bit reg number and whether it's vectorised
328 comb
+= self
.reg_out
.data
.eq(svdec
.reg_out
)
329 comb
+= self
.reg_isvec
.eq(svdec
.isvec
)
331 # decode SPR2 based on instruction type
332 # BCREG implicitly uses LR or TAR for 2nd reg
333 # CTR however is already in fast_spr1 *not* 2.
334 with m
.If(op
.internal_op
== MicrOp
.OP_BCREG
):
335 xo9
= self
.dec
.FormXL
.XO
[9] # 3.0B p38 top bit of XO
336 xo5
= self
.dec
.FormXL
.XO
[5] # 3.0B p38
338 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
)
339 comb
+= self
.fast_out
.ok
.eq(1)
341 comb
+= self
.fast_out
.data
.eq(FastRegs
.TAR
)
342 comb
+= self
.fast_out
.ok
.eq(1)
347 class DecodeBImm(Elaboratable
):
348 """DecodeB immediate from instruction
350 def __init__(self
, dec
):
352 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
353 self
.imm_out
= Data(64, "imm_b")
355 def elaborate(self
, platform
):
359 # select Register B Immediate
360 with m
.Switch(self
.sel_in
):
361 with m
.Case(In2Sel
.CONST_UI
): # unsigned
362 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
)
363 comb
+= self
.imm_out
.ok
.eq(1)
364 with m
.Case(In2Sel
.CONST_SI
): # sign-extended 16-bit
365 si
= Signal(16, reset_less
=True)
366 comb
+= si
.eq(self
.dec
.SI
)
367 comb
+= self
.imm_out
.data
.eq(exts(si
, 16, 64))
368 comb
+= self
.imm_out
.ok
.eq(1)
369 with m
.Case(In2Sel
.CONST_SI_HI
): # sign-extended 16+16=32 bit
370 si_hi
= Signal(32, reset_less
=True)
371 comb
+= si_hi
.eq(self
.dec
.SI
<< 16)
372 comb
+= self
.imm_out
.data
.eq(exts(si_hi
, 32, 64))
373 comb
+= self
.imm_out
.ok
.eq(1)
374 with m
.Case(In2Sel
.CONST_UI_HI
): # unsigned
375 ui
= Signal(16, reset_less
=True)
376 comb
+= ui
.eq(self
.dec
.UI
)
377 comb
+= self
.imm_out
.data
.eq(ui
<< 16)
378 comb
+= self
.imm_out
.ok
.eq(1)
379 with m
.Case(In2Sel
.CONST_LI
): # sign-extend 24+2=26 bit
380 li
= Signal(26, reset_less
=True)
381 comb
+= li
.eq(self
.dec
.LI
<< 2)
382 comb
+= self
.imm_out
.data
.eq(exts(li
, 26, 64))
383 comb
+= self
.imm_out
.ok
.eq(1)
384 with m
.Case(In2Sel
.CONST_BD
): # sign-extend (14+2)=16 bit
385 bd
= Signal(16, reset_less
=True)
386 comb
+= bd
.eq(self
.dec
.BD
<< 2)
387 comb
+= self
.imm_out
.data
.eq(exts(bd
, 16, 64))
388 comb
+= self
.imm_out
.ok
.eq(1)
389 with m
.Case(In2Sel
.CONST_DS
): # sign-extended (14+2=16) bit
390 ds
= Signal(16, reset_less
=True)
391 comb
+= ds
.eq(self
.dec
.DS
<< 2)
392 comb
+= self
.imm_out
.data
.eq(exts(ds
, 16, 64))
393 comb
+= self
.imm_out
.ok
.eq(1)
394 with m
.Case(In2Sel
.CONST_M1
): # signed (-1)
395 comb
+= self
.imm_out
.data
.eq(~
Const(0, 64)) # all 1s
396 comb
+= self
.imm_out
.ok
.eq(1)
397 with m
.Case(In2Sel
.CONST_SH
): # unsigned - for shift
398 comb
+= self
.imm_out
.data
.eq(self
.dec
.sh
)
399 comb
+= self
.imm_out
.ok
.eq(1)
400 with m
.Case(In2Sel
.CONST_SH32
): # unsigned - for shift
401 comb
+= self
.imm_out
.data
.eq(self
.dec
.SH32
)
402 comb
+= self
.imm_out
.ok
.eq(1)
407 class DecodeC(Elaboratable
):
408 """DecodeC from instruction
410 decodes register RC. this is "lane 3" into some CompUnits (not many)
413 def __init__(self
, dec
):
415 self
.sv_rm
= SVP64Rec() # SVP64 RM field
416 self
.sel_in
= Signal(In3Sel
, reset_less
=True)
417 self
.insn_in
= Signal(32, reset_less
=True)
418 self
.reg_out
= Data(7, "reg_c")
419 self
.reg_isvec
= Signal(1, name
="reg_c_isvec") # TODO: in reg_out
421 def elaborate(self
, platform
):
425 m
.submodules
.svdec
= svdec
= SVP64RegExtra()
427 # get the 5-bit reg data before svp64-munging it into 7-bit plus isvec
428 reg
= Signal(5, reset_less
=True)
430 # select Register C field
431 with m
.Switch(self
.sel_in
):
432 with m
.Case(In3Sel
.RB
):
433 # for M-Form shiftrot
434 comb
+= reg
.eq(self
.dec
.RB
)
435 comb
+= self
.reg_out
.ok
.eq(1)
436 with m
.Case(In3Sel
.RS
):
437 comb
+= reg
.eq(self
.dec
.RS
)
438 comb
+= self
.reg_out
.ok
.eq(1)
440 # now do the SVP64 munging. different from DecodeA only by sv_in3
442 extra
= self
.sv_rm
.extra
# SVP64 extra bits 10:18
443 comb
+= svdec
.extra
.eq(extra
) # EXTRA field of SVP64 RM
444 comb
+= svdec
.etype
.eq(op
.SV_Etype
) # EXTRA2/3 for this insn
445 comb
+= svdec
.idx
.eq(op
.sv_in3
) # SVP64 reg #3 (matches in3_sel)
446 comb
+= svdec
.reg_in
.eq(reg
) # 5-bit (RA, RS)
448 # outputs: 7-bit reg number and whether it's vectorised
449 comb
+= self
.reg_out
.data
.eq(svdec
.reg_out
)
450 comb
+= self
.reg_isvec
.eq(svdec
.isvec
)
455 class DecodeOut(Elaboratable
):
456 """DecodeOut from instruction
458 decodes output register RA, RT or SPR
461 def __init__(self
, dec
):
463 self
.sv_rm
= SVP64Rec() # SVP64 RM field
464 self
.sel_in
= Signal(OutSel
, reset_less
=True)
465 self
.insn_in
= Signal(32, reset_less
=True)
466 self
.reg_out
= Data(7, "reg_o")
467 self
.reg_isvec
= Signal(1, name
="reg_o_isvec") # TODO: in reg_out
468 self
.spr_out
= Data(SPR
, "spr_o")
469 self
.fast_out
= Data(3, "fast_o")
471 def elaborate(self
, platform
):
474 m
.submodules
.sprmap
= sprmap
= SPRMap()
476 m
.submodules
.svdec
= svdec
= SVP64RegExtra()
478 # get the 5-bit reg data before svp64-munging it into 7-bit plus isvec
479 reg
= Signal(5, reset_less
=True)
481 # select Register out field
482 with m
.Switch(self
.sel_in
):
483 with m
.Case(OutSel
.RT
):
484 comb
+= reg
.eq(self
.dec
.RT
)
485 comb
+= self
.reg_out
.ok
.eq(1)
486 with m
.Case(OutSel
.RA
):
487 comb
+= reg
.eq(self
.dec
.RA
)
488 comb
+= self
.reg_out
.ok
.eq(1)
489 with m
.Case(OutSel
.SPR
):
490 spr
= Signal(10, reset_less
=True)
491 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
492 # MFSPR move to SPRs - needs mapping
493 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
494 comb
+= sprmap
.spr_i
.eq(spr
)
495 comb
+= self
.spr_out
.eq(sprmap
.spr_o
)
496 comb
+= self
.fast_out
.eq(sprmap
.fast_o
)
498 # now do the SVP64 munging. different from DecodeA only by sv_out
500 extra
= self
.sv_rm
.extra
# SVP64 extra bits 10:18
501 comb
+= svdec
.extra
.eq(extra
) # EXTRA field of SVP64 RM
502 comb
+= svdec
.etype
.eq(op
.SV_Etype
) # EXTRA2/3 for this insn
503 comb
+= svdec
.idx
.eq(op
.sv_out
) # SVP64 reg out1 (matches out_sel)
504 comb
+= svdec
.reg_in
.eq(reg
) # 5-bit (RA, RS)
506 # outputs: 7-bit reg number and whether it's vectorised
507 comb
+= self
.reg_out
.data
.eq(svdec
.reg_out
)
508 comb
+= self
.reg_isvec
.eq(svdec
.isvec
)
511 with m
.Switch(op
.internal_op
):
513 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeA
514 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_BCREG
):
515 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
517 comb
+= self
.fast_out
.data
.eq(FastRegs
.CTR
)
518 comb
+= self
.fast_out
.ok
.eq(1)
520 # RFID 1st spr (fast)
521 with m
.Case(MicrOp
.OP_RFID
):
522 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
523 comb
+= self
.fast_out
.ok
.eq(1)
528 class DecodeOut2(Elaboratable
):
529 """DecodeOut2 from instruction
531 decodes output registers (2nd one). note that RA is *implicit* below,
532 which now causes problems with SVP64
534 TODO: SVP64 is a little more complex, here. svp64 allows extending
535 by one more destination by having one more EXTRA field. RA-as-src
536 is not the same as RA-as-dest. limited in that it's the same first
537 5 bits (from the v3.0B opcode), but still kinda cool. mostly used
538 for operations that have src-as-dest: mostly this is LD/ST-with-update
539 but there are others.
542 def __init__(self
, dec
):
544 self
.sv_rm
= SVP64Rec() # SVP64 RM field
545 self
.sel_in
= Signal(OutSel
, reset_less
=True)
546 self
.lk
= Signal(reset_less
=True)
547 self
.insn_in
= Signal(32, reset_less
=True)
548 self
.reg_out
= Data(7, "reg_o2")
549 #self.reg_isvec = Signal(1, name="reg_o2_isvec") # TODO: in reg_out
550 self
.fast_out
= Data(3, "fast_o2")
552 def elaborate(self
, platform
):
556 #m.submodules.svdec = svdec = SVP64RegExtra()
558 # get the 5-bit reg data before svp64-munging it into 7-bit plus isvec
559 #reg = Signal(5, reset_less=True)
561 if hasattr(self
.dec
.op
, "upd"):
562 # update mode LD/ST uses read-reg A also as an output
563 with m
.If(self
.dec
.op
.upd
== LDSTMode
.update
):
564 comb
+= self
.reg_out
.data
.eq(self
.dec
.RA
)
565 comb
+= self
.reg_out
.ok
.eq(1)
567 # B, BC or BCREG: potential implicit register (LR) output
568 # these give bl, bcl, bclrl, etc.
569 with m
.Switch(op
.internal_op
):
571 # BC* implicit register (LR)
572 with m
.Case(MicrOp
.OP_BC
, MicrOp
.OP_B
, MicrOp
.OP_BCREG
):
573 with m
.If(self
.lk
): # "link" mode
574 comb
+= self
.fast_out
.data
.eq(FastRegs
.LR
) # constant: LR
575 comb
+= self
.fast_out
.ok
.eq(1)
577 # RFID 2nd spr (fast)
578 with m
.Case(MicrOp
.OP_RFID
):
579 comb
+= self
.fast_out
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
580 comb
+= self
.fast_out
.ok
.eq(1)
585 class DecodeRC(Elaboratable
):
586 """DecodeRc from instruction
588 decodes Record bit Rc
591 def __init__(self
, dec
):
593 self
.sel_in
= Signal(RC
, reset_less
=True)
594 self
.insn_in
= Signal(32, reset_less
=True)
595 self
.rc_out
= Data(1, "rc")
597 def elaborate(self
, platform
):
601 # select Record bit out field
602 with m
.Switch(self
.sel_in
):
604 comb
+= self
.rc_out
.data
.eq(self
.dec
.Rc
)
605 comb
+= self
.rc_out
.ok
.eq(1)
607 comb
+= self
.rc_out
.data
.eq(1)
608 comb
+= self
.rc_out
.ok
.eq(1)
609 with m
.Case(RC
.NONE
):
610 comb
+= self
.rc_out
.data
.eq(0)
611 comb
+= self
.rc_out
.ok
.eq(1)
616 class DecodeOE(Elaboratable
):
617 """DecodeOE from instruction
619 decodes OE field: uses RC decode detection which might not be good
621 -- For now, use "rc" in the decode table to decide whether oe exists.
622 -- This is not entirely correct architecturally: For mulhd and
623 -- mulhdu, the OE field is reserved. It remains to be seen what an
624 -- actual POWER9 does if we set it on those instructions, for now we
625 -- test that further down when assigning to the multiplier oe input.
628 def __init__(self
, dec
):
630 self
.sel_in
= Signal(RC
, reset_less
=True)
631 self
.insn_in
= Signal(32, reset_less
=True)
632 self
.oe_out
= Data(1, "oe")
634 def elaborate(self
, platform
):
639 with m
.Switch(op
.internal_op
):
641 # mulhw, mulhwu, mulhd, mulhdu - these *ignore* OE
643 # XXX ARGH! ignoring OE causes incompatibility with microwatt
644 # http://lists.libre-soc.org/pipermail/libre-soc-dev/2020-August/000302.html
645 with m
.Case(MicrOp
.OP_MUL_H64
, MicrOp
.OP_MUL_H32
,
646 MicrOp
.OP_EXTS
, MicrOp
.OP_CNTZ
,
647 MicrOp
.OP_SHL
, MicrOp
.OP_SHR
, MicrOp
.OP_RLC
,
648 MicrOp
.OP_LOAD
, MicrOp
.OP_STORE
,
649 MicrOp
.OP_RLCL
, MicrOp
.OP_RLCR
,
653 # all other ops decode OE field
655 # select OE bit out field
656 with m
.Switch(self
.sel_in
):
658 comb
+= self
.oe_out
.data
.eq(self
.dec
.OE
)
659 comb
+= self
.oe_out
.ok
.eq(1)
664 class DecodeCRIn(Elaboratable
):
665 """Decodes input CR from instruction
667 CR indices - insn fields - (not the data *in* the CR) require only 3
668 bits because they refer to CR0-CR7
671 def __init__(self
, dec
):
673 self
.sv_rm
= SVP64Rec() # SVP64 RM field
674 self
.sel_in
= Signal(CRInSel
, reset_less
=True)
675 self
.insn_in
= Signal(32, reset_less
=True)
676 self
.cr_bitfield
= Data(3, "cr_bitfield")
677 self
.cr_bitfield_b
= Data(3, "cr_bitfield_b")
678 self
.cr_bitfield_o
= Data(3, "cr_bitfield_o")
679 self
.whole_reg
= Data(8, "cr_fxm")
681 def elaborate(self
, platform
):
683 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
689 comb
+= self
.cr_bitfield
.ok
.eq(0)
690 comb
+= self
.cr_bitfield_b
.ok
.eq(0)
691 comb
+= self
.cr_bitfield_o
.ok
.eq(0)
692 comb
+= self
.whole_reg
.ok
.eq(0)
694 with m
.Switch(self
.sel_in
):
695 with m
.Case(CRInSel
.NONE
):
696 pass # No bitfield activated
697 with m
.Case(CRInSel
.CR0
):
698 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
699 comb
+= self
.cr_bitfield
.ok
.eq(1)
700 with m
.Case(CRInSel
.BI
):
701 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BI
[2:5])
702 comb
+= self
.cr_bitfield
.ok
.eq(1)
703 with m
.Case(CRInSel
.BFA
):
704 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BFA
)
705 comb
+= self
.cr_bitfield
.ok
.eq(1)
706 with m
.Case(CRInSel
.BA_BB
):
707 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BA
[2:5])
708 comb
+= self
.cr_bitfield
.ok
.eq(1)
709 comb
+= self
.cr_bitfield_b
.data
.eq(self
.dec
.BB
[2:5])
710 comb
+= self
.cr_bitfield_b
.ok
.eq(1)
711 comb
+= self
.cr_bitfield_o
.data
.eq(self
.dec
.BT
[2:5])
712 comb
+= self
.cr_bitfield_o
.ok
.eq(1)
713 with m
.Case(CRInSel
.BC
):
714 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BC
[2:5])
715 comb
+= self
.cr_bitfield
.ok
.eq(1)
716 with m
.Case(CRInSel
.WHOLE_REG
):
717 comb
+= self
.whole_reg
.ok
.eq(1)
718 move_one
= Signal(reset_less
=True)
719 comb
+= move_one
.eq(self
.insn_in
[20]) # MSB0 bit 11
720 with m
.If((op
.internal_op
== MicrOp
.OP_MFCR
) & move_one
):
721 # must one-hot the FXM field
722 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
723 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
725 # otherwise use all of it
726 comb
+= self
.whole_reg
.data
.eq(0xff)
731 class DecodeCROut(Elaboratable
):
732 """Decodes input CR from instruction
734 CR indices - insn fields - (not the data *in* the CR) require only 3
735 bits because they refer to CR0-CR7
738 def __init__(self
, dec
):
740 self
.sv_rm
= SVP64Rec() # SVP64 RM field
741 self
.rc_in
= Signal(reset_less
=True)
742 self
.sel_in
= Signal(CROutSel
, reset_less
=True)
743 self
.insn_in
= Signal(32, reset_less
=True)
744 self
.cr_bitfield
= Data(3, "cr_bitfield")
745 self
.whole_reg
= Data(8, "cr_fxm")
747 def elaborate(self
, platform
):
751 m
.submodules
.ppick
= ppick
= PriorityPicker(8, reverse_i
=True,
754 comb
+= self
.cr_bitfield
.ok
.eq(0)
755 comb
+= self
.whole_reg
.ok
.eq(0)
756 with m
.Switch(self
.sel_in
):
757 with m
.Case(CROutSel
.NONE
):
758 pass # No bitfield activated
759 with m
.Case(CROutSel
.CR0
):
760 comb
+= self
.cr_bitfield
.data
.eq(0) # CR0 (MSB0 numbering)
761 comb
+= self
.cr_bitfield
.ok
.eq(self
.rc_in
) # only when RC=1
762 with m
.Case(CROutSel
.BF
):
763 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BF
)
764 comb
+= self
.cr_bitfield
.ok
.eq(1)
765 with m
.Case(CROutSel
.BT
):
766 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormXL
.BT
[2:5])
767 comb
+= self
.cr_bitfield
.ok
.eq(1)
768 with m
.Case(CROutSel
.WHOLE_REG
):
769 comb
+= self
.whole_reg
.ok
.eq(1)
770 move_one
= Signal(reset_less
=True)
771 comb
+= move_one
.eq(self
.insn_in
[20])
772 with m
.If((op
.internal_op
== MicrOp
.OP_MTCRF
)):
774 # must one-hot the FXM field
775 comb
+= ppick
.i
.eq(self
.dec
.FXM
)
776 with m
.If(ppick
.en_o
):
777 comb
+= self
.whole_reg
.data
.eq(ppick
.o
)
779 comb
+= self
.whole_reg
.data
.eq(0b00000001) # CR7
781 comb
+= self
.whole_reg
.data
.eq(self
.dec
.FXM
)
783 # otherwise use all of it
784 comb
+= self
.whole_reg
.data
.eq(0xff)
788 # dictionary of Input Record field names that, if they exist,
789 # will need a corresponding CSV Decoder file column (actually, PowerOp)
790 # to be decoded (this includes the single bit names)
791 record_names
= {'insn_type': 'internal_op',
792 'fn_unit': 'function_unit',
796 'imm_data': 'in2_sel',
797 'invert_in': 'inv_a',
798 'invert_out': 'inv_out',
801 'output_carry': 'cry_out',
802 'input_carry': 'cry_in',
803 'is_32bit': 'is_32b',
806 'data_len': 'ldst_len',
807 'byte_reverse': 'br',
808 'sign_extend': 'sgn_ext',
813 class PowerDecodeSubset(Elaboratable
):
814 """PowerDecodeSubset: dynamic subset decoder
816 only fields actually requested are copied over. hence, "subset" (duh).
818 def __init__(self
, dec
, opkls
=None, fn_name
=None, final
=False, state
=None):
820 self
.sv_rm
= SVP64Rec(name
="dec_svp64") # SVP64 RM field
823 self
.fn_name
= fn_name
825 opkls
= Decode2ToOperand
826 self
.do
= opkls(fn_name
)
827 col_subset
= self
.get_col_subset(self
.do
)
829 # only needed for "main" PowerDecode2
831 self
.e
= Decode2ToExecute1Type(name
=self
.fn_name
, do
=self
.do
)
833 # create decoder if one not already given
835 dec
= create_pdecode(name
=fn_name
, col_subset
=col_subset
,
836 row_subset
=self
.rowsubsetfn
)
839 # state information needed by the Decoder
841 state
= CoreState("dec2")
844 def get_col_subset(self
, do
):
845 subset
= {'cr_in', 'cr_out', 'rc_sel'} # needed, non-optional
846 for k
, v
in record_names
.items():
849 print ("get_col_subset", self
.fn_name
, do
.fields
, subset
)
852 def rowsubsetfn(self
, opcode
, row
):
853 return row
['unit'] == self
.fn_name
856 return self
.dec
.ports() + self
.e
.ports() + self
.sv_rm
.ports()
858 def needs_field(self
, field
, op_field
):
863 return hasattr(do
, field
) and self
.op_get(op_field
) is not None
865 def do_copy(self
, field
, val
, final
=False):
866 if final
or self
.final
:
870 if hasattr(do
, field
) and val
is not None:
871 return getattr(do
, field
).eq(val
)
874 def op_get(self
, op_field
):
875 return getattr(self
.dec
.op
, op_field
, None)
877 def elaborate(self
, platform
):
881 op
, do
= self
.dec
.op
, self
.do
882 msr
, cia
= state
.msr
, state
.pc
884 # fill in for a normal instruction (not an exception)
885 # copy over if non-exception, non-privileged etc. is detected
887 if self
.fn_name
is None:
890 name
= self
.fn_name
+ "tmp"
891 self
.e_tmp
= Decode2ToExecute1Type(name
=name
, opkls
=self
.opkls
)
893 # set up submodule decoders
894 m
.submodules
.dec
= self
.dec
895 m
.submodules
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
896 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
)
897 m
.submodules
.dec_cr_in
= self
.dec_cr_in
= DecodeCRIn(self
.dec
)
898 m
.submodules
.dec_cr_out
= self
.dec_cr_out
= DecodeCROut(self
.dec
)
900 # copy instruction through...
902 dec_rc
.insn_in
, dec_oe
.insn_in
,
903 self
.dec_cr_in
.insn_in
, self
.dec_cr_out
.insn_in
]:
904 comb
+= i
.eq(self
.dec
.opcode_in
)
906 # ...and subdecoders' input fields
907 comb
+= dec_rc
.sel_in
.eq(op
.rc_sel
)
908 comb
+= dec_oe
.sel_in
.eq(op
.rc_sel
) # XXX should be OE sel
909 comb
+= self
.dec_cr_in
.sel_in
.eq(op
.cr_in
)
910 comb
+= self
.dec_cr_in
.sv_rm
.eq(self
.sv_rm
)
911 comb
+= self
.dec_cr_out
.sv_rm
.eq(self
.sv_rm
)
912 comb
+= self
.dec_cr_out
.sel_in
.eq(op
.cr_out
)
913 comb
+= self
.dec_cr_out
.rc_in
.eq(dec_rc
.rc_out
.data
)
916 comb
+= self
.do_copy("msr", msr
)
917 comb
+= self
.do_copy("cia", cia
)
919 # set up instruction type
920 # no op: defaults to OP_ILLEGAL
921 comb
+= self
.do_copy("insn_type", self
.op_get("internal_op"))
923 # function unit for decoded instruction: requires minor redirect
925 fn
= self
.op_get("function_unit")
926 spr
= Signal(10, reset_less
=True)
927 comb
+= spr
.eq(decode_spr_num(self
.dec
.SPR
)) # from XFX
929 # for first test only forward SPRs 18 and 19 to MMU, when
930 # operation is MTSPR or MFSPR. TODO: add other MMU SPRs
931 with m
.If(((self
.dec
.op
.internal_op
== MicrOp
.OP_MTSPR
) |
932 (self
.dec
.op
.internal_op
== MicrOp
.OP_MFSPR
)) &
933 ((spr
== SPR
.DSISR
) |
(spr
== SPR
.DAR
))):
934 comb
+= self
.do_copy("fn_unit", Function
.MMU
)
936 comb
+= self
.do_copy("fn_unit",fn
)
939 if self
.needs_field("zero_a", "in1_sel"):
940 m
.submodules
.dec_ai
= dec_ai
= DecodeAImm(self
.dec
)
941 comb
+= dec_ai
.sel_in
.eq(op
.in1_sel
)
942 comb
+= self
.do_copy("zero_a", dec_ai
.immz_out
) # RA==0 detected
943 if self
.needs_field("imm_data", "in2_sel"):
944 m
.submodules
.dec_bi
= dec_bi
= DecodeBImm(self
.dec
)
945 comb
+= dec_bi
.sel_in
.eq(op
.in2_sel
)
946 comb
+= self
.do_copy("imm_data", dec_bi
.imm_out
) # imm in RB
949 comb
+= self
.do_copy("rc", dec_rc
.rc_out
)
950 comb
+= self
.do_copy("oe", dec_oe
.oe_out
)
953 comb
+= self
.do_copy("read_cr_whole", self
.dec_cr_in
.whole_reg
)
954 comb
+= self
.do_copy("write_cr_whole", self
.dec_cr_out
.whole_reg
)
955 comb
+= self
.do_copy("write_cr0", self
.dec_cr_out
.cr_bitfield
.ok
)
957 comb
+= self
.do_copy("input_cr", self
.op_get("cr_in")) # CR in
958 comb
+= self
.do_copy("output_cr", self
.op_get("cr_out")) # CR out
960 # decoded/selected instruction flags
961 comb
+= self
.do_copy("data_len", self
.op_get("ldst_len"))
962 comb
+= self
.do_copy("invert_in", self
.op_get("inv_a"))
963 comb
+= self
.do_copy("invert_out", self
.op_get("inv_out"))
964 comb
+= self
.do_copy("input_carry", self
.op_get("cry_in"))
965 comb
+= self
.do_copy("output_carry", self
.op_get("cry_out"))
966 comb
+= self
.do_copy("is_32bit", self
.op_get("is_32b"))
967 comb
+= self
.do_copy("is_signed", self
.op_get("sgn"))
968 lk
= self
.op_get("lk")
971 comb
+= self
.do_copy("lk", self
.dec
.LK
) # XXX TODO: accessor
973 comb
+= self
.do_copy("byte_reverse", self
.op_get("br"))
974 comb
+= self
.do_copy("sign_extend", self
.op_get("sgn_ext"))
975 comb
+= self
.do_copy("ldst_mode", self
.op_get("upd")) # LD/ST mode
980 class PowerDecode2(PowerDecodeSubset
):
981 """PowerDecode2: the main instruction decoder.
983 whilst PowerDecode is responsible for decoding the actual opcode, this
984 module encapsulates further specialist, sparse information and
985 expansion of fields that is inconvenient to have in the CSV files.
986 for example: the encoding of the immediates, which are detected
987 and expanded out to their full value from an annotated (enum)
990 implicit register usage is also set up, here. for example: OP_BC
991 requires implicitly reading CTR, OP_RFID requires implicitly writing
994 in addition, PowerDecoder2 is responsible for detecting whether
995 instructions are illegal (or privileged) or not, and instead of
996 just leaving at that, *replacing* the instruction to execute with
997 a suitable alternative (trap).
999 LDSTExceptions are done the cycle _after_ they're detected (after
1000 they come out of LDSTCompUnit). basically despite the instruction
1001 being decoded, the results of the decode are completely ignored
1002 and "exception.happened" used to set the "actual" instruction to
1003 "OP_TRAP". the LDSTException data structure gets filled in,
1004 in the CompTrapOpSubset and that's what it fills in SRR.
1006 to make this work, TestIssuer must notice "exception.happened"
1007 after the (failed) LD/ST and copies the LDSTException info from
1008 the output, into here (PowerDecoder2). without incrementing PC.
1011 def __init__(self
, dec
, opkls
=None, fn_name
=None, final
=False, state
=None):
1012 super().__init
__(dec
, opkls
, fn_name
, final
, state
)
1013 self
.exc
= LDSTException("dec2_exc")
1015 def get_col_subset(self
, opkls
):
1016 subset
= super().get_col_subset(opkls
)
1017 subset
.add("asmcode")
1018 subset
.add("in1_sel")
1019 subset
.add("in2_sel")
1020 subset
.add("in3_sel")
1021 subset
.add("out_sel")
1022 subset
.add("sv_in1")
1023 subset
.add("sv_in2")
1024 subset
.add("sv_in3")
1025 subset
.add("sv_out")
1026 subset
.add("SV_Etype")
1027 subset
.add("SV_Ptype")
1029 subset
.add("internal_op")
1033 def elaborate(self
, platform
):
1034 m
= super().elaborate(platform
)
1037 e_out
, op
, do_out
= self
.e
, self
.dec
.op
, self
.e
.do
1038 dec_spr
, msr
, cia
, ext_irq
= state
.dec
, state
.msr
, state
.pc
, state
.eint
1042 # fill in for a normal instruction (not an exception)
1043 # copy over if non-exception, non-privileged etc. is detected
1045 # set up submodule decoders
1046 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
)
1047 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
)
1048 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
)
1049 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
)
1050 m
.submodules
.dec_o2
= dec_o2
= DecodeOut2(self
.dec
)
1052 # copy instruction through...
1053 for i
in [do
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
1054 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
]:
1055 comb
+= i
.eq(self
.dec
.opcode_in
)
1058 for i
in [dec_a
.insn_in
, dec_b
.insn_in
,
1059 dec_c
.insn_in
, dec_o
.insn_in
, dec_o2
.insn_in
]:
1060 comb
+= i
.eq(self
.sv_rm
)
1062 # ...and subdecoders' input fields
1063 comb
+= dec_a
.sel_in
.eq(op
.in1_sel
)
1064 comb
+= dec_b
.sel_in
.eq(op
.in2_sel
)
1065 comb
+= dec_c
.sel_in
.eq(op
.in3_sel
)
1066 comb
+= dec_o
.sel_in
.eq(op
.out_sel
)
1067 comb
+= dec_o2
.sel_in
.eq(op
.out_sel
)
1068 if hasattr(do
, "lk"):
1069 comb
+= dec_o2
.lk
.eq(do
.lk
)
1071 # registers a, b, c and out and out2 (LD/ST EA)
1072 for to_reg
, fromreg
in (
1073 (e
.read_reg1
, dec_a
.reg_out
),
1074 (e
.read_reg2
, dec_b
.reg_out
),
1075 (e
.read_reg3
, dec_c
.reg_out
),
1076 (e
.write_reg
, dec_o
.reg_out
),
1077 (e
.write_ea
, dec_o2
.reg_out
)):
1078 comb
+= to_reg
.data
.eq(fromreg
.data
)
1079 comb
+= to_reg
.ok
.eq(fromreg
.ok
)
1082 comb
+= e
.read_spr1
.eq(dec_a
.spr_out
)
1083 comb
+= e
.write_spr
.eq(dec_o
.spr_out
)
1086 comb
+= e
.read_fast1
.eq(dec_a
.fast_out
)
1087 comb
+= e
.read_fast2
.eq(dec_b
.fast_out
)
1088 comb
+= e
.write_fast1
.eq(dec_o
.fast_out
)
1089 comb
+= e
.write_fast2
.eq(dec_o2
.fast_out
)
1091 # condition registers (CR)
1092 comb
+= e
.read_cr1
.eq(self
.dec_cr_in
.cr_bitfield
)
1093 comb
+= e
.read_cr2
.eq(self
.dec_cr_in
.cr_bitfield_b
)
1094 comb
+= e
.read_cr3
.eq(self
.dec_cr_in
.cr_bitfield_o
)
1095 comb
+= e
.write_cr
.eq(self
.dec_cr_out
.cr_bitfield
)
1097 # sigh this is exactly the sort of thing for which the
1098 # decoder is designed to not need. MTSPR, MFSPR and others need
1099 # access to the XER bits. however setting e.oe is not appropriate
1100 with m
.If(op
.internal_op
== MicrOp
.OP_MFSPR
):
1101 comb
+= e
.xer_in
.eq(0b111) # SO, CA, OV
1102 with m
.If(op
.internal_op
== MicrOp
.OP_CMP
):
1103 comb
+= e
.xer_in
.eq(1<<XERRegs
.SO
) # SO
1104 with m
.If(op
.internal_op
== MicrOp
.OP_MTSPR
):
1105 comb
+= e
.xer_out
.eq(1)
1107 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
1108 with m
.If(op
.internal_op
== MicrOp
.OP_TRAP
):
1109 # *DO NOT* call self.trap here. that would reset absolutely
1110 # everything including destroying read of RA and RB.
1111 comb
+= self
.do_copy("trapaddr", 0x70) # strip first nibble
1113 ####################
1114 # ok so the instruction's been decoded, blah blah, however
1115 # now we need to determine if it's actually going to go ahead...
1116 # *or* if in fact it's a privileged operation, whether there's
1117 # an external interrupt, etc. etc. this is a simple priority
1118 # if-elif-elif sequence. decrement takes highest priority,
1119 # EINT next highest, privileged operation third.
1121 # check if instruction is privileged
1122 is_priv_insn
= instr_is_priv(m
, op
.internal_op
, e
.do
.insn
)
1124 # different IRQ conditions
1125 ext_irq_ok
= Signal()
1126 dec_irq_ok
= Signal()
1131 comb
+= ext_irq_ok
.eq(ext_irq
& msr
[MSR
.EE
]) # v3.0B p944 (MSR.EE)
1132 comb
+= dec_irq_ok
.eq(dec_spr
[63] & msr
[MSR
.EE
]) # 6.5.11 p1076
1133 comb
+= priv_ok
.eq(is_priv_insn
& msr
[MSR
.PR
])
1134 comb
+= illeg_ok
.eq(op
.internal_op
== MicrOp
.OP_ILLEGAL
)
1136 # LD/ST exceptions. TestIssuer copies the exception info at us
1137 # after a failed LD/ST.
1138 with m
.If(exc
.happened
):
1139 with m
.If(exc
.alignment
):
1140 self
.trap(m
, TT
.PRIV
, 0x600)
1141 with m
.Elif(exc
.instr_fault
):
1142 with m
.If(exc
.segment_fault
):
1143 self
.trap(m
, TT
.PRIV
, 0x480)
1145 # pass exception info to trap to create SRR1
1146 self
.trap(m
, TT
.MEMEXC
, 0x400, exc
)
1148 with m
.If(exc
.segment_fault
):
1149 self
.trap(m
, TT
.PRIV
, 0x380)
1151 self
.trap(m
, TT
.PRIV
, 0x300)
1153 # decrement counter (v3.0B p1099): TODO 32-bit version (MSR.LPCR)
1154 with m
.Elif(dec_irq_ok
):
1155 self
.trap(m
, TT
.DEC
, 0x900) # v3.0B 6.5 p1065
1157 # external interrupt? only if MSR.EE set
1158 with m
.Elif(ext_irq_ok
):
1159 self
.trap(m
, TT
.EINT
, 0x500)
1161 # privileged instruction trap
1162 with m
.Elif(priv_ok
):
1163 self
.trap(m
, TT
.PRIV
, 0x700)
1165 # illegal instruction must redirect to trap. this is done by
1166 # *overwriting* the decoded instruction and starting again.
1167 # (note: the same goes for interrupts and for privileged operations,
1168 # just with different trapaddr and traptype)
1169 with m
.Elif(illeg_ok
):
1170 # illegal instruction trap
1171 self
.trap(m
, TT
.ILLEG
, 0x700)
1173 # no exception, just copy things to the output
1177 ####################
1178 # follow-up after trap/irq to set up SRR0/1
1180 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
1181 # Note: OP_SC could actually be modified to just be a trap
1182 with m
.If((do_out
.insn_type
== MicrOp
.OP_TRAP
) |
1183 (do_out
.insn_type
== MicrOp
.OP_SC
)):
1184 # TRAP write fast1 = SRR0
1185 comb
+= e_out
.write_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
1186 comb
+= e_out
.write_fast1
.ok
.eq(1)
1187 # TRAP write fast2 = SRR1
1188 comb
+= e_out
.write_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
1189 comb
+= e_out
.write_fast2
.ok
.eq(1)
1191 # RFID: needs to read SRR0/1
1192 with m
.If(do_out
.insn_type
== MicrOp
.OP_RFID
):
1193 # TRAP read fast1 = SRR0
1194 comb
+= e_out
.read_fast1
.data
.eq(FastRegs
.SRR0
) # constant: SRR0
1195 comb
+= e_out
.read_fast1
.ok
.eq(1)
1196 # TRAP read fast2 = SRR1
1197 comb
+= e_out
.read_fast2
.data
.eq(FastRegs
.SRR1
) # constant: SRR1
1198 comb
+= e_out
.read_fast2
.ok
.eq(1)
1200 # annoying simulator bug
1201 if hasattr(e_out
, "asmcode") and hasattr(self
.dec
.op
, "asmcode"):
1202 comb
+= e_out
.asmcode
.eq(self
.dec
.op
.asmcode
)
1206 def trap(self
, m
, traptype
, trapaddr
, exc
=None):
1207 """trap: this basically "rewrites" the decoded instruction as a trap
1210 op
, e
= self
.dec
.op
, self
.e
1211 comb
+= e
.eq(0) # reset eeeeeverything
1214 comb
+= self
.do_copy("insn", self
.dec
.opcode_in
, True)
1215 comb
+= self
.do_copy("insn_type", MicrOp
.OP_TRAP
, True)
1216 comb
+= self
.do_copy("fn_unit", Function
.TRAP
, True)
1217 comb
+= self
.do_copy("trapaddr", trapaddr
>> 4, True) # bottom 4 bits
1218 comb
+= self
.do_copy("traptype", traptype
, True) # request type
1219 comb
+= self
.do_copy("ldst_exc", exc
, True) # request type
1220 comb
+= self
.do_copy("msr", self
.state
.msr
, True) # copy of MSR "state"
1221 comb
+= self
.do_copy("cia", self
.state
.pc
, True) # copy of PC "state"
1224 def get_rdflags(e
, cu
):
1226 for idx
in range(cu
.n_src
):
1227 regfile
, regname
, _
= cu
.get_in_spec(idx
)
1228 rdflag
, read
= regspec_decode_read(e
, regfile
, regname
)
1230 print("rdflags", rdl
)
1234 if __name__
== '__main__':
1235 pdecode
= create_pdecode()
1236 dec2
= PowerDecode2(pdecode
)
1237 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
1238 with
open("dec2.il", "w") as f
: