def build(self, platform, fragment, build_dir="build", build_name="top", toolchain_path=None, source=True, run=True, ver=None, **kwargs): if toolchain_path is None: if sys.platform == "win32": toolchain_path = "C:\\lscc\\diamond" elif sys.platform == "cygwin": toolchain_path = "/cygdrive/c/lscc/diamond" else: toolchain_path = "/usr/local/diamond" os.makedirs(build_dir, exist_ok=True) cwd = os.getcwd() os.chdir(build_dir) if not isinstance(fragment, _Fragment): fragment = fragment.get_fragment() platform.finalize(fragment) v_output = platform.get_verilog(fragment, name=build_name, **kwargs) named_sc, named_pc = platform.resolve_signals(v_output.ns) 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, build_name) tools.write_to_file(build_name + ".lpf", _build_lpf(named_sc, named_pc)) script = _build_script(build_name, platform.device, toolchain_path, source, ver) if run: _run_script(script) os.chdir(cwd) return v_output.ns
def _run_quartus(build_name, quartus_path, create_rbf): build_script_contents = """# Autogenerated by Migen set -e quartus_map --read_settings_files=on --write_settings_files=off {build_name} -c {build_name} quartus_fit --read_settings_files=off --write_settings_files=off {build_name} -c {build_name} quartus_asm --read_settings_files=off --write_settings_files=off {build_name} -c {build_name} quartus_sta {build_name} -c {build_name}""" if create_rbf: build_script_contents += """ if [ -f "{build_name}.sof" ] then quartus_cpf -c {build_name}.sof {build_name}.rbf fi """ build_script_contents = build_script_contents.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) if subprocess.call(["bash", build_script_file]): raise OSError("Subprocess failed")
def _generate_build_script(self, platform, bitstream_device, sources, build_name): if sys.platform == "win32" or sys.platform == "cygwin": # TODO: add support for Windows raise NotImplementedError("Windows support is not implemented") sh = [ "#!/bin/sh", "# Autogenerated by Migen", "set -ex", # stop execution when any command fail (e); print each command to stderr (x) ] escaped_sources = " ".join([ shlex.quote(f) for f, language, _ in sources if language in ["verilog", "system_verilog"] ]) sh.append( f"symbiflow_synth -t {build_name} -v {escaped_sources} -d {bitstream_device} -p {platform.device} -x {build_name}.xdc" ) sh.append( f"symbiflow_pack -e {build_name}.eblif -P {platform.device} -s {build_name}.sdc" ) sh.append( f"symbiflow_place -e {build_name}.eblif -p {build_name}.pcf -n {build_name}.net -P {platform.device} -s {build_name}.sdc" ) sh.append( f"symbiflow_route -e {build_name}.eblif -P {platform.device} -s {build_name}.sdc" ) sh.append( f"symbiflow_write_fasm -e {build_name}.eblif -P {platform.device}") sh.append( f"symbiflow_write_bitstream -f {build_name}.fasm -d {bitstream_device} -p {platform.device} -b {build_name}.bit" ) tools.write_to_file(f"build_{build_name}.sh", "\n".join(sh) + "\n")
def _build_script(source, build_template, build_name, pnr_pkg_opts, icetime_pkg_opts, freq_constraint): if sys.platform in ("win32", "cygwin"): script_ext = ".bat" build_script_contents = "@echo off\nrem Autogenerated by Migen\n\n" fail_stmt = " || exit /b" else: script_ext = ".sh" build_script_contents = "# Autogenerated by Migen\nset -e\n\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( build_name=build_name, pnr_pkg_opts=pnr_pkg_opts, icetime_pkg_opts=icetime_pkg_opts, freq_constraint=freq_constraint, fail_stmt=fail_stmt) 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
def build(self, platform, fragment, build_dir="build", build_name="top", run=True, mode="xst", **kwargs): if not isinstance(fragment, _Fragment): fragment = fragment.get_fragment() platform.finalize(fragment) ngdbuild_opt = self.ngdbuild_opt vns = None os.makedirs(build_dir, exist_ok=True) cwd = os.getcwd() os.chdir(build_dir) try: if mode in ("xst", "yosys", "cpld"): v_output = platform.get_verilog(fragment, name=build_name, **kwargs) vns = v_output.ns named_sc, named_pc = platform.resolve_signals(vns) v_file = build_name + ".v" v_output.write(v_file) sources = platform.copy_sources(build_dir) | { (v_file, "verilog", "work") } if mode in ("xst", "cpld"): _build_xst_files(platform.device, sources, build_name, self.xst_opt) isemode = mode else: _run_yosys(platform.device, sources, build_name) isemode = "edif" ngdbuild_opt += "-p " + platform.device if mode == "mist": from mist import synthesize synthesize(fragment, platform.constraint_manager.get_io_signals()) if mode == "edif" or mode == "mist": e_output = platform.get_edif(fragment) vns = e_output.ns named_sc, named_pc = platform.resolve_signals(vns) e_file = build_name + ".edif" e_output.write(e_file) isemode = "edif" tools.write_to_file(build_name + ".ucf", _build_ucf(named_sc, named_pc)) if run: _run_ise(build_name, isemode, ngdbuild_opt, self, platform) finally: os.chdir(cwd) return vns
def build(self, platform, fragment, build_dir="build", build_name="top", toolchain_path="/opt/Xilinx/Vivado", source=True, run=True, **kwargs): os.makedirs(build_dir, exist_ok=True) hdl = kwargs.get("hdl", "verilog") if not isinstance(fragment, _Fragment): fragment = fragment.get_fragment() platform.finalize(fragment) self._convert_clocks(platform) self._constrain(platform) output = platform.get_hdl(fragment, hdl=hdl, **kwargs) named_sc, named_pc = platform.resolve_signals(output.ns) hdl_file = "{}.{}".format(build_name, "v" if hdl == "verilog" else "vhd") with ChdirContext(build_dir): output.write(hdl_file) sources = platform.sources | {( hdl_file, "verilog" if hdl == "verilog" else "vhdl", "work")} self._build_batch(platform, sources, platform.edifs, platform.ips, build_name) tools.write_to_file(build_name + ".xdc", _build_xdc(named_sc, named_pc)) if run: _run_vivado(build_name, toolchain_path, source) return output.ns
def build( self, platform, fragment, build_dir="build", build_name="top", toolchain_path="/opt/Xilinx/Vivado", source=True, run=True, ): os.makedirs(build_dir, exist_ok=True) cwd = os.getcwd() os.chdir(build_dir) if not isinstance(fragment, _Fragment): fragment = fragment.get_fragment() platform.finalize(fragment) self._convert_clocks(platform) v_output = platform.get_verilog(fragment) named_sc, named_pc = platform.resolve_signals(v_output.ns) v_file = build_name + ".v" v_output.write(v_file) sources = platform.sources | {(v_file, "verilog", "work")} self._build_batch(platform, sources, build_name) tools.write_to_file(build_name + ".xdc", _build_xdc(named_sc, named_pc)) if run: _run_vivado(build_name, toolchain_path, source) os.chdir(cwd) return v_output.ns
def build(self, platform, fragment, build_dir="build", build_name="top", toolchain_path="/opt/Diamond", run=True): tools.mkdir_noerror(build_dir) cwd = os.getcwd() os.chdir(build_dir) if not isinstance(fragment, _Fragment): fragment = fragment.get_fragment() platform.finalize(fragment) v_output = platform.get_verilog(fragment) named_sc, named_pc = platform.resolve_signals(v_output.ns) 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, build_name) tools.write_to_file(build_name + ".lpf", _build_lpf(named_sc, named_pc)) if run: _run_diamond(build_name, toolchain_path) os.chdir(cwd) return v_output.ns
def build(self, platform, fragment, build_dir="build", build_name="top", toolchain_path="/opt/Xilinx/Vivado", source=True, run=True, **kwargs): os.makedirs(build_dir, exist_ok=True) hdl = kwargs.get("hdl", "verilog") if not isinstance(fragment, _Fragment): fragment = fragment.get_fragment() platform.finalize(fragment) self._convert_clocks(platform) self._constrain(platform) output = platform.get_hdl(fragment, hdl=hdl, **kwargs) named_sc, named_pc = platform.resolve_signals(output.ns) hdl_file = "{}.{}".format(build_name, "v" if hdl == "verilog" else "vhd") with ChdirContext(build_dir): output.write(hdl_file) sources = platform.sources | { (hdl_file, "verilog" if hdl == "verilog" else "vhdl", "work") } self._build_batch(platform, sources, platform.edifs, platform.ips, build_name) tools.write_to_file(build_name + ".xdc", _build_xdc(named_sc, named_pc)) if run: _run_vivado(build_name, toolchain_path, source) return output.ns
def _build_script(build_name, device, toolchain_path, ver=None): if sys.platform in ("win32", "cygwin"): script_ext = ".bat" build_script_contents = "@echo off\nrem Autogenerated by Migen\n\n" copy_stmt = "copy" fail_stmt = " || exit /b" else: script_ext = ".sh" build_script_contents = "# Autogenerated by Migen\nset -e\n\n" copy_stmt = "cp" fail_stmt = "" if sys.platform not in ("win32", "cygwin"): build_script_contents += "bindir={}\n".format(toolchain_path) build_script_contents += ". ${{bindir}}/diamond_env{fail_stmt}\n".format( fail_stmt=fail_stmt) build_script_contents += "{pnmainc} {tcl_script}{fail_stmt}\n".format( pnmainc=os.path.join(toolchain_path, "pnmainc"), tcl_script=build_name + ".tcl", fail_stmt=fail_stmt) for ext in (".bit", ".jed"): if ext == ".jed" and not _produces_jedec(device): continue build_script_contents += "{copy_stmt} {diamond_product} {migen_product}" \ "{fail_stmt}\n".format( copy_stmt=copy_stmt, fail_stmt=fail_stmt, diamond_product=os.path.join("impl", build_name + "_impl" + ext), migen_product=build_name + ext) 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
def _build_batch(self, platform, sources, build_name): tcl = [] for filename, language, library in sources: filename_tcl = "{" + filename + "}" tcl.append("add_files " + filename_tcl) tcl.append("set_property library {} [get_files {}]" .format(library, filename_tcl)) tcl.append("read_xdc {}.xdc".format(build_name)) tcl.extend(c.format(build_name=build_name) for c in self.pre_synthesis_commands) tcl.append("synth_design -top top -part {} -include_dirs {{{}}}".format(platform.device, " ".join(platform.verilog_include_paths))) tcl.append("report_utilization -hierarchical -file {}_utilization_hierarchical_synth.rpt".format(build_name)) tcl.append("report_utilization -file {}_utilization_synth.rpt".format(build_name)) tcl.append("place_design") if self.with_phys_opt: tcl.append("phys_opt_design -directive AddRetime") tcl.append("report_utilization -hierarchical -file {}_utilization_hierarchical_place.rpt".format(build_name)) tcl.append("report_utilization -file {}_utilization_place.rpt".format(build_name)) tcl.append("report_io -file {}_io.rpt".format(build_name)) tcl.append("report_control_sets -verbose -file {}_control_sets.rpt".format(build_name)) tcl.append("report_clock_utilization -file {}_clock_utilization.rpt".format(build_name)) tcl.append("route_design") tcl.append("report_route_status -file {}_route_status.rpt".format(build_name)) tcl.append("report_drc -file {}_drc.rpt".format(build_name)) tcl.append("report_timing_summary -max_paths 10 -file {}_timing.rpt".format(build_name)) tcl.append("report_power -file {}_power.rpt".format(build_name)) for bitstream_command in self.bitstream_commands: tcl.append(bitstream_command.format(build_name=build_name)) tcl.append("write_bitstream -force {}.bit ".format(build_name)) for additional_command in self.additional_commands: tcl.append(additional_command.format(build_name=build_name)) tcl.append("quit") tools.write_to_file(build_name + ".tcl", "\n".join(tcl))
def build(self, platform, fragment, build_dir="build", build_name="top", run=True): tools.mkdir_noerror(build_dir) cwd = os.getcwd() os.chdir(build_dir) if not isinstance(fragment, _Fragment): fragment = fragment.get_fragment() platform.finalize(fragment) v_output = platform.get_verilog(fragment) named_sc, named_pc = platform.resolve_signals(v_output.ns) v_file = build_name + ".v" v_output.write(v_file) sources = platform.sources | {(v_file, "verilog", "work")} _build_yosys(platform.device, sources, platform.verilog_include_paths, build_name) tools.write_to_file(build_name + ".pcf", _build_pcf(named_sc, named_pc)) if run: (family, size, package) = self.parse_device_string(platform.device) new_pnr_opts = self.pnr_opt + " -d " + size + " -P " + package _run_icestorm(build_name, False, self.yosys_opt, new_pnr_opts, self.icepack_opt) os.chdir(cwd) return v_output.ns
def _build_batch(self, platform, sources, build_name): tcl = [] for filename, language, library in sources: filename_tcl = "{" + filename + "}" tcl.append("add_files " + filename_tcl) tcl.append("set_property library {} [get_files {}]" .format(library, filename_tcl)) tcl.append("read_xdc {}.xdc".format(build_name)) tcl.extend(c.format(build_name=build_name) for c in self.pre_synthesis_commands) tcl.append("synth_design -top top -part {} -include_dirs {{{}}}".format(platform.device, " ".join(platform.verilog_include_paths))) tcl.append("report_utilization -hierarchical -file {}_utilization_hierarchical_synth.rpt".format(build_name)) tcl.append("report_utilization -file {}_utilization_synth.rpt".format(build_name)) tcl.append("place_design") if self.with_phys_opt: tcl.append("phys_opt_design -directive AddRetime") tcl.append("report_utilization -hierarchical -file {}_utilization_hierarchical_place.rpt".format(build_name)) tcl.append("report_utilization -file {}_utilization_place.rpt".format(build_name)) tcl.append("report_io -file {}_io.rpt".format(build_name)) tcl.append("report_control_sets -verbose -file {}_control_sets.rpt".format(build_name)) tcl.append("report_clock_utilization -file {}_clock_utilization.rpt".format(build_name)) tcl.append("route_design") tcl.append("report_route_status -file {}_route_status.rpt".format(build_name)) tcl.append("report_drc -file {}_drc.rpt".format(build_name)) tcl.append("report_timing_summary -datasheet -max_paths 10 -file {}_timing.rpt".format(build_name)) tcl.append("report_power -file {}_power.rpt".format(build_name)) for bitstream_command in self.bitstream_commands: tcl.append(bitstream_command.format(build_name=build_name)) tcl.append("write_bitstream -force {}.bit ".format(build_name)) for additional_command in self.additional_commands: tcl.append(additional_command.format(build_name=build_name)) tcl.append("quit") tools.write_to_file(build_name + ".tcl", "\n".join(tcl))
def build(self, platform, fragment, build_dir="build", build_name="top", run=True, **kwargs): os.makedirs(build_dir, exist_ok=True) cwd = os.getcwd() os.chdir(build_dir) if not isinstance(fragment, _Fragment): fragment = fragment.get_fragment() platform.finalize(fragment) v_output = platform.get_verilog(fragment, name=build_name, **kwargs) named_sc, named_pc = platform.resolve_signals(v_output.ns) 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, build_name) tools.write_to_file(build_name + ".lpf", _build_lpf(named_sc, named_pc)) script = _build_script(build_name, platform.device) if run: _run_script(script) os.chdir(cwd) return v_output.ns
def _run_icestorm(build_name, source, yosys_opt, pnr_opt, icetime_opt, icepack_opt): if sys.platform == "win32" or sys.platform == "cygwin": source_cmd = "call " script_ext = ".bat" shell = ["cmd", "/c"] build_script_contents = "@echo off\nrem Autogenerated by Migen\n" fail_stmt = " || exit /b" else: source_cmd = "source " script_ext = ".sh" shell = ["bash"] build_script_contents = "# Autogenerated by Migen\nset -e\n" fail_stmt = "" build_script_contents += """ yosys {yosys_opt} -l {build_name}.rpt {build_name}.ys{fail_stmt} arachne-pnr {pnr_opt} -p {build_name}.pcf {build_name}.blif -o {build_name}.txt{fail_stmt} icetime {icetime_opt} -t -p {build_name}.pcf -r {build_name}.tim {build_name}.txt{fail_stmt} icepack {icepack_opt} {build_name}.txt {build_name}.bin{fail_stmt} """ build_script_contents = build_script_contents.format( build_name=build_name, yosys_opt=yosys_opt, pnr_opt=pnr_opt, icepack_opt=icepack_opt, icetime_opt=icetime_opt, fail_stmt=fail_stmt) build_script_file = "build_" + build_name + script_ext tools.write_to_file(build_script_file, build_script_contents, force_unix=False) command = shell + [build_script_file] r = subprocess.call(command) if r != 0: raise OSError("Subprocess failed")
def build(self, platform, fragment, build_dir="build", build_name="top", run=True, **kwargs): os.makedirs(build_dir, exist_ok=True) cwd = os.getcwd() os.chdir(build_dir) if not isinstance(fragment, _Fragment): fragment = fragment.get_fragment() platform.finalize(fragment) self._convert_clocks(platform) self._constrain(platform) v_output = platform.get_verilog(fragment, name=build_name, **kwargs) named_sc, named_pc = platform.resolve_signals(v_output.ns) v_file = build_name + ".v" v_output.write(v_file) sources = platform.sources | {(v_file, "verilog", "work")} edifs = platform.edifs ips = platform.ips self._build_batch(platform, sources, edifs, ips, build_name) tools.write_to_file(build_name + ".xdc", _build_xdc(named_sc, named_pc)) if run: _run_vivado(build_name) os.chdir(cwd) return v_output.ns
def build(self, platform, fragment, build_dir="build", build_name="top", run=True): os.makedirs(build_dir, exist_ok=True) cwd = os.getcwd() os.chdir(build_dir) if not isinstance(fragment, _Fragment): fragment = fragment.get_fragment() platform.finalize(fragment) v_output = platform.get_verilog(fragment) named_sc, named_pc = platform.resolve_signals(v_output.ns) v_file = build_name + ".v" v_output.write(v_file) sources = platform.sources | {(v_file, "verilog", "work")} _build_yosys(platform.device, sources, platform.verilog_include_paths, build_name) tools.write_to_file(build_name + ".pcf", _build_pcf(named_sc, named_pc)) if run: (family, size, package) = self.parse_device_string(platform.device) pnr_opt = self.pnr_opt + " -d " + size + " -P " + package # TODO: PNR will probably eventually support LP devices. icetime_opt = self.icetime_opt + " -P " + package + \ " -d " + "hx" + size + " -c " + \ str(max(self.freq_constraints.values(), default=0.0)) _run_icestorm(build_name, False, self.yosys_opt, pnr_opt, icetime_opt, self.icepack_opt) os.chdir(cwd) return v_output.ns
def _run_icestorm(source, build_template, build_name, pnr_pkg_opts, icetime_pkg_opts, freq_constraint): if sys.platform == "win32" or sys.platform == "cygwin": script_ext = ".bat" shell = ["cmd", "/c"] build_script_contents = "@echo off\nrem Autogenerated by Migen\n\n" fail_stmt = " || exit /b" else: script_ext = ".sh" shell = ["bash"] build_script_contents = "# Autogenerated by Migen\nset -e\n\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( build_name=build_name, pnr_pkg_opts=pnr_pkg_opts, icetime_pkg_opts=icetime_pkg_opts, freq_constraint=freq_constraint, fail_stmt=fail_stmt) build_script_file = "build_" + build_name + script_ext tools.write_to_file(build_script_file, build_script_contents, force_unix=False) command = shell + [build_script_file] r = subprocess.call(command) if r != 0: raise OSError("Subprocess failed")
def _run_icestorm(source, build_template, build_name, pnr_pkg_opts, icetime_pkg_opts, icetime_constraint): if sys.platform == "win32" or sys.platform == "cygwin": script_ext = ".bat" shell = ["cmd", "/c"] build_script_contents = "@echo off\nrem Autogenerated by Migen\n\n" fail_stmt = " || exit /b" else: script_ext = ".sh" shell = ["bash"] build_script_contents = "# Autogenerated by Migen\nset -e\n\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(build_name=build_name, pnr_pkg_opts=pnr_pkg_opts, icetime_pkg_opts=icetime_pkg_opts, icetime_constraint=icetime_constraint, fail_stmt=fail_stmt) build_script_file = "build_" + build_name + script_ext tools.write_to_file(build_script_file, build_script_contents, force_unix=False) command = shell + [build_script_file] r = subprocess.call(command) if r != 0: raise OSError("Subprocess failed")
def build(self, platform, fragment, build_dir = "build", build_name = "top", run = True, **kwargs): # Create build directory os.makedirs(build_dir, exist_ok=True) cwd = os.getcwd() os.chdir(build_dir) # Finalize design if not isinstance(fragment, _Fragment): fragment = fragment.get_fragment() platform.finalize(fragment) # Generate timing constraints self._build_clock_constraints(platform) # Generate verilog v_output = platform.get_verilog(fragment, name=build_name, **kwargs) named_sc, named_pc = platform.resolve_signals(v_output.ns) v_file = build_name + ".v" v_output.write(v_file) sources = platform.copy_sources(build_dir) | {(v_file, "verilog", "work")} self._generate_build_script( platform = platform, sources = sources, build_name = build_name ) sdc_commands = [ "create_clock", "set_clock_groups", "set_false_path", "set_max_delay", "set_min_delay", "set_multicycle_path", "set_input_delay", "set_output_delay", "set_clock_uncertainty", "set_clock_latency", "set_disable_timing" ] named_pc_sdc = [] for pc in named_pc: cmd = pc.split(maxsplit=1)[0] if cmd in sdc_commands: named_pc_sdc.append(pc) # Generate design constraints tools.write_to_file(build_name + ".pcf", _build_pcf(named_sc)) tools.write_to_file(build_name + ".sdc", _build_sdc(named_pc_sdc)) if run: _run_script(build_name) os.chdir(cwd) return v_output.ns
def _run_sim(build_name): run_script_contents = """obj_dir/Vdut """ run_script_file = "run_" + build_name + ".sh" tools.write_to_file(run_script_file, run_script_contents, force_unix=True) r = subprocess.call(["bash", run_script_file]) if r != 0: raise OSError("Subprocess failed")
def build(self, platform, fragment, build_dir="build", build_name="top", toolchain_path=None, source=None, run=True, mode="xst"): if not isinstance(fragment, _Fragment): fragment = fragment.get_fragment() if toolchain_path is None: if sys.platform == "win32": toolchain_path = "C:\\Xilinx" elif sys.platform == "cygwin": toolchain_path = "/cygdrive/c/Xilinx" else: toolchain_path = "/opt/Xilinx" if source is None: source = sys.platform != "win32" platform.finalize(fragment) ngdbuild_opt = self.ngdbuild_opt vns = None tools.mkdir_noerror(build_dir) cwd = os.getcwd() os.chdir(build_dir) try: if mode == "xst" or mode == "yosys": v_output = platform.get_verilog(fragment) vns = v_output.ns named_sc, named_pc = platform.resolve_signals(vns) v_file = build_name + ".v" v_output.write(v_file) sources = platform.sources | {(v_file, "verilog", "work")} if mode == "xst": _build_xst_files(platform.device, sources, platform.verilog_include_paths, build_name, self.xst_opt) isemode = "xst" else: _run_yosys(platform.device, sources, platform.verilog_include_paths, build_name) isemode = "edif" ngdbuild_opt += "-p " + platform.device if mode == "mist": from mist import synthesize synthesize(fragment, platform.constraint_manager.get_io_signals()) if mode == "edif" or mode == "mist": e_output = platform.get_edif(fragment) vns = e_output.ns named_sc, named_pc = platform.resolve_signals(vns) e_file = build_name + ".edif" e_output.write(e_file) isemode = "edif" tools.write_to_file(build_name + ".ucf", _build_ucf(named_sc, named_pc)) if run: _run_ise(build_name, toolchain_path, source, isemode, ngdbuild_opt, self.bitgen_opt, self.ise_commands, self.map_opt, self.par_opt) finally: os.chdir(cwd) return vns
def build(self, platform, fragment, build_dir="build", build_name="top", use_nextpnr=True, run=True): os.makedirs(build_dir, exist_ok=True) cwd = os.getcwd() os.chdir(build_dir) if not isinstance(fragment, _Fragment): fragment = fragment.get_fragment() platform.finalize(fragment) v_output = platform.get_verilog(fragment) named_sc, named_pc = platform.resolve_signals(v_output.ns) v_file = build_name + ".v" v_output.write(v_file) if use_nextpnr: chosen_yosys_template = self.nextpnr_yosys_template else: chosen_yosys_template = self.yosys_template ys_contents = "\n".join( _.format(build_name=build_name, read_files=self.gen_read_files(platform, v_file)) for _ in chosen_yosys_template) ys_name = build_name + ".ys" tools.write_to_file(ys_name, ys_contents) tools.write_to_file(build_name + ".pcf", _build_pcf(named_sc, named_pc)) (family, series_size, package) = self.parse_device_string(platform.device) if use_nextpnr: pnr_pkg_opts = "--" + series_size + " --package " + package else: pnr_pkg_opts = "-d " + self.get_size_string(series_size) + \ " -P " + package icetime_pkg_opts = "-P " + package + " -d " + series_size freq_constraint = str(max(self.freq_constraints.values(), default=0.0)) if use_nextpnr: chosen_build_template = self.nextpnr_build_template else: chosen_build_template = self.build_template script = _build_script(False, chosen_build_template, build_name, pnr_pkg_opts, icetime_pkg_opts, freq_constraint) if run: _run_script(script) os.chdir(cwd) return v_output.ns
def _build_batch(self, platform, sources, edifs, ips, build_name): tcl = [] tcl.append("create_project -force -name {} -part {}".format(build_name, platform.device)) tcl.append("set_property XPM_LIBRARIES {XPM_CDC XPM_MEMORY} [current_project]") for filename, language, library in sources: filename_tcl = "{" + filename + "}" tcl.append("add_files " + filename_tcl) tcl.append("set_property library {} [get_files {}]" .format(library, filename_tcl)) for filename in edifs: filename_tcl = "{" + filename + "}" tcl.append("read_edif " + filename_tcl) for filename in ips: filename_tcl = "{" + filename + "}" ip = os.path.splitext(os.path.basename(filename))[0] tcl.append("read_ip " + filename_tcl) tcl.append("upgrade_ip [get_ips {}]".format(ip)) tcl.append("generate_target all [get_ips {}]".format(ip)) tcl.append("synth_ip [get_ips {}] -force".format(ip)) tcl.append("get_files -all -of_objects [get_files {}]".format(filename_tcl)) tcl.append("read_xdc {}.xdc".format(build_name)) tcl.extend(c.format(build_name=build_name) for c in self.pre_synthesis_commands) # "-include_dirs {}" crashes Vivado 2016.4 if platform.verilog_include_paths: tcl.append("synth_design -top top -part {} -include_dirs {{{}}}".format(platform.device, " ".join(platform.verilog_include_paths))) else: tcl.append("synth_design -top top -part {}".format(platform.device)) tcl.append("report_timing_summary -file {}_timing_synth.rpt".format(build_name)) tcl.append("report_utilization -hierarchical -file {}_utilization_hierarchical_synth.rpt".format(build_name)) tcl.append("report_utilization -file {}_utilization_synth.rpt".format(build_name)) tcl.append("opt_design") tcl.append("place_design") if self.with_phys_opt: tcl.append("phys_opt_design -directive AddRetime") tcl.append("report_utilization -hierarchical -file {}_utilization_hierarchical_place.rpt".format(build_name)) tcl.append("report_utilization -file {}_utilization_place.rpt".format(build_name)) tcl.append("report_io -file {}_io.rpt".format(build_name)) tcl.append("report_control_sets -verbose -file {}_control_sets.rpt".format(build_name)) tcl.append("report_clock_utilization -file {}_clock_utilization.rpt".format(build_name)) tcl.append("route_design") tcl.append("phys_opt_design") tcl.append("report_timing_summary -no_header -no_detailed_paths") tcl.append("write_checkpoint -force {}_route.dcp".format(build_name)) tcl.append("report_route_status -file {}_route_status.rpt".format(build_name)) tcl.append("report_drc -file {}_drc.rpt".format(build_name)) tcl.append("report_timing_summary -datasheet -max_paths 10 -file {}_timing.rpt".format(build_name)) tcl.append("report_power -file {}_power.rpt".format(build_name)) for bitstream_command in self.bitstream_commands: tcl.append(bitstream_command.format(build_name=build_name)) tcl.append("write_bitstream -force {}.bit ".format(build_name)) for additional_command in self.additional_commands: tcl.append(additional_command.format(build_name=build_name)) tcl.append("quit") tools.write_to_file(build_name + ".tcl", "\n".join(tcl))
def _run_ise(build_name, ise_path, source, mode, ngdbuild_opt, bitgen_opt, ise_commands, map_opt, par_opt, ver=None): if sys.platform == "win32" or sys.platform == "cygwin": source_cmd = "call " script_ext = ".bat" shell = ["cmd", "/c"] build_script_contents = "@echo off\nrem Autogenerated by Migen\n" fail_stmt = " || exit /b" else: source_cmd = "source " script_ext = ".sh" shell = ["bash"] build_script_contents = "# Autogenerated by Migen\nset -e\n" fail_stmt = "" if source: settings = common.settings(ise_path, ver, "ISE_DS") build_script_contents += source_cmd + settings + "\n" if mode == "edif": ext = "edif" else: ext = "ngc" build_script_contents += """ xst -ifn {build_name}.xst{fail_stmt} """ build_script_contents += """ ngdbuild {ngdbuild_opt} -uc {build_name}.ucf {build_name}.{ext} {build_name}.ngd{fail_stmt} map {map_opt} -o {build_name}_map.ncd {build_name}.ngd {build_name}.pcf{fail_stmt} par {par_opt} {build_name}_map.ncd {build_name}.ncd {build_name}.pcf{fail_stmt} bitgen {bitgen_opt} {build_name}.ncd {build_name}.bit{fail_stmt} """ build_script_contents = build_script_contents.format( build_name=build_name, ngdbuild_opt=ngdbuild_opt, bitgen_opt=bitgen_opt, ext=ext, par_opt=par_opt, map_opt=map_opt, fail_stmt=fail_stmt) build_script_contents += ise_commands.format(build_name=build_name) build_script_file = "build_" + build_name + script_ext tools.write_to_file(build_script_file, build_script_contents, force_unix=False) command = shell + [build_script_file] r = tools.subprocess_call_filtered(command, common.colors) if r != 0: raise OSError("Subprocess failed")
def build(self, platform, fragment, build_dir="build", build_name="top", toolchain_path=None, source=True, run=True, mode="xst"): if not isinstance(fragment, _Fragment): fragment = fragment.get_fragment() if toolchain_path is None: if sys.platform == "win32": toolchain_path = "C:\\Xilinx" elif sys.platform == "cygwin": toolchain_path = "/cygdrive/c/Xilinx" else: toolchain_path = "/opt/Xilinx" platform.finalize(fragment) ngdbuild_opt = self.ngdbuild_opt vns = None os.makedirs(build_dir, exist_ok=True) cwd = os.getcwd() os.chdir(build_dir) try: if mode == "xst" or mode == "yosys": v_output = platform.get_verilog(fragment) vns = v_output.ns named_sc, named_pc = platform.resolve_signals(vns) v_file = build_name + ".v" v_output.write(v_file) sources = platform.sources | {(v_file, "verilog", "work")} if mode == "xst": _build_xst_files(platform.device, sources, platform.verilog_include_paths, build_name, self.xst_opt) isemode = "xst" else: _run_yosys(platform.device, sources, platform.verilog_include_paths, build_name) isemode = "edif" ngdbuild_opt += "-p " + platform.device if mode == "mist": from mist import synthesize synthesize(fragment, platform.constraint_manager.get_io_signals()) if mode == "edif" or mode == "mist": e_output = platform.get_edif(fragment) vns = e_output.ns named_sc, named_pc = platform.resolve_signals(vns) e_file = build_name + ".edif" e_output.write(e_file) isemode = "edif" tools.write_to_file(build_name + ".ucf", _build_ucf(named_sc, named_pc)) if run: _run_ise(build_name, toolchain_path, source, isemode, ngdbuild_opt, self.bitgen_opt, self.ise_commands, self.map_opt, self.par_opt) finally: os.chdir(cwd) return vns
def build(self, platform, fragment, build_dir="build", build_name="top", toolchain_path=None, run=True, **kwargs): if toolchain_path is None: toolchain_path = "/usr/share/trellis/" os.makedirs(build_dir, exist_ok=True) cwd = os.getcwd() os.chdir(build_dir) # generate verilog if not isinstance(fragment, _Fragment): fragment = fragment.get_fragment() platform.finalize(fragment) top_output = platform.get_verilog(fragment, name=build_name, **kwargs) named_sc, named_pc = platform.resolve_signals(top_output.ns) top_file = build_name + ".v" top_output.write(top_file) platform.add_source(top_file) # generate constraints tools.write_to_file(build_name + ".lpf", _build_lpf(named_sc, named_pc)) # generate yosys script yosys_script_file = build_name + ".ys" yosys_script_contents = "\n".join( _.format(build_name=build_name, read_files=yosys_import_sources(platform)) for _ in self.yosys_template) tools.write_to_file(yosys_script_file, yosys_script_contents) # transform platform.device to nextpnr's architecture / basecfg (family, size, package) = platform.device.split("-") architecture = nextpnr_ecp5_architectures[(family + "-" + size).lower()] basecfg = "empty_" + (family + "-" + size).lower() + ".config" basecfg = os.path.join(toolchain_path, "misc", "basecfgs", basecfg) freq_constraint = str(max(self.freq_constraints.values(), default=0.0)) script = _build_script(False, self.build_template, build_name, architecture, basecfg, freq_constraint) # run scripts if run: _run_script(script) os.chdir(cwd) return top_output.ns
def _build_yosys(device, sources, vincpaths, build_name): ys_contents = "" incflags = "" for path in vincpaths: incflags += " -I" + path for filename, language, library in sources: ys_contents += "read_{}{} {}\n".format(language, incflags, filename) ys_contents += """synth_ice40 -top top -blif {build_name}.blif""".format(build_name=build_name) ys_name = build_name + ".ys" tools.write_to_file(ys_name, ys_contents)
def _run_ise(build_name, mode, ngdbuild_opt, toolchain, platform): if sys.platform == "win32" or sys.platform == "cygwin": script_ext = ".bat" shell = ["cmd", "/c"] build_script_contents = "@echo off\nrem Autogenerated by Migen\n" fail_stmt = " || exit /b" else: script_ext = ".sh" shell = ["bash"] build_script_contents = "# Autogenerated by Migen\nset -e\n" fail_stmt = "" if mode == "edif": ext = "edif" else: ext = "ngc" build_script_contents += """ xst -ifn {build_name}.xst{fail_stmt} """ build_script_contents += """ ngdbuild {ngdbuild_opt} -uc {build_name}.ucf {build_name}.{ext} {build_name}.ngd{fail_stmt} """ if mode == "cpld": build_script_contents += """ cpldfit -ofmt verilog {par_opt} -p {device} {build_name}.ngd{fail_stmt} taengine -f {build_name}.vm6 -detail -iopath -l {build_name}.tim{fail_stmt} hprep6 -s IEEE1532 -i {build_name}.vm6{fail_stmt} """ else: build_script_contents += """ map {map_opt} -o {build_name}_map.ncd {build_name}.ngd {build_name}.pcf{fail_stmt} par {par_opt} {build_name}_map.ncd {build_name}.ncd {build_name}.pcf{fail_stmt} bitgen {bitgen_opt} {build_name}.ncd {build_name}.bit{fail_stmt} """ build_script_contents = build_script_contents.format( build_name=build_name, ngdbuild_opt=ngdbuild_opt, bitgen_opt=toolchain.bitgen_opt, ext=ext, par_opt=toolchain.par_opt, map_opt=toolchain.map_opt, device=platform.device, fail_stmt=fail_stmt) build_script_contents += toolchain.ise_commands.format( build_name=build_name) build_script_file = "build_" + build_name + script_ext tools.write_to_file(build_script_file, build_script_contents, force_unix=False) command = shell + [build_script_file] r = tools.subprocess_call_filtered(command, common.colors) if r != 0: raise OSError("Subprocess failed")
def _run_ise(build_name, ise_path, source, mode, ngdbuild_opt, toolchain, platform, ver=None): if sys.platform == "win32" or sys.platform == "cygwin": source_cmd = "call " script_ext = ".bat" shell = ["cmd", "/c"] build_script_contents = "@echo off\nrem Autogenerated by Migen\n" fail_stmt = " || exit /b" else: source_cmd = "source " script_ext = ".sh" shell = ["bash"] build_script_contents = "# Autogenerated by Migen\nset -e\n" fail_stmt = "" if source: settings = common.settings(ise_path, ver, "ISE_DS") build_script_contents += source_cmd + tools.cygpath(settings) + "\n" if mode == "edif": ext = "edif" else: ext = "ngc" build_script_contents += """ xst -ifn {build_name}.xst{fail_stmt} """ build_script_contents += """ ngdbuild {ngdbuild_opt} -uc {build_name}.ucf {build_name}.{ext} {build_name}.ngd{fail_stmt} """ if mode == "cpld": build_script_contents += """ cpldfit -ofmt verilog {par_opt} -p {device} {build_name}.ngd{fail_stmt} taengine -f {build_name}.vm6 -detail -iopath -l {build_name}.tim{fail_stmt} hprep6 -s IEEE1532 -i {build_name}.vm6{fail_stmt} """ else: build_script_contents += """ map {map_opt} -o {build_name}_map.ncd {build_name}.ngd {build_name}.pcf{fail_stmt} par {par_opt} {build_name}_map.ncd {build_name}.ncd {build_name}.pcf{fail_stmt} bitgen {bitgen_opt} {build_name}.ncd {build_name}.bit{fail_stmt} """ build_script_contents = build_script_contents.format( build_name=build_name, ngdbuild_opt=ngdbuild_opt, bitgen_opt=toolchain.bitgen_opt, ext=ext, par_opt=toolchain.par_opt, map_opt=toolchain.map_opt, device=platform.device, fail_stmt=fail_stmt) build_script_contents += toolchain.ise_commands.format(build_name=build_name) build_script_file = "build_" + build_name + script_ext tools.write_to_file(build_script_file, build_script_contents, force_unix=False) command = shell + [build_script_file] r = tools.subprocess_call_filtered(command, common.colors) if r != 0: raise OSError("Subprocess failed")
def _run_diamond(build_name, source, ver=None): if sys.platform == "win32" or sys.platform == "cygwin": build_script_contents = "REM Autogenerated by Migen\n" build_script_contents = "pnmainc " + build_name + ".tcl\n" build_script_file = "build_" + build_name + ".bat" tools.write_to_file(build_script_file, build_script_contents) r = subprocess.call([build_script_file]) shutil.copy(os.path.join("implementation", build_name + "_implementation.bit"), build_name + ".bit") else: raise NotImplementedError if r != 0: raise OSError("Subprocess failed")
def _build_files(device, sources, vincpaths, build_name): tcl = [] tcl.append("prj_project new -name \"{}\" -impl \"implementation\" -dev {} -synthesis \"synplify\"".format(build_name, device)) for path in vincpaths: tcl.append("prj_impl option {include path} {\"" + path + "\"}") for filename, language, library in sources: tcl.append("prj_src add \"" + filename + "\" -work " + library) tcl.append("prj_run Synthesis -impl implementation -forceOne") tcl.append("prj_run Translate -impl implementation") tcl.append("prj_run Map -impl implementation") tcl.append("prj_run PAR -impl implementation") tcl.append("prj_run Export -impl implementation -task Bitgen") tools.write_to_file(build_name + ".tcl", "\n".join(tcl))
def add_xilinx_ila(target, debug_clock, output_dir, depth=1024): os.makedirs(os.path.join(output_dir, "gateware"), exist_ok=True) tools.write_to_file(os.path.join(output_dir, "gateware", "insert_ila.tcl"), insert_ila_script()) target.platform.toolchain.post_synthesis_commands.append( "source insert_ila.tcl") target.platform.toolchain.post_synthesis_commands.append( f"batch_insert_ila {{{depth}}}") debug_clock.attr.add(("mark_dbg_hub_clk", "true")) debug_clock.attr.add(("keep", "true")) target.platform.toolchain.post_synthesis_commands.append( "connect_debug_port dbg_hub/clk [get_nets -hierarchical -filter {mark_dbg_hub_clk == true}]" )
def _build_yosys(device, sources, vincpaths, build_name): ys_contents = "" incflags = "" for path in vincpaths: incflags += " -I" + path for filename, language, library in sources: ys_contents += "read_{}{} {}\n".format(language, incflags, filename) ys_contents += """synth_ice40 -top top -blif {build_name}.blif""".format( build_name=build_name) ys_name = build_name + ".ys" tools.write_to_file(ys_name, ys_contents)
def build(self, platform, fragment, build_dir="build", build_name="top", toolchain_path=None, source=True, run=True, mode="xst", **kwargs): if not isinstance(fragment, _Fragment): fragment = fragment.get_fragment() if toolchain_path is None: if sys.platform == "win32": toolchain_path = "C:\\Xilinx" elif sys.platform == "cygwin": toolchain_path = "/cygdrive/c/Xilinx" else: toolchain_path = "/opt/Xilinx" platform.finalize(fragment) ngdbuild_opt = self.ngdbuild_opt vns = None os.makedirs(build_dir, exist_ok=True) with ChdirContext(build_dir): if mode in ("xst", "yosys", "cpld"): v_output = platform.get_hdl(fragment, name=build_name, **kwargs) vns = v_output.ns named_sc, named_pc = platform.resolve_signals(vns) v_file = build_name + ".v" v_output.write(v_file) sources = platform.sources | {(v_file, "verilog", "work")} if mode in ("xst", "cpld"): _build_xst_files(platform.device, sources, platform.verilog_include_paths, build_name, self.xst_opt) isemode = mode else: _run_yosys(platform.device, sources, platform.verilog_include_paths, build_name) isemode = "edif" ngdbuild_opt += "-p " + platform.device if mode == "mist": from mist import synthesize synthesize(fragment, platform.constraint_manager.get_io_signals()) if mode == "edif" or mode == "mist": e_output = platform.get_edif(fragment) vns = e_output.ns named_sc, named_pc = platform.resolve_signals(vns) e_file = build_name + ".edif" e_output.write(e_file) isemode = "edif" tools.write_to_file(build_name + ".ucf", _build_ucf(named_sc, named_pc)) if run: _run_ise(build_name, toolchain_path, source, isemode, ngdbuild_opt, self, platform) return vns
def _build_xst_files(device, sources, build_name, xst_opt): prj_contents = "" for filename, language, library in sources: prj_contents += language + " " + library + " " + filename + "\n" tools.write_to_file(build_name + ".prj", prj_contents) xst_contents = """run -ifn {build_name}.prj -top {build_name} {xst_opt} -ofn {build_name}.ngc -p {device} """.format(build_name=build_name, xst_opt=xst_opt, device=device) tools.write_to_file(build_name + ".xst", xst_contents)
def _run_yosys(device, sources, build_name): ys_contents = "" incflags = "" for filename, language, library in sources: ys_contents += "read_{}{} {}\n".format(language, incflags, filename) ys_contents += """hierarchy -check -top top proc; memory; opt; fsm; opt synth_xilinx -top top -edif {build_name}.edif""".format(build_name=build_name) ys_name = build_name + ".ys" tools.write_to_file(ys_name, ys_contents) r = subprocess.call(["yosys", ys_name]) if r != 0: raise OSError("Subprocess failed")
def _build_files(device, sources, named_sc, named_pc, build_name): lines = [] for filename, language, library in sources: # Enforce use of SystemVerilog # (Quartus does not support global parameters in Verilog) if language == "verilog": language = "systemverilog" lines.append("set_global_assignment -name {lang}_FILE {path} " "-library {lib}".format(lang=language.upper(), path=filename.replace("\\", "/"), lib=library)) 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 build(self, platform, fragment, build_dir="build", build_name="top", toolchain_path=None, run=True, **kwargs): if toolchain_path is None: toolchain_path = "/usr/share/trellis/" os.makedirs(build_dir, exist_ok=True) cwd = os.getcwd() os.chdir(build_dir) # generate verilog if not isinstance(fragment, _Fragment): fragment = fragment.get_fragment() platform.finalize(fragment) top_output = platform.get_verilog(fragment, name=build_name, **kwargs) named_sc, named_pc = platform.resolve_signals(top_output.ns) top_file = build_name + ".v" top_output.write(top_file) platform.add_source(top_file) # generate constraints tools.write_to_file(build_name + ".lpf", _build_lpf(named_sc, named_pc)) # generate yosys script yosys_script_file = build_name + ".ys" yosys_script_contents = "\n".join(_.format(build_name=build_name, read_files=yosys_import_sources(platform)) for _ in self.yosys_template) tools.write_to_file(yosys_script_file, yosys_script_contents) # transform platform.device to nextpnr's architecture / basecfg (family, size, package) = platform.device.split("-") architecture = nextpnr_ecp5_architectures[(family + "-" + size).lower()] basecfg = "empty_" + (family + "-" + size).lower() + ".config" basecfg = os.path.join(toolchain_path, "misc", "basecfgs", basecfg) freq_constraint = str(max(self.freq_constraints.values(), default=0.0)) script = _build_script(False, self.build_template, build_name, architecture, basecfg, freq_constraint) # run scripts if run: _run_script(script) os.chdir(cwd) return top_output.ns
def _build_script(build_name, device, toolchain_path, source, ver=None): if sys.platform in ("win32", "cygwin"): script_ext = ".bat" build_script_contents = "@echo off\nrem Autogenerated by Migen\n\n" copy_stmt = "copy" fail_stmt = " || exit /b" else: script_ext = ".sh" build_script_contents = "# Autogenerated by Migen\nset -e\n\n" copy_stmt = "cp" fail_stmt = "" if source: bindir = _get_bindir(toolchain_path, ver) if sys.platform in ("win32", "cygwin"): build_script_contents += "set PATH={};%PATH%\n".format(bindir) else: build_script_contents += "bindir={}\n".format(bindir) build_script_contents += ". ${{bindir}}/diamond_env{fail_stmt}\n".format( fail_stmt=fail_stmt) build_script_contents += "pnmainc {tcl_script}{fail_stmt}\n".format( tcl_script=build_name + ".tcl", fail_stmt=fail_stmt) for ext in (".bit", ".jed"): if ext == ".jed" and not _produces_jedec(device): continue diamond_product = os.path.join("impl", build_name + "_impl" + ext) if sys.platform in ("win32", "cygwin"): # While Windows itself has no problems with forward slashes # in paths, the COPY command on Windows uses forward slash for # arguments. MinGW Python 3 may (it is not consistent) create # paths with forward slashes on Windows, so remove them just in # case. diamond_product = diamond_product.replace("/", "\\") build_script_contents += "{copy_stmt} {diamond_product} {migen_product}" \ "{fail_stmt}\n".format( copy_stmt=copy_stmt, fail_stmt=fail_stmt, diamond_product=diamond_product, migen_product=build_name + ext) 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
def _build_xst_files(device, sources, vincpaths, build_name, xst_opt): prj_contents = "" for filename, language, library in sources: prj_contents += language + " " + library + " " + tools.cygpath(filename) + "\n" tools.write_to_file(build_name + ".prj", prj_contents) xst_contents = """run -ifn {build_name}.prj -top top {xst_opt} -ofn {build_name}.ngc -p {device} """.format(build_name=build_name, xst_opt=xst_opt, device=device) for path in vincpaths: xst_contents += "-vlgincdir " + tools.cygpath(path) + "\n" tools.write_to_file(build_name + ".xst", xst_contents)
def _build_xst_files(device, sources, vincpaths, build_name, xst_opt): prj_contents = "" for filename, language, library in sources: prj_contents += language + " " + library + " " + filename + "\n" tools.write_to_file(build_name + ".prj", prj_contents) xst_contents = """run -ifn {build_name}.prj -top top {xst_opt} -ofn {build_name}.ngc -p {device} """.format(build_name=build_name, xst_opt=xst_opt, device=device) for path in vincpaths: xst_contents += "-vlgincdir " + path + "\n" tools.write_to_file(build_name + ".xst", xst_contents)
def _build_files(device, sources, build_name): tcl = [] tcl.append( "prj_project new -name \"{}\" -impl \"impl\" -dev {} -synthesis \"synplify\"" .format(build_name, device)) for filename, language, library in sources: tcl.append("prj_src add \"" + filename + "\" -work " + library) tcl.append("prj_impl option top \"{}\"".format(build_name)) tcl.append("prj_project save") tcl.append("prj_run Synthesis -impl impl -forceOne") tcl.append("prj_run Translate -impl impl") tcl.append("prj_run Map -impl impl") tcl.append("prj_run PAR -impl impl") tcl.append("prj_run Export -impl impl -task Bitgen") if _produces_jedec(device): tcl.append("prj_run Export -impl impl -task Jedecgen") tools.write_to_file(build_name + ".tcl", "\n".join(tcl))
def _run_vivado(build_name): if sys.platform == "win32" or sys.platform == "cygwin": build_script_contents = "REM Autogenerated by Migen\n" build_script_contents += "vivado -mode batch -source " + build_name + ".tcl\n" build_script_file = "build_" + build_name + ".bat" tools.write_to_file(build_script_file, build_script_contents) command = build_script_file else: build_script_contents = "# Autogenerated by Migen\nset -e\n" build_script_contents += "export LC_ALL=C\n" # work around "locale::facet::_S_create_c_locale name not valid" build_script_contents += "vivado -mode batch -source " + build_name + ".tcl\n" build_script_file = "build_" + build_name + ".sh" tools.write_to_file(build_script_file, build_script_contents) command = ["bash", build_script_file] r = tools.subprocess_call_filtered(command, common.colors) if r != 0: raise OSError("Subprocess failed")
def _run_yosys(device, sources, vincpaths, build_name): ys_contents = "" incflags = "" for path in vincpaths: incflags += " -I" + path for filename, language, library in sources: ys_contents += "read_{}{} {}\n".format(language, incflags, filename) ys_contents += """hierarchy -check -top top proc; memory; opt; fsm; opt synth_xilinx -top top -edif {build_name}.edif""".format(build_name=build_name) ys_name = build_name + ".ys" tools.write_to_file(ys_name, ys_contents) r = subprocess.call(["yosys", ys_name]) if r != 0: raise OSError("Subprocess failed")
def _run_vivado(build_name, vivado_path, source, ver=None): if sys.platform == "win32" or sys.platform == "cygwin": build_script_contents = "REM Autogenerated by Migen\n" build_script_contents += "vivado -mode batch -source " + build_name + ".tcl\n" build_script_file = "build_" + build_name + ".bat" tools.write_to_file(build_script_file, build_script_contents) command = build_script_file else: build_script_contents = "# Autogenerated by Migen\nset -e\n" settings = common.settings(vivado_path, ver) build_script_contents += "source " + settings + "\n" build_script_contents += "vivado -mode batch -source " + build_name + ".tcl\n" build_script_file = "build_" + build_name + ".sh" tools.write_to_file(build_script_file, build_script_contents) command = ["bash", build_script_file] r = tools.subprocess_call_filtered(command, common.colors) if r != 0: raise OSError("Subprocess failed")
def _run_quartus(build_name, quartus_path): build_script_contents = """# Autogenerated by Migen set -e quartus_map --read_settings_files=on --write_settings_files=off {build_name} -c {build_name} quartus_fit --read_settings_files=off --write_settings_files=off {build_name} -c {build_name} 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) # noqa build_script_file = "build_" + build_name + ".sh" tools.write_to_file(build_script_file, build_script_contents, force_unix=True) if subprocess.call(["bash", build_script_file]): raise OSError("Subprocess failed")
def _build_script(source, build_template, build_name, **kwargs): if sys.platform in ("win32", "cygwin"): script_ext = ".bat" build_script_contents = "@echo off\nrem Autogenerated by Migen\n\n" fail_stmt = " || exit /b" else: script_ext = ".sh" build_script_contents = "# Autogenerated by Migen\nset -e\n\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(build_name=build_name, fail_stmt=fail_stmt, **kwargs) 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
def _run_ise(build_name, ise_path, source, mode, ngdbuild_opt, bitgen_opt, ise_commands, map_opt, par_opt, ver=None): if sys.platform == "win32" or sys.platform == "cygwin": source_cmd = "call " script_ext = ".bat" shell = ["cmd", "/c"] build_script_contents = "@echo off\nrem Autogenerated by Migen\n" fail_stmt = " || exit /b" else: source_cmd = "source " script_ext = ".sh" shell = ["bash"] build_script_contents = "# Autogenerated by Migen\nset -e\n" fail_stmt = "" if source: settings = common.settings(ise_path, ver, "ISE_DS") build_script_contents += source_cmd + settings + "\n" if mode == "edif": ext = "edif" else: ext = "ngc" build_script_contents += """ xst -ifn {build_name}.xst{fail_stmt} """ build_script_contents += """ ngdbuild {ngdbuild_opt} -uc {build_name}.ucf {build_name}.{ext} {build_name}.ngd{fail_stmt} map {map_opt} -o {build_name}_map.ncd {build_name}.ngd {build_name}.pcf{fail_stmt} par {par_opt} {build_name}_map.ncd {build_name}.ncd {build_name}.pcf{fail_stmt} bitgen {bitgen_opt} {build_name}.ncd {build_name}.bit{fail_stmt} """ build_script_contents = build_script_contents.format(build_name=build_name, ngdbuild_opt=ngdbuild_opt, bitgen_opt=bitgen_opt, ext=ext, par_opt=par_opt, map_opt=map_opt, fail_stmt=fail_stmt) build_script_contents += ise_commands.format(build_name=build_name) build_script_file = "build_" + build_name + script_ext tools.write_to_file(build_script_file, build_script_contents, force_unix=False) command = shell + [build_script_file] r = subprocess.call(command) if r != 0: raise OSError("Subprocess failed")
def _build_files(device, sources, vincpaths, named_sc, named_pc, build_name): lines = [] for filename, language, library in sources: # Enforce use of SystemVerilog # (Quartus does not support global parameters in Verilog) if language == "verilog": language = "systemverilog" lines.append( "set_global_assignment -name {lang}_FILE {path} " "-library {lib}".format( lang=language.upper(), path=filename.replace("\\", "/"), lib=library)) for path in vincpaths: lines.append("set_global_assignment -name SEARCH_PATH {}".format( path.replace("\\", "/"))) 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 build(self, platform, fragment, build_dir="build", build_name="top", run=True): os.makedirs(build_dir, exist_ok=True) cwd = os.getcwd() os.chdir(build_dir) if not isinstance(fragment, _Fragment): fragment = fragment.get_fragment() platform.finalize(fragment) v_output = platform.get_verilog(fragment) named_sc, named_pc = platform.resolve_signals(v_output.ns) v_file = build_name + ".v" v_output.write(v_file) ys_contents = "\n".join(_.format(build_name=build_name, read_files=self.gen_read_files(platform, v_file)) for _ in self.yosys_template) ys_name = build_name + ".ys" tools.write_to_file(ys_name, ys_contents) tools.write_to_file(build_name + ".pcf", _build_pcf(named_sc, named_pc)) if run: (family, series_size, package) = self.parse_device_string(platform.device) pnr_pkg_opts = "-d " + self.get_size_string(series_size) + \ " -P " + package icetime_pkg_opts = "-P " + package + " -d " + series_size icetime_constraint = str(max(self.freq_constraints.values(), default=0.0)) _run_icestorm(False, self.build_template, build_name, pnr_pkg_opts, icetime_pkg_opts, icetime_constraint) os.chdir(cwd) return v_output.ns
def _build_sim(platform, vns, build_name, include_paths, sim_path, serial, verbose): include = "" for path in include_paths: include += "-I"+path+" " build_script_contents = """# Autogenerated by Migen rm -rf obj_dir/ verilator {disable_warnings} -O3 --cc dut.v --exe dut_tb.cpp -LDFLAGS "-lpthread" -trace {include} make -j -C obj_dir/ -f Vdut.mk Vdut """.format( disable_warnings="-Wno-fatal", include=include) build_script_file = "build_" + build_name + ".sh" tools.write_to_file(build_script_file, build_script_contents, force_unix=True) _build_tb(platform, vns, serial, os.path.join("..", sim_path, "dut_tb.cpp")) if verbose: r = subprocess.call(["bash", build_script_file]) else: r = subprocess.call(["bash", build_script_file], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT) if r != 0: raise OSError("Subprocess failed")
def _run_quartus(build_name, quartus_path,bitstream_ext="sof"): print("Running _run_quartus Bitstream Extention = {}".format(bitstream_ext)) if bitstream_ext == "svf": quartus_cpf_opt ="-c -q 4.5MHz -g 3.3 -n p" prog_file_ext = "svf" elif bitstream_ext=="sof": quartus_cpf_opt = "-c" prog_file_ext = "rbf" else: raise Exception("_run_quartus unknown programming file extension {}".format(prog_file_ext)) build_script_contents = """# Autogenerated by Migen set -e quartus_map --read_settings_files=on --write_settings_files=off {build_name} -c {build_name} quartus_fit --read_settings_files=off --write_settings_files=off {build_name} -c {build_name} quartus_asm --read_settings_files=off --write_settings_files=off {build_name} -c {build_name} quartus_sta {build_name} -c {build_name} if [ -f "{build_name}.sof" ] then quartus_cpf {quartus_cpf_opt} {build_name}.sof {build_name}.{prog_file_ext} fi """.format(build_name=build_name,quartus_cpf_opt=quartus_cpf_opt,prog_file_ext=prog_file_ext) # noqa build_script_file = "build_" + build_name + ".sh" tools.write_to_file(build_script_file, build_script_contents, force_unix=True) if subprocess.call(["bash", build_script_file]): raise OSError("Subprocess failed")
def load_bitstream(self, bitstream_file): xcf_file = bitstream_file.replace(".bit", ".xcf") xcf_content = _xcf_template.format(bitstream_file=bitstream_file) tools.write_to_file(xcf_file, xcf_content) subprocess.call(["pgrcmd", "-infile", xcf_file])