mirror of
https://github.com/enjoy-digital/litedram.git
synced 2025-01-04 09:52:25 -05:00
Merge branch 'master' of https://github.com/enjoy-digital/litedram
This commit is contained in:
commit
208f5562d1
10 changed files with 153 additions and 102 deletions
|
@ -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,
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
||||
|
|
|
@ -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"],
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
]
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
21
test/test_examples.py
Normal 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)
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue