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 wb_get(dc):
- """simulator process for getting memory load requests
- """
- global stop
+def b(x):
+ return int.from_bytes(x.to_bytes(8, byteorder='little'),
+ byteorder='big', signed=False)
- def b(x):
- return int.from_bytes(x.to_bytes(8, byteorder='little'),
- byteorder='big', signed=False)
- mem = {0x10000: # PARTITION_TABLE_2
+default_mem = { 0x10000: # PARTITION_TABLE_2
# PATB_GR=1 PRTB=0x1000 PRTS=0xb
- b(0x800000000100000b),
+ b(0x800000000100000b),
- 0x30000: # RADIX_ROOT_PTE
+ 0x30000: # RADIX_ROOT_PTE
# V = 1 L = 0 NLB = 0x400 NLS = 9
- b(0x8000000000040009),
+ b(0x8000000000040009),
- 0x40000: # RADIX_SECOND_LEVEL
+ 0x40000: # RADIX_SECOND_LEVEL
# V = 1 L = 1 SW = 0 RPN = 0
# R = 1 C = 1 ATT = 0 EAA 0x7
- b(0xc000000000000187),
+ b(0xc000000000000187),
- 0x1000000: # PROCESS_TABLE_3
+ 0x1000000: # PROCESS_TABLE_3
# RTS1 = 0x2 RPDB = 0x300 RTS2 = 0x5 RPDS = 13
- b(0x40000000000300ad),
- }
+ b(0x40000000000300ad),
+ }
+
+
+def wb_get(c, mem, name):
+ """simulator process for getting memory load requests
+ """
+
+ logfile = open("/tmp/wb_get.log","w")
+ 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 (dc.wb_out.cyc)
- stb = yield (dc.wb_out.stb)
+ cyc = yield (c.wb_out.cyc)
+ stb = yield (c.wb_out.stb)
if cyc and stb:
break
yield
- addr = (yield dc.wb_out.adr) << 3
+ 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 dc.wb_in.dat.eq(data)
- print (" DCACHE get %x data %x" % (addr, data))
- yield dc.wb_in.ack.eq(1)
+ yield c.wb_in.dat.eq(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)
+ yield
+
+
+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 dc.wb_in.ack.eq(0)
+ 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():
+ # 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_il()
+ #test_icache()