Skip to content

Commit bdaf63c

Browse files
committed
Created placer context for accessing various data structures used by the VPR placer. Refactored place.cpp based on the moved global structures by moving certain interrelated routines into other (new) files.
1 parent d32ea3e commit bdaf63c

12 files changed

+813
-600
lines changed

vpr/src/place/place.cpp

Lines changed: 58 additions & 532 deletions
Large diffs are not rendered by default.

vpr/src/place/place_delay_model.cpp

Lines changed: 92 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include "vtr_math.h"
1111
#include "vpr_error.h"
1212

13+
#include "placer_globals.h"
14+
1315
#ifdef VTR_ENABLE_CAPNPROTO
1416
# include "capnp/serialize.h"
1517
# include "place_delay_model.capnp.h"
@@ -18,10 +20,7 @@
1820
# include "serdes_utils.h"
1921
#endif /* VTR_ENABLE_CAPNPROTO */
2022

21-
/*
22-
* DeltaDelayModel
23-
*/
24-
23+
///@brief DeltaDelayModel methods.
2524
float DeltaDelayModel::delay(int from_x, int from_y, int /*from_pin*/, int to_x, int to_y, int /*to_pin*/) const {
2625
int delta_x = std::abs(from_x - to_x);
2726
int delta_y = std::abs(from_y - to_y);
@@ -46,9 +45,11 @@ void DeltaDelayModel::dump_echo(std::string filepath) const {
4645
vtr::fclose(f);
4746
}
4847

49-
/*
50-
* OverrideDelayModel
51-
*/
48+
const DeltaDelayModel* OverrideDelayModel::base_delay_model() const {
49+
return base_delay_model_.get();
50+
}
51+
52+
///@brief OverrideDelayModel methods.
5253
float OverrideDelayModel::delay(int from_x, int from_y, int from_pin, int to_x, int to_y, int to_pin) const {
5354
//First check to if there is an override delay value
5455
auto& device_ctx = g_vpr_ctx.device();
@@ -136,18 +137,14 @@ float OverrideDelayModel::get_delay_override(int from_type, int from_class, int
136137
return iter->second;
137138
}
138139

139-
const DeltaDelayModel* OverrideDelayModel::base_delay_model() const {
140-
return base_delay_model_.get();
141-
}
142-
143140
void OverrideDelayModel::set_base_delay_model(std::unique_ptr<DeltaDelayModel> base_delay_model_obj) {
144141
base_delay_model_ = std::move(base_delay_model_obj);
145142
}
146143

147-
// When writing capnp targetted serialization, always allow compilation when
148-
// VTR_ENABLE_CAPNPROTO=OFF. Generally this means throwing an exception
149-
// instead.
150-
//
144+
/**
145+
* When writing capnp targetted serialization, always allow compilation when
146+
* VTR_ENABLE_CAPNPROTO=OFF. Generally this means throwing an exception instead.
147+
*/
151148
#ifndef VTR_ENABLE_CAPNPROTO
152149

153150
# define DISABLE_ERROR \
@@ -300,3 +297,83 @@ void OverrideDelayModel::write(const std::string& file) const {
300297
}
301298

302299
#endif
300+
301+
///@brief Initialize the placer delay model.
302+
std::unique_ptr<PlaceDelayModel> alloc_lookups_and_delay_model(t_chan_width_dist chan_width_dist,
303+
const t_placer_opts& placer_opts,
304+
const t_router_opts& router_opts,
305+
t_det_routing_arch* det_routing_arch,
306+
std::vector<t_segment_inf>& segment_inf,
307+
const t_direct_inf* directs,
308+
const int num_directs) {
309+
return compute_place_delay_model(placer_opts, router_opts, det_routing_arch, segment_inf,
310+
chan_width_dist, directs, num_directs);
311+
}
312+
313+
/**
314+
* @brief Returns the delay of one point to point connection.
315+
*
316+
* Only estimate delay for signals routed through the inter-block routing network.
317+
* TODO: Do how should we compute the delay for globals. "Global signals are assumed to have zero delay."
318+
*/
319+
float comp_td_single_connection_delay(const PlaceDelayModel* delay_model, ClusterNetId net_id, int ipin) {
320+
auto& cluster_ctx = g_vpr_ctx.clustering();
321+
auto& place_ctx = g_vpr_ctx.placement();
322+
323+
float delay_source_to_sink = 0.;
324+
325+
if (!cluster_ctx.clb_nlist.net_is_ignored(net_id)) {
326+
ClusterPinId source_pin = cluster_ctx.clb_nlist.net_driver(net_id);
327+
ClusterPinId sink_pin = cluster_ctx.clb_nlist.net_pin(net_id, ipin);
328+
329+
ClusterBlockId source_block = cluster_ctx.clb_nlist.pin_block(source_pin);
330+
ClusterBlockId sink_block = cluster_ctx.clb_nlist.pin_block(sink_pin);
331+
332+
int source_block_ipin = cluster_ctx.clb_nlist.pin_logical_index(source_pin);
333+
int sink_block_ipin = cluster_ctx.clb_nlist.pin_logical_index(sink_pin);
334+
335+
int source_x = place_ctx.block_locs[source_block].loc.x;
336+
int source_y = place_ctx.block_locs[source_block].loc.y;
337+
int sink_x = place_ctx.block_locs[sink_block].loc.x;
338+
int sink_y = place_ctx.block_locs[sink_block].loc.y;
339+
340+
/**
341+
* This heuristic only considers delta_x and delta_y, a much better
342+
* heuristic would be to to create a more comprehensive lookup table.
343+
*
344+
* In particular this approach does not accurately capture the effect
345+
* of fast carry-chain connections.
346+
*/
347+
delay_source_to_sink = delay_model->delay(source_x,
348+
source_y,
349+
source_block_ipin,
350+
sink_x,
351+
sink_y,
352+
sink_block_ipin);
353+
if (delay_source_to_sink < 0) {
354+
VPR_ERROR(VPR_ERROR_PLACE,
355+
"in comp_td_single_connection_delay: Bad delay_source_to_sink value %g from %s (at %d,%d) to %s (at %d,%d)\n"
356+
"in comp_td_single_connection_delay: Delay is less than 0\n",
357+
block_type_pin_index_to_name(physical_tile_type(source_block), source_block_ipin).c_str(),
358+
source_x, source_y,
359+
block_type_pin_index_to_name(physical_tile_type(sink_block), sink_block_ipin).c_str(),
360+
sink_x, sink_y,
361+
delay_source_to_sink);
362+
}
363+
}
364+
365+
return (delay_source_to_sink);
366+
}
367+
368+
///@brief Recompute all point to point delays, updating `connection_delay` matrix.
369+
void comp_td_connection_delays(const PlaceDelayModel* delay_model) {
370+
const auto& cluster_ctx = g_vpr_ctx.clustering();
371+
auto& p_timing_ctx = g_placer_ctx.mutable_timing();
372+
auto& connection_delay = p_timing_ctx.connection_delay;
373+
374+
for (auto net_id : cluster_ctx.clb_nlist.nets()) {
375+
for (size_t ipin = 1; ipin < cluster_ctx.clb_nlist.net_pins(net_id).size(); ++ipin) {
376+
connection_delay[net_id][ipin] = comp_td_single_connection_delay(delay_model, net_id, ipin);
377+
}
378+
}
379+
}

vpr/src/place/place_delay_model.h

Lines changed: 55 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
#ifndef PLACE_DELAY_MODEL_H
2-
#define PLACE_DELAY_MODEL_H
1+
/**
2+
* @file place_delay_model.h
3+
* @brief This file contains all the class and function declarations related to
4+
* the placer delay model. For implementations, see place_delay_model.cpp.
5+
*/
36

7+
#pragma once
48
#include "vtr_ndmatrix.h"
59
#include "vtr_flat_map.h"
610
#include "vpr_types.h"
@@ -20,38 +24,63 @@
2024
# define ALWAYS_INLINE inline
2125
#endif
2226

23-
//Abstract interface to a placement delay model
27+
///@brief Forward declarations.
28+
class PlaceDelayModel;
29+
30+
///@brief Initialize the placer delay model.
31+
std::unique_ptr<PlaceDelayModel> alloc_lookups_and_delay_model(t_chan_width_dist chan_width_dist,
32+
const t_placer_opts& place_opts,
33+
const t_router_opts& router_opts,
34+
t_det_routing_arch* det_routing_arch,
35+
std::vector<t_segment_inf>& segment_inf,
36+
const t_direct_inf* directs,
37+
const int num_directs);
38+
39+
///@brief Returns the delay of one point to point connection.
40+
float comp_td_single_connection_delay(const PlaceDelayModel* delay_model, ClusterNetId net_id, int ipin);
41+
42+
///@brief Recompute all point to point delays, updating `connection_delay` matrix.
43+
void comp_td_connection_delays(const PlaceDelayModel* delay_model);
44+
45+
///@brief Abstract interface to a placement delay model.
2446
class PlaceDelayModel {
2547
public:
2648
virtual ~PlaceDelayModel() = default;
2749

28-
// Computes place delay model.
50+
///@brief Computes place delay model.
2951
virtual void compute(
3052
RouterDelayProfiler& route_profiler,
3153
const t_placer_opts& placer_opts,
3254
const t_router_opts& router_opts,
3355
int longest_length)
3456
= 0;
3557

36-
//Returns the delay estimate between the specified block pins
37-
//
38-
// Either compute or read methods must be invoked before invoking
39-
// delay.
58+
/**
59+
* @brief Returns the delay estimate between the specified block pins.
60+
*
61+
* Either compute or read methods must be invoked before invoking delay.
62+
*/
4063
virtual float delay(int from_x, int from_y, int from_pin, int to_x, int to_y, int to_pin) const = 0;
4164

42-
//Dumps the delay model to an echo file
65+
///@brief Dumps the delay model to an echo file.
4366
virtual void dump_echo(std::string filename) const = 0;
4467

45-
// Write place delay model to specified file.
46-
// May be unimplemented, in which case method should throw an exception.
68+
/**
69+
* @brief Write place delay model to specified file.
70+
*
71+
* May be unimplemented, in which case method should throw an exception.
72+
*/
4773
virtual void write(const std::string& file) const = 0;
4874

49-
// Read place delay model from specified file.
50-
// May be unimplemented, in which case method should throw an exception.
75+
/**
76+
* @brief Read place delay model from specified file.
77+
*
78+
* May be unimplemented, in which case method should throw an exception.
79+
*/
5180
virtual void read(const std::string& file) = 0;
5281
};
5382

54-
//A simple delay model based on the distance (delta) between block locations
83+
///@brief A simple delay model based on the distance (delta) between block locations.
5584
class DeltaDelayModel : public PlaceDelayModel {
5685
public:
5786
DeltaDelayModel() {}
@@ -109,10 +138,13 @@ class OverrideDelayModel : public PlaceDelayModel {
109138
short delta_x;
110139
short delta_y;
111140

112-
//A combination of ALWAYS_INLINE attribute and std::lexicographical_compare
113-
//is required for operator< to be inlined by compiler.
114-
//Proper inlining of the function reduces place time by around 5%.
115-
//For more information: https://github.com/verilog-to-routing/vtr-verilog-to-routing/issues/1225
141+
/**
142+
* A combination of ALWAYS_INLINE attribute and std::lexicographical_compare
143+
* is required for operator< to be inlined by compiler. Proper inlining of the
144+
* function reduces place time by around 5%.
145+
*
146+
* For more information: https://github.com/verilog-to-routing/vtr-verilog-to-routing/issues/1225
147+
*/
116148
friend ALWAYS_INLINE bool operator<(const t_override& lhs, const t_override& rhs) {
117149
const short* left = reinterpret_cast<const short*>(&lhs);
118150
const short* right = reinterpret_cast<const short*>(&rhs);
@@ -123,8 +155,11 @@ class OverrideDelayModel : public PlaceDelayModel {
123155

124156
vtr::flat_map2<t_override, float> delay_overrides_;
125157

126-
//operator< treats memory layout of t_override as an array of short
127-
//this requires all members of t_override are shorts and there is no padding between members of t_override
158+
/**
159+
* operator< treats memory layout of t_override as an array of short.
160+
* This requires all members of t_override are shorts and there is no
161+
* padding between members of t_override.
162+
*/
128163
static_assert(sizeof(t_override) == sizeof(t_override::from_type) + sizeof(t_override::to_type) + sizeof(t_override::from_class) + sizeof(t_override::to_class) + sizeof(t_override::delta_x) + sizeof(t_override::delta_y), "Expect t_override to have a memory layout equivalent to an array of short (no padding)");
129164
static_assert(sizeof(t_override::from_type) == sizeof(short), "Expect all t_override data members to be shorts");
130165
static_assert(sizeof(t_override::to_type) == sizeof(short), "Expect all t_override data members to be shorts");
@@ -133,5 +168,3 @@ class OverrideDelayModel : public PlaceDelayModel {
133168
static_assert(sizeof(t_override::delta_x) == sizeof(short), "Expect all t_override data members to be shorts");
134169
static_assert(sizeof(t_override::delta_y) == sizeof(short), "Expect all t_override data members to be shorts");
135170
};
136-
137-
#endif

0 commit comments

Comments
 (0)