prepare write ports to be shared
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 11 Aug 2020 13:32:25 +0000 (14:32 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 11 Aug 2020 13:32:25 +0000 (14:32 +0100)
src/soc/simple/core.py

index 1ebde173a20ab777b62dc38ec4ea0e9d2be6c3d6..de5fa6cd95131abfe03d2b2b5daf0ffe16ba267a 100644 (file)
@@ -281,51 +281,64 @@ class NonProductionCore(Elaboratable):
 
         print("connect wr", regname, fspec)
         rpidx = regname
-        # get the regfile specs for this regfile port
-        (rf, read, write, wid, fuspec) = fspec
 
         # select the required write port.  these are pre-defined sizes
         print(regfile, regs.rf.keys())
         wport = regs.rf[regfile.lower()].w_ports[rpidx]
 
+        fspecs = fspec
+        if not isinstance(fspecs, list):
+            fspecs = [fspecs]
+
+        pplen = 0
+        writes = []
+        ppoffs = []
+        for i, fspec in enumerate(fspecs):
+            # get the regfile specs for this regfile port
+            (rf, read, write, wid, fuspec) = fspec
+            print ("fpsec", i, fspec, len(fuspec))
+            ppoffs.append(pplen) # record offset for picker
+            pplen += len(fuspec)
+
         # create a priority picker to manage this port
-        wrpickers[regfile][rpidx] = wrpick = PriorityPicker(
-            len(fuspec))
-        setattr(m.submodules, "wrpick_%s_%s" %
-                (regfile, rpidx), wrpick)
-
-        # connect the regspec write "reg select" number to this port
-        # only if one FU actually requests (and is granted) the port
-        # will the write-enable be activated
-        with m.If(wrpick.en_o):
-            comb += wport.wen.eq(write)
-        with m.Else():
-            comb += wport.wen.eq(0)
-
-        # connect up the FU req/go signals and the reg-read to the FU
-        # these are arbitrated by Data.ok signals
+        wrpickers[regfile][rpidx] = wrpick = PriorityPicker(pplen)
+        setattr(m.submodules, "wrpick_%s_%s" % (regfile, rpidx), wrpick)
+
         wsigs = []
-        for pi, (funame, fu, idx) in enumerate(fuspec):
-            # write-request comes from dest.ok
-            dest = fu.get_out(idx)
-            fu_dest_latch = fu.get_fu_out(idx)  # latched output
-            name = "wrflag_%s_%s_%d" % (funame, regname, idx)
-            wrflag = Signal(name=name, reset_less=True)
-            comb += wrflag.eq(dest.ok & fu.busy_o)
-
-            # connect request-write to picker input, and output to go-wr
-            fu_active = fu_bitdict[funame]
-            pick = fu.wr.rel_o[idx] & fu_active  # & wrflag
-            comb += wrpick.i[pi].eq(pick)
-            # create a single-pulse go write from the picker output
-            wr_pick = Signal()
-            comb += wr_pick.eq(wrpick.o[pi] & wrpick.en_o)
-            comb += fu.go_wr_i[idx].eq(rising_edge(m, wr_pick))
-            # connect regfile port to input
-            print("reg connect widths",
-                  regfile, regname, pi, funame,
-                  dest.shape(), wport.data_i.shape())
-            wsigs.append(fu_dest_latch)
+        for i, fspec in enumerate(fspecs):
+            # connect up the FU req/go signals and the reg-read to the FU
+            # these are arbitrated by Data.ok signals
+            (rf, read, write, wid, fuspec) = fspec
+            for pi, (funame, fu, idx) in enumerate(fuspec):
+                pi += ppoffs[i]
+
+                # write-request comes from dest.ok
+                dest = fu.get_out(idx)
+                fu_dest_latch = fu.get_fu_out(idx)  # latched output
+                name = "wrflag_%s_%s_%d" % (funame, regname, idx)
+                wrflag = Signal(name=name, reset_less=True)
+                comb += wrflag.eq(dest.ok & fu.busy_o)
+
+                # connect request-write to picker input, and output to go-wr
+                fu_active = fu_bitdict[funame]
+                pick = fu.wr.rel_o[idx] & fu_active  # & wrflag
+                comb += wrpick.i[pi].eq(pick)
+                # create a single-pulse go write from the picker output
+                wr_pick = Signal()
+                comb += wr_pick.eq(wrpick.o[pi] & wrpick.en_o)
+                comb += fu.go_wr_i[idx].eq(rising_edge(m, wr_pick))
+
+                # connect the regspec write "reg select" number to this port
+                # only if one FU actually requests (and is granted) the port
+                # will the write-enable be activated
+                with m.If(wr_pick & wrpick.en_o):
+                    comb += wport.wen.eq(write)
+
+                # connect regfile port to input
+                print("reg connect widths",
+                      regfile, regname, pi, funame,
+                      dest.shape(), wport.data_i.shape())
+                wsigs.append(fu_dest_latch)
 
         # here is where we create the Write Broadcast Bus. simple, eh?
         comb += wport.data_i.eq(ortreereduce_sig(wsigs))