From: Luke Kenneth Casson Leighton Date: Tue, 16 Nov 2021 18:54:21 +0000 (+0000) Subject: use a virtual regfile port for the hazard bitvectors X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b0331bbe19decb29e2adc2ea26082755e3eeb188;p=soc.git use a virtual regfile port for the hazard bitvectors this allows a full width of enables and full width of bits (one per reg being written to) --- diff --git a/src/soc/regfile/regfiles.py b/src/soc/regfile/regfiles.py index 7bd726fd..fc87bee9 100644 --- a/src/soc/regfile/regfiles.py +++ b/src/soc/regfile/regfiles.py @@ -285,9 +285,9 @@ class RegFiles: def make_hazard_vec(self, rf, name): if isinstance(rf, VirtualRegPort): - vec = RegFileArray(1, rf.nregs) + vec = VirtualRegPort(rf.nregs, rf.nregs, wr2=True) else: - vec = RegFileArray(1, rf.depth) + vec = VirtualRegPort(rf.depth, rf.depth, wr2=True) # get read/write port specs and create bitvector ports with same names wr_spec, rd_spec = rf.get_port_specs() # ok, this is complicated/fun. @@ -297,12 +297,8 @@ class RegFiles: # bitvector *ALSO* needs to be wrtten (a 0). therefore we need to # MERGE the wr_spec and rd_spec with some appropriate name prefixes # to make sure they do not clash - rd_bvspec = {'issue': 'issue'} - wr_bvspec = {'set': 'set', 'clr': 'clr'} - #for k, port in wr_spec.items(): - # wr_bvspec["wr_%s" % k] = "wr_%s" % port - #for k, port in rd_spec.items(): - # wr_bvspec["rd_%s" % k] = "rd_%s" % port + rd_bvspec = {'issue': 'full_rd'} + wr_bvspec = {'set': 'full_wr', 'clr': 'full_wr2'} create_ports(vec, wr_bvspec, rd_bvspec) return vec diff --git a/src/soc/regfile/virtual_port.py b/src/soc/regfile/virtual_port.py index 9bb67028..dc5c57d6 100644 --- a/src/soc/regfile/virtual_port.py +++ b/src/soc/regfile/virtual_port.py @@ -18,10 +18,11 @@ from soc.regfile.regfile import RegFileArray class VirtualRegPort(RegFileArray): - def __init__(self, bitwidth, n_regs, rd2=False): + def __init__(self, bitwidth, n_regs, rd2=False, wr2=False): self.bitwidth = bitwidth self.nregs = n_regs self.rd2 = rd2 # eurgh hack + self.wr2 = wr2 # eurgh hack self.regwidth = regwidth = bitwidth // n_regs super().__init__(self.regwidth, n_regs) @@ -32,12 +33,27 @@ class VirtualRegPort(RegFileArray): self.full_rd = RecordObject([("ren", n_regs), ("o_data", bitwidth)], # *full* wid name="full_rd") - if not rd2: - return - self.full_rd2 = RecordObject([("ren", n_regs), + if wr2: + self.full_wr2 = RecordObject([("wen", n_regs), + ("i_data", bitwidth)], # *full* wid + name="full_wr2") + if rd2: + self.full_rd2 = RecordObject([("ren", n_regs), ("o_data", bitwidth)], # *full* wid name="full_rd2") + def connect_full_wr(self, m, wfull, name): + comb = m.d.comb + wr_regs = self.write_reg_port(name) + + # wire up the enable signals from the large (full) port + l = map(lambda port: port.i_data, wr_regs) + le = map(lambda port: port.wen, wr_regs) # get port wen(s) + + # get list of all i_data (and wens) and assign to them via Cat + comb += Cat(*l).eq(wfull.i_data) + comb += Cat(*le).eq(wfull.wen) + def connect_full_rd(self, m, rfull, name): comb = m.d.comb rd_regs = self.read_reg_port(name) @@ -53,25 +69,16 @@ class VirtualRegPort(RegFileArray): m = super().elaborate(platform) comb = m.d.comb - # for internal use only. - wr_regs = self.write_reg_port(f"w") + # connect up full write port + self.connect_full_wr(m, self.full_wr, "w") + if self.wr2: + self.connect_full_wr(m, self.full_wr2, "w2") # connect up full read port self.connect_full_rd(m, self.full_rd, "r") if self.rd2: # hack! self.connect_full_rd(m, self.full_rd2, "r2") - # connect up full write port - wfull = self.full_wr - - # wire up the enable signals from the large (full) port - l = map(lambda port: port.i_data, wr_regs) - le = map(lambda port: port.wen, wr_regs) # get port wen(s) - - # get list of all i_data (and wens) and assign to them via Cat - comb += Cat(*l).eq(wfull.i_data) - comb += Cat(*le).eq(wfull.wen) - return m def __iter__(self): diff --git a/src/soc/simple/core.py b/src/soc/simple/core.py index 3b541541..4e7ade87 100644 --- a/src/soc/simple/core.py +++ b/src/soc/simple/core.py @@ -540,7 +540,10 @@ class NonProductionCore(ControlBase): 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, wf, read, write, wid, fuspec) = fspec + (rf, wf, read, _write, wid, fuspec) = fspec + wrname = "write_%s_%s_%d" % (regfile, regname, i) + write = Signal.like(_write, name=wrname) + comb += write.eq(_write) for pi, (funame, fu, idx) in enumerate(fuspec): pi += ppoffs[i] @@ -592,7 +595,6 @@ class NonProductionCore(ControlBase): comb += wvaddr_en.eq(1<