some PEP8 cosmetic

This commit is contained in:
Alain Péteut 2015-04-20 10:03:08 +02:00 committed by Florent Kermarrec
parent 15625236c1
commit fd966d70ba
4 changed files with 153 additions and 53 deletions

View File

@ -15,7 +15,8 @@ class AlteraPlatform(GenericPlatform):
def get_verilog(self, *args, special_overrides=dict(), **kwargs):
so = dict(common.altera_special_overrides)
so.update(special_overrides)
return GenericPlatform.get_verilog(self, *args, special_overrides=so, **kwargs)
return GenericPlatform.get_verilog(self, *args, special_overrides=so,
**kwargs)
def build(self, *args, **kwargs):
return self.toolchain.build(self, *args, **kwargs)

View File

@ -7,5 +7,7 @@ class USBBlaster(GenericProgrammer):
needs_bitreverse = False
def load_bitstream(self, bitstream_file, port=0):
usb_port = "[USB-"+str(port) + "]"
subprocess.call(["quartus_pgm", "-m", "jtag", "-c", "USB-Blaster" + usb_port, "-o", "p;" + bitstream_file])
usb_port = "[USB-{}]".format(port)
subprocess.call(["quartus_pgm", "-m", "jtag", "-c",
"USB-Blaster{}".format(usb_port), "-o",
"p;{}".format(bitstream_file)])

View File

@ -5,60 +5,90 @@ import os
import subprocess
from migen.fhdl.structure import _Fragment
from mibuild.generic_platform import *
from mibuild.generic_platform import (Pins, IOStandard, Misc)
from mibuild import tools
from mibuild.xilinx import common
def _format_constraint(c):
def _format_constraint(c, signame, fmt_r):
if isinstance(c, Pins):
return "set_location_assignment PIN_" + c.identifiers[0]
return "set_location_assignment -comment \"{name}\" " \
"-to {signame} Pin_{pin}".format(
signame=signame,
name=fmt_r,
pin=c.identifiers[0])
elif isinstance(c, IOStandard):
return "set_instance_assignment -name IO_STANDARD " + "\"" + c.name + "\""
return "set_instance_assignment -name io_standard " \
"-comment \"{name}\" \"{std}\" -to {signame}".format(
signame=signame,
name=fmt_r,
std=c.name)
elif isinstance(c, Misc):
return c.misc
if not isinstance(c.misc, str) and len(c.misc) == 2:
return "set_instance_assignment -comment \"{name}\" " \
"-name {misc[0]} \"{misc[1]}\" -to {signame}".format(
signame=signame,
name=fmt_r,
misc=c.misc)
else:
return "set_instance_assignment -comment \"{name}\" " \
"-name {misc} " \
"-to {signame}".format(
signame=signame,
name=fmt_r,
misc=c.misc)
def _format_qsf(signame, pin, others, resname):
fmt_c = [_format_constraint(c) for c in ([Pins(pin)] + others)]
fmt_r = resname[0] + ":" + str(resname[1])
fmt_r = "{}:{}".format(*resname[:2])
if resname[2] is not None:
fmt_r += "." + resname[2]
r = ""
for c in fmt_c:
r += c + " -to " + signame + " # " + fmt_r + "\n"
return r
fmt_c = [_format_constraint(c, signame, fmt_r) for c in
([Pins(pin)] + others)]
return '\n'.join(fmt_c)
def _build_qsf(named_sc, named_pc):
r = ""
lines = []
for sig, pins, others, resname in named_sc:
if len(pins) > 1:
for i, p in enumerate(pins):
r += _format_qsf(sig + "[" + str(i) + "]", p, others, resname)
lines.append(
_format_qsf("{}[{}]".format(sig, i), p, others, resname))
else:
r += _format_qsf(sig, pins[0], others, resname)
lines.append(_format_qsf(sig, pins[0], others, resname))
if named_pc:
r += "\n" + "\n\n".join(named_pc)
r += "set_global_assignment -name top_level_entity top\n"
return r
lines.append("")
lines.append("\n\n".join(named_pc))
lines.append("set_global_assignment -name top_level_entity top")
return "\n".join(lines)
def _build_files(device, sources, vincpaths, named_sc, named_pc, build_name):
qsf_contents = ""
lines = []
for filename, language, library in sources:
# Enforce use of SystemVerilog (Quartus does not support global parameters in Verilog)
# Enforce use of SystemVerilog
# (Quartus does not support global parameters in Verilog)
if language == "verilog":
language = "systemverilog"
qsf_contents += "set_global_assignment -name " + language.upper() + "_FILE " + filename + " -library " + library + " \n"
lines.append(
"set_global_assignment -name {lang}_FILE {path} "
"-library {lib}".format(
lang=language.upper(),
path=filename.replace("\\", "/"),
lib=library))
for path in vincpaths:
qsf_contents += "set_global_assignment -name SEARCH_PATH " + path + "\n"
lines.append("set_global_assignment -name SEARCH_PATH {}".format(
path.replace("\\", "/")))
qsf_contents += _build_qsf(named_sc, named_pc)
qsf_contents += "set_global_assignment -name DEVICE " + device
tools.write_to_file(build_name + ".qsf", qsf_contents)
lines.append(_build_qsf(named_sc, named_pc))
lines.append("set_global_assignment -name DEVICE {}".format(device))
tools.write_to_file("{}.qsf".format(build_name), "\n".join(lines))
def _run_quartus(build_name, quartus_path):
@ -69,18 +99,19 @@ quartus_fit --read_settings_files=off --write_settings_files=off {build_name} -c
quartus_asm --read_settings_files=off --write_settings_files=off {build_name} -c {build_name}
quartus_sta {build_name} -c {build_name}
""".format(build_name=build_name)
""".format(build_name=build_name) # noqa
build_script_file = "build_" + build_name + ".sh"
tools.write_to_file(build_script_file, build_script_contents, force_unix=True)
tools.write_to_file(build_script_file,
build_script_contents,
force_unix=True)
r = subprocess.call(["bash", build_script_file])
if r != 0:
if subprocess.call(["bash", build_script_file]):
raise OSError("Subprocess failed")
class AlteraQuartusToolchain:
def build(self, platform, fragment, build_dir="build", build_name="top",
quartus_path="/opt/Altera", run=True):
quartus_path="/opt/Altera", run=True):
tools.mkdir_noerror(build_dir)
os.chdir(build_dir)
@ -93,7 +124,12 @@ class AlteraQuartusToolchain:
v_file = build_name + ".v"
v_output.write(v_file)
sources = platform.sources | {(v_file, "verilog", "work")}
_build_files(platform.device, sources, platform.verilog_include_paths, named_sc, named_pc, build_name)
_build_files(platform.device,
sources,
platform.verilog_include_paths,
named_sc,
named_pc,
build_name)
if run:
_run_quartus(build_name, quartus_path)
@ -103,5 +139,11 @@ class AlteraQuartusToolchain:
def add_period_constraint(self, platform, clk, period):
# TODO: handle differential clk
platform.add_platform_command("""set_global_assignment -name DUTY_CYCLE 50 -section_id {clk}""", clk=clk)
platform.add_platform_command("""set_global_assignment -name FMAX_REQUIREMENT "{freq} MHz" -section_id {clk}\n""".format(freq=str(float(1/period)*1000), clk="{clk}"), clk=clk)
platform.add_platform_command(
"set_global_assignment -name duty_cycle 50 -section_id {clk}",
clk=clk)
platform.add_platform_command(
"set_global_assignment -name fmax_requirement \"{freq} MHz\" "
"-section_id {clk}".format(freq=(1. / period) * 1000,
clk="{clk}"),
clk=clk)

View File

@ -1,8 +1,7 @@
import os
import sys
from migen.fhdl.std import *
from migen.fhdl.structure import _Fragment
from migen.fhdl.std import Signal
from migen.genlib.record import Record
from migen.genlib.io import CRG
from migen.fhdl import verilog, edif
@ -21,38 +20,60 @@ class Pins:
for i in identifiers:
self.identifiers += i.split()
def __repr__(self):
return "{}('{}')".format(self.__class__.__name__,
" ".join(self.identifiers))
class IOStandard:
def __init__(self, name):
self.name = name
def __repr__(self):
return "{}('{}')".format(self.__class__.__name__, self.name)
class Drive:
def __init__(self, strength):
self.strength = strength
def __repr__(self):
return "{}('{}')".format(self.__class__.__name__, self.strength)
class Misc:
def __init__(self, misc):
self.misc = misc
def __repr__(self):
return "{}({})".format(self.__class__.__name__, repr(self.misc))
class Subsignal:
def __init__(self, name, *constraints):
self.name = name
self.constraints = list(constraints)
def __repr__(self):
return "{}('{}', {})".format(
self.__class__.__name__,
self.name,
", ".join([repr(constr) for constr in self.constraints]))
class PlatformInfo:
def __init__(self, info):
self.info = info
def __repr__(self):
return "{}({})".format(self.__class__.__name__, repr(self.info))
def _lookup(description, name, number):
for resource in description:
if resource[0] == name and (number is None or resource[1] == number):
return resource
raise ConstraintError("Resource not found: " + name + ":" + str(number))
raise ConstraintError("Resource not found: {}:{}".format(name, number))
def _resource_type(resource):
@ -64,13 +85,16 @@ def _resource_type(resource):
elif isinstance(element, Subsignal):
if t is None:
t = []
assert(isinstance(t, list))
n_bits = None
for c in element.constraints:
if isinstance(c, Pins):
assert(n_bits is None)
n_bits = len(c.identifiers)
t.append((element.name, n_bits))
return t
@ -89,9 +113,11 @@ class ConnectorManager:
pin_list = connector[1]
else:
raise ValueError("Unsupported pin list type {} for connector"
" {}".format(type(connector[1]), conn_name))
" {}".format(type(connector[1]), conn_name))
if conn_name in self.connector_table:
raise ValueError("Connector specified more than once: "+conn_name)
raise ValueError(
"Connector specified more than once: {}".format(conn_name))
self.connector_table[conn_name] = pin_list
def resolve_identifiers(self, identifiers):
@ -101,9 +127,11 @@ class ConnectorManager:
conn, pn = identifier.split(":")
if pn.isdigit():
pn = int(pn)
r.append(self.connector_table[conn][pn])
else:
r.append(identifier)
return r
@ -116,6 +144,7 @@ def _separate_pins(constraints):
pins = c.identifiers
else:
others.append(c)
return pins, others
@ -136,19 +165,23 @@ class ConstraintManager:
obj = Signal(rt, name_override=resource[0])
else:
obj = Record(rt, name=resource[0])
for element in resource[2:]:
if isinstance(element, PlatformInfo):
obj.platform_info = element.info
break
self.available.remove(resource)
self.matched.append((resource, obj))
return obj
def lookup_request(self, name, number=None):
for resource, obj in self.matched:
if resource[0] == name and (number is None or resource[1] == number):
if resource[0] == name and (number is None or
resource[1] == number):
return obj
raise ConstraintError("Resource not found: " + name + ":" + str(number))
raise ConstraintError("Resource not found: {}:{}".format(name, number))
def add_platform_command(self, command, **signals):
self.platform_commands.append((command, signals))
@ -160,6 +193,7 @@ class ConstraintManager:
r.add(obj)
else:
r.update(obj.flatten())
return r
def get_sig_constraints(self):
@ -174,17 +208,21 @@ class ConstraintManager:
has_subsignals = True
else:
top_constraints.append(element)
if has_subsignals:
for element in resource[2:]:
if isinstance(element, Subsignal):
sig = getattr(obj, element.name)
pins, others = _separate_pins(top_constraints + element.constraints)
pins, others = _separate_pins(top_constraints +
element.constraints)
pins = self.connector_manager.resolve_identifiers(pins)
r.append((sig, pins, others, (name, number, element.name)))
r.append((sig, pins, others,
(name, number, element.name)))
else:
pins, others = _separate_pins(top_constraints)
pins = self.connector_manager.resolve_identifiers(pins)
r.append((obj, pins, others, (name, number, None)))
return r
def get_platform_commands(self):
@ -223,27 +261,35 @@ class GenericPlatform:
# if none exists, create a default clock domain and drive it
if not fragment.clock_domains:
if not hasattr(self, "default_clk_name"):
raise NotImplementedError("No default clock and no clock domain defined")
raise NotImplementedError(
"No default clock and no clock domain defined")
crg = CRG(self.request(self.default_clk_name))
fragment += crg.get_fragment()
self.do_finalize(fragment, *args, **kwargs)
self.finalized = True
def do_finalize(self, fragment, *args, **kwargs):
"""overload this and e.g. add_platform_command()'s after the modules had their say"""
"""overload this and e.g. add_platform_command()'s after the modules
had their say"""
if hasattr(self, "default_clk_period"):
try:
self.add_period_constraint(self.lookup_request(self.default_clk_name), self.default_clk_period)
self.add_period_constraint(
self.lookup_request(self.default_clk_name),
self.default_clk_period)
except ConstraintError:
pass
def add_source(self, filename, language=None, library=None):
if language is None:
language = tools.language_by_filename(filename)
if language is None:
language = "verilog" # default to Verilog
if library is None:
library = "work" # default to work
filename = os.path.abspath(filename)
if sys.platform == "win32" or sys.platform == "cygwin":
filename = filename.replace("\\", "/")
@ -277,20 +323,28 @@ class GenericPlatform:
def resolve_signals(self, vns):
# resolve signal names in constraints
sc = self.constraint_manager.get_sig_constraints()
named_sc = [(vns.get_name(sig), pins, others, resource) for sig, pins, others, resource in sc]
named_sc = [(vns.get_name(sig), pins, others, resource)
for sig, pins, others, resource in sc]
# resolve signal names in platform commands
pc = self.constraint_manager.get_platform_commands()
named_pc = []
for template, args in pc:
name_dict = dict((k, vns.get_name(sig)) for k, sig in args.items())
named_pc.append(template.format(**name_dict))
return named_sc, named_pc
def get_verilog(self, fragment, **kwargs):
return verilog.convert(fragment, self.constraint_manager.get_io_signals(), create_clock_domains=False, **kwargs)
return verilog.convert(
fragment,
self.constraint_manager.get_io_signals(),
create_clock_domains=False, **kwargs)
def get_edif(self, fragment, cell_library, vendor, device, **kwargs):
return edif.convert(fragment, self.constraint_manager.get_io_signals(), cell_library, vendor, device, **kwargs)
return edif.convert(
fragment,
self.constraint_manager.get_io_signals(),
cell_library, vendor, device, **kwargs)
def build(self, fragment):
raise NotImplementedError("GenericPlatform.build must be overloaded")
@ -298,9 +352,10 @@ class GenericPlatform:
def build_cmdline(self, *args, **kwargs):
arg = sys.argv[1:]
if len(arg) % 2:
print("Missing value for option: "+sys.argv[-1])
print("Missing value for option: {}".format(sys.argv[-1]))
sys.exit(1)
argdict = dict((k, autotype(v)) for k, v in zip(*[iter(arg)]*2))
argdict = dict((k, autotype(v)) for k, v in zip(*[iter(arg)] * 2))
kwargs.update(argdict)
self.build(*args, **kwargs)