#include "move_utils.h" #include "globals.h" #include "place_util.h" //Records that block 'blk' should be moved to the specified 'to' location e_block_move_result record_block_move(t_pl_blocks_to_be_moved& blocks_affected, ClusterBlockId blk, t_pl_loc to) { auto res = blocks_affected.moved_to.emplace(to); if (!res.second) { log_move_abort("duplicate block move to location"); return e_block_move_result::ABORT; } auto& place_ctx = g_vpr_ctx.mutable_placement(); t_pl_loc from = place_ctx.block_locs[blk].loc; auto res2 = blocks_affected.moved_from.emplace(from); if (!res2.second) { log_move_abort("duplicate block move from location"); return e_block_move_result::ABORT; } VTR_ASSERT_SAFE(to.z < int(place_ctx.grid_blocks[to.x][to.y].blocks.size())); // Sets up the blocks moved int imoved_blk = blocks_affected.num_moved_blocks; blocks_affected.moved_blocks[imoved_blk].block_num = blk; blocks_affected.moved_blocks[imoved_blk].old_loc = from; blocks_affected.moved_blocks[imoved_blk].new_loc = to; blocks_affected.num_moved_blocks++; return e_block_move_result::VALID; } //Moves the blocks in blocks_affected to their new locations void apply_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected) { auto& place_ctx = g_vpr_ctx.mutable_placement(); //Swap the blocks, but don't swap the nets or update place_ctx.grid_blocks //yet since we don't know whether the swap will be accepted for (int iblk = 0; iblk < blocks_affected.num_moved_blocks; ++iblk) { ClusterBlockId blk = blocks_affected.moved_blocks[iblk].block_num; place_ctx.block_locs[blk].loc = blocks_affected.moved_blocks[iblk].new_loc; } } //Commits the blocks in blocks_affected to their new locations (updates inverse //lookups via place_ctx.grid_blocks) void commit_move_blocks(const t_pl_blocks_to_be_moved& blocks_affected) { auto& place_ctx = g_vpr_ctx.mutable_placement(); /* Swap physical location */ for (int iblk = 0; iblk < blocks_affected.num_moved_blocks; ++iblk) { ClusterBlockId blk = blocks_affected.moved_blocks[iblk].block_num; t_pl_loc to = blocks_affected.moved_blocks[iblk].new_loc; t_pl_loc from = blocks_affected.moved_blocks[iblk].old_loc; //Remove from old location only if it hasn't already been updated by a previous block update if (place_ctx.grid_blocks[from.x][from.y].blocks[from.z] == blk) { ; place_ctx.grid_blocks[from.x][from.y].blocks[from.z] = EMPTY_BLOCK_ID; --place_ctx.grid_blocks[from.x][from.y].usage; } //Add to new location if (place_ctx.grid_blocks[to.x][to.y].blocks[to.z] == EMPTY_BLOCK_ID) { ; //Only need to increase usage if previously unused ++place_ctx.grid_blocks[to.x][to.y].usage; } place_ctx.grid_blocks[to.x][to.y].blocks[to.z] = blk; } // Finish updating clb for all blocks } //Moves the blocks in blocks_affected to their old locations void revert_move_blocks(t_pl_blocks_to_be_moved& blocks_affected) { auto& place_ctx = g_vpr_ctx.mutable_placement(); // Swap the blocks back, nets not yet swapped they don't need to be changed for (int iblk = 0; iblk < blocks_affected.num_moved_blocks; ++iblk) { ClusterBlockId blk = blocks_affected.moved_blocks[iblk].block_num; t_pl_loc old = blocks_affected.moved_blocks[iblk].old_loc; place_ctx.block_locs[blk].loc = old; VTR_ASSERT_SAFE_MSG(place_ctx.grid_blocks[old.x][old.y].blocks[old.z] = blk, "Grid blocks should only have been updated if swap commited (not reverted)"); } } //Clears the current move so a new move can be proposed void clear_move_blocks(t_pl_blocks_to_be_moved& blocks_affected) { //Reset moved flags blocks_affected.moved_to.clear(); blocks_affected.moved_from.clear(); //For run-time we just reset num_moved_blocks to zero, but do not free the blocks_affected //array to avoid memory allocation blocks_affected.num_moved_blocks = 0; }