From f6135c847d3801087695086d1c28e9474035350c Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Tue, 11 Aug 2020 14:32:25 +0100 Subject: [PATCH] prepare write ports to be shared --- src/soc/simple/core.py | 89 ++++++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 38 deletions(-) diff --git a/src/soc/simple/core.py b/src/soc/simple/core.py index 1ebde173..de5fa6cd 100644 --- a/src/soc/simple/core.py +++ b/src/soc/simple/core.py @@ -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)) -- 2.30.2