openfpga/src/fpga_sdc/sdc_hierarchy_writer.cpp
/***************************************************************************************
 * Write the hierarchy of grid module and its instances to a plain text file
 * e.g.,
 *    <sdc_file_for_the_module>
 *      <module_name>/<instance_name>
 *        ...
 * This file is mainly used by hierarchical P&R flow 
 *
 * Return 0 if successful
 * Return 1 if there are more serious bugs in the architecture 
 * Return 2 if fail when creating files
 ***************************************************************************************/
Write the hierarchy of grid module and its instances to a plain text file
e.g.,

/

This file is mainly used by hierarchical P&R flow

Return 0 if successful
Return 1 if there are more serious bugs in the architecture
Return 2 if fail when creating files
Write the hierarchy of grid module and its instances to a plain text file e . g . / This file is mainly used by hierarchical P&R flow Return 0 if successful Return 1 if there are more serious bugs in the architecture Return 2 if fail when creating files
void print_pnr_sdc_grid_hierarchy(const std::string& sdc_dir,
                                  const DeviceContext& device_ctx,
                                  const VprDeviceAnnotation& device_annotation,
                                  const ModuleManager& module_manager,
                                  const ModuleId& top_module) {
  std::string fname(sdc_dir + std::string(SDC_GRID_HIERARCHY_FILE_NAME));
  std::string timer_message = std::string("Write Grid hierarchy to plain-text file '") + fname + std::string("'");
  std::string dir_path = format_dir_path(find_path_dir_name(fname));
  create_directory(dir_path);
  vtr::ScopedStartFinishTimer timer(timer_message);
  VTR_ASSERT(true != fname.empty());
  std::fstream fp;
  fp.open(fname, std::fstream::out | std::fstream::trunc);
  check_file_stream(fname.c_str(), fp);
  std::string root_path = format_dir_path(module_manager.module_name(top_module));
  for (const t_physical_tile_type& physical_tile : device_ctx.physical_tile_types) {
    if (true == is_empty_type(&physical_tile)) {
      continue;
    }
    VTR_ASSERT(1 == physical_tile.equivalent_sites.size());
    t_pb_graph_node* pb_graph_head = physical_tile.equivalent_sites[0]->pb_graph_head;
    if (nullptr == pb_graph_head) {
      continue;
    }
    if (true == is_io_type(&physical_tile)) {
      std::set<e_side> io_type_sides = find_physical_io_tile_located_sides(device_ctx.grid,
                                                                           &physical_tile);
      for (const e_side& io_type_side : io_type_sides) {
        std::string grid_module_name = generate_grid_block_module_name(std::string(GRID_MODULE_NAME_PREFIX), 
                                                                       std::string(physical_tile.name),
                                                                       is_io_type(&physical_tile),
                                                                       io_type_side);
        ModuleId grid_module = module_manager.find_module(grid_module_name);
        VTR_ASSERT(true == module_manager.valid_module_id(grid_module));
        fp << "- " << grid_module_name << ":" << "\n";
        for (const size_t& instance_id : module_manager.child_module_instances(top_module, grid_module)) {
          std::string grid_instance_name = module_manager.instance_name(top_module, grid_module, instance_id);
          fp << "  ";
          fp << "- " << grid_instance_name << ":" << "\n";  
          rec_print_pnr_sdc_grid_pb_graph_hierarchy(fp,
                                                    2,
                                                    module_manager, 
                                                    grid_module, 
                                                    device_annotation,
                                                    pb_graph_head);
        } 
        fp << "\n";
      }
    } else {
      std::string grid_module_name = generate_grid_block_module_name(std::string(GRID_MODULE_NAME_PREFIX), 
                                                                     std::string(physical_tile.name),
                                                                     is_io_type(&physical_tile),
                                                                     NUM_SIDES);
      ModuleId grid_module = module_manager.find_module(grid_module_name);
      VTR_ASSERT(true == module_manager.valid_module_id(grid_module));
      fp << "- " << grid_module_name << ":" << "\n";
      for (const size_t& instance_id : module_manager.child_module_instances(top_module, grid_module)) {
        std::string grid_instance_name = module_manager.instance_name(top_module, grid_module, instance_id);
        fp << "  ";
        fp << "- " << grid_instance_name << ":" << "\n";  
        rec_print_pnr_sdc_grid_pb_graph_hierarchy(fp,
                                                  2,
                                                  module_manager, 
                                                  grid_module, 
                                                  device_annotation,
                                                  pb_graph_head);
      } 
      fp << "\n";
    }
  }
  fp.close();
}
void print_pnr_sdc_grid_hierarchy ( const std :: string & sdc_dir , const DeviceContext & device_ctx , const VprDeviceAnnotation & device_annotation , const ModuleManager & module_manager , const ModuleId & top_module ) { std :: string fname ( sdc_dir + std :: string ( SDC_GRID_HIERARCHY_FILE_NAME ) ) ; std :: string timer_message = std :: string ( " " ) + fname + std :: string ( " " ) ; std :: string dir_path = format_dir_path ( find_path_dir_name ( fname ) ) ; create_directory ( dir_path ) ; vtr :: ScopedStartFinishTimer timer ( timer_message ) ; VTR_ASSERT ( true != fname . empty ( ) ) ; std :: fstream fp ; fp . open ( fname , std :: fstream :: out | std :: fstream :: trunc ) ; check_file_stream ( fname . c_str ( ) , fp ) ; std :: string root_path = format_dir_path ( module_manager . module_name ( top_module ) ) ; for ( const t_physical_tile_type & physical_tile : device_ctx . physical_tile_types ) { if ( true == is_empty_type ( & physical_tile ) ) { continue ; } VTR_ASSERT ( 1 == physical_tile . equivalent_sites . size ( ) ) ; t_pb_graph_node * pb_graph_head = physical_tile . equivalent_sites [ 0 ] -> pb_graph_head ; if ( nullptr == pb_graph_head ) { continue ; } if ( true == is_io_type ( & physical_tile ) ) { std :: set < e_side > io_type_sides = find_physical_io_tile_located_sides ( device_ctx . grid , & physical_tile ) ; for ( const e_side & io_type_side : io_type_sides ) { std :: string grid_module_name = generate_grid_block_module_name ( std :: string ( GRID_MODULE_NAME_PREFIX ) , std :: string ( physical_tile . name ) , is_io_type ( & physical_tile ) , io_type_side ) ; ModuleId grid_module = module_manager . find_module ( grid_module_name ) ; VTR_ASSERT ( true == module_manager . valid_module_id ( grid_module ) ) ; fp << " " << grid_module_name << " " << " \n " ; for ( const size_t & instance_id : module_manager . child_module_instances ( top_module , grid_module ) ) { std :: string grid_instance_name = module_manager . instance_name ( top_module , grid_module , instance_id ) ; fp << " " ; fp << " " << grid_instance_name << " " << " \n " ; rec_print_pnr_sdc_grid_pb_graph_hierarchy ( fp , 2 , module_manager , grid_module , device_annotation , pb_graph_head ) ; } fp << " \n " ; } } else { std :: string grid_module_name = generate_grid_block_module_name ( std :: string ( GRID_MODULE_NAME_PREFIX ) , std :: string ( physical_tile . name ) , is_io_type ( & physical_tile ) , NUM_SIDES ) ; ModuleId grid_module = module_manager . find_module ( grid_module_name ) ; VTR_ASSERT ( true == module_manager . valid_module_id ( grid_module ) ) ; fp << " " << grid_module_name << " " << " \n " ; for ( const size_t & instance_id : module_manager . child_module_instances ( top_module , grid_module ) ) { std :: string grid_instance_name = module_manager . instance_name ( top_module , grid_module , instance_id ) ; fp << " " ; fp << " " << grid_instance_name << " " << " \n " ; rec_print_pnr_sdc_grid_pb_graph_hierarchy ( fp , 2 , module_manager , grid_module , device_annotation , pb_graph_head ) ; } fp << " \n " ; } } fp . close ( ) ; }
Write the hierarchy of grid module and its instances to a plain text file
 e.g.,
    <sdc_file_for_the_module>
      <module_name>/<instance_name>
        ...
Write the hierarchy of grid module and its instances to a plain text file e . g . <sdc_file_for_the_module > <module_name > / <instance_name > ...
/* Create directories */ /* Start time count */ /* Use default name if user does not provide one */ /* Create a file handler*/ /* Open a file */ /* Validate the file stream */ /* Bypass empty type or nullptr */ /* Special for I/O block:
       * We will search the grids and see where the I/O blocks are located:
       * - If a I/O block locates on border sides of FPGA fabric:
       *   i.e., one or more from {TOP, RIGHT, BOTTOM, LEFT},
       *   we will generate one module for each border side 
       * - If a I/O block locates in the center of FPGA fabric:
       *   we will generate one module with NUM_SIDES (same treatment as regular grids) 
       */ /* Generate the grid module name */ /* Find the module Id */ /* Go through all the instance */ /* For CLB and heterogenenous blocks */ /* Find the module Id */ /* Go through all the instance */ /* close a file */