+ def _convert_clocks(self, platform):
+ for clk, period in sorted(self.clocks.items(), key=lambda x: x[0].duid):
+ platform.add_platform_command(
+ "create_clock -name {clk} -period " + str(period) +
+ " [get_nets {clk}]", clk=clk)
+ for from_, to in sorted(self.false_paths,
+ key=lambda x: (x[0].duid, x[1].duid)):
+ platform.add_platform_command(
+ "set_clock_groups "
+ "-group [get_clocks -include_generated_clocks -of [get_nets {from_}]] "
+ "-group [get_clocks -include_generated_clocks -of [get_nets {to}]] "
+ "-asynchronous",
+ from_=from_, to=to)
+
+ # make sure add_*_constraint cannot be used again
+ del self.clocks
+ del self.false_paths
+
+ def _constrain(self, platform):
+ # The asynchronous input to a MultiReg is a false path
+ platform.add_platform_command(
+ "set_false_path -quiet "
+ "-to [get_nets -filter {{mr_ff == TRUE}}]"
+ )
+ # The asychronous reset input to the AsyncResetSynchronizer is a false
+ # path
+ platform.add_platform_command(
+ "set_false_path -quiet "
+ "-to [get_pins -filter {{REF_PIN_NAME == PRE}} "
+ "-of [get_cells -filter {{ars_ff1 == TRUE || ars_ff2 == TRUE}}]]"
+ )
+ # clock_period-2ns to resolve metastability on the wire between the
+ # AsyncResetSynchronizer FFs
+ platform.add_platform_command(
+ "set_max_delay 2 -quiet "
+ "-from [get_pins -filter {{REF_PIN_NAME == Q}} "
+ "-of [get_cells -filter {{ars_ff1 == TRUE}}]] "
+ "-to [get_pins -filter {{REF_PIN_NAME == D}} "
+ "-of [get_cells -filter {{ars_ff2 == TRUE}}]]"
+ )
+