class Register(Elaboratable):
- def __init__(self, width):
+ def __init__(self, width, writethru=True):
self.width = width
+ self.writethru = writethru
self._rdports = []
self._wrports = []
def elaborate(self, platform):
m = Module()
- reg = Signal(self.width, name="reg")
+ self.reg = reg = Signal(self.width, name="reg")
# read ports. has write-through detection (returns data written)
for rp in self._rdports:
- wr_detect = Signal(reset_less=False)
with m.If(rp.ren):
- m.d.comb += wr_detect.eq(0)
- for wp in self._wrports:
- with m.If(wp.wen):
- m.d.comb += rp.data_o.eq(wp.data_i)
- m.d.comb += wr_detect.eq(1)
- with m.If(~wr_detect):
+ if self.writethru:
+ wr_detect = Signal(reset_less=False)
+ m.d.comb += wr_detect.eq(0)
+ for wp in self._wrports:
+ with m.If(wp.wen):
+ m.d.comb += rp.data_o.eq(wp.data_i)
+ m.d.comb += wr_detect.eq(1)
+ with m.If(~wr_detect):
+ m.d.comb += rp.data_o.eq(reg)
+ else:
m.d.comb += rp.data_o.eq(reg)
# write ports, don't allow write to address 0 (ignore it)
def ports(self):
res = list(self)
-def treereduce(tree):
+def treereduce(tree, attr="data_o"):
#print ("treereduce", tree)
if not isinstance(tree, list):
return tree
if len(tree) == 1:
- return tree[0].data_o
+ return getattr(tree[0], attr)
if len(tree) == 2:
- return tree[0].data_o | tree[1].data_o
- splitpoint = len(tree) // 2
- return treereduce(tree[:splitpoint]) | treereduce(tree[splitpoint:])
+ return getattr(tree[0], attr) | getattr(tree[1], attr)
+ split = len(tree) // 2
+ return treereduce(tree[:split], attr) | treereduce(tree[split:], attr)
class RegFileArray(Elaboratable):
data = yield rp.data_o
print (data)
+def regfile_array_sim(dut, rp1, rp2, wp):
+ yield wp.data_i.eq(2)
+ yield wp.wen.eq(1<<1)
+ yield
+ yield wp.wen.eq(0)
+ yield rp1.ren.eq(1<<1)
+ yield
+ data = yield rp1.data_o
+ print (data)
+ assert data == 2
+
+ yield rp1.ren.eq(1<<5)
+ yield rp2.ren.eq(1<<1)
+ yield wp.wen.eq(1<<5)
+ yield wp.data_i.eq(6)
+ data = yield rp1.data_o
+ print (data)
+ yield
+ yield wp.wen.eq(0)
+ yield rp1.ren.eq(0)
+ yield rp2.ren.eq(0)
+ data1 = yield rp1.data_o
+ print (data1)
+ data2 = yield rp2.data_o
+ print (data2)
+ assert data1 == 6
+ yield
+ data = yield rp1.data_o
+ print (data)
+
def test_regfile():
dut = RegFile(32, 8)
rp = dut.read_port()
run_simulation(dut, regfile_sim(dut, rp, wp), vcd_name='test_regfile.vcd')
dut = RegFileArray(32, 8)
- rp = dut.read_port("read")
+ rp1 = dut.read_port("read1")
+ rp2 = dut.read_port("read2")
wp = dut.write_port("write")
ports=dut.ports()
print ("ports", ports)
with open("test_regfile_array.il", "w") as f:
f.write(vl)
- #run_simulation(dut, regfile_sim(dut, rp, wp), vcd_name='test_regfile.vcd')
+ run_simulation(dut, regfile_array_sim(dut, rp1, rp2, wp),
+ vcd_name='test_regfile_array.vcd')
if __name__ == '__main__':
test_regfile()