vendor.xilinx_{7series,ultrascale}: add (*keep*) on constrained clocks.
If the clock signal is not a top-level port and has aliases, it can be optimized out, and then the constraint will no longer apply. To prevent this, make sure the constrained signal is preferred over any aliases by using the `keep` attribute. Vivado does not parse attributes like (* keep = 32'd1 *) as valid even though, AFAICT, they are equivalent to (* keep = 1 *) or simply (* keep *) per IEEE 1364. To work around this, use the solution we currently use for Quartus, which is `write_verilog -decimal`. Fixes #373.
This commit is contained in:
parent
7ea81f5f06
commit
892cff059b
2
nmigen/vendor/intel.py
vendored
2
nmigen/vendor/intel.py
vendored
|
@ -146,8 +146,6 @@ class IntelPlatform(TemplatedPlatform):
|
|||
|
||||
def add_clock_constraint(self, clock, frequency):
|
||||
super().add_clock_constraint(clock, frequency)
|
||||
# Make sure the net constrained in the SDC file is kept through synthesis; it is redundant
|
||||
# after Quartus flattens the hierarchy and will be eliminated if not explicitly kept.
|
||||
clock.attrs["keep"] = 1
|
||||
|
||||
# The altiobuf_* and altddio_* primitives are explained in the following Intel documents:
|
||||
|
|
10
nmigen/vendor/xilinx_7series.py
vendored
10
nmigen/vendor/xilinx_7series.py
vendored
|
@ -66,13 +66,15 @@ class Xilinx7SeriesPlatform(TemplatedPlatform):
|
|||
[ -n "${{platform._toolchain_env_var}}" ] && . "${{platform._toolchain_env_var}}"
|
||||
{{emit_commands("sh")}}
|
||||
""",
|
||||
# Vivado doesn't like constructs like (* keep = 32'd1 *), even though they mean the same
|
||||
# thing as (* keep = 1 *); use -decimal to work around that.
|
||||
"{{name}}.v": r"""
|
||||
/* {{autogenerated}} */
|
||||
{{emit_verilog()}}
|
||||
{{emit_verilog(["-decimal"])}}
|
||||
""",
|
||||
"{{name}}.debug.v": r"""
|
||||
/* {{autogenerated}} */
|
||||
{{emit_debug_verilog()}}
|
||||
{{emit_debug_verilog(["-decimal"])}}
|
||||
""",
|
||||
"{{name}}.tcl": r"""
|
||||
# {{autogenerated}}
|
||||
|
@ -177,6 +179,10 @@ class Xilinx7SeriesPlatform(TemplatedPlatform):
|
|||
m.submodules.reset_sync = ResetSynchronizer(rst_i, domain="sync")
|
||||
return m
|
||||
|
||||
def add_clock_constraint(self, clock, frequency):
|
||||
super().add_clock_constraint(clock, frequency)
|
||||
clock.attrs["keep"] = 1
|
||||
|
||||
def _get_xdr_buffer(self, m, pin, *, i_invert=False, o_invert=False):
|
||||
def get_dff(clk, d, q):
|
||||
# SDR I/O is performed by packing a flip-flop into the pad IOB.
|
||||
|
|
10
nmigen/vendor/xilinx_ultrascale.py
vendored
10
nmigen/vendor/xilinx_ultrascale.py
vendored
|
@ -66,13 +66,15 @@ class XilinxUltraScalePlatform(TemplatedPlatform):
|
|||
[ -n "${{platform._toolchain_env_var}}" ] && . "${{platform._toolchain_env_var}}"
|
||||
{{emit_commands("sh")}}
|
||||
""",
|
||||
# Vivado doesn't like constructs like (* keep = 32'd1 *), even though they mean the same
|
||||
# thing as (* keep = 1 *); use -decimal to work around that.
|
||||
"{{name}}.v": r"""
|
||||
/* {{autogenerated}} */
|
||||
{{emit_verilog()}}
|
||||
{{emit_verilog(["-decimal"])}}
|
||||
""",
|
||||
"{{name}}.debug.v": r"""
|
||||
/* {{autogenerated}} */
|
||||
{{emit_debug_verilog()}}
|
||||
{{emit_debug_verilog(["-decimal"])}}
|
||||
""",
|
||||
"{{name}}.tcl": r"""
|
||||
# {{autogenerated}}
|
||||
|
@ -177,6 +179,10 @@ class XilinxUltraScalePlatform(TemplatedPlatform):
|
|||
m.submodules.reset_sync = ResetSynchronizer(rst_i, domain="sync")
|
||||
return m
|
||||
|
||||
def add_clock_constraint(self, clock, frequency):
|
||||
super().add_clock_constraint(clock, frequency)
|
||||
clock.attrs["keep"] = 1
|
||||
|
||||
def _get_xdr_buffer(self, m, pin, *, i_invert=False, o_invert=False):
|
||||
def get_dff(clk, d, q):
|
||||
# SDR I/O is performed by packing a flip-flop into the pad IOB.
|
||||
|
|
Loading…
Reference in a new issue