s6ddrphy: improve genericity by adding wr_bitslip and dqs_ddr_alignment parameters bitslip parameter is renamed to rd_bitslip

This commit is contained in:
Florent Kermarrec 2013-11-06 15:56:53 +01:00 committed by Sebastien Bourdeauducq
parent e7c72a826c
commit 307fb41ca3
2 changed files with 34 additions and 26 deletions

View File

@ -27,12 +27,11 @@ from migen.genlib.record import *
from milkymist import lasmicon
class S6DDRPHY(Module):
def __init__(self, pads, memtype, nphases, cl, bitslip):
def __init__(self, pads, memtype, nphases, cl, rd_bitslip, wr_bitslip, dqs_ddr_alignment):
if memtype not in ["DDR", "LPDDR", "DDR2"]:
raise NotImplementedError("S6DDRPHY only supports DDR, LPDDR and DDR2")
if cl != 3:
raise NotImplementedError("S6DDRPHY only supports CAS LATENCY 3")
a = flen(pads.a)
ba = flen(pads.ba)
d = flen(pads.dq)
@ -118,7 +117,7 @@ class S6DDRPHY(Module):
bitslip_inc = Signal()
sd_sys += [
If(bitslip_cnt == bitslip,
If(bitslip_cnt == rd_bitslip,
bitslip_inc.eq(0)
).Else(
bitslip_cnt.eq(bitslip_cnt+1),
@ -148,7 +147,7 @@ class S6DDRPHY(Module):
for i in range(d//8):
# DQS output
self.specials += Instance("ODDR2",
Instance.Parameter("DDR_ALIGNMENT", "C1"),
Instance.Parameter("DDR_ALIGNMENT", dqs_ddr_alignment),
Instance.Parameter("INIT", 0),
Instance.Parameter("SRTYPE", "ASYNC"),
@ -166,7 +165,7 @@ class S6DDRPHY(Module):
# DQS tristate cmd
self.specials += Instance("ODDR2",
Instance.Parameter("DDR_ALIGNMENT", "C1"),
Instance.Parameter("DDR_ALIGNMENT", dqs_ddr_alignment),
Instance.Parameter("INIT", 0),
Instance.Parameter("SRTYPE", "ASYNC"),
@ -218,18 +217,20 @@ class S6DDRPHY(Module):
drive_dq = Signal()
drive_dq_n = Signal()
d_drive_dq = Signal()
d_drive_dq_n = Signal()
self.comb += [
drive_dq_n.eq(~drive_dq),
d_drive_dq_n.eq(~d_drive_dq)
]
drive_dq_n = [Signal() for i in range(2)]
self.comb += drive_dq_n[0].eq(~drive_dq)
sd_sys += drive_dq_n[1].eq(drive_dq_n[0])
dq_t = Signal(d)
dq_o = Signal(d)
dq_i = Signal(d)
dq_wrdata = []
for i in range(2):
for j in reversed(range(nphases)):
dq_wrdata.append(d_dfi[i*nphases+j].wrdata[:d])
dq_wrdata.append(d_dfi[i*nphases+j].wrdata[d:])
for i in range(d):
# Data serializer
self.specials += Instance("OSERDES2",
@ -247,15 +248,16 @@ class S6DDRPHY(Module):
Instance.Input("RST", 0),
Instance.Input("CLKDIV", sys_clk),
Instance.Input("D1", d_dfi[1*nphases+0].wrdata[i]),
Instance.Input("D2", d_dfi[1*nphases+1].wrdata[i+d]),
Instance.Input("D3", d_dfi[1*nphases+1].wrdata[i]),
Instance.Input("D4", d_dfi[0*nphases+0].wrdata[i+d]),
Instance.Input("D1", dq_wrdata[wr_bitslip+3][i]),
Instance.Input("D2", dq_wrdata[wr_bitslip+2][i]),
Instance.Input("D3", dq_wrdata[wr_bitslip+1][i]),
Instance.Input("D4", dq_wrdata[wr_bitslip+0][i]),
Instance.Output("TQ", dq_t[i]),
Instance.Input("T1", d_drive_dq_n),
Instance.Input("T2", d_drive_dq_n),
Instance.Input("T3", d_drive_dq_n),
Instance.Input("T4", drive_dq_n),
Instance.Input("T1", drive_dq_n[(wr_bitslip+3)//4]),
Instance.Input("T2", drive_dq_n[(wr_bitslip+2)//4]),
Instance.Input("T3", drive_dq_n[(wr_bitslip+1)//4]),
Instance.Input("T4", drive_dq_n[(wr_bitslip+0)//4]),
Instance.Input("TRAIN", 0),
Instance.Input("TCE", 1),
Instance.Input("SHIFTIN1", 0),
@ -309,6 +311,12 @@ class S6DDRPHY(Module):
Instance.InOut("IO", pads.dq[i])
)
dq_wrdata_mask = []
for i in range(2):
for j in reversed(range(nphases)):
dq_wrdata_mask.append(d_dfi[i*nphases+j].wrdata_mask[:d//8])
dq_wrdata_mask.append(d_dfi[i*nphases+j].wrdata_mask[d//8:])
for i in range(d//8):
# Mask serializer
self.specials += Instance("OSERDES2",
@ -326,10 +334,11 @@ class S6DDRPHY(Module):
Instance.Input("RST", 0),
Instance.Input("CLKDIV", sys_clk),
Instance.Input("D1", d_dfi[1*nphases+0].wrdata_mask[i]),
Instance.Input("D2", d_dfi[1*nphases+1].wrdata_mask[i+d//8]),
Instance.Input("D3", d_dfi[1*nphases+1].wrdata_mask[i]),
Instance.Input("D4", d_dfi[0*nphases+0].wrdata_mask[i+d//8]),
Instance.Input("D1", dq_wrdata_mask[wr_bitslip+3][i]),
Instance.Input("D2", dq_wrdata_mask[wr_bitslip+2][i]),
Instance.Input("D3", dq_wrdata_mask[wr_bitslip+1][i]),
Instance.Input("D4", dq_wrdata_mask[wr_bitslip+0][i]),
Instance.Output("TQ"),
Instance.Input("T1"),
Instance.Input("T2"),
@ -359,7 +368,6 @@ class S6DDRPHY(Module):
# DQ/DQS/DM control
#
self.comb += drive_dq.eq(d_dfi[self.phy_settings.wrphase].wrdata_en)
sd_sys += d_drive_dq.eq(drive_dq)
d_dfi_wrdata_en = Signal()
sd_sys += d_dfi_wrdata_en.eq(d_dfi[self.phy_settings.wrphase].wrdata_en)

2
top.py
View File

@ -92,7 +92,7 @@ class SoC(Module):
#
# DFI
#
self.submodules.ddrphy = s6ddrphy.S6DDRPHY(platform.request("ddram"), memtype="DDR", nphases=2, cl=3, bitslip=0)
self.submodules.ddrphy = s6ddrphy.S6DDRPHY(platform.request("ddram"), memtype="DDR", nphases=2, cl=3, rd_bitslip=0, wr_bitslip=3, dqs_ddr_alignment="C1")
self.submodules.dfii = dfii.DFIInjector(sdram_geom.mux_a, sdram_geom.bank_a,
self.ddrphy.phy_settings.dfi_d, self.ddrphy.phy_settings.nphases)
self.submodules.dficon0 = dfi.Interconnect(self.dfii.master, self.ddrphy.dfi)