Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/migen
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 15625236c1fa
Choose a base ref
...
head repository: m-labs/migen
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: a889b4106084
Choose a head ref
  • 3 commits
  • 6 files changed
  • 1 contributor

Commits on Apr 20, 2015

  1. some PEP8 cosmetic

    peteut authored and enjoy-digital committed Apr 20, 2015
    Copy the full SHA
    fd966d7 View commit details
  2. Copy the full SHA
    1b050d9 View commit details
  3. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    a889b41 View commit details
Showing with 284 additions and 54 deletions.
  1. +91 −0 mibuild/altera/_iostd.py
  2. +40 −1 mibuild/altera/common.py
  3. +2 −1 mibuild/altera/platform.py
  4. +4 −2 mibuild/altera/programmer.py
  5. +75 −33 mibuild/altera/quartus.py
  6. +72 −17 mibuild/generic_platform.py
91 changes: 91 additions & 0 deletions mibuild/altera/_iostd.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
'''ALTERA I/O-Standards
'''
import collections
from mibuild.generic_platform import IOStandard

__all__ = ['IOSTD']

_LVTTL = collections.namedtuple(
'V',
'level1V8 level2V5 level3V0 level3V3')(
IOStandard('1.8-V'),
IOStandard('2.5-V'),
IOStandard('3.0-V LVTTL'),
IOStandard('3.3-V LVTTL'))

_LVCMOS = collections.namedtuple(
'V',
'level1V2 level1V5 level1V8 level2V5 level3V0 level3V3')(
IOStandard('1.3 V'),
IOStandard('1.5 V'),
IOStandard('1.8 V'),
IOStandard('2.5 V'),
IOStandard('3.0-V LVCMOS'),
IOStandard('3.3-V LVCMOS'))

_SSTL = collections.namedtuple(
'V',
'level1V5ClassI level1V5ClassII '
'level1V8ClassI level1V8ClassII '
'level2V0ClassI level2V0ClassII')(
IOStandard('SSTL-15 Class I'),
IOStandard('SSTL-15 Class II'),
IOStandard('SSTL-18 Class I'),
IOStandard('SSTL-18 Class II'),
IOStandard('SSTL-2 Class I'),
IOStandard('SSTL-2 Class II'))

_HSTL = collections.namedtuple(
'V',
'level1V2ClassI level1V2ClassII level1V5ClassI level1V5ClassII '
'level1V8ClassI level1V8ClassII')(
IOStandard('1.2-V HSTL Class I'),
IOStandard('1.2-V HSTL Class II'),
IOStandard('HSTL Class I'),
IOStandard('HSTL Class II'),
IOStandard('1.8-V HSTL Class I'),
IOStandard('1.8-V HSTL Class II'))

_DiffSSTL = collections.namedtuple(
'V',
'level1V5 level1V8 level2V0')(
IOStandard('Differential 1.5-V SSTL'),
IOStandard('Differential 1.8-V SSTL'),
IOStandard('Differential SSTL-2'))

_DiffHSTL = collections.namedtuple(
'V',
'level1V2 level1V5 level1V8')(
IOStandard('Differential 1.2-V HSTL'),
IOStandard('Differential 1.5-V HSTL'),
IOStandard('Differential 1.8-V HSTL'))

_PCML = collections.namedtuple(
'V',
'level1V2 level1V4 level1V5 level2V5')(
IOStandard('1.2-V PCML'),
IOStandard('1.4-V PCML'),
IOStandard('1.5-V PCML'),
IOStandard('2.5-V PCML'))

IOSTD = collections.namedtuple(
'CONST',
'LVTTL LVCMOS PCI PCIX SSTL HSTL DiffSSTL DiffHSTL '
'LVDS RSDS miniLVDS LVPECL DiffLVPECL BLVDS PCML DiffPCML HCSL')(
_LVTTL,
_LVCMOS,
IOStandard('3.0-V PCI'),
IOStandard('3.0-V PCI-X'),
_SSTL,
_HSTL,
_DiffSSTL,
_DiffHSTL,
IOStandard('LVDS'),
IOStandard('RSDS'),
IOStandard('mini-LVDS'),
IOStandard('LVPECL'),
IOStandard('Differential LVPECL'),
IOStandard('BLVDS'),
_PCML,
IOStandard('Differential PCML'),
IOStandard('HCSL'))
41 changes: 40 additions & 1 deletion mibuild/altera/common.py
Original file line number Diff line number Diff line change
@@ -1 +1,40 @@
altera_special_overrides = {}
from migen.fhdl.std import (Instance, Module)
from migen.genlib.io import (DifferentialInput, DifferentialOutput)


__all__ = ['altera_special_overrides']


class QuartusDifferentialInputImpl(Module):
def __init__(self, i_p, i_n, o):
self.specials += Instance("ALT_INBUF_DIFF",
name='ibuf_diff',
i_i=i_p,
i_ibar=i_n,
o_o=o)


class QuartusDifferentialInput:
@staticmethod
def lower(dr):
return QuartusDifferentialInputImpl(dr.i_p, dr.i_n, dr.o)


class QuartusDifferentialOutputImpl(Module):
def __init__(self, i, o_p, o_n):
self.specials += Instance("ALT_OUTBUF_DIFF",
name='obuf_diff',
i_i=i,
o_o=o_p,
o_obar=o_n)


class QuartusDifferentialOutput:
@staticmethod
def lower(dr):
return QuartusDifferentialOutputImpl(dr.i, dr.o_p, dr.o_n)

altera_special_overrides = {
DifferentialInput: QuartusDifferentialInput,
DifferentialOutput: QuartusDifferentialOutput
}
3 changes: 2 additions & 1 deletion mibuild/altera/platform.py
Original file line number Diff line number Diff line change
@@ -15,7 +15,8 @@ def __init__(self, *args, toolchain="quartus", **kwargs):
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)
6 changes: 4 additions & 2 deletions mibuild/altera/programmer.py
Original file line number Diff line number Diff line change
@@ -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)])
108 changes: 75 additions & 33 deletions mibuild/altera/quartus.py
Original file line number Diff line number Diff line change
@@ -5,60 +5,90 @@
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 @@ def _run_quartus(build_name, quartus_path):
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 @@ def build(self, platform, fragment, build_dir="build", build_name="top",
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 @@ def build(self, platform, fragment, build_dir="build", build_name="top",

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)
Loading