def __init__(self, bitwidth, n_regs):
self.bitwidth = bitwidth
self.nregs = n_regs
- self.regwidth = bitwidth // n_regs
+ 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.write_reg_port(f"extw")
- self.rd_ports = self.read_reg_port(f"extr")
- # now for internal use
- self._wr_regs = self.write_reg_port(f"intw")
- self._rd_regs = self.read_reg_port(f"intr")
+ 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
self.rd_ports.append(RecordObject([("ren", n_regs),
("data_o", bitwidth)], # *full* wid
name="full_rd"))
+ # now for internal use
+ self._wr_regs = self.write_reg_port(f"intw")
+ self._rd_regs = self.read_reg_port(f"intr")
def elaborate(self, platform):
m = super().elaborate(platform)
# 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(self._get_en_sig([rlast], "ren") != 0):
- # wire up the enable signals and accumulate the data
- l = []
- print (self._rdports)
- for i, port in enumerate(self._rdports[:-1]):
- print (port)
- comb += port.ren.eq(1<<i) # port indices are *unary*-indexed
- l.append(port.data_o)
+ 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
- for i, port in enumerate(self._rdports[:-1]):
- comb += port.eq(self.rd_ports[i])
+ # 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)
# connect up: detect if write is requested on large (full) port
# however due to the delay (1 clock) on write, we also need to
data_sig = Signal(reset_less=True) # sync (one clock delay)
wlast = self.wr_ports[-1]
- comb += en_sig.eq(self._get_en_sig([wlast], "wen") != 0)
+ comb += en_sig.eq(wlast.wen.bool())
sync += data_sig.eq(en_sig)
with m.If(en_sig):
- # wire up the enable signals
- for i, port in enumerate(self._wrports[:-1]):
- comb += port.wen.eq(1<<i) # port indices are *unary*-indexed
+ # 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._wrports[:-1]):
- comb += port.wen.eq(self.wn_ports[i].wen)
+ 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 assign to them via Cat
- l = map(lambda port: port.data_i, self._wrports[:-1])
+ # 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._wrports[:-1]):
- comb += self.wr_ports[i].data_i.eq(port.data_i)
+ for i, port in enumerate(self._wr_regs):
+ comb += port.data_i.eq(self.wr_ports[i].data_i)
return m
def test_regfile():
- dut = VirtualRegPort(32, 4)
+ dut = VirtualRegPort(32, 8)
ports=dut.ports()
print ("ports", ports)
vl = rtlil.convert(dut, ports=ports)