#                  Ports-to-Clocks Correspondence Extraction

 

# The following scripts provide an automatic way to setup an input/output constraint for

# designs with multiple clock domains. For each input / output port, the clock which

# influences it is identified, then, the ports are grouped by their correspondence to

# the clock sources.

 

# Run these procedures directly after reading a verilog design: they don’t require

# the design to be compiled. However, they work on compiled designs well.

 

 

 

#==============================================================================

# Use this procedure in order to extract ports-to-clocks relationship

# Run it before using functions get_ciports and get_coports functions

# Syntax:   setup_cports <list_of_all_clock_ports>

# Example usage:

#

# read verilog ......

# create clock ......

#

# setup_cports {rx_clk tx_clk core_clk}

#

# set_input_delay  [expr 0.5 * $CORE_PERIOD] -clock CORE_CLOCK [get_ciports core_clk]

# set_output_delay  [expr 0.5 * $CORE_PERIOD] -clock CORE_CLOCK [get_coports core_clk]

#

# set_input_delay  [expr 0.5 * $RX_PERIOD] -clock RX_CLOCK [get_ciports rx_clk]

# set_output_delay  [expr 0.5 * $RX_PERIOD] -clock RX_CLOCK [get_coports rx_clk]

#

# set_input_delay  [expr 0.5 * $TX_PERIOD] -clock TX_CLOCK [get_ciports tx_clk]

# set_output_delay  [expr 0.5 * TX_PERIOD] -clock TX_CLOCK [get_coports tx_clk]

 

# The following script sets up an input delay/output delay for each port to be

# equal to a half period of the corresponding port's clock

 

# Note : Use this script directly after reading verilog in order to set automatically

# input/output delays for blocks with the multiple clock domains. However, this script can

# be used on mapped designs as well.

 

#==============================================================================

proc setup_cports {clocks} {

  global ciports coports

  foreach clk $clocks {

    set ciports($clk) ""; set coports($clk) "";

    foreach_in_collection reg [all_fanout -from $clk -flat -only_cells] {

      set creg([get_object_name $reg]) $clk

    }

  }

  foreach_in_collection input [all_inputs] {

    set regs_connected [all_fanout -flat -endpoints_only -only_cells -from $input]

    if {$regs_connected != ""} {

      set object [get_object_name [index_collection $regs_connected 0]]

      if {[string match *_reg* $object]} {

        set related_clock $creg($object)

        lappend ciports($related_clock) [get_object_name $input]

        puts "Input [c2l $input] : $related_clock"

      }

    }

  }

  foreach_in_collection output [all_outputs] {

    set regs_connected [all_fanin -flat -startpoints_only -only_cells -to $output]

    if {$regs_connected != ""} {

      set object [get_object_name [index_collection $regs_connected 0]]

      if {[string match *_reg* $object]} {

        set related_clock $creg($object)

        lappend coports($related_clock) [get_object_name $output]

        puts "Output [c2l $output] : $related_clock"

      }

    }

  }

}

 

#================================================================================ 

# Returns list of input ports which corresponds to specified clock

# Syntax: get_ciports <clock_port_name> [<pattern>]

# Specify pattern in order to constraint the search. If pattern is not

# specified, it is * by default.

# Example: get_ciports rx_clk *_in : Returns the list of input ports which

# corresponds to rx_clk clock port and has the suffix _in.

#================================================================================ 

proc get_ciports {{clock ""} {pattern *}} {

  global ciports

  set ret_list ""

  foreach inport $ciports($clock) {

    if {[string match $pattern $inport]} {lappend ret_list $inport}

  }

  return $ret_list

}

 

 

#================================================================================ 

# Returns list of output ports which corresponds to a specified clock

# Syntax: get_coports <clock_port_name> [<pattern>]

# Specify pattern in order to constraint the search. If pattern is not

# specified, it is * by default.

# Example: get_coports rx_clk *_out : Returns the list of output ports which

# corresponds to rx_clk clock port and has the suffix _out.

#================================================================================ 

proc get_coports {{clock ""} {pattern *}} {

  global coports

  set ret_list ""

  foreach outport $coports($clock) {

    if {[string match $pattern $outport]} {lappend ret_list $outport}

  }

  return $ret_list

}

#================================================================================