sort out core write latching: gate by busy, and use CompUnit dest output
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 11 Jul 2020 22:48:46 +0000 (23:48 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 11 Jul 2020 22:48:46 +0000 (23:48 +0100)
src/soc/experiment/compalu_multi.py
src/soc/experiment/compldst_multi.py
src/soc/simple/core.py

index d1a4a325d348d3742a9311e782fa906bb283e2fe..bfe06c592ed2f8a6f1d0492b3eb9b434073b2a45 100644 (file)
@@ -346,11 +346,14 @@ class MultiCompUnit(RegSpecALUAPI, Elaboratable):
 
         # output the data from the latch on go_write
         for i in range(self.n_dst):
-            with m.If(self.wr.go[i]):
+            with m.If(self.wr.go[i] & self.busy_o):
                 m.d.comb += self.dest[i].eq(drl[i])
 
         return m
 
+    def get_fu_out(self, i):
+        return self.dest[i]
+
     def __iter__(self):
         yield self.rd.go
         yield self.wr.go
index 5a91dca392669ff19fef736dbc2296332ae35555..014ccbe0f376c9c925f552caebd51dd8412f3b98 100644 (file)
@@ -506,6 +506,9 @@ class LDSTCompUnit(RegSpecAPI, Elaboratable):
             return self.addr_o
         #return self.dest[i]
 
+    def get_fu_out(self, i):
+        return self.get_out(i)
+
     def __iter__(self):
         yield self.rd.go
         yield self.go_ad_i
index ebf0e888e696f4dba3db196dc69bc3d3ade4241e..ac88893ec0a5d5c8d13933ed8a408b0de3cffc89 100644 (file)
@@ -41,6 +41,9 @@ import operator
 def ortreereduce(tree, attr="data_o"):
     return treereduce(tree, operator.or_, lambda x: getattr(x, attr))
 
+def ortreereduce_sig(tree):
+    return treereduce(tree, operator.or_, lambda x: x)
+
 
 # helper function to place full regs declarations first
 def sort_fuspecs(fuspecs):
@@ -266,9 +269,9 @@ class NonProductionCore(Elaboratable):
                 # only if one FU actually requests (and is granted) the port
                 # will the write-enable be activated
                 with m.If(wrpick.en_o):
-                    sync += wport.wen.eq(write)
+                    comb += wport.wen.eq(write)
                 with m.Else():
-                    sync += wport.wen.eq(0)
+                    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
@@ -276,6 +279,7 @@ class NonProductionCore(Elaboratable):
                 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)
@@ -284,15 +288,15 @@ class NonProductionCore(Elaboratable):
                     fu_active = fu_bitdict[funame]
                     pick = fu.wr.rel[idx] & fu_active #& wrflag
                     comb += wrpick.i[pi].eq(pick)
-                    sync += fu.go_wr_i[idx].eq(wrpick.o[pi] & wrpick.en_o)
+                    comb += fu.go_wr_i[idx].eq(wrpick.o[pi] & wrpick.en_o)
                     # connect regfile port to input
                     print ("reg connect widths",
                            regfile, regname, pi, funame,
                            dest.shape(), wport.data_i.shape())
-                    wsigs.append(dest)
+                    wsigs.append(fu_dest_latch)
 
                 # here is where we create the Write Broadcast Bus. simple, eh?
-                sync += wport.data_i.eq(ortreereduce(wsigs, "data"))
+                comb += wport.data_i.eq(ortreereduce_sig(wsigs))
 
     def get_byregfiles(self, readmode):