from soc.experiment.mmu import MMU
from soc.experiment.dcache import DCache
+from soc.experiment.icache import ICache
+
+import random
stop = False
+def set_stop(newval):
+ global stop
+ stop = newval
+
+
def b(x):
return int.from_bytes(x.to_bytes(8, byteorder='little'),
byteorder='big', signed=False)
+
+
default_mem = { 0x10000: # PARTITION_TABLE_2
# PATB_GR=1 PRTB=0x1000 PRTS=0xb
b(0x800000000100000b),
}
-def wb_get(c, mem=default_mem):
+def wb_get(c, mem, name):
"""simulator process for getting memory load requests
"""
- global stop
-
+ logfile = open("/tmp/wb_get.log","w")
- mem = mem
+ def log(msg):
+ logfile.write(msg+"\n")
+ print(msg)
+ global stop
while not stop:
while True: # wait for dc_valid
if stop:
+ log("stop")
return
cyc = yield (c.wb_out.cyc)
stb = yield (c.wb_out.stb)
yield
addr = (yield c.wb_out.adr) << 3
if addr not in mem:
- print (" DCACHE LOOKUP FAIL %x" % (addr))
+ log("%s LOOKUP FAIL %x" % (name, addr))
stop = True
return
yield
data = mem[addr]
yield c.wb_in.dat.eq(data)
- print (" DCACHE get %x data %x" % (addr, data))
+ log("%s get %x data %x" % (name, addr, data))
yield c.wb_in.ack.eq(1)
yield
yield c.wb_in.ack.eq(0)
+
+def icache_sim(dut, mem):
+ i_out = dut.i_in
+ i_in = dut.i_out
+ m_out = dut.m_in
+
+ for k,v in mem.items():
+ yield i_in.valid.eq(0)
+ yield i_out.priv_mode.eq(1)
+ yield i_out.req.eq(0)
+ yield i_out.nia.eq(0)
+ yield i_out.stop_mark.eq(0)
+ yield m_out.tlbld.eq(0)
+ yield m_out.tlbie.eq(0)
+ yield m_out.addr.eq(0)
+ yield m_out.pte.eq(0)
+ yield
+ yield
+ yield
+ yield
+ yield i_out.req.eq(1)
+ yield i_out.nia.eq(C(k, 64))
+ while True:
+ yield
+ valid = yield i_in.valid
+ if valid:
+ break
+ nia = yield i_out.nia
+ insn = yield i_in.insn
+ yield
+ assert insn == v, \
+ "insn @%x=%x expected %x" % (nia, insn, v)
+ yield i_out.req.eq(0)
+ yield
+
+
+def test_icache_il():
+ dut = ICache()
+ vl = rtlil.convert(dut, ports=[])
+ with open("test_icache.il", "w") as f:
+ f.write(vl)
+
+
def test_icache():
- pass
+ # create a random set of addresses and "instructions" at those addresses
+ mem = {}
+ # fail 'AssertionError: insn @1d8=0 expected 61928a6100000000'
+ #random.seed(41)
+ # fail infinite loop 'cache read adr: 24 data: 0'
+ random.seed(43)
+ for i in range(3):
+ mem[random.randint(0, 1<<10)] = b(random.randint(0,1<<32))
+
+ # set up module for simulation
+ m = Module()
+ icache = ICache()
+ m.submodules.icache = icache
+
+ # nmigen Simulation
+ sim = Simulator(m)
+ sim.add_clock(1e-6)
+
+ # read from "memory" process and corresponding wishbone "read" process
+ sim.add_sync_process(wrap(icache_sim(icache, mem)))
+ sim.add_sync_process(wrap(wb_get(icache, mem, "ICACHE")))
+ with sim.write_vcd('test_icache.vcd'):
+ sim.run()
def mmu_lookup(mmu, addr):
return phys_addr
+
def mmu_sim(mmu):
global stop
yield mmu.rin.prtbl.eq(0x1000000) # set process table
stop = True
+
def test_mmu():
mmu = MMU()
dcache = DCache()
sim.add_clock(1e-6)
sim.add_sync_process(wrap(mmu_sim(mmu)))
- sim.add_sync_process(wrap(wb_get(dcache)))
+ sim.add_sync_process(wrap(wb_get(dcache, default_mem, "DCACHE")))
with sim.write_vcd('test_mmu.vcd'):
sim.run()
+
if __name__ == '__main__':
test_mmu()
-# test_icache()
+ #test_icache_il()
+ #test_icache()