from litex.build.generic_platform import *
from litex.build.xilinx import XilinxPlatform, VivadoProgrammer
from litex.build.openocd import OpenOCD
import os
import argparse
import sys
from migen import *
# from litex_boards.platforms import acorn
from litex.soc.interconnect.csr import *
from litex.soc.integration.soc_core import *
from litex.soc.integration.builder import *
from litex.soc.cores.clock import *
from litex.soc.cores.led import LedChaser
from litedram.modules import MT41K256M16
from litedram.phy import s7ddrphy
from litepcie.phy.s7pciephy import S7PCIEPHY
from litepcie.core import LitePCIeEndpoint, LitePCIeMSI
from litepcie.frontend.dma import LitePCIeDMA
from litepcie.frontend.wishbone import LitePCIeWishboneBridge
from litepcie.software import generate_litepcie_software
# IOs ----------------------------------------------------------------------------------------------
_io = [
# clk / rst
("clk200", 0,
Subsignal("p", Pins("H4"), IOStandard("DIFF_SSTL15")),
Subsignal("n", Pins("G4"), IOStandard("DIFF_SSTL15"))
),
# Leds
("sys_led", 0, Pins("U22"), IOStandard("LVCMOS33")),
("led2", 0, Pins("W22"), IOStandard("LVCMOS33")),
# SPIFlash
("flash_cs_n", 0, Pins("T19"), IOStandard("LVCMOS33")),
("flash", 0,
Subsignal("mosi", Pins("P22")),
Subsignal("miso", Pins("R22")),
Subsignal("wp", Pins("P21")),
Subsignal("hold", Pins("R21")),
IOStandard("LVCMOS33"),
),
# pcie
("pcie_x1", 0,
Subsignal("rst_n", Pins("M17"), IOStandard("LVCMOS33"), Misc("PULLUP=TRUE")),
Subsignal("clk_p", Pins("F10")),
Subsignal("clk_n", Pins("E10")),
Subsignal("rx_p", Pins("B8")),
Subsignal("rx_n", Pins("A8")),
Subsignal("tx_p", Pins("B4")),
Subsignal("tx_n", Pins("A4")),
),
# dram
("ddram", 0,
Subsignal("a", Pins(
"J1 P6 N5 N3 G1 M3 N2 J5",
"L1 P2 L4 P5 K2 M1 M5"),
IOStandard("SSTL15")),
Subsignal("ba", Pins("P4 H5 H2"), IOStandard("SSTL15")),
Subsignal("ras_n", Pins("M6"), IOStandard("SSTL15")),
Subsignal("cas_n", Pins("M2"), IOStandard("SSTL15")),
Subsignal("we_n", Pins("J2"), IOStandard("SSTL15")),
Subsignal("cs_n", Pins("K1"), IOStandard("SSTL15")),
Subsignal("dm", Pins(
"W2 Y7 V4 V5"),
IOStandard("SSTL15")),
Subsignal("dq", Pins(
"T1 U3 U2 U1 Y2 W1 Y1 V2",
"V7 W9 AB7 AA8 AB8 AB6 Y8 Y9",
"AB1 AB5 AB3 AA1 Y4 AA5 AB2 W4",
"T4 U6 T6 AA6 Y6 T5 U5 R6"),
IOStandard("SSTL15")),
Subsignal("dqs_p", Pins("R3 V9 Y3 W6"),
IOStandard("DIFF_SSTL15")),
Subsignal("dqs_n", Pins("R2 V8 AA3 W5"),
IOStandard("DIFF_SSTL15")),
Subsignal("clk_p", Pins("R1"), IOStandard("DIFF_SSTL15")),
Subsignal("clk_n", Pins("P1"), IOStandard("DIFF_SSTL15")),
Subsignal("cke", Pins("L3"), IOStandard("SSTL15")),
Subsignal("odt", Pins("K3"), IOStandard("SSTL15")),
Subsignal("reset_n", Pins("H3"), IOStandard("LVCMOS15")),
Misc("SLEW=FAST"),
),
]
_serial_io = [
# Serial adapter on P2.
("serial", 0,
Subsignal("tx", Pins("U18")),
Subsignal("rx", Pins("P16")),
Misc("SLEW=FAST"),
IOStandard("LVCMOS33"),
),
]
# Platform -----------------------------------------------------------------------------------------
class Platform(XilinxPlatform):
default_clk_name = "clk200"
default_clk_period = 1e9/200e6
def __init__(self):
XilinxPlatform.__init__(self, "xc7a200tfbg484-2", _io, toolchain="vivado")
self.add_platform_command("set_property INTERNAL_VREF 0.750 [get_iobanks 34]")
self.toolchain.bitstream_commands = [
"set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]",
"set_property BITSTREAM.CONFIG.CONFIGRATE 66 [current_design]",
"set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]",
"set_property CFGBVS VCCO [current_design]",
"set_property CONFIG_VOLTAGE 3.3 [current_design]",
]
self.toolchain.additional_commands = [
# Non-Multiboot SPI-Flash bitstream generation.
"write_cfgmem -force -format bin -interface spix4 -size 16 -loadbit \"up 0x0 {build_name}.bit\" -file {build_name}.bin",
# Multiboot SPI-Flash Operational bitstream generation.
"set_property BITSTREAM.CONFIG.TIMER_CFG 0x0001fbd0 [current_design]",
"set_property BITSTREAM.CONFIG.CONFIGFALLBACK Enable [current_design]",
"write_bitstream -force {build_name}_operational.bit ",
"write_cfgmem -force -format bin -interface spix4 -size 16 -loadbit \"up 0x0 {build_name}_operational.bit\" -file {build_name}_operational.bin",
# Multiboot SPI-Flash Fallback bitstream generation.
"set_property BITSTREAM.CONFIG.NEXT_CONFIG_ADDR 0x00400000 [current_design]",
"write_bitstream -force {build_name}_fallback.bit ",
"write_cfgmem -force -format bin -interface spix4 -size 16 -loadbit \"up 0x0 {build_name}_fallback.bit\" -file {build_name}_fallback.bin"
]
def create_programmer(self, name='openocd'):
if name == 'openocd':
return OpenOCD("openocd_xc7_ft232.cfg", "bscan_spi_xc7a200t.bit")
elif name == 'vivado':
# TODO: some board versions may have s25fl128s
return VivadoProgrammer(flash_part='s25fl256sxxxxxx0-spi-x1_x2_x4')
def do_finalize(self, fragment):
XilinxPlatform.do_finalize(self, fragment)
self.add_period_constraint(self.lookup_request("clk200", loose=True), 1e9/200e6)
# CRG ----------------------------------------------------------------------------------------------
class CRG(Module):
def __init__(self, platform, sys_clk_freq):
self.rst = Signal()
self.clock_domains.cd_sys = ClockDomain()
self.clock_domains.cd_sys4x = ClockDomain(reset_less=True)
self.clock_domains.cd_sys4x_dqs = ClockDomain(reset_less=True)
self.clock_domains.cd_idelay = ClockDomain()
# Clk/Rst
clk200 = platform.request("clk200")
# PLL
self.submodules.pll = pll = S7PLL()
self.comb += pll.reset.eq(self.rst)
pll.register_clkin(clk200, 200e6)
pll.create_clkout(self.cd_sys, sys_clk_freq)
pll.create_clkout(self.cd_sys4x, 4*sys_clk_freq)
pll.create_clkout(self.cd_sys4x_dqs, 4*sys_clk_freq, phase=90)
pll.create_clkout(self.cd_idelay, 200e6)
self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_idelay)
# PCIeSoC -----------------------------------------------------------------------------------------
class PCIeSoC(SoCCore):
def __init__(self, sys_clk_freq = int(100e6), **kwargs):
sys_clk_freq = int(100e6)
platform = Platform()
# SoCCore ----------------------------------------------------------------------------------
SoCCore.__init__(self, platform, sys_clk_freq,
ident = "LiteX SoC on TE0712",
**kwargs)
# CRG --------------------------------------------------------------------------------------
self.submodules.crg = CRG(platform, sys_clk_freq)
# PCIe -------------------------------------------------------------------------------------
# PHY
self.submodules.pcie_phy = S7PCIEPHY(platform, platform.request("pcie_x1"),
data_width = 64,
bar0_size = 0x20000)
self.add_pcie(phy=self.pcie_phy, ndmas=1)
# FIXME: Apply it to all targets (integrate it in LitePCIe?).
platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/sys_clk_freq)
platform.toolchain.pre_placement_commands.add("set_clock_groups -group [get_clocks {sys_clk}] -group [get_clocks userclk1] -asynchronous", sys_clk=self.crg.cd_sys.clk)
platform.toolchain.pre_placement_commands.add("set_clock_groups -group [get_clocks {sys_clk}] -group [get_clocks clk_125mhz] -asynchronous", sys_clk=self.crg.cd_sys.clk)
platform.toolchain.pre_placement_commands.add("set_clock_groups -group [get_clocks {sys_clk}] -group [get_clocks clk_250mhz] -asynchronous", sys_clk=self.crg.cd_sys.clk)
platform.toolchain.pre_placement_commands.add("set_clock_groups -group [get_clocks clk_125mhz] -group [get_clocks clk_250mhz] -asynchronous")
# Create simple LED module (fpga description)
class Blink(Module):
def __init__(self, blink_freq, sys_clk_freq, led):
counter = Signal(32)
# synchronous assignments
self.sync += [
counter.eq(counter + 1),
If(counter == int((sys_clk_freq/blink_freq)/2 - 1),
counter.eq(0),
led.eq(~led)
)
]
# combinatorial assignements
self.comb += []
class LEDModule(Module):
def __init__(self, platform):
pass
# submodules
self.submodules += Blink(1, 100e6, platform.request("sys_led"))
self.submodules += Blink(2, 100e6, platform.request("led2"))
# Build --------------------------------------------------------------------------------------------
def main():
parser = argparse.ArgumentParser(description="LiteX SoC on TE0712")
parser.add_argument("--build", action="store_true", help="Build bitstream")
parser.add_argument("--driver", action="store_true", help="Generate LitePCIe driver")
parser.add_argument("--load", action="store_true", help="Load bitstream")
parser.add_argument("--flash", action="store_true", help="Flash bitstream")
parser.add_argument("--sys-clk-freq", default=100e6, help="System clock frequency.")
builder_args(parser)
soc_core_args(parser)
args = parser.parse_args()
soc = PCIeSoC(
sys_clk_freq = int(float(args.sys_clk_freq)),
**soc_core_argdict(args))
builder = Builder(soc, **builder_argdict(args))
builder.build(run=args.build)
if args.driver:
generate_litepcie_software(soc, os.path.join(builder.output_dir, "driver"))
if args.load:
prog = soc.platform.create_programmer()
prog.load_bitstream(os.path.join(builder.gateware_dir, soc.build_name + ".bit"))
if args.flash:
prog = soc.platform.create_programmer()
prog.load_bitstream(os.path.join(builder.gateware_dir, soc.build_name + ".bin"))
# platform = Platform()
# module = LEDModule(platform)
# platform.build(module)
if __name__ == "__main__":
main()
I know my PCIe lines are right as I use the same pin configurations in a separate Vivado project and I can successfully connect to the Linux CPU through PCIe. Below is the same output when PCIe is recognized correctly.