Skip to content

Commit

Permalink
Merge pull request verilog-to-routing#2669 from verilog-to-routing/te…
Browse files Browse the repository at this point in the history
…mp_place_ref

Remove accesses to global placement state during placement stage
  • Loading branch information
vaughnbetz committed Aug 20, 2024
2 parents 67e5558 + 609bb78 commit 78c89f5
Show file tree
Hide file tree
Showing 111 changed files with 3,100 additions and 2,344 deletions.
4 changes: 2 additions & 2 deletions libs/EXTERNAL/libtatum/libtatum/tatum/TimingReporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,7 @@ Time TimingReporter::report_timing_data_arrival_subpath(std::ostream& os,

{
//Input constraint
TATUM_ASSERT(subpath.elements().size() > 0);
TATUM_ASSERT(!subpath.elements().empty());
const TimingPathElem& path_elem = *(subpath.elements().begin());

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

size_t TimingReporter::estimate_point_print_width(const TimingPath& path) const {
size_t width = 60; //default
for(auto subpath : {path.clock_launch_path(), path.data_arrival_path(), path.clock_capture_path()}) {
for(const auto& subpath : {path.clock_launch_path(), path.data_arrival_path(), path.clock_capture_path()}) {
for(auto elem : subpath.elements()) {
//Take the longest typical point name
std::string point = name_resolver_.node_name(elem.node()) + " (" + name_resolver_.node_type_name(elem.node()) + ")";
Expand Down
10 changes: 5 additions & 5 deletions utils/fasm/src/fasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ void FasmWriterVisitor::visit_top_impl(const char* top_level_name) {
}

void FasmWriterVisitor::visit_clb_impl(ClusterBlockId blk_id, const t_pb* clb) {
auto& place_ctx = g_vpr_ctx.placement();
auto& device_ctx = g_vpr_ctx.device();
auto& cluster_ctx = g_vpr_ctx.clustering();
auto& block_locs = g_vpr_ctx.placement().block_locs();

current_blk_id_ = blk_id;

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

root_clb_ = clb->pb_graph_node;

int x = place_ctx.block_locs[blk_id].loc.x;
int y = place_ctx.block_locs[blk_id].loc.y;
int layer_num = place_ctx.block_locs[blk_id].loc.layer;
int sub_tile = place_ctx.block_locs[blk_id].loc.sub_tile;
int x = block_locs[blk_id].loc.x;
int y = block_locs[blk_id].loc.y;
int layer_num = block_locs[blk_id].loc.layer;
int sub_tile = block_locs[blk_id].loc.sub_tile;
physical_tile_ = device_ctx.grid.get_physical_type({x, y, layer_num});
logical_block_ = cluster_ctx.clb_nlist.block_type(blk_id);
const auto& grid_meta = device_ctx.grid.get_metadata({x, y, layer_num});
Expand Down
2 changes: 1 addition & 1 deletion utils/fasm/test/test_fasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,7 @@ TEST_CASE("fasm_integration_test", "[fasm]") {

// Verify occupied grid LOCs
const auto & place_ctx = g_vpr_ctx.placement();
for (const auto& loc: place_ctx.block_locs) {
for (const auto& loc: place_ctx.block_locs()) {

// Do not consider "IOB" tiles. They do not have fasm features
// defined in the arch.
Expand Down
18 changes: 14 additions & 4 deletions vpr/src/analysis/timing_reports.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,18 @@

#include "VprTimingGraphResolver.h"

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) {
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,
const BlkLocRegistry& blk_loc_registry) {
auto& timing_ctx = g_vpr_ctx.timing();
auto& atom_ctx = g_vpr_ctx.atom();

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

VprTimingGraphResolver resolver(atom_ctx.nlist, atom_ctx.lookup, *timing_ctx.graph, delay_calc, is_flat);
VprTimingGraphResolver resolver(atom_ctx.nlist, atom_ctx.lookup, *timing_ctx.graph, delay_calc, is_flat, blk_loc_registry);
resolver.set_detail_level(analysis_opts.timing_report_detail);

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

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) {
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,
const BlkLocRegistry& blk_loc_registry) {
auto& timing_ctx = g_vpr_ctx.timing();
auto& atom_ctx = g_vpr_ctx.atom();

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

VprTimingGraphResolver resolver(atom_ctx.nlist, atom_ctx.lookup, *timing_ctx.graph, delay_calc, is_flat);
VprTimingGraphResolver resolver(atom_ctx.nlist, atom_ctx.lookup, *timing_ctx.graph, delay_calc, is_flat, blk_loc_registry);
resolver.set_detail_level(analysis_opts.timing_report_detail);

tatum::TimingReporter timing_reporter(resolver, *timing_ctx.graph, *timing_ctx.constraints);
Expand Down
17 changes: 15 additions & 2 deletions vpr/src/analysis/timing_reports.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,20 @@
#include "AnalysisDelayCalculator.h"
#include "vpr_types.h"

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);
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);
class BlkLocRegistry;

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,
const BlkLocRegistry& blk_loc_registry);

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,
const BlkLocRegistry& blk_loc_registry);

#endif
4 changes: 2 additions & 2 deletions vpr/src/base/ShowSetup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -527,10 +527,10 @@ static void ShowPlacerOpts(const t_placer_opts& PlacerOpts,

VTR_LOG("PlacerOpts.pad_loc_type: ");
switch (PlacerOpts.pad_loc_type) {
case FREE:
case e_pad_loc_type::FREE:
VTR_LOG("FREE\n");
break;
case RANDOM:
case e_pad_loc_type::RANDOM:
VTR_LOG("RANDOM\n");
break;
default:
Expand Down
114 changes: 114 additions & 0 deletions vpr/src/base/blk_loc_registry.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@

#include "blk_loc_registry.h"
#include "globals.h"

const vtr::vector_map<ClusterBlockId, t_block_loc>& BlkLocRegistry::block_locs() const {
return block_locs_;
}

vtr::vector_map<ClusterBlockId, t_block_loc>& BlkLocRegistry::mutable_block_locs() {
return block_locs_;
}

const GridBlock& BlkLocRegistry::grid_blocks() const {
return grid_blocks_;
}

GridBlock& BlkLocRegistry::mutable_grid_blocks() {
return grid_blocks_;
}

const vtr::vector_map<ClusterPinId, int>& BlkLocRegistry::physical_pins() const {
return physical_pins_;
}

vtr::vector_map<ClusterPinId, int>& BlkLocRegistry::mutable_physical_pins() {
return physical_pins_;
}

int BlkLocRegistry::tile_pin_index(const ClusterPinId pin) const {
return physical_pins_[pin];
}

int BlkLocRegistry::net_pin_to_tile_pin_index(const ClusterNetId net_id, int net_pin_index) const {
auto& cluster_ctx = g_vpr_ctx.clustering();

// Get the logical pin index of pin within its logical block type
ClusterPinId pin_id = cluster_ctx.clb_nlist.net_pin(net_id, net_pin_index);

return this->tile_pin_index(pin_id);
}

void BlkLocRegistry::set_block_location(ClusterBlockId blk_id, const t_pl_loc& location) {
auto& device_ctx = g_vpr_ctx.device();
auto& cluster_ctx = g_vpr_ctx.clustering();

const std::string& block_name = cluster_ctx.clb_nlist.block_name(blk_id);

//Check if block location is out of range of grid dimensions
if (location.x < 0 || location.x > int(device_ctx.grid.width() - 1)
|| location.y < 0 || location.y > int(device_ctx.grid.height() - 1)) {
VPR_THROW(VPR_ERROR_PLACE, "Block %s with ID %d is out of range at location (%d, %d). \n",
block_name.c_str(), blk_id, location.x, location.y);
}

//Set the location of the block
block_locs_[blk_id].loc = location;

//Check if block is at an illegal location
auto physical_tile = device_ctx.grid.get_physical_type({location.x, location.y, location.layer});
auto logical_block = cluster_ctx.clb_nlist.block_type(blk_id);

if (location.sub_tile >= physical_tile->capacity || location.sub_tile < 0) {
VPR_THROW(VPR_ERROR_PLACE, "Block %s subtile number (%d) is out of range. \n", block_name.c_str(), location.sub_tile);
}

if (!is_sub_tile_compatible(physical_tile, logical_block, block_locs_[blk_id].loc.sub_tile)) {
VPR_THROW(VPR_ERROR_PLACE, "Attempt to place block %s with ID %d at illegal location (%d,%d,%d). \n",
block_name.c_str(),
blk_id,
location.x,
location.y,
location.layer);
}

//Mark the grid location and usage of the block
grid_blocks_.set_block_at_location(location, blk_id);
grid_blocks_.increment_usage({location.x, location.y, location.layer});

place_sync_external_block_connections(blk_id);
}

void BlkLocRegistry::place_sync_external_block_connections(ClusterBlockId iblk) {
const auto& cluster_ctx = g_vpr_ctx.clustering();
const auto& clb_nlist = cluster_ctx.clb_nlist;

t_pl_loc block_loc = block_locs_[iblk].loc;

auto physical_tile = physical_tile_type(block_loc);
auto logical_block = clb_nlist.block_type(iblk);

int sub_tile_index = get_sub_tile_index(iblk, block_locs_);
auto sub_tile = physical_tile->sub_tiles[sub_tile_index];

VTR_ASSERT(sub_tile.num_phy_pins % sub_tile.capacity.total() == 0);

int max_num_block_pins = sub_tile.num_phy_pins / sub_tile.capacity.total();
/* Logical location and physical location is offset by z * max_num_block_pins */

int rel_capacity = block_loc.sub_tile - sub_tile.capacity.low;

for (ClusterPinId pin : clb_nlist.block_pins(iblk)) {
int logical_pin_index = clb_nlist.pin_logical_index(pin);
int sub_tile_pin_index = get_sub_tile_physical_pin(sub_tile_index, physical_tile, logical_block, logical_pin_index);

int new_physical_pin_index = sub_tile.sub_tile_to_tile_pin_indices[sub_tile_pin_index + rel_capacity * max_num_block_pins];

auto result = physical_pins_.find(pin);
if (result != physical_pins_.end()) {
physical_pins_[pin] = new_physical_pin_index;
} else {
physical_pins_.insert(pin, new_physical_pin_index);
}
}
}
85 changes: 85 additions & 0 deletions vpr/src/base/blk_loc_registry.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#ifndef VTR_BLK_LOC_REGISTRY_H
#define VTR_BLK_LOC_REGISTRY_H

#include "clustered_netlist_fwd.h"
#include "vtr_vector_map.h"
#include "vpr_types.h"
#include "grid_block.h"

struct t_block_loc;

/**
* @class BlkLocRegistry contains information about the placement of clustered blocks.
* More specifically:
* 1) block_locs stores the location where each clustered blocks is placed at.
* 2) grid_blocks stores which blocks (if any) are placed at a given location.
* 3) physical_pins stores the mapping between the pins of a clustered block and
* the pins of the physical tile where the clustered blocks is placed.
*
*/
class BlkLocRegistry {
public:
BlkLocRegistry() = default;
~BlkLocRegistry() = default;
BlkLocRegistry(const BlkLocRegistry&) = delete;
BlkLocRegistry& operator=(const BlkLocRegistry&) = default;
BlkLocRegistry(BlkLocRegistry&&) = delete;
BlkLocRegistry& operator=(BlkLocRegistry&&) = delete;

private:
///@brief Clustered block placement locations
vtr::vector_map<ClusterBlockId, t_block_loc> block_locs_;

///@brief Clustered block associated with each grid location (i.e. inverse of block_locs)
GridBlock grid_blocks_;

///@brief Clustered pin placement mapping with physical pin
vtr::vector_map<ClusterPinId, int> physical_pins_;

public:
const vtr::vector_map<ClusterBlockId, t_block_loc>& block_locs() const;
vtr::vector_map<ClusterBlockId, t_block_loc>& mutable_block_locs();

const GridBlock& grid_blocks() const;
GridBlock& mutable_grid_blocks();

const vtr::vector_map<ClusterPinId, int>& physical_pins() const;
vtr::vector_map<ClusterPinId, int>& mutable_physical_pins();

///@brief Returns the physical pin of the tile, related to the given ClusterPinId
int tile_pin_index(const ClusterPinId pin) const;

///@brief Returns the physical pin of the tile, related to the given ClusterNedId, and the net pin index.
int net_pin_to_tile_pin_index(const ClusterNetId net_id, int net_pin_index) const;

/**
* @brief Performs error checking to see if location is legal for block type,
* and sets the location and grid usage of the block if it is legal.
* @param blk_id The unique ID of the clustered block whose location is to set.
* @param location The location where the clustered block should placed at.
*/
void set_block_location(ClusterBlockId blk_id, const t_pl_loc& location);

/**
* @brief Syncs the logical block pins corresponding to the input iblk with the corresponding chosen physical tile
* @param iblk cluster block ID to sync within the assigned physical tile
*
* This routine updates the physical pins vector of the place context after the placement step
* to synchronize the pins related to the logical block with the actual connection interface of
* the belonging physical tile with the RR graph.
*
* This step is required as the logical block can be placed at any compatible sub tile locations
* within a physical tile.
* Given that it is possible to have equivalent logical blocks within a specific sub tile, with
* a different subset of IO pins, the various pins offsets must be correctly computed and assigned
* to the physical pins vector, so that, when the net RR terminals are computed, the correct physical
* tile IO pins are selected.
*
* This routine uses the x,y and sub_tile coordinates of the clb netlist, and expects those to place each netlist block
* at a legal location that can accommodate it.
* It does not check for overuse of locations, therefore it can be used with placements that have resource overuse.
*/
void place_sync_external_block_connections(ClusterBlockId iblk);
};

#endif //VTR_BLK_LOC_REGISTRY_H
59 changes: 59 additions & 0 deletions vpr/src/base/grid_block.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@

#include "grid_block.h"

#include "globals.h"

void GridBlock::zero_initialize() {
auto& device_ctx = g_vpr_ctx.device();

/* Initialize all occupancy to zero. */
for (int layer_num = 0; layer_num < (int)device_ctx.grid.get_num_layers(); layer_num++) {
for (int i = 0; i < (int)device_ctx.grid.width(); i++) {
for (int j = 0; j < (int)device_ctx.grid.height(); j++) {
set_usage({i, j, layer_num}, 0);
auto tile = device_ctx.grid.get_physical_type({i, j, layer_num});

for (const auto& sub_tile : tile->sub_tiles) {
auto capacity = sub_tile.capacity;

for (int k = 0; k < capacity.total(); k++) {
set_block_at_location({i, j, k + capacity.low, layer_num}, ClusterBlockId::INVALID());
}
}
}
}
}
}

void GridBlock::load_from_block_locs(const vtr::vector_map<ClusterBlockId, t_block_loc>& block_locs) {
auto& cluster_ctx = g_vpr_ctx.clustering();
auto& device_ctx = g_vpr_ctx.device();

zero_initialize();

for (ClusterBlockId blk_id : cluster_ctx.clb_nlist.blocks()) {
t_pl_loc location = block_locs[blk_id].loc;

VTR_ASSERT(location.x < (int)device_ctx.grid.width());
VTR_ASSERT(location.y < (int)device_ctx.grid.height());

set_block_at_location(location, blk_id);
increment_usage({location.x, location.y, location.layer});
}
}

int GridBlock::increment_usage(const t_physical_tile_loc& loc) {
int curr_usage = get_usage(loc);
int updated_usage = set_usage(loc, curr_usage + 1);

return updated_usage;
}

int GridBlock::decrement_usage(const t_physical_tile_loc& loc) {
int curr_usage = get_usage(loc);
int updated_usage = set_usage(loc, curr_usage - 1);

return updated_usage;
}


Loading

0 comments on commit 78c89f5

Please sign in to comment.