+++ /dev/null
-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())
+++ /dev/null
-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")
+++ /dev/null
-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
+++ /dev/null
-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")
+++ /dev/null
-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")
+++ /dev/null
-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")
+++ /dev/null
-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)
+++ /dev/null
-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)
--- /dev/null
+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())
--- /dev/null
+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")
--- /dev/null
+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
--- /dev/null
+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")
--- /dev/null
+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")
--- /dev/null
+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")
--- /dev/null
+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)
--- /dev/null
+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)