openfpga/src/tile_direct/build_tile_direct.cpp
/***************************************************************************************
 * Build the point-to-point direct connections based on 
 *   - original VPR arch definition 
 *     This is limited to the inner-column and inner-row connections
 * Note that the direct connections are not limited to CLBs only.
 * It can be more generic and thus cover all the grid types,
 * such as heterogeneous blocks
 *
 * This function supports the following type of direct connection:
 * 1. Direct connection between tiles in the same column or row
 *     +------+      +------+
 *     |      |      |      |
 *     | Tile |----->| Tile |
 *     |      |      |      |
 *     +------+      +------+
 *         | direction connection 
 *         v
 *     +------+
 *     |      |
 *     | Tile |
 *     |      |
 *     +------+
 *
 ***************************************************************************************/


This function supports the following type of direct connection:
1.
This function supports the following type of direct connection : 1 .
static 
void build_inner_column_row_tile_direct(TileDirect& tile_direct,
                                        const t_direct_inf& vpr_direct,
                                        const DeviceContext& device_ctx,
                                        const ArchDirectId& arch_direct_id,
                                        const bool& verbose) {
  std::string from_tile_name = parse_direct_tile_name(std::string(vpr_direct.from_pin));
  PortParser from_tile_port_parser(parse_direct_port(std::string(vpr_direct.from_pin)));
  const BasicPort& from_tile_port = from_tile_port_parser.port();
  std::string to_tile_name = parse_direct_tile_name(std::string(vpr_direct.to_pin));
  PortParser to_tile_port_parser(parse_direct_port(std::string(vpr_direct.to_pin)));
  const BasicPort& to_tile_port = to_tile_port_parser.port();
  for (size_t x = 0; x < device_ctx.grid.width(); ++x) {
    for (size_t y = 0; y < device_ctx.grid.height(); ++y) {
      if (true == is_empty_type(device_ctx.grid[x][y].type)) {
        continue;
      }
      if (from_tile_name != std::string(device_ctx.grid[x][y].type->name)) {
        continue;
      }
      for (const e_side& from_side : {TOP, RIGHT, BOTTOM, LEFT}) {
        std::vector<size_t> from_pins = find_physical_tile_pin_id(device_ctx.grid[x][y].type,
                                                                  device_ctx.grid[x][y].width_offset,
                                                                  device_ctx.grid[x][y].height_offset,
                                                                  from_tile_port,
                                                                  from_side);
        if (0 == from_pins.size()) {
          continue;
        }
        vtr::Point<size_t> from_grid_coord(x, y);
        vtr::Point<size_t> to_grid_coord(x + vpr_direct.x_offset, y + vpr_direct.y_offset);
        if (false == is_grid_coordinate_exist_in_device(device_ctx.grid, to_grid_coord)) {
          continue;
        }
        if (to_tile_name != std::string(device_ctx.grid[to_grid_coord.x()][to_grid_coord.y()].type->name)) {
          continue;
        }
        for (const e_side& to_side : {TOP, RIGHT, BOTTOM, LEFT}) {
          std::vector<size_t> to_pins = find_physical_tile_pin_id(device_ctx.grid[to_grid_coord.x()][to_grid_coord.y()].type,
                                                                  device_ctx.grid[to_grid_coord.x()][to_grid_coord.y()].width_offset,
                                                                  device_ctx.grid[to_grid_coord.x()][to_grid_coord.y()].height_offset,
                                                                  to_tile_port,
                                                                  to_side);
          if (0 == to_pins.size()) {
            continue;
          }
          if (from_pins.size() != to_pins.size()) {
            report_direct_from_port_and_to_port_mismatch(vpr_direct, from_tile_port, to_tile_port);
            exit(1);
          }
          for (size_t ipin = 0; ipin < from_pins.size(); ++ipin) {
            VTR_LOGV(verbose,
                     "Built a inner-column/row tile-to-tile direct from %s[%lu][%lu].%s[%lu] at side '%s' to %s[%lu][%lu].%s[%lu] at side '%s'\n",
                     from_tile_name.c_str(), x, y,
                     from_tile_port.get_name().c_str(), from_pins[ipin],
                     SIDE_STRING[from_side],
                     to_tile_name.c_str(),
                     to_grid_coord.x(), to_grid_coord.y(),
                     to_tile_port.get_name().c_str(), to_pins[ipin],
                     SIDE_STRING[to_side]
                     );
            TileDirectId tile_direct_id = tile_direct.add_direct(from_grid_coord,
                                                                 from_side,
                                                                 from_pins[ipin],
                                                                 to_grid_coord,
                                                                 to_side,
                                                                 to_pins[ipin]);
            tile_direct.set_arch_direct_id(tile_direct_id, arch_direct_id);
          }
        }
      }
    }
  }
}
static void build_inner_column_row_tile_direct ( TileDirect & tile_direct , const t_direct_inf & vpr_direct , const DeviceContext & device_ctx , const ArchDirectId & arch_direct_id , const bool & verbose ) { std :: string from_tile_name = parse_direct_tile_name ( std :: string ( vpr_direct . from_pin ) ) ; PortParser from_tile_port_parser ( parse_direct_port ( std :: string ( vpr_direct . from_pin ) ) ) ; const BasicPort & from_tile_port = from_tile_port_parser . port ( ) ; std :: string to_tile_name = parse_direct_tile_name ( std :: string ( vpr_direct . to_pin ) ) ; PortParser to_tile_port_parser ( parse_direct_port ( std :: string ( vpr_direct . to_pin ) ) ) ; const BasicPort & to_tile_port = to_tile_port_parser . port ( ) ; for ( size_t x = 0 ; x < device_ctx . grid . width ( ) ; ++ x ) { for ( size_t y = 0 ; y < device_ctx . grid . height ( ) ; ++ y ) { if ( true == is_empty_type ( device_ctx . grid [ x ] [ y ] . type ) ) { continue ; } if ( from_tile_name != std :: string ( device_ctx . grid [ x ] [ y ] . type -> name ) ) { continue ; } for ( const e_side & from_side : { TOP , RIGHT , BOTTOM , LEFT } ) { std :: vector < size_t > from_pins = find_physical_tile_pin_id ( device_ctx . grid [ x ] [ y ] . type , device_ctx . grid [ x ] [ y ] . width_offset , device_ctx . grid [ x ] [ y ] . height_offset , from_tile_port , from_side ) ; if ( 0 == from_pins . size ( ) ) { continue ; } vtr :: Point < size_t > from_grid_coord ( x , y ) ; vtr :: Point < size_t > to_grid_coord ( x + vpr_direct . x_offset , y + vpr_direct . y_offset ) ; if ( false == is_grid_coordinate_exist_in_device ( device_ctx . grid , to_grid_coord ) ) { continue ; } if ( to_tile_name != std :: string ( device_ctx . grid [ to_grid_coord . x ( ) ] [ to_grid_coord . y ( ) ] . type -> name ) ) { continue ; } for ( const e_side & to_side : { TOP , RIGHT , BOTTOM , LEFT } ) { std :: vector < size_t > to_pins = find_physical_tile_pin_id ( device_ctx . grid [ to_grid_coord . x ( ) ] [ to_grid_coord . y ( ) ] . type , device_ctx . grid [ to_grid_coord . x ( ) ] [ to_grid_coord . y ( ) ] . width_offset , device_ctx . grid [ to_grid_coord . x ( ) ] [ to_grid_coord . y ( ) ] . height_offset , to_tile_port , to_side ) ; if ( 0 == to_pins . size ( ) ) { continue ; } if ( from_pins . size ( ) != to_pins . size ( ) ) { report_direct_from_port_and_to_port_mismatch ( vpr_direct , from_tile_port , to_tile_port ) ; exit ( 1 ) ; } for ( size_t ipin = 0 ; ipin < from_pins . size ( ) ; ++ ipin ) { VTR_LOGV ( verbose , " \n " , from_tile_name . c_str ( ) , x , y , from_tile_port . get_name ( ) . c_str ( ) , from_pins [ ipin ] , SIDE_STRING [ from_side ] , to_tile_name . c_str ( ) , to_grid_coord . x ( ) , to_grid_coord . y ( ) , to_tile_port . get_name ( ) . c_str ( ) , to_pins [ ipin ] , SIDE_STRING [ to_side ] ) ; TileDirectId tile_direct_id = tile_direct . add_direct ( from_grid_coord , from_side , from_pins [ ipin ] , to_grid_coord , to_side , to_pins [ ipin ] ) ; tile_direct . set_arch_direct_id ( tile_direct_id , arch_direct_id ) ; } } } } } }
Build the point-to-point direct connections based on
   - original VPR arch definition
     This is limited to the inner-column and inner-row connections
 Note that the direct connections are not limited to CLBs only.
Build the point - to - point direct connections based on - original VPR arch definition This is limited to the inner - column and inner - row connections Note that the direct connections are not limited to CLBs only .
/* Get the source tile and pin information */ /* Get the sink tile and pin information */ /* Walk through the device fabric and find the grid that fit the source */ /* Bypass empty grid */ /* Bypass the grid that does not fit the from_tile name */ /* Search all the sides, the from pin may locate any side!
       * Note: the vpr_direct.from_side is NUM_SIDES, which is unintialized
       * This should be reported to VPR!!!
       */ /* Try to find the pin in this tile */ /* If nothing found, we can continue */ /* We should try to the sink grid for inner-column/row direct connections */ /* Bypass the grid that does not fit the from_tile name */ /* Search all the sides, the to pin may locate any side!
         * Note: the vpr_direct.to_side is NUM_SIDES, which is unintialized
         * This should be reported to VPR!!!
         */ /* Try to find the pin in this tile */ /* If nothing found, we can continue */ /* If from port and to port do not match in sizes, error out */ /* Now add the tile direct */