Skip to content

Commit

Permalink
Merge pull request #189 from daveshah1/ddr4_rdimm_init
Browse files Browse the repository at this point in the history
Add support for DDR4 RDIMMs
  • Loading branch information
enjoy-digital committed May 15, 2020
2 parents 7ae4ad5 + 70054ba commit b2a5685
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 11 deletions.
6 changes: 6 additions & 0 deletions litedram/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ def __init__(self, phytype, memtype, databits, dfi_databits,
cl, read_latency, write_latency, nranks=1, cwl=None):
self.set_attributes(locals())
self.cwl = cl if cwl is None else cwl
self.is_rdimm = False

# Optional DDR3/DDR4 electrical settings:
# rtt_nom: Non-Writes on-die termination impedance
Expand All @@ -182,6 +183,11 @@ def add_electrical_settings(self, rtt_nom, rtt_wr, ron):
assert self.memtype in ["DDR3", "DDR4"]
self.set_attributes(locals())

# Optional RDIMM configuration
def set_rdimm(self, tck, rcd_pll_bypass, rcd_ca_cs_drive, rcd_odt_cke_drive, rcd_clk_drive):
assert self.memtype == "DDR4"
self.is_rdimm = True
self.set_attributes(locals())

class GeomSettings(Settings):
def __init__(self, bankbits, rowbits, colbits):
Expand Down
93 changes: 83 additions & 10 deletions litedram/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -364,9 +364,62 @@ def format_mr6(tccd):
mr5 = 0
mr6 = format_mr6(4) # FIXME: tCCD

rdimm_init = []
if phy_settings.is_rdimm:
def get_coarse_speed(tck, pll_bypass):
# JESD82-31A page 78
f_to_coarse_speed = {
1600e6: 0,
1866e6: 1,
2133e6: 2,
2400e6: 3,
2666e6: 4,
2933e6: 5,
3200e6: 6,
}
if pll_bypass:
return 7
else:
for f, speed in f_to_coarse_speed.items():
if tck >= 2/f:
return speed
raise ValueError
def get_fine_speed(tck):
# JESD82-31A page 83
freq = 2/tck
fine_speed = (freq - 1240e6) // 20e6
fine_speed = max(fine_speed, 0)
fine_speed = min(fine_speed, 0b1100001)
return fine_speed

coarse_speed = get_coarse_speed(phy_settings.tck, phy_settings.rcd_pll_bypass)
fine_speed = get_fine_speed(phy_settings.tck)

rcd_reset = 0x060 | 0x0 # F0RC06: command space control; 0: reset RCD

f0rc0f = 0x0F0 | 0x4 # F0RC05: 0 nCK latency adder

f0rc03 = 0x030 | phy_settings.rcd_ca_cs_drive # F0RC03: CA/CS drive strength
f0rc04 = 0x040 | phy_settings.rcd_odt_cke_drive # F0RC04: ODT/CKE drive strength
f0rc05 = 0x050 | phy_settings.rcd_clk_drive # F0RC04: ODT/CKE drive strength

f0rc0a = 0x0A0 | coarse_speed # F0RC0A: coarse speed selection and PLL bypass
f0rc3x = 0x300 | fine_speed # F0RC3x: fine speed selection

rdimm_init = [
("Reset RCD", rcd_reset, 7, cmds["MODE_REGISTER"], 50000),
("Load RCD F0RC0F", f0rc0f, 7, cmds["MODE_REGISTER"], 100),
("Load RCD F0RC03", f0rc03, 7, cmds["MODE_REGISTER"], 100),
("Load RCD F0RC04", f0rc04, 7, cmds["MODE_REGISTER"], 100),
("Load RCD F0RC05", f0rc05, 7, cmds["MODE_REGISTER"], 100),
("Load RCD F0RC0A", f0rc0a, 7, cmds["MODE_REGISTER"], 100),
("Load RCD F0RC3X", f0rc3x, 7, cmds["MODE_REGISTER"], 100),
]

init_sequence = [
("Release reset", 0x0000, 0, cmds["UNRESET"], 50000),
("Bring CKE high", 0x0000, 0, cmds["CKE"], 10000),
] + rdimm_init + [
("Load Mode Register 3", mr3, 3, cmds["MODE_REGISTER"], 0),
("Load Mode Register 6", mr6, 6, cmds["MODE_REGISTER"], 0),
("Load Mode Register 5", mr5, 5, cmds["MODE_REGISTER"], 0),
Expand Down Expand Up @@ -426,6 +479,10 @@ def get_sdram_phy_c_header(phy_settings, timing_settings):
r += "#define SDRAM_PHY_DELAYS 8\n"
r += "#define SDRAM_PHY_BITSLIPS 4\n"

if phy_settings.is_rdimm:
assert phy_settings.memtype == "DDR4"
r += "#define SDRAM_PHY_DDR4_RDIMM\n"

r += "\n"

r += "static void cdelay(int i);\n"
Expand Down Expand Up @@ -482,16 +539,32 @@ def get_sdram_phy_c_header(phy_settings, timing_settings):

r += "static void init_sequence(void)\n{\n"
for comment, a, ba, cmd, delay in init_sequence:
r += "\t/* {0} */\n".format(comment)
r += "\tsdram_dfii_pi0_address_write({0:#x});\n".format(a)
r += "\tsdram_dfii_pi0_baddress_write({0:d});\n".format(ba)
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"
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"

r += "#endif\n"
Expand Down
13 changes: 12 additions & 1 deletion litedram/phy/usddrphy.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ def __init__(self, pads,
memtype = "DDR3",
sys_clk_freq = 100e6,
iodelay_clk_freq = 200e6,
cmd_latency = 0):
cmd_latency = 0,
is_rdimm = False):
phytype = self.__class__.__name__
device = {"USDDRPHY": "ULTRASCALE", "USPDDRPHY": "ULTRASCALE_PLUS"}[phytype]
pads = PHYPadsCombiner(pads)
Expand Down Expand Up @@ -90,6 +91,16 @@ def __init__(self, pads,
write_latency = cwl_sys_latency
)

if is_rdimm:
# All drive settings for an 8-chip load
self.settings.set_rdimm(
tck = tck,
rcd_pll_bypass = False,
rcd_ca_cs_drive = 0x5,
rcd_odt_cke_drive = 0x5,
rcd_clk_drive = 0x5
)

# DFI Interface ----------------------------------------------------------------------------
self.dfi = dfi = Interface(addressbits, bankbits, nranks, 2*databits, nphases)
if memtype == "DDR4":
Expand Down

0 comments on commit b2a5685

Please sign in to comment.