-
Notifications
You must be signed in to change notification settings - Fork 290
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #615 from machdyne/master
add support for Mozart MX2
- Loading branch information
Showing
3 changed files
with
370 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
# | ||
# This file is part of LiteX-Boards. | ||
# | ||
# | ||
# Copyright (c) 2015 Yann Sionneau <[email protected]> | ||
# Copyright (c) 2015-2019 Florent Kermarrec <[email protected]> | ||
# Copyright (c) 2024 Lone Dynamics Corporation <[email protected]> | ||
# | ||
# SPDX-License-Identifier: BSD-2-Clause | ||
|
||
from litex.build.generic_platform import * | ||
from litex.build.xilinx import Xilinx7SeriesPlatform | ||
from litex.build.openfpgaloader import OpenFPGALoader | ||
|
||
# IOs ---------------------------------------------------------------------------------------------- | ||
|
||
_io_vx = [ | ||
|
||
# Clock | ||
("clk48", 0, Pins("F5"), IOStandard("LVCMOS33")), | ||
("clk50", 0, Pins("D4"), IOStandard("LVCMOS33")), | ||
|
||
# DDR3L | ||
("ddram", 0, | ||
Subsignal("a", Pins( | ||
"F12 D15 J15 E16 G11 F15 H13 G15", | ||
"H12 H16 H11 H14 E12 G16 J16"), | ||
IOStandard("SSTL135")), | ||
Subsignal("ba", Pins("E15 D11 F13"), IOStandard("SSTL135")), | ||
Subsignal("ras_n", Pins("D14"), IOStandard("SSTL135")), | ||
Subsignal("cas_n", Pins("E13"), IOStandard("SSTL135")), | ||
Subsignal("we_n", Pins("G12"), IOStandard("SSTL135")), | ||
Subsignal("dm", Pins("A13 D9"), IOStandard("SSTL135")), | ||
Subsignal("dq", Pins( | ||
"A14 C12 B14 D13 B16 C11 C16 C14", | ||
"A9 B10 C8 B12 A8 A12 C9 B11"), | ||
IOStandard("SSTL135"), | ||
Misc("IN_TERM=UNTUNED_SPLIT_60")), | ||
Subsignal("dqs_p", Pins("B15 B9"), IOStandard("DIFF_SSTL135"), | ||
Misc("IN_TERM=UNTUNED_SPLIT_60")), | ||
Subsignal("dqs_n", Pins("A15 A10"), IOStandard("DIFF_SSTL135"), | ||
Misc("IN_TERM=UNTUNED_SPLIT_60")), | ||
Subsignal("clk_p", Pins("G14"), IOStandard("DIFF_SSTL135")), | ||
Subsignal("clk_n", Pins("F14"), IOStandard("DIFF_SSTL135")), | ||
Subsignal("cke", Pins("E11"), IOStandard("SSTL135")), | ||
Subsignal("odt", Pins("D16"), IOStandard("SSTL135")), | ||
Subsignal("reset_n", Pins("M16"), IOStandard("LVCMOS33")), | ||
), | ||
|
||
# Differential Data Multiple Interface | ||
("ddmi", 0, | ||
Subsignal("clk_p", Pins("C1"), IOStandard("TMDS_33")), | ||
Subsignal("clk_n", Pins("B1"), IOStandard("TMDS_33")), | ||
Subsignal("data0_p", Pins("E2"), IOStandard("TMDS_33")), | ||
Subsignal("data0_n", Pins("D1"), IOStandard("TMDS_33")), | ||
Subsignal("data1_p", Pins("F2"), IOStandard("TMDS_33")), | ||
Subsignal("data1_n", Pins("E1"), IOStandard("TMDS_33")), | ||
Subsignal("data2_p", Pins("G2"), IOStandard("TMDS_33")), | ||
Subsignal("data2_n", Pins("G1"), IOStandard("TMDS_33")) | ||
), | ||
|
||
# USB-C | ||
("usb", 0, | ||
Subsignal("d_p", Pins("B2")), | ||
Subsignal("d_n", Pins("A2")), | ||
Subsignal("pullup", Pins("C2")), | ||
IOStandard("LVCMOS33") | ||
), | ||
|
||
# DUAL USB HOST | ||
("usb_host", 0, | ||
Subsignal("dp", Pins("H2 K1")), | ||
Subsignal("dm", Pins("H1 J1")), | ||
IOStandard("LVCMOS33") | ||
), | ||
|
||
# ETHERNET | ||
("eth", 0, | ||
Subsignal("rx_data", Pins("F3 F4"), Misc("PULLUP")), | ||
Subsignal("tx_data", Pins("D3 E3")), | ||
Subsignal("tx_en", Pins("G4")), | ||
Subsignal("crs_dv", Pins("H3"), Misc("PULLUP")), | ||
Subsignal("rst_n", Pins("H4")), | ||
IOStandard("LVCMOS33") | ||
), | ||
|
||
# LVDS | ||
("ds", 0, | ||
Subsignal("ds0", Pins("M2")), | ||
Subsignal("ds1", Pins("R2")), | ||
Subsignal("ds2", Pins("T4")), | ||
IOStandard("LVDS_25") | ||
), | ||
|
||
# DEBUG UART | ||
("serial", 0, | ||
Subsignal("tx", Pins("L2")), | ||
Subsignal("rx", Pins("L3")), | ||
IOStandard("LVCMOS33") | ||
), | ||
|
||
# MMOD | ||
("spiflash4x", 0, | ||
Subsignal("cs_n", Pins("L12")), | ||
#Subsignal("clk", Pins("")), # Accessed through STARTUPE2 | ||
Subsignal("dq", Pins("J13 J14 K15 K16")), | ||
IOStandard("LVCMOS33") | ||
), | ||
|
||
# SD card w/ SD-mode interface | ||
("sdcard", 0, | ||
Subsignal("cd", Pins("K3")), | ||
Subsignal("clk", Pins("R6")), | ||
Subsignal("cmd", Pins("T8")), | ||
Subsignal("data", Pins("T7 P8 T9 T5")), | ||
IOStandard("LVCMOS33") | ||
), | ||
|
||
# SD card w/ SPI interface | ||
("spisdcard", 0, | ||
Subsignal("clk", Pins("R6")), | ||
Subsignal("mosi", Pins("T8")), | ||
Subsignal("cs_n", Pins("T5")), | ||
Subsignal("miso", Pins("T7")), | ||
IOStandard("LVCMOS33"), | ||
), | ||
|
||
] | ||
|
||
_io_v0 = [ | ||
] | ||
|
||
# Connectors --------------------------------------------------------------------------------------- | ||
|
||
_connectors_vx = [ | ||
] | ||
|
||
# Platform ----------------------------------------------------------------------------------------- | ||
|
||
class Platform(Xilinx7SeriesPlatform): | ||
default_clk_name = "clk48" | ||
default_clk_period = 1e9/48e6 | ||
|
||
def __init__(self, revision="v0", variant="a7-35", toolchain="vivado"): | ||
|
||
assert revision in ["v0"] | ||
self.revision = revision | ||
|
||
io = _io_vx | ||
connectors = _connectors_vx | ||
|
||
if revision == "v0": | ||
io += _io_v0 | ||
|
||
device = { | ||
"a7-35": "xc7a35tftg256-1" | ||
}[variant] | ||
Xilinx7SeriesPlatform.__init__(self, device, io, connectors, toolchain=toolchain) | ||
self.toolchain.bitstream_commands = [ | ||
"set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 1 [current_design]", | ||
"set_property BITSTREAM.CONFIG.CONFIGRATE 33 [current_design]" | ||
] | ||
self.toolchain.additional_commands = \ | ||
["write_cfgmem -force -format bin -interface spix1 -size 16 " | ||
"-loadbit \"up 0x0 {build_name}.bit\" -file {build_name}.bin"] | ||
self.add_platform_command("set_property INTERNAL_VREF 0.675 [get_iobanks 34]") | ||
|
||
def create_programmer(self): | ||
bscan_spi = "bscan_spi_xc7a100t.bit" if "xc7a100t" in self.device else "bscan_spi_xc7a35t.bit" | ||
return OpenOCD("openocd_xc7_ft2232.cfg", bscan_spi) | ||
|
||
def do_finalize(self, fragment): | ||
Xilinx7SeriesPlatform.do_finalize(self, fragment) | ||
self.add_platform_command("set_property INTERNAL_VREF 0.675 [get_iobanks 15]") | ||
self.add_period_constraint(self.lookup_request("clk48", loose=True), 1e9/48e6) | ||
self.add_period_constraint(self.lookup_request("clk50", loose=True), 1e9/50e6) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,192 @@ | ||
#!/usr/bin/env python3 | ||
|
||
# | ||
# This file is part of LiteX-Boards. | ||
# | ||
# Copyright (c) 2015-2019 Florent Kermarrec <[email protected]> | ||
# Copyright (c) 2020 Antmicro <www.antmicro.com> | ||
# Copyright (c) 2022 Victor Suarez Rovere <[email protected]> | ||
# Copyright (c) 2024 Lone Dynamics Corporation <[email protected]> | ||
# | ||
# SPDX-License-Identifier: BSD-2-Clause | ||
# | ||
|
||
import os | ||
import sys | ||
import json | ||
|
||
from migen import * | ||
|
||
from litex.gen import * | ||
|
||
from litex_boards.platforms import machdyne_mozart_mx2 | ||
|
||
from litex.build.io import DDROutput | ||
|
||
from migen.genlib.resetsync import AsyncResetSynchronizer | ||
|
||
from litex.soc.cores.clock import * | ||
from litex.soc.cores.usb_ohci import USBOHCI | ||
from litex.soc.cores.video import VideoS7HDMIPHY | ||
|
||
from litex.soc.integration.soc_core import * | ||
from litex.soc.integration.builder import * | ||
from litex.soc.interconnect.csr_eventmanager import * | ||
|
||
from litedram.phy import s7ddrphy | ||
from litedram.modules import MT41J256M16 | ||
|
||
from litex.soc.integration.soc import SoCRegion | ||
|
||
# CRG --------------------------------------------------------------------------------------------- | ||
|
||
class _CRG(LiteXModule): | ||
def __init__(self, platform, sys_clk_freq): | ||
self.rst = Signal() | ||
self.cd_por = ClockDomain() | ||
self.cd_sys = ClockDomain() | ||
self.cd_sys2x = ClockDomain() | ||
self.cd_sys4x = ClockDomain() | ||
self.cd_sys4x_dqs = ClockDomain() | ||
self.cd_init = ClockDomain() | ||
self.cd_eth = ClockDomain() | ||
self.cd_video = ClockDomain() | ||
self.cd_video5x = ClockDomain() | ||
self.cd_idelay = ClockDomain() | ||
self.cd_usb_12 = ClockDomain() | ||
self.cd_usb = ClockDomain() | ||
self.cd_usb_48 = ClockDomain() | ||
|
||
|
||
self.stop = Signal() | ||
self.reset = Signal() | ||
|
||
# Clk / Rst | ||
clk48 = platform.request("clk48") | ||
clk50 = platform.request("clk50") | ||
|
||
# Power on reset | ||
por_count = Signal(16, reset=2**16-1) | ||
por_done = Signal() | ||
self.comb += self.cd_por.clk.eq(clk48) | ||
self.comb += por_done.eq(por_count == 0) | ||
self.sync.por += If(~por_done, por_count.eq(por_count - 1)) | ||
|
||
# PLL | ||
self.pll = pll = S7PLL() | ||
self.comb += pll.reset.eq(~por_done | self.rst) | ||
pll.register_clkin(clk50, 50e6) | ||
pll.create_clkout(self.cd_sys, sys_clk_freq) | ||
pll.create_clkout(self.cd_sys2x, 2*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.idelayctrl = S7IDELAYCTRL(self.cd_idelay) | ||
|
||
self.pll2 = pll2 = S7PLL() | ||
pll2.register_clkin(clk50, 50e6) | ||
pll2.create_clkout(self.cd_eth, 50e6) | ||
pll2.create_clkout(self.cd_video, 25e6) | ||
pll2.create_clkout(self.cd_video5x, 125e6) | ||
|
||
self.cd_usb_48 = self.cd_usb | ||
|
||
self.pll3 = pll3 = S7PLL() | ||
self.comb += pll3.reset.eq(~por_done) | ||
pll3.register_clkin(clk48, 48e6) | ||
pll3.create_clkout(self.cd_usb, 48e6) | ||
pll3.create_clkout(self.cd_usb_12, 12e6) | ||
|
||
# BaseSoC ------------------------------------------------------------------------------------------ | ||
|
||
class BaseSoC(SoCCore): | ||
mem_map = {**SoCCore.mem_map, **{ | ||
"usb_ohci": 0xc0000000, | ||
}} | ||
def __init__(self, revision="v0", variant="a7-35", toolchain="vivado", sys_clk_freq=int(75e6), with_usb_host=False, with_ethernet=False, with_xadc=False, **kwargs): | ||
platform = machdyne_mozart_mx2.Platform(revision=revision, variant=variant, toolchain=toolchain) | ||
|
||
# CRG -------------------------------------------------------------------------------------- | ||
self.crg = _CRG(platform, sys_clk_freq) | ||
|
||
# SoCCore ---------------------------------------------------------------------------------- | ||
SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on Mozart MX1", **kwargs) | ||
|
||
# DRAM ------------------------------------------------------------------------------------- | ||
if not self.integrated_main_ram_size: | ||
self.ddrphy = s7ddrphy.A7DDRPHY(platform.request("ddram"), | ||
memtype = "DDR3", | ||
nphases = 4, | ||
sys_clk_freq = sys_clk_freq) | ||
self.add_sdram("sdram", | ||
phy = self.ddrphy, | ||
module = MT41J256M16(sys_clk_freq, "1:4"), | ||
l2_cache_size = kwargs.get("l2_size", 8192) | ||
) | ||
|
||
# XADC ------------------------------------------------------------------------------------- | ||
if with_xadc: | ||
self.xadc = XADC() | ||
|
||
# SPI Flash -------------------------------------------------------------------------------- | ||
from litespi.modules import W25Q32 | ||
from litespi.opcodes import SpiNorFlashOpCodes as Codes | ||
self.add_spi_flash(mode="4x", module=W25Q32(Codes.READ_1_1_1), with_master=False) | ||
|
||
# DDMI Framebuffer ------------------------------------------------------------------------------------- | ||
self.videophy = VideoS7HDMIPHY(platform.request("ddmi"), clock_domain="video") | ||
self.add_video_framebuffer(phy=self.videophy, timings="640x480@60Hz", clock_domain="video", format="rgb565") | ||
|
||
# USB Host --------------------------------------------------------------------------------- | ||
if with_usb_host: | ||
self.usb_ohci = USBOHCI(platform, platform.request("usb_host"), usb_clk_freq=int(48e6)) | ||
self.bus.add_slave("usb_ohci_ctrl", self.usb_ohci.wb_ctrl, region=SoCRegion(origin=self.mem_map["usb_ohci"], size=0x100000, cached=False)) | ||
self.dma_bus.add_master("usb_ohci_dma", master=self.usb_ohci.wb_dma) | ||
self.comb += self.cpu.interrupt[16].eq(self.usb_ohci.interrupt) | ||
|
||
# Ethernet --------------------------------------------------------------------------------- | ||
if with_ethernet: | ||
from liteeth.phy.rmii import LiteEthPHYRMII | ||
self.ethphy = LiteEthPHYRMII( | ||
clock_pads = None, | ||
pads = platform.request("eth"), | ||
with_hw_init_reset = True, | ||
refclk_cd = "eth") | ||
self.add_ethernet(phy=self.ethphy) | ||
|
||
# Build -------------------------------------------------------------------------------------------- | ||
|
||
def main(): | ||
from litex.build.parser import LiteXArgumentParser | ||
parser = LiteXArgumentParser(platform=machdyne_mozart_mx2.Platform, description="LiteX SoC on Mozart MX2.") | ||
parser.add_argument("--sys-clk-freq", default=75e6, help="System clock frequency.") | ||
parser.add_argument("--revision", default="v0", help="Board Revision (v0).") | ||
parser.add_argument("--with-sdcard", action="store_true", help="Enable SDCard support.") | ||
parser.add_argument("--with-spi-sdcard", action="store_true", help="Enable SPI-mode SDCard support.") | ||
parser.add_argument("--with-usb-host", action="store_true", help="Enable USB host support.") | ||
parser.add_argument("--with-ethernet", action="store_true", help="Enable ethernet support.") | ||
|
||
args = parser.parse_args() | ||
|
||
soc = BaseSoC( | ||
toolchain = args.toolchain, | ||
revision = args.revision, | ||
sys_clk_freq = int(float(args.sys_clk_freq)), | ||
with_usb_host = args.with_usb_host, | ||
with_ethernet = args.with_ethernet, | ||
**parser.soc_argdict) | ||
|
||
if args.with_sdcard: | ||
soc.add_sdcard() | ||
|
||
if args.with_spi_sdcard: | ||
soc.add_spi_sdcard() | ||
|
||
builder = Builder(soc, **parser.builder_argdict) | ||
|
||
if args.build: | ||
builder.build(**parser.toolchain_argdict) | ||
|
||
if __name__ == "__main__": | ||
main() |