From 8de1d91eac29407a78060cc44810f76e71162d37 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Mon, 1 Oct 2018 11:18:39 +0200 Subject: [PATCH 1/7] core: add with_bank paramteter to NativePort (cause issues on adaptation is bank is always exposed) --- litedram/common.py | 7 ++++--- litedram/frontend/crossbar.py | 24 +++++++++++++++++++++--- litedram/frontend/ecc.py | 4 ++-- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/litedram/common.py b/litedram/common.py index 4b9d39a..597c2da 100644 --- a/litedram/common.py +++ b/litedram/common.py @@ -99,6 +99,7 @@ def cmd_description(address_width): ("addr", address_width) ] + def wdata_description(data_width, with_bank): r = [ ("data", data_width), @@ -116,7 +117,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 @@ -126,8 +127,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..7aea3cd 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.settigns.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) ] From f7f8169883f60153b7c7e9eb0768db9e65a94e67 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Mon, 1 Oct 2018 11:18:54 +0200 Subject: [PATCH 2/7] test: update downconverter/upconverter --- test/test_downconverter.py | 22 +++++++++++----------- test/test_upconverter.py | 22 +++++++++++----------- 2 files changed, 22 insertions(+), 22 deletions(-) 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_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 From 1bc016cf6c8072b93ee1a62396b2aa798031e37a Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Mon, 1 Oct 2018 11:29:08 +0200 Subject: [PATCH 3/7] test: add test_examples --- litedram/frontend/crossbar.py | 2 +- test/test_examples.py | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 test/test_examples.py diff --git a/litedram/frontend/crossbar.py b/litedram/frontend/crossbar.py index 7aea3cd..fec6dcd 100644 --- a/litedram/frontend/crossbar.py +++ b/litedram/frontend/crossbar.py @@ -50,7 +50,7 @@ class LiteDRAMCrossbar(Module): data_width=self.controller.data_width, clock_domain="sys", id=len(self.masters), - with_bank=self.controller.settigns.with_reordering) + with_bank=self.controller.settings.with_reordering) self.masters.append(port) # clock domain crossing 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) From 426ae23d2aff8273126705c6e66a6b0a70c1c5eb Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Mon, 1 Oct 2018 11:48:15 +0200 Subject: [PATCH 4/7] examples/litedram_gen: add sdram_module_speedgrade parameter --- examples/arty_config.py | 1 + examples/genesys2_config.py | 1 + examples/litedram_gen.py | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/arty_config.py b/examples/arty_config.py index 373421b..20bca1c 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": "1066", "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"], From 0f46dc4ab7706ba6089010e86dea13350bfaa68c Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Mon, 1 Oct 2018 11:59:54 +0200 Subject: [PATCH 5/7] modules: add DDR3-800 timings for MT41J128M16 and use it on arty example --- examples/arty_config.py | 2 +- litedram/modules.py | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/examples/arty_config.py b/examples/arty_config.py index 20bca1c..8ed4b75 100644 --- a/examples/arty_config.py +++ b/examples/arty_config.py @@ -8,7 +8,7 @@ core_config = { # modules / phy "sdram_module": MT41K128M16, "sdram_module_nb": 1, - "sdram_module_speedgrade": "1066", + "sdram_module_speedgrade": "800", "sdram_rank_nb": 1, "sdram_phy": A7DDRPHY, diff --git a/litedram/modules.py b/litedram/modules.py index da6a020..3964108 100644 --- a/litedram/modules.py +++ b/litedram/modules.py @@ -248,6 +248,14 @@ 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 = (20, None) + tRC_800 = 50.625 + tRAS_800 = 37.5 # DDR3-1066 tRP_1066 = 13.1 tRCD_1066 = 13.1 From 70620689a009c75af94b39de95cb8fcde43d3edd Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Mon, 1 Oct 2018 12:17:50 +0200 Subject: [PATCH 6/7] modules: split DDR3 in 2 categories: Chips and SO-DIMMs --- litedram/modules.py | 55 +++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/litedram/modules.py b/litedram/modules.py index 3964108..cbae78f 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 @@ -309,6 +309,33 @@ class MT41K256M16(MT41J256M16): pass +class K4B2G1646FBCK0(SDRAMModule): ### TODO: optimize and revalidate all timings, at cold and hot temperatures + memtype = "DDR3" + # geometry + nbanks = 8 + nrows = 16384 + ncols = 1024 + # speedgrade invariant timings + tREFI = 7800 # 3900 refresh more often at 85C+ + tWTR = (14, 35) + tCCD = (4, None) + tRRD = 10 # 4 * clk = 10ns + # speedgrade related timings + # DDR3-1600 + tRP_1600 = 13.125 + tRCD_1600 = 13.125 + tWR_1600 = 35 # this is hard-coded in MR0 to be 14 cycles, 14 * 2.5 = 35, see sdram_init.py@L224 + tRFC_1600 = 160 + tFAW_1600 = (None, 40) + # API retro-compatibility + tRP = tRP_1600 + tRCD = tRCD_1600 + tWR = tWR_1600 + tRFC = tRFC_1600 + tFAW = tFAW_1600 + + +# DDR3 (SO-DIMM) class MT8JTF12864(SDRAMModule): memtype = "DDR3" # geometry @@ -374,29 +401,3 @@ class MT18KSF1G72HZ(SDRAMModule): 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 - nbanks = 8 - nrows = 16384 - ncols = 1024 - # speedgrade invariant timings - tREFI = 7800 # 3900 refresh more often at 85C+ - tWTR = (14, 35) - tCCD = (4, None) - tRRD = 10 # 4 * clk = 10ns - # speedgrade related timings - # DDR3-1600 - tRP_1600 = 13.125 - tRCD_1600 = 13.125 - tWR_1600 = 35 # this is hard-coded in MR0 to be 14 cycles, 14 * 2.5 = 35, see sdram_init.py@L224 - tRFC_1600 = 160 - tFAW_1600 = (None, 40) - # API retro-compatibility - tRP = tRP_1600 - tRCD = tRCD_1600 - tWR = tWR_1600 - tRFC = tRFC_1600 - tFAW = tFAW_1600 From 41a8a246b65460fd1abe86d39a4107c349ad60e4 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Mon, 1 Oct 2018 19:41:30 +0200 Subject: [PATCH 7/7] modules: express tFAW in ns --- litedram/modules.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/litedram/modules.py b/litedram/modules.py index cbae78f..62cef5d 100644 --- a/litedram/modules.py +++ b/litedram/modules.py @@ -253,7 +253,7 @@ class MT41J128M16(SDRAMModule): tRCD_800 = 13.1 tWR_800 = 13.1 tRFC_800 = 64 - tFAW_800 = (20, None) + tFAW_800 = (None, 50) tRC_800 = 50.625 tRAS_800 = 37.5 # DDR3-1066 @@ -261,7 +261,7 @@ class MT41J128M16(SDRAMModule): 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 @@ -269,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 @@ -277,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 @@ -352,13 +352,13 @@ class MT8JTF12864(SDRAMModule): tRCD_1066 = 15 tWR_1066 = 15 tRFC_1066 = 86 - tFAW_1066 = (27, None) + tFAW_1066 = (None, 50) # DDR3-1333 tRP_1333 = 15 tRCD_1333 = 15 tWR_1333 = 15 tRFC_1333 = 107 - tFAW_1333 = (30, None) + tFAW_1333 = (None, 45) # API retro-compatibility tRP = tRP_1333 tRCD = tRCD_1333 @@ -382,19 +382,19 @@ class MT18KSF1G72HZ(SDRAMModule): tRCD_1066 = 15 tWR_1066 = 15 tRFC_1066 = 86 - tFAW_1066 = (27, None) + tFAW_1066 = (None, 50) # DDR3-1333 tRP_1333 = 15 tRCD_1333 = 15 tWR_1333 = 15 tRFC_1333 = 107 - tFAW_1333 = (30, None) + tFAW_1333 = (None, 45) # DDR3-1600 tRP_1600 = 13.125 tRCD_1600 = 13.125 tWR_1600 = 13.125 tRFC_1600 = 128 - tFAW_1600 = (32, None) + tFAW_1600 = (None, 40) # API retro-compatibility tRP = tRP_1600 tRCD = tRCD_1600