From 91cae335e593ee8d828b08b5447d9a7817e37da8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Boczar?= Date: Fri, 23 Jul 2021 14:44:15 +0200 Subject: [PATCH 1/7] init: add parentheses around #define with an expression --- litedram/init.py | 2 +- test/reference/ddr3_init.h | 2 +- test/reference/ddr4_init.h | 6 +++--- test/reference/sdr_init.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/litedram/init.py b/litedram/init.py index 7bed74e..4916a42 100644 --- a/litedram/init.py +++ b/litedram/init.py @@ -707,7 +707,7 @@ def get_sdram_phy_c_header(phy_settings, timing_settings): r += "#define SDRAM_PHY_READ_LEVELING_CAPABLE\n" # Define number of modules/delays/bitslips - r += "#define SDRAM_PHY_MODULES SDRAM_PHY_DATABITS/8\n" + r += "#define SDRAM_PHY_MODULES (SDRAM_PHY_DATABITS/8)\n" if phytype in ["USDDRPHY", "USPDDRPHY"]: r += "#define SDRAM_PHY_DELAYS 512\n" r += "#define SDRAM_PHY_BITSLIPS 8\n" diff --git a/test/reference/ddr3_init.h b/test/reference/ddr3_init.h index 6835acc..97e97f6 100644 --- a/test/reference/ddr3_init.h +++ b/test/reference/ddr3_init.h @@ -28,7 +28,7 @@ #define SDRAM_PHY_WRITE_DQ_DQS_TRAINING_CAPABLE #define SDRAM_PHY_WRITE_LATENCY_CALIBRATION_CAPABLE #define SDRAM_PHY_READ_LEVELING_CAPABLE -#define SDRAM_PHY_MODULES SDRAM_PHY_DATABITS/8 +#define SDRAM_PHY_MODULES (SDRAM_PHY_DATABITS/8) #define SDRAM_PHY_DELAYS 32 #define SDRAM_PHY_BITSLIPS 8 diff --git a/test/reference/ddr4_init.h b/test/reference/ddr4_init.h index a45cba5..35bad19 100644 --- a/test/reference/ddr4_init.h +++ b/test/reference/ddr4_init.h @@ -27,7 +27,7 @@ #define SDRAM_PHY_WRITE_LEVELING_CAPABLE #define SDRAM_PHY_WRITE_LATENCY_CALIBRATION_CAPABLE #define SDRAM_PHY_READ_LEVELING_CAPABLE -#define SDRAM_PHY_MODULES SDRAM_PHY_DATABITS/8 +#define SDRAM_PHY_MODULES (SDRAM_PHY_DATABITS/8) #define SDRAM_PHY_DELAYS 512 #define SDRAM_PHY_BITSLIPS 8 @@ -65,7 +65,7 @@ static inline unsigned long sdram_dfii_pix_wrdata_addr(int phase){ default: return 0; } } - + static inline unsigned long sdram_dfii_pix_rddata_addr(int phase){ switch (phase) { case 0: return CSR_SDRAM_DFII_PI0_RDDATA_ADDR; @@ -75,7 +75,7 @@ static inline unsigned long sdram_dfii_pix_rddata_addr(int phase){ default: return 0; } } - + #define DDRX_MR_WRLVL_ADDRESS 1 #define DDRX_MR_WRLVL_RESET 769 #define DDRX_MR_WRLVL_BIT 7 diff --git a/test/reference/sdr_init.h b/test/reference/sdr_init.h index fe8b0f1..e2be7dc 100644 --- a/test/reference/sdr_init.h +++ b/test/reference/sdr_init.h @@ -23,7 +23,7 @@ #define SDRAM_PHY_CWL 2 #define SDRAM_PHY_RDPHASE 0 #define SDRAM_PHY_WRPHASE 0 -#define SDRAM_PHY_MODULES SDRAM_PHY_DATABITS/8 +#define SDRAM_PHY_MODULES (SDRAM_PHY_DATABITS/8) void cdelay(int i); From 993ba3169785e11eeaf2e6416eb42fa123f3c113 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Boczar?= Date: Tue, 3 Aug 2021 15:49:14 +0200 Subject: [PATCH 2/7] init: generate `#define SDRAM_PHY_DFI_DATABITS` constant --- litedram/init.py | 1 + 1 file changed, 1 insertion(+) diff --git a/litedram/init.py b/litedram/init.py index 4916a42..22c32d3 100644 --- a/litedram/init.py +++ b/litedram/init.py @@ -670,6 +670,7 @@ def get_sdram_phy_c_header(phy_settings, timing_settings): r += "#define SDRAM_PHY_"+phytype+"\n" r += "#define SDRAM_PHY_XDR "+str(1 if phy_settings.memtype == "SDR" else 2) + "\n" r += "#define SDRAM_PHY_DATABITS "+str(phy_settings.databits) + "\n" + r += "#define SDRAM_PHY_DFI_DATABITS "+str(phy_settings.dfi_databits) + "\n" r += "#define SDRAM_PHY_PHASES "+str(nphases)+"\n" if phy_settings.cl is not None: r += "#define SDRAM_PHY_CL "+str(phy_settings.cl)+"\n" From 2200bd43a557aef22f53b0daf2b1f82d26e86d97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Boczar?= Date: Tue, 20 Jul 2021 10:24:11 +0200 Subject: [PATCH 3/7] test/reference: update headers to include SDRAM_PHY_DFI_DATABITS --- test/reference/ddr3_init.h | 1 + test/reference/ddr4_init.h | 1 + test/reference/sdr_init.h | 1 + 3 files changed, 3 insertions(+) diff --git a/test/reference/ddr3_init.h b/test/reference/ddr3_init.h index 97e97f6..5ee2cdb 100644 --- a/test/reference/ddr3_init.h +++ b/test/reference/ddr3_init.h @@ -18,6 +18,7 @@ #define SDRAM_PHY_K7DDRPHY #define SDRAM_PHY_XDR 2 #define SDRAM_PHY_DATABITS 64 +#define SDRAM_PHY_DFI_DATABITS 128 #define SDRAM_PHY_PHASES 4 #define SDRAM_PHY_CL 7 #define SDRAM_PHY_CWL 6 diff --git a/test/reference/ddr4_init.h b/test/reference/ddr4_init.h index 35bad19..2f6a261 100644 --- a/test/reference/ddr4_init.h +++ b/test/reference/ddr4_init.h @@ -18,6 +18,7 @@ #define SDRAM_PHY_USDDRPHY #define SDRAM_PHY_XDR 2 #define SDRAM_PHY_DATABITS 64 +#define SDRAM_PHY_DFI_DATABITS 128 #define SDRAM_PHY_PHASES 4 #define SDRAM_PHY_CL 9 #define SDRAM_PHY_CWL 9 diff --git a/test/reference/sdr_init.h b/test/reference/sdr_init.h index e2be7dc..235f0ae 100644 --- a/test/reference/sdr_init.h +++ b/test/reference/sdr_init.h @@ -18,6 +18,7 @@ #define SDRAM_PHY_GENSDRPHY #define SDRAM_PHY_XDR 1 #define SDRAM_PHY_DATABITS 16 +#define SDRAM_PHY_DFI_DATABITS 16 #define SDRAM_PHY_PHASES 1 #define SDRAM_PHY_CL 2 #define SDRAM_PHY_CWL 2 From 377746bfd833b51f7d1a0fb3ae81ced5758c63a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Boczar?= Date: Tue, 3 Aug 2021 15:50:06 +0200 Subject: [PATCH 4/7] init: add helper class to make C code generation simpler --- litedram/init.py | 312 +++++++++++++++++++++++++++++------------------ 1 file changed, 191 insertions(+), 121 deletions(-) diff --git a/litedram/init.py b/litedram/init.py index 22c32d3..f8381db 100644 --- a/litedram/init.py +++ b/litedram/init.py @@ -11,6 +11,7 @@ # SPDX-License-Identifier: BSD-2-Clause import math +from contextlib import contextmanager from migen import * @@ -643,179 +644,248 @@ def get_sdram_phy_init_sequence(phy_settings, timing_settings): # C Header ----------------------------------------------------------------------------------------- +class CGenerator(list): + # C code generator - list of strings (=lines) or CGenerator instances (sub-generators) + def __init__(self, indent=0, indent_str="\t"): + self.indent = indent + self.indent_str = indent_str + + def __iadd__(self, x): + # make `c += "int x = 0;"` append it as line, not char-by-char + if isinstance(x, str): + x = [x] + return super().__iadd__(x) + + def header_guard(self, name): + self._header_guard = name + + def generate_lines(self): + if getattr(self, "_header_guard", None) is not None: + self.insert(0, f"#ifndef {self._header_guard}") + self.insert(1, f"#define {self._header_guard}") + self.insert(2, "") + self.append("") + self.append(f"#endif /* {self._header_guard} */") + self._header_guard = None + lines = [] + for entry in self: + if isinstance(entry, CGenerator): + lines.extend(entry.generate_lines()) + else: + line = (self.indent * self.indent_str) + entry + lines.append(line.rstrip()) + return lines + + def generate(self): + lines = self.generate_lines() + return "\n".join(lines).strip() + "\n" + + def include(self, path): + self.append(f"#include {path}") + + def define(self, var, value=None): + if isinstance(value, (int, float)): + value = str(value) + self.append(f"#define {var}" + (f" {value}" if value is not None else "")) + + def newline(self, n=1): + self.extend([""] * n) + + @contextmanager + def block(self, head=None, newline=True): + if head is not None: + self.append(head + (" {" if not newline else "")) + if newline: + self.append("{") + else: + self.append("{") + subgenerator = CGenerator(indent=self.indent + 1, indent_str=self.indent_str) + yield subgenerator + self.append(subgenerator) + self.append("}") + + def get_sdram_phy_c_header(phy_settings, timing_settings): - r = "#ifndef __GENERATED_SDRAM_PHY_H\n#define __GENERATED_SDRAM_PHY_H\n" - r += "#include \n" - r += "#include \n" - r += "\n" + r = CGenerator() + r.header_guard("__GENERATED_SDRAM_PHY_H") + r.include("") + r.include("") + r.newline() - r += "#define DFII_CONTROL_SEL 0x01\n" - r += "#define DFII_CONTROL_CKE 0x02\n" - r += "#define DFII_CONTROL_ODT 0x04\n" - r += "#define DFII_CONTROL_RESET_N 0x08\n" - r += "\n" + r.define("DFII_CONTROL_SEL", "0x01") + r.define("DFII_CONTROL_CKE", "0x02") + r.define("DFII_CONTROL_ODT", "0x04") + r.define("DFII_CONTROL_RESET_N", "0x08") + r.newline() - r += "#define DFII_COMMAND_CS 0x01\n" - r += "#define DFII_COMMAND_WE 0x02\n" - r += "#define DFII_COMMAND_CAS 0x04\n" - r += "#define DFII_COMMAND_RAS 0x08\n" - r += "#define DFII_COMMAND_WRDATA 0x10\n" - r += "#define DFII_COMMAND_RDDATA 0x20\n" - r += "\n" + r.define("DFII_COMMAND_CS", "0x01") + r.define("DFII_COMMAND_WE", "0x02") + r.define("DFII_COMMAND_CAS", "0x04") + r.define("DFII_COMMAND_RAS", "0x08") + r.define("DFII_COMMAND_WRDATA", "0x10") + r.define("DFII_COMMAND_RDDATA", "0x20") + r.newline() phytype = phy_settings.phytype.upper() nphases = phy_settings.nphases # Define PHY type and number of phases - r += "#define SDRAM_PHY_"+phytype+"\n" - r += "#define SDRAM_PHY_XDR "+str(1 if phy_settings.memtype == "SDR" else 2) + "\n" - r += "#define SDRAM_PHY_DATABITS "+str(phy_settings.databits) + "\n" - r += "#define SDRAM_PHY_DFI_DATABITS "+str(phy_settings.dfi_databits) + "\n" - r += "#define SDRAM_PHY_PHASES "+str(nphases)+"\n" - if phy_settings.cl is not None: - r += "#define SDRAM_PHY_CL "+str(phy_settings.cl)+"\n" - if phy_settings.cwl is not None: - r += "#define SDRAM_PHY_CWL "+str(phy_settings.cwl)+"\n" - if phy_settings.cmd_latency is not None: - r += "#define SDRAM_PHY_CMD_LATENCY "+str(phy_settings.cmd_latency)+"\n" - if phy_settings.cmd_delay is not None: - r += "#define SDRAM_PHY_CMD_DELAY "+str(phy_settings.cmd_delay)+"\n" + r.define(f"SDRAM_PHY_{phytype}") + r.define("SDRAM_PHY_XDR", 1 if phy_settings.memtype == "SDR" else 2) + r.define("SDRAM_PHY_DATABITS", phy_settings.databits) + r.define("SDRAM_PHY_DFI_DATABITS", phy_settings.dfi_databits) + r.define("SDRAM_PHY_PHASES", nphases) + for setting in ["cl", "cwl", "cmd_latency", "cmd_delay"]: + if getattr(phy_settings, setting, None) is not None: + r.define(f"SDRAM_PHY_{setting.upper()}", getattr(phy_settings, setting)) # Define PHY Read.Write phases rdphase = phy_settings.rdphase if isinstance(rdphase, Signal): rdphase = rdphase.reset.value - r += "#define SDRAM_PHY_RDPHASE "+str(rdphase)+"\n" + r.define("SDRAM_PHY_RDPHASE", rdphase) wrphase = phy_settings.wrphase if isinstance(wrphase, Signal): wrphase = wrphase.reset.value - r += "#define SDRAM_PHY_WRPHASE "+str(wrphase)+"\n" + r.define("SDRAM_PHY_WRPHASE", wrphase) - # Define Read/Write Leveling capability + phy_settings.write_leveling = False + phy_settings.write_dq_dqs_training = False + phy_settings.write_latency_calibration = False + phy_settings.read_leveling = False if phytype in ["USDDRPHY", "USPDDRPHY", "K7DDRPHY", "V7DDRPHY", "K7LPDDR4PHY", "V7LPDDR4PHY"]: - r += "#define SDRAM_PHY_WRITE_LEVELING_CAPABLE\n" + phy_settings.write_leveling = True if phytype in ["K7DDRPHY", "V7DDRPHY", "K7LPDDR4PHY", "V7LPDDR4PHY"]: - r += "#define SDRAM_PHY_WRITE_DQ_DQS_TRAINING_CAPABLE\n" + phy_settings.write_dq_dqs_training = True if phytype in ["USDDRPHY", "USPDDRPHY", "A7DDRPHY", "K7DDRPHY", "V7DDRPHY", "A7LPDDR4PHY", "K7LPDDR4PHY", "V7LPDDR4PHY"]: - r += "#define SDRAM_PHY_WRITE_LATENCY_CALIBRATION_CAPABLE\n" - r += "#define SDRAM_PHY_READ_LEVELING_CAPABLE\n" + phy_settings.write_latency_calibration = True + phy_settings.read_leveling = True if phytype in ["ECP5DDRPHY"]: - r += "#define SDRAM_PHY_READ_LEVELING_CAPABLE\n" + phy_settings.read_leveling = True if phytype in ["LPDDR4SIMPHY"]: - r += "#define SDRAM_PHY_READ_LEVELING_CAPABLE\n" + phy_settings.read_leveling = True + + phy_settings.delays = None + phy_settings.bitslips = None + if phytype in ["USDDRPHY", "USPDDRPHY"]: + phy_settings.delays = 512 + phy_settings.bitslips = 8 + elif phytype in ["A7DDRPHY", "K7DDRPHY", "V7DDRPHY"]: + phy_settings.delays = 32 + phy_settings.bitslips = 8 + elif phytype in ["A7LPDDR4PHY", "K7LPDDR4PHY", "V7LPDDR4PHY"]: + phy_settings.delays = 32 + phy_settings.bitslips = 16 + elif phytype in ["ECP5DDRPHY"]: + phy_settings.delays = 8 + phy_settings.bitslips = 4 + elif phytype in ["LPDDR4SIMPHY"]: + phy_settings.delays = 1 + phy_settings.bitslips = 16 + + # Define Read/Write Leveling capability + if phy_settings.write_leveling: + r.define("SDRAM_PHY_WRITE_LEVELING_CAPABLE") + if phy_settings.write_latency_calibration: + r.define("SDRAM_PHY_WRITE_LATENCY_CALIBRATION_CAPABLE") + if phy_settings.write_dq_dqs_training: + r.define("SDRAM_PHY_WRITE_DQ_DQS_TRAINING_CAPABLE") + if phy_settings.read_leveling: + r.define("SDRAM_PHY_READ_LEVELING_CAPABLE") # Define number of modules/delays/bitslips - r += "#define SDRAM_PHY_MODULES (SDRAM_PHY_DATABITS/8)\n" + r.define("SDRAM_PHY_MODULES", "(SDRAM_PHY_DATABITS/8)") if phytype in ["USDDRPHY", "USPDDRPHY"]: - r += "#define SDRAM_PHY_DELAYS 512\n" - r += "#define SDRAM_PHY_BITSLIPS 8\n" + r.define("SDRAM_PHY_DELAYS", 512) + r.define("SDRAM_PHY_BITSLIPS", 8) elif phytype in ["A7DDRPHY", "K7DDRPHY", "V7DDRPHY"]: - r += "#define SDRAM_PHY_DELAYS 32\n" - r += "#define SDRAM_PHY_BITSLIPS 8\n" + r.define("SDRAM_PHY_DELAYS", 32) + r.define("SDRAM_PHY_BITSLIPS", 8) elif phytype in ["A7LPDDR4PHY", "K7LPDDR4PHY", "V7LPDDR4PHY"]: - r += "#define SDRAM_PHY_DELAYS 32\n" - r += "#define SDRAM_PHY_BITSLIPS 16\n" + r.define("SDRAM_PHY_DELAYS", 32) + r.define("SDRAM_PHY_BITSLIPS", 16) elif phytype in ["ECP5DDRPHY"]: - r += "#define SDRAM_PHY_DELAYS 8\n" - r += "#define SDRAM_PHY_BITSLIPS 4\n" + r.define("SDRAM_PHY_DELAYS", 8) + r.define("SDRAM_PHY_BITSLIPS", 4) elif phytype in ["LPDDR4SIMPHY"]: - r += "#define SDRAM_PHY_DELAYS 1\n" - r += "#define SDRAM_PHY_BITSLIPS 16\n" + r.define("SDRAM_PHY_DELAYS", 1) + r.define("SDRAM_PHY_BITSLIPS", 16) if phy_settings.is_rdimm: assert phy_settings.memtype == "DDR4" - r += "#define SDRAM_PHY_DDR4_RDIMM\n" + r.define("SDRAM_PHY_DDR4_RDIMM") - r += "\n" + r.newline() - r += "void cdelay(int i);\n" + r += "void cdelay(int i);" + r.newline() # Commands functions for n in range(nphases): - r += """ -__attribute__((unused)) static inline void command_p{n}(int cmd) -{{ - sdram_dfii_pi{n}_command_write(cmd); - sdram_dfii_pi{n}_command_issue_write(1); -}}""".format(n=str(n)) - r += "\n\n" + with r.block(f"__attribute__((unused)) static inline void command_p{n}(int cmd)") as b: + b += f"sdram_dfii_pi{n}_command_write(cmd);" + b += f"sdram_dfii_pi{n}_command_issue_write(1);" + r.newline() # Write/Read functions - pix_addr_fmt = """ -static inline unsigned long {name}(int phase){{ - switch (phase) {{ - {cases} - default: return 0; - }} -}} - """ - get_cases = lambda addrs: ["case {}: return {};".format(i, addr) for i, addr in enumerate(addrs)] - - r += "#define DFII_PIX_DATA_SIZE CSR_SDRAM_DFII_PI0_WRDATA_SIZE\n" - sdram_dfii_pix_wrdata_addr = [] - for n in range(nphases): - sdram_dfii_pix_wrdata_addr.append("CSR_SDRAM_DFII_PI{n}_WRDATA_ADDR".format(n=n)) - r += pix_addr_fmt.format( - name = "sdram_dfii_pix_wrdata_addr", - cases = "\n\t\t".join(get_cases(sdram_dfii_pix_wrdata_addr))) - - sdram_dfii_pix_rddata_addr = [] - for n in range(nphases): - sdram_dfii_pix_rddata_addr.append("CSR_SDRAM_DFII_PI{n}_RDDATA_ADDR".format(n=n)) - r += pix_addr_fmt.format( - name = "sdram_dfii_pix_rddata_addr", - cases = "\n\t\t".join(get_cases(sdram_dfii_pix_rddata_addr))) - r += "\n" + r.define("DFII_PIX_DATA_SIZE", "CSR_SDRAM_DFII_PI0_WRDATA_SIZE") + r.newline() + for data in ["wrdata", "rddata"]: + with r.block(f"static inline unsigned long sdram_dfii_pix_{data}_addr(int phase)") as b: + with b.block("switch (phase)", newline=False) as s: + for n in range(nphases): + s += f"case {n}: return CSR_SDRAM_DFII_PI{n}_{data.upper()}_ADDR;" + s += "default: return 0;" + r.newline() init_sequence, mr = get_sdram_phy_init_sequence(phy_settings, timing_settings) if phy_settings.memtype in ["DDR3", "DDR4"]: # The value of MR1[7] needs to be modified during write leveling - r += "#define DDRX_MR_WRLVL_ADDRESS {}\n".format(1) - r += "#define DDRX_MR_WRLVL_RESET {}\n".format(mr[1]) - r += "#define DDRX_MR_WRLVL_BIT {}\n\n".format(7) + r.define("DDRX_MR_WRLVL_ADDRESS", 1) + r.define("DDRX_MR_WRLVL_RESET", mr[1]) + r.define("DDRX_MR_WRLVL_BIT", 7) + r.newline() elif phy_settings.memtype in ["LPDDR4"]: # Write leveling enabled by MR2[7] - r += "#define DDRX_MR_WRLVL_ADDRESS {}\n".format(2) - r += "#define DDRX_MR_WRLVL_RESET {}\n".format(mr[2]) - r += "#define DDRX_MR_WRLVL_BIT {}\n\n".format(7) + r.define("DDRX_MR_WRLVL_ADDRESS", 2) + r.define("DDRX_MR_WRLVL_RESET", mr[2]) + r.define("DDRX_MR_WRLVL_BIT", 7) + r.newline() - r += "static inline void init_sequence(void)\n{\n" - for comment, a, ba, cmd, delay in init_sequence: - invert_masks = [(0, 0), ] - if phy_settings.is_rdimm: - assert phy_settings.memtype == "DDR4" - # JESD82-31A page 38 - # - # B-side chips have certain usually-inconsequential address and BA - # bits inverted by the RCD to reduce SSO current. For mode register - # writes, however, we must compensate for this. BG[1] also directs - # writes either to the A side (BG[1]=0) or B side (BG[1]=1) - # - # The 'ba != 7' is because we don't do this to writes to the RCD - # itself. - if ba != 7: - invert_masks.append((0b10101111111000, 0b1111)) + with r.block("static inline void init_sequence(void)") as b: + for comment, a, ba, cmd, delay in init_sequence: + invert_masks = [(0, 0), ] + if phy_settings.is_rdimm: + assert phy_settings.memtype == "DDR4" + # JESD82-31A page 38 + # + # B-side chips have certain usually-inconsequential address and BA + # bits inverted by the RCD to reduce SSO current. For mode register + # writes, however, we must compensate for this. BG[1] also directs + # writes either to the A side (BG[1]=0) or B side (BG[1]=1) + # + # The 'ba != 7' is because we don't do this to writes to the RCD + # itself. + if ba != 7: + invert_masks.append((0b10101111111000, 0b1111)) - for a_inv, ba_inv in invert_masks: - r += "\t/* {0} */\n".format(comment) - r += "\tsdram_dfii_pi0_address_write({0:#x});\n".format(a ^ a_inv) - r += "\tsdram_dfii_pi0_baddress_write({0:d});\n".format(ba ^ ba_inv) - if cmd[:12] == "DFII_CONTROL": - r += "\tsdram_dfii_control_write({0});\n".format(cmd) - else: - r += "\tcommand_p0({0});\n".format(cmd) - if delay: - r += "\tcdelay({0:d});\n".format(delay) - r += "\n" - r += "}\n" + for a_inv, ba_inv in invert_masks: + b += f"/* {comment} */" + b += f"sdram_dfii_pi0_address_write({a ^ a_inv:#x});" + b += f"sdram_dfii_pi0_baddress_write({ba ^ ba_inv:d});" + if cmd.startswith("DFII_CONTROL"): + b += f"sdram_dfii_control_write({cmd});" + else: + b += f"command_p0({cmd});" + if delay: + b += f"cdelay({delay});\n" + b.newline() - r += "#endif\n" - - return r + return r.generate() # Python Header ------------------------------------------------------------------------------------ From 43036c9576b7ceb6f655502f959315caefdda371 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Boczar?= Date: Mon, 28 Jun 2021 15:37:42 +0200 Subject: [PATCH 5/7] test: update *_init.h reference --- test/reference/ddr3_init.h | 67 ++++++++++++++++++++------------------ test/reference/ddr4_init.h | 63 ++++++++++++++++++----------------- test/reference/sdr_init.h | 53 ++++++++++++++++-------------- 3 files changed, 96 insertions(+), 87 deletions(-) diff --git a/test/reference/ddr3_init.h b/test/reference/ddr3_init.h index 5ee2cdb..6850c6e 100644 --- a/test/reference/ddr3_init.h +++ b/test/reference/ddr3_init.h @@ -1,19 +1,20 @@ #ifndef __GENERATED_SDRAM_PHY_H #define __GENERATED_SDRAM_PHY_H + #include #include -#define DFII_CONTROL_SEL 0x01 -#define DFII_CONTROL_CKE 0x02 -#define DFII_CONTROL_ODT 0x04 -#define DFII_CONTROL_RESET_N 0x08 +#define DFII_CONTROL_SEL 0x01 +#define DFII_CONTROL_CKE 0x02 +#define DFII_CONTROL_ODT 0x04 +#define DFII_CONTROL_RESET_N 0x08 -#define DFII_COMMAND_CS 0x01 -#define DFII_COMMAND_WE 0x02 -#define DFII_COMMAND_CAS 0x04 -#define DFII_COMMAND_RAS 0x08 -#define DFII_COMMAND_WRDATA 0x10 -#define DFII_COMMAND_RDDATA 0x20 +#define DFII_COMMAND_CS 0x01 +#define DFII_COMMAND_WE 0x02 +#define DFII_COMMAND_CAS 0x04 +#define DFII_COMMAND_RAS 0x08 +#define DFII_COMMAND_WRDATA 0x10 +#define DFII_COMMAND_RDDATA 0x20 #define SDRAM_PHY_K7DDRPHY #define SDRAM_PHY_XDR 2 @@ -26,8 +27,8 @@ #define SDRAM_PHY_RDPHASE 1 #define SDRAM_PHY_WRPHASE 2 #define SDRAM_PHY_WRITE_LEVELING_CAPABLE -#define SDRAM_PHY_WRITE_DQ_DQS_TRAINING_CAPABLE #define SDRAM_PHY_WRITE_LATENCY_CALIBRATION_CAPABLE +#define SDRAM_PHY_WRITE_DQ_DQS_TRAINING_CAPABLE #define SDRAM_PHY_READ_LEVELING_CAPABLE #define SDRAM_PHY_MODULES (SDRAM_PHY_DATABITS/8) #define SDRAM_PHY_DELAYS 32 @@ -37,47 +38,48 @@ void cdelay(int i); __attribute__((unused)) static inline void command_p0(int cmd) { - sdram_dfii_pi0_command_write(cmd); - sdram_dfii_pi0_command_issue_write(1); + sdram_dfii_pi0_command_write(cmd); + sdram_dfii_pi0_command_issue_write(1); } __attribute__((unused)) static inline void command_p1(int cmd) { - sdram_dfii_pi1_command_write(cmd); - sdram_dfii_pi1_command_issue_write(1); + sdram_dfii_pi1_command_write(cmd); + sdram_dfii_pi1_command_issue_write(1); } __attribute__((unused)) static inline void command_p2(int cmd) { - sdram_dfii_pi2_command_write(cmd); - sdram_dfii_pi2_command_issue_write(1); + sdram_dfii_pi2_command_write(cmd); + sdram_dfii_pi2_command_issue_write(1); } __attribute__((unused)) static inline void command_p3(int cmd) { - sdram_dfii_pi3_command_write(cmd); - sdram_dfii_pi3_command_issue_write(1); + sdram_dfii_pi3_command_write(cmd); + sdram_dfii_pi3_command_issue_write(1); } #define DFII_PIX_DATA_SIZE CSR_SDRAM_DFII_PI0_WRDATA_SIZE -static inline unsigned long sdram_dfii_pix_wrdata_addr(int phase){ - switch (phase) { - case 0: return CSR_SDRAM_DFII_PI0_WRDATA_ADDR; +static inline unsigned long sdram_dfii_pix_wrdata_addr(int phase) +{ + switch (phase) { + case 0: return CSR_SDRAM_DFII_PI0_WRDATA_ADDR; case 1: return CSR_SDRAM_DFII_PI1_WRDATA_ADDR; case 2: return CSR_SDRAM_DFII_PI2_WRDATA_ADDR; case 3: return CSR_SDRAM_DFII_PI3_WRDATA_ADDR; - default: return 0; - } + default: return 0; + } } - -static inline unsigned long sdram_dfii_pix_rddata_addr(int phase){ - switch (phase) { - case 0: return CSR_SDRAM_DFII_PI0_RDDATA_ADDR; +static inline unsigned long sdram_dfii_pix_rddata_addr(int phase) +{ + switch (phase) { + case 0: return CSR_SDRAM_DFII_PI0_RDDATA_ADDR; case 1: return CSR_SDRAM_DFII_PI1_RDDATA_ADDR; case 2: return CSR_SDRAM_DFII_PI2_RDDATA_ADDR; case 3: return CSR_SDRAM_DFII_PI3_RDDATA_ADDR; - default: return 0; - } + default: return 0; + } } - + #define DDRX_MR_WRLVL_ADDRESS 1 #define DDRX_MR_WRLVL_RESET 6 #define DDRX_MR_WRLVL_BIT 7 @@ -124,4 +126,5 @@ static inline void init_sequence(void) cdelay(200); } -#endif + +#endif /* __GENERATED_SDRAM_PHY_H */ diff --git a/test/reference/ddr4_init.h b/test/reference/ddr4_init.h index 2f6a261..5074a10 100644 --- a/test/reference/ddr4_init.h +++ b/test/reference/ddr4_init.h @@ -1,19 +1,20 @@ #ifndef __GENERATED_SDRAM_PHY_H #define __GENERATED_SDRAM_PHY_H + #include #include -#define DFII_CONTROL_SEL 0x01 -#define DFII_CONTROL_CKE 0x02 -#define DFII_CONTROL_ODT 0x04 -#define DFII_CONTROL_RESET_N 0x08 +#define DFII_CONTROL_SEL 0x01 +#define DFII_CONTROL_CKE 0x02 +#define DFII_CONTROL_ODT 0x04 +#define DFII_CONTROL_RESET_N 0x08 -#define DFII_COMMAND_CS 0x01 -#define DFII_COMMAND_WE 0x02 -#define DFII_COMMAND_CAS 0x04 -#define DFII_COMMAND_RAS 0x08 -#define DFII_COMMAND_WRDATA 0x10 -#define DFII_COMMAND_RDDATA 0x20 +#define DFII_COMMAND_CS 0x01 +#define DFII_COMMAND_WE 0x02 +#define DFII_COMMAND_CAS 0x04 +#define DFII_COMMAND_RAS 0x08 +#define DFII_COMMAND_WRDATA 0x10 +#define DFII_COMMAND_RDDATA 0x20 #define SDRAM_PHY_USDDRPHY #define SDRAM_PHY_XDR 2 @@ -36,45 +37,46 @@ void cdelay(int i); __attribute__((unused)) static inline void command_p0(int cmd) { - sdram_dfii_pi0_command_write(cmd); - sdram_dfii_pi0_command_issue_write(1); + sdram_dfii_pi0_command_write(cmd); + sdram_dfii_pi0_command_issue_write(1); } __attribute__((unused)) static inline void command_p1(int cmd) { - sdram_dfii_pi1_command_write(cmd); - sdram_dfii_pi1_command_issue_write(1); + sdram_dfii_pi1_command_write(cmd); + sdram_dfii_pi1_command_issue_write(1); } __attribute__((unused)) static inline void command_p2(int cmd) { - sdram_dfii_pi2_command_write(cmd); - sdram_dfii_pi2_command_issue_write(1); + sdram_dfii_pi2_command_write(cmd); + sdram_dfii_pi2_command_issue_write(1); } __attribute__((unused)) static inline void command_p3(int cmd) { - sdram_dfii_pi3_command_write(cmd); - sdram_dfii_pi3_command_issue_write(1); + sdram_dfii_pi3_command_write(cmd); + sdram_dfii_pi3_command_issue_write(1); } #define DFII_PIX_DATA_SIZE CSR_SDRAM_DFII_PI0_WRDATA_SIZE -static inline unsigned long sdram_dfii_pix_wrdata_addr(int phase){ - switch (phase) { - case 0: return CSR_SDRAM_DFII_PI0_WRDATA_ADDR; +static inline unsigned long sdram_dfii_pix_wrdata_addr(int phase) +{ + switch (phase) { + case 0: return CSR_SDRAM_DFII_PI0_WRDATA_ADDR; case 1: return CSR_SDRAM_DFII_PI1_WRDATA_ADDR; case 2: return CSR_SDRAM_DFII_PI2_WRDATA_ADDR; case 3: return CSR_SDRAM_DFII_PI3_WRDATA_ADDR; - default: return 0; - } + default: return 0; + } } - -static inline unsigned long sdram_dfii_pix_rddata_addr(int phase){ - switch (phase) { - case 0: return CSR_SDRAM_DFII_PI0_RDDATA_ADDR; +static inline unsigned long sdram_dfii_pix_rddata_addr(int phase) +{ + switch (phase) { + case 0: return CSR_SDRAM_DFII_PI0_RDDATA_ADDR; case 1: return CSR_SDRAM_DFII_PI1_RDDATA_ADDR; case 2: return CSR_SDRAM_DFII_PI2_RDDATA_ADDR; case 3: return CSR_SDRAM_DFII_PI3_RDDATA_ADDR; - default: return 0; - } + default: return 0; + } } #define DDRX_MR_WRLVL_ADDRESS 1 @@ -138,4 +140,5 @@ static inline void init_sequence(void) cdelay(200); } -#endif + +#endif /* __GENERATED_SDRAM_PHY_H */ diff --git a/test/reference/sdr_init.h b/test/reference/sdr_init.h index 235f0ae..9054b25 100644 --- a/test/reference/sdr_init.h +++ b/test/reference/sdr_init.h @@ -1,19 +1,20 @@ #ifndef __GENERATED_SDRAM_PHY_H #define __GENERATED_SDRAM_PHY_H + #include #include -#define DFII_CONTROL_SEL 0x01 -#define DFII_CONTROL_CKE 0x02 -#define DFII_CONTROL_ODT 0x04 -#define DFII_CONTROL_RESET_N 0x08 +#define DFII_CONTROL_SEL 0x01 +#define DFII_CONTROL_CKE 0x02 +#define DFII_CONTROL_ODT 0x04 +#define DFII_CONTROL_RESET_N 0x08 -#define DFII_COMMAND_CS 0x01 -#define DFII_COMMAND_WE 0x02 -#define DFII_COMMAND_CAS 0x04 -#define DFII_COMMAND_RAS 0x08 -#define DFII_COMMAND_WRDATA 0x10 -#define DFII_COMMAND_RDDATA 0x20 +#define DFII_COMMAND_CS 0x01 +#define DFII_COMMAND_WE 0x02 +#define DFII_COMMAND_CAS 0x04 +#define DFII_COMMAND_RAS 0x08 +#define DFII_COMMAND_WRDATA 0x10 +#define DFII_COMMAND_RDDATA 0x20 #define SDRAM_PHY_GENSDRPHY #define SDRAM_PHY_XDR 1 @@ -30,26 +31,27 @@ void cdelay(int i); __attribute__((unused)) static inline void command_p0(int cmd) { - sdram_dfii_pi0_command_write(cmd); - sdram_dfii_pi0_command_issue_write(1); + sdram_dfii_pi0_command_write(cmd); + sdram_dfii_pi0_command_issue_write(1); } #define DFII_PIX_DATA_SIZE CSR_SDRAM_DFII_PI0_WRDATA_SIZE -static inline unsigned long sdram_dfii_pix_wrdata_addr(int phase){ - switch (phase) { - case 0: return CSR_SDRAM_DFII_PI0_WRDATA_ADDR; - default: return 0; - } +static inline unsigned long sdram_dfii_pix_wrdata_addr(int phase) +{ + switch (phase) { + case 0: return CSR_SDRAM_DFII_PI0_WRDATA_ADDR; + default: return 0; + } } - -static inline unsigned long sdram_dfii_pix_rddata_addr(int phase){ - switch (phase) { - case 0: return CSR_SDRAM_DFII_PI0_RDDATA_ADDR; - default: return 0; - } +static inline unsigned long sdram_dfii_pix_rddata_addr(int phase) +{ + switch (phase) { + case 0: return CSR_SDRAM_DFII_PI0_RDDATA_ADDR; + default: return 0; + } } - + static inline void init_sequence(void) { /* Bring CKE high */ @@ -93,4 +95,5 @@ static inline void init_sequence(void) cdelay(200); } -#endif + +#endif /* __GENERATED_SDRAM_PHY_H */ From 46ea84470288db32bc21ef7452c15a3f54052329 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Boczar?= Date: Wed, 4 Aug 2021 12:01:41 +0200 Subject: [PATCH 6/7] phy: update PHYs to set capabilities, delays/bitslips in PhySettings --- litedram/common.py | 29 ++++++++++++++--- litedram/init.py | 58 +++------------------------------- litedram/phy/ecp5ddrphy.py | 5 ++- litedram/phy/lpddr4/basephy.py | 1 + litedram/phy/lpddr4/s7phy.py | 6 ++++ litedram/phy/lpddr4/simphy.py | 16 +++++++++- litedram/phy/lpddr4/simsoc.py | 4 --- litedram/phy/s7ddrphy.py | 34 ++++++++++++-------- litedram/phy/usddrphy.py | 33 +++++++++++-------- 9 files changed, 93 insertions(+), 93 deletions(-) diff --git a/litedram/common.py b/litedram/common.py index 88ba2fb..3546d64 100644 --- a/litedram/common.py +++ b/litedram/common.py @@ -11,6 +11,7 @@ import math from functools import reduce from operator import add from collections import OrderedDict +from typing import Union, Optional from migen import * @@ -203,11 +204,29 @@ class Settings: class PhySettings(Settings): - def __init__(self, phytype, memtype, databits, dfi_databits, - nphases, - rdphase, wrphase, - cl, read_latency, write_latency, nranks=1, cwl=None, - cmd_latency=None, cmd_delay=None): + def __init__(self, + phytype: str, + memtype: str, # SDR, DDR, DDR2, ... + databits: int, # number of DQ lines + dfi_databits: int, # per-phase DFI data width + nphases: int, # number of DFI phases + rdphase: Union[int, Signal], # phase on which READ command will be issued by MC + wrphase: Union[int, Signal], # phase on which WRITE command will be issued by MC + cl: int, # latency (DRAM clk) from READ command to first data + read_latency: int, # latency (MC clk) from DFI.rddata_en to DFI.rddata_valid + write_latency: int, # latency (MC clk) from DFI.wrdata_en to DFI.wrdata + nranks: int = 1, # number of DRAM ranks + cwl: Optional[int] = None, # latency (DRAM clk) from WRITE command to first data + cmd_latency: Optional[int] = None, # additional command latency (MC clk) + cmd_delay: Optional[int] = None, # used to force cmd delay during initialization in BIOS + bitslips: int = 0, # number of write/read bitslip taps + delays: int = 0, # number of write/read delay taps + # PHY training capabilities + write_leveling: bool = False, + write_dq_dqs_training: bool = False, + write_latency_calibration: bool = False, + read_leveling: bool = False, + ): self.set_attributes(locals()) self.cwl = cl if cwl is None else cwl self.is_rdimm = False diff --git a/litedram/init.py b/litedram/init.py index f8381db..f45903d 100644 --- a/litedram/init.py +++ b/litedram/init.py @@ -747,45 +747,6 @@ def get_sdram_phy_c_header(phy_settings, timing_settings): if isinstance(wrphase, Signal): wrphase = wrphase.reset.value r.define("SDRAM_PHY_WRPHASE", wrphase) - phy_settings.write_leveling = False - phy_settings.write_dq_dqs_training = False - phy_settings.write_latency_calibration = False - phy_settings.read_leveling = False - if phytype in ["USDDRPHY", "USPDDRPHY", - "K7DDRPHY", "V7DDRPHY", - "K7LPDDR4PHY", "V7LPDDR4PHY"]: - phy_settings.write_leveling = True - if phytype in ["K7DDRPHY", "V7DDRPHY", - "K7LPDDR4PHY", "V7LPDDR4PHY"]: - phy_settings.write_dq_dqs_training = True - if phytype in ["USDDRPHY", "USPDDRPHY", - "A7DDRPHY", "K7DDRPHY", "V7DDRPHY", - "A7LPDDR4PHY", "K7LPDDR4PHY", "V7LPDDR4PHY"]: - phy_settings.write_latency_calibration = True - phy_settings.read_leveling = True - if phytype in ["ECP5DDRPHY"]: - phy_settings.read_leveling = True - if phytype in ["LPDDR4SIMPHY"]: - phy_settings.read_leveling = True - - phy_settings.delays = None - phy_settings.bitslips = None - if phytype in ["USDDRPHY", "USPDDRPHY"]: - phy_settings.delays = 512 - phy_settings.bitslips = 8 - elif phytype in ["A7DDRPHY", "K7DDRPHY", "V7DDRPHY"]: - phy_settings.delays = 32 - phy_settings.bitslips = 8 - elif phytype in ["A7LPDDR4PHY", "K7LPDDR4PHY", "V7LPDDR4PHY"]: - phy_settings.delays = 32 - phy_settings.bitslips = 16 - elif phytype in ["ECP5DDRPHY"]: - phy_settings.delays = 8 - phy_settings.bitslips = 4 - elif phytype in ["LPDDR4SIMPHY"]: - phy_settings.delays = 1 - phy_settings.bitslips = 16 - # Define Read/Write Leveling capability if phy_settings.write_leveling: r.define("SDRAM_PHY_WRITE_LEVELING_CAPABLE") @@ -798,21 +759,10 @@ def get_sdram_phy_c_header(phy_settings, timing_settings): # Define number of modules/delays/bitslips r.define("SDRAM_PHY_MODULES", "(SDRAM_PHY_DATABITS/8)") - if phytype in ["USDDRPHY", "USPDDRPHY"]: - r.define("SDRAM_PHY_DELAYS", 512) - r.define("SDRAM_PHY_BITSLIPS", 8) - elif phytype in ["A7DDRPHY", "K7DDRPHY", "V7DDRPHY"]: - r.define("SDRAM_PHY_DELAYS", 32) - r.define("SDRAM_PHY_BITSLIPS", 8) - elif phytype in ["A7LPDDR4PHY", "K7LPDDR4PHY", "V7LPDDR4PHY"]: - r.define("SDRAM_PHY_DELAYS", 32) - r.define("SDRAM_PHY_BITSLIPS", 16) - elif phytype in ["ECP5DDRPHY"]: - r.define("SDRAM_PHY_DELAYS", 8) - r.define("SDRAM_PHY_BITSLIPS", 4) - elif phytype in ["LPDDR4SIMPHY"]: - r.define("SDRAM_PHY_DELAYS", 1) - r.define("SDRAM_PHY_BITSLIPS", 16) + if phy_settings.delays > 0: + r.define("SDRAM_PHY_DELAYS", phy_settings.delays) + if phy_settings.bitslips > 0: + r.define("SDRAM_PHY_BITSLIPS", phy_settings.bitslips) if phy_settings.is_rdimm: assert phy_settings.memtype == "DDR4" diff --git a/litedram/phy/ecp5ddrphy.py b/litedram/phy/ecp5ddrphy.py index d277e38..4f1010e 100644 --- a/litedram/phy/ecp5ddrphy.py +++ b/litedram/phy/ecp5ddrphy.py @@ -167,7 +167,10 @@ class ECP5DDRPHY(Module, AutoCSR): cl = cl, cwl = cwl, read_latency = cl_sys_latency + 10, - write_latency = cwl_sys_latency + write_latency = cwl_sys_latency, + read_leveling = True, + bitslips = 4, + delays = 8, ) # DFI Interface ---------------------------------------------------------------------------- diff --git a/litedram/phy/lpddr4/basephy.py b/litedram/phy/lpddr4/basephy.py index 1940071..c968676 100644 --- a/litedram/phy/lpddr4/basephy.py +++ b/litedram/phy/lpddr4/basephy.py @@ -181,6 +181,7 @@ class LPDDR4PHY(Module, AutoCSR): write_latency = write_latency, cmd_latency = cmd_latency, cmd_delay = cmd_delay, + bitslips = 16, ) # DFI Interface ---------------------------------------------------------------------------- diff --git a/litedram/phy/lpddr4/s7phy.py b/litedram/phy/lpddr4/s7phy.py index 4baa1db..43be1f0 100644 --- a/litedram/phy/lpddr4/s7phy.py +++ b/litedram/phy/lpddr4/s7phy.py @@ -30,6 +30,12 @@ class S7LPDDR4PHY(DoubleRateLPDDR4PHY): **kwargs ) + self.settings.delays = 32 + self.settings.write_leveling = True + self.settings.write_latency_calibration = True + self.settings.write_dq_dqs_training = True + self.settings.read_level = True + # Parameters ------------------------------------------------------------------------------- # Calculate value of taps needed to shift a signal by 90 degrees. # Using iodelay_clk_freq of 300MHz/400MHz is only valid for -3 and -2/2E speed grades. diff --git a/litedram/phy/lpddr4/simphy.py b/litedram/phy/lpddr4/simphy.py index 36107dd..d059007 100644 --- a/litedram/phy/lpddr4/simphy.py +++ b/litedram/phy/lpddr4/simphy.py @@ -6,6 +6,8 @@ from migen import * +from litex.soc.interconnect.csr import CSR + from litedram.phy.utils import delayed, Serializer, Deserializer, Latency from litedram.phy.sim_utils import SimPad, SimulationPads, SimSerDesMixin from litedram.phy.lpddr4.basephy import LPDDR4PHY, DoubleRateLPDDR4PHY @@ -40,6 +42,12 @@ class LPDDR4SimPHY(SimSerDesMixin, LPDDR4PHY): phytype = "LPDDR4SimPHY", **kwargs) + # fake delays (make no nsense in simulation, but sdram.c expects them) + self.settings.read_leveling = True + self.settings.delays = 1 + self._rdly_dq_rst = CSR() + self._rdly_dq_inc = CSR() + delay = lambda sig, cycles: delayed(self, sig, cycles=cycles) sdr = dict(clkdiv="sys", clk="sys8x") sdr_90 = dict(clkdiv="sys", clk="sys8x_90") @@ -97,8 +105,14 @@ class DoubleRateLPDDR4SimPHY(SimSerDesMixin, DoubleRateLPDDR4PHY): des_latency = Latency(sys2x=Deserializer.LATENCY), phytype = "LPDDR4SimPHY", **kwargs) - self.submodules.half_delay = ClockDomainsRenamer("sys2x")(Module()) + + # fake delays (make no nsense in simulation, but sdram.c expects them) + self.settings.read_leveling = True + self.settings.delays = 1 + self._rdly_dq_rst = CSR() + self._rdly_dq_inc = CSR() + delay = lambda sig, cycles: delayed(self.half_delay, sig, cycles=cycles) sdr = dict(clkdiv="sys2x", clk="sys8x") diff --git a/litedram/phy/lpddr4/simsoc.py b/litedram/phy/lpddr4/simsoc.py index 4024a1a..d500c17 100644 --- a/litedram/phy/lpddr4/simsoc.py +++ b/litedram/phy/lpddr4/simsoc.py @@ -95,10 +95,6 @@ class SimSoC(SoCCore): aligned_reset_zero = True, masked_write = masked_write, ) - # fake delays (make no nsense in simulation, but sdram.c expects them) - self.ddrphy._rdly_dq_rst = CSR() - self.ddrphy._rdly_dq_inc = CSR() - self.add_csr("ddrphy") for p in ["clk", "cke", "odt", "reset_n", "cs", "ca", "dq", "dqs", "dmi"]: self.comb += getattr(pads, p).eq(getattr(self.ddrphy.pads, p)) diff --git a/litedram/phy/s7ddrphy.py b/litedram/phy/s7ddrphy.py index 3f1c27d..f072b63 100644 --- a/litedram/phy/s7ddrphy.py +++ b/litedram/phy/s7ddrphy.py @@ -93,20 +93,26 @@ class S7DDRPHY(Module, AutoCSR): # PHY settings ----------------------------------------------------------------------------- self.settings = PhySettings( - phytype = phytype, - memtype = memtype, - databits = databits, - dfi_databits = 2*databits, - nranks = nranks, - nphases = nphases, - rdphase = self._rdphase.storage, - wrphase = self._wrphase.storage, - cl = cl, - cwl = cwl, - read_latency = cl_sys_latency + 6, - write_latency = cwl_sys_latency - 1, - cmd_latency = cmd_latency, - cmd_delay = cmd_delay, + phytype = phytype, + memtype = memtype, + databits = databits, + dfi_databits = 2*databits, + nranks = nranks, + nphases = nphases, + rdphase = self._rdphase.storage, + wrphase = self._wrphase.storage, + cl = cl, + cwl = cwl, + read_latency = cl_sys_latency + 6, + write_latency = cwl_sys_latency - 1, + cmd_latency = cmd_latency, + cmd_delay = cmd_delay, + write_leveling = with_odelay, + write_dq_dqs_training = with_odelay, + write_latency_calibration = True, + read_leveling = True, + delays = 32, + bitslips = 8, ) # DFI Interface ---------------------------------------------------------------------------- diff --git a/litedram/phy/usddrphy.py b/litedram/phy/usddrphy.py index 312d6c8..78a1a62 100644 --- a/litedram/phy/usddrphy.py +++ b/litedram/phy/usddrphy.py @@ -93,20 +93,25 @@ class USDDRPHY(Module, AutoCSR): # PHY settings ----------------------------------------------------------------------------- self.settings = PhySettings( - phytype = phytype, - memtype = memtype, - databits = databits, - dfi_databits = 2*databits, - nranks = nranks, - nphases = nphases, - rdphase = self._rdphase.storage, - wrphase = self._wrphase.storage, - cl = cl, - cwl = cwl, - read_latency = cl_sys_latency + 5, - write_latency = cwl_sys_latency - 1, - cmd_latency = cmd_latency, - cmd_delay = cmd_delay, + phytype = phytype, + memtype = memtype, + databits = databits, + dfi_databits = 2*databits, + nranks = nranks, + nphases = nphases, + rdphase = self._rdphase.storage, + wrphase = self._wrphase.storage, + cl = cl, + cwl = cwl, + read_latency = cl_sys_latency + 5, + write_latency = cwl_sys_latency - 1, + cmd_latency = cmd_latency, + cmd_delay = cmd_delay, + write_leveling = True, + write_latency_calibration = True, + read_leveling = True, + delays = 512, + bitslips = 8, ) if is_rdimm: From 86cde919874f55141864b96cc2ad131355ddfd2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Boczar?= Date: Thu, 12 Aug 2021 12:14:51 +0200 Subject: [PATCH 7/7] phy: fix typo (read_level -> read_leveling) --- litedram/phy/lpddr4/s7phy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/litedram/phy/lpddr4/s7phy.py b/litedram/phy/lpddr4/s7phy.py index 43be1f0..93e3c59 100644 --- a/litedram/phy/lpddr4/s7phy.py +++ b/litedram/phy/lpddr4/s7phy.py @@ -34,7 +34,7 @@ class S7LPDDR4PHY(DoubleRateLPDDR4PHY): self.settings.write_leveling = True self.settings.write_latency_calibration = True self.settings.write_dq_dqs_training = True - self.settings.read_level = True + self.settings.read_leveling = True # Parameters ------------------------------------------------------------------------------- # Calculate value of taps needed to shift a signal by 90 degrees.