openfpga/src/fabric/build_fabric_io_location_map.cpp
/********************************************************************
 * Find all the GPIO ports in the grid module
 * and cache their port/pin index in the top-level module
 *******************************************************************/
Find all the GPIO ports in the grid module
and cache their port/pin index in the top-level module
Find all the GPIO ports in the grid module and cache their port / pin index in the top - level module
IoLocationMap build_fabric_io_location_map(const ModuleManager& module_manager,
                                           const DeviceGrid& grids) {
  vtr::ScopedStartFinishTimer timer("Create I/O location mapping for top module");
  IoLocationMap io_location_map;
  std::map<std::string, size_t> io_counter;
  std::map<e_side, std::vector<vtr::Point<size_t>>> io_coordinates = generate_perimeter_grid_coordinates( grids);
  for (const e_side& io_side : FPGA_SIDES_CLOCKWISE) {
    for (const vtr::Point<size_t>& io_coordinate : io_coordinates[io_side]) {
      if (true == is_empty_type(grids[io_coordinate.x()][io_coordinate.y()].type)) {
        continue;
      } 
      if ( (0 < grids[io_coordinate.x()][io_coordinate.y()].width_offset)
        || (0 < grids[io_coordinate.x()][io_coordinate.y()].height_offset)) {
        continue;
      }
      t_physical_tile_type_ptr grid_type = grids[io_coordinate.x()][io_coordinate.y()].type;
      std::string grid_module_name_prefix(GRID_MODULE_NAME_PREFIX);
      std::string grid_module_name = generate_grid_block_module_name(grid_module_name_prefix, std::string(grid_type->name), is_io_type(grid_type), io_side);
      ModuleId grid_module = module_manager.find_module(grid_module_name);
      VTR_ASSERT(true == module_manager.valid_module_id(grid_module));
      for (int z = 0; z < grids[io_coordinate.x()][io_coordinate.y()].type->capacity; ++z) {
        for (const ModuleManager::e_module_port_type& module_io_port_type : MODULE_IO_PORT_TYPES) {
          for (const ModulePortId& gpio_port_id : module_manager.module_port_ids_by_type(grid_module, module_io_port_type)) {
            if (false == module_manager.port_is_mappable_io(grid_module, gpio_port_id)) {
              continue;
            }
            const BasicPort& gpio_port = module_manager.module_port(grid_module, gpio_port_id);
            auto curr_io_index = io_counter.find(gpio_port.get_name());
            if (curr_io_index == io_counter.end()) {
              io_counter[gpio_port.get_name()] = 0;
            }
            io_location_map.set_io_index(io_coordinate.x(), io_coordinate.y(), z,
                                         gpio_port.get_name(),
                                         io_counter[gpio_port.get_name()]);
            io_counter[gpio_port.get_name()]++;
          }
        }
      }
    }
  }
  for (size_t ix = 1; ix < grids.width() - 1; ++ix) {
    for (size_t iy = 1; iy < grids.height() - 1; ++iy) {
      if (true == is_empty_type(grids[ix][iy].type)) {
        continue;
      } 
      if ( (0 < grids[ix][iy].width_offset)
        || (0 < grids[ix][iy].height_offset)) {
        continue;
      }
      t_physical_tile_type_ptr grid_type = grids[ix][iy].type;
      std::string grid_module_name_prefix(GRID_MODULE_NAME_PREFIX);
      std::string grid_module_name = generate_grid_block_module_name(grid_module_name_prefix, std::string(grid_type->name), is_io_type(grid_type), NUM_SIDES);
      ModuleId grid_module = module_manager.find_module(grid_module_name);
      VTR_ASSERT(true == module_manager.valid_module_id(grid_module));
      for (int z = 0; z < grids[ix][iy].type->capacity; ++z) {
        for (const ModuleManager::e_module_port_type& module_io_port_type : MODULE_IO_PORT_TYPES) {
          for (const ModulePortId& gpio_port_id : module_manager.module_port_ids_by_type(grid_module, module_io_port_type)) {
            if (false == module_manager.port_is_mappable_io(grid_module, gpio_port_id)) {
              continue;
            }
            const BasicPort& gpio_port = module_manager.module_port(grid_module, gpio_port_id);
            auto curr_io_index = io_counter.find(gpio_port.get_name());
            if (curr_io_index == io_counter.end()) {
              io_counter[gpio_port.get_name()] = 0;
            }
            io_location_map.set_io_index(ix, iy, z,
                                         gpio_port.get_name(),
                                         io_counter[gpio_port.get_name()]);
            io_counter[gpio_port.get_name()]++;
          }
        }
      }
    }
  }
  std::string top_module_name = generate_fpga_top_module_name();
  ModuleId top_module = module_manager.find_module(top_module_name);
  VTR_ASSERT(true == module_manager.valid_module_id(top_module));
  for (const ModuleManager::e_module_port_type& module_io_port_type : MODULE_IO_PORT_TYPES) {
    for (const ModulePortId& gpio_port_id : module_manager.module_port_ids_by_type(top_module, module_io_port_type)) {
      if (false == module_manager.port_is_mappable_io(top_module, gpio_port_id)) {
        continue;
      }
      const BasicPort& gpio_port = module_manager.module_port(top_module, gpio_port_id);
      VTR_ASSERT(io_counter[gpio_port.get_name()] == gpio_port.get_width());
    }
  }
  return io_location_map;
}
IoLocationMap build_fabric_io_location_map ( const ModuleManager & module_manager , const DeviceGrid & grids ) { vtr :: ScopedStartFinishTimer timer ( " " ) ; IoLocationMap io_location_map ; std :: map < std :: string , size_t > io_counter ; std :: map < e_side , std :: vector < vtr :: Point < size_t > > > io_coordinates = generate_perimeter_grid_coordinates ( grids ) ; for ( const e_side & io_side : FPGA_SIDES_CLOCKWISE ) { for ( const vtr :: Point < size_t > & io_coordinate : io_coordinates [ io_side ] ) { if ( true == is_empty_type ( grids [ io_coordinate . x ( ) ] [ io_coordinate . y ( ) ] . type ) ) { continue ; } if ( ( 0 < grids [ io_coordinate . x ( ) ] [ io_coordinate . y ( ) ] . width_offset ) || ( 0 < grids [ io_coordinate . x ( ) ] [ io_coordinate . y ( ) ] . height_offset ) ) { continue ; } t_physical_tile_type_ptr grid_type = grids [ io_coordinate . x ( ) ] [ io_coordinate . y ( ) ] . type ; std :: string grid_module_name_prefix ( GRID_MODULE_NAME_PREFIX ) ; std :: string grid_module_name = generate_grid_block_module_name ( grid_module_name_prefix , std :: string ( grid_type -> name ) , is_io_type ( grid_type ) , io_side ) ; ModuleId grid_module = module_manager . find_module ( grid_module_name ) ; VTR_ASSERT ( true == module_manager . valid_module_id ( grid_module ) ) ; for ( int z = 0 ; z < grids [ io_coordinate . x ( ) ] [ io_coordinate . y ( ) ] . type -> capacity ; ++ z ) { for ( const ModuleManager :: e_module_port_type & module_io_port_type : MODULE_IO_PORT_TYPES ) { for ( const ModulePortId & gpio_port_id : module_manager . module_port_ids_by_type ( grid_module , module_io_port_type ) ) { if ( false == module_manager . port_is_mappable_io ( grid_module , gpio_port_id ) ) { continue ; } const BasicPort & gpio_port = module_manager . module_port ( grid_module , gpio_port_id ) ; auto curr_io_index = io_counter . find ( gpio_port . get_name ( ) ) ; if ( curr_io_index == io_counter . end ( ) ) { io_counter [ gpio_port . get_name ( ) ] = 0 ; } io_location_map . set_io_index ( io_coordinate . x ( ) , io_coordinate . y ( ) , z , gpio_port . get_name ( ) , io_counter [ gpio_port . get_name ( ) ] ) ; io_counter [ gpio_port . get_name ( ) ] ++ ; } } } } } for ( size_t ix = 1 ; ix < grids . width ( ) - 1 ; ++ ix ) { for ( size_t iy = 1 ; iy < grids . height ( ) - 1 ; ++ iy ) { if ( true == is_empty_type ( grids [ ix ] [ iy ] . type ) ) { continue ; } if ( ( 0 < grids [ ix ] [ iy ] . width_offset ) || ( 0 < grids [ ix ] [ iy ] . height_offset ) ) { continue ; } t_physical_tile_type_ptr grid_type = grids [ ix ] [ iy ] . type ; std :: string grid_module_name_prefix ( GRID_MODULE_NAME_PREFIX ) ; std :: string grid_module_name = generate_grid_block_module_name ( grid_module_name_prefix , std :: string ( grid_type -> name ) , is_io_type ( grid_type ) , NUM_SIDES ) ; ModuleId grid_module = module_manager . find_module ( grid_module_name ) ; VTR_ASSERT ( true == module_manager . valid_module_id ( grid_module ) ) ; for ( int z = 0 ; z < grids [ ix ] [ iy ] . type -> capacity ; ++ z ) { for ( const ModuleManager :: e_module_port_type & module_io_port_type : MODULE_IO_PORT_TYPES ) { for ( const ModulePortId & gpio_port_id : module_manager . module_port_ids_by_type ( grid_module , module_io_port_type ) ) { if ( false == module_manager . port_is_mappable_io ( grid_module , gpio_port_id ) ) { continue ; } const BasicPort & gpio_port = module_manager . module_port ( grid_module , gpio_port_id ) ; auto curr_io_index = io_counter . find ( gpio_port . get_name ( ) ) ; if ( curr_io_index == io_counter . end ( ) ) { io_counter [ gpio_port . get_name ( ) ] = 0 ; } io_location_map . set_io_index ( ix , iy , z , gpio_port . get_name ( ) , io_counter [ gpio_port . get_name ( ) ] ) ; io_counter [ gpio_port . get_name ( ) ] ++ ; } } } } } std :: string top_module_name = generate_fpga_top_module_name ( ) ; ModuleId top_module = module_manager . find_module ( top_module_name ) ; VTR_ASSERT ( true == module_manager . valid_module_id ( top_module ) ) ; for ( const ModuleManager :: e_module_port_type & module_io_port_type : MODULE_IO_PORT_TYPES ) { for ( const ModulePortId & gpio_port_id : module_manager . module_port_ids_by_type ( top_module , module_io_port_type ) ) { if ( false == module_manager . port_is_mappable_io ( top_module , gpio_port_id ) ) { continue ; } const BasicPort & gpio_port = module_manager . module_port ( top_module , gpio_port_id ) ; VTR_ASSERT ( io_counter [ gpio_port . get_name ( ) ] == gpio_port . get_width ( ) ) ; } } return io_location_map ; }
Find all the GPIO ports in the grid module
 and cache their port/pin index in the top-level module
Find all the GPIO ports in the grid module and cache their port / pin index in the top - level module
/* Create the coordinate range for each side of FPGA fabric */ /* Walk through all the grids on the perimeter, which are I/O grids */ /* Bypass EMPTY grid */ /* Skip width or height > 1 tiles (mostly heterogeneous blocks) */ /* Find the module name for this type of grid */ /* Find all the GPIO ports in the grid module */ /* MUST DO: register in io location mapping!
       * I/O location mapping is a critical look-up for testbench generators
       * As we add the I/O grid instances to top module by following order:
       * TOP -> RIGHT -> BOTTOM -> LEFT
       * The I/O index will increase in this way as well.
       * This organization I/O indices is also consistent to the way 
       * that GPIOs are wired in function connect_gpio_module()
       *
       * Note: if you change the GPIO function, you should update here as well!
       */ /* Only care mappable I/O */ /* Index always start from zero */ /* Walk through all the center grids, which may include I/O grids */ /* Bypass EMPTY grid */ /* Skip width or height > 1 tiles (mostly heterogeneous blocks) */ /* Find the module name for this type of grid */ /* Find all the GPIO ports in the grid module */ /* MUST DO: register in io location mapping!
       * I/O location mapping is a critical look-up for testbench generators
       * As we add the I/O grid instances to top module by following order:
       * TOP -> RIGHT -> BOTTOM -> LEFT
       * The I/O index will increase in this way as well.
       * This organization I/O indices is also consistent to the way 
       * that GPIOs are wired in function connect_gpio_module()
       *
       * Note: if you change the GPIO function, you should update here as well!
       */ /* Only care mappable I/O */ /* Index always start from zero */ /* Check all the GPIO ports in the top-level module has been mapped */ /* Only care mappable I/O */