From 34b2bd0c283e28a2d7cabf3227a2725e3bf530ad Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 27 Jun 2018 11:27:05 +0200 Subject: [PATCH] boards: add genesys2 (platform with clk/serial/dram/ethernet + target) --- litex/boards/platforms/genesys2.py | 104 ++++++++++++++++++++ litex/boards/targets/genesys2.py | 152 +++++++++++++++++++++++++++++ 2 files changed, 256 insertions(+) create mode 100644 litex/boards/platforms/genesys2.py create mode 100755 litex/boards/targets/genesys2.py diff --git a/litex/boards/platforms/genesys2.py b/litex/boards/platforms/genesys2.py new file mode 100644 index 000000000..0a5fdf154 --- /dev/null +++ b/litex/boards/platforms/genesys2.py @@ -0,0 +1,104 @@ +from litex.build.generic_platform import * +from litex.build.xilinx import XilinxPlatform, VivadoProgrammer + + +_io = [ + ("user_led", 0, Pins("T28"), IOStandard("LVCMOS33")), + ("user_led", 1, Pins("V19"), IOStandard("LVCMOS33")), + ("user_led", 2, Pins("U30"), IOStandard("LVCMOS33")), + ("user_led", 3, Pins("U29"), IOStandard("LVCMOS33")), + ("user_led", 4, Pins("V20"), IOStandard("LVCMOS33")), + ("user_led", 5, Pins("V26"), IOStandard("LVCMOS33")), + ("user_led", 6, Pins("W24"), IOStandard("LVCMOS33")), + ("user_led", 7, Pins("W23"), IOStandard("LVCMOS33")), + + ("cpu_reset_n", 0, Pins("R19"), IOStandard("LVCMOS33")), + + ("user_btn_c", 0, Pins("E18"), IOStandard("LVCMOS33")), + ("user_btn_d", 0, Pins("M19"), IOStandard("LVCMOS33")), + ("user_btn_l", 0, Pins("M20"), IOStandard("LVCMOS33")), + ("user_btn_r", 0, Pins("C19"), IOStandard("LVCMOS33")), + ("user_btn_u", 0, Pins("B19"), IOStandard("LVCMOS33")), + + ("user_dip_sw", 0, Pins("G19"), IOStandard("LVCMOS12")), + ("user_dip_sw", 1, Pins("G25"), IOStandard("LVCMOS12")), + ("user_dip_sw", 2, Pins("H24"), IOStandard("LVCMOS12")), + ("user_dip_sw", 3, Pins("K19"), IOStandard("LVCMOS12")), + ("user_dip_sw", 4, Pins("N19"), IOStandard("LVCMOS12")), + ("user_dip_sw", 5, Pins("P19"), IOStandard("LVCMOS12")), + ("user_dip_sw", 6, Pins("P26"), IOStandard("LVCMOS33")), + ("user_dip_sw", 7, Pins("P27"), IOStandard("LVCMOS33")), + + ("clk200", 0, + Subsignal("p", Pins("AD12"), IOStandard("LVDS")), + Subsignal("n", Pins("AD11"), IOStandard("LVDS")) + ), + + ("serial", 0, + Subsignal("tx", Pins("Y23")), + Subsignal("rx", Pins("Y20")), + IOStandard("LVCMOS33") + ), + + ("ddram", 0, + Subsignal("a", Pins( + "AC12 AE8 AD8 AC10 AD9 AA13 AA10 AA11", + "Y10 Y11 AB8 AA8 AB12 AA12 AH9"), + IOStandard("SSTL15")), + Subsignal("ba", Pins("AE9 AB10 AC11"), IOStandard("SSTL15")), + Subsignal("ras_n", Pins("AE11"), IOStandard("SSTL15")), + Subsignal("cas_n", Pins("AF11"), IOStandard("SSTL15")), + Subsignal("we_n", Pins("AG13"), IOStandard("SSTL15")), + Subsignal("cs_n", Pins("AH12"), IOStandard("SSTL15")), + Subsignal("dm", Pins("AD4 AF3 AH4 AF8"), + IOStandard("SSTL15")), + Subsignal("dq", Pins( + "AD3 AC2 AC1 AC5 AC4 AD6 AE6 AC7", + "AF2 AE1 AF1 AE4 AE3 AE5 AF5 AF6", + "AJ4 AH6 AH5 AH2 AJ2 AJ1 AK1 AJ3", + "AF7 AG7 AJ6 AK6 AJ8 AK8 AK5 AK4"), + IOStandard("SSTL15_T_DCI")), + Subsignal("dqs_p", Pins("AD2 AG4 AG2 AH7"), + IOStandard("DIFF_SSTL15")), + Subsignal("dqs_n", Pins("AD1 AG3 AH1 AJ7"), + IOStandard("DIFF_SSTL15")), + Subsignal("clk_p", Pins("AB9"), IOStandard("DIFF_SSTL15")), + Subsignal("clk_n", Pins("AC9"), IOStandard("DIFF_SSTL15")), + Subsignal("cke", Pins("AJ9"), IOStandard("SSTL15")), + Subsignal("odt", Pins("AK9"), IOStandard("SSTL15")), + Subsignal("reset_n", Pins("AG5"), IOStandard("LVCMOS15")), + Misc("SLEW=FAST"), + Misc("VCCAUX_IO=HIGH") + ), + + ("eth_clocks", 0, + Subsignal("tx", Pins("AE10")), + Subsignal("rx", Pins("AG10")), + IOStandard("LVCMOS15") + ), + ("eth", 0, + Subsignal("rst_n", Pins("AH24"), IOStandard("LVCMOS33")), + Subsignal("int_n", Pins("AK16"), IOStandard("LVCMOS18")), + Subsignal("mdio", Pins("AG12"), IOStandard("LVCMOS15")), + Subsignal("mdc", Pins("AF12"), IOStandard("LVCMOS15")), + Subsignal("rx_ctl", Pins("AH11"), IOStandard("LVCMOS15")), + Subsignal("rx_data", Pins("AJ14 AH14 AK13 AJ13"), IOStandard("LVCMOS15")), + Subsignal("tx_ctl", Pins(" AK14"), IOStandard("LVCMOS15")), + Subsignal("tx_data", Pins("AJ12 AK11 AJ11 AK10"), IOStandard("LVCMOS15")), + ), +] + + +class Platform(XilinxPlatform): + def __init__(self): + XilinxPlatform.__init__(self, "xc7k325t-ffg900-2", _io, toolchain="vivado") + + def create_programmer(self): + return VivadoProgrammer() + + def do_finalize(self, fragment): + XilinxPlatform.do_finalize(self, fragment) + try: + self.add_period_constraint(self.lookup_request("clk200").p, 5.0) + except ConstraintError: + pass diff --git a/litex/boards/targets/genesys2.py b/litex/boards/targets/genesys2.py new file mode 100755 index 000000000..b42743e50 --- /dev/null +++ b/litex/boards/targets/genesys2.py @@ -0,0 +1,152 @@ +#!/usr/bin/env python3 + +import argparse + +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + +from litex.boards.platforms import genesys2 + +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 MT41J256M16 +from litedram.phy import s7ddrphy + +from liteeth.phy.s7rgmii import LiteEthPHYRGMII +from liteeth.core.mac import LiteEthMAC + + +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_clk200 = ClockDomain() + + clk200 = platform.request("clk200") + clk200_se = Signal() + self.specials += Instance("IBUFDS", i_I=clk200.p, i_IB=clk200.n, o_O=clk200_se) + + rst_n = platform.request("cpu_reset_n") + + pll_locked = Signal() + pll_fb = Signal() + self.pll_sys = Signal() + pll_sys4x = Signal() + pll_clk200 = Signal() + self.specials += [ + Instance("PLLE2_BASE", + p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked, + + # VCO @ 1GHz + p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=5.0, + p_CLKFBOUT_MULT=5, p_DIVCLK_DIVIDE=1, + i_CLKIN1=clk200_se, i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, + + # 125MHz + p_CLKOUT0_DIVIDE=8, p_CLKOUT0_PHASE=0.0, + o_CLKOUT0=self.pll_sys, + + # 500MHz + p_CLKOUT1_DIVIDE=2, p_CLKOUT1_PHASE=0.0, + o_CLKOUT1=pll_sys4x, + + # 200MHz + p_CLKOUT2_DIVIDE=5, p_CLKOUT2_PHASE=0.0, + o_CLKOUT2=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_clk200, o_O=self.cd_clk200.clk), + AsyncResetSynchronizer(self.cd_sys, ~pll_locked | ~rst_n), + AsyncResetSynchronizer(self.cd_clk200, ~pll_locked | ~rst_n), + ] + + 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 = genesys2.Platform() + SoCSDRAM.__init__(self, platform, clk_freq=125*1000000, + integrated_rom_size=0x8000, + integrated_sram_size=0x8000, + **kwargs) + + self.submodules.crg = _CRG(platform) + + # sdram + self.submodules.ddrphy = s7ddrphy.K7DDRPHY(platform.request("ddram")) + sdram_module = MT41J256M16(self.clk_freq, "1:4") + self.register_sdram(self.ddrphy, + sdram_module.geom_settings, + sdram_module.timing_settings) + + +class MiniSoC(BaseSoC): + csr_map = { + "ethphy": 18, + "ethmac": 19 + } + csr_map.update(BaseSoC.csr_map) + + interrupt_map = { + "ethmac": 3, + } + interrupt_map.update(BaseSoC.interrupt_map) + + mem_map = { + "ethmac": 0x30000000, # (shadow @0xb0000000) + } + mem_map.update(BaseSoC.mem_map) + + def __init__(self, **kwargs): + BaseSoC.__init__(self, **kwargs) + + self.submodules.ethphy = LiteEthPHYRGMII(self.platform.request("eth_clocks"), + self.platform.request("eth")) + self.submodules.ethmac = LiteEthMAC(phy=self.ethphy, dw=32, interface="wishbone") + self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus) + self.add_memory_region("ethmac", self.mem_map["ethmac"] | self.shadow_base, 0x2000) + + self.crg.cd_sys.clk.attr.add("keep") + self.ethphy.crg.cd_eth_rx.clk.attr.add("keep") + self.ethphy.crg.cd_eth_tx.clk.attr.add("keep") + self.platform.add_period_constraint(self.crg.cd_sys.clk, 8.0) + self.platform.add_period_constraint(self.ethphy.crg.cd_eth_rx.clk, 8.0) + self.platform.add_period_constraint(self.ethphy.crg.cd_eth_tx.clk, 8.0) + self.platform.add_false_path_constraints( + self.crg.cd_sys.clk, + self.ethphy.crg.cd_eth_rx.clk, + self.ethphy.crg.cd_eth_tx.clk) + + +def main(): + parser = argparse.ArgumentParser(description="LiteX SoC port to Genesys 2") + builder_args(parser) + soc_sdram_args(parser) + parser.add_argument("--with-ethernet", action="store_true", + help="enable Ethernet support") + args = parser.parse_args() + + cls = MiniSoC if args.with_ethernet else BaseSoC + soc = cls(**soc_sdram_argdict(args)) + builder = Builder(soc, **builder_argdict(args)) + builder.build() + + +if __name__ == "__main__": + main()