found a way to print out the names of the signals
[openpower-isa.git] / src / openpower / decoder / power_regspec_map.py
1 """regspec_decode
2
3 functions for the relationship between regspecs and Decode2Execute1Type
4
5 these functions encodes the understanding (relationship) between
6 Regfiles, Computation Units, and the Power ISA Decoder (PowerDecoder2).
7
8 based on the regspec, which contains the register file name and register
9 name, return a tuple of:
10
11 * how the decoder should determine whether the Function Unit needs
12 access to a given Regport or not
13 * which Regfile number on that port should be read to get that data
14 * when it comes to writing: likewise, which Regfile num should be written
15
16 Note that some of the port numbering encoding is *unary*. in the case
17 of "Full Condition Register", it's a full 8-bit mask of read/write-enables.
18 This actually matches directly with the XFX field in MTCR, and at
19 some point that 8-bit mask from the instruction could actually be passed
20 directly through to full_cr (TODO).
21
22 For the INT and CR numbering, these are expressed in binary in the
23 instruction and need to be converted to unary (1<<read_reg1.data).
24 Note however that XFX in MTCR is unary-masked!
25
26 XER regs are implicitly-encoded (hard-coded) based on whether the
27 operation has carry or overflow.
28
29 FAST regfile is, again, implicitly encoded, back in PowerDecode2, based
30 on the type of operation (see DecodeB for an example, where fast_out
31 is set, then carried into read_fast2 in PowerDecode2).
32
33 The SPR regfile on the other hand is *binary*-encoded, and, furthermore,
34 has to be "remapped" to internal SPR Enum indices (see SPRMap in PowerDecode2)
35 see https://libre-soc.org/3d_gpu/architecture/regfile/ section on regspecs
36 """
37 from nmigen import Const, Signal
38 from openpower.consts import XERRegsEnum, FastRegsEnum, StateRegsEnum
39 from openpower.decoder.power_enums import CryIn
40 from openpower.util import log
41 from collections import namedtuple
42
43 RegDecodeInfo = namedtuple("RedDecodeInfo", ['okflag', 'regport', 'portlen'])
44
45 # XXX TODO: these portlen numbers *must* increase / adapt for SVP64.
46
47 def regspec_decode_read(m, e, regfile, name):
48 """regspec_decode_read
49 """
50
51 rd = None
52
53 # INT regfile
54
55 if regfile == 'INT':
56 # Int register numbering is *unary* encoded
57 if name == 'ra': # RA
58 rd = RegDecodeInfo(e.read_reg1.ok, e.read_reg1.data, 5)
59 if name == 'rb': # RB
60 rd = RegDecodeInfo(e.read_reg2.ok, e.read_reg2.data, 5)
61 if name == 'rc': # RS
62 rd = RegDecodeInfo(e.read_reg3.ok, e.read_reg3.data, 5)
63
64 # CR regfile
65
66 if regfile == 'CR':
67 # CRRegs register numbering is *unary* encoded
68 if name == 'full_cr': # full CR (from FXM field)
69 rd = RegDecodeInfo(e.do.read_cr_whole.ok,
70 e.do.read_cr_whole.data, 8)
71 if name == 'cr_a': # CR A
72 rd = RegDecodeInfo(e.read_cr1.ok, 1<<(7-e.read_cr1.data), 8)
73 if name == 'cr_b': # CR B
74 rd = RegDecodeInfo(e.read_cr2.ok, 1<<(7-e.read_cr2.data), 8)
75 if name == 'cr_c': # CR C
76 rd = RegDecodeInfo(e.read_cr3.ok, 1<<(7-e.read_cr3.data), 8)
77
78 # XER regfile
79
80 if regfile == 'XER':
81 # XERRegsEnum register numbering is *unary* encoded
82 SO = 1<<XERRegsEnum.SO
83 CA = 1<<XERRegsEnum.CA
84 OV = 1<<XERRegsEnum.OV
85 if name == 'xer_so':
86 # SO needs to be read for overflow *and* for creation
87 # of CR0 and also for MFSPR
88 rd = RegDecodeInfo(((e.do.oe.oe[0] & e.do.oe.ok) |
89 (e.xer_in & SO == SO)|
90 (e.do.rc.rc & e.do.rc.ok)), SO, 3)
91 if name == 'xer_ov':
92 rd = RegDecodeInfo(((e.do.oe.oe[0] & e.do.oe.ok) |
93 (e.xer_in & CA == CA)), OV, 3)
94 if name == 'xer_ca':
95 rd = RegDecodeInfo(((e.do.input_carry == CryIn.CA.value) |
96 (e.xer_in & OV == OV)), CA, 3)
97
98 # STATE regfile
99
100 if regfile == 'STATE':
101 # STATE register numbering is *unary* encoded
102 PC = 1<<StateRegsEnum.PC
103 MSR = 1<<StateRegsEnum.MSR
104 SVSTATE = 1<<StateRegsEnum.SVSTATE
105 if name in ['cia', 'nia']:
106 # TODO: detect read-conditions
107 rd = RegDecodeInfo(Const(1), PC, 3)
108 if name == 'msr':
109 # TODO: detect read-conditions
110 rd = RegDecodeInfo(Const(1), MSR, 3)
111 if name == 'svstate':
112 # TODO: detect read-conditions
113 rd = RegDecodeInfo(Const(1), SVSTATE, 3)
114
115 # FAST regfile
116
117 if regfile == 'FAST':
118 # FAST register numbering is *unary* encoded
119 if name == 'fast1':
120 rd = RegDecodeInfo(e.read_fast1.ok, e.read_fast1.data, 4)
121 if name == 'fast2':
122 rd = RegDecodeInfo(e.read_fast2.ok, e.read_fast2.data, 4)
123 if name == 'fast3':
124 rd = RegDecodeInfo(e.read_fast3.ok, e.read_fast3.data, 4)
125
126 # SPR regfile
127
128 if regfile == 'SPR':
129 # SPR register numbering is *binary* encoded
130 if name == 'spr1':
131 rd = RegDecodeInfo(e.read_spr1.ok, e.read_spr1.data, 10)
132
133 assert rd is not None, "regspec not found %s %s" % (regfile, name)
134
135 rname="rd_decode_%s_%s" % (regfile, name)
136 ok = Signal(name=rname+"_ok", reset_less=True)
137 data = Signal(rd.portlen, name=rname+"_port", reset_less=True)
138 m.d.comb += ok.eq(rd.okflag)
139 m.d.comb += data.eq(rd.regport)
140
141 return RegDecodeInfo(ok, data, rd.portlen)
142
143
144 def regspec_decode_write(m, e, regfile, name):
145 """regspec_decode_write
146 """
147
148 #log("regspec_decode_write", regfile, name, e.__class__.__name__)
149 wr = None
150
151 # INT regfile
152
153 if regfile == 'INT':
154 # Int register numbering is *unary* encoded
155 if name == 'o': # RT
156 wr = RegDecodeInfo(e.write_reg.ok, e.write_reg.data, 5)
157 if name == 'o1': # RA (update mode: LD/ST EA)
158 wr = RegDecodeInfo(e.write_ea.ok, e.write_ea.data, 5)
159
160 # CR regfile
161
162 if regfile == 'CR':
163 # CRRegs register numbering is *unary* encoded
164 # *sigh*. numbering inverted on part-CRs. because POWER.
165 if name == 'full_cr': # full CR (from FXM field)
166 wr = RegDecodeInfo(e.do.write_cr_whole.ok,
167 e.do.write_cr_whole.data, 8)
168 if name == 'cr_a': # CR A
169 wr = RegDecodeInfo(e.write_cr.ok,
170 1<<(7-e.write_cr.data), 8)
171
172 # XER regfile
173
174 if regfile == 'XER':
175 # XERRegsEnum register numbering is *unary* encoded
176 SO = 1<<XERRegsEnum.SO
177 CA = 1<<XERRegsEnum.CA
178 OV = 1<<XERRegsEnum.OV
179 if name == 'xer_so':
180 wr = RegDecodeInfo(e.xer_out | (e.do.oe.oe[0] & e.do.oe.ok),
181 SO, 3) # hmmm
182 if name == 'xer_ov':
183 wr = RegDecodeInfo(e.xer_out | (e.do.oe.oe[0] & e.do.oe.ok),
184 OV, 3) # hmmm
185 if name == 'xer_ca':
186 wr = RegDecodeInfo(e.xer_out | (e.do.output_carry),
187 CA, 3) # hmmm
188
189 # STATE regfile
190
191 if regfile == 'STATE':
192 # STATE register numbering is *unary* encoded
193 PC = 1<<StateRegsEnum.PC
194 MSR = 1<<StateRegsEnum.MSR
195 SVSTATE = 1<<StateRegsEnum.SVSTATE
196 if name in ['cia', 'nia']:
197 wr = RegDecodeInfo(None, PC, 3) # hmmm
198 if name == 'msr':
199 wr = RegDecodeInfo(None, MSR, 3) # hmmm
200 if name == 'svstate':
201 wr = RegDecodeInfo(None, SVSTATE, 3) # hmmm
202
203 # FAST regfile
204
205 if regfile == 'FAST':
206 # FAST register numbering is *unary* encoded
207 if name == 'fast1':
208 wr = RegDecodeInfo(e.write_fast1.ok, e.write_fast1.data, 4)
209 if name == 'fast2':
210 wr = RegDecodeInfo(e.write_fast2.ok, e.write_fast2.data, 4)
211 if name == 'fast3':
212 wr = RegDecodeInfo(e.write_fast3.ok, e.write_fast3.data, 4)
213
214 # SPR regfile
215
216 if regfile == 'SPR':
217 # SPR register numbering is *binary* encoded
218 if name == 'spr1': # SPR1
219 wr = RegDecodeInfo(e.write_spr.ok, e.write_spr.data, 10)
220
221 assert wr is not None, "regspec not found %s %s" % (regfile, name)
222
223 rname="wr_decode_%s_%s" % (regfile, name)
224 if wr.okflag is not None:
225 ok = Signal(name=rname+"_ok", reset_less=True)
226 m.d.comb += ok.eq(wr.okflag)
227 else:
228 # XXX urrrr, really do have to deal with this some time
229 ok = None
230 data = Signal(wr.portlen, name=rname+"_port", reset_less=True)
231 m.d.comb += data.eq(wr.regport)
232
233 return RegDecodeInfo(ok, data, wr.portlen)
234
235
236 def regspec_decode(m, readmode, e, regfile, name):
237 if readmode:
238 return regspec_decode_read(m, e, regfile, name)
239 return regspec_decode_write(m, e, regfile, name)
240