# # This file is part of LiteX-Boards. # # Copyright (c) 2023 Hans Baier # SPDX-License-Identifier: BSD-2-Clause from litex.build.generic_platform import Pins, Subsignal, IOStandard, Misc from litex.build.xilinx import Xilinx7SeriesPlatform from litex.build.openocd import OpenOCD # IOs ---------------------------------------------------------------------------------------------- _io = [ # Clk / Rst ("clk50", 0, Pins("W19"), IOStandard("LVCMOS33")), ("cpu_reset", 0, Pins("Y6"), IOStandard("LVCMOS33")), ("prog_b", 0, Pins("N12"), IOStandard("LVCMOS33")), # The core board does not have a USB serial on it, # so you will have to attach an USB to serial adapter # on these pins ("gpio_serial", 0, Subsignal("tx", Pins("J2:7")), Subsignal("rx", Pins("J2:8")), IOStandard("LVCMOS33") ), # SPIFlash # 128Mbit SPI FLASH ("spiflash4x", 0, # clock needs to be accessed through STARTUPE2 Subsignal("cs_n", Pins("T19")), Subsignal("clk", Pins("L12")), Subsignal("dq", Pins("P22 R22 P21 R21")), IOStandard("LVCMOS33") ), # DDR3 SDRAM # MT41K128M16JT-125K ("ddram", 0, Subsignal("a", Pins("A15 D14 A14 D15 E14 F14 E13 C13 E16 B13 C17 F13 F16 A13"), IOStandard("SSTL15")), Subsignal("ba", Pins("D16 E17 B15"), IOStandard("SSTL15")), Subsignal("ras_n", Pins("B17"), IOStandard("SSTL15")), Subsignal("cas_n", Pins("B16"), IOStandard("SSTL15")), Subsignal("we_n", Pins("A16"), IOStandard("SSTL15")), # cs_n is hardwired on the board #Subsignal("cs_n", Pins(""), IOStandard("SSTL15")), Subsignal("dm", Pins("F19 D20"), IOStandard("SSTL15")), Subsignal("dq", Pins( "B20 A18 A20 D19 A19 C18 C19 E19 C20 D22 D21 E21 C22 G21 B22 E22"), IOStandard("SSTL15"), Misc("IN_TERM=UNTUNED_SPLIT_40")), Subsignal("dqs_p", Pins("F18 B21"), IOStandard("DIFF_SSTL15"), Misc("IN_TERM=UNTUNED_SPLIT_40")), Subsignal("dqs_n", Pins("E18 A21"), IOStandard("DIFF_SSTL15"), Misc("IN_TERM=UNTUNED_SPLIT_40")), Subsignal("clk_p", Pins("C14"), IOStandard("DIFF_SSTL15")), Subsignal("clk_n", Pins("C15"), IOStandard("DIFF_SSTL15")), Subsignal("cke", Pins("B18"), IOStandard("SSTL15")), Subsignal("odt", Pins("D17"), IOStandard("SSTL15")), Subsignal("reset_n", Pins("F15"), IOStandard("SSTL15")), Misc("SLEW=FAST"), ), ] # The connectors are named after the daughterboard, not the core board # because on the different core boards the names vary, but on the # daughterboard they stay the same, which we need to connect the # daughterboard peripherals to the core board. # On this board J2 is U2 and J3 is U4 _connectors = [ ("J2", { # odd row even row 7: "H22", 8: "J22", 9: "H18", 10: "H17", 11: "K22", 12: "K21", 13: "G20", 14: "H20", 15: "H19", 16: "J19", 17: "J21", 18: "J20", 19: "J17", 20: "K17", 21: "L20", 22: "L19", 23: "H14", 24: "J14", 25: "K14", 26: "K13", 27: "M16", 28: "M15", 29: "M20", 30: "N20", 31: "M22", 32: "N22", 33: "L15", 34: "L14", 35: "N19", 36: "N18", 37: "P17", 38: "N17", 39: "T18", 40: "R18", 41: "Y22", 42: "Y21", 43: "U21", 44: "T21", 45: "V20", 46: "U20", 47: "U18", 48: "U17", 49: "V19", 50: "V18", 51: "AB22", 52: "AB21", 53: "AA21", 54: "AA20", 55: "AB20", 56: "AA19", 57: "Y19", 58: "Y18", 59: "AB18", 60: "AA18", }), ("J3", { # odd row even row 7: "B1", 8: "A1", 9: "C2", 10: "B2", 11: "E1", 12: "D1", 13: "E2", 14: "D2", 15: "G1", 16: "F1", 17: "H2", 18: "G2", 19: "K1", 20: "J1", 21: "K2", 22: "J2", 23: "M1", 24: "L1", 25: "K4", 26: "J4", 27: "L3", 28: "K3", 29: "M3", 30: "M2", 31: "P2", 32: "N2", 33: "R1", 34: "P1", 35: "P5", 36: "P4", 37: "R4", 38: "T4", 39: "T5", 40: "U5", 41: "T1", 42: "U1", 43: "W1", 44: "Y1", 45: "AA1", 46: "AB1", 47: "AB3", 48: "AB2", 49: "V4", 50: "W4", 51: "Y3", 52: "AA3", 53: "Y4", 54: "AA4", 55: "AA5", 56: "AB5", 57: "AB7", 58: "AB6", 59: "AA8", 60: "AB8", }) ] # Platform ----------------------------------------------------------------------------------------- class Platform(Xilinx7SeriesPlatform): default_clk_name = "clk50" default_clk_period = 1e9/50e6 kgates = None def __init__(self, kgates=200, toolchain="vivado", with_daughterboard=False): assert(kgates in [100, 200], "kgates can only be 100 or 200 representing a XC7A7100T, XC7TA200T") self.kgates = kgates device = f"xc7a{kgates}tfbg484-1" io = _io connectors = _connectors core_leds_name = "onboard_led" if with_daughterboard else "user_led" io += [ (core_leds_name, 0, Pins("F3"), IOStandard("LVCMOS33")), (core_leds_name, 1, Pins("E3"), IOStandard("LVCMOS33")), ] if with_daughterboard: from litex_boards.platforms.qmtech_daughterboard import QMTechDaughterboard daughterboard = QMTechDaughterboard(IOStandard("LVCMOS33")) io += daughterboard.io connectors += daughterboard.connectors Xilinx7SeriesPlatform.__init__(self, device, io, connectors, toolchain=toolchain) self.toolchain.bitstream_commands = \ ["set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]", "set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]"] self.toolchain.additional_commands = \ ["write_cfgmem -force -format bin -interface spix4 -size 16 " "-loadbit \"up 0x0 {build_name}.bit\" -file {build_name}.bin"] self.add_platform_command("set_property INTERNAL_VREF 0.750 [get_iobanks 16]") self.add_platform_command("set_property CFGBVS VCCO [current_design]") self.add_platform_command("set_property CONFIG_VOLTAGE 3.3 [current_design]") self.toolchain.f4pga_device = device def create_programmer(self): bscan_spi = f"bscan_spi_xc7a{self.kgates}t.bit" return OpenOCD("openocd_xc7_ft2232.cfg", bscan_spi) def do_finalize(self, fragment): Xilinx7SeriesPlatform.do_finalize(self, fragment) self.add_period_constraint(self.lookup_request("clk50", loose=True), 1e9/50e6)