From a0a2b3334edd31cf75fb9344a8b1d069d4881cd8 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sat, 11 Jul 2020 23:48:46 +0100 Subject: [PATCH] sort out core write latching: gate by busy, and use CompUnit dest output --- src/soc/experiment/compalu_multi.py | 5 ++++- src/soc/experiment/compldst_multi.py | 3 +++ src/soc/simple/core.py | 14 +++++++++----- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/soc/experiment/compalu_multi.py b/src/soc/experiment/compalu_multi.py index d1a4a325..bfe06c59 100644 --- a/src/soc/experiment/compalu_multi.py +++ b/src/soc/experiment/compalu_multi.py @@ -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 diff --git a/src/soc/experiment/compldst_multi.py b/src/soc/experiment/compldst_multi.py index 5a91dca3..014ccbe0 100644 --- a/src/soc/experiment/compldst_multi.py +++ b/src/soc/experiment/compldst_multi.py @@ -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 diff --git a/src/soc/simple/core.py b/src/soc/simple/core.py index ebf0e888..ac88893e 100644 --- a/src/soc/simple/core.py +++ b/src/soc/simple/core.py @@ -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): -- 2.30.2