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