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