184 lines
6.7 KiB
Python
184 lines
6.7 KiB
Python
#
|
|
# This file is part of LiteX-Boards.
|
|
#
|
|
# Copyright (c) 2023 Hans Baier <hansfbaier@gmail.com>
|
|
# 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]")
|
|
|
|
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)
|