Fix broken unit tests in test_caller
[soc.git] / src / soc / decoder / power_decoder2.py
1 """Power ISA Decoder second stage
2
3 based on Anton Blanchard microwatt decode2.vhdl
4
5 """
6 from nmigen import Module, Elaboratable, Signal, Mux, Const, Cat, Repl, Record
7 from nmigen.cli import rtlil
8
9 from nmutil.iocontrol import RecordObject
10 from nmutil.extend import exts
11
12 from soc.decoder.power_decoder import create_pdecode
13 from soc.decoder.power_enums import (InternalOp, CryIn, Function,
14 CRInSel, CROutSel,
15 LdstLen, In1Sel, In2Sel, In3Sel,
16 OutSel, SPR, RC)
17
18
19 class DecodeA(Elaboratable):
20 """DecodeA from instruction
21
22 decodes register RA, whether immediate-zero, implicit and
23 explicit CSRs
24 """
25
26 def __init__(self, dec):
27 self.dec = dec
28 self.sel_in = Signal(In1Sel, reset_less=True)
29 self.insn_in = Signal(32, reset_less=True)
30 self.reg_out = Data(5, name="reg_a")
31 self.immz_out = Signal(reset_less=True)
32 self.spr_out = Data(10, "spr_a")
33
34 def elaborate(self, platform):
35 m = Module()
36 comb = m.d.comb
37
38 # select Register A field
39 ra = Signal(5, reset_less=True)
40 comb += ra.eq(self.dec.RA)
41 with m.If((self.sel_in == In1Sel.RA) |
42 ((self.sel_in == In1Sel.RA_OR_ZERO) &
43 (ra != Const(0, 5)))):
44 comb += self.reg_out.data.eq(ra)
45 comb += self.reg_out.ok.eq(1)
46
47 # zero immediate requested
48 with m.If((self.sel_in == In1Sel.RA_OR_ZERO) &
49 (self.reg_out.data == Const(0, 5))):
50 comb += self.immz_out.eq(1)
51
52 # decode SPR1 based on instruction type
53 op = self.dec.op
54 # BC or BCREG: potential implicit register (CTR)
55 with m.If((op.internal_op == InternalOp.OP_BC) |
56 (op.internal_op == InternalOp.OP_BCREG)):
57 with m.If(~self.dec.BO[2]): # 3.0B p38 BO2=0, use CTR reg
58 comb += self.spr_out.data.eq(SPR.CTR) # constant: CTR
59 comb += self.spr_out.ok.eq(1)
60 # MFSPR or MTSPR: move-from / move-to SPRs
61 with m.If((op.internal_op == InternalOp.OP_MFSPR) |
62 (op.internal_op == InternalOp.OP_MTSPR)):
63 comb += self.spr_out.data.eq(self.dec.SPR) # SPR field, XFX
64 comb += self.spr_out.ok.eq(1)
65
66 return m
67
68
69 class Data(Record):
70
71 def __init__(self, width, name):
72 name_ok = "%s_ok" % name
73 layout = ((name, width), (name_ok, 1))
74 Record.__init__(self, layout)
75 self.data = getattr(self, name) # convenience
76 self.ok = getattr(self, name_ok) # convenience
77 self.data.reset_less = True # grrr
78 self.reset_less = True # grrr
79
80 def ports(self):
81 return [self.data, self.ok]
82
83
84 class DecodeB(Elaboratable):
85 """DecodeB from instruction
86
87 decodes register RB, different forms of immediate (signed, unsigned),
88 and implicit SPRs
89 """
90
91 def __init__(self, dec):
92 self.dec = dec
93 self.sel_in = Signal(In2Sel, reset_less=True)
94 self.insn_in = Signal(32, reset_less=True)
95 self.reg_out = Data(5, "reg_b")
96 self.imm_out = Data(64, "imm_b")
97 self.spr_out = Data(10, "spr_b")
98
99 def elaborate(self, platform):
100 m = Module()
101 comb = m.d.comb
102
103 # select Register B field
104 with m.Switch(self.sel_in):
105 with m.Case(In2Sel.RB):
106 comb += self.reg_out.data.eq(self.dec.RB)
107 comb += self.reg_out.ok.eq(1)
108 with m.Case(In2Sel.CONST_UI):
109 comb += self.imm_out.data.eq(self.dec.UI)
110 comb += self.imm_out.ok.eq(1)
111 with m.Case(In2Sel.CONST_SI): # TODO: sign-extend here?
112 comb += self.imm_out.data.eq(
113 exts(self.dec.SI, 16, 64))
114 comb += self.imm_out.ok.eq(1)
115 with m.Case(In2Sel.CONST_UI_HI):
116 comb += self.imm_out.data.eq(self.dec.UI<<16)
117 comb += self.imm_out.ok.eq(1)
118 with m.Case(In2Sel.CONST_SI_HI): # TODO: sign-extend here?
119 comb += self.imm_out.data.eq(self.dec.SI<<16)
120 comb += self.imm_out.data.eq(
121 exts(self.dec.SI << 16, 32, 64))
122 comb += self.imm_out.ok.eq(1)
123 with m.Case(In2Sel.CONST_LI):
124 comb += self.imm_out.data.eq(self.dec.LI<<2)
125 comb += self.imm_out.ok.eq(1)
126 with m.Case(In2Sel.CONST_BD):
127 comb += self.imm_out.data.eq(self.dec.BD<<2)
128 comb += self.imm_out.ok.eq(1)
129 with m.Case(In2Sel.CONST_DS):
130 comb += self.imm_out.data.eq(self.dec.DS<<2)
131 comb += self.imm_out.ok.eq(1)
132 with m.Case(In2Sel.CONST_M1):
133 comb += self.imm_out.data.eq(~Const(0, 64)) # all 1s
134 comb += self.imm_out.ok.eq(1)
135 with m.Case(In2Sel.CONST_SH):
136 comb += self.imm_out.data.eq(self.dec.sh)
137 comb += self.imm_out.ok.eq(1)
138 with m.Case(In2Sel.CONST_SH32):
139 comb += self.imm_out.data.eq(self.dec.SH32)
140 comb += self.imm_out.ok.eq(1)
141
142 # decode SPR2 based on instruction type
143 op = self.dec.op
144 # BCREG implicitly uses CTR or LR for 2nd reg
145 with m.If(op.internal_op == InternalOp.OP_BCREG):
146 with m.If(self.dec.FormXL.XO[9]): # 3.0B p38 top bit of XO
147 comb += self.spr_out.data.eq(SPR.CTR)
148 with m.Else():
149 comb += self.spr_out.data.eq(SPR.LR)
150 comb += self.spr_out.ok.eq(1)
151
152 return m
153
154
155 class DecodeC(Elaboratable):
156 """DecodeC from instruction
157
158 decodes register RC
159 """
160
161 def __init__(self, dec):
162 self.dec = dec
163 self.sel_in = Signal(In3Sel, reset_less=True)
164 self.insn_in = Signal(32, reset_less=True)
165 self.reg_out = Data(5, "reg_c")
166
167 def elaborate(self, platform):
168 m = Module()
169 comb = m.d.comb
170
171 # select Register C field
172 with m.If(self.sel_in == In3Sel.RS):
173 comb += self.reg_out.data.eq(self.dec.RS)
174 comb += self.reg_out.ok.eq(1)
175
176 return m
177
178
179 class DecodeOut(Elaboratable):
180 """DecodeOut from instruction
181
182 decodes output register RA, RT or SPR
183 """
184
185 def __init__(self, dec):
186 self.dec = dec
187 self.sel_in = Signal(OutSel, reset_less=True)
188 self.insn_in = Signal(32, reset_less=True)
189 self.reg_out = Data(5, "reg_o")
190 self.spr_out = Data(10, "spr_o")
191
192 def elaborate(self, platform):
193 m = Module()
194 comb = m.d.comb
195
196 # select Register out field
197 with m.Switch(self.sel_in):
198 with m.Case(OutSel.RT):
199 comb += self.reg_out.data.eq(self.dec.RT)
200 comb += self.reg_out.ok.eq(1)
201 with m.Case(OutSel.RA):
202 comb += self.reg_out.data.eq(self.dec.RA)
203 comb += self.reg_out.ok.eq(1)
204 with m.Case(OutSel.SPR):
205 comb += self.spr_out.data.eq(self.dec.SPR) # from XFX
206 comb += self.spr_out.ok.eq(1)
207
208 return m
209
210
211 class DecodeRC(Elaboratable):
212 """DecodeRc from instruction
213
214 decodes Record bit Rc
215 """
216 def __init__(self, dec):
217 self.dec = dec
218 self.sel_in = Signal(RC, reset_less=True)
219 self.insn_in = Signal(32, reset_less=True)
220 self.rc_out = Data(1, "rc")
221
222 def elaborate(self, platform):
223 m = Module()
224 comb = m.d.comb
225
226 # select Record bit out field
227 with m.Switch(self.sel_in):
228 with m.Case(RC.RC):
229 comb += self.rc_out.data.eq(self.dec.Rc)
230 comb += self.rc_out.ok.eq(1)
231 with m.Case(RC.ONE):
232 comb += self.rc_out.data.eq(1)
233 comb += self.rc_out.ok.eq(1)
234 with m.Case(RC.NONE):
235 comb += self.rc_out.data.eq(0)
236 comb += self.rc_out.ok.eq(1)
237
238 return m
239
240
241 class DecodeOE(Elaboratable):
242 """DecodeOE from instruction
243
244 decodes OE field: uses RC decode detection which might not be good
245
246 -- For now, use "rc" in the decode table to decide whether oe exists.
247 -- This is not entirely correct architecturally: For mulhd and
248 -- mulhdu, the OE field is reserved. It remains to be seen what an
249 -- actual POWER9 does if we set it on those instructions, for now we
250 -- test that further down when assigning to the multiplier oe input.
251 """
252 def __init__(self, dec):
253 self.dec = dec
254 self.sel_in = Signal(RC, reset_less=True)
255 self.insn_in = Signal(32, reset_less=True)
256 self.oe_out = Data(1, "oe")
257
258 def elaborate(self, platform):
259 m = Module()
260 comb = m.d.comb
261
262 # select OE bit out field
263 with m.Switch(self.sel_in):
264 with m.Case(RC.RC):
265 comb += self.oe_out.data.eq(self.dec.OE)
266 comb += self.oe_out.ok.eq(1)
267
268 return m
269
270 class DecodeCRIn(Elaboratable):
271 """Decodes input CR from instruction"""
272
273 def __init__(self, dec):
274 self.dec = dec
275 self.sel_in = Signal(CRInSel, reset_less=True)
276 self.insn_in = Signal(32, reset_less=True)
277 self.cr_bitfield = Data(3, "cr_bitfield")
278 self.cr_bitfield_b = Data(3, "cr_bitfield_b")
279 self.whole_reg = Signal(reset_less=True)
280
281 def elaborate(self, platform):
282 m = Module()
283 comb = m.d.comb
284
285 comb += self.cr_bitfield.ok.eq(0)
286 comb += self.cr_bitfield_b.ok.eq(0)
287 comb += self.whole_reg.eq(0)
288 with m.Switch(self.sel_in):
289 with m.Case(CRInSel.NONE):
290 pass # No bitfield activated
291 with m.Case(CRInSel.CR0):
292 comb += self.cr_bitfield.data.eq(0)
293 comb += self.cr_bitfield.ok.eq(1)
294 with m.Case(CRInSel.BI):
295 comb += self.cr_bitfield.data.eq(self.dec.BI[3:5])
296 comb += self.cr_bitfield.ok.eq(1)
297 with m.Case(CRInSel.BFA):
298 comb += self.cr_bitfield.data.eq(self.dec.FormX.BFA[0:-1])
299 comb += self.cr_bitfield.ok.eq(1)
300 with m.Case(CRInSel.BA_BB):
301 comb += self.cr_bitfield.data.eq(self.dec.BA[3:5])
302 comb += self.cr_bitfield.ok.eq(1)
303 comb += self.cr_bitfield_b.data.eq(self.dec.BB[3:5])
304 comb += self.cr_bitfield_b.ok.eq(1)
305 with m.Case(CRInSel.BC):
306 comb += self.cr_bitfield.data.eq(self.dec.BC[0:-1])
307 comb += self.cr_bitfield.ok.eq(1)
308 with m.Case(CRInSel.WHOLE_REG):
309 comb += self.whole_reg.eq(1)
310
311 return m
312
313 class DecodeCROut(Elaboratable):
314 """Decodes input CR from instruction"""
315
316 def __init__(self, dec):
317 self.dec = dec
318 self.sel_in = Signal(CROutSel, reset_less=True)
319 self.insn_in = Signal(32, reset_less=True)
320 self.cr_bitfield = Data(3, "cr_bitfield")
321 self.whole_reg = Signal(reset_less=True)
322
323 def elaborate(self, platform):
324 m = Module()
325 comb = m.d.comb
326
327 comb += self.cr_bitfield.ok.eq(0)
328 comb += self.whole_reg.eq(0)
329 with m.Switch(self.sel_in):
330 with m.Case(CROutSel.NONE):
331 pass # No bitfield activated
332 with m.Case(CROutSel.CR0):
333 comb += self.cr_bitfield.data.eq(0)
334 comb += self.cr_bitfield.ok.eq(1)
335 with m.Case(CROutSel.BF):
336 comb += self.cr_bitfield.data.eq(self.dec.FormX.BF[0:-1])
337 comb += self.cr_bitfield.ok.eq(1)
338 with m.Case(CROutSel.BT):
339 comb += self.cr_bitfield.data.eq(self.dec.FormXL.BT[3:5])
340 comb += self.cr_bitfield.ok.eq(1)
341 with m.Case(CROutSel.WHOLE_REG):
342 comb += self.whole_reg.eq(1)
343
344 return m
345
346 class XerBits:
347 def __init__(self):
348 self.ca = Signal(2, reset_less=True)
349 self.ov = Signal(2, reset_less=True)
350 self.so = Signal(reset_less=True)
351
352 def ports(self):
353 return [self.ca, self.ov, self.so]
354
355
356 class Decode2ToExecute1Type(RecordObject):
357
358 def __init__(self, name=None):
359
360 RecordObject.__init__(self, name=name)
361
362 self.valid = Signal(reset_less=True)
363 self.insn_type = Signal(InternalOp, reset_less=True)
364 self.fn_unit = Signal(Function, reset_less=True)
365 self.nia = Signal(64, reset_less=True)
366 self.write_reg = Data(5, name="rego")
367 self.read_reg1 = Data(5, name="reg1")
368 self.read_reg2 = Data(5, name="reg2")
369 self.read_reg3 = Data(5, name="reg3")
370 self.imm_data = Data(64, name="imm")
371 self.write_spr = Data(10, name="spro")
372 self.read_spr1 = Data(10, name="spr1")
373 self.read_spr2 = Data(10, name="spr2")
374
375 self.read_cr1 = Data(3, name="cr_in1")
376 self.read_cr2 = Data(3, name="cr_in2")
377 self.read_cr_whole = Signal(reset_less=True)
378 self.write_cr = Data(3, name="cr_out")
379 self.write_cr_whole = Signal(reset_less=True)
380 #self.read_data1 = Signal(64, reset_less=True)
381 #self.read_data2 = Signal(64, reset_less=True)
382 #self.read_data3 = Signal(64, reset_less=True)
383 #self.cr = Signal(32, reset_less=True) # NO: this is from the CR SPR
384 #self.xerc = XerBits() # NO: this is from the XER SPR
385 self.lk = Signal(reset_less=True)
386 self.rc = Data(1, "rc")
387 self.oe = Data(1, "oe")
388 self.invert_a = Signal(reset_less=True)
389 self.zero_a = Signal(reset_less=True)
390 self.invert_out = Signal(reset_less=True)
391 self.input_carry = Signal(CryIn, reset_less=True)
392 self.output_carry = Signal(reset_less=True)
393 self.input_cr = Signal(reset_less=True)
394 self.output_cr = Signal(reset_less=True)
395 self.is_32bit = Signal(reset_less=True)
396 self.is_signed = Signal(reset_less=True)
397 self.insn = Signal(32, reset_less=True)
398 self.data_len = Signal(4, reset_less=True) # bytes
399 self.byte_reverse = Signal(reset_less=True)
400 self.sign_extend = Signal(reset_less=True)# do we need this?
401 self.update = Signal(reset_less=True) # LD/ST is "update" variant
402
403
404 class PowerDecode2(Elaboratable):
405
406 def __init__(self, dec):
407
408 self.dec = dec
409 self.e = Decode2ToExecute1Type()
410
411 def ports(self):
412 return self.dec.ports() + self.e.ports()
413
414 def elaborate(self, platform):
415 m = Module()
416 comb = m.d.comb
417
418 # set up submodule decoders
419 m.submodules.dec = self.dec
420 m.submodules.dec_a = dec_a = DecodeA(self.dec)
421 m.submodules.dec_b = dec_b = DecodeB(self.dec)
422 m.submodules.dec_c = dec_c = DecodeC(self.dec)
423 m.submodules.dec_o = dec_o = DecodeOut(self.dec)
424 m.submodules.dec_rc = dec_rc = DecodeRC(self.dec)
425 m.submodules.dec_oe = dec_oe = DecodeOE(self.dec)
426 m.submodules.dec_cr_in = dec_cr_in = DecodeCRIn(self.dec)
427 m.submodules.dec_cr_out = dec_cr_out = DecodeCROut(self.dec)
428
429 # copy instruction through...
430 for i in [self.e.insn, dec_a.insn_in, dec_b.insn_in,
431 dec_c.insn_in, dec_o.insn_in, dec_rc.insn_in,
432 dec_oe.insn_in, dec_cr_in.insn_in, dec_cr_out.insn_in]:
433 comb += i.eq(self.dec.opcode_in)
434
435 # ...and subdecoders' input fields
436 comb += dec_a.sel_in.eq(self.dec.op.in1_sel)
437 comb += dec_b.sel_in.eq(self.dec.op.in2_sel)
438 comb += dec_c.sel_in.eq(self.dec.op.in3_sel)
439 comb += dec_o.sel_in.eq(self.dec.op.out_sel)
440 comb += dec_rc.sel_in.eq(self.dec.op.rc_sel)
441 comb += dec_oe.sel_in.eq(self.dec.op.rc_sel) # XXX should be OE sel
442 comb += dec_cr_in.sel_in.eq(self.dec.op.cr_in)
443 comb += dec_cr_out.sel_in.eq(self.dec.op.cr_out)
444
445 # decode LD/ST length
446 with m.Switch(self.dec.op.ldst_len):
447 with m.Case(LdstLen.is1B):
448 comb += self.e.data_len.eq(1)
449 with m.Case(LdstLen.is2B):
450 comb += self.e.data_len.eq(2)
451 with m.Case(LdstLen.is4B):
452 comb += self.e.data_len.eq(4)
453 with m.Case(LdstLen.is8B):
454 comb += self.e.data_len.eq(8)
455
456 comb += self.e.nia.eq(0) # XXX TODO
457 comb += self.e.valid.eq(0) # XXX TODO
458 fu = self.dec.op.function_unit
459 itype = Mux(fu == Function.NONE,
460 InternalOp.OP_ILLEGAL,
461 self.dec.op.internal_op)
462 comb += self.e.insn_type.eq(itype)
463 comb += self.e.fn_unit.eq(fu)
464
465 # registers a, b, c and out
466 comb += self.e.read_reg1.eq(dec_a.reg_out)
467 comb += self.e.read_reg2.eq(dec_b.reg_out)
468 comb += self.e.read_reg3.eq(dec_c.reg_out)
469 comb += self.e.write_reg.eq(dec_o.reg_out)
470 comb += self.e.imm_data.eq(dec_b.imm_out) # immediate in RB (usually)
471 comb += self.e.zero_a.eq(dec_a.immz_out) # RA==0 detected
472
473 # rc and oe out
474 comb += self.e.rc.eq(dec_rc.rc_out)
475 comb += self.e.oe.eq(dec_oe.oe_out)
476
477 # SPRs out
478 comb += self.e.read_spr1.eq(dec_a.spr_out)
479 comb += self.e.read_spr2.eq(dec_b.spr_out)
480 comb += self.e.write_spr.eq(dec_o.spr_out)
481
482 comb += self.e.read_cr1.eq(dec_cr_in.cr_bitfield)
483 comb += self.e.read_cr2.eq(dec_cr_in.cr_bitfield_b)
484 comb += self.e.read_cr_whole.eq(dec_cr_in.whole_reg)
485
486 comb += self.e.write_cr.eq(dec_cr_out.cr_bitfield)
487 comb += self.e.write_cr_whole.eq(dec_cr_out.whole_reg)
488
489 # decoded/selected instruction flags
490 comb += self.e.invert_a.eq(self.dec.op.inv_a)
491 comb += self.e.invert_out.eq(self.dec.op.inv_out)
492 comb += self.e.input_carry.eq(self.dec.op.cry_in) # carry comes in
493 comb += self.e.output_carry.eq(self.dec.op.cry_out) # carry goes out
494 comb += self.e.is_32bit.eq(self.dec.op.is_32b)
495 comb += self.e.is_signed.eq(self.dec.op.sgn)
496 with m.If(self.dec.op.lk):
497 comb += self.e.lk.eq(self.dec.LK) # XXX TODO: accessor
498
499 comb += self.e.byte_reverse.eq(self.dec.op.br)
500 comb += self.e.sign_extend.eq(self.dec.op.sgn_ext)
501 comb += self.e.update.eq(self.dec.op.upd) # LD/ST "update" mode
502
503
504
505 # These should be removed eventually
506 comb += self.e.input_cr.eq(self.dec.op.cr_in) # condition reg comes in
507 comb += self.e.output_cr.eq(self.dec.op.cr_out) # condition reg goes in
508
509
510 return m
511
512
513 if __name__ == '__main__':
514 pdecode = create_pdecode()
515 dec2 = PowerDecode2(pdecode)
516 vl = rtlil.convert(dec2, ports=dec2.ports() + pdecode.ports())
517 with open("dec2.il", "w") as f:
518 f.write(vl)
519