add RT as an option for ternary instruction as 3rd register input
[openpower-isa.git] / src / openpower / decoder / power_decoder2.py
1 """Power ISA Decoder second stage
2
3 based on Anton Blanchard microwatt decode2.vhdl
4
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.
7 """
8
9 from nmigen import Module, Elaboratable, Signal, Mux, Const, Cat, Repl, Record
10 from nmigen.cli import rtlil
11 from nmutil.util import sel
12
13 from nmutil.picker import PriorityPicker
14 from nmutil.iocontrol import RecordObject
15 from nmutil.extend import exts
16
17 from openpower.exceptions import LDSTException
18
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,
23 SVP64RMMode)
24 from openpower.sv.svp64 import SVP64Rec
25
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,
29 PowerOp)
30 from openpower.decoder.power_enums import (MicrOp, CryIn, Function,
31 CRInSel, CROutSel,
32 LdstLen, In1Sel, In2Sel, In3Sel,
33 OutSel, SPRfull, SPRreduced,
34 RC, SVP64LDSTmode, LDSTMode,
35 SVEXTRA, SVEtype, SVPtype)
36 from openpower.decoder.decode2execute1 import (Decode2ToExecute1Type, Data,
37 Decode2ToOperand)
38
39 from openpower.consts import (MSR, SPEC, EXTRA2, EXTRA3, SVP64P, field,
40 SPEC_SIZE, SPECb, SPEC_AUG_SIZE, SVP64CROffs,
41 FastRegsEnum, XERRegsEnum, TT)
42
43 from openpower.state import CoreState
44 from openpower.util import (spr_to_fast, log)
45
46
47 def decode_spr_num(spr):
48 return Cat(spr[5:10], spr[0:5])
49
50
51 def instr_is_priv(m, op, insn):
52 """determines if the instruction is privileged or not
53 """
54 comb = m.d.comb
55 is_priv_insn = Signal(reset_less=True)
56 with m.Switch(op):
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) : comb += is_priv_insn.eq(1)
61 with m.Case(MicrOp.OP_MFSPR, MicrOp.OP_MTSPR):
62 with m.If(insn[20]): # field XFX.spr[-1] i think
63 comb += is_priv_insn.eq(1)
64 return is_priv_insn
65
66
67 class SPRMap(Elaboratable):
68 """SPRMap: maps POWER9 SPR numbers to internal enum values, fast and slow
69 """
70
71 def __init__(self, regreduce_en):
72 self.regreduce_en = regreduce_en
73 if regreduce_en:
74 SPR = SPRreduced
75 else:
76 SPR = SPRfull
77
78 self.spr_i = Signal(10, reset_less=True)
79 self.spr_o = Data(SPR, name="spr_o")
80 self.fast_o = Data(3, name="fast_o")
81
82 def elaborate(self, platform):
83 m = Module()
84 if self.regreduce_en:
85 SPR = SPRreduced
86 else:
87 SPR = SPRfull
88 with m.Switch(self.spr_i):
89 for i, x in enumerate(SPR):
90 with m.Case(x.value):
91 m.d.comb += self.spr_o.data.eq(i)
92 m.d.comb += self.spr_o.ok.eq(1)
93 for x, v in spr_to_fast.items():
94 with m.Case(x.value):
95 m.d.comb += self.fast_o.data.eq(v)
96 m.d.comb += self.fast_o.ok.eq(1)
97 return m
98
99
100 class DecodeA(Elaboratable):
101 """DecodeA from instruction
102
103 decodes register RA, implicit and explicit CSRs
104 """
105
106 def __init__(self, dec, op, regreduce_en):
107 self.regreduce_en = regreduce_en
108 if self.regreduce_en:
109 SPR = SPRreduced
110 else:
111 SPR = SPRfull
112 self.dec = dec
113 self.op = op
114 self.sel_in = Signal(In1Sel, reset_less=True)
115 self.insn_in = Signal(32, reset_less=True)
116 self.reg_out = Data(5, name="reg_a")
117 self.spr_out = Data(SPR, "spr_a")
118 self.fast_out = Data(3, "fast_a")
119 self.sv_nz = Signal(1)
120
121 def elaborate(self, platform):
122 m = Module()
123 comb = m.d.comb
124 op = self.op
125 reg = self.reg_out
126 m.submodules.sprmap = sprmap = SPRMap(self.regreduce_en)
127
128 # select Register A field, if *full 7 bits* are zero (2 more from SVP64)
129 ra = Signal(5, reset_less=True)
130 comb += ra.eq(self.dec.RA)
131 with m.If((self.sel_in == In1Sel.RA) |
132 ((self.sel_in == In1Sel.RA_OR_ZERO) &
133 ((ra != Const(0, 5)) | (self.sv_nz != Const(0, 1))))):
134 comb += reg.data.eq(ra)
135 comb += reg.ok.eq(1)
136
137 # some Logic/ALU ops have RS as the 3rd arg, but no "RA".
138 # moved it to 1st position (in1_sel)... because
139 rs = Signal(5, reset_less=True)
140 comb += rs.eq(self.dec.RS)
141 with m.If(self.sel_in == In1Sel.RS):
142 comb += reg.data.eq(rs)
143 comb += reg.ok.eq(1)
144
145 # select Register FRA field,
146 fra = Signal(5, reset_less=True)
147 comb += fra.eq(self.dec.FRA)
148 with m.If(self.sel_in == In1Sel.FRA):
149 comb += reg.data.eq(fra)
150 comb += reg.ok.eq(1)
151
152 # select Register FRS field,
153 frs = Signal(5, reset_less=True)
154 comb += frs.eq(self.dec.FRS)
155 with m.If(self.sel_in == In1Sel.FRS):
156 comb += reg.data.eq(frs)
157 comb += reg.ok.eq(1)
158
159 # decode Fast-SPR based on instruction type
160 with m.Switch(op.internal_op):
161
162 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeOut
163 with m.Case(MicrOp.OP_BC):
164 with m.If(~self.dec.BO[2]): # 3.0B p38 BO2=0, use CTR reg
165 # constant: CTR
166 comb += self.fast_out.data.eq(FastRegsEnum.CTR)
167 comb += self.fast_out.ok.eq(1)
168 with m.Case(MicrOp.OP_BCREG):
169 xo9 = self.dec.FormXL.XO[9] # 3.0B p38 top bit of XO
170 xo5 = self.dec.FormXL.XO[5] # 3.0B p38
171 with m.If(xo9 & ~xo5):
172 # constant: CTR
173 comb += self.fast_out.data.eq(FastRegsEnum.CTR)
174 comb += self.fast_out.ok.eq(1)
175
176 # MFSPR move from SPRs
177 with m.Case(MicrOp.OP_MFSPR):
178 spr = Signal(10, reset_less=True)
179 comb += spr.eq(decode_spr_num(self.dec.SPR)) # from XFX
180 comb += sprmap.spr_i.eq(spr)
181 comb += self.spr_out.eq(sprmap.spr_o)
182 comb += self.fast_out.eq(sprmap.fast_o)
183
184 return m
185
186
187 class DecodeAImm(Elaboratable):
188 """DecodeA immediate from instruction
189
190 decodes register RA, whether immediate-zero, implicit and
191 explicit CSRs. SVP64 mode requires 2 extra bits
192 """
193
194 def __init__(self, dec):
195 self.dec = dec
196 self.sel_in = Signal(In1Sel, reset_less=True)
197 self.immz_out = Signal(reset_less=True)
198 self.sv_nz = Signal(1) # EXTRA bits from SVP64
199
200 def elaborate(self, platform):
201 m = Module()
202 comb = m.d.comb
203
204 # zero immediate requested
205 ra = Signal(5, reset_less=True)
206 comb += ra.eq(self.dec.RA)
207 with m.If((self.sel_in == In1Sel.RA_OR_ZERO) &
208 (ra == Const(0, 5)) &
209 (self.sv_nz == Const(0, 1))):
210 comb += self.immz_out.eq(1)
211
212 return m
213
214
215 class DecodeB(Elaboratable):
216 """DecodeB from instruction
217
218 decodes register RB, different forms of immediate (signed, unsigned),
219 and implicit SPRs. register B is basically "lane 2" into the CompUnits.
220 by industry-standard convention, "lane 2" is where fully-decoded
221 immediates are muxed in.
222 """
223
224 def __init__(self, dec, op):
225 self.dec = dec
226 self.op = op
227 self.sel_in = Signal(In2Sel, reset_less=True)
228 self.insn_in = Signal(32, reset_less=True)
229 self.reg_out = Data(7, "reg_b")
230 self.reg_isvec = Signal(1, name="reg_b_isvec") # TODO: in reg_out
231 self.fast_out = Data(3, "fast_b")
232
233 def elaborate(self, platform):
234 m = Module()
235 comb = m.d.comb
236 op = self.op
237 reg = self.reg_out
238
239 # select Register B field
240 with m.Switch(self.sel_in):
241 with m.Case(In2Sel.FRB):
242 comb += reg.data.eq(self.dec.FRB)
243 comb += reg.ok.eq(1)
244 with m.Case(In2Sel.RB):
245 comb += reg.data.eq(self.dec.RB)
246 comb += reg.ok.eq(1)
247 with m.Case(In2Sel.RS):
248 # for M-Form shiftrot
249 comb += reg.data.eq(self.dec.RS)
250 comb += reg.ok.eq(1)
251
252 # decode SPR2 based on instruction type
253 # BCREG implicitly uses LR or TAR for 2nd reg
254 # CTR however is already in fast_spr1 *not* 2.
255 with m.If(op.internal_op == MicrOp.OP_BCREG):
256 xo9 = self.dec.FormXL.XO[9] # 3.0B p38 top bit of XO
257 xo5 = self.dec.FormXL.XO[5] # 3.0B p38
258 with m.If(~xo9):
259 comb += self.fast_out.data.eq(FastRegsEnum.LR)
260 comb += self.fast_out.ok.eq(1)
261 with m.Elif(xo5):
262 comb += self.fast_out.data.eq(FastRegsEnum.TAR)
263 comb += self.fast_out.ok.eq(1)
264
265 return m
266
267
268 class DecodeBImm(Elaboratable):
269 """DecodeB immediate from instruction
270 """
271 def __init__(self, dec):
272 self.dec = dec
273 self.sel_in = Signal(In2Sel, reset_less=True)
274 self.imm_out = Data(64, "imm_b")
275
276 def elaborate(self, platform):
277 m = Module()
278 comb = m.d.comb
279
280 # select Register B Immediate
281 with m.Switch(self.sel_in):
282 with m.Case(In2Sel.CONST_UI): # unsigned
283 comb += self.imm_out.data.eq(self.dec.UI)
284 comb += self.imm_out.ok.eq(1)
285 with m.Case(In2Sel.CONST_SI): # sign-extended 16-bit
286 si = Signal(16, reset_less=True)
287 comb += si.eq(self.dec.SI)
288 comb += self.imm_out.data.eq(exts(si, 16, 64))
289 comb += self.imm_out.ok.eq(1)
290 with m.Case(In2Sel.CONST_SI_HI): # sign-extended 16+16=32 bit
291 si_hi = Signal(32, reset_less=True)
292 comb += si_hi.eq(self.dec.SI << 16)
293 comb += self.imm_out.data.eq(exts(si_hi, 32, 64))
294 comb += self.imm_out.ok.eq(1)
295 with m.Case(In2Sel.CONST_UI_HI): # unsigned
296 ui = Signal(16, reset_less=True)
297 comb += ui.eq(self.dec.UI)
298 comb += self.imm_out.data.eq(ui << 16)
299 comb += self.imm_out.ok.eq(1)
300 with m.Case(In2Sel.CONST_LI): # sign-extend 24+2=26 bit
301 li = Signal(26, reset_less=True)
302 comb += li.eq(self.dec.LI << 2)
303 comb += self.imm_out.data.eq(exts(li, 26, 64))
304 comb += self.imm_out.ok.eq(1)
305 with m.Case(In2Sel.CONST_BD): # sign-extend (14+2)=16 bit
306 bd = Signal(16, reset_less=True)
307 comb += bd.eq(self.dec.BD << 2)
308 comb += self.imm_out.data.eq(exts(bd, 16, 64))
309 comb += self.imm_out.ok.eq(1)
310 with m.Case(In2Sel.CONST_DS): # sign-extended (14+2=16) bit
311 ds = Signal(16, reset_less=True)
312 comb += ds.eq(self.dec.DS << 2)
313 comb += self.imm_out.data.eq(exts(ds, 16, 64))
314 comb += self.imm_out.ok.eq(1)
315 with m.Case(In2Sel.CONST_M1): # signed (-1)
316 comb += self.imm_out.data.eq(~Const(0, 64)) # all 1s
317 comb += self.imm_out.ok.eq(1)
318 with m.Case(In2Sel.CONST_SH): # unsigned - for shift
319 comb += self.imm_out.data.eq(self.dec.sh)
320 comb += self.imm_out.ok.eq(1)
321 with m.Case(In2Sel.CONST_SH32): # unsigned - for shift
322 comb += self.imm_out.data.eq(self.dec.SH32)
323 comb += self.imm_out.ok.eq(1)
324
325 return m
326
327
328 class DecodeC(Elaboratable):
329 """DecodeC from instruction
330
331 decodes register RC. this is "lane 3" into some CompUnits (not many)
332 """
333
334 def __init__(self, dec, op):
335 self.dec = dec
336 self.op = op
337 self.sel_in = Signal(In3Sel, reset_less=True)
338 self.insn_in = Signal(32, reset_less=True)
339 self.reg_out = Data(5, "reg_c")
340
341 def elaborate(self, platform):
342 m = Module()
343 comb = m.d.comb
344 op = self.op
345 reg = self.reg_out
346
347 # select Register C field
348 with m.Switch(self.sel_in):
349 with m.Case(In3Sel.RB):
350 # for M-Form shiftrot
351 comb += reg.data.eq(self.dec.RB)
352 comb += reg.ok.eq(1)
353 with m.Case(In3Sel.FRS):
354 comb += reg.data.eq(self.dec.FRS)
355 comb += reg.ok.eq(1)
356 with m.Case(In3Sel.FRC):
357 comb += reg.data.eq(self.dec.FRC)
358 comb += reg.ok.eq(1)
359 with m.Case(In3Sel.RS):
360 comb += reg.data.eq(self.dec.RS)
361 comb += reg.ok.eq(1)
362 with m.Case(In3Sel.RC):
363 comb += reg.data.eq(self.dec.RC)
364 comb += reg.ok.eq(1)
365 with m.Case(In3Sel.RT):
366 # for TII-form ternary
367 comb += reg.data.eq(self.dec.RT)
368 comb += reg.ok.eq(1)
369
370 return m
371
372
373 class DecodeOut(Elaboratable):
374 """DecodeOut from instruction
375
376 decodes output register RA, RT or SPR
377 """
378
379 def __init__(self, dec, op, regreduce_en):
380 self.regreduce_en = regreduce_en
381 if self.regreduce_en:
382 SPR = SPRreduced
383 else:
384 SPR = SPRfull
385 self.dec = dec
386 self.op = op
387 self.sel_in = Signal(OutSel, reset_less=True)
388 self.insn_in = Signal(32, reset_less=True)
389 self.reg_out = Data(5, "reg_o")
390 self.spr_out = Data(SPR, "spr_o")
391 self.fast_out = Data(3, "fast_o")
392
393 def elaborate(self, platform):
394 m = Module()
395 comb = m.d.comb
396 m.submodules.sprmap = sprmap = SPRMap(self.regreduce_en)
397 op = self.op
398 reg = self.reg_out
399
400 # select Register out field
401 with m.Switch(self.sel_in):
402 with m.Case(OutSel.FRT):
403 comb += reg.data.eq(self.dec.FRT)
404 comb += reg.ok.eq(1)
405 with m.Case(OutSel.RT):
406 comb += reg.data.eq(self.dec.RT)
407 comb += reg.ok.eq(1)
408 with m.Case(OutSel.RA):
409 comb += reg.data.eq(self.dec.RA)
410 comb += reg.ok.eq(1)
411 with m.Case(OutSel.SPR):
412 spr = Signal(10, reset_less=True)
413 comb += spr.eq(decode_spr_num(self.dec.SPR)) # from XFX
414 # MFSPR move to SPRs - needs mapping
415 with m.If(op.internal_op == MicrOp.OP_MTSPR):
416 comb += sprmap.spr_i.eq(spr)
417 comb += self.spr_out.eq(sprmap.spr_o)
418 comb += self.fast_out.eq(sprmap.fast_o)
419
420 # determine Fast Reg
421 with m.Switch(op.internal_op):
422
423 # BC or BCREG: implicit register (CTR) NOTE: same in DecodeA
424 with m.Case(MicrOp.OP_BC, MicrOp.OP_BCREG):
425 with m.If(~self.dec.BO[2]): # 3.0B p38 BO2=0, use CTR reg
426 # constant: CTR
427 comb += self.fast_out.data.eq(FastRegsEnum.CTR)
428 comb += self.fast_out.ok.eq(1)
429
430 # RFID 1st spr (fast)
431 with m.Case(MicrOp.OP_RFID):
432 comb += self.fast_out.data.eq(FastRegsEnum.SRR0) # SRR0
433 comb += self.fast_out.ok.eq(1)
434
435 return m
436
437
438 class DecodeOut2(Elaboratable):
439 """DecodeOut2 from instruction
440
441 decodes output registers (2nd one). note that RA is *implicit* below,
442 which now causes problems with SVP64
443
444 TODO: SVP64 is a little more complex, here. svp64 allows extending
445 by one more destination by having one more EXTRA field. RA-as-src
446 is not the same as RA-as-dest. limited in that it's the same first
447 5 bits (from the v3.0B opcode), but still kinda cool. mostly used
448 for operations that have src-as-dest: mostly this is LD/ST-with-update
449 but there are others.
450 """
451
452 def __init__(self, dec, op):
453 self.dec = dec
454 self.op = op
455 self.sel_in = Signal(OutSel, reset_less=True)
456 self.svp64_fft_mode = Signal(reset_less=True) # SVP64 FFT mode
457 self.lk = Signal(reset_less=True)
458 self.insn_in = Signal(32, reset_less=True)
459 self.reg_out = Data(5, "reg_o2")
460 self.fp_madd_en = Signal(reset_less=True) # FFT instruction detected
461 self.fast_out = Data(3, "fast_o2")
462 self.fast_out3 = Data(3, "fast_o3")
463
464 def elaborate(self, platform):
465 m = Module()
466 comb = m.d.comb
467 op = self.op
468 #m.submodules.svdec = svdec = SVP64RegExtra()
469
470 # get the 5-bit reg data before svp64-munging it into 7-bit plus isvec
471 #reg = Signal(5, reset_less=True)
472
473 if hasattr(op, "upd"):
474 # update mode LD/ST uses read-reg A also as an output
475 with m.If(op.upd == LDSTMode.update):
476 comb += self.reg_out.data.eq(self.dec.RA)
477 comb += self.reg_out.ok.eq(1)
478
479 # B, BC or BCREG: potential implicit register (LR) output
480 # these give bl, bcl, bclrl, etc.
481 with m.Switch(op.internal_op):
482
483 # BC* implicit register (LR)
484 with m.Case(MicrOp.OP_BC, MicrOp.OP_B, MicrOp.OP_BCREG):
485 with m.If(self.lk): # "link" mode
486 comb += self.fast_out.data.eq(FastRegsEnum.LR) # LR
487 comb += self.fast_out.ok.eq(1)
488
489 # RFID 2nd and 3rd spr (fast)
490 with m.Case(MicrOp.OP_RFID):
491 comb += self.fast_out.data.eq(FastRegsEnum.SRR1) # SRR1
492 comb += self.fast_out.ok.eq(1)
493 comb += self.fast_out3.data.eq(FastRegsEnum.SVSRR0) # SVSRR0
494 comb += self.fast_out3.ok.eq(1)
495
496 # SVP64 FFT mode, FP mul-add: 2nd output reg (FRS) same as FRT
497 # will be offset by VL in hardware
498 #with m.Case(MicrOp.OP_FP_MADD):
499 with m.If(self.svp64_fft_mode):
500 comb += self.reg_out.data.eq(self.dec.FRT)
501 comb += self.reg_out.ok.eq(1)
502 comb += self.fp_madd_en.eq(1)
503
504 return m
505
506
507 class DecodeRC(Elaboratable):
508 """DecodeRc from instruction
509
510 decodes Record bit Rc
511 """
512
513 def __init__(self, dec):
514 self.dec = dec
515 self.sel_in = Signal(RC, reset_less=True)
516 self.insn_in = Signal(32, reset_less=True)
517 self.rc_out = Data(1, "rc")
518
519 def elaborate(self, platform):
520 m = Module()
521 comb = m.d.comb
522
523 # select Record bit out field
524 with m.Switch(self.sel_in):
525 with m.Case(RC.RC):
526 comb += self.rc_out.data.eq(self.dec.Rc)
527 comb += self.rc_out.ok.eq(1)
528 with m.Case(RC.ONE):
529 comb += self.rc_out.data.eq(1)
530 comb += self.rc_out.ok.eq(1)
531 with m.Case(RC.NONE):
532 comb += self.rc_out.data.eq(0)
533 comb += self.rc_out.ok.eq(1)
534
535 return m
536
537
538 class DecodeOE(Elaboratable):
539 """DecodeOE from instruction
540
541 decodes OE field: uses RC decode detection which might not be good
542
543 -- For now, use "rc" in the decode table to decide whether oe exists.
544 -- This is not entirely correct architecturally: For mulhd and
545 -- mulhdu, the OE field is reserved. It remains to be seen what an
546 -- actual POWER9 does if we set it on those instructions, for now we
547 -- test that further down when assigning to the multiplier oe input.
548 """
549
550 def __init__(self, dec, op):
551 self.dec = dec
552 self.op = op
553 self.sel_in = Signal(RC, reset_less=True)
554 self.insn_in = Signal(32, reset_less=True)
555 self.oe_out = Data(1, "oe")
556
557 def elaborate(self, platform):
558 m = Module()
559 comb = m.d.comb
560 op = self.op
561
562 with m.Switch(op.internal_op):
563
564 # mulhw, mulhwu, mulhd, mulhdu - these *ignore* OE
565 # also rotate
566 # XXX ARGH! ignoring OE causes incompatibility with microwatt
567 # http://lists.libre-soc.org/pipermail/libre-soc-dev/2020-August/000302.html
568 with m.Case(MicrOp.OP_MUL_H64, MicrOp.OP_MUL_H32,
569 MicrOp.OP_EXTS, MicrOp.OP_CNTZ,
570 MicrOp.OP_SHL, MicrOp.OP_SHR, MicrOp.OP_RLC,
571 MicrOp.OP_LOAD, MicrOp.OP_STORE,
572 MicrOp.OP_RLCL, MicrOp.OP_RLCR,
573 MicrOp.OP_EXTSWSLI):
574 pass
575
576 # all other ops decode OE field
577 with m.Default():
578 # select OE bit out field
579 with m.Switch(self.sel_in):
580 with m.Case(RC.RC):
581 comb += self.oe_out.data.eq(self.dec.OE)
582 comb += self.oe_out.ok.eq(1)
583
584 return m
585
586
587 class DecodeCRIn(Elaboratable):
588 """Decodes input CR from instruction
589
590 CR indices - insn fields - (not the data *in* the CR) require only 3
591 bits because they refer to CR0-CR7
592 """
593
594 def __init__(self, dec, op):
595 self.dec = dec
596 self.op = op
597 self.sel_in = Signal(CRInSel, reset_less=True)
598 self.insn_in = Signal(32, reset_less=True)
599 self.cr_bitfield = Data(3, "cr_bitfield")
600 self.cr_bitfield_b = Data(3, "cr_bitfield_b")
601 self.cr_bitfield_o = Data(3, "cr_bitfield_o")
602 self.whole_reg = Data(8, "cr_fxm")
603 self.sv_override = Signal(2, reset_less=True) # do not do EXTRA spec
604
605 def elaborate(self, platform):
606 m = Module()
607 comb = m.d.comb
608 op = self.op
609 m.submodules.ppick = ppick = PriorityPicker(8, reverse_i=True,
610 reverse_o=True)
611
612 # zero-initialisation
613 comb += self.cr_bitfield.ok.eq(0)
614 comb += self.cr_bitfield_b.ok.eq(0)
615 comb += self.cr_bitfield_o.ok.eq(0)
616 comb += self.whole_reg.ok.eq(0)
617 comb += self.sv_override.eq(0)
618
619 # select the relevant CR bitfields
620 with m.Switch(self.sel_in):
621 with m.Case(CRInSel.NONE):
622 pass # No bitfield activated
623 with m.Case(CRInSel.CR0):
624 comb += self.cr_bitfield.data.eq(0) # CR0 (MSB0 numbering)
625 comb += self.cr_bitfield.ok.eq(1)
626 comb += self.sv_override.eq(1)
627 with m.Case(CRInSel.CR1):
628 comb += self.cr_bitfield.data.eq(1) # CR1 (MSB0 numbering)
629 comb += self.cr_bitfield.ok.eq(1)
630 comb += self.sv_override.eq(2)
631 with m.Case(CRInSel.BI):
632 comb += self.cr_bitfield.data.eq(self.dec.BI[2:5])
633 comb += self.cr_bitfield.ok.eq(1)
634 with m.Case(CRInSel.BFA):
635 comb += self.cr_bitfield.data.eq(self.dec.FormX.BFA)
636 comb += self.cr_bitfield.ok.eq(1)
637 with m.Case(CRInSel.BA_BB):
638 comb += self.cr_bitfield.data.eq(self.dec.BA[2:5])
639 comb += self.cr_bitfield.ok.eq(1)
640 comb += self.cr_bitfield_b.data.eq(self.dec.BB[2:5])
641 comb += self.cr_bitfield_b.ok.eq(1)
642 comb += self.cr_bitfield_o.data.eq(self.dec.BT[2:5])
643 comb += self.cr_bitfield_o.ok.eq(1)
644 with m.Case(CRInSel.BC):
645 comb += self.cr_bitfield.data.eq(self.dec.BC[2:5])
646 comb += self.cr_bitfield.ok.eq(1)
647 with m.Case(CRInSel.WHOLE_REG):
648 comb += self.whole_reg.ok.eq(1)
649 move_one = Signal(reset_less=True)
650 comb += move_one.eq(self.insn_in[20]) # MSB0 bit 11
651 with m.If((op.internal_op == MicrOp.OP_MFCR) & move_one):
652 # must one-hot the FXM field
653 comb += ppick.i.eq(self.dec.FXM)
654 comb += self.whole_reg.data.eq(ppick.o)
655 with m.Else():
656 # otherwise use all of it
657 comb += self.whole_reg.data.eq(0xff)
658
659 return m
660
661
662 class DecodeCROut(Elaboratable):
663 """Decodes input CR from instruction
664
665 CR indices - insn fields - (not the data *in* the CR) require only 3
666 bits because they refer to CR0-CR7
667 """
668
669 def __init__(self, dec, op):
670 self.dec = dec
671 self.op = op
672 self.rc_in = Signal(reset_less=True)
673 self.sel_in = Signal(CROutSel, reset_less=True)
674 self.insn_in = Signal(32, reset_less=True)
675 self.cr_bitfield = Data(3, "cr_bitfield")
676 self.whole_reg = Data(8, "cr_fxm")
677 self.sv_override = Signal(2, reset_less=True) # do not do EXTRA spec
678
679 def elaborate(self, platform):
680 m = Module()
681 comb = m.d.comb
682 op = self.op
683 m.submodules.ppick = ppick = PriorityPicker(8, reverse_i=True,
684 reverse_o=True)
685
686 comb += self.cr_bitfield.ok.eq(0)
687 comb += self.whole_reg.ok.eq(0)
688 comb += self.sv_override.eq(0)
689
690 # please note these MUST match (setting of cr_bitfield.ok) exactly
691 # with write_cr0 below in PowerDecoder2. the reason it's separated
692 # is to avoid having duplicate copies of DecodeCROut in multiple
693 # PowerDecoderSubsets. register decoding should be a one-off in
694 # PowerDecoder2. see https://bugs.libre-soc.org/show_bug.cgi?id=606
695
696 with m.Switch(self.sel_in):
697 with m.Case(CROutSel.NONE):
698 pass # No bitfield activated
699 with m.Case(CROutSel.CR0):
700 comb += self.cr_bitfield.data.eq(0) # CR0 (MSB0 numbering)
701 comb += self.cr_bitfield.ok.eq(self.rc_in) # only when RC=1
702 comb += self.sv_override.eq(1)
703 with m.Case(CROutSel.CR1):
704 comb += self.cr_bitfield.data.eq(1) # CR1 (MSB0 numbering)
705 comb += self.cr_bitfield.ok.eq(self.rc_in) # only when RC=1
706 comb += self.sv_override.eq(2)
707 with m.Case(CROutSel.BF):
708 comb += self.cr_bitfield.data.eq(self.dec.FormX.BF)
709 comb += self.cr_bitfield.ok.eq(1)
710 with m.Case(CROutSel.BT):
711 comb += self.cr_bitfield.data.eq(self.dec.FormXL.BT[2:5])
712 comb += self.cr_bitfield.ok.eq(1)
713 with m.Case(CROutSel.WHOLE_REG):
714 comb += self.whole_reg.ok.eq(1)
715 move_one = Signal(reset_less=True)
716 comb += move_one.eq(self.insn_in[20])
717 with m.If((op.internal_op == MicrOp.OP_MTCRF)):
718 with m.If(move_one):
719 # must one-hot the FXM field
720 comb += ppick.i.eq(self.dec.FXM)
721 with m.If(ppick.en_o):
722 comb += self.whole_reg.data.eq(ppick.o)
723 with m.Else():
724 comb += self.whole_reg.data.eq(0b00000001) # CR7
725 with m.Else():
726 comb += self.whole_reg.data.eq(self.dec.FXM)
727 with m.Else():
728 # otherwise use all of it
729 comb += self.whole_reg.data.eq(0xff)
730
731 return m
732
733 # dictionary of Input Record field names that, if they exist,
734 # will need a corresponding CSV Decoder file column (actually, PowerOp)
735 # to be decoded (this includes the single bit names)
736 record_names = {'insn_type': 'internal_op',
737 'fn_unit': 'function_unit',
738 'SV_Ptype': 'SV_Ptype',
739 'rc': 'rc_sel',
740 'oe': 'rc_sel',
741 'zero_a': 'in1_sel',
742 'imm_data': 'in2_sel',
743 'invert_in': 'inv_a',
744 'invert_out': 'inv_out',
745 'rc': 'cr_out',
746 'oe': 'cr_in',
747 'output_carry': 'cry_out',
748 'input_carry': 'cry_in',
749 'is_32bit': 'is_32b',
750 'is_signed': 'sgn',
751 'lk': 'lk',
752 'data_len': 'ldst_len',
753 'byte_reverse': 'br',
754 'sign_extend': 'sgn_ext',
755 'ldst_mode': 'upd',
756 }
757
758
759 class PowerDecodeSubset(Elaboratable):
760 """PowerDecodeSubset: dynamic subset decoder
761
762 only fields actually requested are copied over. hence, "subset" (duh).
763 """
764 def __init__(self, dec, opkls=None, fn_name=None, final=False, state=None,
765 svp64_en=True, regreduce_en=False):
766
767 self.svp64_en = svp64_en
768 self.regreduce_en = regreduce_en
769 if svp64_en:
770 self.is_svp64_mode = Signal() # mark decoding as SVP64 Mode
771 self.use_svp64_ldst_dec = Signal() # must use LDST decoder
772 self.use_svp64_fft = Signal() # FFT Mode
773 self.sv_rm = SVP64Rec(name="dec_svp64") # SVP64 RM field
774 self.rm_dec = SVP64RMModeDecode("svp64_rm_dec")
775 # set these to the predicate mask bits needed for the ALU
776 self.pred_sm = Signal() # TODO expand to SIMD mask width
777 self.pred_dm = Signal() # TODO expand to SIMD mask width
778 self.sv_a_nz = Signal(1)
779 self.final = final
780 self.opkls = opkls
781 self.fn_name = fn_name
782 if opkls is None:
783 opkls = Decode2ToOperand
784 self.do = opkls(fn_name)
785 if final:
786 col_subset = self.get_col_subset(self.do)
787 row_subset = self.rowsubsetfn
788 else:
789 col_subset = None
790 row_subset = None
791
792 # "conditions" for Decoders, to enable some weird and wonderful
793 # alternatives. useful for PCR (Program Compatibility Register)
794 # amongst other things
795 if svp64_en:
796 conditions = {'SVP64BREV': self.use_svp64_ldst_dec,
797 'SVP64FFT': self.use_svp64_fft,
798 }
799 else:
800 conditions = None
801
802 # only needed for "main" PowerDecode2
803 if not self.final:
804 self.e = Decode2ToExecute1Type(name=self.fn_name, do=self.do,
805 regreduce_en=regreduce_en)
806
807 # create decoder if one not already given
808 if dec is None:
809 dec = create_pdecode(name=fn_name, col_subset=col_subset,
810 row_subset=row_subset,
811 conditions=conditions)
812 self.dec = dec
813
814 # set up a copy of the PowerOp
815 self.op = PowerOp.like(self.dec.op)
816
817 # state information needed by the Decoder
818 if state is None:
819 state = CoreState("dec2")
820 self.state = state
821
822 def get_col_subset(self, do):
823 subset = { 'cr_in', 'cr_out', 'rc_sel'} # needed, non-optional
824 for k, v in record_names.items():
825 if hasattr(do, k):
826 subset.add(v)
827 log ("get_col_subset", self.fn_name, do.fields, subset)
828 return subset
829
830 def rowsubsetfn(self, opcode, row):
831 """select per-Function-Unit subset of opcodes to be processed
832
833 normally this just looks at the "unit" column. MMU is different
834 in that it processes specific SPR set/get operations that the SPR
835 pipeline should not.
836 """
837 return (row['unit'] == self.fn_name or
838 # sigh a dreadful hack: MTSPR and MFSPR need to be processed
839 # by the MMU pipeline so we direct those opcodes to MMU **AND**
840 # SPR pipelines, then selectively weed out the SPRs that should
841 # or should not not go to each pipeline, further down.
842 # really this should be done by modifying the CSV syntax
843 # to support multiple tasks (unit column multiple entries)
844 # see https://bugs.libre-soc.org/show_bug.cgi?id=310
845 (self.fn_name == 'MMU' and row['unit'] == 'SPR' and
846 row['internal op'] in ['OP_MTSPR', 'OP_MFSPR'])
847 )
848
849 def ports(self):
850 ports = self.dec.ports() + self.e.ports()
851 if self.svp64_en:
852 ports += self.sv_rm.ports()
853 ports.append(self.is_svp64_mode)
854 ports.append(self.use_svp64_ldst_dec )
855 ports.append(self.use_svp64_fft )
856 return ports
857
858 def needs_field(self, field, op_field):
859 if self.final:
860 do = self.do
861 else:
862 do = self.e_tmp.do
863 return hasattr(do, field) and self.op_get(op_field) is not None
864
865 def do_get(self, field, final=False):
866 if final or self.final:
867 do = self.do
868 else:
869 do = self.e_tmp.do
870 return getattr(do, field, None)
871
872 def do_copy(self, field, val, final=False):
873 df = self.do_get(field, final)
874 if df is not None and val is not None:
875 return df.eq(val)
876 return []
877
878 def op_get(self, op_field):
879 return getattr(self.op, op_field, None)
880
881 def elaborate(self, platform):
882 if self.regreduce_en:
883 SPR = SPRreduced
884 else:
885 SPR = SPRfull
886 m = Module()
887 comb = m.d.comb
888 state = self.state
889 op, do = self.dec.op, self.do
890 msr, cia, svstate = state.msr, state.pc, state.svstate
891 # fill in for a normal instruction (not an exception)
892 # copy over if non-exception, non-privileged etc. is detected
893 if not self.final:
894 if self.fn_name is None:
895 name = "tmp"
896 else:
897 name = self.fn_name + "tmp"
898 self.e_tmp = Decode2ToExecute1Type(name=name, opkls=self.opkls,
899 regreduce_en=self.regreduce_en)
900
901 # set up submodule decoders
902 m.submodules.dec = dec = self.dec
903 m.submodules.dec_rc = self.dec_rc = dec_rc = DecodeRC(self.dec)
904 m.submodules.dec_oe = dec_oe = DecodeOE(self.dec, op)
905
906 if self.svp64_en:
907 # and SVP64 RM mode decoder
908 m.submodules.sv_rm_dec = rm_dec = self.rm_dec
909
910 # copy op from decoder
911 comb += self.op.eq(self.dec.op)
912
913 # copy instruction through...
914 for i in [do.insn, dec_rc.insn_in, dec_oe.insn_in, ]:
915 comb += i.eq(self.dec.opcode_in)
916
917 # ...and subdecoders' input fields
918 comb += dec_rc.sel_in.eq(self.op_get("rc_sel"))
919 comb += dec_oe.sel_in.eq(self.op_get("rc_sel")) # XXX should be OE sel
920
921 # copy "state" over
922 comb += self.do_copy("msr", msr)
923 comb += self.do_copy("cia", cia)
924 comb += self.do_copy("svstate", svstate)
925
926 # set up instruction type
927 # no op: defaults to OP_ILLEGAL
928 internal_op = self.op_get("internal_op")
929 comb += self.do_copy("insn_type", internal_op)
930
931 # function unit for decoded instruction: requires minor redirect
932 # for SPR set/get
933 fn = self.op_get("function_unit")
934 spr = Signal(10, reset_less=True)
935 comb += spr.eq(decode_spr_num(self.dec.SPR)) # from XFX
936
937 # Microwatt doesn't implement the partition table
938 # instead has PRTBL register (SPR) to point to process table
939 is_spr_mv = Signal()
940 is_mmu_spr = Signal()
941 comb += is_spr_mv.eq((internal_op == MicrOp.OP_MTSPR) |
942 (internal_op == MicrOp.OP_MFSPR))
943 comb += is_mmu_spr.eq((spr == SPR.DSISR.value) |
944 (spr == SPR.DAR.value) |
945 (spr == SPR.PRTBL.value) |
946 (spr == SPR.PIDR.value))
947 # MMU must receive MMU SPRs
948 with m.If(is_spr_mv & (fn == Function.SPR) & is_mmu_spr):
949 comb += self.do_copy("fn_unit", Function.MMU)
950 comb += self.do_copy("insn_type", internal_op)
951 # SPR pipe must *not* receive MMU SPRs
952 with m.Elif(is_spr_mv & (fn == Function.MMU) & ~is_mmu_spr):
953 comb += self.do_copy("fn_unit", Function.NONE)
954 comb += self.do_copy("insn_type", MicrOp.OP_ILLEGAL)
955 # all others ok
956 with m.Else():
957 comb += self.do_copy("fn_unit", fn)
958
959 # immediates
960 if self.needs_field("zero_a", "in1_sel"):
961 m.submodules.dec_ai = dec_ai = DecodeAImm(self.dec)
962 comb += dec_ai.sv_nz.eq(self.sv_a_nz)
963 comb += dec_ai.sel_in.eq(self.op_get("in1_sel"))
964 comb += self.do_copy("zero_a", dec_ai.immz_out) # RA==0 detected
965 if self.needs_field("imm_data", "in2_sel"):
966 m.submodules.dec_bi = dec_bi = DecodeBImm(self.dec)
967 comb += dec_bi.sel_in.eq(self.op_get("in2_sel"))
968 comb += self.do_copy("imm_data", dec_bi.imm_out) # imm in RB
969
970 # rc and oe out
971 comb += self.do_copy("rc", dec_rc.rc_out)
972 if self.svp64_en:
973 # OE only enabled when SVP64 not active
974 with m.If(~self.is_svp64_mode):
975 comb += self.do_copy("oe", dec_oe.oe_out)
976 else:
977 comb += self.do_copy("oe", dec_oe.oe_out)
978
979 # CR in/out - note: these MUST match with what happens in
980 # DecodeCROut!
981 rc_out = self.dec_rc.rc_out.data
982 with m.Switch(self.op_get("cr_out")):
983 with m.Case(CROutSel.CR0, CROutSel.CR1):
984 comb += self.do_copy("write_cr0", rc_out) # only when RC=1
985 with m.Case(CROutSel.BF, CROutSel.BT):
986 comb += self.do_copy("write_cr0", 1)
987
988 comb += self.do_copy("input_cr", self.op_get("cr_in")) # CR in
989 comb += self.do_copy("output_cr", self.op_get("cr_out")) # CR out
990
991 if self.svp64_en:
992 # connect up SVP64 RM Mode decoding. however... we need a shorter
993 # path, for the LDST bit-reverse detection. so perform partial
994 # decode when SVP64 is detected. then, bit-reverse mode can be
995 # quickly determined, and the Decoder result MUXed over to
996 # the alternative decoder, svdecldst. what a mess... *sigh*
997 sv_ptype = self.op_get("SV_Ptype")
998 fn = self.op_get("function_unit")
999 # detect major opcode for LDs: include 58 here. from CSV files.
1000 # BLECH! TODO: these should be done using "mini decoders",
1001 # using row and column subsets
1002 is_major_ld = Signal()
1003 major = Signal(6) # bits... errr... MSB0 0..5 which is 26:32 python
1004 comb += major.eq(self.dec.opcode_in[26:32])
1005 comb += is_major_ld.eq((major == 34) | (major == 35) |
1006 (major == 50) | (major == 51) |
1007 (major == 48) | (major == 49) |
1008 (major == 42) | (major == 43) |
1009 (major == 40) | (major == 41) |
1010 (major == 32) | (major == 33) |
1011 (major == 58))
1012 with m.If(self.is_svp64_mode & is_major_ld):
1013 # straight-up: "it's a LD". this gives enough info
1014 # for SVP64 RM Mode decoding to detect LD/ST, and
1015 # consequently detect the SHIFT mode. sigh
1016 comb += rm_dec.fn_in.eq(Function.LDST)
1017 with m.Else():
1018 comb += rm_dec.fn_in.eq(fn) # decode needs to know Fn type
1019 comb += rm_dec.ptype_in.eq(sv_ptype) # Single/Twin predicated
1020 comb += rm_dec.rc_in.eq(rc_out) # Rc=1
1021 comb += rm_dec.rm_in.eq(self.sv_rm) # SVP64 RM mode
1022 if self.needs_field("imm_data", "in2_sel"):
1023 bzero = dec_bi.imm_out.ok & ~dec_bi.imm_out.data.bool()
1024 comb += rm_dec.ldst_imz_in.eq(bzero) # B immediate is zero
1025
1026 # main PowerDecoder2 determines if different SVP64 modes enabled
1027 if not self.final:
1028 # if shift mode requested
1029 shiftmode = rm_dec.ldstmode == SVP64LDSTmode.SHIFT
1030 comb += self.use_svp64_ldst_dec.eq(shiftmode)
1031 # detect if SVP64 FFT mode enabled (really bad hack),
1032 # exclude fcfids and others
1033 # XXX this is a REALLY bad hack, REALLY has to be done better.
1034 # likely with a sub-decoder.
1035 xo5 = Signal(1) # 1 bit from Minor 59 XO field == 0b0XXXX
1036 comb += xo5.eq(self.dec.opcode_in[5])
1037 xo = Signal(5) # 5 bits from Minor 59 fcfids == 0b01110
1038 comb += xo.eq(self.dec.opcode_in[1:6])
1039 comb += self.use_svp64_fft.eq((major == 59) & (xo5 == 0b0) &
1040 (xo != 0b01110))
1041
1042 # decoded/selected instruction flags
1043 comb += self.do_copy("data_len", self.op_get("ldst_len"))
1044 comb += self.do_copy("invert_in", self.op_get("inv_a"))
1045 comb += self.do_copy("invert_out", self.op_get("inv_out"))
1046 comb += self.do_copy("input_carry", self.op_get("cry_in"))
1047 comb += self.do_copy("output_carry", self.op_get("cry_out"))
1048 comb += self.do_copy("is_32bit", self.op_get("is_32b"))
1049 comb += self.do_copy("is_signed", self.op_get("sgn"))
1050 lk = self.op_get("lk")
1051 if lk is not None:
1052 with m.If(lk):
1053 comb += self.do_copy("lk", self.dec.LK) # XXX TODO: accessor
1054
1055 comb += self.do_copy("byte_reverse", self.op_get("br"))
1056 comb += self.do_copy("sign_extend", self.op_get("sgn_ext"))
1057 comb += self.do_copy("ldst_mode", self.op_get("upd")) # LD/ST mode
1058
1059 # copy over SVP64 input record fields (if they exist)
1060 if self.svp64_en:
1061 # TODO, really do we have to do these explicitly?? sigh
1062 #for (field, _) in sv_input_record_layout:
1063 # comb += self.do_copy(field, self.rm_dec.op_get(field))
1064 comb += self.do_copy("sv_saturate", self.rm_dec.saturate)
1065 comb += self.do_copy("sv_Ptype", self.rm_dec.ptype_in)
1066 comb += self.do_copy("sv_ldstmode", self.rm_dec.ldstmode)
1067 # these get set up based on incoming mask bits. TODO:
1068 # pass in multiple bits (later, when SIMD backends are enabled)
1069 with m.If(self.rm_dec.pred_sz):
1070 comb += self.do_copy("sv_pred_sz", ~self.pred_sm)
1071 with m.If(self.rm_dec.pred_dz):
1072 comb += self.do_copy("sv_pred_dz", ~self.pred_dm)
1073
1074 return m
1075
1076
1077 class PowerDecode2(PowerDecodeSubset):
1078 """PowerDecode2: the main instruction decoder.
1079
1080 whilst PowerDecode is responsible for decoding the actual opcode, this
1081 module encapsulates further specialist, sparse information and
1082 expansion of fields that is inconvenient to have in the CSV files.
1083 for example: the encoding of the immediates, which are detected
1084 and expanded out to their full value from an annotated (enum)
1085 representation.
1086
1087 implicit register usage is also set up, here. for example: OP_BC
1088 requires implicitly reading CTR, OP_RFID requires implicitly writing
1089 to SRR1 and so on.
1090
1091 in addition, PowerDecoder2 is responsible for detecting whether
1092 instructions are illegal (or privileged) or not, and instead of
1093 just leaving at that, *replacing* the instruction to execute with
1094 a suitable alternative (trap).
1095
1096 LDSTExceptions are done the cycle _after_ they're detected (after
1097 they come out of LDSTCompUnit). basically despite the instruction
1098 being decoded, the results of the decode are completely ignored
1099 and "exception.happened" used to set the "actual" instruction to
1100 "OP_TRAP". the LDSTException data structure gets filled in,
1101 in the CompTrapOpSubset and that's what it fills in SRR.
1102
1103 to make this work, TestIssuer must notice "exception.happened"
1104 after the (failed) LD/ST and copies the LDSTException info from
1105 the output, into here (PowerDecoder2). without incrementing PC.
1106 """
1107
1108 def __init__(self, dec, opkls=None, fn_name=None, final=False,
1109 state=None, svp64_en=True, regreduce_en=False):
1110 super().__init__(dec, opkls, fn_name, final, state, svp64_en,
1111 regreduce_en=False)
1112 self.ldst_exc = LDSTException("dec2_exc")
1113
1114 if self.svp64_en:
1115 self.cr_out_isvec = Signal(1, name="cr_out_isvec")
1116 self.cr_in_isvec = Signal(1, name="cr_in_isvec")
1117 self.cr_in_b_isvec = Signal(1, name="cr_in_b_isvec")
1118 self.cr_in_o_isvec = Signal(1, name="cr_in_o_isvec")
1119 self.in1_isvec = Signal(1, name="reg_a_isvec")
1120 self.in2_isvec = Signal(1, name="reg_b_isvec")
1121 self.in3_isvec = Signal(1, name="reg_c_isvec")
1122 self.o_isvec = Signal(7, name="reg_o_isvec")
1123 self.o2_isvec = Signal(7, name="reg_o2_isvec")
1124 self.in1_step = Signal(7, name="reg_a_step")
1125 self.in2_step = Signal(7, name="reg_b_step")
1126 self.in3_step = Signal(7, name="reg_c_step")
1127 self.o_step = Signal(7, name="reg_o_step")
1128 self.o2_step = Signal(7, name="reg_o2_step")
1129 self.remap_active = Signal(5, name="remap_active") # per reg
1130 self.no_in_vec = Signal(1, name="no_in_vec") # no inputs vector
1131 self.no_out_vec = Signal(1, name="no_out_vec") # no outputs vector
1132 self.loop_continue = Signal(1, name="loop_continue")
1133 else:
1134 self.no_in_vec = Const(1, 1)
1135 self.no_out_vec = Const(1, 1)
1136 self.loop_continue = Const(0, 1)
1137
1138 def get_col_subset(self, opkls):
1139 subset = super().get_col_subset(opkls)
1140 subset.add("asmcode")
1141 subset.add("in1_sel")
1142 subset.add("in2_sel")
1143 subset.add("in3_sel")
1144 subset.add("out_sel")
1145 if self.svp64_en:
1146 subset.add("sv_in1")
1147 subset.add("sv_in2")
1148 subset.add("sv_in3")
1149 subset.add("sv_out")
1150 subset.add("sv_out2")
1151 subset.add("sv_cr_in")
1152 subset.add("sv_cr_out")
1153 subset.add("SV_Etype")
1154 subset.add("SV_Ptype")
1155 # from SVP64RMModeDecode
1156 for (field, _) in sv_input_record_layout:
1157 subset.add(field)
1158 subset.add("lk")
1159 subset.add("internal_op")
1160 subset.add("form")
1161 return subset
1162
1163 def elaborate(self, platform):
1164 m = super().elaborate(platform)
1165 comb = m.d.comb
1166 state = self.state
1167 op, e_out, do_out = self.op, self.e, self.e.do
1168 dec_spr, msr, cia, ext_irq = state.dec, state.msr, state.pc, state.eint
1169 rc_out = self.dec_rc.rc_out.data
1170 e = self.e_tmp
1171 do = e.do
1172
1173 # fill in for a normal instruction (not an exception)
1174 # copy over if non-exception, non-privileged etc. is detected
1175
1176 # set up submodule decoders
1177 m.submodules.dec_a = dec_a = DecodeA(self.dec, op, self.regreduce_en)
1178 m.submodules.dec_b = dec_b = DecodeB(self.dec, op)
1179 m.submodules.dec_c = dec_c = DecodeC(self.dec, op)
1180 m.submodules.dec_o = dec_o = DecodeOut(self.dec, op, self.regreduce_en)
1181 m.submodules.dec_o2 = dec_o2 = DecodeOut2(self.dec, op)
1182 m.submodules.dec_cr_in = self.dec_cr_in = DecodeCRIn(self.dec, op)
1183 m.submodules.dec_cr_out = self.dec_cr_out = DecodeCROut(self.dec, op)
1184 comb += dec_a.sv_nz.eq(self.sv_a_nz)
1185
1186 if self.svp64_en:
1187 # and SVP64 Extra decoders
1188 m.submodules.crout_svdec = crout_svdec = SVP64CRExtra()
1189 m.submodules.crin_svdec = crin_svdec = SVP64CRExtra()
1190 m.submodules.crin_svdec_b = crin_svdec_b = SVP64CRExtra()
1191 m.submodules.crin_svdec_o = crin_svdec_o = SVP64CRExtra()
1192 m.submodules.in1_svdec = in1_svdec = SVP64RegExtra()
1193 m.submodules.in2_svdec = in2_svdec = SVP64RegExtra()
1194 m.submodules.in3_svdec = in3_svdec = SVP64RegExtra()
1195 m.submodules.o_svdec = o_svdec = SVP64RegExtra()
1196 m.submodules.o2_svdec = o2_svdec = SVP64RegExtra()
1197
1198 # debug access to cr svdec (used in get_pdecode_cr_in/out)
1199 self.crout_svdec = crout_svdec
1200 self.crin_svdec = crin_svdec
1201
1202 # get the 5-bit reg data before svp64-munging it into 7-bit plus isvec
1203 reg = Signal(5, reset_less=True)
1204
1205 # copy instruction through...
1206 for i in [do.insn, dec_a.insn_in, dec_b.insn_in,
1207 self.dec_cr_in.insn_in, self.dec_cr_out.insn_in,
1208 dec_c.insn_in, dec_o.insn_in, dec_o2.insn_in]:
1209 comb += i.eq(self.dec.opcode_in)
1210
1211 # CR setup
1212 comb += self.dec_cr_in.sel_in.eq(self.op_get("cr_in"))
1213 comb += self.dec_cr_out.sel_in.eq(self.op_get("cr_out"))
1214 comb += self.dec_cr_out.rc_in.eq(rc_out)
1215
1216 # CR register info
1217 comb += self.do_copy("read_cr_whole", self.dec_cr_in.whole_reg)
1218 comb += self.do_copy("write_cr_whole", self.dec_cr_out.whole_reg)
1219
1220 # ...and subdecoders' input fields
1221 comb += dec_a.sel_in.eq(self.op_get("in1_sel"))
1222 comb += dec_b.sel_in.eq(self.op_get("in2_sel"))
1223 comb += dec_c.sel_in.eq(self.op_get("in3_sel"))
1224 comb += dec_o.sel_in.eq(self.op_get("out_sel"))
1225 comb += dec_o2.sel_in.eq(self.op_get("out_sel"))
1226 if self.svp64_en:
1227 comb += dec_o2.svp64_fft_mode.eq(self.use_svp64_fft)
1228 if hasattr(do, "lk"):
1229 comb += dec_o2.lk.eq(do.lk)
1230
1231 if self.svp64_en:
1232 # now do the SVP64 munging. op.SV_Etype and op.sv_in1 comes from
1233 # PowerDecoder which in turn comes from LDST-RM*.csv and RM-*.csv
1234 # which in turn were auto-generated by sv_analysis.py
1235 extra = self.sv_rm.extra # SVP64 extra bits 10:18
1236
1237 #######
1238 # CR out
1239 comb += crout_svdec.idx.eq(self.op_get("sv_cr_out")) # SVP64 CR out
1240 comb += self.cr_out_isvec.eq(crout_svdec.isvec)
1241
1242 #######
1243 # CR in - selection slightly different due to shared CR field sigh
1244 cr_a_idx = Signal(SVEXTRA)
1245 cr_b_idx = Signal(SVEXTRA)
1246
1247 # these change slightly, when decoding BA/BB. really should have
1248 # their own separate CSV column: sv_cr_in1 and sv_cr_in2, but hey
1249 comb += cr_a_idx.eq(self.op_get("sv_cr_in"))
1250 comb += cr_b_idx.eq(SVEXTRA.NONE)
1251 with m.If(self.op_get("sv_cr_in") == SVEXTRA.Idx_1_2.value):
1252 comb += cr_a_idx.eq(SVEXTRA.Idx1)
1253 comb += cr_b_idx.eq(SVEXTRA.Idx2)
1254
1255 comb += self.cr_in_isvec.eq(crin_svdec.isvec)
1256 comb += self.cr_in_b_isvec.eq(crin_svdec_b.isvec)
1257 comb += self.cr_in_o_isvec.eq(crin_svdec_o.isvec)
1258
1259 # indices are slightly different, BA/BB mess sorted above
1260 comb += crin_svdec.idx.eq(cr_a_idx) # SVP64 CR in A
1261 comb += crin_svdec_b.idx.eq(cr_b_idx) # SVP64 CR in B
1262 comb += crin_svdec_o.idx.eq(self.op_get("sv_cr_out")) # SVP64 CR out
1263
1264 # get SVSTATE srcstep (TODO: elwidth etc.) needed below
1265 vl = Signal.like(self.state.svstate.vl)
1266 srcstep = Signal.like(self.state.svstate.srcstep)
1267 dststep = Signal.like(self.state.svstate.dststep)
1268 comb += vl.eq(self.state.svstate.vl)
1269 comb += srcstep.eq(self.state.svstate.srcstep)
1270 comb += dststep.eq(self.state.svstate.dststep)
1271
1272 in1_step, in2_step = self.in1_step, self.in2_step
1273 in3_step = self.in3_step
1274 o_step, o2_step = self.o_step, self.o2_step
1275
1276 # registers a, b, c and out and out2 (LD/ST EA)
1277 sv_etype = self.op_get("SV_Etype")
1278 for i, stuff in enumerate((
1279 ("RA", e.read_reg1, dec_a.reg_out, in1_svdec, in1_step, False),
1280 ("RB", e.read_reg2, dec_b.reg_out, in2_svdec, in2_step, False),
1281 ("RC", e.read_reg3, dec_c.reg_out, in3_svdec, in3_step, False),
1282 ("RT", e.write_reg, dec_o.reg_out, o_svdec, o_step, True),
1283 ("EA", e.write_ea, dec_o2.reg_out, o2_svdec, o2_step, True))):
1284 rname, to_reg, fromreg, svdec, remapstep, out = stuff
1285 comb += svdec.extra.eq(extra) # EXTRA field of SVP64 RM
1286 comb += svdec.etype.eq(sv_etype) # EXTRA2/3 for this insn
1287 comb += svdec.reg_in.eq(fromreg.data) # 3-bit (CR0/BC/BFA)
1288 comb += to_reg.ok.eq(fromreg.ok)
1289 # *screaam* FFT mode needs an extra offset for RB
1290 # similar to FRS/FRT (below). all of this needs cleanup
1291 offs = Signal(7, name="offs_"+rname, reset_less=True)
1292 comb += offs.eq(0)
1293 if rname == 'RB':
1294 # when FFT sv.ffmadd detected, and REMAP not in use,
1295 # automagically add on an extra offset to RB.
1296 # however when REMAP is active, the FFT REMAP
1297 # schedule takes care of this offset.
1298 with m.If(dec_o2.reg_out.ok & dec_o2.fp_madd_en):
1299 with m.If(~self.remap_active[i]):
1300 with m.If(svdec.isvec):
1301 comb += offs.eq(vl) # VL for Vectors
1302 # detect if Vectorised: add srcstep/dststep if yes.
1303 # to_reg is 7-bits, outs get dststep added, ins get srcstep
1304 with m.If(svdec.isvec):
1305 selectstep = dststep if out else srcstep
1306 step = Signal(7, name="step_%s" % rname.lower())
1307 with m.If(self.remap_active[i]):
1308 comb += step.eq(remapstep)
1309 with m.Else():
1310 comb += step.eq(selectstep)
1311 # reverse gear goes the opposite way
1312 with m.If(self.rm_dec.reverse_gear):
1313 comb += to_reg.data.eq(offs+svdec.reg_out+(vl-1-step))
1314 with m.Else():
1315 comb += to_reg.data.eq(offs+step+svdec.reg_out)
1316 with m.Else():
1317 comb += to_reg.data.eq(offs+svdec.reg_out)
1318
1319 # SVP64 in/out fields
1320 comb += in1_svdec.idx.eq(self.op_get("sv_in1")) # reg #1 (in1_sel)
1321 comb += in2_svdec.idx.eq(self.op_get("sv_in2")) # reg #2 (in2_sel)
1322 comb += in3_svdec.idx.eq(self.op_get("sv_in3")) # reg #3 (in3_sel)
1323 comb += o_svdec.idx.eq(self.op_get("sv_out")) # output (out_sel)
1324 comb += o2_svdec.idx.eq(self.op_get("sv_out2")) # output (implicit)
1325 # XXX TODO - work out where this should come from. the problem is
1326 # that LD-with-update is implied (computed from "is instruction in
1327 # "update mode" rather than specified cleanly as its own CSV column
1328
1329 # output reg-is-vectorised (and when no in/out is vectorised)
1330 comb += self.in1_isvec.eq(in1_svdec.isvec)
1331 comb += self.in2_isvec.eq(in2_svdec.isvec)
1332 comb += self.in3_isvec.eq(in3_svdec.isvec)
1333 comb += self.o_isvec.eq(o_svdec.isvec)
1334 comb += self.o2_isvec.eq(o2_svdec.isvec)
1335
1336 # urrr... don't ask... the implicit register FRS in FFT mode
1337 # "tracks" FRT exactly except it's offset by VL. rather than
1338 # mess up the above with if-statements, override it here.
1339 # same trick is applied to FRA, above, but it's a lot cleaner, there
1340 with m.If(dec_o2.reg_out.ok & dec_o2.fp_madd_en):
1341 comb += offs.eq(0)
1342 with m.If(~self.remap_active[4]):
1343 with m.If(o2_svdec.isvec):
1344 comb += offs.eq(vl) # VL for Vectors
1345 with m.Else():
1346 comb += offs.eq(1) # add 1 if scalar
1347 svdec = o_svdec # yes take source as o_svdec...
1348 with m.If(svdec.isvec):
1349 step = Signal(7, name="step_%s" % rname.lower())
1350 with m.If(self.remap_active[4]):
1351 comb += step.eq(o2_step)
1352 with m.Else():
1353 comb += step.eq(dststep)
1354 # reverse gear goes the opposite way
1355 with m.If(self.rm_dec.reverse_gear):
1356 roffs = offs+(vl-1-step)
1357 comb += to_reg.data.eq(roffs+svdec.reg_out)
1358 with m.Else():
1359 comb += to_reg.data.eq(offs+step+svdec.reg_out)
1360 with m.Else():
1361 comb += to_reg.data.eq(offs+svdec.reg_out)
1362 # ... but write to *second* output
1363 comb += self.o2_isvec.eq(svdec.isvec)
1364 comb += o2_svdec.idx.eq(self.op_get("sv_out"))
1365
1366 # TODO add SPRs here. must be True when *all* are scalar
1367 l = map(lambda svdec: svdec.isvec, [in1_svdec, in2_svdec, in3_svdec,
1368 crin_svdec, crin_svdec_b, crin_svdec_o])
1369 comb += self.no_in_vec.eq(~Cat(*l).bool()) # all input scalar
1370 l = map(lambda svdec: svdec.isvec, [o2_svdec, o_svdec, crout_svdec])
1371 # in mapreduce mode, scalar out is *allowed*
1372 with m.If(self.rm_dec.mode == SVP64RMMode.MAPREDUCE.value):
1373 comb += self.no_out_vec.eq(0)
1374 with m.Else():
1375 comb += self.no_out_vec.eq(~Cat(*l).bool()) # all output scalar
1376 # now create a general-purpose "test" as to whether looping
1377 # should continue. this doesn't include predication bit-tests
1378 loop = self.loop_continue
1379 with m.Switch(self.op_get("SV_Ptype")):
1380 with m.Case(SVPtype.P2.value):
1381 # twin-predication
1382 # TODO: *and cache-inhibited LD/ST!*
1383 comb += loop.eq(~(self.no_in_vec | self.no_out_vec))
1384 with m.Case(SVPtype.P1.value):
1385 # single-predication, test relies on dest only
1386 comb += loop.eq(~self.no_out_vec)
1387 with m.Default():
1388 # not an SV operation, no looping
1389 comb += loop.eq(0)
1390
1391 # condition registers (CR)
1392 for to_reg, cr, name, svdec, out in (
1393 (e.read_cr1, self.dec_cr_in, "cr_bitfield", crin_svdec, 0),
1394 (e.read_cr2, self.dec_cr_in, "cr_bitfield_b", crin_svdec_b, 0),
1395 (e.read_cr3, self.dec_cr_in, "cr_bitfield_o", crin_svdec_o, 0),
1396 (e.write_cr, self.dec_cr_out, "cr_bitfield", crout_svdec, 1)):
1397 fromreg = getattr(cr, name)
1398 comb += svdec.extra.eq(extra) # EXTRA field of SVP64 RM
1399 comb += svdec.etype.eq(sv_etype) # EXTRA2/3 for this insn
1400 comb += svdec.cr_in.eq(fromreg.data) # 3-bit (CR0/BC/BFA)
1401 with m.If(svdec.isvec):
1402 # check if this is CR0 or CR1: treated differently
1403 # (does not "listen" to EXTRA2/3 spec for a start)
1404 # also: the CRs start from completely different locations
1405 step = dststep if out else srcstep
1406 with m.If(cr.sv_override == 1): # CR0
1407 offs = SVP64CROffs.CR0
1408 comb += to_reg.data.eq(step+offs)
1409 with m.Elif(cr.sv_override == 2): # CR1
1410 offs = SVP64CROffs.CR1
1411 comb += to_reg.data.eq(step+1)
1412 with m.Else():
1413 comb += to_reg.data.eq(step+svdec.cr_out) # 7-bit out
1414 with m.Else():
1415 comb += to_reg.data.eq(svdec.cr_out) # 7-bit output
1416 comb += to_reg.ok.eq(fromreg.ok)
1417
1418 # sigh must determine if RA is nonzero (7 bit)
1419 comb += self.sv_a_nz.eq(e.read_reg1.data != Const(0, 7))
1420 else:
1421 # connect up to/from read/write GPRs
1422 for to_reg, fromreg in ((e.read_reg1, dec_a.reg_out),
1423 (e.read_reg2, dec_b.reg_out),
1424 (e.read_reg3, dec_c.reg_out),
1425 (e.write_reg, dec_o.reg_out),
1426 (e.write_ea, dec_o2.reg_out)):
1427 comb += to_reg.data.eq(fromreg.data)
1428 comb += to_reg.ok.eq(fromreg.ok)
1429
1430 # connect up to/from read/write CRs
1431 for to_reg, cr, name in (
1432 (e.read_cr1, self.dec_cr_in, "cr_bitfield", ),
1433 (e.read_cr2, self.dec_cr_in, "cr_bitfield_b", ),
1434 (e.read_cr3, self.dec_cr_in, "cr_bitfield_o", ),
1435 (e.write_cr, self.dec_cr_out, "cr_bitfield", )):
1436 fromreg = getattr(cr, name)
1437 comb += to_reg.data.eq(fromreg.data)
1438 comb += to_reg.ok.eq(fromreg.ok)
1439
1440 if self.svp64_en:
1441 comb += self.rm_dec.ldst_ra_vec.eq(self.in1_isvec) # RA is vector
1442
1443 # SPRs out
1444 comb += e.read_spr1.eq(dec_a.spr_out)
1445 comb += e.write_spr.eq(dec_o.spr_out)
1446
1447 # Fast regs out including SRR0/1/SVSRR0
1448 comb += e.read_fast1.eq(dec_a.fast_out)
1449 comb += e.read_fast2.eq(dec_b.fast_out)
1450 comb += e.write_fast1.eq(dec_o.fast_out) # SRR0 (OP_RFID)
1451 comb += e.write_fast2.eq(dec_o2.fast_out) # SRR1 (ditto)
1452 comb += e.write_fast3.eq(dec_o2.fast_out3) # SVSRR0 (ditto)
1453
1454 # sigh this is exactly the sort of thing for which the
1455 # decoder is designed to not need. MTSPR, MFSPR and others need
1456 # access to the XER bits. however setting e.oe is not appropriate
1457 internal_op = self.op_get("internal_op")
1458 with m.If(internal_op == MicrOp.OP_MFSPR):
1459 comb += e.xer_in.eq(0b111) # SO, CA, OV
1460 with m.If(internal_op == MicrOp.OP_CMP):
1461 comb += e.xer_in.eq(1<<XERRegsEnum.SO) # SO
1462 with m.If(internal_op == MicrOp.OP_MTSPR):
1463 comb += e.xer_out.eq(1)
1464
1465 # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
1466 with m.If(op.internal_op == MicrOp.OP_TRAP):
1467 # *DO NOT* call self.trap here. that would reset absolutely
1468 # everything including destroying read of RA and RB.
1469 comb += self.do_copy("trapaddr", 0x70) # strip first nibble
1470
1471 ####################
1472 # ok so the instruction's been decoded, blah blah, however
1473 # now we need to determine if it's actually going to go ahead...
1474 # *or* if in fact it's a privileged operation, whether there's
1475 # an external interrupt, etc. etc. this is a simple priority
1476 # if-elif-elif sequence. decrement takes highest priority,
1477 # EINT next highest, privileged operation third.
1478
1479 # check if instruction is privileged
1480 is_priv_insn = instr_is_priv(m, op.internal_op, e.do.insn)
1481
1482 # different IRQ conditions
1483 ext_irq_ok = Signal()
1484 dec_irq_ok = Signal()
1485 priv_ok = Signal()
1486 illeg_ok = Signal()
1487 ldst_exc = self.ldst_exc
1488
1489 comb += ext_irq_ok.eq(ext_irq & msr[MSR.EE]) # v3.0B p944 (MSR.EE)
1490 comb += dec_irq_ok.eq(dec_spr[63] & msr[MSR.EE]) # 6.5.11 p1076
1491 comb += priv_ok.eq(is_priv_insn & msr[MSR.PR])
1492 comb += illeg_ok.eq(op.internal_op == MicrOp.OP_ILLEGAL)
1493
1494 # LD/ST exceptions. TestIssuer copies the exception info at us
1495 # after a failed LD/ST.
1496 with m.If(ldst_exc.happened):
1497 with m.If(ldst_exc.alignment):
1498 self.trap(m, TT.PRIV, 0x600)
1499 with m.Elif(ldst_exc.instr_fault):
1500 with m.If(ldst_exc.segment_fault):
1501 self.trap(m, TT.PRIV, 0x480)
1502 with m.Else():
1503 # pass exception info to trap to create SRR1
1504 self.trap(m, TT.MEMEXC, 0x400, ldst_exc)
1505 with m.Else():
1506 with m.If(ldst_exc.segment_fault):
1507 self.trap(m, TT.PRIV, 0x380)
1508 with m.Else():
1509 self.trap(m, TT.PRIV, 0x300)
1510
1511 # decrement counter (v3.0B p1099): TODO 32-bit version (MSR.LPCR)
1512 with m.Elif(dec_irq_ok):
1513 self.trap(m, TT.DEC, 0x900) # v3.0B 6.5 p1065
1514
1515 # external interrupt? only if MSR.EE set
1516 with m.Elif(ext_irq_ok):
1517 self.trap(m, TT.EINT, 0x500)
1518
1519 # privileged instruction trap
1520 with m.Elif(priv_ok):
1521 self.trap(m, TT.PRIV, 0x700)
1522
1523 # illegal instruction must redirect to trap. this is done by
1524 # *overwriting* the decoded instruction and starting again.
1525 # (note: the same goes for interrupts and for privileged operations,
1526 # just with different trapaddr and traptype)
1527 with m.Elif(illeg_ok):
1528 # illegal instruction trap
1529 self.trap(m, TT.ILLEG, 0x700)
1530
1531 # no exception, just copy things to the output
1532 with m.Else():
1533 comb += e_out.eq(e)
1534
1535 ####################
1536 # follow-up after trap/irq to set up SRR0/1
1537
1538 # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
1539 # Note: OP_SC could actually be modified to just be a trap
1540 with m.If((do_out.insn_type == MicrOp.OP_TRAP) |
1541 (do_out.insn_type == MicrOp.OP_SC)):
1542 # TRAP write fast1 = SRR0
1543 comb += e_out.write_fast1.data.eq(FastRegsEnum.SRR0) # SRR0
1544 comb += e_out.write_fast1.ok.eq(1)
1545 # TRAP write fast2 = SRR1
1546 comb += e_out.write_fast2.data.eq(FastRegsEnum.SRR1) # SRR1
1547 comb += e_out.write_fast2.ok.eq(1)
1548 # TRAP write fast2 = SRR1
1549 comb += e_out.write_fast3.data.eq(FastRegsEnum.SVSRR0) # SVSRR0
1550 comb += e_out.write_fast3.ok.eq(1)
1551
1552 # RFID: needs to read SRR0/1
1553 with m.If(do_out.insn_type == MicrOp.OP_RFID):
1554 # TRAP read fast1 = SRR0
1555 comb += e_out.read_fast1.data.eq(FastRegsEnum.SRR0) # SRR0
1556 comb += e_out.read_fast1.ok.eq(1)
1557 # TRAP read fast2 = SRR1
1558 comb += e_out.read_fast2.data.eq(FastRegsEnum.SRR1) # SRR1
1559 comb += e_out.read_fast2.ok.eq(1)
1560 # TRAP read fast2 = SVSRR0
1561 comb += e_out.read_fast3.data.eq(FastRegsEnum.SVSRR0) # SVSRR0
1562 comb += e_out.read_fast3.ok.eq(1)
1563
1564 # annoying simulator bug.
1565 # asmcode may end up getting used for perfcounters?
1566 asmcode = self.op_get("asmcode")
1567 if hasattr(e_out, "asmcode") and asmcode is not None:
1568 comb += e_out.asmcode.eq(asmcode)
1569
1570 return m
1571
1572 def trap(self, m, traptype, trapaddr, ldst_exc=None):
1573 """trap: this basically "rewrites" the decoded instruction as a trap
1574 """
1575 comb = m.d.comb
1576 e = self.e
1577 comb += e.eq(0) # reset eeeeeverything
1578
1579 # start again
1580 comb += self.do_copy("insn", self.dec.opcode_in, True)
1581 comb += self.do_copy("insn_type", MicrOp.OP_TRAP, True)
1582 comb += self.do_copy("fn_unit", Function.TRAP, True)
1583 comb += self.do_copy("trapaddr", trapaddr >> 4, True) # bottom 4 bits
1584 comb += self.do_copy("traptype", traptype, True) # request type
1585 comb += self.do_copy("ldst_exc", ldst_exc, True) # request type
1586 comb += self.do_copy("msr", self.state.msr, True) # copy of MSR "state"
1587 comb += self.do_copy("cia", self.state.pc, True) # copy of PC "state"
1588 comb += self.do_copy("svstate", self.state.svstate, True) # SVSTATE
1589
1590
1591
1592 def get_rdflags(e, cu):
1593 rdl = []
1594 for idx in range(cu.n_src):
1595 regfile, regname, _ = cu.get_in_spec(idx)
1596 rdflag, read = regspec_decode_read(e, regfile, regname)
1597 rdl.append(rdflag)
1598 log("rdflags", rdl)
1599 return Cat(*rdl)
1600
1601
1602 if __name__ == '__main__':
1603 pdecode = create_pdecode()
1604 dec2 = PowerDecode2(pdecode, svp64_en=True)
1605 vl = rtlil.convert(dec2, ports=dec2.ports() + pdecode.ports())
1606 with open("dec2.il", "w") as f:
1607 f.write(vl)