openfpga/src/fpga_sdc/analysis_sdc_grid_writer.cpp
/********************************************************************
 * This function can work in two differnt modes:
 * 1. For partially unused pb blocks
 * ---------------------------------
 * Disable the timing for only unused resources in a physical block
 * We have to walk through pb_graph node, port by port and pin by pin.
 * Identify which pins have not been used, and then disable the timing 
 * for these ports. 
 * Plus, for input ports, we will trace the routing multiplexers
 * and disable the timing for unused inputs.
 *
 * 2. For fully unused pb_blocks
 * ----------------------------- 
 * Disable the timing for a fully unused grid!
 * This is very straightforward!
 * Just walk through each pb_type and disable all the ports using wildcards
 *******************************************************************/
This function can work in two differnt modes:
1. For partially unused pb blocks

Disable the timing for only unused resources in a physical block
We have to walk through pb_graph node, port by port and pin by pin.
Identify which pins have not been used, and then disable the timing
for these ports.
Plus, for input ports, we will trace the routing multiplexers
and disable the timing for unused inputs.

2. For fully unused pb_blocks

Disable the timing for a fully unused grid.
This is very straightforward.
Just walk through each pb_type and disable all the ports using wildcards
This function can work in two differnt modes : 1 . For partially unused pb blocks Disable the timing for only unused resources in a physical block We have to walk through pb_graph node port by port and pin by pin . Identify which pins have not been used and then disable the timing for these ports . Plus for input ports we will trace the routing multiplexers and disable the timing for unused inputs . 2 . For fully unused pb_blocks Disable the timing for a fully unused grid . This is very straightforward . Just walk through each pb_type and disable all the ports using wildcards
static 
void print_analysis_sdc_disable_pb_block_unused_resources(std::fstream& fp,
                                                          t_physical_tile_type_ptr grid_type,
                                                          const vtr::Point<size_t>& grid_coordinate,
                                                          const VprDeviceAnnotation& device_annotation,
                                                          const ModuleManager& module_manager,
                                                          const std::string& grid_instance_name,
                                                          const size_t& grid_z,
                                                          const PhysicalPb& physical_pb,
                                                          const bool& unused_block) {
  if (false == unused_block) {
    VTR_ASSERT(false == physical_pb.empty());
  }
  VTR_ASSERT(1 == grid_type->equivalent_sites.size());
  t_pb_graph_node* pb_graph_head = grid_type->equivalent_sites[0]->pb_graph_head; 
  VTR_ASSERT(nullptr != pb_graph_head);
  std::string pb_module_name = generate_physical_block_module_name(pb_graph_head->pb_type);
  std::string pb_instance_name = generate_physical_block_instance_name(pb_graph_head->pb_type, grid_z);
  ModuleId pb_module = module_manager.find_module(pb_module_name);
  VTR_ASSERT(true == module_manager.valid_module_id(pb_module));
  fp << "#######################################" << std::endl; 
  if (true == unused_block) {
    fp << "# Disable Timing for unused grid[" << grid_coordinate.x() << "][" << grid_coordinate.y() << "][" << grid_z << "]" << std::endl;
  } else {
    VTR_ASSERT_SAFE(false == unused_block);
    fp << "# Disable Timing for unused resources in grid[" << grid_coordinate.x() << "][" << grid_coordinate.y() << "][" << grid_z << "]" << std::endl;
  }
  fp << "#######################################" << std::endl; 
  std::string hierarchy_name = grid_instance_name + std::string("/") + pb_instance_name + std::string("/");
  if (true == unused_block) {
    rec_print_analysis_sdc_disable_unused_pb_graph_nodes(fp, device_annotation,
                                                         module_manager, pb_module, hierarchy_name,
                                                         pb_graph_head); 
  } else { 
    VTR_ASSERT_SAFE(false == unused_block);
    rec_print_analysis_sdc_disable_pb_graph_node_unused_resources(fp, device_annotation,
                                                                  module_manager, pb_module, hierarchy_name,
                                                                  pb_graph_head, physical_pb); 
  }
}
static void print_analysis_sdc_disable_pb_block_unused_resources ( std :: fstream & fp , t_physical_tile_type_ptr grid_type , const vtr :: Point < size_t > & grid_coordinate , const VprDeviceAnnotation & device_annotation , const ModuleManager & module_manager , const std :: string & grid_instance_name , const size_t & grid_z , const PhysicalPb & physical_pb , const bool & unused_block ) { if ( false == unused_block ) { VTR_ASSERT ( false == physical_pb . empty ( ) ) ; } VTR_ASSERT ( 1 == grid_type -> equivalent_sites . size ( ) ) ; t_pb_graph_node * pb_graph_head = grid_type -> equivalent_sites [ 0 ] -> pb_graph_head ; VTR_ASSERT ( nullptr != pb_graph_head ) ; std :: string pb_module_name = generate_physical_block_module_name ( pb_graph_head -> pb_type ) ; std :: string pb_instance_name = generate_physical_block_instance_name ( pb_graph_head -> pb_type , grid_z ) ; ModuleId pb_module = module_manager . find_module ( pb_module_name ) ; VTR_ASSERT ( true == module_manager . valid_module_id ( pb_module ) ) ; fp << " " << std :: endl ; if ( true == unused_block ) { fp << " " << grid_coordinate . x ( ) << " " << grid_coordinate . y ( ) << " " << grid_z << " " << std :: endl ; } else { VTR_ASSERT_SAFE ( false == unused_block ) ; fp << " " << grid_coordinate . x ( ) << " " << grid_coordinate . y ( ) << " " << grid_z << " " << std :: endl ; } fp << " " << std :: endl ; std :: string hierarchy_name = grid_instance_name + std :: string ( " " ) + pb_instance_name + std :: string ( " " ) ; if ( true == unused_block ) { rec_print_analysis_sdc_disable_unused_pb_graph_nodes ( fp , device_annotation , module_manager , pb_module , hierarchy_name , pb_graph_head ) ; } else { VTR_ASSERT_SAFE ( false == unused_block ) ; rec_print_analysis_sdc_disable_pb_graph_node_unused_resources ( fp , device_annotation , module_manager , pb_module , hierarchy_name , pb_graph_head , physical_pb ) ; } }
This function can work in two differnt modes:
 1.
This function can work in two differnt modes : 1 .
/* If the block is partially unused, we should have a physical pb */ /* Find an unique name to the pb instance in this grid
   * Note: this must be consistent with the instance name we used in build_grid_module()!!!
   */ /* TODO: validate that the instance name is used in module manager!!! */ /* Print comments */ /* Go recursively through the pb_graph hierarchy, and disable all the ports level by level */