|
8 | 8 | #include <optional> |
9 | 9 |
|
10 | 10 | #include "NetPinTimingInvalidator.h" |
| 11 | +#include "clustered_netlist.h" |
| 12 | +#include "device_grid.h" |
| 13 | +#include "verify_placement.h" |
11 | 14 | #include "vtr_assert.h" |
12 | 15 | #include "vtr_log.h" |
13 | 16 | #include "vtr_util.h" |
@@ -228,11 +231,6 @@ static int check_placement_costs(const t_placer_costs& costs, |
228 | 231 | PlacerState& placer_state, |
229 | 232 | NetCostHandler& net_cost_handler); |
230 | 233 |
|
231 | | - |
232 | | -static int check_placement_consistency(const BlkLocRegistry& blk_loc_registry); |
233 | | -static int check_block_placement_consistency(const BlkLocRegistry& blk_loc_registry); |
234 | | -static int check_macro_placement_consistency(const BlkLocRegistry& blk_loc_registry); |
235 | | - |
236 | 234 | static float starting_t(const t_annealing_state* state, |
237 | 235 | t_placer_costs* costs, |
238 | 236 | t_annealing_sched annealing_sched, |
@@ -1943,12 +1941,19 @@ static void check_place(const t_placer_costs& costs, |
1943 | 1941 | * every block, blocks are in legal spots, etc. Also recomputes * |
1944 | 1942 | * the final placement cost from scratch and makes sure it is * |
1945 | 1943 | * within roundoff of what we think the cost is. */ |
| 1944 | + const ClusteredNetlist& clb_nlist = g_vpr_ctx.clustering().clb_nlist; |
| 1945 | + const DeviceGrid& device_grid = g_vpr_ctx.device().grid; |
| 1946 | + const auto& cluster_constraints = g_vpr_ctx.floorplanning().cluster_constraints; |
1946 | 1947 |
|
1947 | 1948 | int error = 0; |
1948 | 1949 |
|
1949 | | - error += check_placement_consistency(placer_state.blk_loc_registry()); |
| 1950 | + // Verify the placement invariants independent to the placement flow. |
| 1951 | + error += verify_placement(placer_state.blk_loc_registry(), |
| 1952 | + clb_nlist, |
| 1953 | + device_grid, |
| 1954 | + cluster_constraints); |
| 1955 | + |
1950 | 1956 | error += check_placement_costs(costs, delay_model, criticalities, place_algorithm, placer_state, net_cost_handler); |
1951 | | - error += check_placement_floorplanning(placer_state.block_locs()); |
1952 | 1957 |
|
1953 | 1958 | if (noc_opts.noc) { |
1954 | 1959 | // check the NoC costs during placement if the user is using the NoC supported flow |
@@ -2000,133 +2005,6 @@ static int check_placement_costs(const t_placer_costs& costs, |
2000 | 2005 | return error; |
2001 | 2006 | } |
2002 | 2007 |
|
2003 | | -static int check_placement_consistency(const BlkLocRegistry& blk_loc_registry) { |
2004 | | - return check_block_placement_consistency(blk_loc_registry) + check_macro_placement_consistency(blk_loc_registry); |
2005 | | -} |
2006 | | - |
2007 | | -static int check_block_placement_consistency(const BlkLocRegistry& blk_loc_registry) { |
2008 | | - auto& cluster_ctx = g_vpr_ctx.clustering(); |
2009 | | - auto& device_ctx = g_vpr_ctx.device(); |
2010 | | - const auto& block_locs = blk_loc_registry.block_locs(); |
2011 | | - const auto& grid_blocks = blk_loc_registry.grid_blocks(); |
2012 | | - |
2013 | | - int error = 0; |
2014 | | - |
2015 | | - vtr::vector<ClusterBlockId, int> bdone(cluster_ctx.clb_nlist.blocks().size(), 0); |
2016 | | - |
2017 | | - /* Step through device grid and placement. Check it against blocks */ |
2018 | | - for (int layer_num = 0; layer_num < (int)device_ctx.grid.get_num_layers(); layer_num++) { |
2019 | | - for (int i = 0; i < (int)device_ctx.grid.width(); i++) { |
2020 | | - for (int j = 0; j < (int)device_ctx.grid.height(); j++) { |
2021 | | - const t_physical_tile_loc tile_loc(i, j, layer_num); |
2022 | | - const auto& type = device_ctx.grid.get_physical_type(tile_loc); |
2023 | | - if (grid_blocks.get_usage(tile_loc) > type->capacity) { |
2024 | | - VTR_LOG_ERROR( |
2025 | | - "%d blocks were placed at grid location (%d,%d,%d), but location capacity is %d.\n", |
2026 | | - grid_blocks.get_usage(tile_loc), i, j, layer_num, type->capacity); |
2027 | | - error++; |
2028 | | - } |
2029 | | - int usage_check = 0; |
2030 | | - for (int k = 0; k < type->capacity; k++) { |
2031 | | - ClusterBlockId bnum = grid_blocks.block_at_location({i, j, k, layer_num}); |
2032 | | - if (bnum == ClusterBlockId::INVALID()) { |
2033 | | - continue; |
2034 | | - } |
2035 | | - |
2036 | | - auto logical_block = cluster_ctx.clb_nlist.block_type(bnum); |
2037 | | - auto physical_tile = type; |
2038 | | - t_pl_loc block_loc = block_locs[bnum].loc; |
2039 | | - |
2040 | | - if (physical_tile_type(block_loc) != physical_tile) { |
2041 | | - VTR_LOG_ERROR( |
2042 | | - "Block %zu type (%s) does not match grid location (%zu,%zu, %d) type (%s).\n", |
2043 | | - size_t(bnum), logical_block->name.c_str(), i, j, layer_num, physical_tile->name.c_str()); |
2044 | | - error++; |
2045 | | - } |
2046 | | - |
2047 | | - auto& loc = block_locs[bnum].loc; |
2048 | | - if (loc.x != i || loc.y != j || loc.layer != layer_num |
2049 | | - || !is_sub_tile_compatible(physical_tile, logical_block, |
2050 | | - loc.sub_tile)) { |
2051 | | - VTR_LOG_ERROR( |
2052 | | - "Block %zu's location is (%d,%d,%d,%d) but found in grid at (%d,%d,%d,%d).\n", |
2053 | | - size_t(bnum), |
2054 | | - loc.x, |
2055 | | - loc.y, |
2056 | | - loc.sub_tile, |
2057 | | - loc.layer, |
2058 | | - i, |
2059 | | - j, |
2060 | | - k, |
2061 | | - layer_num); |
2062 | | - error++; |
2063 | | - } |
2064 | | - ++usage_check; |
2065 | | - bdone[bnum]++; |
2066 | | - } |
2067 | | - if (usage_check != grid_blocks.get_usage(tile_loc)) { |
2068 | | - VTR_LOG_ERROR( |
2069 | | - "%d block(s) were placed at location (%d,%d,%d), but location contains %d block(s).\n", |
2070 | | - grid_blocks.get_usage(tile_loc), |
2071 | | - tile_loc.x, |
2072 | | - tile_loc.y, |
2073 | | - tile_loc.layer_num, |
2074 | | - usage_check); |
2075 | | - error++; |
2076 | | - } |
2077 | | - } |
2078 | | - } |
2079 | | - } |
2080 | | - |
2081 | | - /* Check that every block exists in the device_ctx.grid and cluster_ctx.blocks arrays somewhere. */ |
2082 | | - for (ClusterBlockId blk_id : cluster_ctx.clb_nlist.blocks()) |
2083 | | - if (bdone[blk_id] != 1) { |
2084 | | - VTR_LOG_ERROR("Block %zu listed %d times in device context grid.\n", |
2085 | | - size_t(blk_id), bdone[blk_id]); |
2086 | | - error++; |
2087 | | - } |
2088 | | - |
2089 | | - return error; |
2090 | | -} |
2091 | | - |
2092 | | -int check_macro_placement_consistency(const BlkLocRegistry& blk_loc_registry) { |
2093 | | - const auto& pl_macros = blk_loc_registry.place_macros().macros(); |
2094 | | - const auto& block_locs = blk_loc_registry.block_locs(); |
2095 | | - const auto& grid_blocks = blk_loc_registry.grid_blocks(); |
2096 | | - |
2097 | | - int error = 0; |
2098 | | - |
2099 | | - /* Check the pl_macro placement are legal - blocks are in the proper relative position. */ |
2100 | | - for (size_t imacro = 0; imacro < pl_macros.size(); imacro++) { |
2101 | | - auto head_iblk = pl_macros[imacro].members[0].blk_index; |
2102 | | - |
2103 | | - for (size_t imember = 0; imember < pl_macros[imacro].members.size(); imember++) { |
2104 | | - auto member_iblk = pl_macros[imacro].members[imember].blk_index; |
2105 | | - |
2106 | | - // Compute the supposed member's x,y,z location |
2107 | | - t_pl_loc member_pos = block_locs[head_iblk].loc + pl_macros[imacro].members[imember].offset; |
2108 | | - |
2109 | | - // Check the blk_loc_registry.block_locs data structure first |
2110 | | - if (block_locs[member_iblk].loc != member_pos) { |
2111 | | - VTR_LOG_ERROR( |
2112 | | - "Block %zu in pl_macro #%zu is not placed in the proper orientation.\n", |
2113 | | - size_t(member_iblk), imacro); |
2114 | | - error++; |
2115 | | - } |
2116 | | - |
2117 | | - // Then check the blk_loc_registry.grid data structure |
2118 | | - if (grid_blocks.block_at_location(member_pos) != member_iblk) { |
2119 | | - VTR_LOG_ERROR( |
2120 | | - "Block %zu in pl_macro #%zu is not placed in the proper orientation.\n", |
2121 | | - size_t(member_iblk), imacro); |
2122 | | - error++; |
2123 | | - } |
2124 | | - } // Finish going through all the members |
2125 | | - } // Finish going through all the macros |
2126 | | - |
2127 | | - return error; |
2128 | | -} |
2129 | | - |
2130 | 2008 | #ifdef VERBOSE |
2131 | 2009 | void print_clb_placement(const char* fname) { |
2132 | 2010 | /* Prints out the clb placements to a file. */ |
|
0 commit comments