comment DecodeCRIn and DecodeCROut, gratuitously
[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 CR indices - insn fields - (not the data *in* the CR) require only 3
274 bits because they refer to CR0-CR7
275 """
276
277 def __init__(self, dec):
278 self.dec = dec
279 self.sel_in = Signal(CRInSel, reset_less=True)
280 self.insn_in = Signal(32, reset_less=True)
281 self.cr_bitfield = Data(3, "cr_bitfield")
282 self.cr_bitfield_b = Data(3, "cr_bitfield_b")
283 self.whole_reg = Signal(reset_less=True)
284
285 def elaborate(self, platform):
286 m = Module()
287 comb = m.d.comb
288
289 comb += self.cr_bitfield.ok.eq(0)
290 comb += self.cr_bitfield_b.ok.eq(0)
291 comb += self.whole_reg.eq(0)
292 with m.Switch(self.sel_in):
293 with m.Case(CRInSel.NONE):
294 pass # No bitfield activated
295 with m.Case(CRInSel.CR0):
296 comb += self.cr_bitfield.data.eq(0)
297 comb += self.cr_bitfield.ok.eq(1)
298 with m.Case(CRInSel.BI):
299 comb += self.cr_bitfield.data.eq(self.dec.BI[3:5])
300 comb += self.cr_bitfield.ok.eq(1)
301 with m.Case(CRInSel.BFA):
302 comb += self.cr_bitfield.data.eq(self.dec.FormX.BFA[0:-1])
303 comb += self.cr_bitfield.ok.eq(1)
304 with m.Case(CRInSel.BA_BB):
305 comb += self.cr_bitfield.data.eq(self.dec.BA[3:5])
306 comb += self.cr_bitfield.ok.eq(1)
307 comb += self.cr_bitfield_b.data.eq(self.dec.BB[3:5])
308 comb += self.cr_bitfield_b.ok.eq(1)
309 with m.Case(CRInSel.BC):
310 comb += self.cr_bitfield.data.eq(self.dec.BC[0:-1])
311 comb += self.cr_bitfield.ok.eq(1)
312 with m.Case(CRInSel.WHOLE_REG):
313 comb += self.whole_reg.eq(1)
314
315 return m
316
317
318 class DecodeCROut(Elaboratable):
319 """Decodes input CR from instruction
320
321 CR indices - insn fields - (not the data *in* the CR) require only 3
322 bits because they refer to CR0-CR7
323 """
324
325 def __init__(self, dec):
326 self.dec = dec
327 self.sel_in = Signal(CROutSel, reset_less=True)
328 self.insn_in = Signal(32, reset_less=True)
329 self.cr_bitfield = Data(3, "cr_bitfield")
330 self.whole_reg = Signal(reset_less=True)
331
332 def elaborate(self, platform):
333 m = Module()
334 comb = m.d.comb
335
336 comb += self.cr_bitfield.ok.eq(0)
337 comb += self.whole_reg.eq(0)
338 with m.Switch(self.sel_in):
339 with m.Case(CROutSel.NONE):
340 pass # No bitfield activated
341 with m.Case(CROutSel.CR0):
342 comb += self.cr_bitfield.data.eq(0)
343 comb += self.cr_bitfield.ok.eq(1)
344 with m.Case(CROutSel.BF):
345 comb += self.cr_bitfield.data.eq(self.dec.FormX.BF[0:-1])
346 comb += self.cr_bitfield.ok.eq(1)
347 with m.Case(CROutSel.BT):
348 comb += self.cr_bitfield.data.eq(self.dec.FormXL.BT[3:5])
349 comb += self.cr_bitfield.ok.eq(1)
350 with m.Case(CROutSel.WHOLE_REG):
351 comb += self.whole_reg.eq(1)
352
353 return m
354
355
356 class XerBits:
357 def __init__(self):
358 self.ca = Signal(2, reset_less=True)
359 self.ov = Signal(2, reset_less=True)
360 self.so = Signal(reset_less=True)
361
362 def ports(self):
363 return [self.ca, self.ov, self.so]
364
365
366 class Decode2ToExecute1Type(RecordObject):
367
368 def __init__(self, name=None):
369
370 RecordObject.__init__(self, name=name)
371
372 self.valid = Signal(reset_less=True)
373 self.insn_type = Signal(InternalOp, reset_less=True)
374 self.fn_unit = Signal(Function, reset_less=True)
375 self.nia = Signal(64, reset_less=True)
376 self.write_reg = Data(5, name="rego")
377 self.read_reg1 = Data(5, name="reg1")
378 self.read_reg2 = Data(5, name="reg2")
379 self.read_reg3 = Data(5, name="reg3")
380 self.imm_data = Data(64, name="imm")
381 self.write_spr = Data(10, name="spro")
382 self.read_spr1 = Data(10, name="spr1")
383 self.read_spr2 = Data(10, name="spr2")
384
385 self.read_cr1 = Data(3, name="cr_in1")
386 self.read_cr2 = Data(3, name="cr_in2")
387 self.read_cr_whole = Signal(reset_less=True)
388 self.write_cr = Data(3, name="cr_out")
389 self.write_cr_whole = Signal(reset_less=True)
390 #self.read_data1 = Signal(64, reset_less=True)
391 #self.read_data2 = Signal(64, reset_less=True)
392 #self.read_data3 = Signal(64, reset_less=True)
393 #self.cr = Signal(32, reset_less=True) # NO: this is from the CR SPR
394 #self.xerc = XerBits() # NO: this is from the XER SPR
395 self.lk = Signal(reset_less=True)
396 self.rc = Data(1, "rc")
397 self.oe = Data(1, "oe")
398 self.invert_a = Signal(reset_less=True)
399 self.zero_a = Signal(reset_less=True)
400 self.invert_out = Signal(reset_less=True)
401 self.input_carry = Signal(CryIn, reset_less=True)
402 self.output_carry = Signal(reset_less=True)
403 self.input_cr = Signal(reset_less=True) # instr. has a CR as input
404 self.output_cr = Signal(reset_less=True) # instr. has a CR as output
405 self.is_32bit = Signal(reset_less=True)
406 self.is_signed = Signal(reset_less=True)
407 self.insn = Signal(32, reset_less=True)
408 self.data_len = Signal(4, reset_less=True) # bytes
409 self.byte_reverse = Signal(reset_less=True)
410 self.sign_extend = Signal(reset_less=True)# do we need this?
411 self.update = Signal(reset_less=True) # LD/ST is "update" variant
412
413
414 class PowerDecode2(Elaboratable):
415
416 def __init__(self, dec):
417
418 self.dec = dec
419 self.e = Decode2ToExecute1Type()
420
421 def ports(self):
422 return self.dec.ports() + self.e.ports()
423
424 def elaborate(self, platform):
425 m = Module()
426 comb = m.d.comb
427
428 # set up submodule decoders
429 m.submodules.dec = self.dec
430 m.submodules.dec_a = dec_a = DecodeA(self.dec)
431 m.submodules.dec_b = dec_b = DecodeB(self.dec)
432 m.submodules.dec_c = dec_c = DecodeC(self.dec)
433 m.submodules.dec_o = dec_o = DecodeOut(self.dec)
434 m.submodules.dec_rc = dec_rc = DecodeRC(self.dec)
435 m.submodules.dec_oe = dec_oe = DecodeOE(self.dec)
436 m.submodules.dec_cr_in = dec_cr_in = DecodeCRIn(self.dec)
437 m.submodules.dec_cr_out = dec_cr_out = DecodeCROut(self.dec)
438
439 # copy instruction through...
440 for i in [self.e.insn, dec_a.insn_in, dec_b.insn_in,
441 dec_c.insn_in, dec_o.insn_in, dec_rc.insn_in,
442 dec_oe.insn_in, dec_cr_in.insn_in, dec_cr_out.insn_in]:
443 comb += i.eq(self.dec.opcode_in)
444
445 # ...and subdecoders' input fields
446 comb += dec_a.sel_in.eq(self.dec.op.in1_sel)
447 comb += dec_b.sel_in.eq(self.dec.op.in2_sel)
448 comb += dec_c.sel_in.eq(self.dec.op.in3_sel)
449 comb += dec_o.sel_in.eq(self.dec.op.out_sel)
450 comb += dec_rc.sel_in.eq(self.dec.op.rc_sel)
451 comb += dec_oe.sel_in.eq(self.dec.op.rc_sel) # XXX should be OE sel
452 comb += dec_cr_in.sel_in.eq(self.dec.op.cr_in)
453 comb += dec_cr_out.sel_in.eq(self.dec.op.cr_out)
454
455 # decode LD/ST length
456 with m.Switch(self.dec.op.ldst_len):
457 with m.Case(LdstLen.is1B):
458 comb += self.e.data_len.eq(1)
459 with m.Case(LdstLen.is2B):
460 comb += self.e.data_len.eq(2)
461 with m.Case(LdstLen.is4B):
462 comb += self.e.data_len.eq(4)
463 with m.Case(LdstLen.is8B):
464 comb += self.e.data_len.eq(8)
465
466 comb += self.e.nia.eq(0) # XXX TODO
467 comb += self.e.valid.eq(0) # XXX TODO
468 fu = self.dec.op.function_unit
469 itype = Mux(fu == Function.NONE,
470 InternalOp.OP_ILLEGAL,
471 self.dec.op.internal_op)
472 comb += self.e.insn_type.eq(itype)
473 comb += self.e.fn_unit.eq(fu)
474
475 # registers a, b, c and out
476 comb += self.e.read_reg1.eq(dec_a.reg_out)
477 comb += self.e.read_reg2.eq(dec_b.reg_out)
478 comb += self.e.read_reg3.eq(dec_c.reg_out)
479 comb += self.e.write_reg.eq(dec_o.reg_out)
480 comb += self.e.imm_data.eq(dec_b.imm_out) # immediate in RB (usually)
481 comb += self.e.zero_a.eq(dec_a.immz_out) # RA==0 detected
482
483 # rc and oe out
484 comb += self.e.rc.eq(dec_rc.rc_out)
485 comb += self.e.oe.eq(dec_oe.oe_out)
486
487 # SPRs out
488 comb += self.e.read_spr1.eq(dec_a.spr_out)
489 comb += self.e.read_spr2.eq(dec_b.spr_out)
490 comb += self.e.write_spr.eq(dec_o.spr_out)
491
492 comb += self.e.read_cr1.eq(dec_cr_in.cr_bitfield)
493 comb += self.e.read_cr2.eq(dec_cr_in.cr_bitfield_b)
494 comb += self.e.read_cr_whole.eq(dec_cr_in.whole_reg)
495
496 comb += self.e.write_cr.eq(dec_cr_out.cr_bitfield)
497 comb += self.e.write_cr_whole.eq(dec_cr_out.whole_reg)
498
499 # decoded/selected instruction flags
500 comb += self.e.invert_a.eq(self.dec.op.inv_a)
501 comb += self.e.invert_out.eq(self.dec.op.inv_out)
502 comb += self.e.input_carry.eq(self.dec.op.cry_in) # carry comes in
503 comb += self.e.output_carry.eq(self.dec.op.cry_out) # carry goes out
504 comb += self.e.is_32bit.eq(self.dec.op.is_32b)
505 comb += self.e.is_signed.eq(self.dec.op.sgn)
506 with m.If(self.dec.op.lk):
507 comb += self.e.lk.eq(self.dec.LK) # XXX TODO: accessor
508
509 comb += self.e.byte_reverse.eq(self.dec.op.br)
510 comb += self.e.sign_extend.eq(self.dec.op.sgn_ext)
511 comb += self.e.update.eq(self.dec.op.upd) # LD/ST "update" mode
512
513
514
515 # These should be removed eventually
516 comb += self.e.input_cr.eq(self.dec.op.cr_in) # condition reg comes in
517 comb += self.e.output_cr.eq(self.dec.op.cr_out) # condition reg goes in
518
519
520 return m
521
522
523 if __name__ == '__main__':
524 pdecode = create_pdecode()
525 dec2 = PowerDecode2(pdecode)
526 vl = rtlil.convert(dec2, ports=dec2.ports() + pdecode.ports())
527 with open("dec2.il", "w") as f:
528 f.write(vl)
529