From 89cfd95dc572da097a96a6e4653f152558b0173b Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Tue, 26 May 2020 23:02:47 +0100 Subject: [PATCH] redo focus of virtual reg port to do only full datawidth not share with mini-regs --- src/soc/regfile/virtual_port.py | 92 ++++++++++----------------------- 1 file changed, 27 insertions(+), 65 deletions(-) diff --git a/src/soc/regfile/virtual_port.py b/src/soc/regfile/virtual_port.py index 4f025887..cf525293 100644 --- a/src/soc/regfile/virtual_port.py +++ b/src/soc/regfile/virtual_port.py @@ -24,24 +24,14 @@ class VirtualRegPort(RegFileArray): self.regwidth = regwidth = bitwidth // n_regs super().__init__(self.regwidth, n_regs) - # create suite of 8 write and 8 read ports for external use - self.wr_ports = [] - self.rd_ports = [] - for i in range(n_regs): - self.wr_ports.append(RecordObject([("wen", n_regs), - ("data_i", regwidth)], - name="w%d" % i)) - self.rd_ports.append(RecordObject([("ren", n_regs), - ("data_o", regwidth)], - name="r%d" % i)) - # and append the "full" depth variant to the "external" ports - self.wr_ports.append(RecordObject([("wen", n_regs), - ("data_i", bitwidth)], # *full* wid - name="full_wr")) - self.rd_ports.append(RecordObject([("ren", n_regs), - ("data_o", bitwidth)], # *full* wid - name="full_rd")) - # now for internal use + # "full" depth variant of the "external" port + self.full_wr = RecordObject([("wen", n_regs), + ("data_i", bitwidth)], # *full* wid + name="full_wr") + self.full_rd = RecordObject([("ren", n_regs), + ("data_o", bitwidth)], # *full* wid + name="full_rd") + # for internal use self._wr_regs = self.write_reg_port(f"intw") self._rd_regs = self.read_reg_port(f"intr") @@ -51,62 +41,34 @@ class VirtualRegPort(RegFileArray): # connect up: detect if read is requested on large (full) port # nothing fancy needed because reads are same-cycle - rlast = self.rd_ports[-1] - ren_sig = Signal(reset_less=True) - comb += ren_sig.eq(rlast.ren.bool()) - print (rlast) - with m.If(ren_sig): - # wire up the enable signals and chain-accumulate the data - print (self._rd_regs) - l = map(lambda port: port.data_o, self._rd_regs) # get port data(s) - le = map(lambda port: port.ren, self._rd_regs) # get port ren(s) - comb += rlast.data_o.eq(Cat(*l)) # we like Cat on lists - comb += Cat(*le).eq(rlast.ren) - with m.Else(): - # allow request through the corresponding lower indexed ports - # TODO: make data_o and ren fields "directional" then simply - # use record "connect" - for i, port in enumerate(self._rd_regs): - comb += port.ren.eq(self.rd_ports[i].ren) - comb += self.rd_ports[i].data_o.eq(port.data_o) + rfull = self.full_rd + + # wire up the enable signals and chain-accumulate the data + l = map(lambda port: port.data_o, self._rd_regs) # get port data(s) + le = map(lambda port: port.ren, self._rd_regs) # get port ren(s) + + comb += rfull.data_o.eq(Cat(*l)) # we like Cat on lists + comb += Cat(*le).eq(rfull.ren) # connect up: detect if write is requested on large (full) port # however due to the delay (1 clock) on write, we also need to # delay the test. enable is not-delayed, but data is. - en_sig = Signal(reset_less=True) # combinatorial - data_sig = Signal(reset_less=True) # sync (one clock delay) - - wlast = self.wr_ports[-1] - comb += en_sig.eq(wlast.wen.bool()) - sync += data_sig.eq(en_sig) - - with m.If(en_sig): - # wire up the enable signals from the large (full) port - le = map(lambda port: port.wen, self._wr_regs) # get port wen(s) - comb += Cat(*le).eq(wlast.wen) - with m.Else(): - # allow request through the corresponding lower indexed ports - for i, port in enumerate(self._wr_regs): - comb += port.wen.eq(self.wr_ports[i].wen) - - # and (sigh) data is on one clock-delay, connect that too - with m.If(data_sig): - # get list of all data_i (and wens) and assign to them via Cat - l = map(lambda port: port.data_i, self._wr_regs) - comb += Cat(*l).eq(wlast.data_i) - with m.Else(): - # allow data through the corresponding lower indexed ports - for i, port in enumerate(self._wr_regs): - comb += port.data_i.eq(self.wr_ports[i].data_i) + wfull = self.full_wr + + # wire up the enable signals from the large (full) port + l = map(lambda port: port.data_i, self._wr_regs) + le = map(lambda port: port.wen, self._wr_regs) # get port wen(s) + + # get list of all data_i (and wens) and assign to them via Cat + comb += Cat(*l).eq(wfull.data_i) + comb += Cat(*le).eq(wfull.wen) return m def __iter__(self): yield from super().__iter__() - for p in self.wr_ports: - yield from p - for p in self.rd_ports: - yield from p + yield from self.full_wr + yield from self.full_rd def test_regfile(): -- 2.30.2