--- /dev/null
+#!/usr/bin/env python3
+import argparse
+import os
+
+from litex.gen import *
+from litex.gen.genlib.resetsync import AsyncResetSynchronizer
+from litex.gen.fhdl.specials import Keep
+
+from litex.boards.platforms import nexys_video
+
+from litex.soc.integration.soc_core import *
+from litex.soc.integration.builder import *
+
+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_clk200 = ClockDomain()
+
+ clk100 = platform.request("clk100")
+ rst = platform.request("cpu_reset")
+
+ pll_locked = Signal()
+ pll_fb = Signal()
+ pll_sys = Signal()
+ pll_clk200 = Signal()
+ self.specials += [
+ Instance("PLLE2_BASE",
+ p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked,
+
+ # VCO @ 800 MHz
+ p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=10.0,
+ p_CLKFBOUT_MULT=8, p_DIVCLK_DIVIDE=1,
+ i_CLKIN1=clk100, i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb,
+
+ # 100 MHz
+ p_CLKOUT0_DIVIDE=8, p_CLKOUT0_PHASE=0.0,
+ o_CLKOUT0=pll_sys,
+
+ # 200 MHz
+ p_CLKOUT3_DIVIDE=4, p_CLKOUT3_PHASE=0.0,
+ o_CLKOUT3=pll_clk200
+ ),
+ Instance("BUFG", i_I=pll_sys, o_O=self.cd_sys.clk),
+ Instance("BUFG", i_I=pll_clk200, o_O=self.cd_clk200.clk),
+ AsyncResetSynchronizer(self.cd_sys, ~pll_locked | ~rst),
+ AsyncResetSynchronizer(self.cd_clk200, ~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(SoCCore):
+ def __init__(self, **kwargs):
+ platform = nexys_video.Platform()
+ SoCCore.__init__(self, platform, clk_freq=100*1000000,
+ integrated_rom_size=0x8000,
+ integrated_sram_size=0x8000,
+ integrated_main_ram_size=0x10000,
+ **kwargs)
+
+ self.submodules.crg = _CRG(platform)
+
+
+class MiniSoC(BaseSoC):
+ csr_map = {
+ "ethphy": 18,
+ "ethmac": 19
+ }
+ csr_map.update(BaseSoC.csr_map)
+
+ interrupt_map = {
+ "ethmac": 2,
+ }
+ 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.specials += [
+ Keep(self.ethphy.crg.cd_eth_rx.clk),
+ Keep(self.ethphy.crg.cd_eth_tx.clk)
+ ]
+ self.platform.add_platform_command("""
+create_clock -name sys_clk -period 10 [get_nets sys_clk]
+create_clock -name eth_rx_clk -period 8 [get_nets eth_clocks_tx]
+create_clock -name eth_tx_clk -period 8 [get_nets eth_clocks_rx]
+
+set_false_path -from [get_clocks eth_rx_clk] -to [get_clocks sys_clk]
+set_false_path -from [get_clocks sys_clk] -to [get_clocks eth_rx_clk]
+set_false_path -from [get_clocks eth_tx_clk] -to [get_clocks sys_clk]
+set_false_path -from [get_clocks sys_clk] -to [get_clocks eth_tx_clk]
+""")
+
+
+def main():
+ parser = argparse.ArgumentParser(description="LiteX SoC port to Nexys Video")
+ builder_args(parser)
+ soc_core_args(parser)
+ parser.add_argument("--with-ethernet", action="store_true",
+ help="enable Ethernet support")
+ parser.add_argument("--build", action="store_true",
+ help="build bitstream")
+ parser.add_argument("--load", action="store_true",
+ help="load bitstream")
+ args = parser.parse_args()
+
+ cls = MiniSoC if args.with_ethernet else BaseSoC
+ soc = cls(**soc_core_argdict(args))
+ builder = Builder(soc, **builder_argdict(args))
+
+ if args.build:
+ builder.build()
+
+ if args.load:
+ prog = soc.platform.create_programmer()
+ prog.load_bitstream(os.path.join(builder.output_dir, "gateware", "top.bit"))
+
+
+if __name__ == "__main__":
+ main()