split out RegSpecs into separate module
[soc.git] / src / soc / fu / regspec.py
1 # see https://libre-soc.org/3d_gpu/architecture/regfile/ section on regspecs
2
3 def get_regspec_bitwidth(regspec, srcdest, idx):
4 bitspec = regspec[srcdest][idx]
5 wid = 0
6 print (bitspec)
7 for ranges in bitspec[2].split(","):
8 ranges = ranges.split(":")
9 print (ranges)
10 if len(ranges) == 1: # only one bit
11 wid += 1
12 else:
13 start, end = map(int, ranges)
14 wid += (end-start)+1
15 return wid
16
17
18 class RegSpec:
19 def __init__(self, rwid, n_src=None, n_dst=None, name=None):
20 self._rwid = rwid
21 if isinstance(rwid, int):
22 # rwid: integer (covers all registers)
23 self._n_src, self._n_dst = n_src, n_dst
24 else:
25 # rwid: a regspec.
26 self._n_src, self._n_dst = len(rwid[0]), len(rwid[1])
27
28 def _get_dstwid(self, i):
29 if isinstance(self._rwid, int):
30 return self._rwid
31 return get_regspec_bitwidth(self._rwid, 1, i)
32
33 def _get_srcwid(self, i):
34 if isinstance(self._rwid, int):
35 return self._rwid
36 return get_regspec_bitwidth(self._rwid, 0, i)
37
38
39 class RegSpecALUAPI:
40 def __init__(self, rwid, alu):
41 """RegSpecAPI
42
43 * :rwid: regspec
44 * :alu: ALU covered by this regspec
45 """
46 self.rwid = rwid
47 self.alu = alu # actual ALU - set as a "submodule" of the CU
48
49 def get_out(self, i):
50 if isinstance(self.rwid, int): # old - testing - API (rwid is int)
51 return self.alu.out[i]
52 # regspec-based API: look up variable through regspec according to row number
53 return getattr(self.alu.n.data_o, self.rwid[1][i][1])
54
55 def get_in(self, i):
56 if isinstance(self.rwid, int): # old - testing - API (rwid is int)
57 return self.alu.i[i]
58 # regspec-based API: look up variable through regspec according to row number
59 return getattr(self.alu.p.data_i, self.rwid[0][i][1])
60
61 def get_op(self):
62 if isinstance(self.rwid, int): # old - testing - API (rwid is int)
63 return self.alu.op
64 return self.alu.p.data_i.ctx.op