From f08f80bed11f15c0acaf7393c54f24de41f5f126 Mon Sep 17 00:00:00 2001 From: David Shah Date: Tue, 6 Nov 2018 14:39:25 +0000 Subject: [PATCH] working on Versa-5G dram Signed-off-by: David Shah --- litex/boards/platforms/versaecp55g_sdram.py | 152 ++++++++++++++++++++ litex/boards/targets/versaecp55g_sdram.py | 113 +++++++++++++++ 2 files changed, 265 insertions(+) create mode 100644 litex/boards/platforms/versaecp55g_sdram.py create mode 100755 litex/boards/targets/versaecp55g_sdram.py diff --git a/litex/boards/platforms/versaecp55g_sdram.py b/litex/boards/platforms/versaecp55g_sdram.py new file mode 100644 index 00000000..ceec3134 --- /dev/null +++ b/litex/boards/platforms/versaecp55g_sdram.py @@ -0,0 +1,152 @@ +# This file is Copyright (c) 2017 Serge 'q3k' Bazanski +# License: BSD + +from litex.build.generic_platform import * +from litex.build.lattice import LatticePlatform +from litex.build.lattice.programmer import LatticeProgrammer + + +_io = [ + ("clk100", 0, Pins("P3"), IOStandard("LVDS")), + ("rst_n", 0, Pins("T1"), IOStandard("LVCMOS33")), + + ("user_led", 0, Pins("E16"), IOStandard("LVCMOS25")), + ("user_led", 1, Pins("D17"), IOStandard("LVCMOS25")), + ("user_led", 2, Pins("D18"), IOStandard("LVCMOS25")), + ("user_led", 3, Pins("E18"), IOStandard("LVCMOS25")), + ("user_led", 4, Pins("F17"), IOStandard("LVCMOS25")), + ("user_led", 5, Pins("F18"), IOStandard("LVCMOS25")), + ("user_led", 6, Pins("E17"), IOStandard("LVCMOS25")), + ("user_led", 7, Pins("F16"), IOStandard("LVCMOS25")), + + ("user_dip_btn", 0, Pins("H2"), IOStandard("LVCMOS15")), + ("user_dip_btn", 1, Pins("K3"), IOStandard("LVCMOS15")), + ("user_dip_btn", 2, Pins("G3"), IOStandard("LVCMOS15")), + ("user_dip_btn", 3, Pins("F2"), IOStandard("LVCMOS15")), + ("user_dip_btn", 4, Pins("J18"), IOStandard("LVCMOS25")), + ("user_dip_btn", 5, Pins("K18"), IOStandard("LVCMOS25")), + ("user_dip_btn", 6, Pins("K19"), IOStandard("LVCMOS25")), + ("user_dip_btn", 7, Pins("K20"), IOStandard("LVCMOS25")), + + ("serial", 0, + Subsignal("rx", Pins("C11"), IOStandard("LVCMOS33")), + Subsignal("tx", Pins("A11"), IOStandard("LVCMOS33")), + ), + + ("sdram_clock", 0, Pins("E14"), IOStandard("LVCMOS33")), + ("sdram", 0, + Subsignal("a", Pins("C6 E15 A16 B16 D15 C15 B15 E12 D12 B10 C7 A9 C10")), + Subsignal("dq", Pins("B19 B12 B9 E6 D6 E7 D7 B11 C14 A14 E13 D13 C13 B13 A13 A12")), + Subsignal("we_n", Pins("E9")), + Subsignal("ras_n", Pins("B8")), + Subsignal("cas_n", Pins("D9")), + Subsignal("cs_n", Pins("C8")), + Subsignal("cke", Pins("D11")), + Subsignal("ba", Pins("D8 E8")), + Subsignal("dm", Pins("B6 D14")), + IOStandard("LVCMOS33"), Misc("SLEWRATE=FAST") + ), + + ("eth_clocks", 0, + Subsignal("tx", Pins("P19")), + Subsignal("rx", Pins("L20")), + IOStandard("LVCMOS25") + ), + ("eth", 0, + Subsignal("rst_n", Pins("U17")), + Subsignal("mdio", Pins("U18")), + Subsignal("mdc", Pins("T18")), + Subsignal("rx_ctl", Pins("U19")), + Subsignal("rx_data", Pins("T20 U20 T19 R18")), + Subsignal("tx_ctl", Pins("R20")), + Subsignal("tx_data", Pins("N19 N20 P18 P20")), + IOStandard("LVCMOS25") + ), + + ("eth_clocks", 1, + Subsignal("tx", Pins("C20")), + Subsignal("rx", Pins("J19")), + IOStandard("LVCMOS25") + ), + ("eth", 1, + Subsignal("rst_n", Pins("F20")), + Subsignal("mdio", Pins("H20")), + Subsignal("mdc", Pins("G19")), + Subsignal("rx_ctl", Pins("F19")), + Subsignal("rx_data", Pins("G18 G16 H18 H17")), + Subsignal("tx_ctl", Pins("E19")), + Subsignal("tx_data", Pins("J17 J16 D19 D20")), + IOStandard("LVCMOS25") + ), +] + + +class Platform(LatticePlatform): + default_clk_name = "clk100" + default_clk_period = 10 + + def __init__(self, **kwargs): + LatticePlatform.__init__(self, "LFE5UM5G-45F-8BG381C", _io, **kwargs) + + def do_finalize(self, fragment): + LatticePlatform.do_finalize(self, fragment) + try: + self.add_period_constraint(self.lookup_request("eth_clocks", 0).rx, 8.0) + except ConstraintError: + pass + try: + self.add_period_constraint(self.lookup_request("eth_clocks", 1).rx, 8.0) + except ConstraintError: + pass + + def create_programmer(self): + _xcf_template = """ + + + + + + JTAG + + + 1 + Lattice + ECP5UM5G + LFE5UM5G-45F + 0x81112043 + {bitstream_file} + Fast Program + + + + 2 + Lattice + ispCLOCK + ispPAC-CLK5406D + 0x00191043 + Erase,Program,Verify + + 8 + 11111111 + 1 + 0 + + + + + SEQUENTIAL + ENTIRED CHAIN + No Override + TLR + TLR + + + + USB2 + FTUSB-0 + LATTICE ECP5_5G VERSA BOARD A Location 0000 Serial Lattice ECP5_5G VERSA Board A + + +""" + + return LatticeProgrammer(_xcf_template) diff --git a/litex/boards/targets/versaecp55g_sdram.py b/litex/boards/targets/versaecp55g_sdram.py new file mode 100755 index 00000000..c279f8ef --- /dev/null +++ b/litex/boards/targets/versaecp55g_sdram.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python3 + +import argparse + +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + +from litex.boards.platforms import versaecp55g_sdram + +from litex.soc.integration.soc_sdram import * +from litex.soc.integration.builder import * + +from litedram.modules import AS4C32M16 +from litedram.phy import GENSDRPHY + + +class _CRG(Module): + def __init__(self, platform): + self.clock_domains.cd_sys = ClockDomain() + self.clock_domains.cd_sys_ps = ClockDomain() + + # # # + + clk100 = platform.request("clk100") + rst_n = platform.request("rst_n") + + rst = Signal() + self.comb += rst.eq(~rst_n) + + # sys_clk + # FIXME: AsyncResetSynchronizer needs FD1S3BX support. + #self.specials += AsyncResetSynchronizer(self.cd_sys, rst) + self.comb += self.cd_sys.rst.eq(rst) + self.comb += self.cd_sys_ps.rst.eq(rst) + + sys_clk = Signal() + sdram_ps_clk = Signal() + lock = Signal() + + self.specials += Instance( + "EHXPLLL", + i_CLKI=clk100, + i_CLKFB=sys_clk, + i_PHASESEL1=0, + i_PHASESEL0=0, + i_PHASEDIR=0, + i_PHASESTEP=0, + i_PHASELOADREG=0, + i_STDBY=0, + i_PLLWAKESYNC=0, + i_RST=0, + i_ENCLKOP=0, + i_ENCLKOS=0, + o_CLKOP=sys_clk, + o_CLKOS=sdram_ps_clk, + o_LOCK=lock, + p_CLKOS_FPHASE=0, + p_CLKOS_CPHASE=17, + p_CLKOP_FPHASE=0, + p_CLKOP_CPHASE=11, + p_PLL_LOCK_MODE=0, + p_OUTDIVIDER_MUXB="DIVB", + p_OUTDIVIDER_MUXA="DIVA", + p_CLKOS_ENABLE="ENABLED", + p_CLKOP_ENABLE="ENABLED", + p_CLKOS_DIV=12, + p_CLKOP_DIV=12, + p_CLKFB_DIV=1, + p_CLKI_DIV=2, + p_FEEDBK_PATH="CLKOP", + attr=[("ICP_CURRENT", "12"), ("LPF_RESISTOR", "8"), ("MFG_ENABLE_FILTEROPAMP", "1"), ("MFG_GMCREF_SEL", "2")] + ) + + self.comb += self.cd_sys.clk.eq(sys_clk) + self.comb += self.cd_sys_ps.clk.eq(sdram_ps_clk) + sdram_clock = platform.request("sdram_clock") + self.comb += sdram_clock.eq(sdram_ps_clk) + led0 = platform.request("user_led", 0) + self.comb += led0.eq(~lock) + + +class BaseSoC(SoCSDRAM): + def __init__(self, **kwargs): + platform = versaecp55g_sdram.Platform(toolchain="prjtrellis") + sys_clk_freq = int(50e6) + SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq, + l2_size=32, + integrated_rom_size=0x8000, + **kwargs) + + self.submodules.crg = _CRG(platform) + + if not self.integrated_main_ram_size: + self.submodules.sdrphy = GENSDRPHY(platform.request("sdram")) + sdram_module = AS4C32M16(sys_clk_freq, "1:1") + self.register_sdram(self.sdrphy, + sdram_module.geom_settings, + sdram_module.timing_settings) + + +def main(): + parser = argparse.ArgumentParser(description="LiteX SoC port to the ECP5 Versa board with SDRAM hat") + 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() -- 2.30.2