1 """Power ISA Decoder second stage
3 based on Anton Blanchard microwatt decode2.vhdl
6 from nmigen
import Module
, Elaboratable
, Signal
, Mux
, Const
7 from nmigen
.cli
import rtlil
9 from power_decoder
import create_pdecode
10 from power_enums
import (InternalOp
, CryIn
, Function
, LdstLen
,
11 In1Sel
, In2Sel
, In3Sel
, OutSel
, SPR
, RC
)
14 class DecodeA(Elaboratable
):
15 """DecodeA from instruction
17 decodes register RA, whether immediate-zero, implicit and
21 def __init__(self
, 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)
31 def elaborate(self
, platform
):
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)
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)
47 # decode SPR1 based on instruction type
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
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
64 class DecodeB(Elaboratable
):
65 """DecodeB from instruction
67 decodes register RB, different forms of immediate (signed, unsigned),
71 def __init__(self
, 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)
82 def elaborate(self
, platform
):
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)
122 # decode SPR2 based on instruction type
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
)
129 self
.spr_out
.eq(SPR
.LR
)
135 class DecodeC(Elaboratable
):
136 """DecodeC from instruction
141 def __init__(self
, 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)
148 def elaborate(self
, platform
):
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)
160 class DecodeOut(Elaboratable
):
161 """DecodeOut from instruction
163 decodes output register RA, RT or SPR
166 def __init__(self
, 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)
175 def elaborate(self
, platform
):
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
194 class DecodeRC(Elaboratable
):
195 """DecodeRc from instruction
197 decodes Record bit Rc
199 def __init__(self
, 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)
206 def elaborate(self
, platform
):
210 # select Record bit out field
211 with m
.Switch(self
.sel_in
):
213 comb
+= self
.rc_out
.eq(self
.dec
.Rc
[0:-1])
214 comb
+= self
.rcok_out
.eq(1)
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)
225 class DecodeOE(Elaboratable
):
226 """DecodeOE from instruction
228 decodes OE field: uses RC decode detection which might not be good
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.
236 def __init__(self
, 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)
243 def elaborate(self
, platform
):
247 # select OE bit out field
248 with m
.Switch(self
.sel_in
):
250 comb
+= self
.oe_out
.eq(self
.dec
.OE
[0:-1])
251 comb
+= self
.oeok_out
.eq(1)
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)
265 return [self
.ca
, self
.ca32
, self
.ov
, self
.ov32
, self
.so
, ]
268 class Decode2ToExecute1Type
:
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?
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
,
311 self
.data_len
, self
.byte_reverse
, self
.sign_extend
,
312 self
.update
] + self
.xerc
.ports()
315 class PowerDecode2(Elaboratable
):
317 def __init__(self
, dec
):
320 self
.e
= Decode2ToExecute1Type()
323 return self
.dec
.ports() + self
.e
.ports()
325 def elaborate(self
, platform
):
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
)
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
,
342 comb
+= i
.eq(self
.dec
.opcode_in
)
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
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)
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
)
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
)
377 comb
+= self
.e
.rc
.eq(dec_rc
.rc_out
)
378 comb
+= self
.e
.oe
.eq(dec_oe
.oe_out
)
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
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
)
397 comb
+= self
.e
.input_cr
.eq(self
.dec
.op
.cr_in
)
398 comb
+= self
.e
.output_cr
.eq(self
.dec
.op
.cr_out
)
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
: