@@ -498,6 +498,9 @@ void QPHybridSolver::store_solution_into_placement(const Eigen::VectorXd& x_soln
498
498
void QPHybridSolver::update_net_weights (const PreClusterTimingManager& pre_cluster_timing_manager) {
499
499
// For the quadratic solver, we use a basic net weighting scheme for adding
500
500
// timing to the objective.
501
+ //
502
+ // NOTE: This is only for the quadratic solver, other solvers (like B2B) will
503
+ // likely set these weights to something else.
501
504
502
505
// If the pre-cluster timing manager has not been initialized (i.e. timing
503
506
// analysis is off), no need to update.
@@ -977,13 +980,9 @@ std::pair<double, double> B2BSolver::get_delay_derivative(APBlockId driver_blk,
977
980
// the derivative to be the penalty for putting the driver and sink in different
978
981
// tiles.
979
982
if (tile_dx == 0 ) {
980
- VTR_ASSERT_SAFE_MSG (forward_difference_x == -1 .0f * backward_difference_x,
981
- " Delay model expected to be symmetric" );
982
983
d_delay_x = forward_difference_x;
983
984
}
984
985
if (tile_dy == 0 ) {
985
- VTR_ASSERT_SAFE_MSG (forward_difference_y == -1 .0f * backward_difference_y,
986
- " Delay model expected to be symmetric" );
987
986
d_delay_y = forward_difference_y;
988
987
}
989
988
@@ -996,7 +995,7 @@ std::pair<double, double> B2BSolver::get_delay_normalization_facs(APBlockId driv
996
995
// tile. This should be able to remove the units without changing the value
997
996
// too much.
998
997
999
- // Similar to calcuting the derivative, we want to use the legalized position
998
+ // Similar to calculating the derivative, we want to use the legalized position
1000
999
// of the driver block to try and estimate the delay from that block type.
1001
1000
t_physical_tile_loc driver_block_loc (block_x_locs_legalized[driver_blk],
1002
1001
block_y_locs_legalized[driver_blk],
@@ -1053,6 +1052,8 @@ void B2BSolver::init_linear_system(PartialPlacement& p_placement, unsigned itera
1053
1052
// ====================================================================
1054
1053
// Wirelength Connections
1055
1054
// ====================================================================
1055
+ // In the objective there is are wirelength connections and timing
1056
+ // connections, trade-off between the weight of each type of connection.
1056
1057
double wl_net_w = (1 .0f - ap_timing_tradeoff_) * net_weights_[net_id];
1057
1058
1058
1059
// Find the bounding blocks
@@ -1087,15 +1088,13 @@ void B2BSolver::init_linear_system(PartialPlacement& p_placement, unsigned itera
1087
1088
// positions to compute the delay derivative, which do not exist until
1088
1089
// the next iteration. Its fine to do one wirelength driven iteration first.
1089
1090
if (pre_cluster_timing_manager_.is_valid () && iteration != 0 ) {
1090
- // Create connections from each driver pin to each of its sink pins.
1091
+ // Create connections from each driver pin to each of it's sink pins.
1091
1092
// This will incentivize shrinking the distance from drivers to sinks
1092
1093
// of connections which would improve the timing.
1093
1094
APPinId driver_pin = netlist_.net_driver (net_id);
1094
1095
APBlockId driver_blk = netlist_.pin_block (driver_pin);
1095
- for (APPinId net_pin : netlist_.net_pins (net_id)) {
1096
- if (net_pin == driver_pin)
1097
- continue ;
1098
- APBlockId sink_blk = netlist_.pin_block (net_pin);
1096
+ for (APPinId sink_pin : netlist_.net_sinks (net_id)) {
1097
+ APBlockId sink_blk = netlist_.pin_block (sink_pin);
1099
1098
1100
1099
// Get the instantaneous derivative of delay at the given distance
1101
1100
// from driver to sink. This will provide a value which is higher
@@ -1113,26 +1112,27 @@ void B2BSolver::init_linear_system(PartialPlacement& p_placement, unsigned itera
1113
1112
// TODO: If this is negative, it means that the sink should try to move
1114
1113
// away from the driver. Perhaps add an anchor point to pull the
1115
1114
// sink away.
1116
- if (d_delay_x < 0 )
1117
- d_delay_x = 0 ;
1118
- if (d_delay_y < 0 )
1119
- d_delay_y = 0 ;
1115
+ d_delay_x = std::max (d_delay_x, 0.0 );
1116
+ d_delay_y = std::max (d_delay_y, 0.0 );
1120
1117
1121
- // The units for delay is in seconds; however the units for
1122
- // the wirelength term is in tile . To ensure the units match,
1118
+ // The units for delay are in seconds; however the units for
1119
+ // the wirelength term are in tiles . To ensure the units match,
1123
1120
// we need to normalize away the time units. Get normalization
1124
1121
// factors to remove the time units.
1125
1122
auto [delay_x_norm, delay_y_norm] = get_delay_normalization_facs (driver_blk);
1126
1123
1127
1124
// Get the criticality of this timing edge from driver to sink.
1128
- double crit = pre_cluster_timing_manager_.get_timing_info ().setup_pin_criticality (netlist_.pin_atom_pin (net_pin ));
1125
+ double crit = pre_cluster_timing_manager_.get_timing_info ().setup_pin_criticality (netlist_.pin_atom_pin (sink_pin ));
1129
1126
1130
1127
// Set the weight of the connection from driver to sink equal to:
1131
1128
// weight_tradeoff_terms * (1 + crit) * d_delay * delay_norm
1132
1129
// The intuition is that we want the solver to shrink the distance
1133
1130
// from drivers to sinks (which would improve timing) for edges
1134
1131
// with the best tradeoff between delay and wire, with a focus
1135
1132
// on the more critical edges.
1133
+ // The ap_timing_tradeoff serves to trade-off between the wirelength
1134
+ // and timing net weights. The net weights are the general net weights
1135
+ // based on prior knowledge about the nets.
1136
1136
double timing_net_w = ap_timing_tradeoff_ * net_weights_[net_id] * timing_slope_fac_ * (1.0 + crit);
1137
1137
1138
1138
add_connection_to_system (driver_blk, sink_blk,
0 commit comments