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