Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/misoc
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 64f136893836
Choose a base ref
...
head repository: m-labs/misoc
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: c03ef526ebec
Choose a head ref
  • 2 commits
  • 2 files changed
  • 1 contributor

Commits on Aug 4, 2015

  1. sdram/phy/initsequence: add burst chop 4 (BC4) for DDR3

    This is needed for half rate controllers with burst length of 4.
    For best efficiency quarter rate controllers should be used.
    enjoy-digital committed Aug 4, 2015
    Copy the full SHA
    52fba05 View commit details
  2. Copy the full SHA
    c03ef52 View commit details
Showing with 59 additions and 32 deletions.
  1. +8 −5 misoclib/mem/sdram/phy/initsequence.py
  2. +51 −27 misoclib/mem/sdram/phy/s6ddrphy.py
13 changes: 8 additions & 5 deletions misoclib/mem/sdram/phy/initsequence.py
Original file line number Diff line number Diff line change
@@ -142,10 +142,12 @@ def get_sdram_phy_header(sdram_phy_settings):
]
elif sdram_phy_settings.memtype == "DDR3":
bl = 2*sdram_phy_settings.nphases
if bl != 8:
raise NotImplementedError("DDR3 PHY header generator only supports BL of 8")

def format_mr0(cl, wr, dll_reset):
def format_mr0(bl, cl, wr, dll_reset):
bl_to_mr0 = {
4: 0b10,
8: 0b00
}
cl_to_mr0 = {
5: 0b0010,
6: 0b0100,
@@ -168,7 +170,8 @@ def format_mr0(cl, wr, dll_reset):
12: 0b110,
14: 0b111
}
mr0 = (cl_to_mr0[cl] & 1) << 2
mr0 = bl_to_mr0[bl]
mr0 |= (cl_to_mr0[cl] & 1) << 2
mr0 |= ((cl_to_mr0[cl] >> 1) & 0b111) << 4
mr0 |= dll_reset << 8
mr0 |= wr_to_mr0[wr] << 9
@@ -187,7 +190,7 @@ def format_mr2(cwl, rtt_wr):
mr2 |= rtt_wr << 9
return mr2

mr0 = format_mr0(cl, 8, 1) # wr=8 FIXME: this should be ceiling(tWR/tCK)
mr0 = format_mr0(bl, cl, 8, 1) # wr=8 FIXME: this should be ceiling(tWR/tCK)
mr1 = format_mr1(1, 1) # Output Drive Strength RZQ/7 (34 ohm) / Rtt RZQ/4 (60 ohm)
mr2 = format_mr2(sdram_phy_settings.cwl, 2) # Rtt(WR) RZQ/4
mr3 = 0
78 changes: 51 additions & 27 deletions misoclib/mem/sdram/phy/s6ddrphy.py
Original file line number Diff line number Diff line change
@@ -9,7 +9,9 @@
# 5 cycles later, along with the assertion
# of dfi_rddata_valid.
#
# This PHY only supports CAS Latency 3.
# This PHY only supports CAS latency 3 for DDR, LPDDR, DDR2
# and CAS latency 5/CAS write latency 6 for DDR3.
#
# Read commands must be sent on phase 0.
# Write commands must be sent on phase 1.
#
@@ -23,25 +25,41 @@

class S6DDRPHY(Module):
def __init__(self, pads, module, rd_bitslip, wr_bitslip, dqs_ddr_alignment):
if module.memtype not in ["DDR", "LPDDR", "DDR2"]:
raise NotImplementedError("S6DDRPHY only supports DDR, LPDDR and DDR2")
if module.memtype not in ["DDR", "LPDDR", "DDR2", "DDR3"]:
raise NotImplementedError("S6DDRPHY only supports DDR, LPDDR, DDR2 and DDR3")
addressbits = flen(pads.a)
bankbits = flen(pads.ba)
databits = flen(pads.dq)
nphases = 2

self.settings = sdram.PhySettings(
memtype=module.memtype,
dfi_databits=2*databits,
nphases=nphases,
rdphase=0,
wrphase=1,
rdcmdphase=1,
wrcmdphase=0,
cl=3,
read_latency=5,
write_latency=0
)
if module.memtype == "DDR3":
self.settings = sdram.PhySettings(
memtype="DDR3",
dfi_databits=2*databits,
nphases=nphases,
rdphase=0,
wrphase=1,
rdcmdphase=1,
wrcmdphase=0,
cl=5,
cwl=6,
read_latency=6,
write_latency=2
)
else:
self.settings = sdram.PhySettings(
memtype=module.memtype,
dfi_databits=2*databits,
nphases=nphases,
rdphase=0,
wrphase=1,
rdcmdphase=1,
wrcmdphase=0,
cl=3,
read_latency=5,
write_latency=0
)

self.module = module

self.dfi = Interface(addressbits, bankbits, 2*databits, nphases)
@@ -88,6 +106,8 @@ def __init__(self, pads, module, rd_bitslip, wr_bitslip, dqs_ddr_alignment):
r_dfi = Array(Record(phase_cmd_description(addressbits, bankbits)) for i in range(nphases))
for n, phase in enumerate(self.dfi.phases):
sd_sdram_half += [
r_dfi[n].reset_n.eq(phase.reset_n),
r_dfi[n].odt.eq(phase.odt),
r_dfi[n].address.eq(phase.address),
r_dfi[n].bank.eq(phase.bank),
r_dfi[n].cs_n.eq(phase.cs_n),
@@ -106,8 +126,10 @@ def __init__(self, pads, module, rd_bitslip, wr_bitslip, dqs_ddr_alignment):
pads.cas_n.eq(r_dfi[phase_sel].cas_n),
pads.we_n.eq(r_dfi[phase_sel].we_n)
]
if hasattr(pads, "cs_n"):
sd_sdram_half += pads.cs_n.eq(r_dfi[phase_sel].cs_n)
# optional pads
for name in "reset_n", "cs_n", "odt":
if hasattr(pads, name):
sd_sdram_half += getattr(pads, name).eq(getattr(r_dfi[phase_sel], name))

#
# Bitslip
@@ -332,25 +354,27 @@ def __init__(self, pads, module, rd_bitslip, wr_bitslip, dqs_ddr_alignment):
i_SHIFTIN4=0,
)

#
# ODT
#
# ODT not yet supported
if hasattr(pads, "odt"):
self.comb += pads.odt.eq(0)

#
# DQ/DQS/DM control
#
self.comb += drive_dq.eq(d_dfi[self.settings.wrphase].wrdata_en)
if module.memtype == "DDR3":
r_drive_dq = Signal(self.settings.cwl-1)
sd_sdram_half += r_drive_dq.eq(Cat(d_dfi[self.settings.wrphase].wrdata_en, r_drive_dq))
self.comb += drive_dq.eq(r_drive_dq[self.settings.cwl-2])
else:
self.comb += drive_dq.eq(d_dfi[self.settings.wrphase].wrdata_en)

d_dfi_wrdata_en = Signal()
sd_sys += d_dfi_wrdata_en.eq(d_dfi[self.settings.wrphase].wrdata_en)

r_dfi_wrdata_en = Signal(2)
sd_sdram_half += r_dfi_wrdata_en.eq(Cat(d_dfi_wrdata_en, r_dfi_wrdata_en[0]))
r_dfi_wrdata_en = Signal(max(self.settings.cwl, self.settings.cl))
sd_sdram_half += r_dfi_wrdata_en.eq(Cat(d_dfi_wrdata_en, r_dfi_wrdata_en))

self.comb += drive_dqs.eq(r_dfi_wrdata_en[1])
if module.memtype == "DDR3":
self.comb += drive_dqs.eq(r_dfi_wrdata_en[self.settings.cwl-1])
else:
self.comb += drive_dqs.eq(r_dfi_wrdata_en[1])

rddata_sr = Signal(self.settings.read_latency)
sd_sys += rddata_sr.eq(Cat(rddata_sr[1:self.settings.read_latency],