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
7 from power_enums import (InternalOp, CryIn,
8 In1Sel, In2Sel, In3Sel, OutSel, SPR, RC)
9
10 class DecodeA(Elaboratable):
11 def __init__(self, dec):
12 self.dec = dec
13 self.sel_in = Signal(In1Sel, reset_less=True)
14 self.insn_in = Signal(32, reset_less=True)
15 self.reg_out = Signal(5, reset_less=True)
16 self.regok_out = Signal(reset_less=True)
17 self.immz_out = Signal(reset_less=True)
18 self.spr_out = Signal(10, reset_less=True)
19 self.sprok_out = Signal(reset_less=True)
20
21 def elaborate(self, platform):
22 m = Module()
23 comb = m.d.comb
24
25 # select Register A field
26 with m.If((self.sel_in == In1Sel.RA) |
27 ((self.sel_in == In1Sel.RA_OR_ZERO) &
28 (self.reg_out != Const(0, 5)))):
29 comb += self.reg_out.eq(self.dec.RA)
30 comb += self.regok_out.eq(1)
31
32 # zero immediate requested
33 with m.If((self.sel_in == In1Sel.RA_OR_ZERO) &
34 (self.reg_out == Const(0, 5))):
35 comb += self.immz_out.eq(1)
36
37 # decode SPR1 based on instruction type
38 op = self.dec.op
39 # BC or BCREG: potential implicit register (CTR)
40 with m.If(op.internal_op == InternalOP.OP_BC |
41 op.internal_op == InternalOP.OP_BCREG):
42 with m.If(~self.dec.BO[2]): # 3.0B p38 BO2=0, use CTR reg
43 self.spr_out.eq(SPR.CTR) # constant: CTR
44 self.sprok_out.eq(1)
45 # MFSPR or MTSPR: move-from / move-to SPRs
46 with m.If(op.internal_op == InternalOP.OP_MFSPR |
47 op.internal_op == InternalOP.OP_MTSPR):
48 self.spr_out.eq(self.dec.SPR) # decode SPR field from XFX insn
49 self.sprok_out.eq(1)
50
51 return m
52
53
54 class DecodeB(Elaboratable):
55 def __init__(self, dec):
56 self.dec = dec
57 self.sel_in = Signal(In2Sel, reset_less=True)
58 self.insn_in = Signal(32, reset_less=True)
59 self.reg_out = Signal(5, reset_less=True)
60 self.regok_out = Signal(reset_less=True)
61 self.imm_out = Signal(64, reset_less=True)
62 self.immok_out = Signal(reset_less=True)
63 self.spr_out = Signal(10, reset_less=True)
64 self.sprok_out = Signal(reset_less=True)
65
66 def elaborate(self, platform):
67 m = Module()
68 comb = m.d.comb
69
70 # select Register B field
71 with m.Switch(self.sel_in):
72 with m.Case(In2Sel.RB):
73 comb += self.reg_out.eq(self.dec.RB)
74 comb += self.regok_out.eq(1)
75 with m.Case(In2Sel.CONST_UI):
76 comb += self.imm_out.eq(self.dec.SI)
77 comb += self.immok_out.eq(1)
78 with m.Case(In2Sel.CONST_SI): # TODO: sign-extend here?
79 comb += self.imm_out.eq(self.dec.SI)
80 comb += self.immok_out.eq(1)
81 with m.Case(In2Sel.CONST_UI_HI):
82 comb += self.imm_out.eq(self.dec.UI<<4)
83 comb += self.immok_out.eq(1)
84 with m.Case(In2Sel.CONST_UI_SI): # TODO: sign-extend here?
85 comb += self.imm_out.eq(self.dec.UI<<4)
86 comb += self.immok_out.eq(1)
87 with m.Case(In2Sel.CONST_LI):
88 comb += self.imm_out.eq(self.dec.LI<<2)
89 comb += self.immok_out.eq(1)
90 with m.Case(In2Sel.CONST_BD):
91 comb += self.imm_out.eq(self.dec.BD<<2)
92 comb += self.immok_out.eq(1)
93 with m.Case(In2Sel.CONST_DS):
94 comb += self.imm_out.eq(self.dec.DS<<2)
95 comb += self.immok_out.eq(1)
96 with m.Case(In2Sel.CONST_M1):
97 comb += self.imm_out.eq(~Const(0, 64)) # all 1s
98 comb += self.immok_out.eq(1)
99 with m.Case(In2Sel.CONST_SH):
100 comb += self.imm_out.eq(self.dec.sh)
101 comb += self.immok_out.eq(1)
102 with m.Case(In2Sel.CONST_SH32):
103 comb += self.imm_out.eq(self.dec.SH32)
104 comb += self.immok_out.eq(1)
105
106 # decode SPR2 based on instruction type
107 op = self.dec.op
108 # BCREG implicitly uses CTR or LR for 2nd reg
109 with m.If(op.internal_op == InternalOP.OP_BCREG):
110 with m.If(self.dec.FormXL.XO[10]): # 3.0B p38 top bit of XO
111 self.spr_out.eq(SPR.CTR)
112 with m.Else():
113 self.spr_out.eq(SPR.LR)
114 self.sprok_out.eq(1)
115
116 return m
117
118
119 class DecodeC(Elaboratable):
120 def __init__(self, dec):
121 self.dec = dec
122 self.sel_in = Signal(In3Sel, reset_less=True)
123 self.insn_in = Signal(32, reset_less=True)
124 self.reg_out = Signal(5, reset_less=True)
125 self.regok_out = Signal(reset_less=True)
126
127 def elaborate(self, platform):
128 m = Module()
129 comb = m.d.comb
130
131 # select Register C field
132 with m.If(self.sel_in == In3Sel.RC):
133 comb += self.reg_out.eq(self.dec.RC)
134 comb += self.regok_out.eq(1)
135
136 return m
137
138
139 class DecodeOut(Elaboratable):
140 def __init__(self, dec):
141 self.dec = dec
142 self.sel_in = Signal(In1Sel, reset_less=True)
143 self.insn_in = Signal(32, reset_less=True)
144 self.reg_out = Signal(5, reset_less=True)
145 self.regok_out = Signal(reset_less=True)
146 self.spr_out = Signal(10, reset_less=True)
147 self.sprok_out = Signal(reset_less=True)
148
149 def elaborate(self, platform):
150 m = Module()
151 comb = m.d.comb
152
153 # select Register out field
154 with m.Switch(self.sel_in):
155 with m.Case(In1Sel.RT):
156 comb += self.reg_out.eq(self.dec.RT)
157 comb += self.regok_out.eq(1)
158 with m.Case(In1Sel.RA):
159 comb += self.reg_out.eq(self.dec.RA)
160 comb += self.regok_out.eq(1)
161 with m.Case(In1Sel.SPR):
162 self.spr_out.eq(self.dec.SPR) # decode SPR field from XFX insn
163 self.sprok_out.eq(1)
164
165 return m
166
167
168 class DecodeRC(Elaboratable):
169 def __init__(self, dec):
170 self.dec = dec
171 self.sel_in = Signal(RC, reset_less=True)
172 self.insn_in = Signal(32, reset_less=True)
173 self.rc_out = Signal(1, reset_less=True)
174 self.rcok_out = Signal(reset_less=True)
175
176 def elaborate(self, platform):
177 m = Module()
178 comb = m.d.comb
179
180 # select Record bit out field
181 with m.Switch(self.sel_in):
182 with m.Case(RC.RC):
183 comb += self.rc_out.eq(self.dec.Rc)
184 comb += self.rcok_out.eq(1)
185 with m.Case(RC.ONE):
186 comb += self.rc_out.eq(1)
187 comb += self.rcok_out.eq(1)
188 with m.Case(RC.NONE):
189 comb += self.rc_out.eq(0)
190 comb += self.rcok_out.eq(1)
191
192 return m
193
194
195 class DecodeOE(Elaboratable):
196 """
197 -- For now, use "rc" in the decode table to decide whether oe exists.
198 -- This is not entirely correct architecturally: For mulhd and
199 -- mulhdu, the OE field is reserved. It remains to be seen what an
200 -- actual POWER9 does if we set it on those instructions, for now we
201 -- test that further down when assigning to the multiplier oe input.
202 """
203 def __init__(self, dec):
204 self.dec = dec
205 self.sel_in = Signal(RC, reset_less=True)
206 self.insn_in = Signal(32, reset_less=True)
207 self.oe_out = Signal(1, reset_less=True)
208 self.oeok_out = Signal(reset_less=True)
209
210 def elaborate(self, platform):
211 m = Module()
212 comb = m.d.comb
213
214 # select OE bit out field
215 with m.Switch(self.sel_in):
216 with m.Case(RC.RC):
217 comb += self.oe_out.eq(self.dec.OE)
218 comb += self.oeok_out.eq(1)
219
220 return m
221
222
223 class XerBits:
224 def __init__(self):
225 self.ca = Signal(reset_less=True)
226 self.ca32 = Signal(reset_less=True)
227 self.ov = Signal(reset_less=True)
228 self.ov32 = Signal(reset_less=True)
229 self.so = Signal(reset_less=True)
230
231
232 class PowerDecodeToExecute(Elaboratable):
233
234 def __init__(self, width):
235
236 self.valid = Signal(reset_less=True)
237 self.insn_type = Signal(InternalOp, reset_less=True)
238 self.nia = Signal(64, reset_less=True)
239 self.write_reg = Signal(5, reset_less=True)
240 self.read_reg1 = Signal(5, reset_less=True)
241 self.read_reg2 = Signal(5, reset_less=True)
242 self.read_data1 = Signal(64, reset_less=True)
243 self.read_data2 = Signal(64, reset_less=True)
244 self.read_data3 = Signal(64, reset_less=True)
245 self.cr = Signal(32, reset_less=True)
246 self.xerc = XerBits()
247 self.lr = Signal(reset_less=True)
248 self.rc = Signal(reset_less=True)
249 self.oe = Signal(reset_less=True)
250 self.invert_a = Signal(reset_less=True)
251 self.invert_out = Signal(reset_less=True)
252 self.input_carry: Signal(CryIn, reset_less=True)
253 self.output_carry = Signal(reset_less=True)
254 self.input_cr = Signal(reset_less=True)
255 self.output_cr = Signal(reset_less=True)
256 self.is_32bit = Signal(reset_less=True)
257 self.is_signed = Signal(reset_less=True)
258 self.insn = Signal(32, reset_less=True)
259 self.data_len = Signal(4, reset_less=True) # bytes
260 self.byte_reverse = Signal(reset_less=True)
261 self.sign_extend = Signal(reset_less=True)# do we need this?
262 self.update = Signal(reset_less=True) # is this an update instruction?
263
264 def elaborate(self, platform):
265 m = Module()
266 comb = m.d.comb
267
268 return m
269