blob: a8b93f98dbdf03773100e1da70353901321251e2 [file] [log] [blame]
#include "profile_lookahead.h"
using namespace std;
void print_start_end_to_sink(bool is_start, int itry, int inet, int target_node, int itarget) {
if (itry == DB_ITRY && target_node == DB_TARGET_NODE){
if (is_start) {
printf("\n**** itry %d\tSTART ROUTE TO net %d\ttarget %d\tinode %d\n",
itry, inet, itarget, target_node);
printf("COORD: (%d,%d)\n", rr_node[target_node].get_xlow(), rr_node[target_node].get_ylow());
} else {
printf("\n**** itry %d\tFINISH ROUTE TO net %d\ttarget %d\tinode %d\n\n",
itry, inet, itarget, target_node);
}
}
}
void print_expand_neighbours(bool is_parent, int inode, int target_node,
int target_chan_type, int target_pin_x, int target_pin_y,
float expected_cost, float future_Tdel, float new_tot_cost,
float cur_basecost, float cong_cost) {
if (itry_share == DB_ITRY && target_node == DB_TARGET_NODE) {
const char *dir_name[] = {"INC", "DEC", NULL};
const char *node_seg_type[] = {"source", "sink", "ipin", "opin", "chanX", "chanY", NULL};
int dir = (rr_node[inode].get_direction() == INC_DIRECTION) ? 0 : 1;
int inode_type = rr_node[inode].type;
int inode_seg_index = rr_indexed_data[rr_node[inode].get_cost_index()].seg_index;
float basecost, C, Tdel;
int s_x, s_y, e_x, e_y, len;
get_unidir_seg_start(inode, &s_x, &s_y);
get_unidir_seg_end(inode, &e_x, &e_y);
len = rr_node[inode].get_len();
if (is_parent) {
if (target_chan_type == UNDEFINED) {
printf("TARGET CHAN TYPE UNDEFINED\n");
} else {
printf("TARGET CHAN TYPE: %d\tX %d\tY %d\n", target_chan_type, target_pin_x, target_pin_y);
}
Tdel = get_timing_driven_future_Tdel(inode, target_node, &C, &basecost);
printf("EXPAND inode %d(L%d)\t%s\t%s-%d\t(%d,%d)\t(%d,%d)\tpath cost %.3f\texp cost %.3f\n",
inode, len, dir_name[dir], node_seg_type[inode_type],
inode_seg_index, s_x, s_y, e_x, e_y,
rr_node_route_inf[inode].path_cost * pow(10, 10),
Tdel * pow(10, 10) );
} else {
printf("\texpand %d(L%d)\t%s\t%s-%d\t(%d,%d)\t(%d,%d)\t",
inode, len, dir_name[dir], node_seg_type[inode_type],
inode_seg_index, s_x, s_y, e_x, e_y);
printf("exp cost %.3f\tb-Tdel %.3f\ttot cost %.3f\tbCost %.3fcCost %.3f\n",
expected_cost * pow(10, 10), future_Tdel * pow(10, 10),
new_tot_cost * pow(10, 10), cur_basecost * pow(10, 10),
cong_cost * pow(10, 10));
}
}
}
void setup_max_min_criticality(float &max_crit, float &min_crit,
int &max_inet, int &min_inet, int &max_ipin, int &min_ipin, t_slack * slacks) {
/*
* set up max/min criticality && where the max/min happens
* called in try_timing_driven_route()
*/
float max_crit_len_product = -1;
float min_crit_len_product = pow(10, 20);
max_crit = -1;
min_crit = pow(10, 20);
max_inet = -1;
max_ipin = -1;
min_inet = -1;
min_ipin = -1;
for (unsigned int inet = 0; inet < g_clbs_nlist.net.size(); ++inet) {
if (should_route_net(inet) == false)
continue;
if (g_clbs_nlist.net[inet].is_global == true)
continue;
if (g_clbs_nlist.net[inet].is_fixed == true)
continue;
int source_inode = net_rr_terminals[inet][0];
int x_source_mid = (rr_node[source_inode].get_xhigh() + rr_node[source_inode].get_xlow()) / 2;
int y_source_mid = (rr_node[source_inode].get_yhigh() + rr_node[source_inode].get_ylow()) / 2;
unsigned int pin_upbound = (g_clbs_nlist.net[inet].pins.size() > 2) ? 2 : g_clbs_nlist.net[inet].pins.size();
for (unsigned int ipin = 1; ipin < pin_upbound; ipin++) {
float pin_criticality = slacks->timing_criticality[inet][ipin];
int target_inode = net_rr_terminals[inet][ipin];
int x_target_mid = (rr_node[target_inode].get_xhigh() + rr_node[target_inode].get_xlow()) / 2;
int y_target_mid = (rr_node[target_inode].get_yhigh() + rr_node[target_inode].get_ylow()) / 2;
// print long nets only
int bb_len = abs(x_source_mid - x_target_mid + 1) + abs(y_source_mid - y_target_mid + 1);
float len_crit_product = bb_len * pin_criticality;
float len_inv_crit_product = (1./bb_len) * pin_criticality;
max_inet = (len_crit_product > max_crit_len_product) ? inet : max_inet;
max_ipin = (len_crit_product > max_crit_len_product) ? ipin : max_ipin;
min_inet = (len_inv_crit_product < min_crit_len_product) ? inet : min_inet;
min_ipin = (len_inv_crit_product < min_crit_len_product) ? ipin : min_ipin;
max_crit = (len_crit_product > max_crit_len_product) ? pin_criticality : max_crit;
min_crit = (len_inv_crit_product < min_crit_len_product) ? pin_criticality : min_crit;
max_crit_len_product = (len_crit_product > max_crit_len_product) ? len_crit_product : max_crit_len_product;
min_crit_len_product = (len_inv_crit_product < min_crit_len_product) ? len_inv_crit_product : min_crit_len_product;
}
}
//printf("max_inet %d\tmax_ipin %d\tmin_inet %d\tmin_ipin %d\n", max_inet, max_ipin, min_inet, min_ipin);
//printf("max_crit_len_product %f\tmin_crit %f\n", max_crit_len_product, min_crit);
//printf("\n");
}
void print_critical_path_from_rt(struct s_heap *hptr, float target_criticality, int new_nodes_count, float actual_Tdel) {
int target_node = hptr->index;
if (target_node == DB_TARGET_NODE && itry_share == DB_ITRY) {
int inode = hptr->u.prev_node;
printf("CRITICAL PATH %d: back trace start\tcrit: %fNEW NODES %d\n", target_node, target_criticality, new_nodes_count);
while (rr_node_route_inf[inode].prev_node != NO_PREVIOUS) {
// this is backtrace, so print in anti-direction order
int ix_s, ix_e, iy_s, iy_e;
get_unidir_seg_end(inode, &ix_s, &iy_s);
get_unidir_seg_start(inode, &ix_e, &iy_e);
int prev_inode = rr_node_route_inf[inode].prev_node;
float bTdel = rr_node_route_inf[inode].back_Tdel;
float bbTdel = rr_node_route_inf[prev_inode].back_Tdel;
int wire_type = rr_indexed_data[rr_node[inode].get_cost_index()].seg_index;
float dummy, basecost = 0;
printf("\tid:%d - %d\tstart(%d,%d)\tend(%d,%d)\tbackTdel:%einodeTdel:%e\tactual future Tdel:%.3f\test future Tdel:%.3f\n",
inode, wire_type, ix_s, iy_s, ix_e, iy_e,
bTdel, (bTdel - bbTdel),
(actual_Tdel - bTdel) * pow(10, 10),
get_timing_driven_future_Tdel(inode, target_node, &dummy, &basecost) * pow(10, 10));
inode = prev_inode;
}
}
}
void setup_new_lookahead_dev(int furthest_wire_inode, int target_node, float total_Tdel, int new_nodes_count) {
/*
float estimated_future_cost = rr_node_route_inf[inode].path_cost
- rr_node_route_inf[inode].backward_path_cost;
float actual_future_cost = actual_tot_cost
- rr_node_route_inf[inode].backward_path_cost;
*/
float new_nodes_dev = 0.;
float estimated_future_cost, actual_future_cost;
float c_downstream, basecost;
estimated_future_cost = get_timing_driven_future_Tdel(furthest_wire_inode, target_node, &c_downstream, &basecost);
actual_future_cost = total_Tdel - rr_node_route_inf[furthest_wire_inode].back_Tdel;
if (subtree_count.count(new_nodes_count) <= 0) {
subtree_count[new_nodes_count] = 0;
subtree_size_avg[new_nodes_count] = 0;
subtree_est_dev_avg[new_nodes_count] = 0;
}
if (actual_future_cost != 0) {
new_nodes_dev = (estimated_future_cost / actual_future_cost - 1);
}
subtree_count[new_nodes_count] ++;
int tree_counter = subtree_count[new_nodes_count];
// running avg: geo mean for subtree size; arithmetic mean for dev
if (subtree_size_avg[new_nodes_count] == 0) {
subtree_size_avg[new_nodes_count] = subtree_size_avg[0];
} else {
float temp = pow(subtree_size_avg[new_nodes_count], (tree_counter - 1) / (float)tree_counter);
subtree_size_avg[new_nodes_count] = temp * pow(subtree_size_avg[0], 1.0/(float)tree_counter);
}
if (target_node == DB_TARGET_NODE) {
print_db_node_inf(DB_TARGET_NODE);
}
float cur_dev = new_nodes_dev;
if (cur_dev < -0.6 && new_nodes_count > 10)
printf("\nXXXXX TARGET NODE %d\n\n", target_node);
subtree_est_dev_avg[new_nodes_count] = ((tree_counter - 1) * subtree_est_dev_avg[new_nodes_count]
+ cur_dev) / (float)tree_counter;
}