okaaay add a "rdflags" function which obtains the yes/no flags for each register...
[soc.git] / src / soc / fu / regspec.py
1 """RegSpecs
2
3 see https://libre-soc.org/3d_gpu/architecture/regfile/ section on regspecs
4
5 this module is a key strategic module that links pipeline specifications
6 (soc.fu.*.pipe_data and soc.fo.*.pipeline) to MultiCompUnits. MultiCompUnits
7 know absolutely nothing about the data passing through them: all they know
8 is: how many inputs they need to manage, and how many outputs.
9
10 regspecs tell MultiCompUnit what the ordering of the inputs is, how many to
11 create, and how to connect them up to the ALU being "managed" by this CompUnit.
12 likewise for outputs.
13
14 later (TODO) the Register Files will be connected to MultiCompUnits, and,
15 again, the regspecs will say which Regfile (which type) is connected to
16 which MultiCompUnit port, how wide the connection is, and so on.
17
18 """
19
20
21 def get_regspec_bitwidth(regspec, srcdest, idx):
22 print ("get_regspec_bitwidth", regspec, srcdest, idx)
23 bitspec = regspec[srcdest][idx]
24 wid = 0
25 print (bitspec)
26 for ranges in bitspec[2].split(","):
27 ranges = ranges.split(":")
28 print (ranges)
29 if len(ranges) == 1: # only one bit
30 wid += 1
31 else:
32 start, end = map(int, ranges)
33 wid += (end-start)+1
34 return wid
35
36
37 class RegSpec:
38 def __init__(self, rwid, n_src=None, n_dst=None, name=None):
39 self._rwid = rwid
40 if isinstance(rwid, int):
41 # rwid: integer (covers all registers)
42 self._n_src, self._n_dst = n_src, n_dst
43 else:
44 # rwid: a regspec.
45 self._n_src, self._n_dst = len(rwid[0]), len(rwid[1])
46
47 def _get_dstwid(self, i):
48 if isinstance(self._rwid, int):
49 return self._rwid
50 return get_regspec_bitwidth(self._rwid, 1, i)
51
52 def _get_srcwid(self, i):
53 if isinstance(self._rwid, int):
54 return self._rwid
55 return get_regspec_bitwidth(self._rwid, 0, i)
56
57
58 class RegSpecALUAPI:
59 def __init__(self, rwid, alu):
60 """RegSpecAPI
61
62 * :rwid: regspec
63 * :alu: ALU covered by this regspec
64 """
65 self.rwid = rwid
66 self.alu = alu # actual ALU - set as a "submodule" of the CU
67
68 def get_in_name(self, i):
69 return self.rwid[0][i][1]
70
71 def get_out_name(self, i):
72 return self.rwid[1][i][1]
73
74 def get_out(self, i):
75 if isinstance(self.rwid, int): # old - testing - API (rwid is int)
76 return self.alu.out[i]
77 # regspec-based API: look up variable through regspec thru row number
78 return getattr(self.alu.n.data_o, self.get_out_name(i))
79
80 def get_in(self, i):
81 if isinstance(self.rwid, int): # old - testing - API (rwid is int)
82 return self.alu.i[i]
83 # regspec-based API: look up variable through regspec thru row number
84 return getattr(self.alu.p.data_i, self.get_in_name(i))
85
86 def get_op(self):
87 if isinstance(self.rwid, int): # old - testing - API (rwid is int)
88 return self.alu.op
89 return self.alu.p.data_i.ctx.op