diff --git a/nmigen/build/plat.py b/nmigen/build/plat.py index d9f2ab2..17f147b 100644 --- a/nmigen/build/plat.py +++ b/nmigen/build/plat.py @@ -368,6 +368,17 @@ class TemplatedPlatform(Platform): def hierarchy(signal, separator): return separator.join(name_map[signal][1:]) + def ascii_escape(string): + def escape_one(match): + if match.group(1) is None: + return match.group(2) + else: + return "_{:02x}_".format(ord(match.group(1)[0])) + return "".join(escape_one(m) for m in re.finditer(r"([^A-Za-z0-9_])|(.)", string)) + + def tcl_escape(string): + return "{" + re.sub(r"([{}\\])", r"\\\1", string) + "}" + def verbose(arg): if "NMIGEN_verbose" in os.environ: return arg @@ -387,6 +398,8 @@ class TemplatedPlatform(Platform): trim_blocks=True, lstrip_blocks=True, undefined=jinja2.StrictUndefined) compiled.environment.filters["options"] = options compiled.environment.filters["hierarchy"] = hierarchy + compiled.environment.filters["ascii_escape"] = ascii_escape + compiled.environment.filters["tcl_escape"] = tcl_escape except jinja2.TemplateSyntaxError as e: e.args = ("{} (at {}:{})".format(e.message, origin, e.lineno),) raise diff --git a/nmigen/vendor/intel.py b/nmigen/vendor/intel.py index 2f0c81f..07ee95b 100644 --- a/nmigen/vendor/intel.py +++ b/nmigen/vendor/intel.py @@ -85,22 +85,22 @@ class IntelPlatform(TemplatedPlatform): {% endif %} {% for file in platform.iter_extra_files(".v") -%} - set_global_assignment -name VERILOG_FILE "{{file}}" + set_global_assignment -name VERILOG_FILE {{file|tcl_escape}} {% endfor %} {% for file in platform.iter_extra_files(".sv") -%} - set_global_assignment -name SYSTEMVERILOG_FILE "{{file}}" + set_global_assignment -name SYSTEMVERILOG_FILE {{file|tcl_escape}} {% endfor %} {% for file in platform.iter_extra_files(".vhd", ".vhdl") -%} - set_global_assignment -name VHDL_FILE "{{file}}" + set_global_assignment -name VHDL_FILE {{file|tcl_escape}} {% endfor %} set_global_assignment -name VERILOG_FILE {{name}}.v set_global_assignment -name TOP_LEVEL_ENTITY {{name}} set_global_assignment -name DEVICE {{platform.device}}{{platform.package}}{{platform.speed}}{{platform.suffix}} - {% for port_name, pin_name, extras in platform.iter_port_constraints_bits() -%} - set_location_assignment -to "{{port_name}}" PIN_{{pin_name}} - {% for key, value in extras.items() -%} - set_instance_assignment -to "{{port_name}}" -name {{key}} "{{value}}" + {% for port_name, pin_name, attrs in platform.iter_port_constraints_bits() -%} + set_location_assignment -to {{port_name|tcl_escape}} PIN_{{pin_name}} + {% for key, value in attrs.items() -%} + set_instance_assignment -to {{port_name|tcl_escape}} -name {{key}} {{value|tcl_escape}} {% endfor %} {% endfor %} @@ -109,9 +109,9 @@ class IntelPlatform(TemplatedPlatform): "{{name}}.sdc": r""" {% for net_signal, port_signal, frequency in platform.iter_clock_constraints() -%} {% if port_signal is not none -%} - create_clock -name {{port_signal.name}} -period {{1000000000/frequency}} [get_ports {{port_signal.name}}] + create_clock -name {{port_signal.name|tcl_escape}} -period {{1000000000/frequency}} [get_ports {{port_signal.name|tcl_escape}}] {% else -%} - create_clock -name {{net_signal.name}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("|")}}] + create_clock -name {{net_signal.name|tcl_escape}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("|")|tcl_escape}}] {% endif %} {% endfor %} """, diff --git a/nmigen/vendor/lattice_ecp5.py b/nmigen/vendor/lattice_ecp5.py index 53e1626..cfa20ee 100644 --- a/nmigen/vendor/lattice_ecp5.py +++ b/nmigen/vendor/lattice_ecp5.py @@ -126,11 +126,11 @@ class LatticeECP5Platform(TemplatedPlatform): # {{autogenerated}} BLOCK ASYNCPATHS; BLOCK RESETPATHS; - {% for port_name, pin_name, extras in platform.iter_port_constraints_bits() -%} + {% for port_name, pin_name, attrs in platform.iter_port_constraints_bits() -%} LOCATE COMP "{{port_name}}" SITE "{{pin_name}}"; - {% if extras -%} + {% if attrs -%} IOBUF PORT "{{port_name}}" - {%- for key, value in extras.items() %} {{key}}={{value}}{% endfor %}; + {%- for key, value in attrs.items() %} {{key}}={{value}}{% endfor %}; {% endif %} {% endfor %} {% for net_signal, port_signal, frequency in platform.iter_clock_constraints() -%} @@ -206,7 +206,7 @@ class LatticeECP5Platform(TemplatedPlatform): -lpf {{name}}.lpf \ -synthesis synplify {% for file in platform.iter_extra_files(".v", ".sv", ".vhd", ".vhdl") -%} - prj_src add "{{file}}" + prj_src add {{file|tcl_escape}} {% endfor %} prj_src add {{name}}.v prj_impl option top {{name}} @@ -217,7 +217,7 @@ class LatticeECP5Platform(TemplatedPlatform): prj_run Translate -impl impl -forceAll prj_run Map -impl impl -forceAll prj_run PAR -impl impl -forceAll - prj_run Export -impl "impl" -forceAll -task Bitgen + prj_run Export -impl impl -forceAll -task Bitgen {{get_override("script_after_export")|default("# (script_after_export placeholder)")}} """, "{{name}}.lpf": r""" @@ -234,9 +234,9 @@ class LatticeECP5Platform(TemplatedPlatform): "{{name}}.sdc": r""" {% for net_signal, port_signal, frequency in platform.iter_clock_constraints() -%} {% if port_signal is not none -%} - create_clock -name {{port_signal.name}} -period {{1000000000/frequency}} [get_ports {{port_signal.name}}] + create_clock -name {{port_signal.name|tcl_escape}} -period {{1000000000/frequency}} [get_ports {{port_signal.name|tcl_escape}}] {% else -%} - create_clock -name {{net_signal.name}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("/")}}] + create_clock -name {{net_signal.name|tcl_escape}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("/")|tcl_escape}}] {% endif %} {% endfor %} {{get_override("add_constraints")|default("# (add_constraints placeholder)")}} diff --git a/nmigen/vendor/lattice_ice40.py b/nmigen/vendor/lattice_ice40.py index 94dd02a..4617d03 100644 --- a/nmigen/vendor/lattice_ice40.py +++ b/nmigen/vendor/lattice_ice40.py @@ -224,7 +224,7 @@ class LatticeICE40Platform(TemplatedPlatform): "{{name}}_syn.prj": r""" # {{autogenerated}} {% for file in platform.iter_extra_files(".v", ".sv", ".vhd", ".vhdl") -%} - add_file -verilog {{file}} + add_file -verilog {{file|tcl_escape}} {% endfor %} add_file -verilog {{name}}.v add_file -constraint {{name}}.sdc @@ -246,9 +246,9 @@ class LatticeICE40Platform(TemplatedPlatform): # {{autogenerated}} {% for net_signal, port_signal, frequency in platform.iter_clock_constraints() -%} {% if port_signal is not none -%} - create_clock -name {{port_signal.name}} -period {{1000000000/frequency}} [get_ports {{port_signal.name}}] + create_clock -name {{port_signal.name|tcl_escape}} -period {{1000000000/frequency}} [get_ports {{port_signal.name|tcl_escape}}] {% else -%} - create_clock -name {{net_signal.name}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("/")}}] + create_clock -name {{net_signal.name|tcl_escape}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("/")|tcl_escape}}] {% endif %} {% endfor %} {{get_override("add_constraints")|default("# (add_constraints placeholder)")}} diff --git a/nmigen/vendor/lattice_machxo2.py b/nmigen/vendor/lattice_machxo2.py index 962994b..3ce9962 100644 --- a/nmigen/vendor/lattice_machxo2.py +++ b/nmigen/vendor/lattice_machxo2.py @@ -66,7 +66,7 @@ class LatticeMachXO2Platform(TemplatedPlatform): -lpf {{name}}.lpf \ -synthesis synplify {% for file in platform.iter_extra_files(".v", ".sv", ".vhd", ".vhdl") -%} - prj_src add "{{file}}" + prj_src add {{file|tcl_escape}} {% endfor %} prj_src add {{name}}.v prj_impl option top {{name}} @@ -84,11 +84,11 @@ class LatticeMachXO2Platform(TemplatedPlatform): # {{autogenerated}} BLOCK ASYNCPATHS; BLOCK RESETPATHS; - {% for port_name, pin_name, extras in platform.iter_port_constraints_bits() -%} + {% for port_name, pin_name, attrs in platform.iter_port_constraints_bits() -%} LOCATE COMP "{{port_name}}" SITE "{{pin_name}}"; - {% if extras -%} + {% if attrs -%} IOBUF PORT "{{port_name}}" - {%- for key, value in extras.items() %} {{key}}={{value}}{% endfor %}; + {%- for key, value in attrs.items() %} {{key}}={{value}}{% endfor %}; {% endif %} {% endfor %} {{get_override("add_preferences")|default("# (add_preferences placeholder)")}} @@ -96,9 +96,9 @@ class LatticeMachXO2Platform(TemplatedPlatform): "{{name}}.sdc": r""" {% for net_signal, port_signal, frequency in platform.iter_clock_constraints() -%} {% if port_signal is not none -%} - create_clock -name {{port_signal.name}} -period {{1000000000/frequency}} [get_ports {{port_signal.name}}] + create_clock -name {{port_signal.name|tcl_escape}} -period {{1000000000/frequency}} [get_ports {{port_signal.name|tcl_escape}}] {% else -%} - create_clock -name {{net_signal.name}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("/")}}] + create_clock -name {{net_signal.name|tcl_escape}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("/")|tcl_escape}}] {% endif %} {% endfor %} {{get_override("add_constraints")|default("# (add_constraints placeholder)")}} diff --git a/nmigen/vendor/xilinx_7series.py b/nmigen/vendor/xilinx_7series.py index 128035d..5da57a6 100644 --- a/nmigen/vendor/xilinx_7series.py +++ b/nmigen/vendor/xilinx_7series.py @@ -78,12 +78,12 @@ class Xilinx7SeriesPlatform(TemplatedPlatform): # {{autogenerated}} create_project -force -name {{name}} -part {{platform.device}}{{platform.package}}-{{platform.speed}}{{"-" + platform.grade if platform.grade else ""}} {% for file in platform.iter_extra_files(".v", ".sv", ".vhd", ".vhdl") -%} - add_files {{file}} + add_files {{file|tcl_escape}} {% endfor %} add_files {{name}}.v read_xdc {{name}}.xdc {% for file in platform.iter_extra_files(".xdc") -%} - read_xdc {{file}} + read_xdc {{file|tcl_escape}} {% endfor %} {{get_override("script_after_read")|default("# (script_after_read placeholder)")}} synth_design -top {{name}} @@ -128,16 +128,16 @@ class Xilinx7SeriesPlatform(TemplatedPlatform): "{{name}}.xdc": r""" # {{autogenerated}} {% for port_name, pin_name, attrs in platform.iter_port_constraints_bits() -%} - set_property LOC {{pin_name}} [get_ports {{port_name}}] + set_property LOC {{pin_name}} [get_ports {{port_name|tcl_escape}}] {% for attr_name, attr_value in attrs.items() -%} - set_property {{attr_name}} {{attr_value}} [get_ports {{port_name}}] + set_property {{attr_name}} {{attr_value|tcl_escape}} [get_ports {{port_name|tcl_escape}}] {% endfor %} {% endfor %} {% for net_signal, port_signal, frequency in platform.iter_clock_constraints() -%} {% if port_signal is not none -%} - create_clock -name {{port_signal.name}} -period {{1000000000/frequency}} [get_ports {{port_signal.name}}] + create_clock -name {{port_signal.name|ascii_escape}} -period {{1000000000/frequency}} [get_ports {{port_signal.name|tcl_escape}}] {% else -%} - create_clock -name {{net_signal.name}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("/")}}] + create_clock -name {{net_signal.name|ascii_escape}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("/")|tcl_escape}}] {% endif %} {% endfor %} {{get_override("add_constraints")|default("# (add_constraints placeholder)")}} diff --git a/nmigen/vendor/xilinx_ultrascale.py b/nmigen/vendor/xilinx_ultrascale.py index 113753c..d4136fb 100644 --- a/nmigen/vendor/xilinx_ultrascale.py +++ b/nmigen/vendor/xilinx_ultrascale.py @@ -78,12 +78,12 @@ class XilinxUltraScalePlatform(TemplatedPlatform): # {{autogenerated}} create_project -force -name {{name}} -part {{platform.device}}-{{platform.package}}-{{platform.speed}}{{"-" + platform.grade if platform.grade else ""}} {% for file in platform.iter_extra_files(".v", ".sv", ".vhd", ".vhdl") -%} - add_files {{file}} + add_files {{file|tcl_escape}} {% endfor %} add_files {{name}}.v read_xdc {{name}}.xdc {% for file in platform.iter_extra_files(".xdc") -%} - read_xdc {{file}} + read_xdc {{file|tcl_escape}} {% endfor %} {{get_override("script_after_read")|default("# (script_after_read placeholder)")}} synth_design -top {{name}} @@ -128,16 +128,16 @@ class XilinxUltraScalePlatform(TemplatedPlatform): "{{name}}.xdc": r""" # {{autogenerated}} {% for port_name, pin_name, attrs in platform.iter_port_constraints_bits() -%} - set_property LOC {{pin_name}} [get_ports {{port_name}}] + set_property LOC {{pin_name}} [get_ports {{port_name|tcl_escape}}] {% for attr_name, attr_value in attrs.items() -%} - set_property {{attr_name}} {{attr_value}} [get_ports {{port_name}}] + set_property {{attr_name}} {{attr_value|tcl_escape}} [get_ports {{port_name|tcl_escape}}] {% endfor %} {% endfor %} {% for net_signal, port_signal, frequency in platform.iter_clock_constraints() -%} {% if port_signal is not none -%} - create_clock -name {{port_signal.name}} -period {{1000000000/frequency}} [get_ports {{port_signal.name}}] + create_clock -name {{port_signal.name|ascii_escape}} -period {{1000000000/frequency}} [get_ports {{port_signal.name|tcl_escape}}] {% else -%} - create_clock -name {{net_signal.name}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("/")}}] + create_clock -name {{net_signal.name|ascii_escape}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("/")|tcl_escape}}] {% endif %} {% endfor %} {{get_override("add_constraints")|default("# (add_constraints placeholder)")}}