diff --git a/examples/arty_config.py b/examples/arty_config.py index 373421b..8ed4b75 100644 --- a/examples/arty_config.py +++ b/examples/arty_config.py @@ -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, diff --git a/examples/genesys2_config.py b/examples/genesys2_config.py index 1480342..2ad175d 100644 --- a/examples/genesys2_config.py +++ b/examples/genesys2_config.py @@ -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, diff --git a/examples/litedram_gen.py b/examples/litedram_gen.py index 2e1fbd6..a6f82ae 100755 --- a/examples/litedram_gen.py +++ b/examples/litedram_gen.py @@ -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"], diff --git a/litedram/common.py b/litedram/common.py index 3104b53..70f3a32 100644 --- a/litedram/common.py +++ b/litedram/common.py @@ -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() diff --git a/litedram/frontend/crossbar.py b/litedram/frontend/crossbar.py index 2c3f4eb..fec6dcd 100644 --- a/litedram/frontend/crossbar.py +++ b/litedram/frontend/crossbar.py @@ -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 diff --git a/litedram/frontend/ecc.py b/litedram/frontend/ecc.py index 5037944..f7a4249 100644 --- a/litedram/frontend/ecc.py +++ b/litedram/frontend/ecc.py @@ -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) ] diff --git a/litedram/modules.py b/litedram/modules.py index da6a020..62cef5d 100644 --- a/litedram/modules.py +++ b/litedram/modules.py @@ -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 diff --git a/test/test_downconverter.py b/test/test_downconverter.py index 1542621..7d76332 100755 --- a/test/test_downconverter.py +++ b/test/test_downconverter.py @@ -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 diff --git a/test/test_examples.py b/test/test_examples.py new file mode 100644 index 0000000..3f31525 --- /dev/null +++ b/test/test_examples.py @@ -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) diff --git a/test/test_upconverter.py b/test/test_upconverter.py index e11a403..baa5d1f 100755 --- a/test/test_upconverter.py +++ b/test/test_upconverter.py @@ -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