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 soc
.decoder
.power_decoder
import create_pdecode
10 from soc
.decoder
.power_enums
import (InternalOp
, CryIn
, Function
,
11 LdstLen
, In1Sel
, In2Sel
, In3Sel
,
15 class DecodeA(Elaboratable
):
16 """DecodeA from instruction
18 decodes register RA, whether immediate-zero, implicit and
22 def __init__(self
, 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")
30 def elaborate(self
, platform
):
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)
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)
48 # decode SPR1 based on instruction type
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)
66 def __init__(self
, width
, name
):
68 self
.data
= Signal(width
, name
=name
, reset_less
=True)
69 self
.ok
= Signal(name
="%s_ok" % name
, reset_less
=True)
72 return [self
.data
.eq(rhs
.data
),
76 return [self
.data
, self
.ok
]
79 class DecodeB(Elaboratable
):
80 """DecodeB from instruction
82 decodes register RB, different forms of immediate (signed, unsigned),
86 def __init__(self
, 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")
94 def elaborate(self
, platform
):
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)
134 # decode SPR2 based on instruction type
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
)
141 comb
+= self
.spr_out
.data
.eq(SPR
.LR
)
142 comb
+= self
.spr_out
.ok
.eq(1)
147 class DecodeC(Elaboratable
):
148 """DecodeC from instruction
153 def __init__(self
, 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")
159 def elaborate(self
, platform
):
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)
171 class DecodeOut(Elaboratable
):
172 """DecodeOut from instruction
174 decodes output register RA, RT or SPR
177 def __init__(self
, 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")
184 def elaborate(self
, platform
):
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)
203 class DecodeRC(Elaboratable
):
204 """DecodeRc from instruction
206 decodes Record bit Rc
208 def __init__(self
, 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")
214 def elaborate(self
, platform
):
218 # select Record bit out field
219 with m
.Switch(self
.sel_in
):
221 comb
+= self
.rc_out
.data
.eq(self
.dec
.Rc
[0:-1])
222 comb
+= self
.rc_out
.ok
.eq(1)
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)
232 class DecodeCR(Elaboratable
):
233 """DecodeRc from instruction
235 decodes Record bit Rc
237 def __init__(self
, dec
):
239 self
.cr_out
= Data(3, "cr")
240 self
.insn_in
= Signal(32, reset_less
=True)
241 self
.sel_in
= Signal(1, reset_less
=True)
243 def elaborate(self
, platform
):
247 # select Record bit out field
248 with m
.If(self
.sel_in
):
249 comb
+= self
.cr_out
.data
.eq(self
.dec
.BF
[0:-1])
251 comb
+= self
.cr_out
.ok
.eq(self
.sel_in
)
255 class DecodeOE(Elaboratable
):
256 """DecodeOE from instruction
258 decodes OE field: uses RC decode detection which might not be good
260 -- For now, use "rc" in the decode table to decide whether oe exists.
261 -- This is not entirely correct architecturally: For mulhd and
262 -- mulhdu, the OE field is reserved. It remains to be seen what an
263 -- actual POWER9 does if we set it on those instructions, for now we
264 -- test that further down when assigning to the multiplier oe input.
266 def __init__(self
, dec
):
268 self
.sel_in
= Signal(RC
, reset_less
=True)
269 self
.insn_in
= Signal(32, reset_less
=True)
270 self
.oe_out
= Data(1, "oe")
272 def elaborate(self
, platform
):
276 # select OE bit out field
277 with m
.Switch(self
.sel_in
):
279 comb
+= self
.oe_out
.data
.eq(self
.dec
.OE
[0:-1])
280 comb
+= self
.oe_out
.ok
.eq(1)
287 self
.ca
= Signal(reset_less
=True)
288 self
.ca32
= Signal(reset_less
=True)
289 self
.ov
= Signal(reset_less
=True)
290 self
.ov32
= Signal(reset_less
=True)
291 self
.so
= Signal(reset_less
=True)
294 return [self
.ca
, self
.ca32
, self
.ov
, self
.ov32
, self
.so
, ]
297 class Decode2ToExecute1Type
:
301 self
.valid
= Signal(reset_less
=True)
302 self
.insn_type
= Signal(InternalOp
, reset_less
=True)
303 self
.nia
= Signal(64, reset_less
=True)
304 self
.write_reg
= Data(5, name
="rego")
305 self
.read_reg1
= Data(5, name
="reg1")
306 self
.read_reg2
= Data(5, name
="reg2")
307 self
.read_reg3
= Data(5, name
="reg3")
308 self
.imm_data
= Data(64, name
="imm")
309 self
.write_spr
= Data(10, name
="spro")
310 self
.read_spr1
= Data(10, name
="spr1")
311 self
.read_spr2
= Data(10, name
="spr2")
312 self
.cr_sel
= Data(3, name
="cr_sel")
313 #self.read_data1 = Signal(64, reset_less=True)
314 #self.read_data2 = Signal(64, reset_less=True)
315 #self.read_data3 = Signal(64, reset_less=True)
316 #self.cr = Signal(32, reset_less=True) # NO: this is from the CR SPR
317 #self.xerc = XerBits() # NO: this is from the XER SPR
318 self
.lk
= Signal(reset_less
=True)
319 self
.rc
= Data(1, "rc")
320 self
.oe
= Data(1, "oe")
321 self
.invert_a
= Signal(reset_less
=True)
322 self
.invert_out
= Signal(reset_less
=True)
323 self
.input_carry
= Signal(CryIn
, reset_less
=True)
324 self
.output_carry
= Signal(reset_less
=True)
325 self
.input_cr
= Signal(reset_less
=True)
326 self
.output_cr
= Signal(reset_less
=True)
327 self
.is_32bit
= Signal(reset_less
=True)
328 self
.is_signed
= Signal(reset_less
=True)
329 self
.insn
= Signal(32, reset_less
=True)
330 self
.data_len
= Signal(4, reset_less
=True) # bytes
331 self
.byte_reverse
= Signal(reset_less
=True)
332 self
.sign_extend
= Signal(reset_less
=True)# do we need this?
333 self
.update
= Signal(reset_less
=True) # is this an update instruction?
336 return [self
.valid
, self
.insn_type
, self
.nia
,
337 #self.read_data1, self.read_data2, self.read_data3,
340 self
.invert_a
, self
.invert_out
,
341 self
.input_carry
, self
.output_carry
,
342 self
.input_cr
, self
.output_cr
,
343 self
.is_32bit
, self
.is_signed
,
345 self
.data_len
, self
.byte_reverse
, self
.sign_extend
,
349 self
.write_spr
.ports() + \
350 self
.read_spr1
.ports() + \
351 self
.read_spr2
.ports() + \
352 self
.write_reg
.ports() + \
353 self
.read_reg1
.ports() + \
354 self
.read_reg2
.ports() + \
355 self
.read_reg3
.ports() + \
356 self
.imm_data
.ports()
357 # + self.xerc.ports()
359 class PowerDecode2(Elaboratable
):
361 def __init__(self
, dec
):
364 self
.e
= Decode2ToExecute1Type()
367 return self
.dec
.ports() + self
.e
.ports()
369 def elaborate(self
, platform
):
373 # set up submodule decoders
374 m
.submodules
.dec
= self
.dec
375 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
)
376 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
)
377 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
)
378 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
)
379 m
.submodules
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
380 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
)
381 m
.submodules
.dec_cr
= dec_cr
= DecodeCR(self
.dec
)
383 # copy instruction through...
384 for i
in [self
.e
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
385 dec_c
.insn_in
, dec_o
.insn_in
, dec_rc
.insn_in
,
386 dec_oe
.insn_in
, dec_cr
.insn_in
]:
387 comb
+= i
.eq(self
.dec
.opcode_in
)
389 # ...and subdecoders' input fields
390 comb
+= dec_a
.sel_in
.eq(self
.dec
.op
.in1_sel
)
391 comb
+= dec_b
.sel_in
.eq(self
.dec
.op
.in2_sel
)
392 comb
+= dec_c
.sel_in
.eq(self
.dec
.op
.in3_sel
)
393 comb
+= dec_o
.sel_in
.eq(self
.dec
.op
.out_sel
)
394 comb
+= dec_rc
.sel_in
.eq(self
.dec
.op
.rc_sel
)
395 comb
+= dec_oe
.sel_in
.eq(self
.dec
.op
.rc_sel
) # XXX should be OE sel
396 comb
+= dec_cr
.sel_in
.eq(self
.dec
.op
.cr_out
)
398 # decode LD/ST length
399 with m
.Switch(self
.dec
.op
.ldst_len
):
400 with m
.Case(LdstLen
.is1B
):
401 comb
+= self
.e
.data_len
.eq(1)
402 with m
.Case(LdstLen
.is2B
):
403 comb
+= self
.e
.data_len
.eq(2)
404 with m
.Case(LdstLen
.is4B
):
405 comb
+= self
.e
.data_len
.eq(4)
406 with m
.Case(LdstLen
.is8B
):
407 comb
+= self
.e
.data_len
.eq(8)
409 #comb += self.e.nia.eq(self.dec.nia) # XXX TODO
410 itype
= Mux(self
.dec
.op
.function_unit
== Function
.NONE
,
411 InternalOp
.OP_ILLEGAL
,
412 self
.dec
.op
.internal_op
)
413 comb
+= self
.e
.insn_type
.eq(itype
)
415 # registers a, b, c and out
416 comb
+= self
.e
.read_reg1
.eq(dec_a
.reg_out
)
417 comb
+= self
.e
.read_reg2
.eq(dec_b
.reg_out
)
418 comb
+= self
.e
.read_reg3
.eq(dec_c
.reg_out
)
419 comb
+= self
.e
.write_reg
.eq(dec_o
.reg_out
)
420 comb
+= self
.e
.imm_data
.eq(dec_b
.imm_out
)
423 comb
+= self
.e
.rc
.eq(dec_rc
.rc_out
)
424 comb
+= self
.e
.oe
.eq(dec_oe
.oe_out
)
427 comb
+= self
.e
.read_spr1
.eq(dec_a
.spr_out
)
428 comb
+= self
.e
.read_spr2
.eq(dec_b
.spr_out
)
429 comb
+= self
.e
.write_spr
.eq(dec_o
.spr_out
)
431 # decoded/selected instruction flags
432 comb
+= self
.e
.invert_a
.eq(self
.dec
.op
.inv_a
)
433 comb
+= self
.e
.invert_out
.eq(self
.dec
.op
.inv_out
)
434 comb
+= self
.e
.input_carry
.eq(self
.dec
.op
.cry_in
)
435 comb
+= self
.e
.output_carry
.eq(self
.dec
.op
.cry_out
)
436 comb
+= self
.e
.is_32bit
.eq(self
.dec
.op
.is_32b
)
437 comb
+= self
.e
.is_signed
.eq(self
.dec
.op
.sgn
)
438 with m
.If(self
.dec
.op
.lk
):
439 comb
+= self
.e
.lk
.eq(self
.dec
.LK
[0:-1]) # XXX TODO: accessor
441 comb
+= self
.e
.byte_reverse
.eq(self
.dec
.op
.br
)
442 comb
+= self
.e
.sign_extend
.eq(self
.dec
.op
.sgn_ext
)
443 comb
+= self
.e
.update
.eq(self
.dec
.op
.upd
)
445 comb
+= self
.e
.input_cr
.eq(self
.dec
.op
.cr_in
)
446 comb
+= self
.e
.output_cr
.eq(self
.dec
.op
.cr_out
)
448 comb
+= self
.e
.cr_sel
.eq(dec_cr
.cr_out
)
453 if __name__
== '__main__':
454 pdecode
= create_pdecode()
455 dec2
= PowerDecode2(pdecode
)
456 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
457 with
open("dec2.il", "w") as f
: