#include #include #include #include "echo_arch.h" #include "arch_types.h" #include "vtr_list.h" #include "vtr_util.h" #include "vtr_memory.h" #include "vtr_assert.h" using vtr::t_linked_vptr; void PrintArchInfo(FILE* Echo, const t_arch* arch); static void PrintPb_types_rec(FILE* Echo, const t_pb_type* pb_type, int level); static void PrintPb_types_recPower(FILE* Echo, const t_pb_type* pb_type, const char* tabs); /* Output the data from architecture data so user can verify it * was interpretted correctly. */ void EchoArch(const char* EchoFile, const std::vector& PhysicalTileTypes, const std::vector& LogicalBlockTypes, const t_arch* arch) { int i, j; FILE* Echo; t_model* cur_model; t_model_ports* model_port; t_linked_vptr* cur_vptr; Echo = vtr::fopen(EchoFile, "w"); cur_model = nullptr; //Print all layout device switch/segment list info first PrintArchInfo(Echo, arch); //Models fprintf(Echo, "*************************************************\n"); for (j = 0; j < 2; j++) { if (j == 0) { fprintf(Echo, "Printing user models \n"); cur_model = arch->models; } else if (j == 1) { fprintf(Echo, "Printing library models \n"); cur_model = arch->model_library; } while (cur_model) { fprintf(Echo, "Model: \"%s\"\n", cur_model->name); model_port = cur_model->inputs; while (model_port) { fprintf(Echo, "\tInput Ports: \"%s\" \"%d\" min_size=\"%d\"\n", model_port->name, model_port->size, model_port->min_size); model_port = model_port->next; } model_port = cur_model->outputs; while (model_port) { fprintf(Echo, "\tOutput Ports: \"%s\" \"%d\" min_size=\"%d\"\n", model_port->name, model_port->size, model_port->min_size); model_port = model_port->next; } cur_vptr = cur_model->pb_types; i = 0; while (cur_vptr != nullptr) { fprintf(Echo, "\tpb_type %d: \"%s\"\n", i, ((t_pb_type*)cur_vptr->data_vptr)->name); cur_vptr = cur_vptr->next; i++; } cur_model = cur_model->next; } } fprintf(Echo, "*************************************************\n\n"); fprintf(Echo, "*************************************************\n"); for (auto& Type : PhysicalTileTypes) { fprintf(Echo, "Type: \"%s\"\n", Type.name); fprintf(Echo, "\tcapacity: %d\n", Type.capacity); fprintf(Echo, "\twidth: %d\n", Type.width); fprintf(Echo, "\theight: %d\n", Type.height); for (const t_fc_specification& fc_spec : Type.fc_specs) { fprintf(Echo, "fc_value_type: "); if (fc_spec.fc_value_type == e_fc_value_type::ABSOLUTE) { fprintf(Echo, "ABSOLUTE"); } else if (fc_spec.fc_value_type == e_fc_value_type::FRACTIONAL) { fprintf(Echo, "FRACTIONAL"); } else { VTR_ASSERT(false); } fprintf(Echo, " fc_value: %f", fc_spec.fc_value); fprintf(Echo, " segment: %s", arch->Segments[fc_spec.seg_index].name.c_str()); fprintf(Echo, " pins:"); for (int pin : fc_spec.pins) { fprintf(Echo, " %d", pin); } fprintf(Echo, "\n"); } fprintf(Echo, "\tnum_drivers: %d\n", Type.num_drivers); fprintf(Echo, "\tnum_receivers: %d\n", Type.num_receivers); int index = Type.index; fprintf(Echo, "\tindex: %d\n", index); for (auto LogicalBlock : Type.equivalent_sites) { fprintf(Echo, "\nEquivalent Site: %s\n", LogicalBlock->name); } fprintf(Echo, "\n"); } fprintf(Echo, "*************************************************\n\n"); fprintf(Echo, "*************************************************\n"); for (auto& LogicalBlock : LogicalBlockTypes) { if (LogicalBlock.pb_type) { PrintPb_types_rec(Echo, LogicalBlock.pb_type, 2); } fprintf(Echo, "\n"); } fclose(Echo); } //Added May 2013 Daniel Chen, help dump arch info after loading from XML void PrintArchInfo(FILE* Echo, const t_arch* arch) { int i, j; fprintf(Echo, "Printing architecture... \n\n"); //Layout fprintf(Echo, "*************************************************\n"); for (const auto& grid_layout : arch->grid_layouts) { if (grid_layout.grid_type == GridDefType::AUTO) { fprintf(Echo, "Layout: '%s' Type: auto Aspect_Ratio: %f\n", grid_layout.name.c_str(), grid_layout.aspect_ratio); } else { VTR_ASSERT(grid_layout.grid_type == GridDefType::FIXED); fprintf(Echo, "Layout: '%s' Type: fixed Width: %d Height %d\n", grid_layout.name.c_str(), grid_layout.width, grid_layout.height); } } fprintf(Echo, "*************************************************\n\n"); //Device fprintf(Echo, "*************************************************\n"); fprintf(Echo, "Device Info:\n"); fprintf(Echo, "\tSizing: R_minW_nmos %e R_minW_pmos %e\n", arch->R_minW_nmos, arch->R_minW_pmos); fprintf(Echo, "\tArea: grid_logic_tile_area %e\n", arch->grid_logic_tile_area); fprintf(Echo, "\tChannel Width Distribution:\n"); switch (arch->Chans.chan_x_dist.type) { case (UNIFORM): fprintf(Echo, "\t\tx: type uniform peak %e\n", arch->Chans.chan_x_dist.peak); break; case (GAUSSIAN): fprintf(Echo, "\t\tx: type gaussian peak %e \ width %e Xpeak %e dc %e\n", arch->Chans.chan_x_dist.peak, arch->Chans.chan_x_dist.width, arch->Chans.chan_x_dist.xpeak, arch->Chans.chan_x_dist.dc); break; case (PULSE): fprintf(Echo, "\t\tx: type pulse peak %e \ width %e Xpeak %e dc %e\n", arch->Chans.chan_x_dist.peak, arch->Chans.chan_x_dist.width, arch->Chans.chan_x_dist.xpeak, arch->Chans.chan_x_dist.dc); break; case (DELTA): fprintf(Echo, "\t\tx: distr dleta peak %e \ Xpeak %e dc %e\n", arch->Chans.chan_x_dist.peak, arch->Chans.chan_x_dist.xpeak, arch->Chans.chan_x_dist.dc); break; default: fprintf(Echo, "\t\tInvalid Distribution!\n"); break; } switch (arch->Chans.chan_y_dist.type) { case (UNIFORM): fprintf(Echo, "\t\ty: type uniform peak %e\n", arch->Chans.chan_y_dist.peak); break; case (GAUSSIAN): fprintf(Echo, "\t\ty: type gaussian peak %e \ width %e Xpeak %e dc %e\n", arch->Chans.chan_y_dist.peak, arch->Chans.chan_y_dist.width, arch->Chans.chan_y_dist.xpeak, arch->Chans.chan_y_dist.dc); break; case (PULSE): fprintf(Echo, "\t\ty: type pulse peak %e \ width %e Xpeak %e dc %e\n", arch->Chans.chan_y_dist.peak, arch->Chans.chan_y_dist.width, arch->Chans.chan_y_dist.xpeak, arch->Chans.chan_y_dist.dc); break; case (DELTA): fprintf(Echo, "\t\ty: distr dleta peak %e \ Xpeak %e dc %e\n", arch->Chans.chan_y_dist.peak, arch->Chans.chan_y_dist.xpeak, arch->Chans.chan_y_dist.dc); break; default: fprintf(Echo, "\t\tInvalid Distribution!\n"); break; } switch (arch->SBType) { case (WILTON): fprintf(Echo, "\tSwitch Block: type wilton fs %d\n", arch->Fs); break; case (UNIVERSAL): fprintf(Echo, "\tSwitch Block: type universal fs %d\n", arch->Fs); break; case (SUBSET): fprintf(Echo, "\tSwitch Block: type subset fs %d\n", arch->Fs); break; default: break; } fprintf(Echo, "\tInput Connect Block Switch Name: %s\n", arch->ipin_cblock_switch_name.c_str()); fprintf(Echo, "*************************************************\n\n"); //Switch list fprintf(Echo, "*************************************************\n"); fprintf(Echo, "Switch List:\n"); //13 is hard coded because format of %e is always 1.123456e+12 //It always consists of 10 alphanumeric digits, a decimal //and a sign for (i = 0; i < arch->num_switches; i++) { if (arch->Switches[i].type() == SwitchType::MUX) { fprintf(Echo, "\tSwitch[%d]: name %s type mux\n", i + 1, arch->Switches[i].name); } else if (arch->Switches[i].type() == SwitchType::TRISTATE) { fprintf(Echo, "\tSwitch[%d]: name %s type tristate\n", i + 1, arch->Switches[i].name); } else if (arch->Switches[i].type() == SwitchType::SHORT) { fprintf(Echo, "\tSwitch[%d]: name %s type short\n", i + 1, arch->Switches[i].name); } else if (arch->Switches[i].type() == SwitchType::BUFFER) { fprintf(Echo, "\tSwitch[%d]: name %s type buffer\n", i + 1, arch->Switches[i].name); } else { VTR_ASSERT(arch->Switches[i].type() == SwitchType::PASS_GATE); fprintf(Echo, "\tSwitch[%d]: name %s type pass_gate\n", i + 1, arch->Switches[i].name); } fprintf(Echo, "\t\t\t\tR %e Cin %e Cout %e\n", arch->Switches[i].R, arch->Switches[i].Cin, arch->Switches[i].Cout); fprintf(Echo, "\t\t\t\t#Tdel values %d buf_size %e mux_trans_size %e\n", (int)arch->Switches[i].Tdel_map_.size(), arch->Switches[i].buf_size, arch->Switches[i].mux_trans_size); if (arch->Switches[i].power_buffer_type == POWER_BUFFER_TYPE_AUTO) { fprintf(Echo, "\t\t\t\tpower_buffer_size auto\n"); } else { fprintf(Echo, "\t\t\t\tpower_buffer_size %e\n", arch->Switches[i].power_buffer_size); } } fprintf(Echo, "*************************************************\n\n"); //Segment List fprintf(Echo, "*************************************************\n"); fprintf(Echo, "Segment List:\n"); for (i = 0; i < (int)(arch->Segments).size(); i++) { const struct t_segment_inf& seg = arch->Segments[i]; fprintf(Echo, "\tSegment[%d]: frequency %d length %d R_metal %e C_metal %e\n", i + 1, seg.frequency, seg.length, seg.Rmetal, seg.Cmetal); if (seg.directionality == UNI_DIRECTIONAL) { //wire_switch == arch_opin_switch fprintf(Echo, "\t\t\t\ttype unidir mux_name %s\n", arch->Switches[seg.arch_wire_switch].name); } else { //Should be bidir fprintf(Echo, "\t\t\t\ttype bidir wire_switch %s arch_opin_switch %s\n", arch->Switches[seg.arch_wire_switch].name, arch->Switches[seg.arch_opin_switch].name); } fprintf(Echo, "\t\t\t\tcb "); for (j = 0; j < (int)seg.cb.size(); j++) { if (seg.cb[j]) { fprintf(Echo, "1 "); } else { fprintf(Echo, "0 "); } } fprintf(Echo, "\n"); fprintf(Echo, "\t\t\t\tsb "); for (j = 0; j < (int)seg.sb.size(); j++) { if (seg.sb[j]) { fprintf(Echo, "1 "); } else { fprintf(Echo, "0 "); } } fprintf(Echo, "\n"); } fprintf(Echo, "*************************************************\n\n"); //Direct List fprintf(Echo, "*************************************************\n"); fprintf(Echo, "Direct List:\n"); for (i = 0; i < arch->num_directs; i++) { fprintf(Echo, "\tDirect[%d]: name %s from_pin %s to_pin %s\n", i + 1, arch->Directs[i].name, arch->Directs[i].from_pin, arch->Directs[i].to_pin); fprintf(Echo, "\t\t\t\t x_offset %d y_offset %d z_offset %d\n", arch->Directs[i].x_offset, arch->Directs[i].y_offset, arch->Directs[i].z_offset); } fprintf(Echo, "*************************************************\n\n"); //Architecture Power fprintf(Echo, "*************************************************\n"); fprintf(Echo, "Power:\n"); if (arch->power) { fprintf(Echo, "\tlocal_interconnect C_wire %e factor %f\n", arch->power->C_wire_local, arch->power->local_interc_factor); fprintf(Echo, "\tlogical_effort_factor %f trans_per_sram_bit %f\n", arch->power->logical_effort_factor, arch->power->transistors_per_SRAM_bit); } fprintf(Echo, "*************************************************\n\n"); //Architecture Clock fprintf(Echo, "*************************************************\n"); fprintf(Echo, "Clock:\n"); if (arch->clocks) { for (i = 0; i < arch->clocks->num_global_clocks; i++) { if (arch->clocks->clock_inf[i].autosize_buffer) { fprintf(Echo, "\tClock[%d]: buffer_size auto C_wire %e", i + 1, arch->clocks->clock_inf->C_wire); } else { fprintf(Echo, "\tClock[%d]: buffer_size %e C_wire %e", i + 1, arch->clocks->clock_inf[i].buffer_size, arch->clocks->clock_inf[i].C_wire); } fprintf(Echo, "\t\t\t\tstat_prob %f switch_density %f period %e", arch->clocks->clock_inf[i].prob, arch->clocks->clock_inf[i].dens, arch->clocks->clock_inf[i].period); } } fprintf(Echo, "*************************************************\n\n"); } static void PrintPb_types_rec(FILE* Echo, const t_pb_type* pb_type, int level) { int i, j, k; char* tabs; tabs = (char*)vtr::malloc((level + 1) * sizeof(char)); for (i = 0; i < level; i++) { tabs[i] = '\t'; } tabs[level] = '\0'; fprintf(Echo, "%spb_type name: %s\n", tabs, pb_type->name); fprintf(Echo, "%s\tblif_model: %s\n", tabs, pb_type->blif_model); fprintf(Echo, "%s\tclass_type: %d\n", tabs, pb_type->class_type); fprintf(Echo, "%s\tnum_modes: %d\n", tabs, pb_type->num_modes); fprintf(Echo, "%s\tnum_ports: %d\n", tabs, pb_type->num_ports); for (i = 0; i < pb_type->num_ports; i++) { fprintf(Echo, "%s\tport %s type %d num_pins %d\n", tabs, pb_type->ports[i].name, pb_type->ports[i].type, pb_type->ports[i].num_pins); } if (pb_type->num_modes > 0) { /*one or more modes*/ for (i = 0; i < pb_type->num_modes; i++) { fprintf(Echo, "%s\tmode %s:\n", tabs, pb_type->modes[i].name); for (j = 0; j < pb_type->modes[i].num_pb_type_children; j++) { PrintPb_types_rec(Echo, &pb_type->modes[i].pb_type_children[j], level + 2); } for (j = 0; j < pb_type->modes[i].num_interconnect; j++) { fprintf(Echo, "%s\t\tinterconnect %d %s %s\n", tabs, pb_type->modes[i].interconnect[j].type, pb_type->modes[i].interconnect[j].input_string, pb_type->modes[i].interconnect[j].output_string); for (k = 0; k < pb_type->modes[i].interconnect[j].num_annotations; k++) { fprintf(Echo, "%s\t\t\tannotation %s %s %d: %s\n", tabs, pb_type->modes[i].interconnect[j].annotations[k].input_pins, pb_type->modes[i].interconnect[j].annotations[k].output_pins, pb_type->modes[i].interconnect[j].annotations[k].format, pb_type->modes[i].interconnect[j].annotations[k].value[0]); } //Print power info for interconnects if (pb_type->modes[i].interconnect[j].interconnect_power) { if (pb_type->modes[i].interconnect[j].interconnect_power->power_usage.dynamic || pb_type->modes[i].interconnect[j].interconnect_power->power_usage.leakage) { fprintf(Echo, "%s\t\t\tpower %e %e\n", tabs, pb_type->modes[i].interconnect[j].interconnect_power->power_usage.dynamic, pb_type->modes[i].interconnect[j].interconnect_power->power_usage.leakage); } } } } } else { /*leaf pb with unknown model*/ /*LUT(names) already handled, it naturally has 2 modes. * I/O has no annotations to be displayed * All other library or user models may have delays specificied, e.g. Tsetup and Tcq * Display the additional information*/ if (strcmp(pb_type->model->name, MODEL_NAMES) && strcmp(pb_type->model->name, MODEL_INPUT) && strcmp(pb_type->model->name, MODEL_OUTPUT)) { for (k = 0; k < pb_type->num_annotations; k++) { fprintf(Echo, "%s\t\t\tannotation %s %s %s %d: %s\n", tabs, pb_type->annotations[k].clock, pb_type->annotations[k].input_pins, pb_type->annotations[k].output_pins, pb_type->annotations[k].format, pb_type->annotations[k].value[0]); } } } if (pb_type->pb_type_power) { PrintPb_types_recPower(Echo, pb_type, tabs); } free(tabs); } //Added May 2013 Daniel Chen, help dump arch info after loading from XML static void PrintPb_types_recPower(FILE* Echo, const t_pb_type* pb_type, const char* tabs) { int i = 0; /*Print power information for each pb if available*/ switch (pb_type->pb_type_power->estimation_method) { case POWER_METHOD_UNDEFINED: fprintf(Echo, "%s\tpower method: undefined\n", tabs); break; case POWER_METHOD_IGNORE: if (pb_type->parent_mode) { /*if NOT top-level pb (all top-level pb has NULL parent_mode, check parent's power method * This is because of the inheritance property of auto-size*/ if (pb_type->parent_mode->parent_pb_type->pb_type_power->estimation_method == POWER_METHOD_IGNORE) break; } fprintf(Echo, "%s\tpower method: ignore\n", tabs); break; case POWER_METHOD_SUM_OF_CHILDREN: fprintf(Echo, "%s\tpower method: sum-of-children\n", tabs); break; case POWER_METHOD_AUTO_SIZES: if (pb_type->parent_mode) { /*if NOT top-level pb (all top-level pb has NULL parent_mode, check parent's power method * This is because of the inheritance property of auto-size*/ if (pb_type->parent_mode->parent_pb_type->pb_type_power->estimation_method == POWER_METHOD_AUTO_SIZES) break; } fprintf(Echo, "%s\tpower method: auto-size\n", tabs); break; case POWER_METHOD_SPECIFY_SIZES: if (pb_type->parent_mode) { /*if NOT top-level pb (all top-level pb has NULL parent_mode, check parent's power method * This is because of the inheritance property of specify-size*/ if (pb_type->parent_mode->parent_pb_type->pb_type_power->estimation_method == POWER_METHOD_SPECIFY_SIZES) break; } fprintf(Echo, "%s\tpower method: specify-size\n", tabs); for (i = 0; i < pb_type->num_ports; i++) { //Print all the power information on each port, only if available, //will not print if value is 0 or NULL if (pb_type->ports[i].port_power->buffer_type || pb_type->ports[i].port_power->wire_type || pb_type->pb_type_power->absolute_power_per_instance.leakage || pb_type->pb_type_power->absolute_power_per_instance.dynamic) { fprintf(Echo, "%s\t\tport %s type %d num_pins %d\n", tabs, pb_type->ports[i].name, pb_type->ports[i].type, pb_type->ports[i].num_pins); //Buffer size switch (pb_type->ports[i].port_power->buffer_type) { case (POWER_BUFFER_TYPE_UNDEFINED): case (POWER_BUFFER_TYPE_NONE): break; case (POWER_BUFFER_TYPE_AUTO): fprintf(Echo, "%s\t\t\tbuffer_size %s\n", tabs, "auto"); break; case (POWER_BUFFER_TYPE_ABSOLUTE_SIZE): fprintf(Echo, "%s\t\t\tbuffer_size %f\n", tabs, pb_type->ports[i].port_power->buffer_size); break; default: break; } switch (pb_type->ports[i].port_power->wire_type) { case (POWER_WIRE_TYPE_UNDEFINED): case (POWER_WIRE_TYPE_IGNORED): break; case (POWER_WIRE_TYPE_C): fprintf(Echo, "%s\t\t\twire_cap: %e\n", tabs, pb_type->ports[i].port_power->wire.C); break; case (POWER_WIRE_TYPE_ABSOLUTE_LENGTH): fprintf(Echo, "%s\t\t\twire_len(abs): %e\n", tabs, pb_type->ports[i].port_power->wire.absolute_length); break; case (POWER_WIRE_TYPE_RELATIVE_LENGTH): fprintf(Echo, "%s\t\t\twire_len(rel): %f\n", tabs, pb_type->ports[i].port_power->wire.relative_length); break; case (POWER_WIRE_TYPE_AUTO): fprintf(Echo, "%s\t\t\twire_len: %s\n", tabs, "auto"); break; default: break; } } } //Output static power even if non zero if (pb_type->pb_type_power->absolute_power_per_instance.leakage) fprintf(Echo, "%s\t\tstatic power_per_instance: %e \n", tabs, pb_type->pb_type_power->absolute_power_per_instance.leakage); if (pb_type->pb_type_power->absolute_power_per_instance.dynamic) fprintf(Echo, "%s\t\tdynamic power_per_instance: %e \n", tabs, pb_type->pb_type_power->absolute_power_per_instance.dynamic); break; case POWER_METHOD_TOGGLE_PINS: if (pb_type->parent_mode) { /*if NOT top-level pb (all top-level pb has NULL parent_mode, check parent's power method * This is because once energy_per_toggle is specified at one level, * all children pb's are energy_per_toggle and only want to display once*/ if (pb_type->parent_mode->parent_pb_type->pb_type_power->estimation_method == POWER_METHOD_TOGGLE_PINS) break; } fprintf(Echo, "%s\tpower method: pin-toggle\n", tabs); for (i = 0; i < pb_type->num_ports; i++) { /*Print all the power information on each port, only if available, * will not print if value is 0 or NULL*/ if (pb_type->ports[i].port_power->energy_per_toggle || pb_type->ports[i].port_power->scaled_by_port || pb_type->pb_type_power->absolute_power_per_instance.leakage || pb_type->pb_type_power->absolute_power_per_instance.dynamic) { fprintf(Echo, "%s\t\tport %s type %d num_pins %d\n", tabs, pb_type->ports[i].name, pb_type->ports[i].type, pb_type->ports[i].num_pins); //Toggle Energy if (pb_type->ports[i].port_power->energy_per_toggle) { fprintf(Echo, "%s\t\t\tenergy_per_toggle %e\n", tabs, pb_type->ports[i].port_power->energy_per_toggle); } //Scaled by port (could be reversed) if (pb_type->ports[i].port_power->scaled_by_port) { if (pb_type->ports[i].port_power->scaled_by_port->num_pins > 1) { fprintf(Echo, (pb_type->ports[i].port_power->reverse_scaled ? "%s\t\t\tscaled_by_static_prob_n: %s[%d]\n" : "%s\t\t\tscaled_by_static_prob: %s[%d]\n"), tabs, pb_type->ports[i].port_power->scaled_by_port->name, pb_type->ports[i].port_power->scaled_by_port_pin_idx); } else { fprintf(Echo, (pb_type->ports[i].port_power->reverse_scaled ? "%s\t\t\tscaled_by_static_prob_n: %s\n" : "%s\t\t\tscaled_by_static_prob: %s\n"), tabs, pb_type->ports[i].port_power->scaled_by_port->name); } } } } //Output static power even if non zero if (pb_type->pb_type_power->absolute_power_per_instance.leakage) fprintf(Echo, "%s\t\tstatic power_per_instance: %e \n", tabs, pb_type->pb_type_power->absolute_power_per_instance.leakage); if (pb_type->pb_type_power->absolute_power_per_instance.dynamic) fprintf(Echo, "%s\t\tdynamic power_per_instance: %e \n", tabs, pb_type->pb_type_power->absolute_power_per_instance.dynamic); break; case POWER_METHOD_C_INTERNAL: if (pb_type->parent_mode) { /*if NOT top-level pb (all top-level pb has NULL parent_mode, check parent's power method * This is because of values at this level includes all children pb's*/ if (pb_type->parent_mode->parent_pb_type->pb_type_power->estimation_method == POWER_METHOD_C_INTERNAL) break; } fprintf(Echo, "%s\tpower method: C-internal\n", tabs); if (pb_type->pb_type_power->absolute_power_per_instance.leakage) fprintf(Echo, "%s\t\tstatic power_per_instance: %e \n", tabs, pb_type->pb_type_power->absolute_power_per_instance.leakage); if (pb_type->pb_type_power->C_internal) fprintf(Echo, "%s\t\tdynamic c-internal: %e \n", tabs, pb_type->pb_type_power->C_internal); break; case POWER_METHOD_ABSOLUTE: if (pb_type->parent_mode) { /*if NOT top-level pb (all top-level pb has NULL parent_mode, check parent's power method * This is because of values at this level includes all children pb's*/ if (pb_type->parent_mode->parent_pb_type->pb_type_power->estimation_method == POWER_METHOD_ABSOLUTE) break; } fprintf(Echo, "%s\tpower method: absolute\n", tabs); if (pb_type->pb_type_power->absolute_power_per_instance.leakage) fprintf(Echo, "%s\t\tstatic power_per_instance: %e \n", tabs, pb_type->pb_type_power->absolute_power_per_instance.leakage); if (pb_type->pb_type_power->absolute_power_per_instance.dynamic) fprintf(Echo, "%s\t\tdynamic power_per_instance: %e \n", tabs, pb_type->pb_type_power->absolute_power_per_instance.dynamic); break; default: fprintf(Echo, "%s\tpower method: error has occcured\n", tabs); break; } }