build.plat: use tcl_quote instead of tcl_escape.

The premise of `tcl_escape` is incorrect: it is not possible, by design,
to escape a single backslash inside of a Tcl {}-quoted string:

    $ tclsh
    % puts {\\}
    \\

`tcl_quote` should be used instead since it can escape arbitrary strings
(and uses the right algorithm already).
This commit is contained in:
Catherine 2024-02-29 19:30:31 +00:00
parent 65191be1b1
commit 871d726ad4
7 changed files with 20 additions and 24 deletions

View file

@ -423,9 +423,6 @@ class TemplatedPlatform(Platform):
return f"_{ord(match.group(1)[0]):02x}_"
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 tcl_quote(string):
return '"' + re.sub(r"([$[\\])", r"\\\1", string) + '"'
@ -449,7 +446,6 @@ class TemplatedPlatform(Platform):
compiled.environment.filters["options"] = options
compiled.environment.filters["hierarchy"] = hierarchy
compiled.environment.filters["ascii_escape"] = ascii_escape
compiled.environment.filters["tcl_escape"] = tcl_escape
compiled.environment.filters["tcl_quote"] = tcl_quote
except jinja2.TemplateSyntaxError as e:
e.args = (f"{e.message} (at {origin}:{e.lineno})",)

View file

@ -288,7 +288,7 @@ class GowinPlatform(TemplatedPlatform):
"{{name}}.sdc": r"""
// {{autogenerated}}
{% for net_signal,port_signal,frequency in platform.iter_clock_constraints() -%}
create_clock -name {{port_signal.name|tcl_escape}} -period {{1000000000/frequency}} [get_ports {{port_signal.name|tcl_escape}}]
create_clock -name {{port_signal.name|tcl_quote}} -period {{1000000000/frequency}} [get_ports {{port_signal.name|tcl_quote}}]
{% endfor %}
{{get_override("add_constraints")|default("# (add_constraints placeholder)")}}
""",

View file

@ -206,7 +206,7 @@ class LatticeECP5Platform(TemplatedPlatform):
-lpf {{name}}.lpf \
-synthesis synplify
{% for file in platform.iter_files(".v", ".sv", ".vhd", ".vhdl") -%}
prj_src add {{file|tcl_escape}}
prj_src add {{file|tcl_quote}}
{% endfor %}
prj_src add {{name}}.v
prj_impl option top {{name}}
@ -237,9 +237,9 @@ class LatticeECP5Platform(TemplatedPlatform):
set_hierarchy_separator {/}
{% for net_signal, port_signal, frequency in platform.iter_clock_constraints() -%}
{% if port_signal is not none -%}
create_clock -name {{port_signal.name|tcl_escape}} -period {{1000000000/frequency}} [get_ports {{port_signal.name|tcl_escape}}]
create_clock -name {{port_signal.name|tcl_quote}} -period {{1000000000/frequency}} [get_ports {{port_signal.name|tcl_quote}}]
{% else -%}
create_clock -name {{net_signal.name|tcl_escape}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("/")|tcl_escape}}]
create_clock -name {{net_signal.name|tcl_quote}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("/")|tcl_quote}}]
{% endif %}
{% endfor %}
{{get_override("add_constraints")|default("# (add_constraints placeholder)")}}

View file

@ -216,7 +216,7 @@ class LatticeICE40Platform(TemplatedPlatform):
"{{name}}_syn.prj": r"""
# {{autogenerated}}
{% for file in platform.iter_files(".v", ".sv", ".vhd", ".vhdl") -%}
add_file -verilog {{file|tcl_escape}}
add_file -verilog {{file|tcl_quote}}
{% endfor %}
add_file -verilog {{name}}.v
add_file -constraint {{name}}.sdc
@ -239,9 +239,9 @@ class LatticeICE40Platform(TemplatedPlatform):
set_hierarchy_separator {/}
{% for net_signal, port_signal, frequency in platform.iter_clock_constraints() -%}
{% if port_signal is not none -%}
create_clock -name {{port_signal.name|tcl_escape}} -period {{1000000000/frequency}} [get_ports {{port_signal.name|tcl_escape}}]
create_clock -name {{port_signal.name|tcl_quote}} -period {{1000000000/frequency}} [get_ports {{port_signal.name|tcl_quote}}]
{% else -%}
create_clock -name {{net_signal.name|tcl_escape}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("/")|tcl_escape}}]
create_clock -name {{net_signal.name|tcl_quote}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("/")|tcl_quote}}]
{% endif %}
{% endfor %}
{{get_override("add_constraints")|default("# (add_constraints placeholder)")}}

View file

@ -72,7 +72,7 @@ class LatticeMachXO2Or3LPlatform(TemplatedPlatform):
-lpf {{name}}.lpf \
-synthesis synplify
{% for file in platform.iter_files(".v", ".sv", ".vhd", ".vhdl") -%}
prj_src add {{file|tcl_escape}}
prj_src add {{file|tcl_quote}}
{% endfor %}
prj_src add {{name}}.v
prj_impl option top {{name}}
@ -104,9 +104,9 @@ class LatticeMachXO2Or3LPlatform(TemplatedPlatform):
set_hierarchy_separator {/}
{% for net_signal, port_signal, frequency in platform.iter_clock_constraints() -%}
{% if port_signal is not none -%}
create_clock -name {{port_signal.name|tcl_escape}} -period {{1000000000/frequency}} [get_ports {{port_signal.name|tcl_escape}}]
create_clock -name {{port_signal.name|tcl_quote}} -period {{1000000000/frequency}} [get_ports {{port_signal.name|tcl_quote}}]
{% else -%}
create_clock -name {{net_signal.name|tcl_escape}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("/")|tcl_escape}}]
create_clock -name {{net_signal.name|tcl_quote}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("/")|tcl_quote}}]
{% endif %}
{% endfor %}
{{get_override("add_constraints")|default("# (add_constraints placeholder)")}}

View file

@ -64,7 +64,7 @@ class QuicklogicPlatform(TemplatedPlatform):
# {{autogenerated}}
{% for port_name, pin_name, attrs in platform.iter_port_constraints_bits() -%}
{% for attr_name, attr_value in attrs.items() -%}
set_property {{attr_name}} {{attr_value}} [get_ports {{port_name|tcl_escape}} }]
set_property {{attr_name}} {{attr_value}} [get_ports {{port_name|tcl_quote}} }]
{% endfor %}
{% endfor %}
{{get_override("add_constraints")|default("# (add_constraints placeholder)")}}

View file

@ -158,12 +158,12 @@ class XilinxPlatform(TemplatedPlatform):
# {{autogenerated}}
create_project -force -name {{name}} -part {{platform._part}}
{% for file in platform.iter_files(".v", ".sv", ".vhd", ".vhdl") -%}
add_files {{file|tcl_escape}}
add_files {{file|tcl_quote}}
{% endfor %}
add_files {{name}}.v
read_xdc {{name}}.xdc
{% for file in platform.iter_files(".xdc") -%}
read_xdc {{file|tcl_escape}}
read_xdc {{file|tcl_quote}}
{% endfor %}
{{get_override("script_after_read")|default("# (script_after_read placeholder)")}}
synth_design -top {{name}} {{get_override("synth_design_opts")}}
@ -218,16 +218,16 @@ class XilinxPlatform(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|tcl_escape}}]
set_property LOC {{pin_name}} [get_ports {{port_name|tcl_quote}}]
{% for attr_name, attr_value in attrs.items() -%}
set_property {{attr_name}} {{attr_value|tcl_escape}} [get_ports {{port_name|tcl_escape}}]
set_property {{attr_name}} {{attr_value|tcl_quote}} [get_ports {{port_name|tcl_quote}}]
{% 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|ascii_escape}} -period {{1000000000/frequency}} [get_ports {{port_signal.name|tcl_escape}}]
create_clock -name {{port_signal.name|ascii_escape}} -period {{1000000000/frequency}} [get_ports {{port_signal.name|tcl_quote}}]
{% else -%}
create_clock -name {{net_signal.name|ascii_escape}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("/")|tcl_escape}}]
create_clock -name {{net_signal.name|ascii_escape}} -period {{1000000000/frequency}} [get_nets {{net_signal|hierarchy("/")|tcl_quote}}]
{% endif %}
{% endfor %}
{{get_override("add_constraints")|default("# (add_constraints placeholder)")}}
@ -417,7 +417,7 @@ class XilinxPlatform(TemplatedPlatform):
# {{autogenerated}}
{% for port_name, pin_name, attrs in platform.iter_port_constraints_bits() -%}
{% for attr_name, attr_value in attrs.items() -%}
set_property {{attr_name}} {{attr_value}} [get_ports {{port_name|tcl_escape}} }]
set_property {{attr_name}} {{attr_value}} [get_ports {{port_name|tcl_quote}} }]
{% endfor %}
{% endfor %}
{{get_override("add_constraints")|default("# (add_constraints placeholder)")}}
@ -529,8 +529,8 @@ class XilinxPlatform(TemplatedPlatform):
# {{autogenerated}}
{% for port_name, pin_name, attrs in platform.iter_port_constraints_bits() -%}
{% for attr_name, attr_value in attrs.items() -%}
set_property {{attr_name}} {{attr_value}} [get_ports {{port_name|tcl_escape}}]
set_property LOC {{pin_name}} [get_ports {{port_name|tcl_escape}}]
set_property {{attr_name}} {{attr_value}} [get_ports {{port_name|tcl_quote}}]
set_property LOC {{pin_name}} [get_ports {{port_name|tcl_quote}}]
{% endfor %}
{% endfor %}
""",