@@ -164,8 +164,8 @@ static vtr::vector<ClusterNetId, char> bb_updated_before;
164
164
*/
165
165
static ClbNetPinsMatrix<float > connection_delay; // Delays based on committed block positions
166
166
static ClbNetPinsMatrix<float > proposed_connection_delay; // Delays for proposed block positions (only
167
- // for connections effected by move, otherwise
168
- // INVALID_DELAY)
167
+ // for connections effected by move, otherwise
168
+ // INVALID_DELAY)
169
169
170
170
static ClbNetPinsMatrix<float > connection_setup_slack; // Setup slacks based on most recently updated timing graph
171
171
@@ -175,18 +175,18 @@ static ClbNetPinsMatrix<float> connection_setup_slack; //Setup slacks based on m
175
175
*/
176
176
static PlacerTimingCosts connection_timing_cost; // Costs of committed block positions
177
177
static ClbNetPinsMatrix<double > proposed_connection_timing_cost; // Costs for proposed block positions
178
- // (only for connection effected by
179
- // move, otherwise INVALID_DELAY)
178
+ // (only for connection effected by
179
+ // move, otherwise INVALID_DELAY)
180
180
181
181
/*
182
182
* Timing cost of nets (i.e. sum of criticality * delay for each net sink/connection).
183
183
* Index ranges: [0..cluster_ctx.clb_nlist.nets().size()-1]
184
184
*/
185
185
static vtr::vector<ClusterNetId, double > net_timing_cost; // Like connection_timing_cost, but summed
186
- // accross net pins. Used to allow more
187
- // efficient recalculation of timing cost
188
- // if only a sub-set of nets are changed
189
- // while maintaining numeric stability.
186
+ // accross net pins. Used to allow more
187
+ // efficient recalculation of timing cost
188
+ // if only a sub-set of nets are changed
189
+ // while maintaining numeric stability.
190
190
191
191
/* [0..cluster_ctx.clb_nlist.nets().size()-1]. Store the bounding box coordinates and the number of *
192
192
* blocks on each of a net's bounding box (to allow efficient updates), *
@@ -403,9 +403,9 @@ static void commit_td_cost(const t_pl_blocks_to_be_moved& blocks_affected);
403
403
404
404
static void revert_td_cost (const t_pl_blocks_to_be_moved& blocks_affected);
405
405
406
- static void invalidate_affected_connection_delays (const std::vector<ClusterPinId>& sink_pins_affected ,
407
- ClusteredPinTimingInvalidator* pin_tedges_invalidator,
408
- TimingInfo* timing_info);
406
+ static void invalidate_affected_connections (const t_pl_blocks_to_be_moved& blocks_affected ,
407
+ ClusteredPinTimingInvalidator* pin_tedges_invalidator,
408
+ TimingInfo* timing_info);
409
409
410
410
static bool driven_by_moved_block (const ClusterNetId net, const t_pl_blocks_to_be_moved& blocks_affected);
411
411
@@ -417,9 +417,6 @@ static double comp_td_connection_cost(const PlaceDelayModel* delay_mode, const P
417
417
static double sum_td_net_cost (ClusterNetId net);
418
418
static double sum_td_costs ();
419
419
420
- static void find_affected_sink_pins (const t_pl_blocks_to_be_moved& blocks_affected,
421
- std::vector<ClusterPinId>& sink_pins_affected);
422
-
423
420
static float analyze_setup_slack_cost (const PlacerSetupSlacks* setup_slacks);
424
421
425
422
static e_move_result assess_swap (double delta_c, double t);
@@ -690,9 +687,9 @@ void try_place(const t_placer_opts& placer_opts,
690
687
prev_inverse_costs.timing_cost = 1 / costs.timing_cost ;
691
688
prev_inverse_costs.bb_cost = 1 / costs.bb_cost ;
692
689
costs.cost = 1 ; /* our new cost function uses normalized values of */
693
- /* bb_cost and timing_cost, the value of cost will be reset */
694
- /* to 1 at each temperature when *_TIMING_DRIVEN_PLACE is true */
695
- } else { /* BOUNDING_BOX_PLACE */
690
+ /* bb_cost and timing_cost, the value of cost will be reset */
691
+ /* to 1 at each temperature when *_TIMING_DRIVEN_PLACE is true */
692
+ } else { /* BOUNDING_BOX_PLACE */
696
693
costs.cost = costs.bb_cost = comp_bb_cost (NORMAL);
697
694
costs.timing_cost = 0 ;
698
695
outer_crit_iter_count = 0 ;
@@ -1647,22 +1644,16 @@ static e_move_result try_swap(float t,
1647
1644
bb_delta_c,
1648
1645
timing_delta_c);
1649
1646
1650
- // Find all the sink pins with changed connection delays from the affected blocks.
1651
- // These sink pins will be passed into the pin_timing_invalidator for timing update.
1652
- // They will also be added to the pin invalidator when we wish to revert a timing update.
1653
- std::vector<ClusterPinId> sink_pins_affected;
1654
- find_affected_sink_pins (blocks_affected, sink_pins_affected);
1655
-
1656
1647
// For setup slack analysis, we first do a timing analysis to get the newest slack values
1657
1648
// resulted from the proposed block moves. If the move turns out to be accepted, we keep
1658
1649
// the updated slack values and commit the block moves. If rejected, we reject the proposed
1659
1650
// block moves and revert this timing analysis.
1660
1651
if (place_algorithm == SLACK_TIMING_PLACE) {
1661
1652
// Gather all the connections with modified delays for incremental timing updates.
1662
1653
// This routine relies on comparing proposed_connection_delay and connection_delay.
1663
- invalidate_affected_connection_delays (sink_pins_affected ,
1664
- pin_timing_invalidator,
1665
- timing_info);
1654
+ invalidate_affected_connections (blocks_affected ,
1655
+ pin_timing_invalidator,
1656
+ timing_info);
1666
1657
1667
1658
// Update the connection_timing_cost and connection_delay
1668
1659
// values from the temporary values.
@@ -1723,9 +1714,9 @@ static e_move_result try_swap(float t,
1723
1714
// This routine relies on comparing proposed_connection_delay and connection_delay
1724
1715
// If the setup slack analysis was not performed, the
1725
1716
// sink pins are yet to be invalidated.
1726
- invalidate_affected_connection_delays (sink_pins_affected ,
1727
- pin_timing_invalidator,
1728
- timing_info);
1717
+ invalidate_affected_connections (blocks_affected ,
1718
+ pin_timing_invalidator,
1719
+ timing_info);
1729
1720
1730
1721
// update the connection_timing_cost and connection_delay
1731
1722
// values from the temporary values
@@ -1756,9 +1747,9 @@ static e_move_result try_swap(float t,
1756
1747
// Re-invalidate the affected sink pins since the proposed move is
1757
1748
// rejected, and the same blocks are reverted to their original
1758
1749
// positions. The affected sink pins should stay the same.
1759
- invalidate_affected_connection_delays (sink_pins_affected ,
1760
- pin_timing_invalidator,
1761
- timing_info);
1750
+ invalidate_affected_connections (blocks_affected ,
1751
+ pin_timing_invalidator,
1752
+ timing_info);
1762
1753
1763
1754
/* Revert the timing update */
1764
1755
update_timing_classes (crit_exponent,
@@ -1845,7 +1836,7 @@ static int find_affected_nets_and_update_costs(const t_place_algorithm& place_al
1845
1836
update_net_bb (net_id, blocks_affected, iblk, blk, blk_pin);
1846
1837
1847
1838
if (place_algorithm.is_timing_driven ()) {
1848
- // Determine the change in timing costs if required
1839
+ /* Determine the change in connection delay and timing cost */
1849
1840
update_td_delta_costs (delay_model, *criticalities, net_id, blk_pin, blocks_affected, timing_delta_c);
1850
1841
}
1851
1842
}
@@ -1907,6 +1898,35 @@ static void update_net_bb(const ClusterNetId net,
1907
1898
}
1908
1899
}
1909
1900
1901
+ /* *
1902
+ * @brief Calculate the new connection delay and timing cost of all the
1903
+ * sink pins affected by moving a specific pin to a new location.
1904
+ * Also calculates the total change in the timing cost.
1905
+ *
1906
+ * Assumes that the blocks have been moved to the proposed new locations.
1907
+ * Otherwise, the routine comp_td_connection_delay() will not be able to
1908
+ * calculate the most up to date connection delay estimation value.
1909
+ *
1910
+ * If the moved pin is a driver pin, then all the sink connections that are
1911
+ * driven by this driver pin are considered.
1912
+ *
1913
+ * If the moved pin is a sink pin, then it is the only pin considered. But
1914
+ * in some cases, the sink is already accounted for if it is also driven
1915
+ * by a driver pin located on a moved block. Computing it again would double
1916
+ * count its affect on the total timing cost change (delta_timing_cost).
1917
+ *
1918
+ * It is possible for some connections to have unchanged delays. For instance,
1919
+ * if we are using a dx/dy delay model, this could occur if a sink pin moved
1920
+ * to a new position with the same dx/dy from its net's driver pin.
1921
+ *
1922
+ * We skip these connections with unchanged delay values as their delay need
1923
+ * not be updated. Their timing costs also do not require any update, since
1924
+ * the criticalities values are always kept stale/unchanged during an block
1925
+ * swap attempt. (Unchanged Delay * Unchanged Criticality = Unchanged Cost)
1926
+ *
1927
+ * This is also done to minimize the number of timing node/edge invalidations
1928
+ * for incremental static timing analysis (incremental STA).
1929
+ */
1910
1930
static void update_td_delta_costs (const PlaceDelayModel* delay_model,
1911
1931
const PlacerCriticalities& criticalities,
1912
1932
const ClusterNetId net,
@@ -1916,69 +1936,50 @@ static void update_td_delta_costs(const PlaceDelayModel* delay_model,
1916
1936
auto & cluster_ctx = g_vpr_ctx.clustering ();
1917
1937
1918
1938
if (cluster_ctx.clb_nlist .pin_type (pin) == PinType::DRIVER) {
1919
- // This pin is a net driver on a moved block.
1920
- // Re-compute all point to point connections for this net.
1939
+ /* This pin is a net driver on a moved block. */
1940
+ /* Recompute all point to point connection delays for the net sinks. */
1921
1941
for (size_t ipin = 1 ; ipin < cluster_ctx.clb_nlist .net_pins (net).size (); ipin++) {
1922
1942
float temp_delay = comp_td_connection_delay (delay_model, net, ipin);
1923
- proposed_connection_delay[net][ipin] = temp_delay;
1943
+ /* If the delay hasn't changed, do not mark this pin as affected */
1944
+ if (temp_delay == connection_delay[net][ipin]) {
1945
+ continue ;
1946
+ }
1924
1947
1948
+ /* Calculate proposed delay and cost values */
1949
+ proposed_connection_delay[net][ipin] = temp_delay;
1925
1950
proposed_connection_timing_cost[net][ipin] = criticalities.criticality (net, ipin) * temp_delay;
1926
1951
delta_timing_cost += proposed_connection_timing_cost[net][ipin] - connection_timing_cost[net][ipin];
1927
1952
1953
+ /* Record this connection in blocks_affected.affected_pins */
1928
1954
ClusterPinId sink_pin = cluster_ctx.clb_nlist .net_pin (net, ipin);
1929
1955
blocks_affected.affected_pins .push_back (sink_pin);
1930
1956
}
1931
1957
} else {
1932
- // This pin is a net sink on a moved block
1958
+ /* This pin is a net sink on a moved block */
1933
1959
VTR_ASSERT_SAFE (cluster_ctx.clb_nlist .pin_type (pin) == PinType::SINK);
1934
1960
1935
- // If this net is being driven by a moved block, we do not
1936
- // need to compute the change in the timing cost (here) since it will
1937
- // be computed by the net's driver pin (since the driver block moved).
1938
- //
1939
- // Computing it here would double count the change, and mess up the
1940
- // delta_timing_cost value.
1961
+ /* Check if this sink's net is driven by a moved block */
1941
1962
if (!driven_by_moved_block (net, blocks_affected)) {
1942
- int net_pin = cluster_ctx.clb_nlist .pin_net_index (pin);
1963
+ /* Get the sink pin index in the net */
1964
+ int ipin = cluster_ctx.clb_nlist .pin_net_index (pin);
1943
1965
1944
- float temp_delay = comp_td_connection_delay (delay_model, net, net_pin);
1945
- proposed_connection_delay[net][net_pin] = temp_delay;
1966
+ float temp_delay = comp_td_connection_delay (delay_model, net, ipin);
1967
+ /* If the delay hasn't changed, do not mark this pin as affected */
1968
+ if (temp_delay == connection_delay[net][ipin]) {
1969
+ return ;
1970
+ }
1946
1971
1947
- proposed_connection_timing_cost[net][net_pin] = criticalities.criticality (net, net_pin) * temp_delay;
1948
- delta_timing_cost += proposed_connection_timing_cost[net][net_pin] - connection_timing_cost[net][net_pin];
1972
+ /* Calculate proposed delay and cost values */
1973
+ proposed_connection_delay[net][ipin] = temp_delay;
1974
+ proposed_connection_timing_cost[net][ipin] = criticalities.criticality (net, ipin) * temp_delay;
1975
+ delta_timing_cost += proposed_connection_timing_cost[net][ipin] - connection_timing_cost[net][ipin];
1949
1976
1977
+ /* Record this connection in blocks_affected.affected_pins */
1950
1978
blocks_affected.affected_pins .push_back (pin);
1951
1979
}
1952
1980
}
1953
1981
}
1954
1982
1955
- /* *
1956
- * @brief Find all the sink pins with changed connection delays from the affected blocks.
1957
- *
1958
- * These sink pins will be passed into the pin_timing_invalidator for timing update.
1959
- * They will also be added to the pin invalidator when we wish to revert a timing update.
1960
- *
1961
- * It is possible that some connections may not have changed delay. For instance, if
1962
- * using a dx/dy delay model, this could occur if a sink moved to a new position with
1963
- * the same dx/dy from it's driver. To minimize work during the incremental STA update
1964
- * we do not invalidate such unchanged connections.
1965
- */
1966
- static void find_affected_sink_pins (const t_pl_blocks_to_be_moved& blocks_affected,
1967
- std::vector<ClusterPinId>& sink_pins_affected) {
1968
- auto & cluster_ctx = g_vpr_ctx.clustering ();
1969
- auto & clb_nlist = cluster_ctx.clb_nlist ;
1970
-
1971
- for (ClusterPinId clb_pin : blocks_affected.affected_pins ) {
1972
- ClusterNetId net = clb_nlist.pin_net (clb_pin);
1973
- int ipin = clb_nlist.pin_net_index (clb_pin);
1974
-
1975
- if (proposed_connection_delay[net][ipin] != connection_delay[net][ipin]) {
1976
- // Delay has changed. Must invalidate this sink pin.
1977
- sink_pins_affected.push_back (clb_pin);
1978
- }
1979
- }
1980
- }
1981
-
1982
1983
/* *
1983
1984
* @brief Check if the setup slack has gotten better or worse due to block swap.
1984
1985
*
@@ -2233,23 +2234,23 @@ static void revert_td_cost(const t_pl_blocks_to_be_moved& blocks_affected) {
2233
2234
}
2234
2235
2235
2236
/* *
2236
- * @brief Invalidates the delays of connections effected by the specified move .
2237
+ * @brief Invalidates the connections affected by the specified block moves .
2237
2238
*
2238
- * Relies on find_affected_sink_pins() to find all the connections with different
2239
- * `proposed_connection_delay` and `connection_delay`.
2239
+ * All the connections recorded in blocks_affected.affected_pins have different
2240
+ * values for `proposed_connection_delay` and `connection_delay`.
2240
2241
*
2241
- * Invalidate all the timing graph edges associated with these sink pins via the
2242
- * ClusteredPinTimingInvalidator class.
2242
+ * Invalidate all the timing graph edges associated with these connections via
2243
+ * the ClusteredPinTimingInvalidator class.
2243
2244
*/
2244
- static void invalidate_affected_connection_delays (const std::vector<ClusterPinId>& sink_pins_affected ,
2245
- ClusteredPinTimingInvalidator* pin_tedges_invalidator,
2246
- TimingInfo* timing_info) {
2245
+ static void invalidate_affected_connections (const t_pl_blocks_to_be_moved& blocks_affected ,
2246
+ ClusteredPinTimingInvalidator* pin_tedges_invalidator,
2247
+ TimingInfo* timing_info) {
2247
2248
VTR_ASSERT_SAFE (timing_info);
2248
2249
VTR_ASSERT_SAFE (pin_tedges_invalidator);
2249
2250
2250
- // Invalidate timing graph edges affected by the move
2251
- for (ClusterPinId clb_pin : sink_pins_affected ) {
2252
- pin_tedges_invalidator->invalidate_connection (clb_pin , timing_info);
2251
+ /* Invalidate timing graph edges affected by the move */
2252
+ for (ClusterPinId pin : blocks_affected. affected_pins ) {
2253
+ pin_tedges_invalidator->invalidate_connection (pin , timing_info);
2253
2254
}
2254
2255
}
2255
2256
0 commit comments