-def dcache_load(dut, addr, nc=0):
- yield dut.d_in.load.eq(1)
- yield dut.d_in.nc.eq(nc)
- yield dut.d_in.addr.eq(addr)
- yield dut.d_in.byte_sel.eq(~0)
- yield dut.d_in.valid.eq(1)
- yield
- yield dut.d_in.valid.eq(0)
- yield dut.d_in.byte_sel.eq(0)
- while not (yield dut.d_out.valid):
- yield
- data = yield dut.d_out.data
- return data
-
-
-def dcache_store(dut, addr, data, nc=0):
- yield dut.d_in.load.eq(0)
- yield dut.d_in.nc.eq(nc)
- yield dut.d_in.data.eq(data)
- yield dut.d_in.byte_sel.eq(~0)
- yield dut.d_in.addr.eq(addr)
- yield dut.d_in.valid.eq(1)
- yield
- yield dut.d_in.valid.eq(0)
- yield dut.d_in.byte_sel.eq(0)
- while not (yield dut.d_out.valid):
- yield
-
-
-def dcache_random_sim(dut, mem):
-
- # start copy of mem
- sim_mem = deepcopy(mem)
- print ("mem len", len(sim_mem))
-
- # clear stuff
- yield dut.d_in.valid.eq(0)
- yield dut.d_in.load.eq(0)
- yield dut.d_in.priv_mode.eq(1)
- yield dut.d_in.nc.eq(0)
- yield dut.d_in.addr.eq(0)
- yield dut.d_in.data.eq(0)
- yield dut.m_in.valid.eq(0)
- yield dut.m_in.addr.eq(0)
- yield dut.m_in.pte.eq(0)
- # wait 4 * clk_period
- yield
- yield
- yield
- yield
-
- print ()
-
- #for i in range(1024):
- # sim_mem[i] = i
-
- for i in range(1024):
- addr = randint(0, 1023)
- data = randint(0, (1<<64)-1)
- sim_mem[addr] = data
- row = addr
- addr *= 8
-
- print ("random testing %d 0x%x row %d data 0x%x" % (i, addr, row, data))
-
- yield from dcache_load(dut, addr)
- yield from dcache_store(dut, addr, data)
-
- addr = randint(0, 1023)
- sim_data = sim_mem[addr]
- row = addr
- addr *= 8
-
- print (" load 0x%x row %d expect data 0x%x" % (addr, row, sim_data))
- data = yield from dcache_load(dut, addr)
- assert data == sim_data, \
- "check addr 0x%x row %d data %x != %x" % (addr, row, data, sim_data)
-
- for addr in range(1024):
- data = yield from dcache_load(dut, addr*8)
- assert data == sim_mem[addr], \
- "final check %x data %x != %x" % (addr*8, data, sim_mem[addr])
-
-
-def dcache_sim(dut, mem):
- # clear stuff
- yield dut.d_in.valid.eq(0)
- yield dut.d_in.load.eq(0)
- yield dut.d_in.priv_mode.eq(1)
- yield dut.d_in.nc.eq(0)
- yield dut.d_in.addr.eq(0)
- yield dut.d_in.data.eq(0)
- yield dut.m_in.valid.eq(0)
- yield dut.m_in.addr.eq(0)
- yield dut.m_in.pte.eq(0)
- # wait 4 * clk_period
- yield
- yield
- yield
- yield
-
- # Cacheable read of address 4
- data = yield from dcache_load(dut, 0x58)
- addr = yield dut.d_in.addr
- assert data == 0x0000001700000016, \
- f"data @%x=%x expected 0x0000001700000016" % (addr, data)
-
- # Cacheable read of address 20
- data = yield from dcache_load(dut, 0x20)
- addr = yield dut.d_in.addr
- assert data == 0x0000000900000008, \
- f"data @%x=%x expected 0x0000000900000008" % (addr, data)
-
- # Cacheable read of address 30
- data = yield from dcache_load(dut, 0x530)
- addr = yield dut.d_in.addr
- assert data == 0x0000014D0000014C, \
- f"data @%x=%x expected 0000014D0000014C" % (addr, data)
-
- # 2nd Cacheable read of address 30
- data = yield from dcache_load(dut, 0x530)
- addr = yield dut.d_in.addr
- assert data == 0x0000014D0000014C, \
- f"data @%x=%x expected 0000014D0000014C" % (addr, data)
-
- # Non-cacheable read of address 100
- data = yield from dcache_load(dut, 0x100, nc=1)
- addr = yield dut.d_in.addr
- assert data == 0x0000004100000040, \
- f"data @%x=%x expected 0000004100000040" % (addr, data)
-
- # Store at address 530
- yield from dcache_store(dut, 0x530, 0x121)
-
- # Store at address 30
- yield from dcache_store(dut, 0x530, 0x12345678)
-
- # 3nd Cacheable read of address 530
- data = yield from dcache_load(dut, 0x530)
- addr = yield dut.d_in.addr
- assert data == 0x12345678, \
- f"data @%x=%x expected 0x12345678" % (addr, data)
-
- # 4th Cacheable read of address 20
- data = yield from dcache_load(dut, 0x20)
- addr = yield dut.d_in.addr
- assert data == 0x0000000900000008, \
- f"data @%x=%x expected 0x0000000900000008" % (addr, data)
-
- yield
- yield
- yield
- yield
-
-
-def test_dcache(mem, test_fn, test_name):
- dut = DCache()
-
- memory = Memory(width=64, depth=16*64, init=mem, simulate=True)
- sram = SRAM(memory=memory, granularity=8)
-
- m = Module()
- m.submodules.dcache = dut
- m.submodules.sram = sram
-
- m.d.comb += sram.bus.cyc.eq(dut.wb_out.cyc)
- m.d.comb += sram.bus.stb.eq(dut.wb_out.stb)
- m.d.comb += sram.bus.we.eq(dut.wb_out.we)
- m.d.comb += sram.bus.sel.eq(dut.wb_out.sel)
- m.d.comb += sram.bus.adr.eq(dut.wb_out.adr)
- m.d.comb += sram.bus.dat_w.eq(dut.wb_out.dat)
-
- m.d.comb += dut.wb_in.ack.eq(sram.bus.ack)
- m.d.comb += dut.wb_in.dat.eq(sram.bus.dat_r)
-
- # nmigen Simulation
- sim = Simulator(m)
- sim.add_clock(1e-6)
-
- sim.add_sync_process(wrap(test_fn(dut, mem)))
- with sim.write_vcd('test_dcache%s.vcd' % test_name):
- sim.run()