diff --git a/litex/boards/targets/nexys_video.py b/litex/boards/targets/nexys_video.py new file mode 100644 index 000000000..4704c9ce8 --- /dev/null +++ b/litex/boards/targets/nexys_video.py @@ -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()