Further RCV optimizations: cap min budget below max budget | no longer incrementing total path delay between budget iterations | set target delay equal to min delay | allow a higher iteration number to run (20 vs 7) and a smaller stopping condition (1e-12 vs 800e-12)
diff --git a/vpr/src/route/route_budgets.cpp b/vpr/src/route/route_budgets.cpp
index 92ea8f6..dafda27 100644
--- a/vpr/src/route/route_budgets.cpp
+++ b/vpr/src/route/route_budgets.cpp
@@ -139,6 +139,10 @@
/*Delay target values are calculated based on the function outlined in the RCV algorithm*/
for (auto net_id : cluster_ctx.clb_nlist.nets()) {
for (auto pin_id : cluster_ctx.clb_nlist.net_sinks(net_id)) {
+ int ipin = cluster_ctx.clb_nlist.pin_net_index(pin_id);
+ //cap max budget to be bigger or equal than min budget
+ if (delay_max_budget[net_id][ipin] < delay_min_budget[net_id][ipin])
+ delay_max_budget[net_id][ipin] = delay_min_budget[net_id][ipin];
calculate_delay_targets(net_id, pin_id);
}
}
@@ -149,7 +153,10 @@
int ipin = cluster_ctx.clb_nlist.pin_net_index(pin_id);
/*Target delay is calculated using equation in the RCV algorithm*/
- delay_target[net_id][ipin] = min(0.5 * (delay_min_budget[net_id][ipin] + delay_max_budget[net_id][ipin]), delay_min_budget[net_id][ipin] + 0.1e-9);
+ //delay_target[net_id][ipin] = min(0.5 * (delay_min_budget[net_id][ipin] + delay_max_budget[net_id][ipin]), delay_min_budget[net_id][ipin] + 0.1e-9);
+
+ //set min budget delay to be delay_target for now. Guardband can be added later
+ delay_target[net_id][ipin] = delay_min_budget[net_id][ipin];
}
void route_budgets::allocate_slack_using_weights(vtr::vector_map<ClusterNetId, float *> &net_delay, const ClusteredPinAtomPinsLookup& netlist_pin_lookup) {
@@ -159,6 +166,8 @@
* Weights here are defined as the delay for the connections
* Values for conditions in the while loops are pulled from the RCV paper*/
std::shared_ptr<SetupHoldTimingInfo> timing_info = nullptr;
+ //this is used to calculate total path delay -> to make sure it doesn't get incremented every iteration
+ std::shared_ptr<SetupHoldTimingInfo> orig_timing_info = nullptr;
unsigned iteration;
float max_budget_change;
@@ -170,13 +179,16 @@
iteration = 0;
max_budget_change = 900e-12;
- /*This allocates long path slack and increases the budgets*/
- while ((iteration > 3 && max_budget_change > 800e-12) || iteration <= 3) {
+ //pass in original timing_info to use for total path delay calculations. This ensures the same total path delay is used throughout the RCV iterations.
+ orig_timing_info = perform_sta (delay_max_budget);
+
+ /*This allocates long path slack and increases the budgets. Stopping conditions are set differently from RCV paper because they showed better results*/
+ while ((iteration > 3 && max_budget_change > 1e-12) || iteration <= 3) {
timing_info = perform_sta(delay_max_budget);
- max_budget_change = minimax_PERT(timing_info, delay_max_budget, net_delay, netlist_pin_lookup, SETUP, true);
+ max_budget_change = minimax_PERT(orig_timing_info, timing_info, delay_max_budget, net_delay, netlist_pin_lookup, SETUP, true);
iteration++;
- if (iteration > 7)
+ if (iteration > 10)
break;
}
@@ -187,12 +199,12 @@
max_budget_change = 900e-12;
/*Allocate the short path slack to decrease the budgets accordingly*/
- while ((iteration > 3 && max_budget_change > 800e-12) || iteration <= 3) {
+ while ((iteration > 3 && max_budget_change > 1e-12) || iteration <= 3) {
timing_info = perform_sta(delay_min_budget);
- max_budget_change = minimax_PERT(timing_info, delay_min_budget, net_delay, netlist_pin_lookup, HOLD, true);
+ max_budget_change = minimax_PERT(orig_timing_info, timing_info, delay_min_budget, net_delay, netlist_pin_lookup, HOLD, true);
iteration++;
- if (iteration > 7)
+ if (iteration > 10)
break;
}
@@ -208,7 +220,7 @@
keep_budget_in_bounds(delay_min_budget);
}
timing_info = perform_sta(delay_min_budget);
- max_budget_change = minimax_PERT(timing_info, delay_min_budget, net_delay, netlist_pin_lookup, HOLD, false);
+ max_budget_change = minimax_PERT(orig_timing_info, timing_info, delay_min_budget, net_delay, netlist_pin_lookup, HOLD, false);
iteration++;
}
/*budgets may go below minimum delay bound to optimize for setup time*/
@@ -223,6 +235,8 @@
unsigned iteration;
float max_budget_change;
std::shared_ptr<SetupHoldTimingInfo> timing_info = nullptr;
+ std::shared_ptr<SetupHoldTimingInfo> orig_timing_info = nullptr;
+ orig_timing_info = perform_sta (delay_max_budget);
iteration = 0;
max_budget_change = 900e-12;
@@ -230,10 +244,10 @@
while (iteration < 7 && max_budget_change > 5e-12) {
timing_info = perform_sta(delay_max_budget);
- max_budget_change = minimax_PERT(timing_info, delay_max_budget, net_delay, netlist_pin_lookup, HOLD, true, NEGATIVE);
+ max_budget_change = minimax_PERT(orig_timing_info, timing_info, delay_max_budget, net_delay, netlist_pin_lookup, HOLD, true, NEGATIVE);
timing_info = perform_sta(delay_max_budget);
- second_max_budget_change = minimax_PERT(timing_info, delay_max_budget, net_delay, netlist_pin_lookup, SETUP, true, NEGATIVE);
+ second_max_budget_change = minimax_PERT(orig_timing_info, timing_info, delay_max_budget, net_delay, netlist_pin_lookup, SETUP, true, NEGATIVE);
max_budget_change = max(max_budget_change, second_max_budget_change);
iteration++;
@@ -294,7 +308,7 @@
}
}
-float route_budgets::minimax_PERT(std::shared_ptr<SetupHoldTimingInfo> timing_info, vtr::vector_map<ClusterNetId, float *> &temp_budgets,
+float route_budgets::minimax_PERT(std::shared_ptr<SetupHoldTimingInfo> orig_timing_info, std::shared_ptr<SetupHoldTimingInfo> timing_info, vtr::vector_map<ClusterNetId, float *> &temp_budgets,
vtr::vector_map<ClusterNetId, float *> &net_delay, const ClusteredPinAtomPinsLookup& netlist_pin_lookup, analysis_type analysis_type,
bool keep_in_bounds, slack_allocated_type slack_type) {
/*This function uses weights to calculate how much slack to allocate to a connection.
@@ -302,8 +316,9 @@
auto& cluster_ctx = g_vpr_ctx.clustering();
auto& atom_ctx = g_vpr_ctx.atom();
-
- std::shared_ptr<const tatum::SetupHoldTimingAnalyzer> timing_analyzer = timing_info->setup_hold_analyzer();
+
+ //this is used to calculate the total path delay. Using orig_timing_info so that total path delay is not incremented every iteration.
+ std::shared_ptr<const tatum::SetupHoldTimingAnalyzer> timing_analyzer = orig_timing_info->setup_hold_analyzer();
float total_path_delay = 0;
float path_slack;
float max_budget_change = 0;
@@ -691,3 +706,4 @@
/*Returns if the budgets have been loaded yet*/
return set;
}
+
diff --git a/vpr/src/route/route_budgets.h b/vpr/src/route/route_budgets.h
index ba2c4c7..2786062 100644
--- a/vpr/src/route/route_budgets.h
+++ b/vpr/src/route/route_budgets.h
@@ -60,7 +60,7 @@
void allocate_slack_using_weights(vtr::vector_map<ClusterNetId, float *> &net_delay, const ClusteredPinAtomPinsLookup& netlist_pin_lookup);
/*Sometimes want to allocate only positive or negative slack.
By default, allocate both*/
- float minimax_PERT(std::shared_ptr<SetupHoldTimingInfo> timing_info, vtr::vector_map<ClusterNetId, float *> &temp_budgets,
+ float minimax_PERT(std::shared_ptr<SetupHoldTimingInfo> orig_timing_info, std::shared_ptr<SetupHoldTimingInfo> timing_info, vtr::vector_map<ClusterNetId, float *> &temp_budgets,
vtr::vector_map<ClusterNetId, float *> &net_delay, const ClusteredPinAtomPinsLookup& netlist_pin_lookup, analysis_type analysis_type,
bool keep_in_bounds, slack_allocated_type slack_type = BOTH);
void process_negative_slack_using_minimax(vtr::vector_map<ClusterNetId, float *> &net_delay, const ClusteredPinAtomPinsLookup& netlist_pin_lookup);
@@ -114,3 +114,4 @@
#endif /* ROUTE_BUDGETS_H */
+