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