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