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