From: Sebastien Bourdeauducq Date: Sat, 23 Nov 2013 09:34:28 +0000 (+0100) Subject: Add 'mibuild/' from commit '9d5931c969810a236de2a2713cfd5e509839d097' X-Git-Tag: 24jan2021_ls180~2099^2~443 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=62ec66bc0065c4fcca21967dde60e856dbc9d584;p=litex.git Add 'mibuild/' from commit '9d5931c969810a236de2a2713cfd5e509839d097' git-subtree-dir: mibuild git-subtree-mainline: 7e4024beb3cd10c31ee575eddf9a61d79e0d2c61 git-subtree-split: 9d5931c969810a236de2a2713cfd5e509839d097 --- 62ec66bc0065c4fcca21967dde60e856dbc9d584 diff --cc mibuild/.gitignore index 00000000,00000000..8d35cb32 new file mode 100644 --- /dev/null +++ b/mibuild/.gitignore @@@ -1,0 -1,0 +1,2 @@@ ++__pycache__ ++*.pyc diff --cc mibuild/LICENSE index 00000000,00000000..cdc6303b new file mode 100644 --- /dev/null +++ b/mibuild/LICENSE @@@ -1,0 -1,0 +1,29 @@@ ++Unless otherwise noted, Mibuild is copyright (C) 2013 Sebastien Bourdeauducq. ++All rights reserved. ++ ++Redistribution and use in source and binary forms, with or without modification, ++are permitted provided that the following conditions are met: ++ ++1. Redistributions of source code must retain the above copyright notice, this ++ list of conditions and the following disclaimer. ++2. Redistributions in binary form must reproduce the above copyright notice, ++ this list of conditions and the following disclaimer in the documentation ++ and/or other materials provided with the distribution. ++ ++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ++ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ++WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ++ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ ++ ++Other authors retain ownership of their contributions. If a submission can ++reasonably be considered independently copyrightable, it's yours and we ++encourage you to claim it with appropriate copyright notices. This submission ++then falls under the "otherwise noted" category. All submissions are strongly ++encouraged to use the two-clause BSD license reproduced above. diff --cc mibuild/README index 00000000,00000000..df95d062 new file mode 100644 --- /dev/null +++ b/mibuild/README @@@ -1,0 -1,0 +1,27 @@@ ++Mibuild (Milkymist Build system) ++ a build system and board database for Migen-based FPGA designs ++ ++Quick intro: ++ ++from migen.fhdl.std import * ++from mibuild.platforms import m1 ++plat = m1.Platform() ++led = plat.request("user_led") ++m = Module() ++counter = Signal(26) ++m.comb += led.eq(counter[25]) ++m.sync += counter.eq(counter + 1) ++plat.build_cmdline(m) ++ ++Code repository: ++https://github.com/milkymist/mibuild ++Migen: ++https://github.com/milkymist/migen ++Experimental version of the Milkymist SoC based on Migen: ++https://github.com/milkymist/milkymist-ng ++ ++Mibuild is designed for Python 3.3. ++ ++Send questions, comments and patches to devel [AT] lists.milkymist.org ++Description files for new boards welcome. ++We are also on IRC: #milkymist on the Freenode network. diff --cc mibuild/mibuild/__init__.py index 00000000,00000000..e69de29b new file mode 100644 --- /dev/null +++ b/mibuild/mibuild/__init__.py diff --cc mibuild/mibuild/altera_quartus.py index 00000000,00000000..781b104f new file mode 100644 --- /dev/null +++ b/mibuild/mibuild/altera_quartus.py @@@ -1,0 -1,0 +1,105 @@@ ++# This file is Copyright (c) 2013 Florent Kermarrec ++# License: BSD ++ ++import os, subprocess ++ ++from migen.fhdl.structure import _Fragment ++from mibuild.generic_platform import * ++from mibuild.crg import SimpleCRG ++from mibuild import tools ++ ++def _add_period_constraint(platform, clk, period): ++ 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) ++ ++class CRG_SE(SimpleCRG): ++ def __init__(self, platform, clk_name, rst_name, period, rst_invert=False): ++ SimpleCRG.__init__(self, platform, clk_name, rst_name, rst_invert) ++ _add_period_constraint(platform, self.cd_sys.clk, period) ++ ++def _format_constraint(c): ++ if isinstance(c, Pins): ++ return "set_location_assignment PIN_" + c.identifiers[0] ++ elif isinstance(c, IOStandard): ++ return "set_instance_assignment -name IO_STANDARD " + "\"" + c.name + "\"" ++ elif isinstance(c, Misc): ++ return 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]) ++ 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 ++ ++def _build_qsf(named_sc, named_pc): ++ r = "" ++ 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) ++ else: ++ r += _format_qsf(sig, pins[0], others, resname) ++ if named_pc: ++ r += "\n" + "\n\n".join(named_pc) ++ return r ++ ++def _build_files(device, sources, named_sc, named_pc, build_name): ++ qsf_contents = "" ++ for filename, language in sources: ++ qsf_contents += "set_global_assignment -name "+language.upper()+"_FILE " + filename.replace("\\","/") + "\n" ++ ++ 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) ++ ++def _run_quartus(build_name, quartus_path): ++ build_script_contents = """# Autogenerated by mibuild ++ ++quartus_map {build_name}.qpf ++quartus_fit {build_name}.qpf ++quartus_asm {build_name}.qpf ++quartus_sta {build_name}.qpf ++ ++""".format(build_name=build_name) ++ build_script_file = "build_" + build_name + ".sh" ++ tools.write_to_file(build_script_file, build_script_contents) ++ ++ r = subprocess.call(["bash", build_script_file]) ++ if r != 0: ++ raise OSError("Subprocess failed") ++ ++class AlteraQuartusPlatform(GenericPlatform): ++ def build(self, fragment, build_dir="build", build_name="top", ++ quartus_path="/opt/Altera", run=True): ++ tools.mkdir_noerror(build_dir) ++ os.chdir(build_dir) ++ ++ if not isinstance(fragment, _Fragment): ++ fragment = fragment.get_fragment() ++ self.finalize(fragment) ++ ++ v_src, named_sc, named_pc = self.get_verilog(fragment) ++ v_file = build_name + ".v" ++ tools.write_to_file(v_file, v_src) ++ sources = self.sources + [(v_file, "verilog")] ++ _build_files(self.device, sources, named_sc, named_pc, build_name) ++ if run: ++ _run_quartus(build_name, quartus_path) ++ ++ os.chdir("..") ++ ++ def build_arg_ns(self, ns, *args, **kwargs): ++ for n in ["build_dir", "build_name", "quartus_path"]: ++ kwargs[n] = getattr(ns, n) ++ kwargs["run"] = not ns.no_run ++ self.build(*args, **kwargs) ++ ++ def add_arguments(self, parser): ++ parser.add_argument("--build-dir", default="build", help="Set the directory in which to generate files and run Quartus") ++ parser.add_argument("--build-name", default="top", help="Base name for the generated files") ++ parser.add_argument("--quartus-path", default="/opt/Altera", help="Quartus installation path (without version directory)") ++ parser.add_argument("--no-run", action="store_true", help="Only generate files, do not run Quartus") diff --cc mibuild/mibuild/crg.py index 00000000,00000000..5d51a13b new file mode 100644 --- /dev/null +++ b/mibuild/mibuild/crg.py @@@ -1,0 -1,0 +1,14 @@@ ++from migen.fhdl.std import * ++ ++class SimpleCRG(Module): ++ def __init__(self, platform, clk_name, rst_name, rst_invert=False): ++ reset_less = rst_name is None ++ self.clock_domains.cd_sys = ClockDomain(reset_less=reset_less) ++ self._clk = platform.request(clk_name) ++ self.comb += self.cd_sys.clk.eq(self._clk) ++ ++ if not reset_less: ++ if rst_invert: ++ self.comb += self.cd_sys.rst.eq(~platform.request(rst_name)) ++ else: ++ self.comb += self.cd_sys.rst.eq(platform.request(rst_name)) diff --cc mibuild/mibuild/generic_platform.py index 00000000,00000000..17c8752a new file mode 100644 --- /dev/null +++ b/mibuild/mibuild/generic_platform.py @@@ -1,0 -1,0 +1,238 @@@ ++import os, argparse ++ ++from migen.fhdl.std import * ++from migen.fhdl.structure import _Fragment ++from migen.genlib.record import Record ++from migen.fhdl import verilog, edif ++ ++from mibuild import tools ++ ++class ConstraintError(Exception): ++ pass ++ ++class Pins: ++ def __init__(self, *identifiers): ++ self.identifiers = [] ++ for i in identifiers: ++ self.identifiers += i.split() ++ ++class IOStandard: ++ def __init__(self, name): ++ self.name = name ++ ++class Drive: ++ def __init__(self, strength): ++ self.strength = strength ++ ++class Misc: ++ def __init__(self, misc): ++ self.misc = misc ++ ++class Subsignal: ++ def __init__(self, name, *constraints): ++ self.name = name ++ self.constraints = list(constraints) ++ ++class PlatformInfo: ++ def __init__(self, info): ++ self.info = 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)) ++ ++def _resource_type(resource): ++ t = None ++ for element in resource[2:]: ++ if isinstance(element, Pins): ++ assert(t is None) ++ t = len(element.identifiers) ++ 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 ++ ++def _separate_pins(constraints): ++ pins = None ++ others = [] ++ for c in constraints: ++ if isinstance(c, Pins): ++ assert(pins is None) ++ pins = c.identifiers ++ else: ++ others.append(c) ++ return pins, others ++ ++class ConstraintManager: ++ def __init__(self, description): ++ self.available = list(description) ++ self.matched = [] ++ self.platform_commands = [] ++ ++ def request(self, name, number=None): ++ resource = _lookup(self.available, name, number) ++ rt = _resource_type(resource) ++ if isinstance(rt, int): ++ 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): ++ return obj ++ raise ConstraintError("Resource not found: " + name + ":" + str(number)) ++ ++ def add_platform_command(self, command, **signals): ++ self.platform_commands.append((command, signals)) ++ ++ def get_io_signals(self): ++ r = set() ++ for resource, obj in self.matched: ++ if isinstance(obj, Signal): ++ r.add(obj) ++ else: ++ r.update(obj.flatten()) ++ return r ++ ++ def get_sig_constraints(self): ++ r = [] ++ for resource, obj in self.matched: ++ name = resource[0] ++ number = resource[1] ++ has_subsignals = False ++ top_constraints = [] ++ for element in resource[2:]: ++ if isinstance(element, Subsignal): ++ 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) ++ r.append((sig, pins, others, (name, number, element.name))) ++ else: ++ pins, others = _separate_pins(top_constraints) ++ r.append((obj, pins, others, (name, number, None))) ++ return r ++ ++ def get_platform_commands(self): ++ return self.platform_commands ++ ++ ++class GenericPlatform: ++ def __init__(self, device, io, default_crg_factory=None, name=None): ++ self.device = device ++ self.constraint_manager = ConstraintManager(io) ++ self.default_crg_factory = default_crg_factory ++ if name is None: ++ name = self.__module__.split(".")[-1] ++ self.name = name ++ self.sources = [] ++ self.finalized = False ++ ++ def request(self, *args, **kwargs): ++ return self.constraint_manager.request(*args, **kwargs) ++ ++ def lookup_request(self, *args, **kwargs): ++ return self.constraint_manager.lookup_request(*args, **kwargs) ++ ++ def add_platform_command(self, *args, **kwargs): ++ return self.constraint_manager.add_platform_command(*args, **kwargs) ++ ++ def finalize(self, fragment, *args, **kwargs): ++ if self.finalized: ++ raise ConstraintError("Already finalized") ++ # if none exists, create a default clock domain and drive it ++ if not fragment.clock_domains: ++ if self.default_crg_factory is None: ++ raise NotImplementedError("No clock/reset generator defined by either platform or user") ++ crg = self.default_crg_factory(self) ++ 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""" ++ pass ++ ++ def add_source(self, filename, language=None): ++ if language is None: ++ language = tools.language_by_filename(filename) ++ if language is None: ++ language = "verilog" # default to Verilog ++ filename = os.path.abspath(filename) ++ self.sources.append((filename, language)) ++ ++ def add_sources(self, path, *filenames, language=None): ++ for f in filenames: ++ self.add_source(os.path.join(path, f), language) ++ ++ def add_source_dir(self, path): ++ for root, dirs, files in os.walk(path): ++ for filename in files: ++ language = tools.language_by_filename(filename) ++ if language is not None: ++ self.add_source(os.path.join(root, filename), language) ++ ++ 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] ++ # 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_source(self, fragment, gen_fn): ++ if not isinstance(fragment, _Fragment): ++ fragment = fragment.get_fragment() ++ # generate source ++ src, vns = gen_fn(fragment) ++ named_sc, named_pc = self._resolve_signals(vns) ++ return src, named_sc, named_pc ++ ++ def get_verilog(self, fragment, **kwargs): ++ return self._get_source(fragment, lambda f: verilog.convert(f, self.constraint_manager.get_io_signals(), ++ return_ns=True, create_clock_domains=False, **kwargs)) ++ ++ def get_edif(self, fragment, cell_library, vendor, device, **kwargs): ++ return self._get_source(fragment, lambda f: edif.convert(f, self.constraint_manager.get_io_signals(), ++ cell_library, vendor, device, return_ns=True, **kwargs)) ++ ++ def build(self, fragment): ++ raise NotImplementedError("GenericPlatform.build must be overloaded") ++ ++ def add_arguments(self, parser): ++ pass # default: no arguments ++ ++ def build_arg_ns(self, ns, *args, **kwargs): ++ self.build(*args, **kwargs) ++ ++ def build_cmdline(self, *args, **kwargs): ++ parser = argparse.ArgumentParser(description="FPGA bitstream build system") ++ self.add_arguments(parser) ++ ns = parser.parse_args() ++ self.build_arg_ns(ns, *args, **kwargs) diff --cc mibuild/mibuild/platforms/__init__.py index 00000000,00000000..e69de29b new file mode 100644 --- /dev/null +++ b/mibuild/mibuild/platforms/__init__.py diff --cc mibuild/mibuild/platforms/de0nano.py index 00000000,00000000..567f8749 new file mode 100644 --- /dev/null +++ b/mibuild/mibuild/platforms/de0nano.py @@@ -1,0 -1,0 +1,95 @@@ ++# This file is Copyright (c) 2013 Florent Kermarrec ++# License: BSD ++ ++from mibuild.generic_platform import * ++from mibuild.altera_quartus import AlteraQuartusPlatform, CRG_SE ++ ++_io = [ ++ ("clk50", 0, Pins("R8"), IOStandard("3.3-V LVTTL")), ++ ++ ("user_led", 0, Pins("A15"), IOStandard("3.3-V LVTTL")), ++ ("user_led", 1, Pins("A13"), IOStandard("3.3-V LVTTL")), ++ ("user_led", 2, Pins("B13"), IOStandard("3.3-V LVTTL")), ++ ("user_led", 3, Pins("A11"), IOStandard("3.3-V LVTTL")), ++ ("user_led", 4, Pins("D1"), IOStandard("3.3-V LVTTL")), ++ ("user_led", 5, Pins("F3"), IOStandard("3.3-V LVTTL")), ++ ("user_led", 6, Pins("B1"), IOStandard("3.3-V LVTTL")), ++ ("user_led", 7, Pins("L3"), IOStandard("3.3-V LVTTL")), ++ ++ ("key", 0, Pins("J15"), IOStandard("3.3-V LVTTL")), ++ ("key", 1, Pins("E1"), IOStandard("3.3-V LVTTL")), ++ ++ ("sw", 0, Pins("M1"), IOStandard("3.3-V LVTTL")), ++ ("sw", 1, Pins("T9"), IOStandard("3.3-V LVTTL")), ++ ("sw", 2, Pins("B9"), IOStandard("3.3-V LVTTL")), ++ ("sw", 3, Pins("M15"), IOStandard("3.3-V LVTTL")), ++ ++ ("serial", 0, ++ Subsignal("tx", Pins("D3"), IOStandard("3.3-V LVTTL")), ++ Subsignal("rx", Pins("C3"), IOStandard("3.3-V LVTTL")) ++ ), ++ ++ ("sdram_clock", 0, Pins("R4"), IOStandard("3.3-V LVTTL")), ++ ("sdram", 0, ++ Subsignal("a", Pins("P2 N5 N6 M8 P8 T7 N8 T6 R1 P1 N2 N1 L4")), ++ Subsignal("ba", Pins("M7 M6")), ++ Subsignal("cs_n", Pins("P6")), ++ Subsignal("cke", Pins("L7")), ++ Subsignal("ras_n", Pins("L2")), ++ Subsignal("cas_n", Pins("L1")), ++ Subsignal("we_n", Pins("C2")), ++ Subsignal("dq", Pins("G2 G1 L8 K5 K2 J2 J1 R7 T4 T2 T3 R3 R5 P3 N3 K1")), ++ Subsignal("dqm", Pins("R6","T5")), ++ IOStandard("3.3-V LVTTL") ++ ), ++ ++ ("epcs", 0, ++ Subsignal("data0", Pins("H2")), ++ Subsignal("dclk", Pins("H1")), ++ Subsignal("ncs0", Pins("D2")), ++ Subsignal("asd0", Pins("C1")), ++ IOStandard("3.3-V LVTTL") ++ ), ++ ++ ("i2c", 0, ++ Subsignal("sclk", Pins("F2")), ++ Subsignal("sdat", Pins("F1")), ++ IOStandard("3.3-V LVTTL") ++ ), ++ ++ ("g_sensor", 0, ++ Subsignal("cs_n", Pins("G5")), ++ Subsignal("int", Pins("M2")), ++ IOStandard("3.3-V LVTTL") ++ ), ++ ++ ("adc", 0, ++ Subsignal("cs_n", Pins("A10")), ++ Subsignal("saddr", Pins("B10")), ++ Subsignal("sclk", Pins("B14")), ++ Subsignal("sdat", Pins("A9")), ++ IOStandard("3.3-V LVTTL") ++ ), ++ ++ ("gpio_0", 0, ++ Pins("D3 C3 A2 A3 B3 B4 A4 B5 A5 D5 B6 A6 B7 D6 A7 C6", ++ "C8 E6 E7 D8 E8 F8 F9 E9 C9 D9 E11 E10 C11 B11 A12 D11", ++ "D12 B12"), ++ IOStandard("3.3-V LVTTL") ++ ), ++ ("gpio_1", 0, ++ Pins("F13 T15 T14 T13 R13 T12 R12 T11 T10 R11 P11 R10 N12 P9 N9 N11", ++ "L16 K16 R16 L15 P15 P16 R14 N16 N15 P14 L14 N14 M10 L13 J16 K15", ++ "J13 J14"), ++ IOStandard("3.3-V LVTTL") ++ ), ++ ("gpio_2", 0, ++ Pins("A14 B16 C14 C16 C15 D16 D15 D14 F15 F16 F14 G16 G15"), ++ IOStandard("3.3-V LVTTL") ++ ), ++] ++ ++class Platform(AlteraQuartusPlatform): ++ def __init__(self): ++ AlteraQuartusPlatform.__init__(self, "EP4CE22F17C6", _io, ++ lambda p: CRG_SE(p, "clk50", "key", 20.0, True)) diff --cc mibuild/mibuild/platforms/kc705.py index 00000000,00000000..bb47edcc new file mode 100644 --- /dev/null +++ b/mibuild/mibuild/platforms/kc705.py @@@ -1,0 -1,0 +1,84 @@@ ++from mibuild.generic_platform import * ++from mibuild.xilinx_ise import XilinxISEPlatform, CRG_DS ++ ++_io = [ ++ ("user_led", 0, Pins("AB8"), IOStandard("LVCMOS15")), ++ ("user_led", 1, Pins("AA8"), IOStandard("LVCMOS15")), ++ ("user_led", 2, Pins("AC9"), IOStandard("LVCMOS15")), ++ ("user_led", 3, Pins("AB9"), IOStandard("LVCMOS15")), ++ ("user_led", 4, Pins("AE26"), IOStandard("LVCMOS25")), ++ ("user_led", 5, Pins("G19"), IOStandard("LVCMOS25")), ++ ("user_led", 6, Pins("E18"), IOStandard("LVCMOS25")), ++ ("user_led", 7, Pins("F16"), IOStandard("LVCMOS25")), ++ ++ ("cpu_reset", 0, Pins("AB7"), IOStandard("LVCMOS15")), ++ ++ ("user_btn_c", 0, Pins("G12"), IOStandard("LVCMOS25")), ++ ("user_btn_n", 0, Pins("AA12"), IOStandard("LVCMOS15")), ++ ("user_btn_s", 0, Pins("AB12"), IOStandard("LVCMOS15")), ++ ("user_btn_w", 0, Pins("AC6"), IOStandard("LVCMOS15")), ++ ("user_btn_e", 0, Pins("AG5"), IOStandard("LVCMOS15")), ++ ++ ("user_dip_btn", 0, Pins("Y29"), IOStandard("LVCMOS25")), ++ ("user_dip_btn", 1, Pins("W29"), IOStandard("LVCMOS25")), ++ ("user_dip_btn", 2, Pins("AA28"), IOStandard("LVCMOS25")), ++ ("user_dip_btn", 3, Pins("Y28"), IOStandard("LVCMOS25")), ++ ++ ("clk200", 0, ++ Subsignal("p", Pins("AD12"), IOStandard("LVDS")), ++ Subsignal("n", Pins("AD11"), IOStandard("LVDS")) ++ ), ++ ++ ("clk156", 0, ++ Subsignal("p", Pins("K28"), IOStandard("LVDS_25")), ++ Subsignal("n", Pins("K29"), IOStandard("LVDS_25")) ++ ), ++ ++ ("i2c", 0, ++ Subsignal("scl", Pins("K21")), ++ Subsignal("sda", Pins("L21")), ++ IOStandard("LVCMOS25")), ++ ++ ("serial", 0, ++ Subsignal("cts", Pins("L27")), ++ Subsignal("rts", Pins("K23")), ++ Subsignal("tx", Pins("K24")), ++ Subsignal("rx", Pins("M19")), ++ IOStandard("LVCMOS25")), ++ ++ ("mmc", 0, ++ Subsignal("wp", Pins("Y21")), ++ Subsignal("det", Pins("AA21")), ++ Subsignal("cmd", Pins("AB22")), ++ Subsignal("clk", Pins("AB23")), ++ Subsignal("dat", Pins("AC20 AA23 AA22 AC21")), ++ IOStandard("LVCMOS25")), ++ ++ ("lcd", 0, ++ Subsignal("db", Pins("AA13 AA10 AA11 Y10")), ++ Subsignal("e", Pins("AB10")), ++ Subsignal("rs", Pins("Y11")), ++ Subsignal("rw", Pins("AB13")), ++ IOStandard("LVCMOS15")), ++ ++ ("rotary", 0, ++ Subsignal("a", Pins("Y26")), ++ Subsignal("b", Pins("Y25")), ++ Subsignal("push", Pins("AA26")), ++ IOStandard("LVCMOS25")), ++ ++ ("hdmi", 0, ++ Subsignal("d", Pins("B23 A23 E23 D23 F25 E25 E24 D24 F26 E26 G23 G24 J19 H19 L17 L18 K19 K20")), ++ Subsignal("de", Pins("H17")), ++ Subsignal("clk", Pins("K18")), ++ Subsignal("vsync", Pins("H20")), ++ Subsignal("hsync", Pins("J18")), ++ Subsignal("int", Pins("AH24")), ++ Subsignal("spdif", Pins("J17")), ++ Subsignal("spdif_out", Pins("G20")), ++ IOStandard("LVCMOS25")), ++] ++ ++class Platform(XilinxISEPlatform): ++ def __init__(self, crg_factory=lambda p: CRG_DS(p, "user_clk", "cpu_reset", 6.4)): ++ XilinxISEPlatform.__init__(self, "xc7k325t-ffg900-1", _io, crg_factory) diff --cc mibuild/mibuild/platforms/lx9_microboard.py index 00000000,00000000..955aea52 new file mode 100644 --- /dev/null +++ b/mibuild/mibuild/platforms/lx9_microboard.py @@@ -1,0 -1,0 +1,119 @@@ ++from mibuild.generic_platform import * ++from mibuild.xilinx_ise import XilinxISEPlatform, CRG_SE ++ ++_io = [ ++ ("user_btn", 0, Pins("V4"), IOStandard("LVCMOS33"), ++ Misc("PULLDOWN"), Misc("TIG")), ++ ++ ("user_led", 0, Pins("P4"), Misc("SLEW=QUIETIO"), IOStandard("LVCMOS18")), ++ ("user_led", 1, Pins("L6"), Misc("SLEW=QUIETIO"), IOStandard("LVCMOS18")), ++ ("user_led", 2, Pins("F5"), Misc("SLEW=QUIETIO"), IOStandard("LVCMOS18")), ++ ("user_led", 3, Pins("C2"), Misc("SLEW=QUIETIO"), IOStandard("LVCMOS18")), ++ ++ ("user_dip", 0, Pins("B3"), Misc("PULLDOWN"), IOStandard("LVCMOS33")), ++ ("user_dip", 1, Pins("A3"), Misc("PULLDOWN"), IOStandard("LVCMOS33")), ++ ("user_dip", 2, Pins("B4"), Misc("PULLDOWN"), IOStandard("LVCMOS33")), ++ ("user_dip", 3, Pins("A4"), Misc("PULLDOWN"), IOStandard("LVCMOS33")), ++ ++ # TI CDCE913 programmable triple-output PLL ++ ("clk_y1", 0, Pins("V10"), IOStandard("LVCMOS33")), # default: 40 MHz ++ ("clk_y2", 0, Pins("K15"), IOStandard("LVCMOS33")), # default: 66 2/3 MHz ++ ("clk_y3", 0, Pins("C10"), IOStandard("LVCMOS33")), # default: 100 MHz ++ ++ # Maxim DS1088LU oscillator, not populated ++ ("clk_backup", 0, Pins("R8"), IOStandard("LVCMOS33")), ++ ++ # TI CDCE913 PLL I2C control ++ ("pll", 0, ++ Subsignal("scl", Pins("P12")), ++ Subsignal("sda", Pins("U13")), ++ Misc("PULLUP"), ++ IOStandard("LVCMOS33")), ++ ++ # Micron N25Q128 SPI Flash ++ ("spiflash", 0, ++ Subsignal("clk", Pins("R15")), ++ Subsignal("cs_n", Pins("V3")), ++ Subsignal("dq", Pins("T13 R13 T14 V14")), ++ IOStandard("LVCMOS33")), ++ ++ # PMOD extension connectors ++ ("pmod", 0, ++ Subsignal("d", Pins("F15 F16 C17 C18 F14 G14 D17 D18")), ++ IOStandard("LVCMOS33")), ++ ("pmod", 1, ++ Subsignal("d", Pins("H12 G13 E16 E18 K12 K13 F17 F18")), ++ IOStandard("LVCMOS33")), ++ ++ ("serial", 0, ++ Subsignal("tx", Pins("T7"), Misc("SLEW=SLOW")), ++ Subsignal("rx", Pins("R7"), Misc("PULLUP")), ++ IOStandard("LVCMOS33")), ++ ++ ("ddram_clock", 0, ++ Subsignal("p", Pins("G3")), ++ Subsignal("n", Pins("G1")), ++ IOStandard("MOBILE_DDR")), # actually DIFF_ ++ ++ # Micron MT46H32M16LFBF-5 LPDDR ++ ("ddram", 0, ++ Subsignal("a", Pins("J7 J6 H5 L7 F3 H4 H3 H6 " ++ "D2 D1 F4 D3 G6")), ++ Subsignal("ba", Pins("F2 F1")), ++ Subsignal("dq", Pins("L2 L1 K2 K1 H2 H1 J3 J1 " ++ "M3 M1 N2 N1 T2 T1 U2 U1")), ++ Subsignal("cke", Pins("H7")), ++ Subsignal("we_n", Pins("E3")), ++ Subsignal("cs_n", Pins("K6")), # NC! ++ Subsignal("cas_n", Pins("K5")), ++ Subsignal("ras_n", Pins("L5")), ++ Subsignal("dm", Pins("K3", "K4")), ++ Subsignal("dqs", Pins("L4", "P2")), ++ Subsignal("rzq", Pins("N4")), ++ IOStandard("MOBILE_DDR")), ++ ++ # Nat Semi DP83848J 10/100 Ethernet PHY ++ # pull-ups on rx_data set phy addr to 11110b ++ # and prevent isolate mode (addr 00000b) ++ ("eth_clocks", 0, ++ Subsignal("rx", Pins("L15")), ++ Subsignal("tx", Pins("H17")), ++ IOStandard("LVCMOS33")), ++ ++ ("eth", 0, ++ Subsignal("col", Pins("M18"), Misc("PULLDOWN")), ++ Subsignal("crs", Pins("N17"), Misc("PULLDOWN")), ++ Subsignal("mdc", Pins("M16")), ++ Subsignal("mdio", Pins("L18")), ++ Subsignal("rst_n", Pins("T18"), Misc("TIG")), ++ Subsignal("rx_data", Pins("T17 N16 N15 P18"), Misc("PULLUP")), ++ Subsignal("dv", Pins("P17")), ++ Subsignal("rx_er", Pins("N18")), ++ Subsignal("tx_data", Pins("K18 K17 J18 J16")), ++ Subsignal("tx_en", Pins("L17")), ++ Subsignal("tx_er", Pins("L16")), # NC! ++ IOStandard("LVCMOS33")), ++ ] ++ ++ ++class Platform(XilinxISEPlatform): ++ def __init__(self): ++ XilinxISEPlatform.__init__(self, "xc6slx9-2csg324", _io, ++ lambda p: CRG_SE(p, "clk_y3", "user_btn", 10.)) ++ self.add_platform_command(""" ++CONFIG VCCAUX = "3.3"; ++""") ++ ++ def do_finalize(self, fragment): ++ try: ++ eth_clocks = self.lookup_request("eth_clocks") ++ self.add_platform_command(""" ++NET "{phy_rx_clk}" TNM_NET = "GRPphy_rx_clk"; ++NET "{phy_tx_clk}" TNM_NET = "GRPphy_tx_clk"; ++TIMESPEC "TSphy_rx_clk" = PERIOD "GRPphy_rx_clk" 40 ns HIGH 50%; ++TIMESPEC "TSphy_tx_clk" = PERIOD "GRPphy_tx_clk" 40 ns HIGH 50%; ++TIMESPEC "TSphy_tx_clk_io" = FROM "GRPphy_tx_clk" TO "PADS" 10 ns; ++TIMESPEC "TSphy_rx_clk_io" = FROM "PADS" TO "GRPphy_rx_clk" 10 ns; ++""", phy_rx_clk=eth_clocks.rx, phy_tx_clk=eth_clocks.tx) ++ except ContraintError: ++ pass diff --cc mibuild/mibuild/platforms/m1.py index 00000000,00000000..d72a6bde new file mode 100644 --- /dev/null +++ b/mibuild/mibuild/platforms/m1.py @@@ -1,0 -1,0 +1,155 @@@ ++from mibuild.generic_platform import * ++from mibuild.xilinx_ise import XilinxISEPlatform, CRG_SE ++ ++_io = [ ++ ("user_led", 0, Pins("B16"), IOStandard("LVCMOS33"), Drive(24), Misc("SLEW=QUIETIO")), ++ ("user_led", 1, Pins("A16"), IOStandard("LVCMOS33"), Drive(24), Misc("SLEW=QUIETIO")), ++ ++ ("user_btn", 0, Pins("AB4"), IOStandard("LVCMOS33")), ++ ("user_btn", 1, Pins("AA4"), IOStandard("LVCMOS33")), ++ ("user_btn", 2, Pins("AB5"), IOStandard("LVCMOS33")), ++ ++ ("clk50", 0, Pins("AB11"), IOStandard("LVCMOS33")), ++ ++ # When executing softcore code in-place from the flash, we want ++ # the flash reset to be released before the system reset. ++ ("norflash_rst_n", 0, Pins("P22"), IOStandard("LVCMOS33"), Misc("SLEW=FAST"), Drive(8)), ++ ("norflash", 0, ++ Subsignal("adr", Pins("L22 L20 K22 K21 J19 H20 F22", ++ "F21 K17 J17 E22 E20 H18 H19 F20", ++ "G19 C22 C20 D22 D21 F19 F18 D20 D19")), ++ Subsignal("d", Pins("AA20 U14 U13 AA6 AB6 W4 Y4 Y7", ++ "AA2 AB2 V15 AA18 AB18 Y13 AA12 AB12"), Misc("PULLDOWN")), ++ Subsignal("oe_n", Pins("M22")), ++ Subsignal("we_n", Pins("N20")), ++ Subsignal("ce_n", Pins("M21")), ++ IOStandard("LVCMOS33"), Misc("SLEW=FAST"), Drive(8) ++ ), ++ ++ ("serial", 0, ++ Subsignal("tx", Pins("L17"), IOStandard("LVCMOS33"), Misc("SLEW=SLOW")), ++ Subsignal("rx", Pins("K18"), IOStandard("LVCMOS33"), Misc("PULLUP")) ++ ), ++ ++ ("ddram_clock", 0, ++ Subsignal("p", Pins("M3")), ++ Subsignal("n", Pins("L4")), ++ IOStandard("SSTL2_I") ++ ), ++ ("ddram", 0, ++ Subsignal("a", Pins("B1 B2 H8 J7 E4 D5 K7 F5 G6 C1 C3 D1 D2")), ++ Subsignal("ba", Pins("A2 E6")), ++ Subsignal("cs_n", Pins("F7")), ++ Subsignal("cke", Pins("G7")), ++ Subsignal("ras_n", Pins("E5")), ++ Subsignal("cas_n", Pins("C4")), ++ Subsignal("we_n", Pins("D3")), ++ Subsignal("dq", Pins("Y2 W3 W1 P8 P7 P6 P5 T4 T3", ++ "U4 V3 N6 N7 M7 M8 R4 P4 M6 L6 P3 N4", ++ "M5 V2 V1 U3 U1 T2 T1 R3 R1 P2 P1")), ++ Subsignal("dm", Pins("E1 E3 F3 G4")), ++ Subsignal("dqs", Pins("F1 F2 H5 H6")), ++ IOStandard("SSTL2_I") ++ ), ++ ++ ("eth_clocks", 0, ++ Subsignal("phy", Pins("M20")), ++ Subsignal("rx", Pins("H22")), ++ Subsignal("tx", Pins("H21")), ++ IOStandard("LVCMOS33") ++ ), ++ ("eth", 0, ++ Subsignal("rst_n", Pins("R22")), ++ Subsignal("dv", Pins("V21")), ++ Subsignal("rx_er", Pins("V22")), ++ Subsignal("rx_data", Pins("U22 U20 T22 T21")), ++ Subsignal("tx_en", Pins("N19")), ++ Subsignal("tx_er", Pins("M19")), ++ Subsignal("tx_data", Pins("M16 L15 P19 P20")), ++ Subsignal("col", Pins("W20")), ++ Subsignal("crs", Pins("W22")), ++ IOStandard("LVCMOS33") ++ ), ++ ++ ("vga_clock", 0, Pins("A11"), IOStandard("LVCMOS33")), ++ ("vga", 0, ++ Subsignal("r", Pins("C6 B6 A6 C7 A7 B8 A8 D9")), ++ Subsignal("g", Pins("C8 C9 A9 D7 D8 D10 C10 B10")), ++ Subsignal("b", Pins("D11 C12 B12 A12 C13 A13 D14 C14")), ++ Subsignal("hsync_n", Pins("A14")), ++ Subsignal("vsync_n", Pins("C15")), ++ Subsignal("psave_n", Pins("B14")), ++ IOStandard("LVCMOS33") ++ ), ++ ++ ("mmc", 0, ++ Subsignal("clk", Pins("A10")), ++ Subsignal("cmd", Pins("B18")), ++ Subsignal("dat", Pins("A18 E16 C17 A17")), ++ IOStandard("LVCMOS33") ++ ), ++ ++ # Digital video mixer extension board ++ ("dvi_in", 0, ++ Subsignal("clk", Pins("A20")), ++ Subsignal("data0_n", Pins("A21")), ++ Subsignal("data1", Pins("B21")), ++ Subsignal("data2_n", Pins("B22")), ++ Subsignal("scl", Pins("G16")), ++ Subsignal("sda", Pins("G17")), ++ IOStandard("LVCMOS33") ++ ), ++ ("dvi_in", 1, ++ Subsignal("clk", Pins("H17")), ++ Subsignal("data0_n", Pins("H16")), ++ Subsignal("data1", Pins("F17")), ++ Subsignal("data2_n", Pins("F16")), ++ Subsignal("scl", Pins("J16")), ++ Subsignal("sda", Pins("K16")), ++ IOStandard("LVCMOS33") ++ ), ++ ("dvi_pots", 0, ++ Subsignal("charge", Pins("A18")), # SD_DAT0 ++ Subsignal("blackout", Pins("C17")), # SD_DAT2 ++ Subsignal("crossfade", Pins("A17")), # SD_DAT3 ++ IOStandard("LVCMOS33") ++ ) ++] ++ ++class Platform(XilinxISEPlatform): ++ def __init__(self): ++ XilinxISEPlatform.__init__(self, "xc6slx45-fgg484-2", _io, ++ lambda p: CRG_SE(p, "clk50", None)) ++ ++ def do_finalize(self, fragment): ++ try: ++ self.add_platform_command(""" ++NET "{clk50}" TNM_NET = "GRPclk50"; ++TIMESPEC "TSclk50" = PERIOD "GRPclk50" 20 ns HIGH 50%; ++""", clk50=self.lookup_request("clk50")) ++ except ConstraintError: ++ pass ++ ++ try: ++ eth_clocks = self.lookup_request("eth_clocks") ++ self.add_platform_command(""" ++NET "{phy_rx_clk}" TNM_NET = "GRPphy_rx_clk"; ++NET "{phy_tx_clk}" TNM_NET = "GRPphy_tx_clk"; ++TIMESPEC "TSphy_rx_clk" = PERIOD "GRPphy_rx_clk" 40 ns HIGH 50%; ++TIMESPEC "TSphy_tx_clk" = PERIOD "GRPphy_tx_clk" 40 ns HIGH 50%; ++TIMESPEC "TSphy_tx_clk_io" = FROM "GRPphy_tx_clk" TO "PADS" 10 ns; ++TIMESPEC "TSphy_rx_clk_io" = FROM "PADS" TO "GRPphy_rx_clk" 10 ns; ++""", phy_rx_clk=eth_clocks.rx, phy_tx_clk=eth_clocks.tx) ++ except ConstraintError: ++ pass ++ ++ for i in range(2): ++ si = "dviclk"+str(i) ++ try: ++ self.add_platform_command(""" ++NET "{dviclk}" TNM_NET = "GRP"""+si+""""; ++NET "{dviclk}" CLOCK_DEDICATED_ROUTE = FALSE; ++TIMESPEC "TS"""+si+"""" = PERIOD "GRP"""+si+"""" 26.7 ns HIGH 50%; ++""", dviclk=self.lookup_request("dvi_in", i).clk) ++ except ConstraintError: ++ pass diff --cc mibuild/mibuild/platforms/mixxeo.py index 00000000,00000000..12b242fb new file mode 100644 --- /dev/null +++ b/mibuild/mibuild/platforms/mixxeo.py @@@ -1,0 -1,0 +1,191 @@@ ++from mibuild.generic_platform import * ++from mibuild.xilinx_ise import XilinxISEPlatform, CRG_SE ++ ++_io = [ ++ ("user_led", 0, Pins("V5"), IOStandard("LVCMOS33"), Drive(24), Misc("SLEW=QUIETIO")), ++ ++ ("clk50", 0, Pins("AB13"), IOStandard("LVCMOS33")), ++ ++ # When executing softcore code in-place from the flash, we want ++ # the flash reset to be released before the system reset. ++ ("norflash_rst_n", 0, Pins("P22"), IOStandard("LVCMOS33"), Misc("SLEW=FAST"), Drive(8)), ++ ("norflash", 0, ++ Subsignal("adr", Pins("L22 L20 K22 K21 J19 H20 F22", ++ "F21 K17 J17 E22 E20 H18 H19 F20", ++ "G19 C22 C20 D22 D21 F19 F18 D20 D19")), ++ Subsignal("d", Pins("AA20 U14 U13 AA6 AB6 W4 Y4 Y7", ++ "AA2 AB2 V15 AA18 AB18 Y13 AA12 AB12"), Misc("PULLDOWN")), ++ Subsignal("oe_n", Pins("M22")), ++ Subsignal("we_n", Pins("N20")), ++ Subsignal("ce_n", Pins("M21")), ++ IOStandard("LVCMOS33"), Misc("SLEW=FAST"), Drive(8) ++ ), ++ ++ ("serial", 0, ++ Subsignal("tx", Pins("L17"), IOStandard("LVCMOS33"), Misc("SLEW=SLOW")), ++ Subsignal("rx", Pins("K18"), IOStandard("LVCMOS33"), Misc("PULLUP")) ++ ), ++ ++ ("ddram_clock", 0, ++ Subsignal("p", Pins("M3")), ++ Subsignal("n", Pins("L4")), ++ IOStandard("SSTL2_I") ++ ), ++ ("ddram", 0, ++ Subsignal("a", Pins("B1 B2 H8 J7 E4 D5 K7 F5 G6 C1 C3 D1 D2")), ++ Subsignal("ba", Pins("A2 E6")), ++ Subsignal("cs_n", Pins("F7")), ++ Subsignal("cke", Pins("G7")), ++ Subsignal("ras_n", Pins("E5")), ++ Subsignal("cas_n", Pins("C4")), ++ Subsignal("we_n", Pins("D3")), ++ Subsignal("dq", Pins("Y2 W3 W1 P8 P7 P6 P5 T4 T3", ++ "U4 V3 N6 N7 M7 M8 R4 P4 M6 L6 P3 N4", ++ "M5 V2 V1 U3 U1 T2 T1 R3 R1 P2 P1")), ++ Subsignal("dm", Pins("E1 E3 F3 G4")), ++ Subsignal("dqs", Pins("F1 F2 H5 H6")), ++ IOStandard("SSTL2_I") ++ ), ++ ++ ("eth_clocks", 0, ++ Subsignal("phy", Pins("M20")), ++ Subsignal("rx", Pins("H22")), ++ Subsignal("tx", Pins("H21")), ++ IOStandard("LVCMOS33") ++ ), ++ ("eth", 0, ++ Subsignal("rst_n", Pins("R22")), ++ Subsignal("dv", Pins("V21")), ++ Subsignal("rx_er", Pins("V22")), ++ Subsignal("rx_data", Pins("U22 U20 T22 T21")), ++ Subsignal("tx_en", Pins("N19")), ++ Subsignal("tx_er", Pins("M19")), ++ Subsignal("tx_data", Pins("M16 L15 P19 P20")), ++ Subsignal("col", Pins("W20")), ++ Subsignal("crs", Pins("W22")), ++ IOStandard("LVCMOS33") ++ ), ++ ++ ("vga_out", 0, ++ Subsignal("clk", Pins("A10")), ++ Subsignal("r", Pins("C6 B6 A6 C7 A7 B8 A8 D9")), ++ Subsignal("g", Pins("C8 C9 A9 D7 D8 D10 C10 B10")), ++ Subsignal("b", Pins("D11 C12 B12 A12 C13 A13 D14 C14")), ++ Subsignal("hsync_n", Pins("A14")), ++ Subsignal("vsync_n", Pins("C15")), ++ Subsignal("psave_n", Pins("B14")), ++ IOStandard("LVCMOS33") ++ ), ++ ("dvi_out", 0, ++ Subsignal("clk_p", Pins("W12"), IOStandard("TMDS_33")), ++ Subsignal("clk_n", Pins("Y12"), IOStandard("TMDS_33")), ++ Subsignal("data0_p", Pins("Y16"), IOStandard("TMDS_33")), ++ Subsignal("data0_n", Pins("W15"), IOStandard("TMDS_33")), ++ Subsignal("data1_p", Pins("AA16"), IOStandard("TMDS_33")), ++ Subsignal("data1_n", Pins("AB16"), IOStandard("TMDS_33")), ++ Subsignal("data2_p", Pins("Y15"), IOStandard("TMDS_33")), ++ Subsignal("data2_n", Pins("AB15"), IOStandard("TMDS_33")), ++ ), ++ ++ ("mmc", 0, ++ Subsignal("clk", Pins("J3")), ++ Subsignal("cmd", Pins("K1")), ++ Subsignal("dat", Pins("J6 K6 N1 K5")), ++ IOStandard("LVCMOS33") ++ ), ++ ++ ("dvi_in", 0, ++ Subsignal("clk_p", Pins("K20"), IOStandard("TMDS_33")), ++ Subsignal("clk_n", Pins("K19"), IOStandard("TMDS_33")), ++ Subsignal("data0_p", Pins("B21"), IOStandard("TMDS_33")), ++ Subsignal("data0_n", Pins("B22"), IOStandard("TMDS_33")), ++ Subsignal("data1_p", Pins("A20"), IOStandard("TMDS_33")), ++ Subsignal("data1_n", Pins("A21"), IOStandard("TMDS_33")), ++ Subsignal("data2_p", Pins("K16"), IOStandard("TMDS_33")), ++ Subsignal("data2_n", Pins("J16"), IOStandard("TMDS_33")), ++ Subsignal("scl", Pins("G20"), IOStandard("LVCMOS33")), ++ Subsignal("sda", Pins("H16"), IOStandard("LVCMOS33")), ++ Subsignal("hpd_notif", Pins("G22"), IOStandard("LVCMOS33")), ++ Subsignal("hpd_en", Pins("G17"), IOStandard("LVCMOS33")) ++ ), ++ ("dvi_in", 1, ++ Subsignal("clk_p", Pins("C11"), IOStandard("TMDS_33")), ++ Subsignal("clk_n", Pins("A11"), IOStandard("TMDS_33")), ++ Subsignal("data0_p", Pins("B18"), IOStandard("TMDS_33")), ++ Subsignal("data0_n", Pins("A18"), IOStandard("TMDS_33")), ++ Subsignal("data1_p", Pins("C17"), IOStandard("TMDS_33")), ++ Subsignal("data1_n", Pins("A17"), IOStandard("TMDS_33")), ++ Subsignal("data2_p", Pins("E16"), IOStandard("TMDS_33")), ++ Subsignal("data2_n", Pins("D17"), IOStandard("TMDS_33")), ++ Subsignal("scl", Pins("F17"), IOStandard("LVCMOS33")), ++ Subsignal("sda", Pins("F16"), IOStandard("LVCMOS33")), ++ Subsignal("hpd_notif", Pins("G16"), IOStandard("LVCMOS33")), ++ Subsignal("hpd_en", Pins("B20"), IOStandard("LVCMOS33")) ++ ), ++ ("dvi_in", 2, ++ Subsignal("clk_p", Pins("Y11"), IOStandard("TMDS_33")), ++ Subsignal("clk_n", Pins("AB11"), IOStandard("TMDS_33")), ++ Subsignal("data0_p", Pins("V11"), IOStandard("TMDS_33")), ++ Subsignal("data0_n", Pins("W11"), IOStandard("TMDS_33")), ++ Subsignal("data1_p", Pins("AA10"), IOStandard("TMDS_33")), ++ Subsignal("data1_n", Pins("AB10"), IOStandard("TMDS_33")), ++ Subsignal("data2_p", Pins("R11"), IOStandard("TMDS_33")), ++ Subsignal("data2_n", Pins("T11"), IOStandard("TMDS_33")), ++ Subsignal("scl", Pins("C16"), IOStandard("LVCMOS33")), ++ Subsignal("sda", Pins("B16"), IOStandard("LVCMOS33")), ++ Subsignal("hpd_notif", Pins("D6"), IOStandard("LVCMOS33")), ++ Subsignal("hpd_en", Pins("A4"), IOStandard("LVCMOS33")) ++ ), ++ ("dvi_in", 3, ++ Subsignal("clk_p", Pins("J20"), IOStandard("TMDS_33")), ++ Subsignal("clk_n", Pins("J22"), IOStandard("TMDS_33")), ++ Subsignal("data0_p", Pins("P18"), IOStandard("TMDS_33")), ++ Subsignal("data0_n", Pins("R19"), IOStandard("TMDS_33")), ++ Subsignal("data1_p", Pins("P17"), IOStandard("TMDS_33")), ++ Subsignal("data1_n", Pins("N16"), IOStandard("TMDS_33")), ++ Subsignal("data2_p", Pins("M17"), IOStandard("TMDS_33")), ++ Subsignal("data2_n", Pins("M18"), IOStandard("TMDS_33")), ++ Subsignal("scl", Pins("P21"), IOStandard("LVCMOS33")), ++ Subsignal("sda", Pins("N22"), IOStandard("LVCMOS33")), ++ Subsignal("hpd_notif", Pins("H17"), IOStandard("LVCMOS33")), ++ Subsignal("hpd_en", Pins("C19"), IOStandard("LVCMOS33")) ++ ), ++] ++ ++class Platform(XilinxISEPlatform): ++ def __init__(self): ++ XilinxISEPlatform.__init__(self, "xc6slx45-fgg484-2", _io, ++ lambda p: CRG_SE(p, "clk50", None)) ++ self.add_platform_command("CONFIG VCCAUX=\"3.3\";\n") ++ ++ def do_finalize(self, fragment): ++ try: ++ self.add_platform_command(""" ++NET "{clk50}" TNM_NET = "GRPclk50"; ++TIMESPEC "TSclk50" = PERIOD "GRPclk50" 20 ns HIGH 50%; ++""", clk50=self.lookup_request("clk50")) ++ except ConstraintError: ++ pass ++ ++ try: ++ eth_clocks = self.lookup_request("eth_clocks") ++ self.add_platform_command(""" ++NET "{phy_rx_clk}" TNM_NET = "GRPphy_rx_clk"; ++NET "{phy_tx_clk}" TNM_NET = "GRPphy_tx_clk"; ++TIMESPEC "TSphy_rx_clk" = PERIOD "GRPphy_rx_clk" 40 ns HIGH 50%; ++TIMESPEC "TSphy_tx_clk" = PERIOD "GRPphy_tx_clk" 40 ns HIGH 50%; ++TIMESPEC "TSphy_tx_clk_io" = FROM "GRPphy_tx_clk" TO "PADS" 10 ns; ++TIMESPEC "TSphy_rx_clk_io" = FROM "PADS" TO "GRPphy_rx_clk" 10 ns; ++""", phy_rx_clk=eth_clocks.rx, phy_tx_clk=eth_clocks.tx) ++ except ConstraintError: ++ pass ++ ++ for i in range(4): ++ si = "dviclk"+str(i) ++ try: ++ self.add_platform_command(""" ++NET "{dviclk}" TNM_NET = "GRP"""+si+""""; ++TIMESPEC "TS"""+si+"""" = PERIOD "GRP"""+si+"""" 12.00 ns HIGH 50%; ++""", dviclk=self.lookup_request("dvi_in", i).clk_p) ++ except ConstraintError: ++ pass diff --cc mibuild/mibuild/platforms/ml605.py index 00000000,00000000..72c49e67 new file mode 100644 --- /dev/null +++ b/mibuild/mibuild/platforms/ml605.py @@@ -1,0 -1,0 +1,56 @@@ ++from mibuild.generic_platform import * ++from mibuild.xilinx_ise import XilinxISEPlatform, CRG_DS ++ ++_io = [ ++ # System clock (Differential 200MHz) ++ ("clk200", 0, ++ Subsignal("p", Pins("J9"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")), ++ Subsignal("n", Pins("H9"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")) ++ ), ++ ++ # User clock (66MHz) ++ ("clk66", 0, Pins("U23"), IOStandard("LVCMOS25")), ++ ++ # CPU reset switch ++ ("cpu_reset", 0, Pins("H10"), IOStandard("SSTL15")), ++ ++ # LEDs ++ ("user_led", 0, Pins("AC22"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")), ++ ("user_led", 1, Pins("AC24"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")), ++ ("user_led", 2, Pins("AE22"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")), ++ ("user_led", 3, Pins("AE23"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")), ++ ("user_led", 4, Pins("AB23"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")), ++ ("user_led", 5, Pins("AG23"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")), ++ ("user_led", 6, Pins("AE24"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")), ++ ("user_led", 7, Pins("AD24"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")), ++ ++ # USB-to-UART ++ ("serial", 0, ++ Subsignal("tx", Pins("J25"), IOStandard("LVCMOS25")), ++ Subsignal("rx", Pins("J24"), IOStandard("LVCMOS25")) ++ ), ++ ++ # 10/100/1000 Tri-Speed Ethernet PHY ++ ("eth_clocks", 0, ++ Subsignal("rx", Pins("AP11")), ++ Subsignal("tx", Pins("AD12")), ++ IOStandard("LVCMOS25") ++ ), ++ ("eth", 0, ++ Subsignal("rst_n", Pins("AH13")), ++ Subsignal("dv", Pins("AM13")), ++ Subsignal("rx_er", Pins("AG12")), ++ Subsignal("rx_data", Pins("AN13 AF14 AE14 AN12 AM12 AD11 AC12 AC13")), ++ Subsignal("tx_en", Pins("AJ10")), ++ Subsignal("tx_er", Pins("AH10")), ++ Subsignal("tx_data", Pins("AM11 AL11 AG10 AG11 AL10 AM10 AE11 AF11")), ++ Subsignal("col", Pins("AK13")), ++ Subsignal("crs", Pins("AL13")), ++ IOStandard("LVCMOS25") ++ ) ++] ++ ++class Platform(XilinxISEPlatform): ++ def __init__(self): ++ XilinxISEPlatform.__init__(self, "xc6vlx240t-ff1156-1", _io, ++ lambda p: CRG_DS(p, "clk200", "user_btn", 5.0)) diff --cc mibuild/mibuild/platforms/papilio_pro.py index 00000000,00000000..7c8a6316 new file mode 100644 --- /dev/null +++ b/mibuild/mibuild/platforms/papilio_pro.py @@@ -1,0 -1,0 +1,44 @@@ ++from mibuild.generic_platform import * ++from mibuild.xilinx_ise import XilinxISEPlatform, CRG_SE ++ ++_io = [ ++ ("user_led", 0, Pins("P112"), IOStandard("LVCMOS33"), Drive(24), Misc("SLEW=QUIETIO")), ++ ++ ("user_btn", 0, Pins("P114"), IOStandard("LVCMOS33")), # C0 ++ ("user_btn", 1, Pins("P115"), IOStandard("LVCMOS33")), # C1 ++ ++ ("clk32", 0, Pins("P94"), IOStandard("LVCMOS33")), ++ ++ ("serial", 0, ++ Subsignal("tx", Pins("P105"), IOStandard("LVCMOS33"), Misc("SLEW=SLOW")), ++ Subsignal("rx", Pins("P101"), IOStandard("LVCMOS33"), Misc("PULLUP")) ++ ), ++ ++ ("spiflash", 0, ++ Subsignal("cs", Pins("P38")), ++ Subsignal("clk", Pins("P70")), ++ Subsignal("mosi", Pins("P64")), ++ Subsignal("miso", Pins("P65"), Misc("PULLUP")), ++ IOStandard("LVCMOS33"), Misc("SLEW=FAST") ++ ), ++ ++ ("sdram_clock", 0, Pins("P32"), IOStandard("LVCMOS33"), Misc("SLEW=FAST")), ++ ("sdram", 0, ++ Subsignal("a", Pins("P140 P139 P138 P137 P46 P45 P44", ++ "P43 P41 P40 P141 P35 P34")), ++ Subsignal("ba", Pins("P143 P142")), ++ Subsignal("cs_n", Pins("P1")), ++ Subsignal("cke", Pins("P33")), ++ Subsignal("ras_n", Pins("P2")), ++ Subsignal("cas_n", Pins("P5")), ++ Subsignal("we_n", Pins("P6")), ++ Subsignal("dq", Pins("P9 P10 P11 P12 P14 P15 P16 P8 P21 P22 P23 P24 P26 P27 P29 P30")), ++ Subsignal("dm", Pins("P7 P17")), ++ IOStandard("LVCMOS33"), Misc("SLEW=FAST") ++ ), ++] ++ ++class Platform(XilinxISEPlatform): ++ def __init__(self): ++ XilinxISEPlatform.__init__(self, "xc6slx9-tqg144-2", _io, ++ lambda p: CRG_SE(p, "clk32", None, 31.25)) diff --cc mibuild/mibuild/platforms/rhino.py index 00000000,00000000..4609d1bb new file mode 100644 --- /dev/null +++ b/mibuild/mibuild/platforms/rhino.py @@@ -1,0 -1,0 +1,137 @@@ ++from mibuild.generic_platform import * ++from mibuild.xilinx_ise import XilinxISEPlatform, CRG_DS ++ ++_io = [ ++ ("user_led", 0, Pins("Y3")), ++ ("user_led", 1, Pins("Y1")), ++ ("user_led", 2, Pins("W2")), ++ ("user_led", 3, Pins("W1")), ++ ("user_led", 4, Pins("V3")), ++ ("user_led", 5, Pins("V1")), ++ ("user_led", 6, Pins("U2")), ++ ("user_led", 7, Pins("U1")), ++ ++ ("clk100", 0, ++ Subsignal("p", Pins("B14"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")), ++ Subsignal("n", Pins("A14"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")) ++ ), ++ ++ ("gpio", 0, Pins("R8")), ++ ++ ("gpmc", 0, ++ Subsignal("clk", Pins("R26")), ++ Subsignal("a", Pins("N17 N18 L23 L24 N19 N20 N21 N22 P17 P19")), ++ Subsignal("d", Pins("N23 N24 R18 R19 P21 P22 R20 R21 P24 P26 R23 R24 T22 T23 U23 R25")), ++ Subsignal("we_n", Pins("W26")), ++ Subsignal("oe_n", Pins("AA25")), ++ Subsignal("ale_n", Pins("AA26")), ++ IOStandard("LVCMOS33")), ++ # Warning: CS are numbered 1-7 on ARM side and 0-6 on FPGA side. ++ # Numbers here are given on the FPGA side. ++ ("gpmc_ce_n", 0, Pins("V23"), IOStandard("LVCMOS33")), # nCS0 ++ ("gpmc_ce_n", 1, Pins("U25"), IOStandard("LVCMOS33")), # nCS1 ++ ("gpmc_ce_n", 2, Pins("W25"), IOStandard("LVCMOS33")), # nCS6 ++ ("gpmc_dmareq_n", 0, Pins("T24"), IOStandard("LVCMOS33")), # nCS2 ++ ("gpmc_dmareq_n", 1, Pins("T26"), IOStandard("LVCMOS33")), # nCS3 ++ ("gpmc_dmareq_n", 2, Pins("V24"), IOStandard("LVCMOS33")), # nCS4 ++ ("gpmc_dmareq_n", 3, Pins("V26"), IOStandard("LVCMOS33")), # nCS5 ++ ++ # FMC150 ++ ("fmc150_ctrl", 0, ++ Subsignal("spi_sclk", Pins("AE5")), ++ Subsignal("spi_data", Pins("AF5")), ++ ++ Subsignal("adc_sdo", Pins("U13")), ++ Subsignal("adc_en_n", Pins("AA15")), ++ Subsignal("adc_reset", Pins("V13")), ++ ++ Subsignal("cdce_sdo", Pins("AA8")), ++ Subsignal("cdce_en_n", Pins("Y9")), ++ Subsignal("cdce_reset_n", Pins("AB7")), ++ Subsignal("cdce_pd_n", Pins("AC6")), ++ Subsignal("cdce_pll_status", Pins("W7")), ++ Subsignal("cdce_ref_en", Pins("W8")), ++ ++ Subsignal("dac_sdo", Pins("W9")), ++ Subsignal("dac_en_n", Pins("W10")), ++ ++ Subsignal("mon_sdo", Pins("AC5")), ++ Subsignal("mon_en_n", Pins("AD6")), ++ Subsignal("mon_reset_n", Pins("AF6")), ++ Subsignal("mon_int_n", Pins("AD5")), ++ ++ Subsignal("pg_c2m", Pins("AA23"), IOStandard("LVCMOS33")) ++ ), ++ ("ti_dac", 0, # DAC3283 ++ Subsignal("dat_p", Pins("AA10 AA9 V11 Y11 W14 Y12 AD14 AE13"), IOStandard("LVDS_25")), ++ Subsignal("dat_n", Pins("AB11 AB9 V10 AA11 Y13 AA12 AF14 AF13"), IOStandard("LVDS_25")), ++ Subsignal("frame_p", Pins("AB13"), IOStandard("LVDS_25")), ++ Subsignal("frame_n", Pins("AA13"), IOStandard("LVDS_25")), ++ Subsignal("txenable", Pins("AB15"), IOStandard("LVCMOS25")) ++ ), ++ ("ti_adc", 0, # ADS62P49 ++ Subsignal("dat_a_p", Pins("AB14 Y21 W20 AB22 V18 W17 AA21")), ++ Subsignal("dat_a_n", Pins("AC14 AA22 Y20 AC22 W19 W18 AB21")), ++ Subsignal("dat_b_p", Pins("Y17 U15 AA19 W16 AA18 Y15 V14")), ++ Subsignal("dat_b_n", Pins("AA17 V16 AB19 Y16 AB17 AA16 V15")), ++ IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE") ++ ), ++ ("fmc150_clocks", 0, ++ Subsignal("dac_clk_p", Pins("V12"), IOStandard("LVDS_25")), ++ Subsignal("dac_clk_n", Pins("W12"), IOStandard("LVDS_25")), ++ Subsignal("adc_clk_p", Pins("AE15"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")), ++ Subsignal("adc_clk_n", Pins("AF15"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")), ++ Subsignal("clk_to_fpga", Pins("W24"), IOStandard("LVCMOS25")) ++ ), ++ ++ ("fmc150_ext_trigger", 0, Pins("U26")), ++ ++ # Vermeer radar testbed ++ # Switch controller ++ ("pca9555", 0, ++ Subsignal("sda", Pins("C13")), ++ Subsignal("scl", Pins("G8")), ++ IOStandard("LVCMOS33") ++ ), ++ # TX path ++ ("pe43602", 0, ++ Subsignal("d", Pins("H8")), ++ Subsignal("clk", Pins("B3")), ++ Subsignal("le", Pins("F7")), ++ IOStandard("LVCMOS33") ++ ), ++ ("rfmd2081", 0, ++ Subsignal("enx", Pins("E5")), ++ Subsignal("sclk", Pins("G6")), ++ Subsignal("sdata", Pins("F5")), ++ Subsignal("locked", Pins("E6")), ++ IOStandard("LVCMOS33") ++ ), ++ # RX path ++ ("lmh6521", 0, ++ Subsignal("scsb", Pins("C5")), ++ Subsignal("sclk", Pins("G10")), ++ Subsignal("sdi", Pins("D5")), ++ Subsignal("sdo", Pins("F9")), ++ IOStandard("LVCMOS33") ++ ), ++ ("lmh6521", 1, ++ Subsignal("scsb", Pins("E10")), ++ Subsignal("sclk", Pins("A4")), ++ Subsignal("sdi", Pins("B4")), ++ Subsignal("sdo", Pins("H10")), ++ IOStandard("LVCMOS33") ++ ), ++ ("rffc5071", 0, ++ Subsignal("enx", Pins("A2")), ++ Subsignal("sclk", Pins("G9")), ++ Subsignal("sdata", Pins("H9")), ++ Subsignal("locked", Pins("A3")), ++ IOStandard("LVCMOS33") ++ ) ++] ++ ++class Platform(XilinxISEPlatform): ++ def __init__(self): ++ XilinxISEPlatform.__init__(self, "xc6slx150t-fgg676-3", _io, ++ lambda p: CRG_DS(p, "clk100", "gpio", 10.0)) diff --cc mibuild/mibuild/platforms/roach.py index 00000000,00000000..a23bd90f new file mode 100644 --- /dev/null +++ b/mibuild/mibuild/platforms/roach.py @@@ -1,0 -1,0 +1,33 @@@ ++from mibuild.generic_platform import * ++from mibuild.xilinx_ise import XilinxISEPlatform ++ ++_io = [ ++ ("epb", 0, ++ Subsignal("cs_n", Pins("K13")), ++ Subsignal("r_w_n", Pins("AF20")), ++ Subsignal("be_n", Pins("AF14 AF18")), ++ Subsignal("oe_n", Pins("AF21")), ++ Subsignal("addr", Pins("AE23 AE22 AG18 AG12 AG15 AG23 AF19 AE12 AG16 AF13 AG20 AF23", ++ "AH17 AH15 L20 J22 H22 L15 L16 K22 K21 K16 J15")), ++ Subsignal("addr_gp", Pins("L21 G22 K23 K14 L14 J12")), ++ Subsignal("data", Pins("AF15 AE16 AE21 AD20 AF16 AE17 AE19 AD19 AG22 AH22 AH12 AG13", ++ "AH20 AH19 AH14 AH13")), ++ Subsignal("rdy", Pins("K12")), ++ IOStandard("LVCMOS33") ++ ), ++ ("roach_clocks", 0, ++ Subsignal("epb_clk", Pins("AH18"), IOStandard("LVCMOS33")), ++ Subsignal("sys_clk_n", Pins("H13")), ++ Subsignal("sys_clk_p", Pins("J14")), ++ Subsignal("aux0_clk_p", Pins("G15")), ++ Subsignal("aux0_clk_n", Pins("G16")), ++ Subsignal("aux1_clk_p", Pins("H14")), ++ Subsignal("aux1_clk_n", Pins("H15")), ++ Subsignal("dly_clk_n", Pins("J17")), ++ Subsignal("dly_clk_p", Pins("J16")), ++ ), ++] ++ ++class Platform(XilinxISEPlatform): ++ def __init__(self): ++ XilinxISEPlatform.__init__(self, "xc5vsx95t-ff1136-1", _io) diff --cc mibuild/mibuild/tools.py index 00000000,00000000..1c2493e4 new file mode 100644 --- /dev/null +++ b/mibuild/mibuild/tools.py @@@ -1,0 -1,0 +1,20 @@@ ++import os ++ ++def mkdir_noerror(d): ++ try: ++ os.mkdir(d) ++ except OSError: ++ pass ++ ++def language_by_filename(name): ++ extension = name.rsplit(".")[-1] ++ if extension in ["v", "vh", "vo"]: ++ return "verilog" ++ if extension in ["vhd", "vhdl", "vho"]: ++ return "vhdl" ++ return None ++ ++def write_to_file(filename, contents): ++ f = open(filename, "w") ++ f.write(contents) ++ f.close() diff --cc mibuild/mibuild/xilinx_ise.py index 00000000,00000000..8df2cfba new file mode 100644 --- /dev/null +++ b/mibuild/mibuild/xilinx_ise.py @@@ -1,0 -1,0 +1,215 @@@ ++import os, struct, subprocess, sys ++from decimal import Decimal ++ ++from migen.fhdl.std import * ++from migen.fhdl.specials import SynthesisDirective ++from migen.genlib.cdc import * ++from migen.fhdl.structure import _Fragment ++ ++from mibuild.generic_platform import * ++from mibuild.crg import SimpleCRG ++from mibuild import tools ++ ++def _add_period_constraint(platform, clk, period): ++ if period is not None: ++ platform.add_platform_command("""NET "{clk}" TNM_NET = "GRPclk"; ++TIMESPEC "TSclk" = PERIOD "GRPclk" """+str(period)+""" ns HIGH 50%;""", clk=clk) ++ ++class CRG_SE(SimpleCRG): ++ def __init__(self, platform, clk_name, rst_name, period=None, rst_invert=False): ++ SimpleCRG.__init__(self, platform, clk_name, rst_name, rst_invert) ++ _add_period_constraint(platform, self._clk, period) ++ ++class CRG_DS(Module): ++ def __init__(self, platform, clk_name, rst_name, period=None, rst_invert=False): ++ reset_less = rst_name is None ++ self.clock_domains.cd_sys = ClockDomain(reset_less=reset_less) ++ self._clk = platform.request(clk_name) ++ _add_period_constraint(platform, self._clk.p, period) ++ self.specials += Instance("IBUFGDS", ++ Instance.Input("I", self._clk.p), ++ Instance.Input("IB", self._clk.n), ++ Instance.Output("O", self.cd_sys.clk) ++ ) ++ if not reset_less: ++ if rst_invert: ++ self.comb += self.cd_sys.rst.eq(~platform.request(rst_name)) ++ else: ++ self.comb += self.cd_sys.rst.eq(platform.request(rst_name)) ++ ++def _format_constraint(c): ++ if isinstance(c, Pins): ++ return "LOC=" + c.identifiers[0] ++ elif isinstance(c, IOStandard): ++ return "IOSTANDARD=" + c.name ++ elif isinstance(c, Drive): ++ return "DRIVE=" + str(c.strength) ++ elif isinstance(c, Misc): ++ return c.misc ++ ++def _format_ucf(signame, pin, others, resname): ++ fmt_c = [] ++ for c in [Pins(pin)] + others: ++ fc = _format_constraint(c) ++ if fc is not None: ++ fmt_c.append(fc) ++ fmt_r = resname[0] + ":" + str(resname[1]) ++ if resname[2] is not None: ++ fmt_r += "." + resname[2] ++ return "NET \"" + signame + "\" " + " | ".join(fmt_c) + "; # " + fmt_r + "\n" ++ ++def _build_ucf(named_sc, named_pc): ++ r = "" ++ for sig, pins, others, resname in named_sc: ++ if len(pins) > 1: ++ for i, p in enumerate(pins): ++ r += _format_ucf(sig + "(" + str(i) + ")", p, others, resname) ++ else: ++ r += _format_ucf(sig, pins[0], others, resname) ++ if named_pc: ++ r += "\n" + "\n\n".join(named_pc) ++ return r ++ ++def _build_files(device, sources, named_sc, named_pc, build_name): ++ tools.write_to_file(build_name + ".ucf", _build_ucf(named_sc, named_pc)) ++ ++ prj_contents = "" ++ for filename, language in sources: ++ prj_contents += language + " work " + filename + "\n" ++ tools.write_to_file(build_name + ".prj", prj_contents) ++ ++ xst_contents = """run ++-ifn %s.prj ++-top top ++-ifmt MIXED ++-opt_mode SPEED ++-reduce_control_sets auto ++-register_balancing yes ++-ofn %s.ngc ++-p %s""" % (build_name, build_name, device) ++ tools.write_to_file(build_name + ".xst", xst_contents) ++ ++def _is_valid_version(path, v): ++ try: ++ Decimal(v) ++ return os.path.isdir(os.path.join(path, v)) ++ except: ++ return False ++ ++def _run_ise(build_name, ise_path, source, mode="verilog"): ++ if sys.platform == "win32" or sys.platform == "cygwin": ++ source = False ++ build_script_contents = "# Autogenerated by mibuild\nset -e\n" ++ if source: ++ vers = [ver for ver in os.listdir(ise_path) if _is_valid_version(ise_path, ver)] ++ tools_version = max(vers) ++ bits = struct.calcsize("P")*8 ++ ++ xilinx_settings_file = os.path.join(ise_path, tools_version, "ISE_DS", "settings{0}.sh".format(bits)) ++ if not os.path.exists(xilinx_settings_file) and bits == 64: ++ # if we are on 64-bit system but the toolchain isn't, try the 32-bit env. ++ xilinx_settings_file = os.path.join(ise_path, tools_version, "ISE_DS", "settings32.sh") ++ build_script_contents += "source " + xilinx_settings_file + "\n" ++ if mode == "edif": ++ build_script_contents += """ ++ngdbuild -uc {build_name}.ucf {build_name}.edif {build_name}.ngd""" ++ else: ++ build_script_contents += """ ++xst -ifn {build_name}.xst ++ngdbuild -uc {build_name}.ucf {build_name}.ngc {build_name}.ngd""" ++ ++ build_script_contents += """ ++map -ol high -w -o {build_name}_map.ncd {build_name}.ngd {build_name}.pcf ++par -ol high -w {build_name}_map.ncd {build_name}.ncd {build_name}.pcf ++bitgen -g LCK_cycle:6 -g Binary:Yes -w {build_name}.ncd {build_name}.bit ++""" ++ build_script_contents = build_script_contents.format(build_name=build_name) ++ build_script_file = "build_" + build_name + ".sh" ++ tools.write_to_file(build_script_file, build_script_contents) ++ ++ r = subprocess.call(["bash", build_script_file]) ++ if r != 0: ++ raise OSError("Subprocess failed") ++ ++class XilinxNoRetimingImpl(Module): ++ def __init__(self, reg): ++ self.specials += SynthesisDirective("attribute register_balancing of {r} is no", r=reg) ++ ++class XilinxNoRetiming: ++ @staticmethod ++ def lower(dr): ++ return XilinxNoRetimingImpl(dr.reg) ++ ++class XilinxMultiRegImpl(MultiRegImpl): ++ def __init__(self, *args, **kwargs): ++ MultiRegImpl.__init__(self, *args, **kwargs) ++ self.specials += [SynthesisDirective("attribute shreg_extract of {r} is no", r=r) ++ for r in self.regs] ++ ++class XilinxMultiReg: ++ @staticmethod ++ def lower(dr): ++ return XilinxMultiRegImpl(dr.i, dr.o, dr.odomain, dr.n) ++ ++class XilinxISEPlatform(GenericPlatform): ++ def get_verilog(self, *args, special_overrides=dict(), **kwargs): ++ so = { ++ NoRetiming: XilinxNoRetiming, ++ MultiReg: XilinxMultiReg ++ } ++ so.update(special_overrides) ++ return GenericPlatform.get_verilog(self, *args, special_overrides=so, **kwargs) ++ ++ def get_edif(self, fragment, **kwargs): ++ return GenericPlatform.get_edif(self, fragment, "UNISIMS", "Xilinx", self.device, **kwargs) ++ ++ def build(self, fragment, build_dir="build", build_name="top", ++ ise_path="/opt/Xilinx", source=True, run=True, mode="verilog"): ++ tools.mkdir_noerror(build_dir) ++ os.chdir(build_dir) ++ ++ if not isinstance(fragment, _Fragment): ++ fragment = fragment.get_fragment() ++ self.finalize(fragment) ++ ++ if mode == "verilog": ++ v_src, named_sc, named_pc = self.get_verilog(fragment) ++ v_file = build_name + ".v" ++ tools.write_to_file(v_file, v_src) ++ sources = self.sources + [(v_file, "verilog")] ++ _build_files(self.device, sources, named_sc, named_pc, build_name) ++ if run: ++ _run_ise(build_name, ise_path, source, mode="verilog") ++ ++ if mode == "mist": ++ from mist import synthesize ++ synthesize(fragment, self.constraint_manager.get_io_signals()) ++ ++ if mode == "edif" or mode == "mist": ++ e_src, named_sc, named_pc = self.get_edif(fragment) ++ e_file = build_name + ".edif" ++ tools.write_to_file(e_file, e_src) ++ sources = self.sources + [(e_file, "edif")] ++ tools.write_to_file(build_name + ".ucf", _build_ucf(named_sc, named_pc)) ++ if run: ++ _run_ise(build_name, ise_path, source, mode="edif") ++ ++ os.chdir("..") ++ ++ def build_arg_ns(self, ns, *args, **kwargs): ++ for n in ["build_dir", "build_name", "ise_path"]: ++ attr = getattr(ns, n) ++ if attr is not None: ++ kwargs[n] = attr ++ if ns.no_source: ++ kwargs["source"] = False ++ if ns.no_run: ++ kwargs["run"] = False ++ self.build(*args, **kwargs) ++ ++ def add_arguments(self, parser): ++ parser.add_argument("--build-dir", default=None, help="Set the directory in which to generate files and run ISE") ++ parser.add_argument("--build-name", default=None, help="Base name for the generated files") ++ parser.add_argument("--ise-path", default=None, help="ISE installation path (without version directory)") ++ parser.add_argument("--no-source", action="store_true", help="Do not source ISE settings file") ++ parser.add_argument("--no-run", action="store_true", help="Only generate files, do not run ISE") diff --cc mibuild/setup.py index 00000000,00000000..4322807b new file mode 100755 --- /dev/null +++ b/mibuild/setup.py @@@ -1,0 -1,0 +1,37 @@@ ++#!/usr/bin/env python3 ++ ++import sys, os ++from setuptools import setup ++from setuptools import find_packages ++ ++here = os.path.abspath(os.path.dirname(__file__)) ++README = open(os.path.join(here, "README")).read() ++ ++required_version = (3, 3) ++if sys.version_info < required_version: ++ raise SystemExit("Mibuild requires python {0} or greater".format( ++ ".".join(map(str, required_version)))) ++ ++setup( ++ name="mibuild", ++ version="unknown", ++ description="Build system and board definitions for Migen FPGA designs", ++ long_description=README, ++ author="Sebastien Bourdeauducq", ++ author_email="sebastien@milkymist.org", ++ url="http://www.milkymist.org", ++ download_url="https://github.com/milkymist/mibuild", ++ packages=find_packages(here), ++ license="BSD", ++ platforms=["Any"], ++ keywords="HDL ASIC FPGA hardware design", ++ classifiers=[ ++ "Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)", ++ "Environment :: Console", ++ "Development Status :: Alpha", ++ "Intended Audience :: Developers", ++ "License :: OSI Approved :: BSD License", ++ "Operating System :: OS Independent", ++ "Programming Language :: Python", ++ ], ++)