add XLEN option to regfiles via pspec
[soc.git] / src / soc / regfile / regfiles.py
index 1ce560e9da8cb3bd51f13ee06aa72b5ede15a1e4..5ef301a8bf8bdbda55ad86131fd5f54ea66b5fe8 100644 (file)
@@ -33,6 +33,7 @@ from openpower.consts import StateRegsEnum, XERRegsEnum, FastRegsEnum
 
 from nmigen import Module
 from nmigen.cli import rtlil
+from nmutil.latch import SRLatch
 
 
 def create_ports(rf, wr_spec, rd_spec):
@@ -69,20 +70,36 @@ class StateRegs(RegFileArray, StateRegsEnum):
     (d_rd2)
 
     """
-    def __init__(self, svp64_en=False, regreduce_en=False):
-        super().__init__(64, StateRegsEnum.N_REGS)
+    def __init__(self, svp64_en=False, regreduce_en=False, resets=None):
+        super().__init__(64, StateRegsEnum.N_REGS, resets=resets)
         wr_spec, rd_spec = self.get_port_specs()
         create_ports(self, wr_spec, rd_spec)
 
     def get_port_specs(self):
-        w_port_spec = {'nia': "nia",
+        w_port_spec = { # these 3 allow writing state by Function Units
+                        # strictly speaking this should not be allowed,
+                        # the information should be passed back to Issuer
+                        # to work out what to do
+                        'nia': "nia",
                         'msr': "msr",
                         'svstate': "svstate",
-                        'sv': "sv", # writing SVSTATE (issuer)
-                        'd_wr1': "d_wr1"} # writing PC (issuer)
-        r_port_spec = {'cia': "cia", # reading PC (issuer)
+                        'issue': "issue", # writing DEC/TB
+                        'state1': "state1", # SPR pipeline
+                        # these 3 allow writing state by Issuer
+                        'sv': "sv", # writing SVSTATE
+                        'd_wr1': "d_wr1", # writing PC
+                        'd_wr2': "d_wr2"} # writing MSR
+        r_port_spec = { # these are for reading state by Issuer but
+                        # the FUs do not read them: they are passed in
+                        # because of multi-issue / pipelining / etc.
+                        # the state could be totally different and is
+                        # only known *at* issue time, *by* the issuer
+                        'cia': "cia", # reading PC (issuer)
                         'msr': "msr", # reading MSR (issuer)
                         'sv': "sv", # reading SV (issuer)
+                        # SPR and DEC/TB FSM
+                        'issue': "issue", # reading DEC/TB
+                        'state1': "state1", # SPR pipeline
                         }
         return w_port_spec, r_port_spec
 
@@ -96,8 +113,8 @@ class IntRegs(RegFileMem): #class IntRegs(RegFileArray):
     * Array-based unary-indexed (not binary-indexed)
     * write-through capability (read on same cycle as write)
     """
-    def __init__(self, svp64_en=False, regreduce_en=False):
-        super().__init__(64, 32, fwd_bus_mode=not regreduce_en)
+    def __init__(self, svp64_en=False, regreduce_en=False, reg_wid=64):
+        super().__init__(reg_wid, 32, fwd_bus_mode=False)
         self.svp64_en = svp64_en
         self.regreduce_en = regreduce_en
         wr_spec, rd_spec = self.get_port_specs()
@@ -124,7 +141,7 @@ class IntRegs(RegFileMem): #class IntRegs(RegFileArray):
 class FastRegs(RegFileMem, FastRegsEnum): #RegFileArray):
     """FastRegs
 
-    FAST regfile  - CTR, LR, TAR, SRR1, SRR2, XER, TB, DEC, SVSRR0
+    FAST regfile  - CTR, LR, TAR, SRR1, SRR2, XER, SVSRR0
 
     * QTY 6of 64-bit registers
     * 3R2W
@@ -134,7 +151,7 @@ class FastRegs(RegFileMem, FastRegsEnum): #RegFileArray):
     Note: r/w issue are used by issuer to increment/decrement TB/DEC.
     """
     def __init__(self, svp64_en=False, regreduce_en=False):
-        super().__init__(64, FastRegsEnum.N_REGS, fwd_bus_mode=not regreduce_en)
+        super().__init__(64, FastRegsEnum.N_REGS, fwd_bus_mode=False)
         self.svp64_en = svp64_en
         self.regreduce_en = regreduce_en
         wr_spec, rd_spec = self.get_port_specs()
@@ -142,13 +159,15 @@ class FastRegs(RegFileMem, FastRegsEnum): #RegFileArray):
 
     def get_port_specs(self):
         w_port_spec = {'fast1': "dest1",
-                       'issue': "issue", # writing DEC/TB
                        }
         r_port_spec = {'fast1': "src1",
-                       'issue': "issue", # reading DEC/TB
+                        'dmi': "dmi" # needed for Debug (DMI)
                         }
         if not self.regreduce_en:
             r_port_spec['fast2'] = "src2"
+            r_port_spec['fast3'] = "src3"
+            w_port_spec['fast2'] = "dest2"
+            w_port_spec['fast3'] = "dest3"
 
         return w_port_spec, r_port_spec
 
@@ -230,7 +249,7 @@ class SPRRegs(RegFileMem):
         else:
             n_sprs = len(SPRfull)
         super().__init__(width=64, depth=n_sprs,
-                         fwd_bus_mode=not regreduce_en)
+                         fwd_bus_mode=False)
         self.svp64_en = svp64_en
         self.regreduce_en = regreduce_en
         wr_spec, rd_spec = self.get_port_specs()
@@ -251,7 +270,8 @@ class RegFiles:
               ('fast', FastRegs),
               ('state', StateRegs),
               ('spr', SPRRegs),]
-    def __init__(self, pspec, make_hazard_vecs=False):
+    def __init__(self, pspec, make_hazard_vecs=False,
+                      state_resets=None): # state file reset values
         # test is SVP64 is to be enabled
         svp64_en = hasattr(pspec, "svp64") and (pspec.svp64 == True)
 
@@ -259,46 +279,42 @@ class RegFiles:
         regreduce_en = hasattr(pspec, "regreduce") and \
                       (pspec.regreduce == True)
 
+        # get Integer File register width
+        reg_wid = 64
+        if isinstance(pspec.XLEN, int):
+            reg_wid = pspec.XLEN
+
         self.rf = {} # register file dict
         # create regfiles here, Factory style
         for (name, kls) in RegFiles.regkls:
-            rf = self.rf[name] = kls(svp64_en, regreduce_en)
+            kwargs = {'svp64_en': svp64_en, 'regreduce_en': regreduce_en}
+            if name == 'state':
+                kwargs['resets'] = state_resets
+            if name == 'int':
+                kwargs['reg_wid'] = reg_wid
+            rf = self.rf[name] = kls(**kwargs)
             # also add these as instances, self.state, self.fast, self.cr etc.
             setattr(self, name, rf)
 
         self.rv, self.wv = {}, {}
         if make_hazard_vecs:
             # create a read-hazard and write-hazard vectors for this regfile
-            self.wv = make_vecs(self, "wr") # global write vectors
-            self.rv = make_vecs(self, "rd") # global read vectors
+            self.wv = self.make_vecs("wr") # global write vectors
+            self.rv = self.make_vecs("rd") # global read vectors
 
     def make_vecs(self, name):
         vec = {}
         # create regfiles here, Factory style
         for (name, kls) in RegFiles.regkls:
+            rf = self.rf[name]
             vec[name] = self.make_hazard_vec(rf, name)
         return vec
 
     def make_hazard_vec(self, rf, name):
         if isinstance(rf, VirtualRegPort):
-            vec = RegFileArray(rf.bitwidth, 1)
-        else:
-            vec = RegFileArray(rf.depth, 1)
-        if name in ['int', 'cr', 'xer']:
-            n_wrs = 3
-        elif name in ['fast']:
-            n_wrs = 2
+            vec = SRLatch(sync=False, llen=rf.nregs, name=name)
         else:
-            n_wrs = 1
-        # add write ports
-        vec.w_ports = {}
-        for i in range(n_wrs):
-            pname = "wr%d" % i
-            vec.w_ports[pname] = vec.write_port("%s_%s" % (name, pname))
-        # add read port
-        vec.r_ports = {}
-        pname = "rd%d" % 0
-        vec.r_ports[pname] = vec.read_port("%s_%s" % (name, pname))
+            vec = SRLatch(sync=False, llen=rf.depth, name=name)
         return vec
 
     def elaborate_into(self, m, platform):
@@ -313,7 +329,8 @@ class RegFiles:
 if __name__ == '__main__':
     m = Module()
     from soc.config.test.test_loadstore import TestMemPspec
-    pspec = TestMemPspec()
+    pspec = TestMemPspec(regreduce_en=True,
+                         XLEN=32) # integer reg width = 32
     rf = RegFiles(pspec, make_hazard_vecs=True)
     rf.elaborate_into(m, None)
     vl = rtlil.convert(m)