Skip to content

Commit 78c89f5

Browse files
authored
Merge pull request #2669 from verilog-to-routing/temp_place_ref
Remove accesses to global placement state during placement stage
2 parents 67e5558 + 609bb78 commit 78c89f5

File tree

111 files changed

+3100
-2344
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

111 files changed

+3100
-2344
lines changed

libs/EXTERNAL/libtatum/libtatum/tatum/TimingReporter.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,7 @@ Time TimingReporter::report_timing_data_arrival_subpath(std::ostream& os,
606606

607607
{
608608
//Input constraint
609-
TATUM_ASSERT(subpath.elements().size() > 0);
609+
TATUM_ASSERT(!subpath.elements().empty());
610610
const TimingPathElem& path_elem = *(subpath.elements().begin());
611611

612612
Time input_constraint;
@@ -712,7 +712,7 @@ bool TimingReporter::nearly_equal(const Time& lhs, const Time& rhs) const {
712712

713713
size_t TimingReporter::estimate_point_print_width(const TimingPath& path) const {
714714
size_t width = 60; //default
715-
for(auto subpath : {path.clock_launch_path(), path.data_arrival_path(), path.clock_capture_path()}) {
715+
for(const auto& subpath : {path.clock_launch_path(), path.data_arrival_path(), path.clock_capture_path()}) {
716716
for(auto elem : subpath.elements()) {
717717
//Take the longest typical point name
718718
std::string point = name_resolver_.node_name(elem.node()) + " (" + name_resolver_.node_type_name(elem.node()) + ")";

utils/fasm/src/fasm.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ void FasmWriterVisitor::visit_top_impl(const char* top_level_name) {
3737
}
3838

3939
void FasmWriterVisitor::visit_clb_impl(ClusterBlockId blk_id, const t_pb* clb) {
40-
auto& place_ctx = g_vpr_ctx.placement();
4140
auto& device_ctx = g_vpr_ctx.device();
4241
auto& cluster_ctx = g_vpr_ctx.clustering();
42+
auto& block_locs = g_vpr_ctx.placement().block_locs();
4343

4444
current_blk_id_ = blk_id;
4545

@@ -48,10 +48,10 @@ void FasmWriterVisitor::visit_clb_impl(ClusterBlockId blk_id, const t_pb* clb) {
4848

4949
root_clb_ = clb->pb_graph_node;
5050

51-
int x = place_ctx.block_locs[blk_id].loc.x;
52-
int y = place_ctx.block_locs[blk_id].loc.y;
53-
int layer_num = place_ctx.block_locs[blk_id].loc.layer;
54-
int sub_tile = place_ctx.block_locs[blk_id].loc.sub_tile;
51+
int x = block_locs[blk_id].loc.x;
52+
int y = block_locs[blk_id].loc.y;
53+
int layer_num = block_locs[blk_id].loc.layer;
54+
int sub_tile = block_locs[blk_id].loc.sub_tile;
5555
physical_tile_ = device_ctx.grid.get_physical_type({x, y, layer_num});
5656
logical_block_ = cluster_ctx.clb_nlist.block_type(blk_id);
5757
const auto& grid_meta = device_ctx.grid.get_metadata({x, y, layer_num});

utils/fasm/test/test_fasm.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,7 @@ TEST_CASE("fasm_integration_test", "[fasm]") {
569569

570570
// Verify occupied grid LOCs
571571
const auto & place_ctx = g_vpr_ctx.placement();
572-
for (const auto& loc: place_ctx.block_locs) {
572+
for (const auto& loc: place_ctx.block_locs()) {
573573

574574
// Do not consider "IOB" tiles. They do not have fasm features
575575
// defined in the arch.

vpr/src/analysis/timing_reports.cpp

+14-4
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,18 @@
1212

1313
#include "VprTimingGraphResolver.h"
1414

15-
void generate_setup_timing_stats(const std::string& prefix, const SetupTimingInfo& timing_info, const AnalysisDelayCalculator& delay_calc, const t_analysis_opts& analysis_opts, bool is_flat) {
15+
void generate_setup_timing_stats(const std::string& prefix,
16+
const SetupTimingInfo& timing_info,
17+
const AnalysisDelayCalculator& delay_calc,
18+
const t_analysis_opts& analysis_opts,
19+
bool is_flat,
20+
const BlkLocRegistry& blk_loc_registry) {
1621
auto& timing_ctx = g_vpr_ctx.timing();
1722
auto& atom_ctx = g_vpr_ctx.atom();
1823

1924
print_setup_timing_summary(*timing_ctx.constraints, *timing_info.setup_analyzer(), "Final ", analysis_opts.write_timing_summary);
2025

21-
VprTimingGraphResolver resolver(atom_ctx.nlist, atom_ctx.lookup, *timing_ctx.graph, delay_calc, is_flat);
26+
VprTimingGraphResolver resolver(atom_ctx.nlist, atom_ctx.lookup, *timing_ctx.graph, delay_calc, is_flat, blk_loc_registry);
2227
resolver.set_detail_level(analysis_opts.timing_report_detail);
2328

2429
tatum::TimingReporter timing_reporter(resolver, *timing_ctx.graph, *timing_ctx.constraints);
@@ -32,13 +37,18 @@ void generate_setup_timing_stats(const std::string& prefix, const SetupTimingInf
3237
timing_reporter.report_unconstrained_setup(prefix + "report_unconstrained_timing.setup.rpt", *timing_info.setup_analyzer());
3338
}
3439

35-
void generate_hold_timing_stats(const std::string& prefix, const HoldTimingInfo& timing_info, const AnalysisDelayCalculator& delay_calc, const t_analysis_opts& analysis_opts, bool is_flat) {
40+
void generate_hold_timing_stats(const std::string& prefix,
41+
const HoldTimingInfo& timing_info,
42+
const AnalysisDelayCalculator& delay_calc,
43+
const t_analysis_opts& analysis_opts,
44+
bool is_flat,
45+
const BlkLocRegistry& blk_loc_registry) {
3646
auto& timing_ctx = g_vpr_ctx.timing();
3747
auto& atom_ctx = g_vpr_ctx.atom();
3848

3949
print_hold_timing_summary(*timing_ctx.constraints, *timing_info.hold_analyzer(), "Final ");
4050

41-
VprTimingGraphResolver resolver(atom_ctx.nlist, atom_ctx.lookup, *timing_ctx.graph, delay_calc, is_flat);
51+
VprTimingGraphResolver resolver(atom_ctx.nlist, atom_ctx.lookup, *timing_ctx.graph, delay_calc, is_flat, blk_loc_registry);
4252
resolver.set_detail_level(analysis_opts.timing_report_detail);
4353

4454
tatum::TimingReporter timing_reporter(resolver, *timing_ctx.graph, *timing_ctx.constraints);

vpr/src/analysis/timing_reports.h

+15-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,20 @@
55
#include "AnalysisDelayCalculator.h"
66
#include "vpr_types.h"
77

8-
void generate_setup_timing_stats(const std::string& prefix, const SetupTimingInfo& timing_info, const AnalysisDelayCalculator& delay_calc, const t_analysis_opts& report_detail, bool is_flat);
9-
void generate_hold_timing_stats(const std::string& prefix, const HoldTimingInfo& timing_info, const AnalysisDelayCalculator& delay_calc, const t_analysis_opts& report_detail, bool is_flat);
8+
class BlkLocRegistry;
9+
10+
void generate_setup_timing_stats(const std::string& prefix,
11+
const SetupTimingInfo& timing_info,
12+
const AnalysisDelayCalculator& delay_calc,
13+
const t_analysis_opts& report_detail,
14+
bool is_flat,
15+
const BlkLocRegistry& blk_loc_registry);
16+
17+
void generate_hold_timing_stats(const std::string& prefix,
18+
const HoldTimingInfo& timing_info,
19+
const AnalysisDelayCalculator& delay_calc,
20+
const t_analysis_opts& report_detail,
21+
bool is_flat,
22+
const BlkLocRegistry& blk_loc_registry);
1023

1124
#endif

vpr/src/base/ShowSetup.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -527,10 +527,10 @@ static void ShowPlacerOpts(const t_placer_opts& PlacerOpts,
527527

528528
VTR_LOG("PlacerOpts.pad_loc_type: ");
529529
switch (PlacerOpts.pad_loc_type) {
530-
case FREE:
530+
case e_pad_loc_type::FREE:
531531
VTR_LOG("FREE\n");
532532
break;
533-
case RANDOM:
533+
case e_pad_loc_type::RANDOM:
534534
VTR_LOG("RANDOM\n");
535535
break;
536536
default:

vpr/src/base/blk_loc_registry.cpp

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
2+
#include "blk_loc_registry.h"
3+
#include "globals.h"
4+
5+
const vtr::vector_map<ClusterBlockId, t_block_loc>& BlkLocRegistry::block_locs() const {
6+
return block_locs_;
7+
}
8+
9+
vtr::vector_map<ClusterBlockId, t_block_loc>& BlkLocRegistry::mutable_block_locs() {
10+
return block_locs_;
11+
}
12+
13+
const GridBlock& BlkLocRegistry::grid_blocks() const {
14+
return grid_blocks_;
15+
}
16+
17+
GridBlock& BlkLocRegistry::mutable_grid_blocks() {
18+
return grid_blocks_;
19+
}
20+
21+
const vtr::vector_map<ClusterPinId, int>& BlkLocRegistry::physical_pins() const {
22+
return physical_pins_;
23+
}
24+
25+
vtr::vector_map<ClusterPinId, int>& BlkLocRegistry::mutable_physical_pins() {
26+
return physical_pins_;
27+
}
28+
29+
int BlkLocRegistry::tile_pin_index(const ClusterPinId pin) const {
30+
return physical_pins_[pin];
31+
}
32+
33+
int BlkLocRegistry::net_pin_to_tile_pin_index(const ClusterNetId net_id, int net_pin_index) const {
34+
auto& cluster_ctx = g_vpr_ctx.clustering();
35+
36+
// Get the logical pin index of pin within its logical block type
37+
ClusterPinId pin_id = cluster_ctx.clb_nlist.net_pin(net_id, net_pin_index);
38+
39+
return this->tile_pin_index(pin_id);
40+
}
41+
42+
void BlkLocRegistry::set_block_location(ClusterBlockId blk_id, const t_pl_loc& location) {
43+
auto& device_ctx = g_vpr_ctx.device();
44+
auto& cluster_ctx = g_vpr_ctx.clustering();
45+
46+
const std::string& block_name = cluster_ctx.clb_nlist.block_name(blk_id);
47+
48+
//Check if block location is out of range of grid dimensions
49+
if (location.x < 0 || location.x > int(device_ctx.grid.width() - 1)
50+
|| location.y < 0 || location.y > int(device_ctx.grid.height() - 1)) {
51+
VPR_THROW(VPR_ERROR_PLACE, "Block %s with ID %d is out of range at location (%d, %d). \n",
52+
block_name.c_str(), blk_id, location.x, location.y);
53+
}
54+
55+
//Set the location of the block
56+
block_locs_[blk_id].loc = location;
57+
58+
//Check if block is at an illegal location
59+
auto physical_tile = device_ctx.grid.get_physical_type({location.x, location.y, location.layer});
60+
auto logical_block = cluster_ctx.clb_nlist.block_type(blk_id);
61+
62+
if (location.sub_tile >= physical_tile->capacity || location.sub_tile < 0) {
63+
VPR_THROW(VPR_ERROR_PLACE, "Block %s subtile number (%d) is out of range. \n", block_name.c_str(), location.sub_tile);
64+
}
65+
66+
if (!is_sub_tile_compatible(physical_tile, logical_block, block_locs_[blk_id].loc.sub_tile)) {
67+
VPR_THROW(VPR_ERROR_PLACE, "Attempt to place block %s with ID %d at illegal location (%d,%d,%d). \n",
68+
block_name.c_str(),
69+
blk_id,
70+
location.x,
71+
location.y,
72+
location.layer);
73+
}
74+
75+
//Mark the grid location and usage of the block
76+
grid_blocks_.set_block_at_location(location, blk_id);
77+
grid_blocks_.increment_usage({location.x, location.y, location.layer});
78+
79+
place_sync_external_block_connections(blk_id);
80+
}
81+
82+
void BlkLocRegistry::place_sync_external_block_connections(ClusterBlockId iblk) {
83+
const auto& cluster_ctx = g_vpr_ctx.clustering();
84+
const auto& clb_nlist = cluster_ctx.clb_nlist;
85+
86+
t_pl_loc block_loc = block_locs_[iblk].loc;
87+
88+
auto physical_tile = physical_tile_type(block_loc);
89+
auto logical_block = clb_nlist.block_type(iblk);
90+
91+
int sub_tile_index = get_sub_tile_index(iblk, block_locs_);
92+
auto sub_tile = physical_tile->sub_tiles[sub_tile_index];
93+
94+
VTR_ASSERT(sub_tile.num_phy_pins % sub_tile.capacity.total() == 0);
95+
96+
int max_num_block_pins = sub_tile.num_phy_pins / sub_tile.capacity.total();
97+
/* Logical location and physical location is offset by z * max_num_block_pins */
98+
99+
int rel_capacity = block_loc.sub_tile - sub_tile.capacity.low;
100+
101+
for (ClusterPinId pin : clb_nlist.block_pins(iblk)) {
102+
int logical_pin_index = clb_nlist.pin_logical_index(pin);
103+
int sub_tile_pin_index = get_sub_tile_physical_pin(sub_tile_index, physical_tile, logical_block, logical_pin_index);
104+
105+
int new_physical_pin_index = sub_tile.sub_tile_to_tile_pin_indices[sub_tile_pin_index + rel_capacity * max_num_block_pins];
106+
107+
auto result = physical_pins_.find(pin);
108+
if (result != physical_pins_.end()) {
109+
physical_pins_[pin] = new_physical_pin_index;
110+
} else {
111+
physical_pins_.insert(pin, new_physical_pin_index);
112+
}
113+
}
114+
}

vpr/src/base/blk_loc_registry.h

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#ifndef VTR_BLK_LOC_REGISTRY_H
2+
#define VTR_BLK_LOC_REGISTRY_H
3+
4+
#include "clustered_netlist_fwd.h"
5+
#include "vtr_vector_map.h"
6+
#include "vpr_types.h"
7+
#include "grid_block.h"
8+
9+
struct t_block_loc;
10+
11+
/**
12+
* @class BlkLocRegistry contains information about the placement of clustered blocks.
13+
* More specifically:
14+
* 1) block_locs stores the location where each clustered blocks is placed at.
15+
* 2) grid_blocks stores which blocks (if any) are placed at a given location.
16+
* 3) physical_pins stores the mapping between the pins of a clustered block and
17+
* the pins of the physical tile where the clustered blocks is placed.
18+
*
19+
*/
20+
class BlkLocRegistry {
21+
public:
22+
BlkLocRegistry() = default;
23+
~BlkLocRegistry() = default;
24+
BlkLocRegistry(const BlkLocRegistry&) = delete;
25+
BlkLocRegistry& operator=(const BlkLocRegistry&) = default;
26+
BlkLocRegistry(BlkLocRegistry&&) = delete;
27+
BlkLocRegistry& operator=(BlkLocRegistry&&) = delete;
28+
29+
private:
30+
///@brief Clustered block placement locations
31+
vtr::vector_map<ClusterBlockId, t_block_loc> block_locs_;
32+
33+
///@brief Clustered block associated with each grid location (i.e. inverse of block_locs)
34+
GridBlock grid_blocks_;
35+
36+
///@brief Clustered pin placement mapping with physical pin
37+
vtr::vector_map<ClusterPinId, int> physical_pins_;
38+
39+
public:
40+
const vtr::vector_map<ClusterBlockId, t_block_loc>& block_locs() const;
41+
vtr::vector_map<ClusterBlockId, t_block_loc>& mutable_block_locs();
42+
43+
const GridBlock& grid_blocks() const;
44+
GridBlock& mutable_grid_blocks();
45+
46+
const vtr::vector_map<ClusterPinId, int>& physical_pins() const;
47+
vtr::vector_map<ClusterPinId, int>& mutable_physical_pins();
48+
49+
///@brief Returns the physical pin of the tile, related to the given ClusterPinId
50+
int tile_pin_index(const ClusterPinId pin) const;
51+
52+
///@brief Returns the physical pin of the tile, related to the given ClusterNedId, and the net pin index.
53+
int net_pin_to_tile_pin_index(const ClusterNetId net_id, int net_pin_index) const;
54+
55+
/**
56+
* @brief Performs error checking to see if location is legal for block type,
57+
* and sets the location and grid usage of the block if it is legal.
58+
* @param blk_id The unique ID of the clustered block whose location is to set.
59+
* @param location The location where the clustered block should placed at.
60+
*/
61+
void set_block_location(ClusterBlockId blk_id, const t_pl_loc& location);
62+
63+
/**
64+
* @brief Syncs the logical block pins corresponding to the input iblk with the corresponding chosen physical tile
65+
* @param iblk cluster block ID to sync within the assigned physical tile
66+
*
67+
* This routine updates the physical pins vector of the place context after the placement step
68+
* to synchronize the pins related to the logical block with the actual connection interface of
69+
* the belonging physical tile with the RR graph.
70+
*
71+
* This step is required as the logical block can be placed at any compatible sub tile locations
72+
* within a physical tile.
73+
* Given that it is possible to have equivalent logical blocks within a specific sub tile, with
74+
* a different subset of IO pins, the various pins offsets must be correctly computed and assigned
75+
* to the physical pins vector, so that, when the net RR terminals are computed, the correct physical
76+
* tile IO pins are selected.
77+
*
78+
* This routine uses the x,y and sub_tile coordinates of the clb netlist, and expects those to place each netlist block
79+
* at a legal location that can accommodate it.
80+
* It does not check for overuse of locations, therefore it can be used with placements that have resource overuse.
81+
*/
82+
void place_sync_external_block_connections(ClusterBlockId iblk);
83+
};
84+
85+
#endif //VTR_BLK_LOC_REGISTRY_H

vpr/src/base/grid_block.cpp

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
2+
#include "grid_block.h"
3+
4+
#include "globals.h"
5+
6+
void GridBlock::zero_initialize() {
7+
auto& device_ctx = g_vpr_ctx.device();
8+
9+
/* Initialize all occupancy to zero. */
10+
for (int layer_num = 0; layer_num < (int)device_ctx.grid.get_num_layers(); layer_num++) {
11+
for (int i = 0; i < (int)device_ctx.grid.width(); i++) {
12+
for (int j = 0; j < (int)device_ctx.grid.height(); j++) {
13+
set_usage({i, j, layer_num}, 0);
14+
auto tile = device_ctx.grid.get_physical_type({i, j, layer_num});
15+
16+
for (const auto& sub_tile : tile->sub_tiles) {
17+
auto capacity = sub_tile.capacity;
18+
19+
for (int k = 0; k < capacity.total(); k++) {
20+
set_block_at_location({i, j, k + capacity.low, layer_num}, ClusterBlockId::INVALID());
21+
}
22+
}
23+
}
24+
}
25+
}
26+
}
27+
28+
void GridBlock::load_from_block_locs(const vtr::vector_map<ClusterBlockId, t_block_loc>& block_locs) {
29+
auto& cluster_ctx = g_vpr_ctx.clustering();
30+
auto& device_ctx = g_vpr_ctx.device();
31+
32+
zero_initialize();
33+
34+
for (ClusterBlockId blk_id : cluster_ctx.clb_nlist.blocks()) {
35+
t_pl_loc location = block_locs[blk_id].loc;
36+
37+
VTR_ASSERT(location.x < (int)device_ctx.grid.width());
38+
VTR_ASSERT(location.y < (int)device_ctx.grid.height());
39+
40+
set_block_at_location(location, blk_id);
41+
increment_usage({location.x, location.y, location.layer});
42+
}
43+
}
44+
45+
int GridBlock::increment_usage(const t_physical_tile_loc& loc) {
46+
int curr_usage = get_usage(loc);
47+
int updated_usage = set_usage(loc, curr_usage + 1);
48+
49+
return updated_usage;
50+
}
51+
52+
int GridBlock::decrement_usage(const t_physical_tile_loc& loc) {
53+
int curr_usage = get_usage(loc);
54+
int updated_usage = set_usage(loc, curr_usage - 1);
55+
56+
return updated_usage;
57+
}
58+
59+

0 commit comments

Comments
 (0)