From 2f5784432d2bd42686c91ea148fcb7849317cf5d Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Fri, 29 Jan 2021 09:21:48 +0100 Subject: [PATCH] phys: improve handling of required/optional command pads and make cke/odt optional on all phys. --- litedram/phy/ecp5ddrphy.py | 27 ++++++++++++++++----------- litedram/phy/gensdrphy.py | 24 +++++++++++++++--------- litedram/phy/s7ddrphy.py | 27 ++++++++++++++++----------- litedram/phy/usddrphy.py | 29 +++++++++++++++++------------ 4 files changed, 64 insertions(+), 43 deletions(-) diff --git a/litedram/phy/ecp5ddrphy.py b/litedram/phy/ecp5ddrphy.py index 72e86d4..d277e38 100644 --- a/litedram/phy/ecp5ddrphy.py +++ b/litedram/phy/ecp5ddrphy.py @@ -200,18 +200,23 @@ class ECP5DDRPHY(Module, AutoCSR): # Commands ----------------------------------------------------------------------------- commands = { - "a" : "address", - "ba" : "bank" , - "ras_n": "ras_n" , - "cas_n": "cas_n" , - "we_n" : "we_n" , - "cke" : "cke" , - "odt" : "odt" , + # Pad name: (DFI name, Pad type (required or optional)) + "reset_n" : ("reset_n", "optional"), + "cs_n" : ("cs_n", "optional"), + "a" : ("address", "required"), + "ba" : ("bank" , "required"), + "ras_n" : ("ras_n" , "required"), + "cas_n" : ("cas_n" , "required"), + "we_n" : ("we_n" , "required"), + "cke" : ("cke" , "optional"), + "odt" : ("odt" , "optional"), } - if hasattr(pads, "reset_n"): commands.update({"reset_n" : "reset_n"}) - if hasattr(pads, "cs_n") : commands.update({"cs_n" : "cs_n"}) - for pad_name, dfi_name in commands.items(): - pad = getattr(pads, pad_name) + for pad_name, (dfi_name, pad_type) in commands.items(): + pad = getattr(pads, pad_name, None) + if (pad is None): + if (pad_type == "required"): + raise ValueError(f"DRAM pad {pad_name} required but not found in pads.") + continue for i in range(len(pad)): pad_oddrx2f = Signal() self.specials += Instance("ODDRX2F", diff --git a/litedram/phy/gensdrphy.py b/litedram/phy/gensdrphy.py index 066b482..4cbd407 100644 --- a/litedram/phy/gensdrphy.py +++ b/litedram/phy/gensdrphy.py @@ -52,18 +52,24 @@ class GENSDRPHY(Module): for pads_group in range(len(pads.groups)): pads.sel_group(pads_group) + # Commands ----------------------------------------------------------------------------- commands = { - "a" : "address", - "ba" : "bank" , - "ras_n": "ras_n" , - "cas_n": "cas_n" , - "we_n" : "we_n" , + # Pad name: (DFI name, Pad type (required or optional)) + "cs_n" : ("cs_n", "optional"), + "a" : ("address", "required"), + "ba" : ("bank" , "required"), + "ras_n" : ("ras_n" , "required"), + "cas_n" : ("cas_n" , "required"), + "we_n" : ("we_n" , "required"), + "cke" : ("cke" , "optional"), } - if hasattr(pads, "cke") : commands.update({"cke" : "cke"}) - if hasattr(pads, "cs_n"): commands.update({"cs_n" : "cs_n"}) - for pad_name, dfi_name in commands.items(): - pad = getattr(pads, pad_name) + for pad_name, (dfi_name, pad_type) in commands.items(): + pad = getattr(pads, pad_name, None) + if (pad is None): + if (pad_type == "required"): + raise ValueError(f"DRAM pad {pad_name} required but not found in pads.") + continue for i in range(len(pad)): self.specials += SDROutput(i=getattr(dfi.p0, dfi_name)[i], o=pad[i]) diff --git a/litedram/phy/s7ddrphy.py b/litedram/phy/s7ddrphy.py index cc39c86..2665845 100644 --- a/litedram/phy/s7ddrphy.py +++ b/litedram/phy/s7ddrphy.py @@ -162,18 +162,23 @@ class S7DDRPHY(Module, AutoCSR): # Commands ----------------------------------------------------------------------------- commands = { - "a" : "address", - "ba" : "bank" , - "ras_n": "ras_n" , - "cas_n": "cas_n" , - "we_n" : "we_n" , - "cke" : "cke" , - "odt" : "odt" , + # Pad name: (DFI name, Pad type (required or optional)) + "reset_n" : ("reset_n", "optional"), + "cs_n" : ("cs_n", "optional"), + "a" : ("address", "required"), + "ba" : ("bank" , "required"), + "ras_n" : ("ras_n" , "required"), + "cas_n" : ("cas_n" , "required"), + "we_n" : ("we_n" , "required"), + "cke" : ("cke" , "optional"), + "odt" : ("odt" , "optional"), } - if hasattr(pads, "reset_n"): commands.update({"reset_n" : "reset_n"}) - if hasattr(pads, "cs_n") : commands.update({"cs_n" : "cs_n"}) - for pad_name, dfi_name in commands.items(): - pad = getattr(pads, pad_name) + for pad_name, (dfi_name, pad_type) in commands.items(): + pad = getattr(pads, pad_name, None) + if (pad is None): + if (pad_type == "required"): + raise ValueError(f"DRAM pad {pad_name} required but not found in pads.") + continue for i in range(len(pad)): oq = Signal() self.specials += Instance("OSERDESE2", diff --git a/litedram/phy/usddrphy.py b/litedram/phy/usddrphy.py index 2bd032b..0644b4c 100644 --- a/litedram/phy/usddrphy.py +++ b/litedram/phy/usddrphy.py @@ -186,19 +186,24 @@ class USDDRPHY(Module, AutoCSR): # Commands ----------------------------------------------------------------------------- pads_ba = Signal(bankbits) commands = { - "a" : "address", - pads_ba : "bank", - "ras_n" : "ras_n" , - "cas_n" : "cas_n" , - "we_n" : "we_n" , - "cke" : "cke" , - "odt" : "odt" , + # Pad name: (DFI name, Pad type (required or optional)) + "reset_n" : ("reset_n", "optional"), + "cs_n" : ("cs_n", "optional"), + "a" : ("address", "required"), + pads_ba : ("bank" , "required"), + "ras_n" : ("ras_n" , "required"), + "cas_n" : ("cas_n" , "required"), + "we_n" : ("we_n" , "required"), + "cke" : ("cke" , "optional"), + "odt" : ("odt" , "optional"), + "act_n" : ("act_n", "optional"), } - if hasattr(pads, "reset_n"): commands.update({"reset_n" : "reset_n"}) - if hasattr(pads, "cs_n") : commands.update({"cs_n" : "cs_n"}) - if hasattr(pads, "act_n") : commands.update({"act_n" : "act_n"}) - for pad_name, dfi_name in commands.items(): - pad = pad_name if isinstance(pad_name, Signal) else getattr(pads, pad_name) + for pad_name, (dfi_name, pad_type) in commands.items(): + pad = pad_name if isinstance(pad_name, Signal) else getattr(pads, pad_name, None) + if (pad is None): + if (pad_type == "required"): + raise ValueError(f"DRAM pad {pad_name} required but not found in pads.") + continue for i in range(len(pad)): o_nodelay = Signal() self.specials += [