boards: add nexys4ddr

This commit is contained in:
Florent Kermarrec 2018-02-06 14:43:20 +01:00
parent 2ecd1b0666
commit ee4fa597b4
2 changed files with 199 additions and 0 deletions

View File

@ -0,0 +1,82 @@
# This file is Copyright (c) 2018 Florent Kermarrec <florent@enjoy-digital.fr>
# License: BSD
from litex.build.generic_platform import *
from litex.build.xilinx import XilinxPlatform, XC3SProg, VivadoProgrammer
_io = [
("user_led", 0, Pins("H17"), IOStandard("LVCMOS33")),
("user_led", 1, Pins("K15"), IOStandard("LVCMOS33")),
("user_led", 2, Pins("J13"), IOStandard("LVCMOS33")),
("user_led", 3, Pins("N14"), IOStandard("LVCMOS33")),
("user_led", 4, Pins("R18"), IOStandard("LVCMOS33")),
("user_led", 5, Pins("V17"), IOStandard("LVCMOS33")),
("user_led", 6, Pins("U17"), IOStandard("LVCMOS33")),
("user_led", 7, Pins("U16"), IOStandard("LVCMOS33")),
("user_led", 8, Pins("V16"), IOStandard("LVCMOS33")),
("user_led", 9, Pins("T15"), IOStandard("LVCMOS33")),
("user_led", 10, Pins("U14"), IOStandard("LVCMOS33")),
("user_led", 11, Pins("T16"), IOStandard("LVCMOS33")),
("user_led", 12, Pins("V15"), IOStandard("LVCMOS33")),
("user_led", 13, Pins("V14"), IOStandard("LVCMOS33")),
("user_led", 14, Pins("V12"), IOStandard("LVCMOS33")),
("user_led", 15, Pins("V11"), IOStandard("LVCMOS33")),
("clk100", 0, Pins("E3"), IOStandard("LVCMOS33")),
("cpu_reset", 0, Pins("C12"), IOStandard("LVCMOS33")),
("serial", 0,
Subsignal("tx", Pins("D4")),
Subsignal("rx", Pins("C4")),
IOStandard("LVCMOS33"),
),
("ddram", 0,
Subsignal("a", Pins(
"M4 P4 M6 T1 L3 P5 M2 N1",
"L4 N5 R2 K5 N6"),
IOStandard("SSTL18_II")),
Subsignal("ba", Pins("P2 P3 R1"), IOStandard("SSTL18_II")),
Subsignal("ras_n", Pins("N4"), IOStandard("SSTL18_II")),
Subsignal("cas_n", Pins("L3"), IOStandard("SSTL18_II")),
Subsignal("we_n", Pins("N2"), IOStandard("SSTL18_II")),
Subsignal("dm", Pins("T6 U1"), IOStandard("SSTL18_II")),
Subsignal("dq", Pins(
"R7 V6 R8 U7 V7 R6 U6 R5",
"T5 U3 V5 U4 V4 T4 V1 T3"),
IOStandard("SSTL18_II"),
Misc("IN_TERM=UNTUNED_SPLIT_50")),
Subsignal("dqs_p", Pins("U9 U2"), IOStandard("DIFF_SSTL18_II")),
Subsignal("dqs_n", Pins("V9 V2"), IOStandard("DIFF_SSTL18_II")),
Subsignal("clk_p", Pins("L6"), IOStandard("DIFF_SSTL18_II")),
Subsignal("clk_n", Pins("L5"), IOStandard("DIFF_SSTL18_II")),
Subsignal("cke", Pins("M1"), IOStandard("SSTL18_II")),
Subsignal("odt", Pins("M3"), IOStandard("SSTL18_II")),
Subsignal("cs_n", Pins("K6"), IOStandard("SSTL18_II")),
Misc("SLEW=FAST"),
),
]
class Platform(XilinxPlatform):
default_clk_name = "clk100"
default_clk_period = 10.0
def __init__(self, programmer="vivado"):
XilinxPlatform.__init__(self, "xc7a100t-CSG324-1", _io, toolchain="vivado")
self.programmer = programmer
self.add_platform_command("set_property INTERNAL_VREF 0.750 [get_iobanks 35]")
def create_programmer(self):
if self.programmer == "xc3sprog":
return XC3SProg("nexys4")
elif self.programmer == "vivado":
return VivadoProgrammer()
else:
raise ValueError("{} programmer is not supported"
.format(self.programmer))
def do_finalize(self, fragment):
XilinxPlatform.do_finalize(self, fragment)

117
litex/boards/targets/nexys4ddr.py Executable file
View File

@ -0,0 +1,117 @@
#!/usr/bin/env python3
import argparse
from litex.gen import *
from litex.gen.genlib.resetsync import AsyncResetSynchronizer
from litex.boards.platforms import nexys4ddr
from litex.soc.integration.soc_core import mem_decoder
from litex.soc.integration.soc_sdram import *
from litex.soc.integration.builder import *
from litedram.modules import MT41K256M16
from litedram.phy import a7ddrphy
class _CRG(Module):
def __init__(self, platform):
self.clock_domains.cd_sys = ClockDomain()
self.clock_domains.cd_sys4x = ClockDomain(reset_less=True)
self.clock_domains.cd_sys4x_dqs = ClockDomain(reset_less=True)
self.clock_domains.cd_clk200 = ClockDomain()
self.clock_domains.cd_clk100 = ClockDomain()
clk100 = platform.request("clk100")
rst = ~platform.request("cpu_reset")
pll_locked = Signal()
pll_fb = Signal()
self.pll_sys = Signal()
pll_sys4x = Signal()
pll_sys4x_dqs = Signal()
pll_clk200 = Signal()
self.specials += [
Instance("PLLE2_BASE",
p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked,
# VCO @ 1600 MHz
p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=10.0,
p_CLKFBOUT_MULT=16, p_DIVCLK_DIVIDE=1,
i_CLKIN1=clk100, i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb,
# 100 MHz
p_CLKOUT0_DIVIDE=16, p_CLKOUT0_PHASE=0.0,
o_CLKOUT0=self.pll_sys,
# 400 MHz
p_CLKOUT1_DIVIDE=4, p_CLKOUT1_PHASE=0.0,
o_CLKOUT1=pll_sys4x,
# 400 MHz dqs
p_CLKOUT2_DIVIDE=4, p_CLKOUT2_PHASE=90.0,
o_CLKOUT2=pll_sys4x_dqs,
# 200 MHz
p_CLKOUT3_DIVIDE=8, p_CLKOUT3_PHASE=0.0,
o_CLKOUT3=pll_clk200
),
Instance("BUFG", i_I=self.pll_sys, o_O=self.cd_sys.clk),
Instance("BUFG", i_I=pll_sys4x, o_O=self.cd_sys4x.clk),
Instance("BUFG", i_I=pll_sys4x_dqs, o_O=self.cd_sys4x_dqs.clk),
Instance("BUFG", i_I=pll_clk200, o_O=self.cd_clk200.clk),
Instance("BUFG", i_I=clk100, o_O=self.cd_clk100.clk),
AsyncResetSynchronizer(self.cd_sys, ~pll_locked | rst),
AsyncResetSynchronizer(self.cd_clk200, ~pll_locked | rst),
AsyncResetSynchronizer(self.cd_clk100, ~pll_locked | rst),
]
reset_counter = Signal(4, reset=15)
ic_reset = Signal(reset=1)
self.sync.clk200 += \
If(reset_counter != 0,
reset_counter.eq(reset_counter - 1)
).Else(
ic_reset.eq(0)
)
self.specials += Instance("IDELAYCTRL", i_REFCLK=ClockSignal("clk200"), i_RST=ic_reset)
class BaseSoC(SoCSDRAM):
csr_map = {
"ddrphy": 16,
}
csr_map.update(SoCSDRAM.csr_map)
def __init__(self, **kwargs):
platform = nexys4ddr.Platform()
SoCSDRAM.__init__(self, platform, clk_freq=100*1000000,
integrated_rom_size=0x8000,
integrated_sram_size=0x8000,
**kwargs)
self.submodules.crg = _CRG(platform)
# sdram
self.submodules.ddrphy = a7ddrphy.A7DDRPHY(platform.request("ddram"))
self.add_constant("READ_LEVELING_BITSLIP", 3)
self.add_constant("READ_LEVELING_DELAY", 14)
sdram_module = MT41K256M16(self.clk_freq, "1:4")
self.register_sdram(self.ddrphy,
sdram_module.geom_settings,
sdram_module.timing_settings)
def main():
parser = argparse.ArgumentParser(description="LiteX SoC port to Nexys4DDR")
builder_args(parser)
soc_sdram_args(parser)
args = parser.parse_args()
soc = BaseSoC(**soc_sdram_argdict(args))
builder = Builder(soc, **builder_argdict(args))
builder.build()
if __name__ == "__main__":
main()