phy/gensdrphy: fix problems with half-rate phy, tested on minispartan6

This commit is contained in:
Jędrzej Boczar 2020-07-14 10:58:58 +02:00
parent 7f55e2e2c5
commit 2c5fc6621a
3 changed files with 37 additions and 26 deletions

View File

@ -45,7 +45,8 @@ class ControllerSettings(Settings):
class LiteDRAMController(Module): class LiteDRAMController(Module):
def __init__(self, phy_settings, geom_settings, timing_settings, clk_freq, def __init__(self, phy_settings, geom_settings, timing_settings, clk_freq,
controller_settings=ControllerSettings()): controller_settings=ControllerSettings()):
address_align = log2_int(burst_lengths[phy_settings.memtype]) burst_length = phy_settings.nphases * (1 if phy_settings.memtype == "SDR" else 2)
address_align = log2_int(burst_length)
# Settings --------------------------------------------------------------------------------- # Settings ---------------------------------------------------------------------------------
self.settings = controller_settings self.settings = controller_settings

View File

@ -20,7 +20,7 @@ cmds = {
def get_sdr_phy_init_sequence(phy_settings, timing_settings): def get_sdr_phy_init_sequence(phy_settings, timing_settings):
cl = phy_settings.cl cl = phy_settings.cl
bl = 1 bl = phy_settings.nphases
mr = log2_int(bl) + (cl << 4) mr = log2_int(bl) + (cl << 4)
reset_dll = 1 << 8 reset_dll = 1 << 8

View File

@ -50,26 +50,23 @@ class GENSDRPHY(Module):
pads.sel_group(pads_group) pads.sel_group(pads_group)
# Addresses and Commands --------------------------------------------------------------- # Addresses and Commands ---------------------------------------------------------------
for i in range(len(pads.a)): self.specials += [SDROutput(i=dfi.p0.address[i], o=pads.a[i]) for i in range(len(pads.a))]
self.specials += SDROutput(i=dfi.p0.address[i], o=pads.a[i], clk=ClockSignal("sys")) self.specials += [SDROutput(i=dfi.p0.bank[i], o=pads.ba[i]) for i in range(len(pads.ba))]
for i in range(len(pads.ba)): self.specials += SDROutput(i=dfi.p0.cas_n, o=pads.cas_n)
self.specials += SDROutput(i=dfi.p0.bank[i], o=pads.ba[i], clk=ClockSignal("sys")) self.specials += SDROutput(i=dfi.p0.ras_n, o=pads.ras_n)
self.specials += SDROutput(i=dfi.p0.cas_n, o=pads.cas_n, clk=ClockSignal("sys")) self.specials += SDROutput(i=dfi.p0.we_n, o=pads.we_n)
self.specials += SDROutput(i=dfi.p0.ras_n, o=pads.ras_n, clk=ClockSignal("sys"))
self.specials += SDROutput(i=dfi.p0.we_n, o=pads.we_n, clk=ClockSignal("sys"))
if hasattr(pads, "cke"): if hasattr(pads, "cke"):
self.specials += SDROutput(i=dfi.p0.cke, o=pads.cke, clk=ClockSignal("sys")) self.specials += SDROutput(i=dfi.p0.cke, o=pads.cke)
if hasattr(pads, "cs_n"): if hasattr(pads, "cs_n"):
self.specials += SDROutput(i=dfi.p0.cs_n, o=pads.cs_n, clk=ClockSignal("sys")) self.specials += SDROutput(i=dfi.p0.cs_n, o=pads.cs_n)
# DQ/DM Data Path -------------------------------------------------------------------------- # DQ/DM Data Path --------------------------------------------------------------------------
for i in range(len(pads.dq)): for i in range(len(pads.dq)):
self.specials += SDRTristate( self.specials += SDRTristate(
io = pads.dq[i], io = pads.dq[i],
o = dfi.p0.wrdata[i], o = dfi.p0.wrdata[i],
oe = dfi.p0.wrdata_en, oe = dfi.p0.wrdata_en,
i = dfi.p0.rddata[i], i = dfi.p0.rddata[i],
clk = ClockSignal("sys")
) )
if hasattr(pads, "dm"): if hasattr(pads, "dm"):
for i in range(len(pads.dm)): for i in range(len(pads.dm)):
@ -104,23 +101,36 @@ class HalfRateGENSDRPHY(Module):
nranks = nranks, nranks = nranks,
nphases = nphases, nphases = nphases,
rdphase = 0, rdphase = 0,
wrphase = 1, wrphase = 0,
rdcmdphase = 1, rdcmdphase = 1,
wrcmdphase = 0, wrcmdphase = 1,
cl = cl, cl = cl,
read_latency = (cl + cmd_latency)//2 + 1, read_latency = (cl + cmd_latency)//2 + 2, # FIXME: should be possible to have 1 cycle less latency
write_latency = 0 write_latency = 0
) )
# DFI adaptation --------------------------------------------------------------------------- # DFI adaptation ---------------------------------------------------------------------------
self.dfi = dfi = Interface(addressbits, bankbits, nranks, databits, nphases) self.dfi = dfi = Interface(addressbits, bankbits, nranks, databits, nphases)
# Select active sys2x phase # Clock ------------------------------------------------------------------------------------
# sys ----____----____
# select active sys2x phase
# sys_clk ----____----____
# phase_sel 0 1 0 1 # phase_sel 0 1 0 1
# sys2x --__--__--__--__ self.phase_sel = phase_sel = Signal()
phase_sel = Signal(reset=1) phase_sys2x = Signal.like(phase_sel)
self.sync.sys2x += phase_sel.eq(~phase_sel) phase_sys = Signal.like(phase_sys2x)
self.sync += phase_sys.eq(phase_sys2x)
self.sync.sys2x += [
If(phase_sys2x == phase_sys,
phase_sel.eq(0),
).Else(
phase_sel.eq(~phase_sel)
),
phase_sys2x.eq(~phase_sel)
]
# Commands and address # Commands and address
dfi_omit = set(["rddata", "rddata_valid", "wrdata_en"]) dfi_omit = set(["rddata", "rddata_valid", "wrdata_en"])
@ -137,7 +147,7 @@ class HalfRateGENSDRPHY(Module):
self.comb += full_rate_phy.dfi.phases[0].wrdata_en.eq(wr_data_en | wr_data_en_d) self.comb += full_rate_phy.dfi.phases[0].wrdata_en.eq(wr_data_en | wr_data_en_d)
# Reads # Reads
rddata = Signal(2*databits) rddata = Signal(databits)
rddata_valid = Signal() rddata_valid = Signal()
self.sync.sys2x += [ self.sync.sys2x += [
@ -149,5 +159,5 @@ class HalfRateGENSDRPHY(Module):
dfi.phases[0].rddata.eq(rddata), dfi.phases[0].rddata.eq(rddata),
dfi.phases[0].rddata_valid.eq(rddata_valid), dfi.phases[0].rddata_valid.eq(rddata_valid),
dfi.phases[1].rddata.eq(full_rate_phy.dfi.phases[0].rddata), dfi.phases[1].rddata.eq(full_rate_phy.dfi.phases[0].rddata),
dfi.phases[1].rddata_valid.eq(full_rate_phy.dfi.phases[0].rddata_valid), dfi.phases[1].rddata_valid.eq(rddata_valid),
] ]