sdram: create test dir and move lasmicon/minicon tests to it
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 2 Mar 2015 07:42:55 +0000 (08:42 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 2 Mar 2015 07:42:55 +0000 (08:42 +0100)
16 files changed:
misoclib/mem/sdram/lasmicon/test/abstract_transactions_lasmi.py [deleted file]
misoclib/mem/sdram/lasmicon/test/bankmachine.py [deleted file]
misoclib/mem/sdram/lasmicon/test/common.py [deleted file]
misoclib/mem/sdram/lasmicon/test/lasmicon.py [deleted file]
misoclib/mem/sdram/lasmicon/test/lasmicon_df.py [deleted file]
misoclib/mem/sdram/lasmicon/test/lasmicon_wb.py [deleted file]
misoclib/mem/sdram/lasmicon/test/refresher.py [deleted file]
misoclib/mem/sdram/minicon/tb/minicontb.py [deleted file]
misoclib/mem/sdram/test/abstract_transactions_lasmi.py [new file with mode: 0644]
misoclib/mem/sdram/test/bankmachine_tb.py [new file with mode: 0644]
misoclib/mem/sdram/test/common.py [new file with mode: 0644]
misoclib/mem/sdram/test/lasmicon_df_tb.py [new file with mode: 0644]
misoclib/mem/sdram/test/lasmicon_tb.py [new file with mode: 0644]
misoclib/mem/sdram/test/lasmicon_wb.py [new file with mode: 0644]
misoclib/mem/sdram/test/minicon_tb.py [new file with mode: 0644]
misoclib/mem/sdram/test/refresher.py [new file with mode: 0644]

diff --git a/misoclib/mem/sdram/lasmicon/test/abstract_transactions_lasmi.py b/misoclib/mem/sdram/lasmicon/test/abstract_transactions_lasmi.py
deleted file mode 100644 (file)
index 6bfb1fd..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-from migen.fhdl.std import *
-from migen.bus.transactions import *
-from migen.sim.generic import run_simulation
-
-from misoclib.mem.sdram.bus import lasmibus
-
-def my_generator(n):
-       bank = n % 4
-       for x in range(4):
-               t = TWrite(4*bank+x, 0x1000*bank + 0x100*x)
-               yield t
-               print("{0}: Wrote in {1} cycle(s)".format(n, t.latency))
-
-       for x in range(4):
-               t = TRead(4*bank+x)
-               yield t
-               print("{0}: Read {1:x} in {2} cycle(s)".format(n, t.data, t.latency))
-               assert(t.data == 0x1000*bank + 0x100*x)
-
-class MyModel(lasmibus.TargetModel):
-       def read(self, bank, address):
-               r = 0x1000*bank + 0x100*address
-               #print("read from bank {0} address {1} -> {2:x}".format(bank, address, r))
-               return r
-
-       def write(self, bank, address, data, we):
-               print("write to bank {0} address {1:x} data {2:x}".format(bank, address, data))
-               assert(data == 0x1000*bank + 0x100*address)
-
-class TB(Module):
-       def __init__(self):
-               self.submodules.controller = lasmibus.Target(MyModel(), aw=4, dw=32, nbanks=4, req_queue_size=4,
-                       read_latency=4, write_latency=1)
-               self.submodules.xbar = lasmibus.Crossbar([self.controller.bus], 2)
-               self.initiators = [lasmibus.Initiator(my_generator(n), self.xbar.get_master()) for n in range(4)]
-               self.submodules += self.initiators
-
-if __name__ == "__main__":
-       run_simulation(TB())
diff --git a/misoclib/mem/sdram/lasmicon/test/bankmachine.py b/misoclib/mem/sdram/lasmicon/test/bankmachine.py
deleted file mode 100644 (file)
index 12bdcd2..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-from migen.fhdl.std import *
-from migen.sim.generic import run_simulation
-
-from misoclib.mem.sdram.bus import lasmibus
-from misoclib.mem.sdram.lasmicon.bankmachine import *
-
-from common import sdram_phy, sdram_geom, sdram_timing, CommandLogger
-
-def my_generator():
-       for x in range(10):
-               yield True, x
-       for x in range(10):
-               yield False, 128*x
-
-class TB(Module):
-       def __init__(self):
-               self.req = Interface(32, 32, 1,
-                       sdram_timing.req_queue_size, sdram_phy.read_latency, sdram_phy.write_latency)
-               self.submodules.dut = BankMachine(sdram_geom, sdram_timing, 2, 0, self.req)
-               self.submodules.logger = CommandLogger(self.dut.cmd, True)
-               self.generator = my_generator()
-               self.dat_ack_cnt = 0
-
-       def do_simulation(self, selfp):
-               if selfp.req.dat_ack:
-                       self.dat_ack_cnt += 1
-               if selfp.req.req_ack:
-                       try:
-                               we, adr = next(self.generator)
-                       except StopIteration:
-                               selfp.req.stb = 0
-                               if not selfp.req.lock:
-                                       print("data ack count: {0}".format(self.dat_ack_cnt))
-                                       raise StopSimulation
-                               return
-                       selfp.req.adr = adr
-                       selfp.req.we = we
-                       selfp.req.stb = 1
-
-if __name__ == "__main__":
-       run_simulation(TB(), vcd_name="my.vcd")
diff --git a/misoclib/mem/sdram/lasmicon/test/common.py b/misoclib/mem/sdram/lasmicon/test/common.py
deleted file mode 100644 (file)
index 3d60d70..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-from fractions import Fraction
-from math import ceil
-
-from migen.fhdl.std import *
-
-from misoclib import sdram
-
-MHz = 1000000
-clk_freq = (83 + Fraction(1, 3))*MHz
-
-clk_period_ns = 1000000000/clk_freq
-def ns(t, margin=True):
-       if margin:
-               t += clk_period_ns/2
-       return ceil(t/clk_period_ns)
-
-sdram_phy = sdram.PhySettings(
-       memtype="DDR",
-       dfi_d=64,
-       nphases=2,
-       rdphase=0,
-       wrphase=1,
-       rdcmdphase=1,
-       wrcmdphase=0,
-       cl=3,
-       read_latency=5,
-       write_latency=0
-)
-
-sdram_geom = sdram.GeomSettings(
-       bank_a=2,
-       row_a=13,
-       col_a=10
-)
-sdram_timing = sdram.TimingSettings(
-       tRP=ns(15),
-       tRCD=ns(15),
-       tWR=ns(15),
-       tWTR=2,
-       tREFI=ns(7800, False),
-       tRFC=ns(70),
-
-       req_queue_size=8,
-       read_time=32,
-       write_time=16
-)
-
-def decode_sdram(ras_n, cas_n, we_n, bank, address):
-       elts = []
-       if not ras_n and cas_n and we_n:
-               elts.append("ACTIVATE")
-               elts.append("BANK " + str(bank))
-               elts.append("ROW " + str(address))
-       elif ras_n and not cas_n and we_n:
-               elts.append("READ\t")
-               elts.append("BANK " + str(bank))
-               elts.append("COL " + str(address))
-       elif ras_n and not cas_n and not we_n:
-               elts.append("WRITE\t")
-               elts.append("BANK " + str(bank))
-               elts.append("COL " + str(address))
-       elif ras_n and cas_n and not we_n:
-               elts.append("BST")
-       elif not ras_n and not cas_n and we_n:
-               elts.append("AUTO REFRESH")
-       elif not ras_n and cas_n and not we_n:
-               elts.append("PRECHARGE")
-               if address & 2**10:
-                       elts.append("ALL")
-               else:
-                       elts.append("BANK " + str(bank))
-       elif not ras_n and not cas_n and not we_n:
-               elts.append("LMR")
-       return elts
-
-class CommandLogger(Module):
-       def __init__(self, cmd, rw=False):
-               self.cmd = cmd
-               if rw:
-                       self.comb += self.cmd.ack.eq(1)
-
-       def do_simulation(self, selfp):
-               elts = ["@" + str(selfp.simulator.cycle_counter)]
-               cmdp = selfp.cmd
-               elts += decode_sdram(cmdp.ras_n, cmdp.cas_n, cmdp.we_n, cmdp.ba, cmdp.a)
-               if len(elts) > 1:
-                       print("\t".join(elts))
-       do_simulation.passive = True
-
-class DFILogger(Module):
-       def __init__(self, dfi):
-               self.dfi = dfi
-
-       def do_simulation(self, selfp):
-               dfip = selfp.dfi
-               for i, p in enumerate(dfip.phases):
-                       elts = ["@" + str(selfp.simulator.cycle_counter) + ":" + str(i)]
-                       elts += decode_sdram(p.ras_n, p.cas_n, p.we_n, p.bank, p.address)
-                       if len(elts) > 1:
-                               print("\t".join(elts))
-       do_simulation.passive = True
diff --git a/misoclib/mem/sdram/lasmicon/test/lasmicon.py b/misoclib/mem/sdram/lasmicon/test/lasmicon.py
deleted file mode 100644 (file)
index af792bb..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-from migen.fhdl.std import *
-from migen.sim.generic import run_simulation
-
-from misoclib.mem.sdram.bus import lasmibus
-from misoclib.mem.sdram.lasmicon import *
-
-from common import sdram_phy, sdram_geom, sdram_timing, DFILogger
-
-def my_generator_r(n):
-       for x in range(10):
-               t = TRead(128*n + 48*n*x)
-               yield t
-       print("{0:3}: reads done".format(n))
-
-def my_generator_w(n):
-       for x in range(10):
-               t = TWrite(128*n + 48*n*x, x)
-               yield t
-       print("{0:3}: writes done".format(n))
-
-def my_generator(n):
-       if n % 2:
-               return my_generator_w(n // 2)
-       else:
-               return my_generator_r(n // 2)
-
-class TB(Module):
-       def __init__(self):
-               self.submodules.dut = LASMIcon(sdram_phy, sdram_geom, sdram_timing)
-               self.submodules.xbar = lasmibus.Crossbar([self.dut.lasmic], self.dut.nrowbits)
-               self.submodules.logger = DFILogger(self.dut.dfi)
-
-               masters = [self.xbar.get_master() for i in range(6)]
-               self.initiators = [Initiator(my_generator(n), master)
-                       for n, master in enumerate(masters)]
-               self.submodules += self.initiators
-
-if __name__ == "__main__":
-       run_simulation(TB(), vcd_name="my.vcd")
diff --git a/misoclib/mem/sdram/lasmicon/test/lasmicon_df.py b/misoclib/mem/sdram/lasmicon/test/lasmicon_df.py
deleted file mode 100644 (file)
index 7f2f886..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-from migen.fhdl.std import *
-from migen.sim.generic import run_simulation
-
-from misoclib.mem.sdram.bus import lasmibus
-from misoclib.mem.sdram.lasmicon import *
-from misoclib.mem.sdram.frontend import dma_lasmi
-
-from common import sdram_phy, sdram_geom, sdram_timing, DFILogger
-
-class TB(Module):
-       def __init__(self):
-               self.submodules.ctler = LASMIcon(sdram_phy, sdram_geom, sdram_timing)
-               self.submodules.xbar = lasmibus.Crossbar([self.ctler.lasmic], self.ctler.nrowbits)
-               self.submodules.logger = DFILogger(self.ctler.dfi)
-               self.submodules.writer = dma_lasmi.Writer(self.xbar.get_master())
-
-               self.comb += self.writer.address_data.stb.eq(1)
-               pl = self.writer.address_data.payload
-               pl.a.reset = 255
-               pl.d.reset = pl.a.reset*2
-               self.sync += If(self.writer.address_data.ack,
-                       pl.a.eq(pl.a + 1),
-                       pl.d.eq(pl.d + 2)
-               )
-               self.open_row = None
-
-       def do_simulation(self, selfp):
-               dfip = selfp.ctler.dfi
-               for p in dfip.phases:
-                       if p.ras_n and not p.cas_n and not p.we_n: # write
-                               d = dfip.phases[0].wrdata | (dfip.phases[1].wrdata << 64)
-                               print(d)
-                               if d != p.address//2 + p.bank*512 + self.open_row*2048:
-                                       print("**** ERROR ****")
-                       elif not p.ras_n and p.cas_n and p.we_n: # activate
-                               self.open_row = p.address
-
-if __name__ == "__main__":
-       run_simulation(TB(), ncycles=3500, vcd_name="my.vcd")
diff --git a/misoclib/mem/sdram/lasmicon/test/lasmicon_wb.py b/misoclib/mem/sdram/lasmicon/test/lasmicon_wb.py
deleted file mode 100644 (file)
index 53fc7b8..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-from migen.fhdl.std import *
-from migen.bus import wishbone
-from migen.bus.transactions import *
-from migen.sim.generic import run_simulation
-
-from misoclib.mem.sdram.bus import lasmibus
-from misoclib.mem.sdram.lasmicon import *
-from misoclib.mem.sdram.frontend import wishbone2lasmi
-
-from common import sdram_phy, sdram_geom, sdram_timing, DFILogger
-
-l2_size = 8192 # in bytes
-
-def my_generator():
-       for x in range(20):
-               t = TWrite(x, x)
-               yield t
-               print(str(t) + " delay=" + str(t.latency))
-       for x in range(20):
-               t = TRead(x)
-               yield t
-               print(str(t) + " delay=" + str(t.latency))
-       for x in range(20):
-               t = TRead(x+l2_size//4)
-               yield t
-               print(str(t) + " delay=" + str(t.latency))
-
-class TB(Module):
-       def __init__(self):
-               self.submodules.ctler = LASMIcon(sdram_phy, sdram_geom, sdram_timing)
-               self.submodules.xbar = lasmibus.Crossbar([self.ctler.lasmic], self.ctler.nrowbits)
-               self.submodules.logger = DFILogger(self.ctler.dfi)
-               self.submodules.bridge = wishbone2lasmi.WB2LASMI(l2_size//4, self.xbar.get_master())
-               self.submodules.initiator = wishbone.Initiator(my_generator())
-               self.submodules.conn = wishbone.InterconnectPointToPoint(self.initiator.bus, self.bridge.wishbone)
-
-if __name__ == "__main__":
-       run_simulation(TB(), vcd_name="my.vcd")
diff --git a/misoclib/mem/sdram/lasmicon/test/refresher.py b/misoclib/mem/sdram/lasmicon/test/refresher.py
deleted file mode 100644 (file)
index 7845bf9..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-from random import Random
-
-from migen.fhdl.std import *
-from migen.sim.generic import run_simulation
-
-from misoclib.mem.sdram.lasmicon.refresher import *
-
-from common import CommandLogger
-
-class Granter(Module):
-       def __init__(self, req, ack):
-               self.req = req
-               self.ack = ack
-               self.state = 0
-               self.prng = Random(92837)
-
-       def do_simulation(self, selfp):
-               elts = ["@" + str(selfp.simulator.cycle_counter)]
-
-               if self.state == 0:
-                       if selfp.req:
-                               elts.append("Refresher requested access")
-                               self.state = 1
-               elif self.state == 1:
-                       if self.prng.randrange(0, 5) == 0:
-                               elts.append("Granted access to refresher")
-                               selfp.ack = 1
-                               self.state = 2
-               elif self.state == 2:
-                       if not selfp.req:
-                               elts.append("Refresher released access")
-                               selfp.ack = 0
-                               self.state = 0
-
-               if len(elts) > 1:
-                       print("\t".join(elts))
-
-class TB(Module):
-       def __init__(self):
-               self.submodules.dut = Refresher(13, 2, tRP=3, tREFI=100, tRFC=5)
-               self.submodules.logger = CommandLogger(self.dut.cmd)
-               self.submodules.granter = Granter(self.dut.req, self.dut.ack)
-
-if __name__ == "__main__":
-       run_simulation(TB(), ncycles=400)
diff --git a/misoclib/mem/sdram/minicon/tb/minicontb.py b/misoclib/mem/sdram/minicon/tb/minicontb.py
deleted file mode 100644 (file)
index d132139..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-from migen.fhdl.std import *
-from migen.bus.transactions import TRead, TWrite
-from migen.bus import wishbone
-from migen.sim.generic import Simulator
-from migen.sim import icarus
-from mibuild.platforms import papilio_pro as board
-from misoclib import sdram
-from misoclib.mem.sdram.minicon import Minicon
-from misoclib.mem.sdram.phy import gensdrphy
-from itertools import chain
-from os.path import isfile
-import sys
-
-clk_freq = 80000000
-
-from math import ceil
-
-def ns(t, margin=True):
-       clk_period_ns = 1000000000/clk_freq
-       if margin:
-               t += clk_period_ns/2
-       return ceil(t/clk_period_ns)
-
-class MiniconTB(Module):
-       def __init__(self, sdrphy, dfi, sdram_geom, sdram_timing, pads, sdram_clk):
-
-               self.clk_freq = 80000000
-               phy_settings = sdrphy.phy_settings
-               rdphase = phy_settings.rdphase
-               self.submodules.slave = Minicon(phy_settings, sdram_geom, sdram_timing)
-
-               self.submodules.tap = wishbone.Tap(self.slave.bus)
-               self.submodules.dc = dc = wishbone.DownConverter(32, phy_settings.nphases*flen(dfi.phases[rdphase].rddata))
-               self.submodules.master = wishbone.Initiator(self.genxfers(), bus=dc.wishbone_i)
-               self.submodules.intercon = wishbone.InterconnectPointToPoint(dc.wishbone_o, self.slave.bus)
-
-               self.submodules.sdrphy = self.sdrphy = sdrphy
-               self.dfi = dfi
-               self.pads = pads
-
-               self.specials += Instance("mt48lc4m16a2",
-                       io_Dq=pads.dq,
-                       i_Addr=pads.a,
-                       i_Ba=pads.ba,
-                       i_Clk=ClockSignal(),
-                       i_Cke=pads.cke,
-                       i_Cs_n=pads.cs_n,
-                       i_Ras_n=pads.ras_n,
-                       i_Cas_n=pads.cas_n,
-                       i_We_n=pads.we_n,
-                       i_Dqm=pads.dm
-               )
-
-       def genxfers(self):
-               cycle = 0
-               for a in chain(range(4),range(256,260),range(1024,1028)):
-                       t = TRead(a)
-                       yield t
-                       print("read {} in {} cycles".format(t.data, t.latency))
-               for a in chain(range(4),range(256,260),range(1024,1028),range(4096,4100)):
-                       t = TWrite(a, 0xaa55aa55+cycle)
-                       cycle += 1
-                       yield t
-                       print("read {} in {} cycles".format(t.data, t.latency))
-               for a in chain(range(4),range(256,260),range(1024,1028),range(4096,4100)):
-                       t = TRead(a)
-                       yield t
-                       print("read {} in {} cycles".format(t.data, t.latency))
-
-       def gen_simulation(self, selfp):
-               dfi = selfp.dfi
-               phy = self.sdrphy
-               rdphase = phy.phy_settings.rdphase
-               cycle = 0
-
-               while True:
-                       yield
-
-class MyTopLevel:
-       def __init__(self, vcd_name=None, vcd_level=1,
-         top_name="top", dut_type="dut", dut_name="dut",
-         cd_name="sys", clk_period=10):
-               self.vcd_name = vcd_name
-               self.vcd_level = vcd_level
-               self.top_name = top_name
-               self.dut_type = dut_type
-               self.dut_name = dut_name
-
-               self._cd_name = cd_name
-               self._clk_period = clk_period
-
-               cd = ClockDomain(self._cd_name)
-               cd_ps = ClockDomain("sys_ps")
-               self.clock_domains = [cd, cd_ps]
-               self.ios = {cd.clk, cd.rst, cd_ps.clk}
-
-       def get(self, sockaddr):
-               template1 = """`timescale 1ns / 1ps
-
-module {top_name}();
-
-reg {clk_name};
-reg {rst_name};
-reg sys_ps_clk;
-
-initial begin
-       {rst_name} <= 1'b1;
-       @(posedge {clk_name});
-       {rst_name} <= 1'b0;
-end
-
-always begin
-       {clk_name} <= 1'b0;
-       #{hclk_period};
-       {clk_name} <= 1'b1;
-       #{hclk_period};
-end
-
-always @(posedge {clk_name} or negedge {clk_name})
-       sys_ps_clk <= #({hclk_period}*2-3) {clk_name};
-
-{dut_type} {dut_name}(
-       .{rst_name}({rst_name}),
-       .{clk_name}({clk_name}),
-       .sys_ps_clk(sys_ps_clk)
-);
-
-initial $migensim_connect("{sockaddr}");
-always @(posedge {clk_name}) $migensim_tick;
-"""
-               template2 = """
-initial begin
-       $dumpfile("{vcd_name}");
-       $dumpvars({vcd_level}, {dut_name});
-end
-"""
-               r = template1.format(top_name=self.top_name,
-                       dut_type=self.dut_type,
-                       dut_name=self.dut_name,
-                       clk_name=self._cd_name + "_clk",
-                       rst_name=self._cd_name + "_rst",
-                       hclk_period=str(self._clk_period/2),
-                       sockaddr=sockaddr)
-               if self.vcd_name is not None:
-                       r += template2.format(vcd_name=self.vcd_name,
-                               vcd_level=str(self.vcd_level),
-                               dut_name=self.dut_name)
-               r += "\nendmodule"
-               return r
-
-
-if __name__ == "__main__":
-
-       plat = board.Platform()
-
-       sdram_geom = sdram.GeomSettings(
-               bank_a=2,
-               row_a=12,
-               col_a=8
-       )
-
-       sdram_timing = sdram.TimingSettings(
-               tRP=ns(15),
-               tRCD=ns(15),
-               tWR=ns(14),
-               tWTR=2,
-               tREFI=ns(64*1000*1000/4096, False),
-               tRFC=ns(66),
-               req_queue_size=8,
-               read_time=32,
-               write_time=16
-       )
-
-       sdram_pads = plat.request("sdram")
-       sdram_clk = plat.request("sdram_clock")
-
-       sdrphy = gensdrphy.GENSDRPHY(sdram_pads)
-
-# This sets CL to 2 during LMR done on 1st cycle
-       sdram_pads.a.reset = 1<<5
-
-       s = MiniconTB(sdrphy, sdrphy.dfi, sdram_geom, sdram_timing, pads=sdram_pads, sdram_clk=sdram_clk)
-
-       extra_files = [ "sdram_model/mt48lc4m16a2.v" ]
-
-       if not isfile(extra_files[0]):
-               print("ERROR: You need to download Micron Verilog simulation model for MT48LC4M16A2 and put it in sdram_model/mt48lc4m16a2.v")
-               print("File can be downloaded from this URL: http://www.micron.com/-/media/documents/products/sim%20model/dram/dram/4054mt48lc4m16a2.zip")
-               sys.exit(1)
-
-       with Simulator(s, MyTopLevel("top.vcd", clk_period=int(1/0.08)), icarus.Runner(extra_files=extra_files, keep_files=True)) as sim:
-               sim.run(5000)
diff --git a/misoclib/mem/sdram/test/abstract_transactions_lasmi.py b/misoclib/mem/sdram/test/abstract_transactions_lasmi.py
new file mode 100644 (file)
index 0000000..6bfb1fd
--- /dev/null
@@ -0,0 +1,39 @@
+from migen.fhdl.std import *
+from migen.bus.transactions import *
+from migen.sim.generic import run_simulation
+
+from misoclib.mem.sdram.bus import lasmibus
+
+def my_generator(n):
+       bank = n % 4
+       for x in range(4):
+               t = TWrite(4*bank+x, 0x1000*bank + 0x100*x)
+               yield t
+               print("{0}: Wrote in {1} cycle(s)".format(n, t.latency))
+
+       for x in range(4):
+               t = TRead(4*bank+x)
+               yield t
+               print("{0}: Read {1:x} in {2} cycle(s)".format(n, t.data, t.latency))
+               assert(t.data == 0x1000*bank + 0x100*x)
+
+class MyModel(lasmibus.TargetModel):
+       def read(self, bank, address):
+               r = 0x1000*bank + 0x100*address
+               #print("read from bank {0} address {1} -> {2:x}".format(bank, address, r))
+               return r
+
+       def write(self, bank, address, data, we):
+               print("write to bank {0} address {1:x} data {2:x}".format(bank, address, data))
+               assert(data == 0x1000*bank + 0x100*address)
+
+class TB(Module):
+       def __init__(self):
+               self.submodules.controller = lasmibus.Target(MyModel(), aw=4, dw=32, nbanks=4, req_queue_size=4,
+                       read_latency=4, write_latency=1)
+               self.submodules.xbar = lasmibus.Crossbar([self.controller.bus], 2)
+               self.initiators = [lasmibus.Initiator(my_generator(n), self.xbar.get_master()) for n in range(4)]
+               self.submodules += self.initiators
+
+if __name__ == "__main__":
+       run_simulation(TB())
diff --git a/misoclib/mem/sdram/test/bankmachine_tb.py b/misoclib/mem/sdram/test/bankmachine_tb.py
new file mode 100644 (file)
index 0000000..12bdcd2
--- /dev/null
@@ -0,0 +1,41 @@
+from migen.fhdl.std import *
+from migen.sim.generic import run_simulation
+
+from misoclib.mem.sdram.bus import lasmibus
+from misoclib.mem.sdram.lasmicon.bankmachine import *
+
+from common import sdram_phy, sdram_geom, sdram_timing, CommandLogger
+
+def my_generator():
+       for x in range(10):
+               yield True, x
+       for x in range(10):
+               yield False, 128*x
+
+class TB(Module):
+       def __init__(self):
+               self.req = Interface(32, 32, 1,
+                       sdram_timing.req_queue_size, sdram_phy.read_latency, sdram_phy.write_latency)
+               self.submodules.dut = BankMachine(sdram_geom, sdram_timing, 2, 0, self.req)
+               self.submodules.logger = CommandLogger(self.dut.cmd, True)
+               self.generator = my_generator()
+               self.dat_ack_cnt = 0
+
+       def do_simulation(self, selfp):
+               if selfp.req.dat_ack:
+                       self.dat_ack_cnt += 1
+               if selfp.req.req_ack:
+                       try:
+                               we, adr = next(self.generator)
+                       except StopIteration:
+                               selfp.req.stb = 0
+                               if not selfp.req.lock:
+                                       print("data ack count: {0}".format(self.dat_ack_cnt))
+                                       raise StopSimulation
+                               return
+                       selfp.req.adr = adr
+                       selfp.req.we = we
+                       selfp.req.stb = 1
+
+if __name__ == "__main__":
+       run_simulation(TB(), vcd_name="my.vcd")
diff --git a/misoclib/mem/sdram/test/common.py b/misoclib/mem/sdram/test/common.py
new file mode 100644 (file)
index 0000000..3d60d70
--- /dev/null
@@ -0,0 +1,101 @@
+from fractions import Fraction
+from math import ceil
+
+from migen.fhdl.std import *
+
+from misoclib import sdram
+
+MHz = 1000000
+clk_freq = (83 + Fraction(1, 3))*MHz
+
+clk_period_ns = 1000000000/clk_freq
+def ns(t, margin=True):
+       if margin:
+               t += clk_period_ns/2
+       return ceil(t/clk_period_ns)
+
+sdram_phy = sdram.PhySettings(
+       memtype="DDR",
+       dfi_d=64,
+       nphases=2,
+       rdphase=0,
+       wrphase=1,
+       rdcmdphase=1,
+       wrcmdphase=0,
+       cl=3,
+       read_latency=5,
+       write_latency=0
+)
+
+sdram_geom = sdram.GeomSettings(
+       bank_a=2,
+       row_a=13,
+       col_a=10
+)
+sdram_timing = sdram.TimingSettings(
+       tRP=ns(15),
+       tRCD=ns(15),
+       tWR=ns(15),
+       tWTR=2,
+       tREFI=ns(7800, False),
+       tRFC=ns(70),
+
+       req_queue_size=8,
+       read_time=32,
+       write_time=16
+)
+
+def decode_sdram(ras_n, cas_n, we_n, bank, address):
+       elts = []
+       if not ras_n and cas_n and we_n:
+               elts.append("ACTIVATE")
+               elts.append("BANK " + str(bank))
+               elts.append("ROW " + str(address))
+       elif ras_n and not cas_n and we_n:
+               elts.append("READ\t")
+               elts.append("BANK " + str(bank))
+               elts.append("COL " + str(address))
+       elif ras_n and not cas_n and not we_n:
+               elts.append("WRITE\t")
+               elts.append("BANK " + str(bank))
+               elts.append("COL " + str(address))
+       elif ras_n and cas_n and not we_n:
+               elts.append("BST")
+       elif not ras_n and not cas_n and we_n:
+               elts.append("AUTO REFRESH")
+       elif not ras_n and cas_n and not we_n:
+               elts.append("PRECHARGE")
+               if address & 2**10:
+                       elts.append("ALL")
+               else:
+                       elts.append("BANK " + str(bank))
+       elif not ras_n and not cas_n and not we_n:
+               elts.append("LMR")
+       return elts
+
+class CommandLogger(Module):
+       def __init__(self, cmd, rw=False):
+               self.cmd = cmd
+               if rw:
+                       self.comb += self.cmd.ack.eq(1)
+
+       def do_simulation(self, selfp):
+               elts = ["@" + str(selfp.simulator.cycle_counter)]
+               cmdp = selfp.cmd
+               elts += decode_sdram(cmdp.ras_n, cmdp.cas_n, cmdp.we_n, cmdp.ba, cmdp.a)
+               if len(elts) > 1:
+                       print("\t".join(elts))
+       do_simulation.passive = True
+
+class DFILogger(Module):
+       def __init__(self, dfi):
+               self.dfi = dfi
+
+       def do_simulation(self, selfp):
+               dfip = selfp.dfi
+               for i, p in enumerate(dfip.phases):
+                       elts = ["@" + str(selfp.simulator.cycle_counter) + ":" + str(i)]
+                       elts += decode_sdram(p.ras_n, p.cas_n, p.we_n, p.bank, p.address)
+                       if len(elts) > 1:
+                               print("\t".join(elts))
+       do_simulation.passive = True
diff --git a/misoclib/mem/sdram/test/lasmicon_df_tb.py b/misoclib/mem/sdram/test/lasmicon_df_tb.py
new file mode 100644 (file)
index 0000000..7f2f886
--- /dev/null
@@ -0,0 +1,39 @@
+from migen.fhdl.std import *
+from migen.sim.generic import run_simulation
+
+from misoclib.mem.sdram.bus import lasmibus
+from misoclib.mem.sdram.lasmicon import *
+from misoclib.mem.sdram.frontend import dma_lasmi
+
+from common import sdram_phy, sdram_geom, sdram_timing, DFILogger
+
+class TB(Module):
+       def __init__(self):
+               self.submodules.ctler = LASMIcon(sdram_phy, sdram_geom, sdram_timing)
+               self.submodules.xbar = lasmibus.Crossbar([self.ctler.lasmic], self.ctler.nrowbits)
+               self.submodules.logger = DFILogger(self.ctler.dfi)
+               self.submodules.writer = dma_lasmi.Writer(self.xbar.get_master())
+
+               self.comb += self.writer.address_data.stb.eq(1)
+               pl = self.writer.address_data.payload
+               pl.a.reset = 255
+               pl.d.reset = pl.a.reset*2
+               self.sync += If(self.writer.address_data.ack,
+                       pl.a.eq(pl.a + 1),
+                       pl.d.eq(pl.d + 2)
+               )
+               self.open_row = None
+
+       def do_simulation(self, selfp):
+               dfip = selfp.ctler.dfi
+               for p in dfip.phases:
+                       if p.ras_n and not p.cas_n and not p.we_n: # write
+                               d = dfip.phases[0].wrdata | (dfip.phases[1].wrdata << 64)
+                               print(d)
+                               if d != p.address//2 + p.bank*512 + self.open_row*2048:
+                                       print("**** ERROR ****")
+                       elif not p.ras_n and p.cas_n and p.we_n: # activate
+                               self.open_row = p.address
+
+if __name__ == "__main__":
+       run_simulation(TB(), ncycles=3500, vcd_name="my.vcd")
diff --git a/misoclib/mem/sdram/test/lasmicon_tb.py b/misoclib/mem/sdram/test/lasmicon_tb.py
new file mode 100644 (file)
index 0000000..af792bb
--- /dev/null
@@ -0,0 +1,39 @@
+from migen.fhdl.std import *
+from migen.sim.generic import run_simulation
+
+from misoclib.mem.sdram.bus import lasmibus
+from misoclib.mem.sdram.lasmicon import *
+
+from common import sdram_phy, sdram_geom, sdram_timing, DFILogger
+
+def my_generator_r(n):
+       for x in range(10):
+               t = TRead(128*n + 48*n*x)
+               yield t
+       print("{0:3}: reads done".format(n))
+
+def my_generator_w(n):
+       for x in range(10):
+               t = TWrite(128*n + 48*n*x, x)
+               yield t
+       print("{0:3}: writes done".format(n))
+
+def my_generator(n):
+       if n % 2:
+               return my_generator_w(n // 2)
+       else:
+               return my_generator_r(n // 2)
+
+class TB(Module):
+       def __init__(self):
+               self.submodules.dut = LASMIcon(sdram_phy, sdram_geom, sdram_timing)
+               self.submodules.xbar = lasmibus.Crossbar([self.dut.lasmic], self.dut.nrowbits)
+               self.submodules.logger = DFILogger(self.dut.dfi)
+
+               masters = [self.xbar.get_master() for i in range(6)]
+               self.initiators = [Initiator(my_generator(n), master)
+                       for n, master in enumerate(masters)]
+               self.submodules += self.initiators
+
+if __name__ == "__main__":
+       run_simulation(TB(), vcd_name="my.vcd")
diff --git a/misoclib/mem/sdram/test/lasmicon_wb.py b/misoclib/mem/sdram/test/lasmicon_wb.py
new file mode 100644 (file)
index 0000000..53fc7b8
--- /dev/null
@@ -0,0 +1,38 @@
+from migen.fhdl.std import *
+from migen.bus import wishbone
+from migen.bus.transactions import *
+from migen.sim.generic import run_simulation
+
+from misoclib.mem.sdram.bus import lasmibus
+from misoclib.mem.sdram.lasmicon import *
+from misoclib.mem.sdram.frontend import wishbone2lasmi
+
+from common import sdram_phy, sdram_geom, sdram_timing, DFILogger
+
+l2_size = 8192 # in bytes
+
+def my_generator():
+       for x in range(20):
+               t = TWrite(x, x)
+               yield t
+               print(str(t) + " delay=" + str(t.latency))
+       for x in range(20):
+               t = TRead(x)
+               yield t
+               print(str(t) + " delay=" + str(t.latency))
+       for x in range(20):
+               t = TRead(x+l2_size//4)
+               yield t
+               print(str(t) + " delay=" + str(t.latency))
+
+class TB(Module):
+       def __init__(self):
+               self.submodules.ctler = LASMIcon(sdram_phy, sdram_geom, sdram_timing)
+               self.submodules.xbar = lasmibus.Crossbar([self.ctler.lasmic], self.ctler.nrowbits)
+               self.submodules.logger = DFILogger(self.ctler.dfi)
+               self.submodules.bridge = wishbone2lasmi.WB2LASMI(l2_size//4, self.xbar.get_master())
+               self.submodules.initiator = wishbone.Initiator(my_generator())
+               self.submodules.conn = wishbone.InterconnectPointToPoint(self.initiator.bus, self.bridge.wishbone)
+
+if __name__ == "__main__":
+       run_simulation(TB(), vcd_name="my.vcd")
diff --git a/misoclib/mem/sdram/test/minicon_tb.py b/misoclib/mem/sdram/test/minicon_tb.py
new file mode 100644 (file)
index 0000000..d132139
--- /dev/null
@@ -0,0 +1,192 @@
+from migen.fhdl.std import *
+from migen.bus.transactions import TRead, TWrite
+from migen.bus import wishbone
+from migen.sim.generic import Simulator
+from migen.sim import icarus
+from mibuild.platforms import papilio_pro as board
+from misoclib import sdram
+from misoclib.mem.sdram.minicon import Minicon
+from misoclib.mem.sdram.phy import gensdrphy
+from itertools import chain
+from os.path import isfile
+import sys
+
+clk_freq = 80000000
+
+from math import ceil
+
+def ns(t, margin=True):
+       clk_period_ns = 1000000000/clk_freq
+       if margin:
+               t += clk_period_ns/2
+       return ceil(t/clk_period_ns)
+
+class MiniconTB(Module):
+       def __init__(self, sdrphy, dfi, sdram_geom, sdram_timing, pads, sdram_clk):
+
+               self.clk_freq = 80000000
+               phy_settings = sdrphy.phy_settings
+               rdphase = phy_settings.rdphase
+               self.submodules.slave = Minicon(phy_settings, sdram_geom, sdram_timing)
+
+               self.submodules.tap = wishbone.Tap(self.slave.bus)
+               self.submodules.dc = dc = wishbone.DownConverter(32, phy_settings.nphases*flen(dfi.phases[rdphase].rddata))
+               self.submodules.master = wishbone.Initiator(self.genxfers(), bus=dc.wishbone_i)
+               self.submodules.intercon = wishbone.InterconnectPointToPoint(dc.wishbone_o, self.slave.bus)
+
+               self.submodules.sdrphy = self.sdrphy = sdrphy
+               self.dfi = dfi
+               self.pads = pads
+
+               self.specials += Instance("mt48lc4m16a2",
+                       io_Dq=pads.dq,
+                       i_Addr=pads.a,
+                       i_Ba=pads.ba,
+                       i_Clk=ClockSignal(),
+                       i_Cke=pads.cke,
+                       i_Cs_n=pads.cs_n,
+                       i_Ras_n=pads.ras_n,
+                       i_Cas_n=pads.cas_n,
+                       i_We_n=pads.we_n,
+                       i_Dqm=pads.dm
+               )
+
+       def genxfers(self):
+               cycle = 0
+               for a in chain(range(4),range(256,260),range(1024,1028)):
+                       t = TRead(a)
+                       yield t
+                       print("read {} in {} cycles".format(t.data, t.latency))
+               for a in chain(range(4),range(256,260),range(1024,1028),range(4096,4100)):
+                       t = TWrite(a, 0xaa55aa55+cycle)
+                       cycle += 1
+                       yield t
+                       print("read {} in {} cycles".format(t.data, t.latency))
+               for a in chain(range(4),range(256,260),range(1024,1028),range(4096,4100)):
+                       t = TRead(a)
+                       yield t
+                       print("read {} in {} cycles".format(t.data, t.latency))
+
+       def gen_simulation(self, selfp):
+               dfi = selfp.dfi
+               phy = self.sdrphy
+               rdphase = phy.phy_settings.rdphase
+               cycle = 0
+
+               while True:
+                       yield
+
+class MyTopLevel:
+       def __init__(self, vcd_name=None, vcd_level=1,
+         top_name="top", dut_type="dut", dut_name="dut",
+         cd_name="sys", clk_period=10):
+               self.vcd_name = vcd_name
+               self.vcd_level = vcd_level
+               self.top_name = top_name
+               self.dut_type = dut_type
+               self.dut_name = dut_name
+
+               self._cd_name = cd_name
+               self._clk_period = clk_period
+
+               cd = ClockDomain(self._cd_name)
+               cd_ps = ClockDomain("sys_ps")
+               self.clock_domains = [cd, cd_ps]
+               self.ios = {cd.clk, cd.rst, cd_ps.clk}
+
+       def get(self, sockaddr):
+               template1 = """`timescale 1ns / 1ps
+
+module {top_name}();
+
+reg {clk_name};
+reg {rst_name};
+reg sys_ps_clk;
+
+initial begin
+       {rst_name} <= 1'b1;
+       @(posedge {clk_name});
+       {rst_name} <= 1'b0;
+end
+
+always begin
+       {clk_name} <= 1'b0;
+       #{hclk_period};
+       {clk_name} <= 1'b1;
+       #{hclk_period};
+end
+
+always @(posedge {clk_name} or negedge {clk_name})
+       sys_ps_clk <= #({hclk_period}*2-3) {clk_name};
+
+{dut_type} {dut_name}(
+       .{rst_name}({rst_name}),
+       .{clk_name}({clk_name}),
+       .sys_ps_clk(sys_ps_clk)
+);
+
+initial $migensim_connect("{sockaddr}");
+always @(posedge {clk_name}) $migensim_tick;
+"""
+               template2 = """
+initial begin
+       $dumpfile("{vcd_name}");
+       $dumpvars({vcd_level}, {dut_name});
+end
+"""
+               r = template1.format(top_name=self.top_name,
+                       dut_type=self.dut_type,
+                       dut_name=self.dut_name,
+                       clk_name=self._cd_name + "_clk",
+                       rst_name=self._cd_name + "_rst",
+                       hclk_period=str(self._clk_period/2),
+                       sockaddr=sockaddr)
+               if self.vcd_name is not None:
+                       r += template2.format(vcd_name=self.vcd_name,
+                               vcd_level=str(self.vcd_level),
+                               dut_name=self.dut_name)
+               r += "\nendmodule"
+               return r
+
+
+if __name__ == "__main__":
+
+       plat = board.Platform()
+
+       sdram_geom = sdram.GeomSettings(
+               bank_a=2,
+               row_a=12,
+               col_a=8
+       )
+
+       sdram_timing = sdram.TimingSettings(
+               tRP=ns(15),
+               tRCD=ns(15),
+               tWR=ns(14),
+               tWTR=2,
+               tREFI=ns(64*1000*1000/4096, False),
+               tRFC=ns(66),
+               req_queue_size=8,
+               read_time=32,
+               write_time=16
+       )
+
+       sdram_pads = plat.request("sdram")
+       sdram_clk = plat.request("sdram_clock")
+
+       sdrphy = gensdrphy.GENSDRPHY(sdram_pads)
+
+# This sets CL to 2 during LMR done on 1st cycle
+       sdram_pads.a.reset = 1<<5
+
+       s = MiniconTB(sdrphy, sdrphy.dfi, sdram_geom, sdram_timing, pads=sdram_pads, sdram_clk=sdram_clk)
+
+       extra_files = [ "sdram_model/mt48lc4m16a2.v" ]
+
+       if not isfile(extra_files[0]):
+               print("ERROR: You need to download Micron Verilog simulation model for MT48LC4M16A2 and put it in sdram_model/mt48lc4m16a2.v")
+               print("File can be downloaded from this URL: http://www.micron.com/-/media/documents/products/sim%20model/dram/dram/4054mt48lc4m16a2.zip")
+               sys.exit(1)
+
+       with Simulator(s, MyTopLevel("top.vcd", clk_period=int(1/0.08)), icarus.Runner(extra_files=extra_files, keep_files=True)) as sim:
+               sim.run(5000)
diff --git a/misoclib/mem/sdram/test/refresher.py b/misoclib/mem/sdram/test/refresher.py
new file mode 100644 (file)
index 0000000..7845bf9
--- /dev/null
@@ -0,0 +1,45 @@
+from random import Random
+
+from migen.fhdl.std import *
+from migen.sim.generic import run_simulation
+
+from misoclib.mem.sdram.lasmicon.refresher import *
+
+from common import CommandLogger
+
+class Granter(Module):
+       def __init__(self, req, ack):
+               self.req = req
+               self.ack = ack
+               self.state = 0
+               self.prng = Random(92837)
+
+       def do_simulation(self, selfp):
+               elts = ["@" + str(selfp.simulator.cycle_counter)]
+
+               if self.state == 0:
+                       if selfp.req:
+                               elts.append("Refresher requested access")
+                               self.state = 1
+               elif self.state == 1:
+                       if self.prng.randrange(0, 5) == 0:
+                               elts.append("Granted access to refresher")
+                               selfp.ack = 1
+                               self.state = 2
+               elif self.state == 2:
+                       if not selfp.req:
+                               elts.append("Refresher released access")
+                               selfp.ack = 0
+                               self.state = 0
+
+               if len(elts) > 1:
+                       print("\t".join(elts))
+
+class TB(Module):
+       def __init__(self):
+               self.submodules.dut = Refresher(13, 2, tRP=3, tREFI=100, tRFC=5)
+               self.submodules.logger = CommandLogger(self.dut.cmd)
+               self.submodules.granter = Granter(self.dut.req, self.dut.ack)
+
+if __name__ == "__main__":
+       run_simulation(TB(), ncycles=400)