2012-03-31 12:11:29 -04:00
|
|
|
from fractions import Fraction
|
|
|
|
from math import ceil
|
|
|
|
|
2013-05-22 11:10:13 -04:00
|
|
|
from migen.fhdl.std import *
|
2012-03-30 10:40:51 -04:00
|
|
|
from migen.sim.generic import Proxy
|
|
|
|
|
2013-07-15 11:45:55 -04:00
|
|
|
from milkymist import lasmicon
|
2012-03-31 12:11:29 -04:00
|
|
|
|
|
|
|
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)
|
|
|
|
|
2013-07-15 11:45:55 -04:00
|
|
|
sdram_phy = lasmicon.PhySettings(
|
|
|
|
type="DDR",
|
2012-04-01 17:23:45 -04:00
|
|
|
dfi_d=64,
|
|
|
|
nphases=2,
|
|
|
|
rdphase=0,
|
2013-07-15 11:45:55 -04:00
|
|
|
wrphase=1,
|
|
|
|
cl=3
|
2012-04-01 17:23:45 -04:00
|
|
|
)
|
2013-07-15 11:45:55 -04:00
|
|
|
sdram_geom = lasmicon.GeomSettings(
|
2012-03-31 12:11:29 -04:00
|
|
|
bank_a=2,
|
|
|
|
row_a=13,
|
|
|
|
col_a=10
|
|
|
|
)
|
2013-07-15 11:45:55 -04:00
|
|
|
sdram_timing = lasmicon.TimingSettings(
|
2012-03-31 12:11:29 -04:00
|
|
|
tRP=ns(15),
|
|
|
|
tRCD=ns(15),
|
|
|
|
tWR=ns(15),
|
2013-07-15 11:45:55 -04:00
|
|
|
tWTR=2,
|
2012-03-31 12:11:29 -04:00
|
|
|
tREFI=ns(7800, False),
|
|
|
|
tRFC=ns(70),
|
|
|
|
|
2013-07-15 11:45:55 -04:00
|
|
|
read_latency=5,
|
|
|
|
write_latency=0,
|
2012-03-31 12:11:29 -04:00
|
|
|
|
2013-07-15 11:45:55 -04:00
|
|
|
req_queue_size=8,
|
2012-03-31 12:11:29 -04:00
|
|
|
read_time=32,
|
|
|
|
write_time=16
|
|
|
|
)
|
|
|
|
|
2012-04-01 17:23:45 -04:00
|
|
|
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
|
|
|
|
|
2013-07-15 11:45:55 -04:00
|
|
|
class CommandLogger(Module):
|
2012-03-31 12:11:29 -04:00
|
|
|
def __init__(self, cmd, rw=False):
|
2012-03-30 10:40:51 -04:00
|
|
|
self.cmd = cmd
|
2013-07-15 11:45:55 -04:00
|
|
|
if rw:
|
|
|
|
self.comb += self.cmd.ack.eq(1)
|
2012-03-30 10:40:51 -04:00
|
|
|
|
|
|
|
def do_simulation(self, s):
|
|
|
|
elts = ["@" + str(s.cycle_counter)]
|
|
|
|
cmdp = Proxy(s, self.cmd)
|
2012-04-01 17:23:45 -04:00
|
|
|
elts += decode_sdram(cmdp.ras_n, cmdp.cas_n, cmdp.we_n, cmdp.ba, cmdp.a)
|
2012-03-30 10:40:51 -04:00
|
|
|
if len(elts) > 1:
|
|
|
|
print("\t".join(elts))
|
2012-03-31 03:56:22 -04:00
|
|
|
|
2013-07-15 11:45:55 -04:00
|
|
|
class DFILogger(Module):
|
2012-04-01 17:23:45 -04:00
|
|
|
def __init__(self, dfi):
|
|
|
|
self.dfi = dfi
|
|
|
|
|
|
|
|
def do_simulation(self, s):
|
|
|
|
dfip = Proxy(s, self.dfi)
|
|
|
|
|
|
|
|
for i, p in enumerate(dfip.phases):
|
2013-07-15 11:45:55 -04:00
|
|
|
elts = ["@" + str(s.cycle_counter) + ":" + str(i)]
|
2012-04-01 17:23:45 -04:00
|
|
|
elts += decode_sdram(p.ras_n, p.cas_n, p.we_n, p.bank, p.address)
|
|
|
|
if len(elts) > 1:
|
|
|
|
print("\t".join(elts))
|