1 """Power ISA Decoder second stage
3 based on Anton Blanchard microwatt decode2.vhdl
6 from nmigen
import Module
, Elaboratable
, Signal
, Mux
, Const
, Cat
, Repl
, Record
7 from nmigen
.cli
import rtlil
9 from nmutil
.iocontrol
import RecordObject
10 from nmutil
.extend
import exts
12 from soc
.decoder
.power_decoder
import create_pdecode
13 from soc
.decoder
.power_enums
import (InternalOp
, CryIn
, Function
,
15 LdstLen
, In1Sel
, In2Sel
, In3Sel
,
19 class DecodeA(Elaboratable
):
20 """DecodeA from instruction
22 decodes register RA, whether immediate-zero, implicit and
26 def __init__(self
, dec
):
28 self
.sel_in
= Signal(In1Sel
, reset_less
=True)
29 self
.insn_in
= Signal(32, reset_less
=True)
30 self
.reg_out
= Data(5, name
="reg_a")
31 self
.immz_out
= Signal(reset_less
=True)
32 self
.spr_out
= Data(10, "spr_a")
34 def elaborate(self
, platform
):
38 # select Register A field
39 ra
= Signal(5, reset_less
=True)
40 comb
+= ra
.eq(self
.dec
.RA
)
41 with m
.If((self
.sel_in
== In1Sel
.RA
) |
42 ((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
43 (ra
!= Const(0, 5)))):
44 comb
+= self
.reg_out
.data
.eq(ra
)
45 comb
+= self
.reg_out
.ok
.eq(1)
47 # zero immediate requested
48 with m
.If((self
.sel_in
== In1Sel
.RA_OR_ZERO
) &
49 (self
.reg_out
.data
== Const(0, 5))):
50 comb
+= self
.immz_out
.eq(1)
52 # decode SPR1 based on instruction type
54 # BC or BCREG: potential implicit register (CTR)
55 with m
.If((op
.internal_op
== InternalOp
.OP_BC
) |
56 (op
.internal_op
== InternalOp
.OP_BCREG
)):
57 with m
.If(~self
.dec
.BO
[2]): # 3.0B p38 BO2=0, use CTR reg
58 comb
+= self
.spr_out
.data
.eq(SPR
.CTR
) # constant: CTR
59 comb
+= self
.spr_out
.ok
.eq(1)
60 # MFSPR or MTSPR: move-from / move-to SPRs
61 with m
.If((op
.internal_op
== InternalOp
.OP_MFSPR
) |
62 (op
.internal_op
== InternalOp
.OP_MTSPR
)):
63 comb
+= self
.spr_out
.data
.eq(self
.dec
.SPR
) # SPR field, XFX
64 comb
+= self
.spr_out
.ok
.eq(1)
71 def __init__(self
, width
, name
):
72 name_ok
= "%s_ok" % name
73 layout
= ((name
, width
), (name_ok
, 1))
74 Record
.__init
__(self
, layout
)
75 self
.data
= getattr(self
, name
) # convenience
76 self
.ok
= getattr(self
, name_ok
) # convenience
77 self
.data
.reset_less
= True # grrr
78 self
.reset_less
= True # grrr
81 return [self
.data
, self
.ok
]
84 class DecodeB(Elaboratable
):
85 """DecodeB from instruction
87 decodes register RB, different forms of immediate (signed, unsigned),
91 def __init__(self
, dec
):
93 self
.sel_in
= Signal(In2Sel
, reset_less
=True)
94 self
.insn_in
= Signal(32, reset_less
=True)
95 self
.reg_out
= Data(5, "reg_b")
96 self
.imm_out
= Data(64, "imm_b")
97 self
.spr_out
= Data(10, "spr_b")
99 def elaborate(self
, platform
):
103 # select Register B field
104 with m
.Switch(self
.sel_in
):
105 with m
.Case(In2Sel
.RB
):
106 comb
+= self
.reg_out
.data
.eq(self
.dec
.RB
)
107 comb
+= self
.reg_out
.ok
.eq(1)
108 with m
.Case(In2Sel
.CONST_UI
):
109 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
)
110 comb
+= self
.imm_out
.ok
.eq(1)
111 with m
.Case(In2Sel
.CONST_SI
): # TODO: sign-extend here?
112 comb
+= self
.imm_out
.data
.eq(
113 exts(self
.dec
.SI
, 16, 64))
114 comb
+= self
.imm_out
.ok
.eq(1)
115 with m
.Case(In2Sel
.CONST_UI_HI
):
116 comb
+= self
.imm_out
.data
.eq(self
.dec
.UI
<<16)
117 comb
+= self
.imm_out
.ok
.eq(1)
118 with m
.Case(In2Sel
.CONST_SI_HI
): # TODO: sign-extend here?
119 comb
+= self
.imm_out
.data
.eq(self
.dec
.SI
<<16)
120 comb
+= self
.imm_out
.data
.eq(
121 exts(self
.dec
.SI
<< 16, 32, 64))
122 comb
+= self
.imm_out
.ok
.eq(1)
123 with m
.Case(In2Sel
.CONST_LI
):
124 comb
+= self
.imm_out
.data
.eq(self
.dec
.LI
<<2)
125 comb
+= self
.imm_out
.ok
.eq(1)
126 with m
.Case(In2Sel
.CONST_BD
):
127 comb
+= self
.imm_out
.data
.eq(self
.dec
.BD
<<2)
128 comb
+= self
.imm_out
.ok
.eq(1)
129 with m
.Case(In2Sel
.CONST_DS
):
130 comb
+= self
.imm_out
.data
.eq(self
.dec
.DS
<<2)
131 comb
+= self
.imm_out
.ok
.eq(1)
132 with m
.Case(In2Sel
.CONST_M1
):
133 comb
+= self
.imm_out
.data
.eq(~
Const(0, 64)) # all 1s
134 comb
+= self
.imm_out
.ok
.eq(1)
135 with m
.Case(In2Sel
.CONST_SH
):
136 comb
+= self
.imm_out
.data
.eq(self
.dec
.sh
)
137 comb
+= self
.imm_out
.ok
.eq(1)
138 with m
.Case(In2Sel
.CONST_SH32
):
139 comb
+= self
.imm_out
.data
.eq(self
.dec
.SH32
)
140 comb
+= self
.imm_out
.ok
.eq(1)
142 # decode SPR2 based on instruction type
144 # BCREG implicitly uses CTR or LR for 2nd reg
145 with m
.If(op
.internal_op
== InternalOp
.OP_BCREG
):
146 with m
.If(self
.dec
.FormXL
.XO
[9]): # 3.0B p38 top bit of XO
147 comb
+= self
.spr_out
.data
.eq(SPR
.CTR
)
149 comb
+= self
.spr_out
.data
.eq(SPR
.LR
)
150 comb
+= self
.spr_out
.ok
.eq(1)
155 class DecodeC(Elaboratable
):
156 """DecodeC from instruction
161 def __init__(self
, dec
):
163 self
.sel_in
= Signal(In3Sel
, reset_less
=True)
164 self
.insn_in
= Signal(32, reset_less
=True)
165 self
.reg_out
= Data(5, "reg_c")
167 def elaborate(self
, platform
):
171 # select Register C field
172 with m
.If(self
.sel_in
== In3Sel
.RS
):
173 comb
+= self
.reg_out
.data
.eq(self
.dec
.RS
)
174 comb
+= self
.reg_out
.ok
.eq(1)
179 class DecodeOut(Elaboratable
):
180 """DecodeOut from instruction
182 decodes output register RA, RT or SPR
185 def __init__(self
, dec
):
187 self
.sel_in
= Signal(OutSel
, reset_less
=True)
188 self
.insn_in
= Signal(32, reset_less
=True)
189 self
.reg_out
= Data(5, "reg_o")
190 self
.spr_out
= Data(10, "spr_o")
192 def elaborate(self
, platform
):
196 # select Register out field
197 with m
.Switch(self
.sel_in
):
198 with m
.Case(OutSel
.RT
):
199 comb
+= self
.reg_out
.data
.eq(self
.dec
.RT
)
200 comb
+= self
.reg_out
.ok
.eq(1)
201 with m
.Case(OutSel
.RA
):
202 comb
+= self
.reg_out
.data
.eq(self
.dec
.RA
)
203 comb
+= self
.reg_out
.ok
.eq(1)
204 with m
.Case(OutSel
.SPR
):
205 comb
+= self
.spr_out
.data
.eq(self
.dec
.SPR
) # from XFX
206 comb
+= self
.spr_out
.ok
.eq(1)
211 class DecodeRC(Elaboratable
):
212 """DecodeRc from instruction
214 decodes Record bit Rc
216 def __init__(self
, dec
):
218 self
.sel_in
= Signal(RC
, reset_less
=True)
219 self
.insn_in
= Signal(32, reset_less
=True)
220 self
.rc_out
= Data(1, "rc")
222 def elaborate(self
, platform
):
226 # select Record bit out field
227 with m
.Switch(self
.sel_in
):
229 comb
+= self
.rc_out
.data
.eq(self
.dec
.Rc
)
230 comb
+= self
.rc_out
.ok
.eq(1)
232 comb
+= self
.rc_out
.data
.eq(1)
233 comb
+= self
.rc_out
.ok
.eq(1)
234 with m
.Case(RC
.NONE
):
235 comb
+= self
.rc_out
.data
.eq(0)
236 comb
+= self
.rc_out
.ok
.eq(1)
241 class DecodeOE(Elaboratable
):
242 """DecodeOE from instruction
244 decodes OE field: uses RC decode detection which might not be good
246 -- For now, use "rc" in the decode table to decide whether oe exists.
247 -- This is not entirely correct architecturally: For mulhd and
248 -- mulhdu, the OE field is reserved. It remains to be seen what an
249 -- actual POWER9 does if we set it on those instructions, for now we
250 -- test that further down when assigning to the multiplier oe input.
252 def __init__(self
, dec
):
254 self
.sel_in
= Signal(RC
, reset_less
=True)
255 self
.insn_in
= Signal(32, reset_less
=True)
256 self
.oe_out
= Data(1, "oe")
258 def elaborate(self
, platform
):
262 # select OE bit out field
263 with m
.Switch(self
.sel_in
):
265 comb
+= self
.oe_out
.data
.eq(self
.dec
.OE
)
266 comb
+= self
.oe_out
.ok
.eq(1)
270 class DecodeCRIn(Elaboratable
):
271 """Decodes input CR from instruction"""
273 def __init__(self
, dec
):
275 self
.sel_in
= Signal(CRInSel
, reset_less
=True)
276 self
.insn_in
= Signal(32, reset_less
=True)
277 self
.cr_bitfield
= Data(3, "cr_bitfield")
278 self
.cr_bitfield_b
= Data(3, "cr_bitfield_b")
279 self
.whole_reg
= Signal(reset_less
=True)
281 def elaborate(self
, platform
):
285 comb
+= self
.cr_bitfield
.ok
.eq(0)
286 comb
+= self
.cr_bitfield_b
.ok
.eq(0)
287 comb
+= self
.whole_reg
.eq(0)
288 with m
.Switch(self
.sel_in
):
289 with m
.Case(CRInSel
.NONE
):
290 pass # No bitfield activated
291 with m
.Case(CRInSel
.CR0
):
292 comb
+= self
.cr_bitfield
.data
.eq(0)
293 comb
+= self
.cr_bitfield
.ok
.eq(1)
294 with m
.Case(CRInSel
.BI
):
295 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BI
[3:5])
296 comb
+= self
.cr_bitfield
.ok
.eq(1)
297 with m
.Case(CRInSel
.BFA
):
298 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BFA
[0:-1])
299 comb
+= self
.cr_bitfield
.ok
.eq(1)
300 with m
.Case(CRInSel
.BA_BB
):
301 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BA
[3:5])
302 comb
+= self
.cr_bitfield
.ok
.eq(1)
303 comb
+= self
.cr_bitfield_b
.data
.eq(self
.dec
.BB
[3:5])
304 comb
+= self
.cr_bitfield_b
.ok
.eq(1)
305 with m
.Case(CRInSel
.BC
):
306 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.BC
[0:-1])
307 comb
+= self
.cr_bitfield
.ok
.eq(1)
308 with m
.Case(CRInSel
.WHOLE_REG
):
309 comb
+= self
.whole_reg
.eq(1)
313 class DecodeCROut(Elaboratable
):
314 """Decodes input CR from instruction"""
316 def __init__(self
, dec
):
318 self
.sel_in
= Signal(CROutSel
, reset_less
=True)
319 self
.insn_in
= Signal(32, reset_less
=True)
320 self
.cr_bitfield
= Data(3, "cr_bitfield")
321 self
.whole_reg
= Signal(reset_less
=True)
323 def elaborate(self
, platform
):
327 comb
+= self
.cr_bitfield
.ok
.eq(0)
328 comb
+= self
.whole_reg
.eq(0)
329 with m
.Switch(self
.sel_in
):
330 with m
.Case(CROutSel
.NONE
):
331 pass # No bitfield activated
332 with m
.Case(CROutSel
.CR0
):
333 comb
+= self
.cr_bitfield
.data
.eq(0)
334 comb
+= self
.cr_bitfield
.ok
.eq(1)
335 with m
.Case(CROutSel
.BF
):
336 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormX
.BF
[0:-1])
337 comb
+= self
.cr_bitfield
.ok
.eq(1)
338 with m
.Case(CROutSel
.BT
):
339 comb
+= self
.cr_bitfield
.data
.eq(self
.dec
.FormXL
.BT
[3:5])
340 comb
+= self
.cr_bitfield
.ok
.eq(1)
341 with m
.Case(CROutSel
.WHOLE_REG
):
342 comb
+= self
.whole_reg
.eq(1)
348 self
.ca
= Signal(2, reset_less
=True)
349 self
.ov
= Signal(2, reset_less
=True)
350 self
.so
= Signal(reset_less
=True)
353 return [self
.ca
, self
.ov
, self
.so
]
356 class Decode2ToExecute1Type(RecordObject
):
358 def __init__(self
, name
=None):
360 RecordObject
.__init
__(self
, name
=name
)
362 self
.valid
= Signal(reset_less
=True)
363 self
.insn_type
= Signal(InternalOp
, reset_less
=True)
364 self
.fn_unit
= Signal(Function
, reset_less
=True)
365 self
.nia
= Signal(64, reset_less
=True)
366 self
.write_reg
= Data(5, name
="rego")
367 self
.read_reg1
= Data(5, name
="reg1")
368 self
.read_reg2
= Data(5, name
="reg2")
369 self
.read_reg3
= Data(5, name
="reg3")
370 self
.imm_data
= Data(64, name
="imm")
371 self
.write_spr
= Data(10, name
="spro")
372 self
.read_spr1
= Data(10, name
="spr1")
373 self
.read_spr2
= Data(10, name
="spr2")
375 self
.read_cr1
= Data(3, name
="cr_in1")
376 self
.read_cr2
= Data(3, name
="cr_in2")
377 self
.read_cr_whole
= Signal(reset_less
=True)
378 self
.write_cr
= Data(3, name
="cr_out")
379 self
.write_cr_whole
= Signal(reset_less
=True)
380 #self.read_data1 = Signal(64, reset_less=True)
381 #self.read_data2 = Signal(64, reset_less=True)
382 #self.read_data3 = Signal(64, reset_less=True)
383 #self.cr = Signal(32, reset_less=True) # NO: this is from the CR SPR
384 #self.xerc = XerBits() # NO: this is from the XER SPR
385 self
.lk
= Signal(reset_less
=True)
386 self
.rc
= Data(1, "rc")
387 self
.oe
= Data(1, "oe")
388 self
.invert_a
= Signal(reset_less
=True)
389 self
.zero_a
= Signal(reset_less
=True)
390 self
.invert_out
= Signal(reset_less
=True)
391 self
.input_carry
= Signal(CryIn
, reset_less
=True)
392 self
.output_carry
= Signal(reset_less
=True)
393 self
.input_cr
= Signal(reset_less
=True)
394 self
.output_cr
= Signal(reset_less
=True)
395 self
.is_32bit
= Signal(reset_less
=True)
396 self
.is_signed
= Signal(reset_less
=True)
397 self
.insn
= Signal(32, reset_less
=True)
398 self
.data_len
= Signal(4, reset_less
=True) # bytes
399 self
.byte_reverse
= Signal(reset_less
=True)
400 self
.sign_extend
= Signal(reset_less
=True)# do we need this?
401 self
.update
= Signal(reset_less
=True) # LD/ST is "update" variant
404 class PowerDecode2(Elaboratable
):
406 def __init__(self
, dec
):
409 self
.e
= Decode2ToExecute1Type()
412 return self
.dec
.ports() + self
.e
.ports()
414 def elaborate(self
, platform
):
418 # set up submodule decoders
419 m
.submodules
.dec
= self
.dec
420 m
.submodules
.dec_a
= dec_a
= DecodeA(self
.dec
)
421 m
.submodules
.dec_b
= dec_b
= DecodeB(self
.dec
)
422 m
.submodules
.dec_c
= dec_c
= DecodeC(self
.dec
)
423 m
.submodules
.dec_o
= dec_o
= DecodeOut(self
.dec
)
424 m
.submodules
.dec_rc
= dec_rc
= DecodeRC(self
.dec
)
425 m
.submodules
.dec_oe
= dec_oe
= DecodeOE(self
.dec
)
426 m
.submodules
.dec_cr_in
= dec_cr_in
= DecodeCRIn(self
.dec
)
427 m
.submodules
.dec_cr_out
= dec_cr_out
= DecodeCROut(self
.dec
)
429 # copy instruction through...
430 for i
in [self
.e
.insn
, dec_a
.insn_in
, dec_b
.insn_in
,
431 dec_c
.insn_in
, dec_o
.insn_in
, dec_rc
.insn_in
,
432 dec_oe
.insn_in
, dec_cr_in
.insn_in
, dec_cr_out
.insn_in
]:
433 comb
+= i
.eq(self
.dec
.opcode_in
)
435 # ...and subdecoders' input fields
436 comb
+= dec_a
.sel_in
.eq(self
.dec
.op
.in1_sel
)
437 comb
+= dec_b
.sel_in
.eq(self
.dec
.op
.in2_sel
)
438 comb
+= dec_c
.sel_in
.eq(self
.dec
.op
.in3_sel
)
439 comb
+= dec_o
.sel_in
.eq(self
.dec
.op
.out_sel
)
440 comb
+= dec_rc
.sel_in
.eq(self
.dec
.op
.rc_sel
)
441 comb
+= dec_oe
.sel_in
.eq(self
.dec
.op
.rc_sel
) # XXX should be OE sel
442 comb
+= dec_cr_in
.sel_in
.eq(self
.dec
.op
.cr_in
)
443 comb
+= dec_cr_out
.sel_in
.eq(self
.dec
.op
.cr_out
)
445 # decode LD/ST length
446 with m
.Switch(self
.dec
.op
.ldst_len
):
447 with m
.Case(LdstLen
.is1B
):
448 comb
+= self
.e
.data_len
.eq(1)
449 with m
.Case(LdstLen
.is2B
):
450 comb
+= self
.e
.data_len
.eq(2)
451 with m
.Case(LdstLen
.is4B
):
452 comb
+= self
.e
.data_len
.eq(4)
453 with m
.Case(LdstLen
.is8B
):
454 comb
+= self
.e
.data_len
.eq(8)
456 comb
+= self
.e
.nia
.eq(0) # XXX TODO
457 comb
+= self
.e
.valid
.eq(0) # XXX TODO
458 fu
= self
.dec
.op
.function_unit
459 itype
= Mux(fu
== Function
.NONE
,
460 InternalOp
.OP_ILLEGAL
,
461 self
.dec
.op
.internal_op
)
462 comb
+= self
.e
.insn_type
.eq(itype
)
463 comb
+= self
.e
.fn_unit
.eq(fu
)
465 # registers a, b, c and out
466 comb
+= self
.e
.read_reg1
.eq(dec_a
.reg_out
)
467 comb
+= self
.e
.read_reg2
.eq(dec_b
.reg_out
)
468 comb
+= self
.e
.read_reg3
.eq(dec_c
.reg_out
)
469 comb
+= self
.e
.write_reg
.eq(dec_o
.reg_out
)
470 comb
+= self
.e
.imm_data
.eq(dec_b
.imm_out
) # immediate in RB (usually)
471 comb
+= self
.e
.zero_a
.eq(dec_a
.immz_out
) # RA==0 detected
474 comb
+= self
.e
.rc
.eq(dec_rc
.rc_out
)
475 comb
+= self
.e
.oe
.eq(dec_oe
.oe_out
)
478 comb
+= self
.e
.read_spr1
.eq(dec_a
.spr_out
)
479 comb
+= self
.e
.read_spr2
.eq(dec_b
.spr_out
)
480 comb
+= self
.e
.write_spr
.eq(dec_o
.spr_out
)
482 comb
+= self
.e
.read_cr1
.eq(dec_cr_in
.cr_bitfield
)
483 comb
+= self
.e
.read_cr2
.eq(dec_cr_in
.cr_bitfield_b
)
484 comb
+= self
.e
.read_cr_whole
.eq(dec_cr_in
.whole_reg
)
486 comb
+= self
.e
.write_cr
.eq(dec_cr_out
.cr_bitfield
)
487 comb
+= self
.e
.write_cr_whole
.eq(dec_cr_out
.whole_reg
)
489 # decoded/selected instruction flags
490 comb
+= self
.e
.invert_a
.eq(self
.dec
.op
.inv_a
)
491 comb
+= self
.e
.invert_out
.eq(self
.dec
.op
.inv_out
)
492 comb
+= self
.e
.input_carry
.eq(self
.dec
.op
.cry_in
) # carry comes in
493 comb
+= self
.e
.output_carry
.eq(self
.dec
.op
.cry_out
) # carry goes out
494 comb
+= self
.e
.is_32bit
.eq(self
.dec
.op
.is_32b
)
495 comb
+= self
.e
.is_signed
.eq(self
.dec
.op
.sgn
)
496 with m
.If(self
.dec
.op
.lk
):
497 comb
+= self
.e
.lk
.eq(self
.dec
.LK
) # XXX TODO: accessor
499 comb
+= self
.e
.byte_reverse
.eq(self
.dec
.op
.br
)
500 comb
+= self
.e
.sign_extend
.eq(self
.dec
.op
.sgn_ext
)
501 comb
+= self
.e
.update
.eq(self
.dec
.op
.upd
) # LD/ST "update" mode
505 # These should be removed eventually
506 comb
+= self
.e
.input_cr
.eq(self
.dec
.op
.cr_in
) # condition reg comes in
507 comb
+= self
.e
.output_cr
.eq(self
.dec
.op
.cr_out
) # condition reg goes in
513 if __name__
== '__main__':
514 pdecode
= create_pdecode()
515 dec2
= PowerDecode2(pdecode
)
516 vl
= rtlil
.convert(dec2
, ports
=dec2
.ports() + pdecode
.ports())
517 with
open("dec2.il", "w") as f
: