phys: move get_cl_cw/get_sys_latency/get_sys_phases helpers to common
This commit is contained in:
parent
509f60652a
commit
dc1bb53a88
|
@ -3,13 +3,16 @@
|
||||||
# This file is Copyright (c) 2018 bunnie <bunnie@kosagi.com>
|
# This file is Copyright (c) 2018 bunnie <bunnie@kosagi.com>
|
||||||
# License: BSD
|
# License: BSD
|
||||||
|
|
||||||
|
import math
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
from operator import add
|
from operator import add
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
from migen import *
|
from migen import *
|
||||||
|
|
||||||
from litex.soc.interconnect import stream
|
from litex.soc.interconnect import stream
|
||||||
|
|
||||||
|
# Helpers ------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
burst_lengths = {
|
burst_lengths = {
|
||||||
"SDR": 1,
|
"SDR": 1,
|
||||||
|
@ -20,7 +23,37 @@ burst_lengths = {
|
||||||
"DDR4": 8
|
"DDR4": 8
|
||||||
}
|
}
|
||||||
|
|
||||||
# Settings ---------------------------------------------------------------------
|
def get_cl_cw(memtype, tck):
|
||||||
|
f_to_cl_cwl = OrderedDict()
|
||||||
|
if memtype == "DDR2":
|
||||||
|
f_to_cl_cwl[400e6] = (3, 2)
|
||||||
|
f_to_cl_cwl[533e6] = (4, 3)
|
||||||
|
f_to_cl_cwl[677e6] = (5, 4)
|
||||||
|
f_to_cl_cwl[800e6] = (6, 5)
|
||||||
|
f_to_cl_cwl[1066e6] = (7, 5)
|
||||||
|
elif memtype == "DDR3":
|
||||||
|
f_to_cl_cwl[800e6] = ( 6, 5)
|
||||||
|
f_to_cl_cwl[1066e6] = ( 7, 6)
|
||||||
|
f_to_cl_cwl[1333e6] = (10, 7)
|
||||||
|
f_to_cl_cwl[1600e6] = (11, 8)
|
||||||
|
elif memtype == "DDR4":
|
||||||
|
f_to_cl_cwl[1600e6] = (11, 9)
|
||||||
|
else:
|
||||||
|
raise ValueError
|
||||||
|
for f, (cl, cwl) in f_to_cl_cwl.items():
|
||||||
|
if tck >= 2/f:
|
||||||
|
return cl, cwl
|
||||||
|
raise ValueError
|
||||||
|
|
||||||
|
def get_sys_latency(nphases, cas_latency):
|
||||||
|
return math.ceil(cas_latency/nphases)
|
||||||
|
|
||||||
|
def get_sys_phases(nphases, sys_latency, cas_latency):
|
||||||
|
dat_phase = sys_latency*nphases - cas_latency
|
||||||
|
cmd_phase = (dat_phase - 1)%nphases
|
||||||
|
return cmd_phase, dat_phase
|
||||||
|
|
||||||
|
# Settings -----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
class Settings:
|
class Settings:
|
||||||
def set_attributes(self, attributes):
|
def set_attributes(self, attributes):
|
||||||
|
@ -56,7 +89,7 @@ class TimingSettings(Settings):
|
||||||
def __init__(self, tRP, tRCD, tWR, tWTR, tREFI, tRFC, tFAW, tCCD, tRRD, tRC, tRAS, tZQCS):
|
def __init__(self, tRP, tRCD, tWR, tWTR, tREFI, tRFC, tFAW, tCCD, tRRD, tRC, tRAS, tZQCS):
|
||||||
self.set_attributes(locals())
|
self.set_attributes(locals())
|
||||||
|
|
||||||
# Layouts/Interface ------------------------------------------------------------
|
# Layouts/Interface --------------------------------------------------------------------------------
|
||||||
|
|
||||||
def cmd_layout(address_width):
|
def cmd_layout(address_width):
|
||||||
return [
|
return [
|
||||||
|
@ -123,7 +156,7 @@ class LiteDRAMInterface(Record):
|
||||||
layout += data_layout(self.data_width)
|
layout += data_layout(self.data_width)
|
||||||
Record.__init__(self, layout)
|
Record.__init__(self, layout)
|
||||||
|
|
||||||
# Ports ------------------------------------------------------------------------
|
# Ports --------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
class LiteDRAMNativePort(Settings):
|
class LiteDRAMNativePort(Settings):
|
||||||
def __init__(self, mode, address_width, data_width, clock_domain="sys", id=0):
|
def __init__(self, mode, address_width, data_width, clock_domain="sys", id=0):
|
||||||
|
@ -167,7 +200,7 @@ class LiteDRAMNativeReadPort(LiteDRAMNativePort):
|
||||||
LiteDRAMNativePort.__init__(self, "read", *args, **kwargs)
|
LiteDRAMNativePort.__init__(self, "read", *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
# Timing Controllers -----------------------------------------------------------
|
# Timing Controllers -------------------------------------------------------------------------------
|
||||||
|
|
||||||
class tXXDController(Module):
|
class tXXDController(Module):
|
||||||
def __init__(self, txxd):
|
def __init__(self, txxd):
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
# DDR3: 800 MT/s
|
# DDR3: 800 MT/s
|
||||||
|
|
||||||
import math
|
import math
|
||||||
from collections import OrderedDict
|
|
||||||
|
|
||||||
from migen import *
|
from migen import *
|
||||||
from migen.genlib.misc import timeline, BitSlip
|
from migen.genlib.misc import timeline, BitSlip
|
||||||
|
@ -16,30 +15,9 @@ from migen.genlib.misc import WaitTimer
|
||||||
|
|
||||||
from litex.soc.interconnect.csr import *
|
from litex.soc.interconnect.csr import *
|
||||||
|
|
||||||
from litedram.common import PhySettings
|
from litedram.common import *
|
||||||
from litedram.phy.dfi import *
|
from litedram.phy.dfi import *
|
||||||
|
|
||||||
# Helpers ------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
def get_cl_cw(memtype, tck):
|
|
||||||
f_to_cl_cwl = OrderedDict()
|
|
||||||
if memtype == "DDR3":
|
|
||||||
f_to_cl_cwl[800e6] = (6, 5)
|
|
||||||
else:
|
|
||||||
raise ValueError
|
|
||||||
for f, (cl, cwl) in f_to_cl_cwl.items():
|
|
||||||
if tck >= 2/f:
|
|
||||||
return cl, cwl
|
|
||||||
raise ValueError
|
|
||||||
|
|
||||||
def get_sys_latency(nphases, cas_latency):
|
|
||||||
return math.ceil(cas_latency/nphases)
|
|
||||||
|
|
||||||
def get_sys_phases(nphases, sys_latency, cas_latency):
|
|
||||||
dat_phase = sys_latency*nphases - cas_latency
|
|
||||||
cmd_phase = (dat_phase - 1)%nphases
|
|
||||||
return cmd_phase, dat_phase
|
|
||||||
|
|
||||||
# Lattice ECP5 DDR PHY Initialization --------------------------------------------------------------
|
# Lattice ECP5 DDR PHY Initialization --------------------------------------------------------------
|
||||||
|
|
||||||
class ECP5DDRPHYInit(Module):
|
class ECP5DDRPHYInit(Module):
|
||||||
|
|
|
@ -7,45 +7,16 @@
|
||||||
# DDR3: 800, 1066, 1333 and 1600 MT/s
|
# DDR3: 800, 1066, 1333 and 1600 MT/s
|
||||||
|
|
||||||
import math
|
import math
|
||||||
from collections import OrderedDict
|
|
||||||
|
|
||||||
from migen import *
|
from migen import *
|
||||||
from migen.genlib.misc import BitSlip
|
from migen.genlib.misc import BitSlip
|
||||||
|
|
||||||
from litex.soc.interconnect.csr import *
|
from litex.soc.interconnect.csr import *
|
||||||
|
|
||||||
from litedram.common import PhySettings
|
from litedram.common import *
|
||||||
from litedram.phy.dfi import *
|
from litedram.phy.dfi import *
|
||||||
|
|
||||||
|
|
||||||
def get_cl_cw(memtype, tck):
|
|
||||||
f_to_cl_cwl = OrderedDict()
|
|
||||||
if memtype == "DDR2":
|
|
||||||
f_to_cl_cwl[400e6] = (3, 2)
|
|
||||||
f_to_cl_cwl[533e6] = (4, 3)
|
|
||||||
f_to_cl_cwl[677e6] = (5, 4)
|
|
||||||
f_to_cl_cwl[800e6] = (6, 5)
|
|
||||||
f_to_cl_cwl[1066e6] = (7, 5)
|
|
||||||
elif memtype == "DDR3":
|
|
||||||
f_to_cl_cwl[800e6] = ( 6, 5)
|
|
||||||
f_to_cl_cwl[1066e6] = ( 7, 6)
|
|
||||||
f_to_cl_cwl[1333e6] = (10, 7)
|
|
||||||
f_to_cl_cwl[1600e6] = (11, 8)
|
|
||||||
else:
|
|
||||||
raise ValueError
|
|
||||||
for f, (cl, cwl) in f_to_cl_cwl.items():
|
|
||||||
if tck >= 2/f:
|
|
||||||
return cl, cwl
|
|
||||||
raise ValueError
|
|
||||||
|
|
||||||
def get_sys_latency(nphases, cas_latency):
|
|
||||||
return math.ceil(cas_latency/nphases)
|
|
||||||
|
|
||||||
def get_sys_phases(nphases, sys_latency, cas_latency):
|
|
||||||
dat_phase = sys_latency*nphases - cas_latency
|
|
||||||
cmd_phase = (dat_phase - 1)%nphases
|
|
||||||
return cmd_phase, dat_phase
|
|
||||||
|
|
||||||
class S7DDRPHY(Module, AutoCSR):
|
class S7DDRPHY(Module, AutoCSR):
|
||||||
def __init__(self, pads, with_odelay, memtype="DDR3", nphases=4, sys_clk_freq=100e6, iodelay_clk_freq=200e6, cmd_latency=0):
|
def __init__(self, pads, with_odelay, memtype="DDR3", nphases=4, sys_clk_freq=100e6, iodelay_clk_freq=200e6, cmd_latency=0):
|
||||||
assert not (memtype == "DDR3" and nphases == 2) # FIXME: Needs BL8 support for nphases=2
|
assert not (memtype == "DDR3" and nphases == 2) # FIXME: Needs BL8 support for nphases=2
|
||||||
|
|
|
@ -6,42 +6,16 @@
|
||||||
# DDR4: 1600 MT/s
|
# DDR4: 1600 MT/s
|
||||||
|
|
||||||
import math
|
import math
|
||||||
from collections import OrderedDict
|
|
||||||
|
|
||||||
from migen import *
|
from migen import *
|
||||||
from migen.genlib.misc import BitSlip, WaitTimer
|
from migen.genlib.misc import BitSlip, WaitTimer
|
||||||
|
|
||||||
from litex.soc.interconnect.csr import *
|
from litex.soc.interconnect.csr import *
|
||||||
|
|
||||||
from litedram.common import PhySettings
|
from litedram.common import *
|
||||||
from litedram.phy.dfi import *
|
from litedram.phy.dfi import *
|
||||||
|
|
||||||
|
|
||||||
def get_cl_cw(memtype, tck):
|
|
||||||
f_to_cl_cwl = OrderedDict()
|
|
||||||
if memtype == "DDR3":
|
|
||||||
f_to_cl_cwl[800e6] = ( 6, 5)
|
|
||||||
f_to_cl_cwl[1066e6] = ( 7, 6)
|
|
||||||
f_to_cl_cwl[1333e6] = (10, 7)
|
|
||||||
f_to_cl_cwl[1600e6] = (11, 8)
|
|
||||||
elif memtype == "DDR4":
|
|
||||||
f_to_cl_cwl[1600e6] = (11, 9)
|
|
||||||
else:
|
|
||||||
raise ValueError
|
|
||||||
for f, (cl, cwl) in f_to_cl_cwl.items():
|
|
||||||
if tck >= 2/f:
|
|
||||||
return cl, cwl
|
|
||||||
raise ValueError
|
|
||||||
|
|
||||||
def get_sys_latency(nphases, cas_latency):
|
|
||||||
return math.ceil(cas_latency/nphases)
|
|
||||||
|
|
||||||
def get_sys_phases(nphases, sys_latency, cas_latency):
|
|
||||||
dat_phase = sys_latency*nphases - cas_latency
|
|
||||||
cmd_phase = (dat_phase - 1)%nphases
|
|
||||||
return cmd_phase, dat_phase
|
|
||||||
|
|
||||||
|
|
||||||
class DDR4DFIMux(Module):
|
class DDR4DFIMux(Module):
|
||||||
def __init__(self, dfi_i, dfi_o):
|
def __init__(self, dfi_i, dfi_o):
|
||||||
for i in range(len(dfi_i.phases)):
|
for i in range(len(dfi_i.phases)):
|
||||||
|
|
Loading…
Reference in New Issue