vpr/src/place/initial_placement.cpp
/* Place blocks that are NOT a part of any macro.
 * We'll randomly place each block in the clustered netlist, one by one. */
Place blocks that are NOT a part of any macro.
We'll randomly place each block in the clustered netlist, one by one.
Place blocks that are NOT a part of any macro . We ' ll randomly place each block in the clustered netlist one by one .
static void initial_placement_blocks(int* free_locations, enum e_pad_loc_type pad_loc_type) {
    int itype, ipos;
    auto& cluster_ctx = g_vpr_ctx.clustering();
    auto& device_ctx = g_vpr_ctx.device();
    auto& place_ctx = g_vpr_ctx.mutable_placement();
    auto blocks = cluster_ctx.clb_nlist.blocks();
    std::vector<ClusterBlockId> sorted_blocks(blocks.begin(), blocks.end());
    auto criteria = [&cluster_ctx](const ClusterBlockId lhs, ClusterBlockId rhs) {
        auto lhs_logical_block = cluster_ctx.clb_nlist.block_type(lhs);
        auto rhs_logical_block = cluster_ctx.clb_nlist.block_type(rhs);
        auto lhs_num_tiles = lhs_logical_block->equivalent_tiles.size();
        auto rhs_num_tiles = rhs_logical_block->equivalent_tiles.size();
        return lhs_num_tiles < rhs_num_tiles;
    };
    if (device_ctx.has_multiple_equivalent_tiles) {
        std::sort(sorted_blocks.begin(), sorted_blocks.end(), criteria);
    }
    for (auto blk_id : sorted_blocks) {
        if (place_ctx.block_locs[blk_id].loc.x != -1) { 
            continue;
        }
        auto logical_block = cluster_ctx.clb_nlist.block_type(blk_id);
        if (!(is_io_type(pick_best_physical_type(logical_block)) && pad_loc_type == USER)) {
            auto type = pick_placement_type(logical_block, 1, free_locations);
            if (type == nullptr) {
                VPR_FATAL_ERROR(VPR_ERROR_PLACE,
                                "Initial placement failed.\n"
                                "Could not place block %s (#%zu); no free locations of type %s (#%d).\n",
                                cluster_ctx.clb_nlist.block_name(blk_id).c_str(), size_t(blk_id), logical_block->name, logical_block->index);
            }
            itype = type->index;
            t_pl_loc to;
            initial_placement_location(free_locations, ipos, itype, to);
            VTR_ASSERT(place_ctx.grid_blocks[to.x][to.y].blocks[to.z] == EMPTY_BLOCK_ID);
            place_ctx.grid_blocks[to.x][to.y].blocks[to.z] = blk_id;
            place_ctx.grid_blocks[to.x][to.y].usage++;
            place_ctx.block_locs[blk_id].loc = to;
            if (is_io_type(pick_best_physical_type(logical_block)) && pad_loc_type == RANDOM) {
                place_ctx.block_locs[blk_id].is_fixed = true;
            }
            legal_pos[itype][ipos] = legal_pos[itype][free_locations[itype] - 1]; 
            free_locations[itype]--;
        }
    }
}
static void initial_placement_blocks ( int * free_locations , enum e_pad_loc_type pad_loc_type ) { int itype , ipos ; auto & cluster_ctx = g_vpr_ctx . clustering ( ) ; auto & device_ctx = g_vpr_ctx . device ( ) ; auto & place_ctx = g_vpr_ctx . mutable_placement ( ) ; auto blocks = cluster_ctx . clb_nlist . blocks ( ) ; std :: vector < ClusterBlockId > sorted_blocks ( blocks . begin ( ) , blocks . end ( ) ) ; auto criteria = [ & cluster_ctx ] ( const ClusterBlockId lhs , ClusterBlockId rhs ) { auto lhs_logical_block = cluster_ctx . clb_nlist . block_type ( lhs ) ; auto rhs_logical_block = cluster_ctx . clb_nlist . block_type ( rhs ) ; auto lhs_num_tiles = lhs_logical_block -> equivalent_tiles . size ( ) ; auto rhs_num_tiles = rhs_logical_block -> equivalent_tiles . size ( ) ; return lhs_num_tiles < rhs_num_tiles ; } ; if ( device_ctx . has_multiple_equivalent_tiles ) { std :: sort ( sorted_blocks . begin ( ) , sorted_blocks . end ( ) , criteria ) ; } for ( auto blk_id : sorted_blocks ) { if ( place_ctx . block_locs [ blk_id ] . loc . x != -1 ) { continue ; } auto logical_block = cluster_ctx . clb_nlist . block_type ( blk_id ) ; if ( ! ( is_io_type ( pick_best_physical_type ( logical_block ) ) && pad_loc_type == USER ) ) { auto type = pick_placement_type ( logical_block , 1 , free_locations ) ; if ( type == nullptr ) { VPR_FATAL_ERROR ( VPR_ERROR_PLACE , " \n " " \n " , cluster_ctx . clb_nlist . block_name ( blk_id ) . c_str ( ) , size_t ( blk_id ) , logical_block -> name , logical_block -> index ) ; } itype = type -> index ; t_pl_loc to ; initial_placement_location ( free_locations , ipos , itype , to ) ; VTR_ASSERT ( place_ctx . grid_blocks [ to . x ] [ to . y ] . blocks [ to . z ] == EMPTY_BLOCK_ID ) ; place_ctx . grid_blocks [ to . x ] [ to . y ] . blocks [ to . z ] = blk_id ; place_ctx . grid_blocks [ to . x ] [ to . y ] . usage ++ ; place_ctx . block_locs [ blk_id ] . loc = to ; if ( is_io_type ( pick_best_physical_type ( logical_block ) ) && pad_loc_type == RANDOM ) { place_ctx . block_locs [ blk_id ] . is_fixed = true ; } legal_pos [ itype ] [ ipos ] = legal_pos [ itype ] [ free_locations [ itype ] - 1 ] ; free_locations [ itype ] -- ; } } }
Place blocks that are NOT a part of any macro.
Place blocks that are NOT a part of any macro .
// Sorting blocks to place to have most constricted ones to be placed first // -1 is a sentinel for an empty block // block placed. /* Don't do IOs if the user specifies IOs; we'll read those locations later. */ /* Randomly select a free location of the appropriate type for blk_id.
             * We have a linearized list of all the free locations that can
             * accommodate a block of that type in free_locations[itype].
             * Choose one randomly and put blk_id there. Then we don't want to pick
             * that location again, so remove it from the free_locations array.
             */ // Make sure that the position is EMPTY_BLOCK before placing the block down //Mark IOs as fixed if specifying a (fixed) random placement /* Ensure randomizer doesn't pick this location again, since it's occupied. Could shift all the
             * legal positions in legal_pos to remove the entry (choice) we just used, but faster to
             * just move the last entry in legal_pos to the spot we just used and decrement the
             * count of free_locations. */ /* overwrite used block position */