This commit is contained in:
2018-10-01 19:36:05 -04:00
commit 208f5562d1
10 changed files with 153 additions and 102 deletions

View file

@ -8,6 +8,7 @@ core_config = {
# modules / phy
"sdram_module": MT41K128M16,
"sdram_module_nb": 1,
"sdram_module_speedgrade": "800",
"sdram_rank_nb": 1,
"sdram_phy": A7DDRPHY,

View file

@ -8,6 +8,7 @@ core_config = {
# modules / phy
"sdram_module": MT41J256M16,
"sdram_module_nb": 2,
"sdram_module_speedgrade": "1333",
"sdram_rank_nb": 1,
"sdram_phy": K7DDRPHY,

View file

@ -210,7 +210,7 @@ class LiteDRAMCore(SoCSDRAM):
rtt_nom=core_config["rtt_nom"],
rtt_wr=core_config["rtt_wr"],
ron=core_config["ron"])
sdram_module = core_config["sdram_module"](sys_clk_freq, "1:4")
sdram_module = core_config["sdram_module"](sys_clk_freq, "1:4", speedgrade=core_config["sdram_module_speedgrade"])
controller_settings = controller_settings=ControllerSettings(
cmd_buffer_depth=core_config["cmd_buffer_depth"],
read_time=core_config["read_time"],

View file

@ -102,6 +102,7 @@ def cmd_description(address_width):
("addr", address_width)
]
def wdata_description(data_width, with_bank):
r = [
("data", data_width),
@ -119,7 +120,7 @@ def rdata_description(data_width, with_bank):
class LiteDRAMNativePort:
def __init__(self, mode, address_width, data_width, clock_domain="sys", id=0):
def __init__(self, mode, address_width, data_width, clock_domain="sys", id=0, with_bank=False):
self.mode = mode
self.address_width = address_width
self.data_width = data_width
@ -129,8 +130,8 @@ class LiteDRAMNativePort:
self.lock = Signal()
self.cmd = stream.Endpoint(cmd_description(address_width))
self.wdata = stream.Endpoint(wdata_description(data_width, True))
self.rdata = stream.Endpoint(rdata_description(data_width, True))
self.wdata = stream.Endpoint(wdata_description(data_width, with_bank))
self.rdata = stream.Endpoint(rdata_description(data_width, with_bank))
self.flush = Signal()

View file

@ -44,12 +44,24 @@ class LiteDRAMCrossbar(Module):
data_width = self.controller.data_width
# crossbar port
port = LiteDRAMNativePort(mode, self.rca_bits + self.bank_bits - self.rank_bits, self.controller.data_width, "sys", len(self.masters))
port = LiteDRAMNativePort(
mode=mode,
address_width=self.rca_bits + self.bank_bits - self.rank_bits,
data_width=self.controller.data_width,
clock_domain="sys",
id=len(self.masters),
with_bank=self.controller.settings.with_reordering)
self.masters.append(port)
# clock domain crossing
if clock_domain != "sys":
new_port = LiteDRAMNativePort(mode, port.address_width, port.data_width, clock_domain, port.id)
new_port = LiteDRAMNativePort(
mode=mode,
address_width=port.address_width,
data_width=port.data_width,
clock_domain=clock_domain,
id=port.id,
with_bank=self.controller.settings.with_reordering)
self.submodules += LiteDRAMNativePortCDC(new_port, port)
port = new_port
@ -59,7 +71,13 @@ class LiteDRAMCrossbar(Module):
addr_shift = -log2_int(data_width//self.controller.data_width)
else:
addr_shift = log2_int(self.controller.data_width//data_width)
new_port = LiteDRAMNativePort(mode, port.address_width + addr_shift, data_width, clock_domain, port.id)
new_port = LiteDRAMNativePort(
mode=mode,
address_width=port.address_width + addr_shift,
data_width=data_width,
clock_domain=clock_domain,
id=port.id,
with_bank=self.controller.settings.with_reordering)
self.submodules += ClockDomainsRenamer(clock_domain)(LiteDRAMNativePortConverter(new_port, port, reverse))
port = new_port

View file

@ -211,7 +211,7 @@ class LiteDRAMNativePortECC(Module, AutoCSR):
ecc_wdata = BufferizeEndpoints({"source": DIR_SOURCE})(ecc_wdata)
self.submodules += ecc_wdata
self.comb += [
port_from.wdata.connect(ecc_wdata.sink),
port_from.wdata.connect(ecc_wdata.sink, omit={"bank"}),
ecc_wdata.source.connect(port_to.wdata)
]
@ -223,7 +223,7 @@ class LiteDRAMNativePortECC(Module, AutoCSR):
self.submodules += ecc_rdata
self.comb += [
ecc_rdata.enable.eq(self.enable.storage),
port_to.rdata.connect(ecc_rdata.sink),
port_to.rdata.connect(ecc_rdata.sink, omit={"bank"}),
ecc_rdata.source.connect(port_from.rdata)
]

View file

@ -235,7 +235,7 @@ class P3R1GE4JGF(SDRAMModule):
tRFC = 127.5
# DDR3
# DDR3 (Chips)
class MT41J128M16(SDRAMModule):
memtype = "DDR3"
# geometry
@ -248,12 +248,20 @@ class MT41J128M16(SDRAMModule):
tCCD = (4, None)
tRRD = 10
# speedgrade related timings
# DDR3-800
tRP_800 = 13.1
tRCD_800 = 13.1
tWR_800 = 13.1
tRFC_800 = 64
tFAW_800 = (None, 50)
tRC_800 = 50.625
tRAS_800 = 37.5
# DDR3-1066
tRP_1066 = 13.1
tRCD_1066 = 13.1
tWR_1066 = 13.1
tRFC_1066 = 86
tFAW_1066 = (27, None)
tFAW_1066 = (None, 50)
tRC_1066 = 50.625
tRAS_1066 = 37.5
# DDR3-1333
@ -261,7 +269,7 @@ class MT41J128M16(SDRAMModule):
tRCD_1333 = 13.5
tWR_1333 = 13.5
tRFC_1333 = 107
tFAW_1333 = (30, None)
tFAW_1333 = (None, 45)
tRC_1333 = 49.5
tRAS_1333 = 36
# DDR3-1600
@ -269,7 +277,7 @@ class MT41J128M16(SDRAMModule):
tRCD_1600 = 13.75
tWR_1600 = 13.75
tRFC_1600 = 128
tFAW_1600 = (32, None)
tFAW_1600 = (None, 40)
tRC_1600 = 48.75
tRAS_1600 = 35
# API retro-compatibility
@ -301,73 +309,6 @@ class MT41K256M16(MT41J256M16):
pass
class MT8JTF12864(SDRAMModule):
memtype = "DDR3"
# geometry
nbanks = 8
nrows = 16384
ncols = 1024
# speedgrade invariant timings
tREFI = 64e6/8192
tWTR = (4, 7.5)
tCCD = (4, None)
# speedgrade related timings
# DDR3-1066
tRP_1066 = 15
tRCD_1066 = 15
tWR_1066 = 15
tRFC_1066 = 86
tFAW_1066 = (27, None)
# DDR3-1333
tRP_1333 = 15
tRCD_1333 = 15
tWR_1333 = 15
tRFC_1333 = 107
tFAW_1333 = (30, None)
# API retro-compatibility
tRP = tRP_1333
tRCD = tRCD_1333
tWR = tWR_1333
tRFC = tRFC_1333
tFAW = tFAW_1333
class MT18KSF1G72HZ(SDRAMModule):
memtype = "DDR3"
# geometry
nbanks = 8
nrows = 65536
ncols = 1024
# speedgrade invariant timings
tREFI = 64e6/8192
tWTR = (4, 7.5)
tCCD = (4, None)
# DDR3-1066
tRP_1066 = 15
tRCD_1066 = 15
tWR_1066 = 15
tRFC_1066 = 86
tFAW_1066 = (27, None)
# DDR3-1333
tRP_1333 = 15
tRCD_1333 = 15
tWR_1333 = 15
tRFC_1333 = 107
tFAW_1333 = (30, None)
# DDR3-1600
tRP_1600 = 13.125
tRCD_1600 = 13.125
tWR_1600 = 13.125
tRFC_1600 = 128
tFAW_1600 = (32, None)
# API retro-compatibility
tRP = tRP_1600
tRCD = tRCD_1600
tWR = tWR_1600
tRFC = tRFC_1600
tFAW = tFAW_1600
class K4B2G1646FBCK0(SDRAMModule): ### TODO: optimize and revalidate all timings, at cold and hot temperatures
memtype = "DDR3"
# geometry
@ -392,3 +333,71 @@ class K4B2G1646FBCK0(SDRAMModule): ### TODO: optimize and revalidate all timing
tWR = tWR_1600
tRFC = tRFC_1600
tFAW = tFAW_1600
# DDR3 (SO-DIMM)
class MT8JTF12864(SDRAMModule):
memtype = "DDR3"
# geometry
nbanks = 8
nrows = 16384
ncols = 1024
# speedgrade invariant timings
tREFI = 64e6/8192
tWTR = (4, 7.5)
tCCD = (4, None)
# speedgrade related timings
# DDR3-1066
tRP_1066 = 15
tRCD_1066 = 15
tWR_1066 = 15
tRFC_1066 = 86
tFAW_1066 = (None, 50)
# DDR3-1333
tRP_1333 = 15
tRCD_1333 = 15
tWR_1333 = 15
tRFC_1333 = 107
tFAW_1333 = (None, 45)
# API retro-compatibility
tRP = tRP_1333
tRCD = tRCD_1333
tWR = tWR_1333
tRFC = tRFC_1333
tFAW = tFAW_1333
class MT18KSF1G72HZ(SDRAMModule):
memtype = "DDR3"
# geometry
nbanks = 8
nrows = 65536
ncols = 1024
# speedgrade invariant timings
tREFI = 64e6/8192
tWTR = (4, 7.5)
tCCD = (4, None)
# DDR3-1066
tRP_1066 = 15
tRCD_1066 = 15
tWR_1066 = 15
tRFC_1066 = 86
tFAW_1066 = (None, 50)
# DDR3-1333
tRP_1333 = 15
tRCD_1333 = 15
tWR_1333 = 15
tRFC_1333 = 107
tFAW_1333 = (None, 45)
# DDR3-1600
tRP_1600 = 13.125
tRCD_1600 = 13.125
tWR_1600 = 13.125
tRFC_1600 = 128
tFAW_1600 = (None, 40)
# API retro-compatibility
tRP = tRP_1600
tRCD = tRCD_1600
tWR = tWR_1600
tRFC = tRFC_1600
tFAW = tFAW_1600

View file

@ -4,7 +4,7 @@ from migen import *
from litex.soc.interconnect.stream import *
from litedram.common import LiteDRAMWritePort, LiteDRAMReadPort
from litedram.common import LiteDRAMNativeWritePort, LiteDRAMNativeReadPort
from litedram.frontend.adaptation import LiteDRAMNativePortConverter
from test.common import *
@ -15,17 +15,17 @@ from litex.gen.sim import *
class DUT(Module):
def __init__(self):
# write port and converter
self.write_user_port = LiteDRAMWritePort(aw=32, dw=64)
self.write_crossbar_port = LiteDRAMWritePort(aw=32, dw=32)
write_converter = LiteDRAMNativePortConverter(self.write_user_port,
self.write_crossbar_port)
self.write_user_port = LiteDRAMNativeWritePort(address_width=32, data_width=64)
self.write_crossbar_port = LiteDRAMNativeWritePort(address_width=32, data_width=32)
write_converter = LiteDRAMNativePortConverter(
self.write_user_port, self.write_crossbar_port)
self.submodules += write_converter
# read port and converter
self.read_user_port = LiteDRAMReadPort(aw=32, dw=64)
self.read_crossbar_port = LiteDRAMReadPort(aw=32, dw=32)
read_converter = LiteDRAMNativePortConverter(self.read_user_port,
self.read_crossbar_port)
self.read_user_port = LiteDRAMNativeReadPort(address_width=32, data_width=64)
self.read_crossbar_port = LiteDRAMNativeReadPort(address_width=32, data_width=32)
read_converter = LiteDRAMNativePortConverter(
self.read_user_port, self.read_crossbar_port)
self.submodules += read_converter
# memory
@ -50,7 +50,7 @@ def main_generator(write_port, read_port):
for i in range(8):
yield write_port.cmd.valid.eq(1)
yield write_port.cmd.we.eq(1)
yield write_port.cmd.adr.eq(i)
yield write_port.cmd.addr.eq(i)
yield write_port.wdata.valid.eq(1)
yield write_port.wdata.data.eq(write_data[i])
yield
@ -65,7 +65,7 @@ def main_generator(write_port, read_port):
for i in range(8):
yield read_port.cmd.valid.eq(1)
yield read_port.cmd.we.eq(0)
yield read_port.cmd.adr.eq(i)
yield read_port.cmd.addr.eq(i)
yield
while (yield read_port.cmd.ready) == 0:
yield

21
test/test_examples.py Normal file
View file

@ -0,0 +1,21 @@
import unittest
import os
def build_config(name):
errors = 0
os.system("rm -rf examples/build")
os.system("cd examples && python3 litedram_gen.py {}_config.py".format(name))
errors += not os.path.isfile("examples/build/gateware/litedram_core.v")
os.system("rm -rf examples/build")
return errors
class TestExamples(unittest.TestCase):
def test_arty(self):
errors = build_config("arty")
self.assertEqual(errors, 0)
def test_genesys2(self):
errors = build_config("genesys2")
self.assertEqual(errors, 0)

View file

@ -4,7 +4,7 @@ from migen import *
from litex.soc.interconnect.stream import *
from litedram.common import LiteDRAMWritePort, LiteDRAMReadPort
from litedram.common import LiteDRAMNativeWritePort, LiteDRAMNativeReadPort
from litedram.frontend.adaptation import LiteDRAMNativePortConverter
from test.common import *
@ -15,17 +15,17 @@ from litex.gen.sim import *
class DUT(Module):
def __init__(self):
# write port and converter
self.write_user_port = LiteDRAMWritePort(aw=32, dw=32)
self.write_crossbar_port = LiteDRAMWritePort(aw=32, dw=128)
write_converter = LiteDRAMNativePortConverter(self.write_user_port,
self.write_crossbar_port)
self.write_user_port = LiteDRAMNativeWritePort(address_width=32, data_width=32)
self.write_crossbar_port = LiteDRAMNativeWritePort(address_width=32, data_width=128)
write_converter = LiteDRAMNativePortConverter(
self.write_user_port, self.write_crossbar_port)
self.submodules += write_converter
# read port and converter
self.read_user_port = LiteDRAMReadPort(aw=32, dw=32)
self.read_crossbar_port = LiteDRAMReadPort(aw=32, dw=128)
read_converter = LiteDRAMNativePortConverter(self.read_user_port,
self.read_crossbar_port)
self.read_user_port = LiteDRAMNativeReadPort(address_width=32, data_width=32)
self.read_crossbar_port = LiteDRAMNativeReadPort(address_width=32, data_width=128)
read_converter = LiteDRAMNativePortConverter(
self.read_user_port, self.read_crossbar_port)
self.submodules += read_converter
# memory
@ -50,7 +50,7 @@ def main_generator(write_port, read_port):
for i in range(16):
yield write_port.cmd.valid.eq(1)
yield write_port.cmd.we.eq(1)
yield write_port.cmd.adr.eq(i)
yield write_port.cmd.addr.eq(i)
yield
while (yield write_port.cmd.ready) == 0:
yield
@ -68,7 +68,7 @@ def main_generator(write_port, read_port):
for i in range(16):
yield read_port.cmd.valid.eq(1)
yield read_port.cmd.we.eq(0)
yield read_port.cmd.adr.eq(i)
yield read_port.cmd.addr.eq(i)
yield
while (yield read_port.cmd.ready) == 0:
yield