Bring into line with master
This commit is contained in:
commit
33e202edd4
|
@ -4,7 +4,9 @@
|
|||
# License: BSD
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import math
|
||||
import subprocess
|
||||
import shutil
|
||||
|
||||
|
@ -40,7 +42,7 @@ def _format_lpf(signame, pin, others, resname):
|
|||
return "\n".join(lpf)
|
||||
|
||||
|
||||
def _build_lpf(named_sc, named_pc, build_name):
|
||||
def _build_lpf(named_sc, named_pc, clocks, vns, build_name):
|
||||
lpf = []
|
||||
lpf.append("BLOCK RESETPATHS;")
|
||||
lpf.append("BLOCK ASYNCPATHS;")
|
||||
|
@ -51,7 +53,16 @@ def _build_lpf(named_sc, named_pc, build_name):
|
|||
else:
|
||||
lpf.append(_format_lpf(sig, pins[0], others, resname))
|
||||
if named_pc:
|
||||
lpf.append("\n\n".join(named_pc))
|
||||
lpf.append("\n".join(named_pc))
|
||||
|
||||
# Note: .lpf is only used post-synthesis, Synplify constraints clocks by default to 200MHz.
|
||||
for clk, period in clocks.items():
|
||||
clk_name = vns.get_name(clk)
|
||||
lpf.append("FREQUENCY {} \"{}\" {} MHz;".format(
|
||||
"PORT" if clk_name in [name for name, _, _, _ in named_sc] else "NET",
|
||||
clk_name,
|
||||
str(1e3/period)))
|
||||
|
||||
tools.write_to_file(build_name + ".lpf", "\n".join(lpf))
|
||||
|
||||
# Project (.tcl) -----------------------------------------------------------------------------------
|
||||
|
@ -67,13 +78,15 @@ def _build_tcl(device, sources, vincpaths, build_name):
|
|||
"-synthesis \"synplify\""
|
||||
]))
|
||||
|
||||
def tcl_path(path): return path.replace("\\", "/")
|
||||
|
||||
# Add include paths
|
||||
vincpath = ';'.join(map(lambda x: x.replace('\\', '/'), vincpaths))
|
||||
vincpath = ";".join(map(lambda x: tcl_path(x), vincpaths))
|
||||
tcl.append("prj_impl option {include path} {\"" + vincpath + "\"}")
|
||||
|
||||
# Add sources
|
||||
for filename, language, library in sources:
|
||||
tcl.append("prj_src add \"" + filename.replace("\\", "/") + "\" -work " + library)
|
||||
tcl.append("prj_src add \"{}\" -work {}".format(tcl_path(filename), library))
|
||||
|
||||
# Set top level
|
||||
tcl.append("prj_impl option top \"{}\"".format(build_name))
|
||||
|
@ -89,6 +102,10 @@ def _build_tcl(device, sources, vincpaths, build_name):
|
|||
tcl.append("prj_run Export -impl impl -task Bitgen")
|
||||
if _produces_jedec(device):
|
||||
tcl.append("prj_run Export -impl impl -task Jedecgen")
|
||||
|
||||
# Close project
|
||||
tcl.append("prj_project close")
|
||||
|
||||
tools.write_to_file(build_name + ".tcl", "\n".join(tcl))
|
||||
|
||||
# Script -------------------------------------------------------------------------------------------
|
||||
|
@ -130,6 +147,34 @@ def _run_script(script):
|
|||
if subprocess.call(shell + [script]) != 0:
|
||||
raise OSError("Subprocess failed")
|
||||
|
||||
def _check_timing(build_name):
|
||||
lines = open("impl/{}_impl.par".format(build_name), "r").readlines()
|
||||
runs = [None, None]
|
||||
for i in range(len(lines)-1):
|
||||
if lines[i].startswith("Level/") and lines[i+1].startswith("Cost "):
|
||||
runs[0] = i + 2
|
||||
if lines[i].startswith("* : Design saved.") and runs[0] is not None:
|
||||
runs[1] = i
|
||||
break
|
||||
assert all(map(lambda x: x is not None, runs))
|
||||
|
||||
p = re.compile(r"(^\s*\S+\s+\*?\s+[0-9]+\s+)(\S+)(\s+\S+\s+)(\S+)(\s+.*)")
|
||||
for l in lines[runs[0]:runs[1]]:
|
||||
m = p.match(l)
|
||||
if m is None: continue
|
||||
limit = 1e-8
|
||||
setup = m.group(2)
|
||||
hold = m.group(4)
|
||||
# If there were no freq constraints in lpf, ratings will be dashed.
|
||||
# results will likely be terribly unreliable, so bail
|
||||
assert not setup == hold == "-", "No timing constraints were provided"
|
||||
setup, hold = map(float, (setup, hold))
|
||||
if setup > limit and hold > limit:
|
||||
# At least one run met timing
|
||||
# XXX is this necessarily the run from which outputs will be used?
|
||||
return
|
||||
raise Exception("Failed to meet timing")
|
||||
|
||||
# LatticeDiamondToolchain --------------------------------------------------------------------------
|
||||
|
||||
class LatticeDiamondToolchain:
|
||||
|
@ -149,12 +194,14 @@ class LatticeDiamondToolchain:
|
|||
special_overrides = common.lattice_ecp5_special_overrides
|
||||
|
||||
def __init__(self):
|
||||
self.clocks = {}
|
||||
self.false_paths = set() # FIXME: use it
|
||||
|
||||
def build(self, platform, fragment,
|
||||
build_dir = "build",
|
||||
build_name = "top",
|
||||
run = True,
|
||||
timingstrict = True,
|
||||
**kwargs):
|
||||
|
||||
# Create build directory
|
||||
|
@ -175,7 +222,7 @@ class LatticeDiamondToolchain:
|
|||
platform.add_source(v_file)
|
||||
|
||||
# Generate design constraints file (.lpf)
|
||||
_build_lpf(named_sc, named_pc, build_name)
|
||||
_build_lpf(named_sc, named_pc, self.clocks, v_output.ns, build_name)
|
||||
|
||||
# Generate design script file (.tcl)
|
||||
_build_tcl(platform.device, platform.sources, platform.verilog_include_paths, build_name)
|
||||
|
@ -186,6 +233,8 @@ class LatticeDiamondToolchain:
|
|||
# Run
|
||||
if run:
|
||||
_run_script(script)
|
||||
if timingstrict:
|
||||
_check_timing(build_name)
|
||||
|
||||
os.chdir(cwd)
|
||||
|
||||
|
@ -193,9 +242,12 @@ class LatticeDiamondToolchain:
|
|||
|
||||
def add_period_constraint(self, platform, clk, period):
|
||||
clk.attr.add("keep")
|
||||
# TODO: handle differential clk
|
||||
platform.add_platform_command("""FREQUENCY PORT "{clk}" {freq} MHz;""".format(
|
||||
freq=str(float(1/period)*1000), clk="{clk}"), clk=clk)
|
||||
period = math.floor(period*1e3)/1e3 # round to lowest picosecond
|
||||
if clk in self.clocks:
|
||||
if period != self.clocks[clk]:
|
||||
raise ValueError("Clock already constrained to {:.2f}ns, new constraint to {:.2f}ns"
|
||||
.format(self.clocks[clk], period))
|
||||
self.clocks[clk] = period
|
||||
|
||||
def add_false_path_constraint(self, platform, from_, to):
|
||||
from_.attr.add("keep")
|
||||
|
|
|
@ -93,32 +93,35 @@ def parse_device(device):
|
|||
_build_template = [
|
||||
"yosys -l {build_name}.rpt {build_name}.ys",
|
||||
"nextpnr-ice40 --json {build_name}.json --pcf {build_name}.pcf --asc {build_name}.txt \
|
||||
--pre-pack {build_name}_pre_pack.py --{architecture} --package {package} {timefailarg}",
|
||||
--pre-pack {build_name}_pre_pack.py --{architecture} --package {package} {timefailarg} {ignoreloops} --seed {seed}",
|
||||
"icepack -s {build_name}.txt {build_name}.bin"
|
||||
]
|
||||
|
||||
def _build_script(build_template, build_name, architecture, package, timingstrict):
|
||||
def _build_script(build_template, build_name, architecture, package, timingstrict, ignoreloops, seed):
|
||||
if sys.platform in ("win32", "cygwin"):
|
||||
script_ext = ".bat"
|
||||
build_script_contents = "@echo off\nrem Autogenerated by LiteX / git: " + tools.get_litex_git_revision() + "\n\n"
|
||||
script_contents = "@echo off\nrem Autogenerated by LiteX / git: " + tools.get_litex_git_revision() + "\n\n"
|
||||
fail_stmt = " || exit /b"
|
||||
else:
|
||||
script_ext = ".sh"
|
||||
build_script_contents = "# Autogenerated by LiteX / git: " + tools.get_litex_git_revision() + "\nset -e\n"
|
||||
script_contents = "# Autogenerated by LiteX / git: " + tools.get_litex_git_revision() + "\nset -e\n"
|
||||
fail_stmt = ""
|
||||
|
||||
for s in build_template:
|
||||
s_fail = s + "{fail_stmt}\n" # Required so Windows scripts fail early.
|
||||
build_script_contents += s_fail.format(
|
||||
script_contents += s_fail.format(
|
||||
build_name = build_name,
|
||||
architecture = architecture,
|
||||
package = package,
|
||||
timefailarg = "--timing-allow-fail" if not timingstrict else "",
|
||||
fail_stmt = fail_stmt)
|
||||
ignoreloops = "--ignore-loops" if ignoreloops else "",
|
||||
fail_stmt = fail_stmt,
|
||||
seed = seed)
|
||||
|
||||
build_script_file = "build_" + build_name + script_ext
|
||||
tools.write_to_file(build_script_file, build_script_contents,force_unix=False)
|
||||
return build_script_file
|
||||
script_file = "build_" + build_name + script_ext
|
||||
tools.write_to_file(script_file, script_contents, force_unix=False)
|
||||
|
||||
return script_file
|
||||
|
||||
def _run_script(script):
|
||||
if sys.platform in ("win32", "cygwin"):
|
||||
|
@ -158,6 +161,8 @@ class LatticeIceStormToolchain:
|
|||
synth_opts = "",
|
||||
run = True,
|
||||
timingstrict = False,
|
||||
ignoreloops = False,
|
||||
seed = 1,
|
||||
**kwargs):
|
||||
|
||||
# Create build directory
|
||||
|
@ -190,7 +195,7 @@ class LatticeIceStormToolchain:
|
|||
(family, architecture, package) = parse_device(platform.device)
|
||||
|
||||
# Generate build script
|
||||
script = _build_script(self.build_template, build_name, architecture, package, timingstrict)
|
||||
script = _build_script(self.build_template, build_name, architecture, package, timingstrict, ignoreloops, seed)
|
||||
|
||||
# Run
|
||||
if run:
|
||||
|
@ -207,3 +212,18 @@ class LatticeIceStormToolchain:
|
|||
raise ValueError("Clock already constrained to {:.2f}ns, new constraint to {:.2f}ns"
|
||||
.format(self.clocks[clk], period))
|
||||
self.clocks[clk] = period
|
||||
|
||||
def icestorm_args(parser):
|
||||
parser.add_argument("--nextpnr-timingstrict", action="store_true",
|
||||
help="fail if timing not met, i.e., do NOT pass '--timing-allow-fail' to nextpnr")
|
||||
parser.add_argument("--nextpnr-ignoreloops", action="store_true",
|
||||
help="ignore combinational loops in timing analysis, i.e. pass '--ignore-loops' to nextpnr")
|
||||
parser.add_argument("--nextpnr-seed", default=1, type=int,
|
||||
help="seed to pass to nextpnr")
|
||||
|
||||
def icestorm_argdict(args):
|
||||
return {
|
||||
"timingstrict": args.nextpnr_timingstrict,
|
||||
"ignoreloops": args.nextpnr_ignoreloops,
|
||||
"seed": args.nextpnr_seed,
|
||||
}
|
|
@ -117,11 +117,11 @@ nextpnr_ecp5_architectures = {
|
|||
_build_template = [
|
||||
"yosys -l {build_name}.rpt {build_name}.ys",
|
||||
"nextpnr-ecp5 --json {build_name}.json --lpf {build_name}.lpf --textcfg {build_name}.config \
|
||||
--{architecture} --package {package} --speed {speed_grade} {timefailarg} {ignoreloops}",
|
||||
"ecppack {build_name}.config --svf {build_name}.svf --bit {build_name}.bit --bootaddr={bootaddr}"
|
||||
--{architecture} --package {package} --speed {speed_grade} {timefailarg} {ignoreloops} --seed {seed}",
|
||||
"ecppack {build_name}.config --svf {build_name}.svf --bit {build_name}.bit"
|
||||
]
|
||||
|
||||
def _build_script(source, build_template, build_name, architecture, package, speed_grade, timingstrict, ignoreloops, bootaddr):
|
||||
def _build_script(source, build_template, build_name, architecture, package, speed_grade, timingstrict, ignoreloops, bootaddr, seed):
|
||||
if sys.platform in ("win32", "cygwin"):
|
||||
script_ext = ".bat"
|
||||
script_contents = "@echo off\nrem Autogenerated by LiteX / git: " + tools.get_litex_git_revision() + "\n\n"
|
||||
|
@ -141,7 +141,8 @@ def _build_script(source, build_template, build_name, architecture, package, spe
|
|||
timefailarg = "--timing-allow-fail" if not timingstrict else "",
|
||||
ignoreloops = "--ignore-loops" if ignoreloops else "",
|
||||
bootaddr = bootaddr,
|
||||
fail_stmt = fail_stmt)
|
||||
fail_stmt = fail_stmt,
|
||||
seed = seed)
|
||||
|
||||
script_file = "build_" + build_name + script_ext
|
||||
tools.write_to_file(script_file, script_contents, force_unix=False)
|
||||
|
@ -188,6 +189,7 @@ class LatticeTrellisToolchain:
|
|||
timingstrict = False,
|
||||
ignoreloops = False,
|
||||
bootaddr = 0,
|
||||
seed = 1,
|
||||
**kwargs):
|
||||
|
||||
# Create build directory
|
||||
|
@ -219,8 +221,7 @@ class LatticeTrellisToolchain:
|
|||
|
||||
# Generate build script
|
||||
script = _build_script(False, self.build_template, build_name, architecture, package,
|
||||
speed_grade, timingstrict, ignoreloops, bootaddr)
|
||||
|
||||
speed_grade, timingstrict, ignoreloops, bootaddr, seed)
|
||||
# Run
|
||||
if run:
|
||||
_run_script(script)
|
||||
|
@ -248,11 +249,14 @@ def trellis_args(parser):
|
|||
help="ignore combinational loops in timing analysis, i.e. pass '--ignore-loops' to nextpnr")
|
||||
parser.add_argument("--ecppack-bootaddr", default=0,
|
||||
help="Set boot address for next image, i.e. pass '--bootaddr xxx' to ecppack")
|
||||
parser.add_argument("--nextpnr-seed", default=1, type=int,
|
||||
help="seed to pass to nextpnr")
|
||||
|
||||
def trellis_argdict(args):
|
||||
return {
|
||||
"nowidelut": args.yosys_nowidelut,
|
||||
"timingstrict": args.nextpnr_timingstrict,
|
||||
"ignoreloops": args.nextpnr_ignoreloops,
|
||||
"bootaddr": args.ecppack_bootaddr
|
||||
"bootaddr": args.ecppack_bootaddr,
|
||||
"seed": args.nextpnr_seed,
|
||||
}
|
||||
|
|
|
@ -88,6 +88,7 @@ CPU_VARIANTS = {
|
|||
"minimal" : ["min",],
|
||||
"lite" : ["light", "zephyr", "nuttx"],
|
||||
"standard": [None, "std"],
|
||||
"imac": [],
|
||||
"full": [],
|
||||
"linux" : [],
|
||||
"linuxd" : [],
|
||||
|
|
|
@ -25,6 +25,8 @@ CPU_VARIANTS = {
|
|||
"lite+debug": "VexRiscv_LiteDebug",
|
||||
"standard": "VexRiscv",
|
||||
"standard+debug": "VexRiscv_Debug",
|
||||
"imac": "VexRiscv_IMAC",
|
||||
"imac+debug": "VexRiscv_IMACDebug",
|
||||
"full": "VexRiscv_Full",
|
||||
"full+debug": "VexRiscv_FullDebug",
|
||||
"linux": "VexRiscv_Linux",
|
||||
|
@ -47,6 +49,8 @@ GCC_FLAGS = {
|
|||
"lite+debug": "-march=rv32i -mabi=ilp32",
|
||||
"standard": "-march=rv32im -mabi=ilp32",
|
||||
"standard+debug": "-march=rv32im -mabi=ilp32",
|
||||
"imac": "-march=rv32imac -mabi=ilp32",
|
||||
"imac+debug": "-march=rv32imac -mabi=ilp32",
|
||||
"full": "-march=rv32im -mabi=ilp32",
|
||||
"full+debug": "-march=rv32im -mabi=ilp32",
|
||||
"linux": "-march=rv32ima -mabi=ilp32",
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
# This file is Copyright (c) 2020 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||
# License: BSD
|
||||
|
||||
from migen import *
|
||||
from migen.genlib.misc import WaitTimer
|
||||
|
||||
from litex.soc.interconnect.csr import *
|
||||
|
||||
# Led Chaser ---------------------------------------------------------------------------------------
|
||||
|
||||
_CHASER_MODE = 0
|
||||
_CONTROL_MODE = 1
|
||||
|
||||
class LedChaser(Module, AutoCSR):
|
||||
def __init__(self, pads, sys_clk_freq, period=1e0):
|
||||
self._out = CSRStorage(len(pads), description="Led Output(s) Control.")
|
||||
|
||||
# # #
|
||||
|
||||
n = len(pads)
|
||||
chaser = Signal(n)
|
||||
mode = Signal(reset=_CHASER_MODE)
|
||||
timer = WaitTimer(int(period*sys_clk_freq/(2*n)))
|
||||
self.submodules += timer
|
||||
self.comb += timer.wait.eq(~timer.done)
|
||||
self.sync += If(timer.done, chaser.eq(Cat(~chaser[-1], chaser)))
|
||||
self.sync += If(self._out.re, mode.eq(_CONTROL_MODE))
|
||||
self.comb += [
|
||||
If(mode == _CONTROL_MODE,
|
||||
pads.eq(self._out.storage)
|
||||
).Else(
|
||||
pads.eq(chaser)
|
||||
)
|
||||
]
|
|
@ -239,11 +239,13 @@ class UART(Module, AutoCSR, UARTInterface):
|
|||
self.ev.rx.trigger.eq(~rx_fifo.source.valid)
|
||||
]
|
||||
|
||||
class UARTWishboneBridge(WishboneStreamingBridge):
|
||||
class UARTBone(WishboneStreamingBridge):
|
||||
def __init__(self, pads, clk_freq, baudrate=115200):
|
||||
self.submodules.phy = RS232PHY(pads, clk_freq, baudrate)
|
||||
WishboneStreamingBridge.__init__(self, self.phy, clk_freq)
|
||||
|
||||
class UARTWishboneBridge(UARTBone): pass
|
||||
|
||||
# UART Multiplexer ---------------------------------------------------------------------------------
|
||||
|
||||
class UARTMultiplexer(Module):
|
||||
|
|
|
@ -282,7 +282,8 @@ class SoCBusHandler(Module):
|
|||
return is_io
|
||||
|
||||
# Add Master/Slave -----------------------------------------------------------------------------
|
||||
def add_adapter(self, name, interface):
|
||||
def add_adapter(self, name, interface, direction="m2s"):
|
||||
assert direction in ["m2s", "s2m"]
|
||||
if interface.data_width != self.data_width:
|
||||
self.logger.info("{} Bus {} from {}-bit to {}-bit.".format(
|
||||
colorer(name),
|
||||
|
@ -290,7 +291,11 @@ class SoCBusHandler(Module):
|
|||
colorer(interface.data_width),
|
||||
colorer(self.data_width)))
|
||||
new_interface = wishbone.Interface(data_width=self.data_width)
|
||||
self.submodules += wishbone.Converter(interface, new_interface)
|
||||
if direction == "m2s":
|
||||
converter = wishbone.Converter(master=interface, slave=new_interface)
|
||||
if direction == "s2m":
|
||||
converter = wishbone.Converter(master=new_interface, slave=interface)
|
||||
self.submodules += converter
|
||||
return new_interface
|
||||
else:
|
||||
return interface
|
||||
|
@ -304,7 +309,7 @@ class SoCBusHandler(Module):
|
|||
colorer("already declared", color="red")))
|
||||
self.logger.error(self)
|
||||
raise
|
||||
master = self.add_adapter(name, master)
|
||||
master = self.add_adapter(name, master, "m2s")
|
||||
self.masters[name] = master
|
||||
self.logger.info("{} {} as Bus Master.".format(
|
||||
colorer(name, color="underline"),
|
||||
|
@ -336,7 +341,7 @@ class SoCBusHandler(Module):
|
|||
colorer("already declared", color="red")))
|
||||
self.logger.error(self)
|
||||
raise
|
||||
slave = self.add_adapter(name, slave)
|
||||
slave = self.add_adapter(name, slave, "s2m")
|
||||
self.slaves[name] = slave
|
||||
self.logger.info("{} {} as Bus Slave.".format(
|
||||
colorer(name, color="underline"),
|
||||
|
@ -753,8 +758,8 @@ class SoC(Module):
|
|||
def add_csr_bridge(self, origin):
|
||||
self.submodules.csr_bridge = wishbone2csr.WB2CSR(
|
||||
bus_csr = csr_bus.Interface(
|
||||
address_width = self.csr.address_width,
|
||||
data_width = self.csr.data_width))
|
||||
address_width = self.csr.address_width,
|
||||
data_width = self.csr.data_width))
|
||||
csr_size = 2**(self.csr.address_width + 2)
|
||||
csr_region = SoCRegion(origin=origin, size=csr_size, cached=False)
|
||||
self.bus.add_slave("csr", self.csr_bridge.wishbone, csr_region)
|
||||
|
@ -926,13 +931,9 @@ class LiteXSoC(SoC):
|
|||
if name == "stub":
|
||||
self.comb += self.uart.sink.ready.eq(1)
|
||||
|
||||
# Bridge
|
||||
elif name in ["bridge"]:
|
||||
self.submodules.uart = uart.UARTWishboneBridge(
|
||||
pads = self.platform.request("serial"),
|
||||
clk_freq = self.sys_clk_freq,
|
||||
baudrate = baudrate)
|
||||
self.bus.add_master(name="uart_bridge", master=self.uart.wishbone)
|
||||
# UARTBone / Bridge
|
||||
elif name in ["uartbone", "bridge"]:
|
||||
self.add_uartbone(baudrate=baudrate)
|
||||
|
||||
# Crossover
|
||||
elif name in ["crossover"]:
|
||||
|
@ -986,6 +987,15 @@ class LiteXSoC(SoC):
|
|||
else:
|
||||
self.add_constant("UART_POLLING")
|
||||
|
||||
# Add UARTbone ---------------------------------------------------------------------------------
|
||||
def add_uartbone(self, name="serial", baudrate=115200):
|
||||
from litex.soc.cores import uart
|
||||
self.submodules.uartbone = uart.UARTBone(
|
||||
pads = self.platform.request(name),
|
||||
clk_freq = self.sys_clk_freq,
|
||||
baudrate = baudrate)
|
||||
self.bus.add_master(name="uartbone", master=self.uartbone.wishbone)
|
||||
|
||||
# Add SDRAM ------------------------------------------------------------------------------------
|
||||
def add_sdram(self, name, phy, module, origin, size=None,
|
||||
l2_cache_size = 8192,
|
||||
|
@ -1133,7 +1143,7 @@ class LiteXSoC(SoC):
|
|||
eth_tx_clk)
|
||||
|
||||
# Add Etherbone --------------------------------------------------------------------------------
|
||||
def add_etherbone(self, name="etherbone", phy=None,
|
||||
def add_etherbone(self, name="etherbone", phy=None, clock_domain=None,
|
||||
mac_address = 0x10e2d5000000,
|
||||
ip_address = "192.168.1.50",
|
||||
udp_port = 1234):
|
||||
|
@ -1146,9 +1156,21 @@ class LiteXSoC(SoC):
|
|||
mac_address = mac_address,
|
||||
ip_address = ip_address,
|
||||
clk_freq = self.clk_freq)
|
||||
if clock_domain is not None: # FIXME: Could probably be avoided.
|
||||
ethcore = ClockDomainsRenamer("eth_tx")(ethcore)
|
||||
self.submodules += ethcore
|
||||
|
||||
# Clock domain renaming
|
||||
if clock_domain is not None: # FIXME: Could probably be avoided.
|
||||
self.clock_domains.cd_etherbone = ClockDomain("etherbone")
|
||||
self.comb += self.cd_etherbone.clk.eq(ClockSignal(clock_domain))
|
||||
self.comb += self.cd_etherbone.rst.eq(ResetSignal(clock_domain))
|
||||
clock_domain = "etherbone"
|
||||
else:
|
||||
clock_domain = "sys"
|
||||
|
||||
# Etherbone
|
||||
etherbone = LiteEthEtherbone(ethcore.udp, udp_port)
|
||||
etherbone = LiteEthEtherbone(ethcore.udp, udp_port, cd=clock_domain)
|
||||
setattr(self.submodules, name, etherbone)
|
||||
self.add_wb_master(etherbone.wishbone.bus)
|
||||
# Timing constraints
|
||||
|
@ -1168,10 +1190,10 @@ class LiteXSoC(SoC):
|
|||
# Add SPI Flash --------------------------------------------------------------------------------
|
||||
def add_spi_flash(self, name="spiflash", mode="4x", dummy_cycles=None, clk_freq=None):
|
||||
assert dummy_cycles is not None # FIXME: Get dummy_cycles from SPI Flash
|
||||
assert mode in ["4x"] # FIXME: Add 1x support.
|
||||
assert mode in ["1x", "4x"]
|
||||
if clk_freq is None: clk_freq = self.clk_freq/2 # FIXME: Get max clk_freq from SPI Flash
|
||||
spiflash = SpiFlash(
|
||||
pads = self.platform.request(name + mode),
|
||||
pads = self.platform.request(name if mode == "1x" else name + mode),
|
||||
dummy = dummy_cycles,
|
||||
div = ceil(self.clk_freq/clk_freq),
|
||||
with_bitbang = True,
|
||||
|
|
|
@ -61,6 +61,11 @@ class SoCCore(LiteXSoC):
|
|||
}
|
||||
|
||||
def __init__(self, platform, clk_freq,
|
||||
# Bus parameters
|
||||
bus_standard = "wishbone",
|
||||
bus_data_width = 32,
|
||||
bus_address_width = 32,
|
||||
bus_timeout = 1e6,
|
||||
# CPU parameters
|
||||
cpu_type = "vexriscv",
|
||||
cpu_reset_address = None,
|
||||
|
@ -92,18 +97,15 @@ class SoCCore(LiteXSoC):
|
|||
with_timer = True,
|
||||
# Controller parameters
|
||||
with_ctrl = True,
|
||||
# Wishbone parameters
|
||||
with_wishbone = True,
|
||||
wishbone_timeout_cycles = 1e6,
|
||||
# Others
|
||||
**kwargs):
|
||||
|
||||
# New LiteXSoC class ----------------------------------------------------------------------------
|
||||
LiteXSoC.__init__(self, platform, clk_freq,
|
||||
bus_standard = "wishbone",
|
||||
bus_data_width = 32,
|
||||
bus_address_width = 32,
|
||||
bus_timeout = wishbone_timeout_cycles,
|
||||
bus_standard = bus_standard,
|
||||
bus_data_width = bus_data_width,
|
||||
bus_address_width = bus_address_width,
|
||||
bus_timeout = bus_timeout,
|
||||
bus_reserved_regions = {},
|
||||
|
||||
csr_data_width = csr_data_width,
|
||||
|
@ -127,9 +129,6 @@ class SoCCore(LiteXSoC):
|
|||
cpu_reset_address = None if cpu_reset_address == "None" else cpu_reset_address
|
||||
cpu_variant = cpu.check_format_cpu_variant(cpu_variant)
|
||||
|
||||
if not with_wishbone:
|
||||
self.mem_map["csr"] = 0x00000000
|
||||
|
||||
self.cpu_type = cpu_type
|
||||
self.cpu_variant = cpu_variant
|
||||
self.cpu_cls = cpu_cls
|
||||
|
@ -141,9 +140,6 @@ class SoCCore(LiteXSoC):
|
|||
|
||||
self.csr_data_width = csr_data_width
|
||||
|
||||
self.with_wishbone = with_wishbone
|
||||
self.wishbone_timeout_cycles = wishbone_timeout_cycles
|
||||
|
||||
self.wb_slaves = {}
|
||||
|
||||
# Modules instances ------------------------------------------------------------------------
|
||||
|
@ -187,9 +183,8 @@ class SoCCore(LiteXSoC):
|
|||
if with_timer:
|
||||
self.add_timer(name="timer0")
|
||||
|
||||
# Add Wishbone to CSR bridge
|
||||
if with_wishbone:
|
||||
self.add_csr_bridge(self.mem_map["csr"])
|
||||
# Add CSR bridge
|
||||
self.add_csr_bridge(self.mem_map["csr"])
|
||||
|
||||
# Methods --------------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -191,6 +191,13 @@ void sdrwlon(void)
|
|||
sdram_dfii_pi0_address_write(DDRX_MR1 | (1 << 7));
|
||||
sdram_dfii_pi0_baddress_write(1);
|
||||
command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
|
||||
|
||||
#ifdef SDRAM_PHY_DDR4_RDIMM
|
||||
sdram_dfii_pi0_address_write((DDRX_MR1 | (1 << 7)) ^ 0x2BF8) ;
|
||||
sdram_dfii_pi0_baddress_write(1 ^ 0xF);
|
||||
command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
|
||||
#endif
|
||||
|
||||
ddrphy_wlevel_en_write(1);
|
||||
}
|
||||
|
||||
|
@ -199,6 +206,13 @@ void sdrwloff(void)
|
|||
sdram_dfii_pi0_address_write(DDRX_MR1);
|
||||
sdram_dfii_pi0_baddress_write(1);
|
||||
command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
|
||||
|
||||
#ifdef SDRAM_PHY_DDR4_RDIMM
|
||||
sdram_dfii_pi0_address_write(DDRX_MR1 ^ 0x2BF8);
|
||||
sdram_dfii_pi0_baddress_write(1 ^ 0xF);
|
||||
command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
|
||||
#endif
|
||||
|
||||
ddrphy_wlevel_en_write(0);
|
||||
}
|
||||
|
||||
|
@ -903,7 +917,7 @@ static void memspeed(void)
|
|||
end = timer0_value_read();
|
||||
read_speed = (8*MEMTEST_DATA_SIZE*(CONFIG_CLOCK_FREQUENCY/1000000))/(start - end);
|
||||
|
||||
printf("Memspeed Writes: %dMbps Reads: %dMbps\n", write_speed, read_speed);
|
||||
printf("Memspeed Writes: %ldMbps Reads: %ldMbps\n", write_speed, read_speed);
|
||||
}
|
||||
|
||||
int memtest(void)
|
||||
|
|
Loading…
Reference in New Issue