add comments
[soc.git] / src / soc / experiment / compalu_multi.py
index 3e41739c3b5f0c877e98fc8888e4a9e020a9948d..784070452b3fd2f43e4c6b6d72952066d67ca9eb 100644 (file)
@@ -8,6 +8,7 @@ from nmutil.iocontrol import RecordObject
 
 from soc.decoder.power_decoder2 import Data
 from soc.decoder.power_enums import InternalOp
+from soc.fu.regspec import RegSpec, RegSpecALUAPI
 
 
 """ Computation Unit (aka "ALU Manager").
@@ -68,22 +69,8 @@ def go_record(n, name):
     return r
 
 # see https://libre-soc.org/3d_gpu/architecture/regfile/ section on regspecs
-def get_regspec_bitwidth(regspec, srcdest, idx):
-    bitspec = regspec[srcdest][idx]
-    wid = 0
-    print (bitspec)
-    for ranges in bitspec[2].split(","):
-        ranges = ranges.split(":")
-        print (ranges)
-        if len(ranges) == 1: # only one bit
-            wid += 1
-        else:
-            start, end = map(int, ranges)
-            wid += (end-start)+1
-    return wid
-
-
-class CompUnitRecord(RecordObject):
+
+class CompUnitRecord(RegSpec, RecordObject):
     """CompUnitRecord
 
     base class for Computation Units, to provide a uniform API
@@ -100,16 +87,11 @@ class CompUnitRecord(RecordObject):
     see https://libre-soc.org/3d_gpu/architecture/regfile/ section on regspecs
     """
     def __init__(self, subkls, rwid, n_src=None, n_dst=None, name=None):
+        RegSpec.__init__(self, rwid, n_src, n_dst)
         RecordObject.__init__(self, name)
-        self._rwid = rwid
-        if isinstance(rwid, int):
-            # rwid: integer (covers all registers)
-            self._n_src, self._n_dst = n_src, n_dst
-        else:
-            # rwid: a regspec.
-            self._n_src, self._n_dst = len(rwid[0]), len(rwid[1])
         self._subkls = subkls
 
+        # create source operands
         src = []
         for i in range(n_src):
             j = i + 1 # name numbering to match src1/src2
@@ -120,6 +102,7 @@ class CompUnitRecord(RecordObject):
             src.append(sreg)
         self._src_i = src
 
+        # create dest operands
         dst = []
         for i in range(n_dst):
             j = i + 1 # name numbering to match dest1/2...
@@ -130,31 +113,22 @@ class CompUnitRecord(RecordObject):
             dst.append(dreg)
         self._dest = dst
 
+        # operation / data input
+        self.oper_i = subkls() # operand
+
+        # create read/write and other scoreboard signalling
         self.rd = go_record(n_src, name="rd") # read in, req out
         self.wr = go_record(n_dst, name="wr") # write in, req out
         self.issue_i = Signal(reset_less=True) # fn issue in
         self.shadown_i = Signal(reset=1) # shadow function, defaults to ON
         self.go_die_i = Signal() # go die (reset)
 
-        # operation / data input
-        self.oper_i = subkls() # operand
-
         # output (busy/done)
         self.busy_o = Signal(reset_less=True) # fn busy out
         self.done_o = Signal(reset_less=True)
 
-    def _get_dstwid(self, i):
-        if isinstance(self._rwid, int):
-            return self._rwid
-        return get_regspec_bitwidth(self._rwid, 1, i)
-
-    def _get_srcwid(self, i):
-        if isinstance(self._rwid, int):
-            return self._rwid
-        return get_regspec_bitwidth(self._rwid, 0, i)
-
 
-class MultiCompUnit(Elaboratable):
+class MultiCompUnit(RegSpecALUAPI, Elaboratable):
     def __init__(self, rwid, alu, opsubsetkls, n_src=2, n_dst=1):
         """MultiCompUnit
 
@@ -164,23 +138,24 @@ class MultiCompUnit(Elaboratable):
         * :n_src:       number of src operands
         * :n_dst:       number of destination operands
         """
+        RegSpecALUAPI.__init__(self, rwid, alu)
         self.n_src, self.n_dst = n_src, n_dst
-        self.rwid = rwid
         self.opsubsetkls = opsubsetkls
-        self.alu = alu # actual ALU - set as a "submodule" of the CU
         self.cu = cu = CompUnitRecord(opsubsetkls, rwid, n_src, n_dst)
 
+        # convenience names for src operands
         for i in range(n_src):
             j = i + 1 # name numbering to match src1/src2
             name = "src%d_i" % j
             setattr(self, name, getattr(cu, name))
 
+        # convenience names for dest operands
         for i in range(n_dst):
             j = i + 1 # name numbering to match dest1/2...
             name = "dest%d_i" % j
             setattr(self, name, getattr(cu, name))
 
-        # convenience names
+        # more convenience names
         self.rd = cu.rd
         self.wr = cu.wr
         self.go_rd_i = self.rd.go # temporary naming
@@ -200,22 +175,6 @@ class MultiCompUnit(Elaboratable):
         self.data_o = self.dest[0] # Dest out
         self.done_o = cu.done_o
 
-    def get_out(self, i):
-        if isinstance(self.rwid, int): # old - testing - API (rwid is int)
-            return self.alu.out[i]
-        # regspec-based API: look up variable through regspec according to row number
-        return getattr(self.alu.n.data_o, self.rwid[1][i][1])
-
-    def get_in(self, i):
-        if isinstance(self.rwid, int): # old - testing - API (rwid is int)
-            return self.alu.i[i]
-        # regspec-based API: look up variable through regspec according to row number
-        return getattr(self.alu.p.data_i, self.rwid[0][i][1])
-
-    def get_op(self):
-        if isinstance(self.rwid, int): # old - testing - API (rwid is int)
-            return self.alu.op
-        return self.alu.p.data_i.ctx.op
     def elaborate(self, platform):
         m = Module()
         m.submodules.alu = self.alu