/* * convert slicing tree into actual floorplan * returns the number of dead blocks compacted */ int tree_to_flp(tree_node_t *root, flp_t *flp, int compact_dead, double compact_ratio) { /* for now, only choose the floorplan with * the minimum area regardless of the overall * aspect ratio */ int pos = min_area_pos(root->curve); #if VERBOSE > 1 double compacted_area = 0.0; #endif int dead_count = recursive_sizing(root, pos, 0.0, 0.0, 0, compact_dead, compact_ratio, #if VERBOSE > 1 &compacted_area, #endif flp); int compacted = (flp->n_units - 1) / 2 - dead_count; flp->n_units -= compacted; #if VERBOSE > 1 fprintf(stdout, "%d dead blocks, %.2f%% of the core compacted\n", compacted, compacted_area / (get_total_area(flp)-compacted_area) * 100); #endif return compacted; }
/* print the statistics about this floorplan. * note that connects_file is NULL if wire * information is already populated */ void print_flp_stats(flp_t *flp, RC_model_t *model, char *l2_label, char *power_file, char *connects_file) { double core, total, occupied; /* area */ double width, height, aspect, total_w, total_h; double wire_metric; double peak, avg; /* temperature */ double *power, *temp; FILE *fp = NULL; char str[STR_SIZE]; if (connects_file) { fp = fopen(connects_file, "r"); if (!fp) { sprintf(str, "error opening file %s\n", connects_file); fatal(str); } flp_populate_connects(flp, fp); } power = hotspot_vector(model); temp = hotspot_vector(model); read_power(model, power, power_file); core = get_core_area(flp, l2_label); total = get_total_area(flp); total_w = get_total_width(flp); total_h = get_total_height(flp); occupied = get_core_occupied_area(flp, l2_label); width = get_core_width(flp, l2_label); height = get_core_height(flp, l2_label); aspect = (height > width) ? (height/width) : (width/height); wire_metric = get_wire_metric(flp); populate_R_model(model, flp); steady_state_temp(model, power, temp); peak = find_max_temp(model, temp); avg = find_avg_temp(model, temp); fprintf(stdout, "printing summary statistics about the floorplan\n"); fprintf(stdout, "total area:\t%g\n", total); fprintf(stdout, "total width:\t%g\n", total_w); fprintf(stdout, "total height:\t%g\n", total_h); fprintf(stdout, "core area:\t%g\n", core); fprintf(stdout, "occupied area:\t%g\n", occupied); fprintf(stdout, "area utilization:\t%.3f\n", occupied / core * 100.0); fprintf(stdout, "core width:\t%g\n", width); fprintf(stdout, "core height:\t%g\n", height); fprintf(stdout, "core aspect ratio:\t%.3f\n", aspect); fprintf(stdout, "wire length metric:\t%.3f\n", wire_metric); fprintf(stdout, "peak temperature:\t%.3f\n", peak); fprintf(stdout, "avg temperature:\t%.3f\n", avg); free_dvector(power); free_dvector(temp); if (fp) fclose(fp); }
/* * this is the metric function used for the floorplanning. * in order to enable a different metric, just change the * return statement of this function to return an appropriate * metric. The current metric used is a linear function of * area (A), temperature (T) and wire length (W): * lambdaA * A + lambdaT * T + lambdaW * W * thermal model and power density are passed as parameters * since temperature is used in the metric. */ double flp_evaluate_metric(flp_t *flp, RC_model_t *model, double *power, double lambdaA, double lambdaT, double lambdaW) { double tmax, area, wire_length, width, height, aspect; double *temp; temp = hotspot_vector(model); populate_R_model(model, flp); steady_state_temp(model, power, temp); tmax = find_max_temp(model, temp); area = get_total_area(flp); wire_length = get_wire_metric(flp); width = get_total_width(flp); height = get_total_height(flp); if (width > height) aspect = width / height; else aspect = height / width; free_dvector(temp); /* can return any arbitrary function of area, tmax and wire_length */ return (lambdaA * area + lambdaT * tmax + lambdaW * wire_length); }
/* * wrap the L2 around this floorplan. L2's area information * is obtained from flp_desc. memory for L2 and its arms has * already been allocated in the flp. note that flp & flp_desc * have L2 hidden beyond the boundary at this point */ void flp_wrap_l2(flp_t *flp, flp_desc_t *flp_desc) { /* * x is the width of the L2 arms * y is the height of the bottom portion */ double x, y, core_width, core_height, total_side, core_area, l2_area; unit_t *l2, *l2_left, *l2_right; /* find L2 dimensions so that the total chip becomes a square */ core_area = get_total_area(flp); core_width = get_total_width(flp); core_height = get_total_height(flp); /* flp_desc has L2 hidden beyond the boundary */ l2_area = flp_desc->units[flp_desc->n_units].area; total_side = sqrt(core_area + l2_area); /* * width of the total chip after L2 wrapping is equal to * the width of the core plus the width of the two arms */ x = (total_side - core_width) / 2.0; y = total_side - core_height; /* * we are trying to solve the equation * (2*x+core_width) * (y+core_height) * = l2_area + core_area * for x and y. it is possible that the values * turnout to be negative if we restrict the * total chip to be a square. in that case, * theoretically, any value of x in the range * (0, l2_area/(2*core_height)) and the * corresponding value of y or any value of y * in the range (0, l2_area/core_width) and the * corresponding value of x would be a solution * we look for a solution with a reasonable * aspect ratio. i.e., we constrain kx = y (or * ky = x depending on the aspect ratio of the * core) where k = WRAP_L2_RATIO. solving the equation * with this constraint, we get the following */ if ( x <= 0 || y <= 0.0) { double sum; if (core_width >= core_height) { sum = WRAP_L2_RATIO * core_width + 2 * core_height; x = (sqrt(sum*sum + 8*WRAP_L2_RATIO*l2_area) - sum) / (4*WRAP_L2_RATIO); y = WRAP_L2_RATIO * x; } else { sum = core_width + 2 * WRAP_L2_RATIO * core_height; y = (sqrt(sum*sum + 8*WRAP_L2_RATIO*l2_area) - sum) / (4*WRAP_L2_RATIO); x = WRAP_L2_RATIO * y; } total_side = 2 * x + core_width; } /* fix the positions of core blocks */ flp_translate(flp, x, y); /* restore the L2 blocks */ flp->n_units += (L2_ARMS+1); /* copy L2 info again from flp_desc but from beyond the boundary */ copy_l2_info(flp, flp->n_units-L2_ARMS-1, flp_desc, flp_desc->n_units, flp_desc->n_units); /* fix the positions of the L2 blocks. connectivity * information has already been fixed (in flp_placeholder). * bottom L2 block - (leftx, bottomy) is already (0,0) */ l2 = &flp->units[flp->n_units-1-L2_ARMS]; l2->width = total_side; l2->height = y; l2->leftx = l2->bottomy = 0; /* left L2 arm */ l2_left = &flp->units[flp->n_units-L2_ARMS+L2_LEFT]; l2_left->width = x; l2_left->height = core_height; l2_left->leftx = 0; l2_left->bottomy = y; /* right L2 arm */ l2_right = &flp->units[flp->n_units-L2_ARMS+L2_RIGHT]; l2_right->width = x; l2_right->height = core_height; l2_right->leftx = x + core_width; l2_right->bottomy = y; }