boards/targets: add nexys_video
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Tue, 1 Dec 2015 09:19:30 +0000 (10:19 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Tue, 1 Dec 2015 09:19:41 +0000 (10:19 +0100)
litex/boards/targets/nexys_video.py [new file with mode: 0644]

diff --git a/litex/boards/targets/nexys_video.py b/litex/boards/targets/nexys_video.py
new file mode 100644 (file)
index 0000000..4704c9c
--- /dev/null
@@ -0,0 +1,143 @@
+#!/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()