convert branch pipeline to use msr/cia as immediates
[soc.git] / src / soc / fu / pipe_data.py
index 764de09fbda099faccf957cd132fdd5eb73e999f..13e854344c3eb3cbdb9b2e2857619da443f28bc8 100644 (file)
@@ -1,17 +1,83 @@
-from ieee754.fpcommon.getop import FPPipeContext
+from nmutil.concurrentunit import PipeContext
+from nmutil.dynamicpipe import SimpleHandshakeRedir
+from nmigen import Signal
+from soc.decoder.power_decoder2 import Data
+from soc.fu.regspec import get_regspec_bitwidth
 
 
 class IntegerData:
+    """IntegerData: base class for all pipeline data structures
 
-    def __init__(self, pspec):
-        self.ctx = FPPipeContext(pspec)
+    this class auto-constructs parameters (placing them in self.data)
+    based on "regspecs".  this is conceptually similar to nmigen Record
+    (Layout, actually) except that Layout does not contain the right type
+    of information for connecting up to Register Files.
+
+    by having a base class that handles creation of pipeline input/output
+    in a structured fashion, CompUnits may conform to that same structured
+    API, and when it comes to actually connecting up to regfiles, the same
+    holds true.
+
+    the alternative is mountains of explicit code (which quickly becomes
+    unmaintainable).
+
+    note the mode parameter - output.  output pipeline data structures
+    need to have an "ok" flag added, which is used by the CompUnit and
+    by the Register File to determine if the output shall in fact be
+    written to the register file or not.
+
+    input data has *already* been determined to have had to have been read,
+    this by PowerDecoder2.
+    """
+
+    def __init__(self, pspec, output):
+        self.ctx = PipeContext(pspec) # context for ReservationStation usage
         self.muxid = self.ctx.muxid
+        self.data = []
+        self.is_output = output
+        for i, (regfile, regname, widspec) in enumerate(self.regspec):
+            wid = get_regspec_bitwidth([self.regspec], 0, i)
+            if output:
+                sig = Data(wid, name=regname)
+            else:
+                sig = Signal(wid, name=regname, reset_less=True)
+            setattr(self, regname, sig)
+            self.data.append(sig)
 
     def __iter__(self):
         yield from self.ctx
+        yield from self.data
 
     def eq(self, i):
-        return [self.ctx.eq(i.ctx)]
+        eqs = [self.ctx.eq(i.ctx)]
+        assert len(self.data) == len(i.data), \
+               "length of %s mismatch against %s: %s %s" % \
+                   (repr(self), repr(i), repr(self.data), repr(i.data))
+        for j in range(len(self.data)):
+            assert type(self.data[j]) == type(i.data[j]), \
+                   "type mismatch in IntegerData %s %s" % \
+                   (repr(self.data[j]), repr(i.data[j]))
+            eqs.append(self.data[j].eq(i.data[j]))
+        return eqs
 
     def ports(self):
-        return self.ctx.ports()
+        return self.ctx.ports() # TODO: include self.data
+
+
+# hmmm there has to be a better way than this
+def get_rec_width(rec):
+    recwidth = 0
+    # Setup random inputs for dut.op
+    for p in rec.ports():
+        width = p.width
+        recwidth += width
+    return recwidth
+
+
+class CommonPipeSpec:
+    def __init__(self, id_wid):
+        self.pipekls = SimpleHandshakeRedir
+        self.id_wid = id_wid
+        self.opkls = lambda _: self.opsubsetkls(name="op")
+        self.op_wid = get_rec_width(self.opkls(None)) # hmm..
+        self.stage = None