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