def wait_busy(port, no=False):
while True:
- busy = yield port.pi.busy_o
+ busy = yield port.busy_o
print("busy", no, busy)
if bool(busy) == no:
break
def wait_addr(port):
while True:
- addr_ok = yield port.pi.addr_ok_o
+ addr_ok = yield port.addr_ok_o
print("addrok", addr_ok)
if addr_ok:
break
def wait_ldok(port):
while True:
- ldok = yield port.pi.ld.ok
+ ldok = yield port.ld.ok
print("ldok", ldok)
if ldok:
break
yield
-def l0_cache_st(dut, addr, data, datalen):
- if isinstance(dut.pi, Record):
- port1 = dut
- else:
- port1 = dut.pi
+def pi_st(port1, addr, data, datalen):
# have to wait until not busy
yield from wait_busy(port1, no=False) # wait until not busy
# set up a ST on the port. address first:
- yield port1.pi.is_st_i.eq(1) # indicate ST
- yield port1.pi.data_len.eq(datalen) # ST length (1/2/4/8)
+ yield port1.is_st_i.eq(1) # indicate ST
+ yield port1.data_len.eq(datalen) # ST length (1/2/4/8)
- yield port1.pi.addr.data.eq(addr) # set address
- yield port1.pi.addr.ok.eq(1) # set ok
+ yield port1.addr.data.eq(addr) # set address
+ yield port1.addr.ok.eq(1) # set ok
yield Settle()
yield from wait_addr(port1) # wait until addr ok
# yield # not needed, just for checking
# yield # not needed, just for checking
# assert "ST" for one cycle (required by the API)
- yield port1.pi.st.data.eq(data)
- yield port1.pi.st.ok.eq(1)
+ yield port1.st.data.eq(data)
+ yield port1.st.ok.eq(1)
yield
- yield port1.pi.st.ok.eq(0)
+ yield port1.st.ok.eq(0)
yield from wait_busy(port1, True) # wait while busy
# can go straight to reset.
- yield port1.pi.is_st_i.eq(0) # end
- yield port1.pi.addr.ok.eq(0) # set !ok
+ yield port1.is_st_i.eq(0) # end
+ yield port1.addr.ok.eq(0) # set !ok
-def l0_cache_ld(dut, addr, datalen):
-
- if isinstance(dut.pi, Record):
- port1 = dut
- else:
- port1 = dut.pi
+def pi_ld(port1, addr, datalen):
# have to wait until not busy
yield from wait_busy(port1, no=False) # wait until not busy
# set up a LD on the port. address first:
- yield port1.pi.is_ld_i.eq(1) # indicate LD
- yield port1.pi.data_len.eq(datalen) # LD length (1/2/4/8)
+ yield port1.is_ld_i.eq(1) # indicate LD
+ yield port1.data_len.eq(datalen) # LD length (1/2/4/8)
- yield port1.pi.addr.data.eq(addr) # set address
- yield port1.pi.addr.ok.eq(1) # set ok
+ yield port1.addr.data.eq(addr) # set address
+ yield port1.addr.ok.eq(1) # set ok
yield Settle()
yield from wait_addr(port1) # wait until addr ok
yield
yield from wait_ldok(port1) # wait until ld ok
- data = yield port1.pi.ld.data
+ data = yield port1.ld.data
# cleanup
- yield port1.pi.is_ld_i.eq(0) # end
- yield port1.pi.addr.ok.eq(0) # set !ok
+ yield port1.is_ld_i.eq(0) # end
+ yield port1.addr.ok.eq(0) # set !ok
yield from wait_busy(port1, no=False) # wait while not busy
return data
-def l0_cache_ldst(arg, dut):
+def pi_ldst(arg, dut):
# do two half-word stores at consecutive addresses, then two loads
addr1 = 0x04
data = 0xbeef
data2 = 0xf00f
#data = 0x4
- yield from l0_cache_st(dut, addr1, data, 2)
- yield from l0_cache_st(dut, addr2, data2, 2)
- result = yield from l0_cache_ld(dut, addr1, 2)
- result2 = yield from l0_cache_ld(dut, addr2, 2)
+ yield from pi_st(dut, addr1, data, 2)
+ yield from pi_st(dut, addr2, data2, 2)
+ result = yield from pi_ld(dut, addr1, 2)
+ result2 = yield from pi_ld(dut, addr2, 2)
arg.assertEqual(data, result, "data %x != %x" % (result, data))
arg.assertEqual(data2, result2, "data2 %x != %x" % (result2, data2))
# now load both in a 32-bit load to make sure they're really consecutive
data3 = data | (data2 << 16)
- result3 = yield from l0_cache_ld(dut, addr1, 4)
+ result3 = yield from pi_ld(dut, addr1, 4)
arg.assertEqual(data3, result3, "data3 %x != %x" % (result3, data3))
with open("test_pi_%s.il" % ifacetype, "w") as f:
f.write(vl)
- run_simulation(dut, {"sync": l0_cache_ldst(testcls, cmpi.pi)},
+ run_simulation(dut, {"sync": pi_ldst(testcls, cmpi.pi.pi)},
vcd_name='test_pi_%s.vcd' % ifacetype)
from soc.config.test.test_loadstore import TestMemPspec
from soc.config.loadstore import ConfigMemoryPortInterface
from soc.experiment.pimem import PortInterface
-
+from soc.config.test.test_pi2ls import pi_ld, pi_st, pi_ldst
import unittest
def l0_cache_st(dut, addr, data, datalen):
- l0 = dut.l0
- mem = dut.pimem
- port0 = l0.dports[0]
- port1 = l0.dports[1]
-
- # have to wait until not busy
- yield from wait_busy(port1, no=False) # wait until not busy
-
- # set up a ST on the port. address first:
- yield port1.is_st_i.eq(1) # indicate ST
- yield port1.data_len.eq(datalen) # ST length (1/2/4/8)
-
- yield port1.addr.data.eq(addr) # set address
- yield port1.addr.ok.eq(1) # set ok
- yield from wait_addr(port1) # wait until addr ok
- # yield # not needed, just for checking
- # yield # not needed, just for checking
- # assert "ST" for one cycle (required by the API)
- yield port1.st.data.eq(data)
- yield port1.st.ok.eq(1)
- yield
- yield port1.st.ok.eq(0)
-
- # can go straight to reset.
- yield port1.is_st_i.eq(0) # end
- yield port1.addr.ok.eq(0) # set !ok
- yield from wait_busy(port1, False) # wait until not busy
+ return pi_st(dut.l0, addr, datalen)
def l0_cache_ld(dut, addr, datalen, expected):
-
- l0 = dut.l0
- mem = dut.pimem
- port1 = l0.dports[0]
- port2 = l0.dports[2]
-
- # have to wait until not busy
- yield from wait_busy(port1, no=False) # wait until not busy
-
- # set up a LD on the port. address first:
- yield port1.is_ld_i.eq(1) # indicate LD
- yield port1.data_len.eq(datalen) # LD length (1/2/4/8)
-
- yield port1.addr.data.eq(addr) # set address
- yield port1.addr.ok.eq(1) # set ok
- yield from wait_addr(port1) # wait until addr ok
-
- yield from wait_ldok(port1) # wait until ld ok
- data = yield port1.ld.data
-
- # cleanup
- yield port1.is_ld_i.eq(0) # end
- yield port1.addr.ok.eq(0) # set !ok
- yield from wait_busy(port1, no=False) # wait until not busy
-
- return data
+ return pi_ld(dut.l0, addr, datalen)
def l0_cache_ldst(arg, dut):
- yield
- addr = 0x2
- data = 0xbeef
- data2 = 0xf00f
- #data = 0x4
- yield from l0_cache_st(dut, 0x2, data, 2)
- yield from l0_cache_st(dut, 0x4, data2, 2)
- result = yield from l0_cache_ld(dut, 0x2, 2, data)
- result2 = yield from l0_cache_ld(dut, 0x4, 2, data2)
- yield
- arg.assertEqual(data, result, "data %x != %x" % (result, data))
- arg.assertEqual(data2, result2, "data2 %x != %x" % (result2, data2))
+ port0 = dut.l0.dports[0]
+ return pi_ldst(arg, port0)
def data_merger_merge(dut):
class TestL0Cache(unittest.TestCase):
- def test_l0_cache(self):
+ def test_l0_cache_test_bare_wb(self):
- dut = TstL0CacheBuffer(regwid=64)
- #vl = rtlil.convert(dut, ports=dut.ports())
- #with open("test_basic_l0_cache.il", "w") as f:
- # f.write(vl)
+ dut = TstL0CacheBuffer(regwid=64, ifacetype='test_bare_wb')
+ vl = rtlil.convert(dut, ports=[])# TODOdut.ports())
+ with open("test_basic_l0_cache_bare_wb.il", "w") as f:
+ f.write(vl)
+
+ run_simulation(dut, l0_cache_ldst(self, dut),
+ vcd_name='test_l0_cache_basic_bare_wb.vcd')
+
+ def test_l0_cache_testpi(self):
+
+ dut = TstL0CacheBuffer(regwid=64, ifacetype='testpi')
+ vl = rtlil.convert(dut, ports=[])# TODOdut.ports())
+ with open("test_basic_l0_cache.il", "w") as f:
+ f.write(vl)
run_simulation(dut, l0_cache_ldst(self, dut),
- vcd_name='test_l0_cache_basic.vcd')
+ vcd_name='test_l0_cache_basic_testpi.vcd')
class TestDataMerger(unittest.TestCase):