97df57aeb7889eb35fd44fabbd97ccfd2e30b64f
[openpower-isa.git] / src / openpower / decoder / isa / svshape.py
1 from openpower.decoder.selectable_int import (FieldSelectableInt, SelectableInt,
2 selectconcat)
3 from openpower.decoder.isa.remapyield import iterate_indices
4 from openpower.decoder.isa.remap_fft_yield import iterate_butterfly_indices
5 from openpower.sv.svp64 import SVP64SHAPE
6 import os
7 from copy import deepcopy
8 from openpower.util import log
9
10
11 class SVSHAPE(SelectableInt):
12 def __init__(self, value):
13 SelectableInt.__init__(self, value, 32)
14 offs = 0
15 # set up sub-fields from Record layout
16 self.fsi = {}
17 l = deepcopy(SVP64SHAPE.layout)
18 l.reverse()
19 for field, width in l:
20 end = offs+width
21 fs = tuple(range(offs, end))
22 v = FieldSelectableInt(self, fs)
23 self.fsi[field] = v
24 #log("SVSHAPE setup field", field, offs, end)
25 offs = end
26
27 @property
28 def order(self):
29 permute = self.fsi['permute'].asint(msb0=True)
30 return SVP64SHAPE.order(permute)
31
32 @order.setter
33 def order(self, value):
34 rorder = SVP64SHAPE.rorder(value)
35 self.fsi['permute'].eq(rorder)
36
37 @property
38 def xdimsz(self):
39 return self.fsi['xdimsz'].asint(msb0=True)+1
40
41 @xdimsz.setter
42 def xdimsz(self, value):
43 self.fsi['xdimsz'].eq(value-1)
44
45 @property
46 def ydimsz(self):
47 return self.fsi['ydimsz'].asint(msb0=True)+1
48
49 @ydimsz.setter
50 def ydimsz(self, value):
51 self.fsi['ydimsz'].eq(value-1)
52
53 @property
54 def zdimsz(self):
55 return self.fsi['zdimsz'].asint(msb0=True)+1
56
57 @zdimsz.setter
58 def zdimsz(self, value):
59 self.fsi['zdimsz'].eq(value-1)
60
61 @property
62 def lims(self):
63 return [self.xdimsz, self.ydimsz, self.zdimsz]
64
65 @lims.setter
66 def lims(self, value):
67 self.xdimsz = value[0]
68 self.ydimsz = value[1]
69 self.zdimsz = value[2]
70
71 @property
72 def invxyz(self):
73 inv = self.fsi['invxyz'].asint(msb0=True)
74 return [(inv & 0b1), (inv & 0b10) >> 1, (inv & 0b100) >> 2]
75
76 @invxyz.setter
77 def invxyz(self, value):
78 self.fsi['invxyz'].eq(value[0] | (value[1]<<1) | (value[2]<<2))
79
80 @property
81 def mode(self):
82 return self.fsi['mode'].asint(msb0=True)
83
84 @mode.setter
85 def mode(self, value):
86 self.fsi['mode'].eq(value)
87
88 @property
89 def skip(self):
90 return self.fsi['skip'].asint(msb0=True)
91
92 @skip.setter
93 def skip(self, value):
94 self.fsi['skip'].eq(value)
95
96 @property
97 def offset(self):
98 return self.fsi['offset'].asint(msb0=True)
99
100 @offset.setter
101 def offset(self, value):
102 self.fsi['offset'].eq(value)
103
104 def get_iterator(self):
105 if self.mode == 0b00:
106 iterate_fn = iterate_indices
107 elif self.mode == 0b01:
108 iterate_fn = iterate_butterfly_indices
109 # create a **NEW** iterator each time this is called
110 return iterate_fn(deepcopy(self))
111
112
113 if __name__ == '__main__':
114 os.environ['SILENCELOG'] = "1"
115 xdim = 3
116 ydim = 2
117 zdim = 1
118 SVSHAPE0 = SVSHAPE(0)
119 SVSHAPE0.lims = [xdim, ydim, zdim]
120 SVSHAPE0.order = [1,0,2] # experiment with different permutations, here
121 SVSHAPE0.mode = 0b00
122 SVSHAPE0.skip = 0b00
123 SVSHAPE0.offset = 0 # experiment with different offset, here
124 SVSHAPE0.invxyz = [0,0,0] # inversion if desired
125
126 VL = xdim * ydim * zdim
127
128 print ("Matrix Mode")
129 for idx, new_idx in enumerate(SVSHAPE0.get_iterator()):
130 if idx >= VL:
131 break
132 print ("%d->%d" % (idx, new_idx))
133
134 print ("")
135 print ("FFT Mode")
136
137 # set the dimension sizes here
138 xdim = 8
139 ydim = 0 # not needed
140 zdim = 0 # again, not needed
141
142 # set total. err don't know how to calculate how many there are...
143 # do it manually for now
144
145 VL = 0
146 size = 2
147 n = xdim
148 while size <= n:
149 halfsize = size // 2
150 tablestep = n // size
151 for i in range(0, n, size):
152 for j in range(i, i + halfsize):
153 VL += 1
154 size *= 2
155
156 # j schedule
157 SVSHAPE0 = SVSHAPE(0)
158 SVSHAPE0.lims = [xdim, ydim, zdim]
159 SVSHAPE0.order = [0,1,2] # experiment with different permutations, here
160 SVSHAPE0.mode = 0b00
161 SVSHAPE0.offset = 0 # experiment with different offset, here
162 SVSHAPE0.invxyz = [0,0,0] # inversion if desired
163 # j+halfstep schedule
164 SVSHAPE1 = SVSHAPE(0)
165 SVSHAPE1.lims = [xdim, ydim, zdim]
166 SVSHAPE1.order = [0,1,2] # experiment with different permutations, here
167 SVSHAPE1.mode = 0b01
168 SVSHAPE1.offset = 0 # experiment with different offset, here
169 SVSHAPE1.invxyz = [0,0,0] # inversion if desired
170 # k schedule
171 SVSHAPE2 = SVSHAPE(0)
172 SVSHAPE2.lims = [xdim, ydim, zdim]
173 SVSHAPE2.order = [0,1,2] # experiment with different permutations, here
174 SVSHAPE2.mode = 0b10
175 SVSHAPE2.offset = 0 # experiment with different offset, here
176 SVSHAPE2.invxyz = [0,0,0] # inversion if desired
177
178 # enumerate over the iterator function, getting new indices
179 schedule = []
180 for idx, (jl, jh, k) in enumerate(zip(iterate_indices(SVSHAPE0),
181 iterate_indices(SVSHAPE1),
182 iterate_indices(SVSHAPE2))):
183 if idx >= VL:
184 break
185 schedule.append((jl, jh, k))
186
187 # ok now pretty-print the results, with some debug output
188 size = 2
189 idx = 0
190 while size <= n:
191 halfsize = size // 2
192 tablestep = n // size
193 print ("size %d halfsize %d tablestep %d" % \
194 (size, halfsize, tablestep))
195 for i in range(0, n, size):
196 prefix = "i %d\t" % i
197 k = 0
198 for j in range(i, i + halfsize):
199 jl, jh, ks = schedule[idx]
200 print (" %-3d\t%s j=%-2d jh=%-2d k=%-2d -> "
201 "j[jl=%-2d] j[jh=%-2d] exptable[k=%d]" % \
202 (idx, prefix, j, j+halfsize, k,
203 jl, jh, ks))
204 k += tablestep
205 idx += 1
206 size *= 2
207