Merge pull request #243 from tweakoz/master

add FPGA Boards (Digilent CMOD A7, Digilent Nexys 4, Micronova Mercury2)
This commit is contained in:
enjoy-digital 2021-07-27 12:17:04 +02:00 committed by GitHub
commit 369d2cf49d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 968 additions and 0 deletions

View File

@ -0,0 +1,80 @@
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2018 William D. Jones <thor0505@comcast.net>
# Copyright (c) 2020 Staf Verhaegen <staf@fibraservi.eu>
# SPDX-License-Identifier: BSD-2-Clause
from litex.build.generic_platform import Pins, Subsignal, IOStandard, Misc
from litex.build.xilinx import XilinxPlatform
from litex.build.openocd import OpenOCD
# IOs ----------------------------------------------------------------------------------------------
_io = [
# Clk / Rst
("clk12", 0, Pins("L17"), IOStandard("LVCMOS33")),
## Buttons
("cpu_reset", 0, Pins("A18"), IOStandard("LVCMOS33")),
("user_btn", 0, Pins("B18"), IOStandard("LVCMOS33")),
# Leds
("user_led", 0, Pins("A17"), IOStandard("LVCMOS33")),
("user_led", 1, Pins("C16"), IOStandard("LVCMOS33")),
("rgb_led", 0,
Subsignal("r", Pins("C17")),
Subsignal("g", Pins("B16")),
Subsignal("b", Pins("B17")),
IOStandard("LVCMOS33"),
),
# Serial
("serial", 0,
Subsignal("tx", Pins("J18")),
Subsignal("rx", Pins("J17")),
IOStandard("LVCMOS33")),
("issiram", 0,
Subsignal(
"addr",
Pins("M18 M19 K17 N17 P17 P18 R18 W19",
"U19 V19 W18 T17 T18 U17 U18 V16",
"W16 W17 V15"),
IOStandard("LVCMOS33")),
Subsignal(
"data",
Pins("W15 W13 W14 U15 U16 V13 V14 U14"),
IOStandard("LVCMOS33")),
Subsignal("wen", Pins("R19"), IOStandard("LVCMOS33")),
Subsignal("cen", Pins("N19"), IOStandard("LVCMOS33")),
Misc("SLEW=FAST"),
),
]
# Connectors ---------------------------------------------------------------------------------------
_connectors = [
]
# Platform -----------------------------------------------------------------------------------------
class Xc7A35t_Platform(XilinxPlatform):
def __init__(self, io, conns ):
XilinxPlatform.__init__(self, "xc7a35t-cpg236-1", io, conns, toolchain="vivado")
def do_finalize(self,fragment):
self.add_period_constraint(self.lookup_request("clk12", loose=True), self.default_clk_period)
def get_platform(base_platform):
class the_platform(base_platform):
def __init__(self):
self.default_clk_name = "clk12"
self.default_clk_period = 1e9/12e6
base_platform.__init__(self,_io, _connectors)
def do_finalize(self, fragment):
base_platform.do_finalize(self, fragment)
return the_platform()

View File

@ -0,0 +1,229 @@
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2018-2019 Florent Kermarrec <florent@enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause
from litex.build.generic_platform import *
from litex.build.xilinx import XilinxPlatform, VivadoProgrammer
from litex.build.openocd import OpenOCD
# IOs ----------------------------------------------------------------------------------------------
_io = [
# Clk / Rst
("clk100", 0, Pins("E3"), IOStandard("LVCMOS33")),
("cpu_reset", 0, Pins("C12"), IOStandard("LVCMOS33")),
# Leds
("user_led", 0, Pins("T8"), IOStandard("LVCMOS33")),
("user_led", 1, Pins("V9"), IOStandard("LVCMOS33")),
("user_led", 2, Pins("R8"), IOStandard("LVCMOS33")),
("user_led", 3, Pins("T6"), IOStandard("LVCMOS33")),
("user_led", 4, Pins("T5"), IOStandard("LVCMOS33")),
("user_led", 5, Pins("T4"), IOStandard("LVCMOS33")),
("user_led", 6, Pins("U7"), IOStandard("LVCMOS33")),
("user_led", 7, Pins("U6"), IOStandard("LVCMOS33")),
("user_led", 8, Pins("V4"), IOStandard("LVCMOS33")),
("user_led", 9, Pins("U3"), IOStandard("LVCMOS33")),
("user_led", 10, Pins("V1"), IOStandard("LVCMOS33")),
("user_led", 11, Pins("R1"), IOStandard("LVCMOS33")),
("user_led", 12, Pins("P5"), IOStandard("LVCMOS33")),
("user_led", 13, Pins("U1"), IOStandard("LVCMOS33")),
("user_led", 14, Pins("R2"), IOStandard("LVCMOS33")),
("user_led", 15, Pins("P2"), IOStandard("LVCMOS33")),
# 7SEG DISPLAY
("segled_an", 0, Pins("N6"), IOStandard("LVCMOS33")),
("segled_an", 1, Pins("M6"), IOStandard("LVCMOS33")),
("segled_an", 2, Pins("M3"), IOStandard("LVCMOS33")),
("segled_an", 3, Pins("N5"), IOStandard("LVCMOS33")),
("segled_an", 4, Pins("N2"), IOStandard("LVCMOS33")),
("segled_an", 5, Pins("N4"), IOStandard("LVCMOS33")),
("segled_an", 6, Pins("L1"), IOStandard("LVCMOS33")),
("segled_an", 7, Pins("M1"), IOStandard("LVCMOS33")),
("segled_ca", 0, Pins("L3"), IOStandard("LVCMOS33")),
("segled_cb", 0, Pins("N1"), IOStandard("LVCMOS33")),
("segled_cc", 0, Pins("L5"), IOStandard("LVCMOS33")),
("segled_cd", 0, Pins("L4"), IOStandard("LVCMOS33")),
("segled_ce", 0, Pins("K3"), IOStandard("LVCMOS33")),
("segled_cf", 0, Pins("M2"), IOStandard("LVCMOS33")),
("segled_cg", 0, Pins("L6"), IOStandard("LVCMOS33")),
("segled_dp", 0, Pins("M4"), IOStandard("LVCMOS33")),
("rgb_led", 0,
Subsignal("r", Pins("K6")),
Subsignal("g", Pins("H6")),
Subsignal("b", Pins("L16")),
IOStandard("LVCMOS33"),
),
("rgb_led", 1,
Subsignal("r", Pins("K5")),
Subsignal("g", Pins("F13")),
Subsignal("b", Pins("F6")),
IOStandard("LVCMOS33"),
),
# Switches
("user_sw", 0, Pins("U9"), IOStandard("LVCMOS33")),
("user_sw", 1, Pins("U8"), IOStandard("LVCMOS33")),
("user_sw", 2, Pins("R7"), IOStandard("LVCMOS33")),
("user_sw", 3, Pins("R6"), IOStandard("LVCMOS33")),
("user_sw", 4, Pins("R5"), IOStandard("LVCMOS33")),
("user_sw", 5, Pins("V7"), IOStandard("LVCMOS33")),
("user_sw", 6, Pins("V6"), IOStandard("LVCMOS33")),
("user_sw", 7, Pins("V5"), IOStandard("LVCMOS33")),
("user_sw", 8, Pins("U4"), IOStandard("LVCMOS33")),
("user_sw", 9, Pins("V2"), IOStandard("LVCMOS33")),
("user_sw", 10, Pins("U2"), IOStandard("LVCMOS33")),
("user_sw", 11, Pins("T3"), IOStandard("LVCMOS33")),
("user_sw", 12, Pins("T1"), IOStandard("LVCMOS33")),
("user_sw", 13, Pins("R3"), IOStandard("LVCMOS33")),
("user_sw", 14, Pins("P3"), IOStandard("LVCMOS33")),
("user_sw", 15, Pins("P4"), IOStandard("LVCMOS33")),
# Buttons
("user_btn", 0, Pins("T16"), IOStandard("LVCMOS33")),
("user_btn", 1, Pins("R10"), IOStandard("LVCMOS33")),
("user_btn", 2, Pins("F15"), IOStandard("LVCMOS33")),
("user_btn", 3, Pins("V10"), IOStandard("LVCMOS33")),
("user_btn", 4, Pins("E16"), IOStandard("LVCMOS33")),
# Serial
("serial", 0,
Subsignal("tx", Pins("D4")),
Subsignal("rx", Pins("C4")),
IOStandard("LVCMOS33"),
),
# SDCard
("spisdcard", 0,
Subsignal("rst", Pins("E2")),
Subsignal("clk", Pins("B1")),
Subsignal("mosi", Pins("C1"), Misc("PULLUP True")),
Subsignal("cs_n", Pins("D2"), Misc("PULLUP True")),
Subsignal("miso", Pins("C2"), Misc("PULLUP True")),
Misc("SLEW=FAST"),
IOStandard("LVCMOS33"),
),
("sdcard", 0,
Subsignal("rst", Pins("E2"), Misc("PULLUP True")),
Subsignal("data", Pins("C2 E1 F1 D2"), Misc("PULLUP True")),
Subsignal("cmd", Pins("C1"), Misc("PULLUP True")),
Subsignal("clk", Pins("B1")),
Subsignal("cd", Pins("A1")),
Misc("SLEW=FAST"),
IOStandard("LVCMOS33"),
),
("cellularram", 0,
Subsignal(
"addr",
Pins("J18 H17 H15 J17 H16 K15 K13 N15 V16 U14 V14 V12 P14 U16 R15 N14 N16 M13 V17 U17 T10 M16 U13"),
),
Subsignal(
"data",
Pins("R12 T11 U12 R13 U18 R17 T18 R18 F18 G18 G17 M18 M17 P18 N17 P17"),
),
Subsignal("oen", Pins("H14")),
Subsignal("wen", Pins("R11")),
Subsignal("clk", Pins("T15")),
Subsignal("adv", Pins("T13")),
Subsignal("wait", Pins("T14")),
Subsignal("cen", Pins("L18")),
Subsignal("ub", Pins("J13")),
Subsignal("lb", Pins("J15")),
Subsignal("cre", Pins("J14")),
Misc("SLEW=FAST"),
IOStandard("LVCMOS33"),
),
# RMII Ethernet
("eth_clocks", 0,
Subsignal("ref_clk", Pins("D5")),
IOStandard("LVCMOS33"),
),
("aud_pwm", 0,
Subsignal("pwm_out", Pins("A11")),
Subsignal("enable", Pins("D12")),
IOStandard("LVCMOS33"),
),
("eth", 0,
Subsignal("rst_n", Pins("B3")),
Subsignal("rx_data", Pins("C11 D10")),
Subsignal("crs_dv", Pins("D9")),
Subsignal("tx_en", Pins("B9")),
Subsignal("tx_data", Pins("A10 A8")),
Subsignal("mdc", Pins("C9")),
Subsignal("mdio", Pins("A9")),
Subsignal("rx_er", Pins("C10")),
Subsignal("int_n", Pins("B8")),
IOStandard("LVCMOS33")
),
# VGA
("vga", 0,
Subsignal("hsync_n", Pins("B11")),
Subsignal("vsync_n", Pins("B12")),
Subsignal("r", Pins("A4 C5 B4 A3")),
Subsignal("g", Pins("A6 B6 A5 C6")),
Subsignal("b", Pins("D7 C7 B7 D8")),
IOStandard("LVCMOS33")
),
]
# Connectors ---------------------------------------------------------------------------------------
_connectors = [
("pmoda", "B13 F14 D17 E17 G13 C17 D18 E18"),
("pmodb", "G14 P15 V11 V15 K16 R16 T9 U11"),
("pmodc", "K2 E7 J3 J4 K1 E6 J2 G6"),
("pmodd", "H4 H1 G1 G3 H2 G4 G2 F3"),
("pmodxdac", "A13 A15 B16 B18 A14 A16 B17 A18"),
]
# PMODS --------------------------------------------------------------------------------------------
def sdcard_pmod_io(pmod):
return [
# SDCard PMOD:
# - https://store.digilentinc.com/pmod-microsd-microsd-card-slot/
("spisdcard", 0,
Subsignal("clk", Pins(f"{pmod}:3")),
Subsignal("mosi", Pins(f"{pmod}:1"), Misc("PULLUP True")),
Subsignal("cs_n", Pins(f"{pmod}:0"), Misc("PULLUP True")),
Subsignal("miso", Pins(f"{pmod}:2"), Misc("PULLUP True")),
Misc("SLEW=FAST"),
IOStandard("LVCMOS33"),
),
("sdcard", 0,
Subsignal("data", Pins(f"{pmod}:2 {pmod}:4 {pmod}:5 {pmod}:0"), Misc("PULLUP True")),
Subsignal("cmd", Pins(f"{pmod}:1"), Misc("PULLUP True")),
Subsignal("clk", Pins(f"{pmod}:3")),
Subsignal("cd", Pins(f"{pmod}:6")),
Misc("SLEW=FAST"),
IOStandard("LVCMOS33"),
),
]
_sdcard_pmod_io = sdcard_pmod_io("pmodd") # SDCARD PMOD on JD.
# Platform -----------------------------------------------------------------------------------------
class Platform(XilinxPlatform):
default_clk_name = "clk100"
default_clk_period = 1e9/100e6
def __init__(self):
XilinxPlatform.__init__(self, "xc7a100t-CSG324-1", _io, _connectors, toolchain="vivado")
self.add_platform_command("set_property INTERNAL_VREF 0.750 [get_iobanks 34]")
def create_programmer(self):
return OpenOCD("openocd_xc7_ft2232.cfg", "bscan_spi_xc7a100t.bit")
def do_finalize(self, fragment):
XilinxPlatform.do_finalize(self, fragment)
self.add_period_constraint(self.lookup_request("clk100", loose=True), 1e9/100e6)
self.add_period_constraint(self.lookup_request("eth_clocks:ref_clk", loose=True), 1e9/50e6)

View File

@ -0,0 +1,62 @@
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2018 William D. Jones <thor0505@comcast.net>
# Copyright (c) 2020 Staf Verhaegen <staf@fibraservi.eu>
# SPDX-License-Identifier: BSD-2-Clause
from litex.build.generic_platform import Pins, Subsignal, IOStandard, Misc
from litex.build.xilinx import XilinxPlatform
from litex.build.openocd import OpenOCD
# IOs ----------------------------------------------------------------------------------------------
_io = [
# Clk / Rst
("clk50", 0, Pins("N14"), IOStandard("LVCMOS33")),
# Leds
("user_led", 0, Pins("M1"), IOStandard("LVCMOS33")),
("user_led", 1, Pins("A14"), IOStandard("LVCMOS33")),
("user_led", 2, Pins("A13"), IOStandard("LVCMOS33")),
# Serial
("serial", 0,
Subsignal("tx", Pins("N11")), # BDBUS1
Subsignal("rx", Pins("E11")), # BDBUS0
IOStandard("LVCMOS33")
),
("issiram", 0,
Subsignal("addr", Pins("M4 N3 N4 P3 M5 E5 D5 D3 B7 B4 J4 H4 H3 G4 E6 A7 A5 A4 C4"), IOStandard("LVCMOS33")),
Subsignal("data", Pins("L5 L3 L4 R2 F3 F4 E3 D6"), IOStandard("LVCMOS33")),
Subsignal("wen", Pins("R1"), IOStandard("LVCMOS33")),
Subsignal("cen", Pins("M6"), IOStandard("LVCMOS33")),
Misc("SLEW=FAST"),
),
]
# Connectors ---------------------------------------------------------------------------------------
_connectors = [
]
# Platform -----------------------------------------------------------------------------------------
class Xc7A35t_Platform(XilinxPlatform):
def __init__(self, io, conns ):
XilinxPlatform.__init__(self, "xc7a35tftg256-1", io, conns, toolchain="vivado")
def do_finalize(self,fragment):
self.add_period_constraint(self.lookup_request("clk50", loose=True), self.default_clk_period)
def get_platform(base_platform):
class the_platform(base_platform):
def __init__(self):
self.default_clk_name = "clk50"
self.default_clk_period = 1e9/50e6
base_platform.__init__(self,_io, _connectors)
def do_finalize(self, fragment):
base_platform.do_finalize(self, fragment)
return the_platform()

View File

@ -0,0 +1,174 @@
#!/usr/bin/env python3
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2020 Florent Kermarrec <florent@enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause
import os
import sys
import argparse
from migen import *
from litex.build.io import CRG
from litex.build.xilinx.vivado import vivado_build_args, vivado_build_argdict
from litex_boards.platforms import digilent_cmod_a7
#from litex.soc.cores.spi_flash import SpiFlash
from litex.soc.cores.clock import *
from litex.soc.integration.soc_core import *
from litex.soc.integration.soc import SoCRegion
from litex.soc.integration.builder import *
from litex.soc.cores.led import LedChaser
from litex.soc.interconnect import wishbone
from litex.soc.integration.soc import colorer
kB = 1024
mB = 1024*kB
class _CRG(Module):
def __init__(self, platform, sys_clk_freq):
self.rst = Signal()
self.cpu_reset = 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)
# # #
plls_clk12 = platform.request("clk12")
rst_n = platform.request("cpu_reset")
self.comb += self.cpu_reset.eq(rst_n)
self.submodules.pll = pll = S7MMCM(speedgrade=-1)
self.comb += pll.reset.eq(self.cpu_reset | self.rst)
pll.register_clkin(plls_clk12, 12e6)
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)
platform.add_false_path_constraints(self.cd_sys.clk, pll.clkin) # Ignore sys_clk to pll.clkin path created by SoC's rst.
# AsyncSRAM ------------------------------------------------------------------------------------------
class AsyncSRAM(Module):
def __init__(self, platform, size):
addr_width = size//8
data_width = 8
self.bus = wishbone.Interface(data_width=data_width,adr_width=addr_width)
issiram = platform.request("issiram")
addr = issiram.addr
data = issiram.data
wen = issiram.wen
cen = issiram.cen
########################
tristate_data = TSTriple(data_width)
self.specials += tristate_data.get_tristate(data)
########################
chip_ena = self.bus.cyc & self.bus.stb & self.bus.sel[0]
write_ena = (chip_ena & self.bus.we)
########################
# external write enable,
# external chip enable,
# internal tristate write enable
########################
self.comb += [
cen.eq(~chip_ena),
wen.eq(~write_ena),
tristate_data.oe.eq(write_ena)
]
########################
# address and data
########################
self.comb += [
addr.eq(self.bus.adr[:addr_width]),
self.bus.dat_r.eq(tristate_data.i[:data_width]),
tristate_data.o.eq(self.bus.dat_w[:data_width])
]
########################
# generate ack
########################
self.sync += [
self.bus.ack.eq(self.bus.cyc & self.bus.stb & ~self.bus.ack),
]
########################
def addAsyncSram(soc, platform, name, origin, size):
ram_bus = wishbone.Interface(data_width=soc.bus.data_width)
ram = AsyncSRAM(platform,size)
soc.bus.add_slave(name, ram.bus, SoCRegion(origin=origin, size=size, mode="rw"))
soc.check_if_exists(name)
soc.logger.info("ISSIRAM {} {} {}.".format(
colorer(name),
colorer("added", color="green"),
soc.bus.regions[name]))
setattr(soc.submodules, name, ram)
# BaseSoC ------------------------------------------------------------------------------------------
class BaseSoC(SoCCore):
def __init__(self,
variant="a7-35",
toolchain="vivado",
sys_clk_freq=int(100e6),
ident_version=True,
with_jtagbone=True,
with_mapped_flash=False,
**kwargs):
xc7a35t_base = digilent_cmod_a7.Xc7A35t_Platform
platform = digilent_cmod_a7.get_platform(xc7a35t_base)
# SoCCore ----------------------------------------------------------------------------------
SoCCore.__init__(self, platform, sys_clk_freq,
ident = "LiteX SoC on Digilent CmodA7",
ident_version = True,
**kwargs)
# CRG --------------------------------------------------------------------------------------
self.submodules.crg = _CRG(platform, sys_clk_freq)
addAsyncSram(self,platform,"main_ram",0x40000000,512*1024)
# Leds -------------------------------------------------------------------------------------
self.submodules.leds = LedChaser(
pads = platform.request_all("user_led"),
sys_clk_freq = sys_clk_freq)
# Build --------------------------------------------------------------------------------------------
def main():
parser = argparse.ArgumentParser(description="LiteX SoC on Arty A7")
parser.add_argument("--toolchain", default="vivado", help="Toolchain use to build (default: vivado)")
parser.add_argument("--build", action="store_true", help="Build bitstream")
parser.add_argument("--load", action="store_true", help="Load bitstream")
parser.add_argument("--variant", default="a7-35", help="Board variant: a7-35 (default) or a7-100")
parser.add_argument("--sys-clk-freq", default=48e6, help="System clock frequency (default: 48MHz)")
builder_args(parser)
soc_core_args(parser)
vivado_build_args(parser)
args = parser.parse_args()
soc = BaseSoC(
variant = args.variant,
toolchain = args.toolchain,
sys_clk_freq = int(float(args.sys_clk_freq)),
**soc_core_argdict(args)
)
builder_argd = builder_argdict(args)
builder = Builder(soc, **builder_argd)
builder_kwargs = vivado_build_argdict(args) if args.toolchain == "vivado" else {}
builder.build(**builder_kwargs, run=args.build)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,248 @@
#!/usr/bin/env python3
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2020 Florent Kermarrec <florent@enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause
import os
import sys
import argparse
import math
from migen import *
from litex.build.io import CRG
from litex_boards.platforms import digilent_nexys4
#from litex.soc.cores.spi_flash import SpiFlash
from litex.soc.cores.clock import *
from litex.soc.integration.soc_core import *
from litex.soc.integration.soc import SoCRegion
from litex.soc.integration.builder import *
from litex.soc.cores.led import LedChaser
from litex.soc.interconnect import wishbone
from litex.soc.integration.soc import colorer
from litex.soc.cores.video import VideoVGAPHY
from liteeth.phy.rmii import LiteEthPHYRMII
# CRG ----------------------------------------------------------------------------------------------
class _CRG(Module):
def __init__(self, platform, sys_clk_freq):
self.rst = Signal()
self.clock_domains.cd_sys = ClockDomain()
self.clock_domains.cd_sys2x = ClockDomain(reset_less=True)
self.clock_domains.cd_sys2x_dqs = ClockDomain(reset_less=True)
self.clock_domains.cd_idelay = ClockDomain()
self.clock_domains.cd_eth = ClockDomain()
self.clock_domains.cd_vga = ClockDomain(reset_less=True)
# # #
self.submodules.pll = pll = S7MMCM(speedgrade=-1)
self.comb += pll.reset.eq(~platform.request("cpu_reset") | self.rst)
pll.register_clkin(platform.request("clk100"), 100e6)
pll.create_clkout(self.cd_sys, sys_clk_freq)
pll.create_clkout(self.cd_sys2x, 2*sys_clk_freq)
pll.create_clkout(self.cd_sys2x_dqs, 2*sys_clk_freq, phase=90)
pll.create_clkout(self.cd_idelay, 200e6)
pll.create_clkout(self.cd_eth, 50e6)
pll.create_clkout(self.cd_vga, 40e6)
platform.add_false_path_constraints(self.cd_sys.clk, pll.clkin) # Ignore sys_clk to pll.clkin path created by SoC's rst.
self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_idelay)
# CellularRAM (https://media.digikey.com/PDF/Data%20Sheets/Micron%20Technology%20Inc%20PDFs/MT45W8MW16BGX.pdf)
class CellularRAM(Module):
def __init__(self, soc, platform):
sys_clk_freq = soc.sys_clk_freq
addr_width = 23
data_width = 16
delay_for_70ns = (70e-9) / (1.0/sys_clk_freq)
delay_for_70ns = int(math.ceil(delay_for_70ns))+1
#print("sys_clk_freq<%g> delay_for_70ns<%g>\n"%(sys_clk_freq,delay_for_70ns))
self.bus = wishbone.Interface(data_width=data_width,adr_width=addr_width)
self.delaycounter = Signal(5)
cellram = platform.request("cellularram")
addr = cellram.addr
data = cellram.data
wen = cellram.wen
oen = cellram.oen
cen = cellram.cen
clk = cellram.clk
cre = cellram.cre
adv = cellram.adv # address valid (low)
lb = cellram.lb
ub = cellram.ub
########################
tristate_data = TSTriple(data_width)
self.specials += tristate_data.get_tristate(data)
########################
i_rst = ResetSignal("sys")
fsm = FSM(reset_state="RESET")
fsm = ResetInserter()(fsm)
self.submodules.fsm = fsm
self.sync += fsm.reset.eq(i_rst)
########################
fsm.act("RESET",
NextState("INIT"))
########################
fsm.act("INIT",
NextValue(self.delaycounter,0),
NextValue(self.bus.ack,0),
NextValue(cen,1),
NextValue(adv,1),
NextValue(lb,1),
NextValue(ub,1),
NextValue(clk,0),
NextValue(cre,0),
NextValue(tristate_data.oe,0),
NextState("IDLE"))
########################
fsm.act("IDLE",
If(self.bus.stb & self.bus.cyc,
NextValue(lb,~self.bus.sel[0]),
NextValue(ub,~self.bus.sel[1]),
NextValue(self.delaycounter,0),
NextValue(cen,0),
NextValue(adv,0),
NextValue(addr,self.bus.adr[:addr_width]),
If(self.bus.we,
NextValue(wen,0),
NextValue(oen,1),
NextValue(tristate_data.oe,1),
NextValue(tristate_data.o,self.bus.dat_w[:data_width]),
NextState("WRITE")
).Else(
NextValue(wen,1),
NextValue(oen,0),
NextValue(tristate_data.oe,0),
NextState("READ")
)
)
)
########################
fsm.act("WRITE",
NextValue(self.delaycounter,self.delaycounter+1),
If(self.delaycounter==delay_for_70ns,
NextValue(self.bus.ack,1),
NextState("INIT"))
)
########################
fsm.act("READ",
NextValue(self.delaycounter,self.delaycounter+1),
NextValue(self.bus.dat_r,tristate_data.i[:data_width]),
If(self.delaycounter==delay_for_70ns,
NextValue(self.bus.ack,1),
NextState("INIT"))
)
########################
def addCellularRAM(soc, platform, name, origin):
size = 16*1024*1024
ram_bus = wishbone.Interface(data_width=soc.bus.data_width)
ram = CellularRAM(soc,platform)
soc.bus.add_slave(name, ram.bus, SoCRegion(origin=origin, size=size, mode="rw"))
soc.check_if_exists(name)
soc.logger.info("CELLULARRAM {} {} {}.".format(
colorer(name),
colorer("added", color="green"),
soc.bus.regions[name]))
setattr(soc.submodules, name, ram)
# BaseSoC ------------------------------------------------------------------------------------------
class BaseSoC(SoCCore):
def __init__(self, sys_clk_freq=int(75e6), with_ethernet=False, with_etherbone=False, with_video_terminal=False, with_video_framebuffer=False, **kwargs):
platform = digilent_nexys4.Platform()
# SoCCore ----------------------------------_-----------------------------------------------
SoCCore.__init__(self, platform, sys_clk_freq,
ident = "LiteX SoC on Nexys4",
**kwargs)
# CRG --------------------------------------------------------------------------------------
self.submodules.crg = _CRG(platform, sys_clk_freq)
# Cellular RAM -------------------------------------------------------------------------------
addCellularRAM(self,platform,"main_ram",0x40000000)
# Ethernet / Etherbone ---------------------------------------------------------------------
if with_ethernet or with_etherbone:
self.submodules.ethphy = LiteEthPHYRMII(
clock_pads = self.platform.request("eth_clocks"),
pads = self.platform.request("eth"))
if with_ethernet:
self.add_ethernet(phy=self.ethphy)
if with_etherbone:
self.add_etherbone(phy=self.ethphy)
# Video ------------------------------------------------------------------------------------
if with_video_terminal or with_video_framebuffer:
self.submodules.videophy = VideoVGAPHY(platform.request("vga"), clock_domain="vga")
if with_video_terminal:
self.add_video_terminal(phy=self.videophy, timings="800x600@60Hz", clock_domain="vga")
if with_video_framebuffer:
self.add_video_framebuffer(phy=self.videophy, timings="800x600@60Hz", clock_domain="vga")
# Leds -------------------------------------------------------------------------------------
self.submodules.leds = LedChaser(
pads = platform.request_all("user_led"),
sys_clk_freq = sys_clk_freq)
# Build --------------------------------------------------------------------------------------------
def main():
parser = argparse.ArgumentParser(description="LiteX SoC on Nexys4")
parser.add_argument("--build", action="store_true", help="Build bitstream")
parser.add_argument("--load", action="store_true", help="Load bitstream")
parser.add_argument("--sys-clk-freq", default=75e6, help="System clock frequency (default: 75MHz)")
ethopts = parser.add_mutually_exclusive_group()
ethopts.add_argument("--with-ethernet", action="store_true", help="Enable Ethernet support")
ethopts.add_argument("--with-etherbone", action="store_true", help="Enable Etherbone support")
sdopts = parser.add_mutually_exclusive_group()
sdopts.add_argument("--with-spi-sdcard", action="store_true", help="Enable SPI-mode SDCard support")
sdopts.add_argument("--with-sdcard", action="store_true", help="Enable SDCard support")
viopts = parser.add_mutually_exclusive_group()
viopts.add_argument("--with-video-terminal", action="store_true", help="Enable Video Terminal (VGA)")
viopts.add_argument("--with-video-framebuffer", action="store_true", help="Enable Video Framebuffer (VGA)")
builder_args(parser)
soc_core_args(parser)
args = parser.parse_args()
soc = BaseSoC(
sys_clk_freq = int(float(args.sys_clk_freq)),
with_ethernet = args.with_ethernet,
with_etherbone = args.with_etherbone,
with_video_terminal = args.with_video_terminal,
with_video_framebuffer = args.with_video_framebuffer,
**soc_core_argdict(args)
)
if args.with_spi_sdcard:
soc.add_spi_sdcard()
if args.with_sdcard:
soc.add_sdcard()
builder = Builder(soc, **builder_argdict(args))
builder.build(run=args.build)
if args.load:
prog = soc.platform.create_programmer()
prog.load_bitstream(os.path.join(builder.gateware_dir, soc.build_name + ".bit"))
if __name__ == "__main__":
main()

View File

@ -0,0 +1,175 @@
#!/usr/bin/env python3
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2020 Florent Kermarrec <florent@enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause
import os
import sys
import argparse
from migen import *
from litex.build.io import CRG
from litex_boards.platforms import micronova_mercury2
from litex.build.xilinx.vivado import vivado_build_args, vivado_build_argdict
#from litex.soc.cores.spi_flash import SpiFlash
from litex.soc.cores.clock import *
from litex.soc.integration.soc_core import *
from litex.soc.integration.soc import SoCRegion
from litex.soc.integration.builder import *
from litex.soc.cores.led import LedChaser
from litex.soc.interconnect import wishbone
from litex.soc.integration.soc import colorer
kB = 1024
mB = 1024*kB
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)
# # #
#plls_reset = platform.request("cpu_reset")
plls_clk50 = platform.request("clk50")
self.submodules.pll = pll = S7MMCM(speedgrade=-1)
self.comb += pll.reset.eq(self.rst)
pll.register_clkin(plls_clk50, 50e6)
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)
platform.add_false_path_constraints(self.cd_sys.clk, pll.clkin) # Ignore sys_clk to pll.clkin path created by SoC's rst.
# AsyncSRAM ------------------------------------------------------------------------------------------
class AsyncSRAM(Module):
def __init__(self, platform, size):
addr_width = size//8
data_width = 8
self.bus = wishbone.Interface(data_width=data_width,adr_width=addr_width)
issiram = platform.request("issiram")
addr = issiram.addr
data = issiram.data
wen = issiram.wen
cen = issiram.cen
########################
tristate_data = TSTriple(data_width)
self.specials += tristate_data.get_tristate(data)
########################
chip_ena = self.bus.cyc & self.bus.stb & self.bus.sel[0]
write_ena = (chip_ena & self.bus.we)
########################
# external write enable,
# external chip enable,
# internal tristate write enable
########################
self.comb += [
cen.eq(~chip_ena),
wen.eq(~write_ena),
tristate_data.oe.eq(write_ena)
]
########################
# address and data
########################
self.comb += [
addr.eq(self.bus.adr[:addr_width]),
self.bus.dat_r.eq(tristate_data.i[:data_width]),
tristate_data.o.eq(self.bus.dat_w[:data_width])
]
########################
# generate ack
########################
self.sync += [
self.bus.ack.eq(self.bus.cyc & self.bus.stb & ~self.bus.ack),
]
########################
def addAsyncSram(soc, platform, name, origin, size):
ram_bus = wishbone.Interface(data_width=soc.bus.data_width)
ram = AsyncSRAM(platform,size)
soc.bus.add_slave(name, ram.bus, SoCRegion(origin=origin, size=size, mode="rw"))
soc.check_if_exists(name)
soc.logger.info("ISSIRAM {} {} {}.".format(
colorer(name),
colorer("added", color="green"),
soc.bus.regions[name]))
setattr(soc.submodules, name, ram)
# BaseSoC ------------------------------------------------------------------------------------------
class BaseSoC(SoCCore):
def __init__(self,
variant="a7-35",
toolchain="vivado",
sys_clk_freq=int(100e6),
ident_version=True,
with_jtagbone=True,
with_mapped_flash=False,
enable_leds = True,
**kwargs):
xc7a35t_base = micronova_mercury2.Xc7A35t_Platform
platform = micronova_mercury2.get_platform(xc7a35t_base)
# SoCCore ----------------------------------------------------------------------------------
SoCCore.__init__(self, platform, sys_clk_freq,
ident = "LiteX SoC on MicroNova Mercury2",
ident_version = True,
**kwargs)
# CRG --------------------------------------------------------------------------------------
self.submodules.crg = _CRG(platform, sys_clk_freq)
addAsyncSram(self,platform,"main_ram",0x40000000,512*1024)
#self.add_timer()
# Leds -------------------------------------------------------------------------------------
if enable_leds:
self.submodules.leds = LedChaser(
pads = platform.request_all("user_led"),
sys_clk_freq = sys_clk_freq)
# Build --------------------------------------------------------------------------------------------
def main():
parser = argparse.ArgumentParser(description="LiteX SoC on MicroNova Mercury2")
parser.add_argument("--toolchain", default="vivado", help="Toolchain use to build (default: vivado)")
parser.add_argument("--build", action="store_true", help="Build bitstream")
parser.add_argument("--load", action="store_true", help="Load bitstream")
parser.add_argument("--variant", default="a7-35", help="Board variant: a7-35 (default) or a7-100")
parser.add_argument("--sys-clk-freq", default=50e6, help="System clock frequency (default: 50MHz)")
builder_args(parser)
soc_core_args(parser)
vivado_build_args(parser)
args = parser.parse_args()
soc = BaseSoC(
variant = args.variant,
toolchain = args.toolchain,
sys_clk_freq = int(float(args.sys_clk_freq)),
**soc_core_argdict(args)
)
builder_argd = builder_argdict(args)
builder = Builder(soc, **builder_argd)
builder_kwargs = vivado_build_argdict(args) if args.toolchain == "vivado" else {}
builder.build(**builder_kwargs, run=args.build)
if __name__ == "__main__":
main()