/** * Recursively resolves an IDENTIFIER to a parameter into its actual value, * by looking it up in the global_param_table_sc * Also try and fold any BINARY_OPERATIONs now that an IDENTIFIER has been * resolved */ ast_node_t *resolve_node(char *module_name, ast_node_t *node) { if (node) { long sc_spot; int i; info_ast_visit_t *node_details; STRING_CACHE *local_param_table_sc; ast_node_t *node_copy; node_copy = (ast_node_t *)malloc(sizeof(ast_node_t)); memcpy(node_copy, node, sizeof(ast_node_t)); node_copy->children = malloc(sizeof(ast_node_t*) * node_copy->num_children); for (i = 0; i < node->num_children; i++) { node_copy->children[i] = resolve_node(module_name, node->children[i]); } switch (node->type) { case IDENTIFIERS: oassert(module_name); sc_spot = sc_lookup_string(global_param_table_sc, module_name); oassert(sc_spot != -1); local_param_table_sc = (STRING_CACHE *)global_param_table_sc->data[sc_spot]; sc_spot = sc_lookup_string(local_param_table_sc, node->types.identifier); if (sc_spot != -1) { node = ((ast_node_t *)local_param_table_sc->data[sc_spot]); oassert(node->type == NUMBERS); } break; case BINARY_OPERATION: node_copy->shared_node = TRUE; node_details = constantFold(node_copy); node_copy->shared_node = FALSE; if (node_details && node_details->is_constant_folded == TRUE) { node = node_details->from; free(node_details); oassert(node->type == NUMBERS); } break; default: break; } free(node_copy->children); free(node_copy); } return node; }
/*--------------------------------------------------------------------------------------------- * (function: mark_clock_node ) *-------------------------------------------------------------------------------------------*/ void mark_clock_node ( netlist_t *netlist, char *clock_name ) { long sc_spot; nnet_t *clock_net; nnode_t *clock_node; /* lookup the node */ if ((sc_spot = sc_lookup_string(netlist->nets_sc, clock_name)) == -1) { error_message(NETLIST_ERROR, file_line_number, -1, "clock input does not exist (%s)\n", clock_name); } clock_net = (nnet_t*)netlist->nets_sc->data[sc_spot]; clock_node = clock_net->driver_pin->node; netlist->clocks = (nnode_t**)realloc(netlist->clocks, sizeof(nnode_t*)*(netlist->num_clocks+1)); netlist->clocks[netlist->num_clocks] = clock_node; netlist->num_clocks++; /* Mark it as a special set of inputs */ clock_node->type = CLOCK_NODE; }
long sc_add_string(STRING_CACHE * sc, char *string) { long i; long hash; void *a; i = sc_lookup_string(sc, string); if(i >= 0) return i; if(sc->free >= sc->size) { sc->size = sc->size * 2 + 10; a = sc_do_alloc(sc->size, sizeof(char *)); if(sc->free > 0) memcpy(a, sc->string, sc->free * sizeof(char *)); free(sc->string); sc->string = (char **)a; a = sc_do_alloc(sc->size, sizeof(void *)); if(sc->free > 0) memcpy(a, sc->data, sc->free * sizeof(void *)); free(sc->data); sc->data = (void **)a; generate_sc_hash(sc); } i = sc->free; sc->free++; sc->string[i] = strdup(string); sc->data[i] = NULL; hash = string_hash(sc, string) % sc->string_hash_size; sc->next_string[i] = sc->string_hash[hash]; sc->string_hash[hash] = i; return i; }
/*--------------------------------------------------------------------------------------------- * (function: hookup_output_pouts_from_signal_list) * hooks the pin into the output net, by checking for a driving net *-------------------------------------------------------------------------------------------*/ void hookup_output_pins_from_signal_list(nnode_t *node, int n_start_idx, signal_list_t* output_list, int ol_start_idx, int width) { int i; long sc_spot_output; for (i = 0; i < width; i++) { oassert(output_list->count > (ol_start_idx+i)); /* hook outpin to the node */ add_output_pin_to_node(node, output_list->pins[ol_start_idx+i], n_start_idx+i); if ((sc_spot_output = sc_lookup_string(output_nets_sc, output_list->pins[ol_start_idx+i]->name)) == -1) { /* this output pin does not have a net OR we couldn't find it */ error_message(NETLIST_ERROR, -1, -1, "Net for driver (%s) doesn't exist for node %s\n", output_list->pins[ol_start_idx+i]->name, node->name); } /* hook the outpin into the net */ add_driver_pin_to_net(((nnet_t*)output_nets_sc->data[sc_spot_output]), output_list->pins[ol_start_idx+i]); } }
/*--------------------------------------------------------------------------------------------- * (function: get_name_of_pins * Assume module connections can be one of: Array entry, Concat, Signal, Array range reference * Return a list of strings *-------------------------------------------------------------------------------------------*/ char_list_t *get_name_of_pins(ast_node_t *var_node, char *instance_name_prefix) { char **return_string = NULL; char_list_t *return_list = (char_list_t*)malloc(sizeof(char_list_t)); ast_node_t *rnode[3]; int i; int width = 0; if (var_node->type == ARRAY_REF) { width = 1; return_string = (char**)malloc(sizeof(char*)); rnode[1] = resolve_node(instance_name_prefix, var_node->children[1]); oassert(rnode[1]->type == NUMBERS); oassert(var_node->children[0]->type == IDENTIFIERS); return_string[0] = make_full_ref_name(NULL, NULL, NULL, var_node->children[0]->types.identifier, rnode[1]->types.number.value); } else if (var_node->type == RANGE_REF) { rnode[0] = resolve_node(instance_name_prefix, var_node->children[0]); rnode[1] = resolve_node(instance_name_prefix, var_node->children[1]); rnode[2] = resolve_node(instance_name_prefix, var_node->children[2]); oassert(rnode[1]->type == NUMBERS && rnode[2]->type == NUMBERS); width = abs(rnode[1]->types.number.value - rnode[2]->types.number.value) + 1; if (rnode[0]->type == IDENTIFIERS) { return_string = (char**)malloc(sizeof(char*)*width); for (i = 0; i < width; i++) return_string[i] = make_full_ref_name(NULL, NULL, NULL, rnode[0]->types.identifier, rnode[2]->types.number.value+i); } else { oassert(rnode[0]->type == NUMBERS); return_string = get_name_of_pins_number(rnode[0], rnode[2]->types.number.value, width); } } else if (var_node->type == IDENTIFIERS) { /* need to look in the symbol table for details about this identifier (i.e. is it a port) */ long sc_spot; ast_node_t *sym_node; // try and resolve var_node sym_node = resolve_node(instance_name_prefix, var_node); if (sym_node == var_node) { char *temp_string = make_full_ref_name(NULL, NULL, NULL, var_node->types.identifier, -1); if ((sc_spot = sc_lookup_string(local_symbol_table_sc, temp_string)) == -1) { error_message(NETLIST_ERROR, var_node->line_number, var_node->file_number, "Missing declaration of this symbol %s\n", temp_string); } free(temp_string); sym_node = (ast_node_t*)local_symbol_table_sc->data[sc_spot]; if (sym_node->children[1] == NULL) { width = 1; return_string = (char**)malloc(sizeof(char*)*width); return_string[0] = make_full_ref_name(NULL, NULL, NULL, var_node->types.identifier, -1); } else if (sym_node->children[3] == NULL) { int index = 0; rnode[1] = resolve_node(instance_name_prefix, sym_node->children[1]); rnode[2] = resolve_node(instance_name_prefix, sym_node->children[2]); oassert(rnode[1]->type == NUMBERS && rnode[2]->type == NUMBERS); width = (rnode[1]->types.number.value - rnode[2]->types.number.value + 1); return_string = (char**)malloc(sizeof(char*)*width); for (i = 0; i < width; i++) { return_string[index] = make_full_ref_name(NULL, NULL, NULL, var_node->types.identifier, i+rnode[2]->types.number.value); index++; } } else if (sym_node->children[3] != NULL) { oassert(FALSE); } else { } } else { oassert(sym_node->type == NUMBERS); width = sym_node->types.number.binary_size; return_string = get_name_of_pins_number(sym_node, 0, width); } } else if (var_node->type == NUMBERS) { width = var_node->types.number.binary_size; return_string = get_name_of_pins_number(var_node, 0, width); } else if (var_node->type == CONCATENATE) { if (var_node->types.concat.num_bit_strings == 0) { oassert(FALSE); } else { if (var_node->types.concat.num_bit_strings == -1) { /* If this hasn't been made into a string list then do it */ make_concat_into_list_of_strings(var_node, instance_name_prefix); } width = var_node->types.concat.num_bit_strings; return_string = (char**)malloc(sizeof(char*)*width); for (i = 0; i < width; i++) // 0th bit is MSB so need to access reverse { return_string[i] = (char*)malloc(sizeof(char)*strlen(var_node->types.concat.bit_strings[var_node->types.concat.num_bit_strings-i-1])+1); sprintf(return_string[i], "%s", var_node->types.concat.bit_strings[var_node->types.concat.num_bit_strings-i-1]); } } } else { oassert(FALSE); } return_list->strings = return_string; return_list->num_strings = width; return return_list; }
/*--------------------------------------------------------------------------------------------- * (function: get_name of_port_at_bit) * Assume module connections can be one of: Array entry, Concat, Signal, Array range reference *-------------------------------------------------------------------------------------------*/ char *get_name_of_pin_at_bit(ast_node_t *var_node, int bit, char *instance_name_prefix) { char *return_string; ast_node_t *rnode[3]; if (var_node->type == ARRAY_REF) { oassert(var_node->children[0]->type == IDENTIFIERS); oassert(var_node->children[1]->type == NUMBERS); return_string = make_full_ref_name(NULL, NULL, NULL, var_node->children[0]->types.identifier, (int)var_node->children[1]->types.number.value); } else if (var_node->type == RANGE_REF) { rnode[1] = resolve_node(instance_name_prefix, var_node->children[1]); rnode[2] = resolve_node(instance_name_prefix, var_node->children[2]); oassert(var_node->children[0]->type == IDENTIFIERS); oassert(rnode[1]->type == NUMBERS && rnode[2]->type == NUMBERS); oassert((rnode[1]->types.number.value >= rnode[2]->types.number.value+bit) && bit >= 0); return_string = make_full_ref_name(NULL, NULL, NULL, var_node->children[0]->types.identifier, rnode[2]->types.number.value+bit); } else if ((var_node->type == IDENTIFIERS) && (bit == -1)) { return_string = make_full_ref_name(NULL, NULL, NULL, var_node->types.identifier, -1); } else if (var_node->type == IDENTIFIERS) { long sc_spot; int pin_index; if ((sc_spot = sc_lookup_string(local_symbol_table_sc, var_node->types.identifier)) == -1) { pin_index = 0; error_message(NETLIST_ERROR, var_node->line_number, var_node->file_number, "Missing declaration of this symbol %s\n", var_node->types.identifier); } if (((ast_node_t*)local_symbol_table_sc->data[sc_spot])->children[1] == NULL) { pin_index = bit; } else if (((ast_node_t*)local_symbol_table_sc->data[sc_spot])->children[3] == NULL) { oassert(((ast_node_t*)local_symbol_table_sc->data[sc_spot])->children[2]->type == NUMBERS); pin_index = ((ast_node_t*)local_symbol_table_sc->data[sc_spot])->children[2]->types.number.value + bit; } else oassert(FALSE); return_string = make_full_ref_name(NULL, NULL, NULL, var_node->types.identifier, pin_index); } else if (var_node->type == NUMBERS) { if (bit == -1) bit = 0; oassert(bit < var_node->types.number.binary_size); if (var_node->types.number.binary_string[var_node->types.number.binary_size-bit-1] == '1') { return_string = (char*)malloc(sizeof(char)*11+1); // ONE_VCC_CNS sprintf(return_string, "ONE_VCC_CNS"); } else if (var_node->types.number.binary_string[var_node->types.number.binary_size-bit-1] == '0') { return_string = (char*)malloc(sizeof(char)*13+1); // ZERO_GND_ZERO sprintf(return_string, "ZERO_GND_ZERO"); } else { return_string = NULL; oassert(FALSE); } } else if (var_node->type == CONCATENATE) { if (var_node->types.concat.num_bit_strings == 0) { return_string = NULL; oassert(FALSE); } else { if (var_node->types.concat.num_bit_strings == -1) { /* If this hasn't been made into a string list then do it */ make_concat_into_list_of_strings(var_node, instance_name_prefix); } return_string = (char*)malloc(sizeof(char)*strlen(var_node->types.concat.bit_strings[bit])+1); sprintf(return_string, "%s", var_node->types.concat.bit_strings[bit]); } } else { return_string = NULL; error_message(NETLIST_ERROR, var_node->line_number, var_node->file_number, "Unsupported variable type.\n"); oassert(FALSE); } return return_string; }
/*--------------------------------------------------------------------------------------------- * (function: make_concat_into_list_of_strings) * 0th idx will be the MSbit *-------------------------------------------------------------------------------------------*/ void make_concat_into_list_of_strings(ast_node_t *concat_top, char *instance_name_prefix) { int i, j; ast_node_t *rnode[3]; concat_top->types.concat.num_bit_strings = 0; concat_top->types.concat.bit_strings = NULL; /* recursively do all embedded concats */ for (i = 0; i < concat_top->num_children; i++) { if (concat_top->children[i]->type == CONCATENATE) { make_concat_into_list_of_strings(concat_top->children[i], instance_name_prefix); } } for (i = 0; i < concat_top->num_children; i++) { if (concat_top->children[i]->type == IDENTIFIERS) { char *temp_string = make_full_ref_name(NULL, NULL, NULL, concat_top->children[i]->types.identifier, -1); long sc_spot; if ((sc_spot = sc_lookup_string(local_symbol_table_sc, temp_string)) == -1) { error_message(NETLIST_ERROR, concat_top->line_number, concat_top->file_number, "Missing declaration of this symbol %s\n", temp_string); } free(temp_string); if (((ast_node_t*)local_symbol_table_sc->data[sc_spot])->children[1] == NULL) { concat_top->types.concat.num_bit_strings ++; concat_top->types.concat.bit_strings = (char**)realloc(concat_top->types.concat.bit_strings, sizeof(char*)*(concat_top->types.concat.num_bit_strings)); concat_top->types.concat.bit_strings[concat_top->types.concat.num_bit_strings-1] = get_name_of_pin_at_bit(concat_top->children[i], -1, instance_name_prefix); } else if (((ast_node_t*)local_symbol_table_sc->data[sc_spot])->children[3] == NULL) { /* reverse thorugh the range since highest bit in index will be lower in the string indx */ rnode[1] = resolve_node(instance_name_prefix, ((ast_node_t*)local_symbol_table_sc->data[sc_spot])->children[1]); rnode[2] = resolve_node(instance_name_prefix, ((ast_node_t*)local_symbol_table_sc->data[sc_spot])->children[2]); oassert(rnode[1]->type == NUMBERS && rnode[2]->type == NUMBERS); for (j = rnode[1]->types.number.value - rnode[2]->types.number.value; j >= 0; j--) { concat_top->types.concat.num_bit_strings ++; concat_top->types.concat.bit_strings = (char**)realloc(concat_top->types.concat.bit_strings, sizeof(char*)*(concat_top->types.concat.num_bit_strings)); concat_top->types.concat.bit_strings[concat_top->types.concat.num_bit_strings-1] = get_name_of_pin_at_bit(concat_top->children[i], j, instance_name_prefix); } } else if (((ast_node_t*)local_symbol_table_sc->data[sc_spot])->children[3] != NULL) { oassert(FALSE); } } else if (concat_top->children[i]->type == ARRAY_REF) { concat_top->types.concat.num_bit_strings ++; concat_top->types.concat.bit_strings = (char**)realloc(concat_top->types.concat.bit_strings, sizeof(char*)*(concat_top->types.concat.num_bit_strings)); concat_top->types.concat.bit_strings[concat_top->types.concat.num_bit_strings-1] = get_name_of_pin_at_bit(concat_top->children[i], 0, instance_name_prefix); } else if (concat_top->children[i]->type == RANGE_REF) { rnode[1] = resolve_node(instance_name_prefix, concat_top->children[i]->children[1]); rnode[2] = resolve_node(instance_name_prefix, concat_top->children[i]->children[2]); oassert(rnode[1]->type == NUMBERS && rnode[2]->type == NUMBERS); oassert(rnode[1]->types.number.value >= rnode[2]->types.number.value); int width = abs(rnode[1]->types.number.value - rnode[2]->types.number.value) + 1; //for (j = rnode[1]->types.number.value - rnode[2]->types.number.value; j >= 0; j--) // Changed to forward to fix concatenation bug. for (j = 0; j < width; j++) { concat_top->types.concat.num_bit_strings ++; concat_top->types.concat.bit_strings = (char**)realloc(concat_top->types.concat.bit_strings, sizeof(char*)*(concat_top->types.concat.num_bit_strings)); concat_top->types.concat.bit_strings[concat_top->types.concat.num_bit_strings-1] = get_name_of_pin_at_bit(concat_top->children[i], ((rnode[1]->types.number.value - rnode[2]->types.number.value))-j, instance_name_prefix); } } else if (concat_top->children[i]->type == NUMBERS) { if(concat_top->children[i]->types.number.base == DEC) { error_message(NETLIST_ERROR, concat_top->line_number, concat_top->file_number, "Concatenation can't include decimal numbers due to conflict on bits\n"); } // Changed to reverse to fix concatenation bug. for (j = concat_top->children[i]->types.number.binary_size-1; j>= 0; j--) { concat_top->types.concat.num_bit_strings ++; concat_top->types.concat.bit_strings = (char**)realloc(concat_top->types.concat.bit_strings, sizeof(char*)*(concat_top->types.concat.num_bit_strings)); concat_top->types.concat.bit_strings[concat_top->types.concat.num_bit_strings-1] = get_name_of_pin_at_bit(concat_top->children[i], j, instance_name_prefix); } } else if (concat_top->children[i]->type == CONCATENATE) { /* forward through list since we build concatenate list in idx order of MSB at index 0 and LSB at index list_size */ for (j = 0; j < concat_top->children[i]->types.concat.num_bit_strings; j++) { concat_top->types.concat.num_bit_strings ++; concat_top->types.concat.bit_strings = (char**)realloc(concat_top->types.concat.bit_strings, sizeof(char*)*(concat_top->types.concat.num_bit_strings)); concat_top->types.concat.bit_strings[concat_top->types.concat.num_bit_strings-1] = get_name_of_pin_at_bit(concat_top->children[i], j, instance_name_prefix); } } else { error_message(NETLIST_ERROR, concat_top->line_number, concat_top->file_number, "Unsupported operation within a concatenation.\n"); } } }
/*--------------------------------------------------------------------------------------------- * (function: output_activation_file_ace_and_function_file) * Creates the 2 files (+1 .ace file) for the power estimation. * Traverses the blif_netlist, net_netlist to print out tranisition densities * and static probabilities. Also, pushes out functions based on the clustered * netlist. *-------------------------------------------------------------------------------------------*/ void output_activation_file_ace_and_function_file(char *output_filename, int lut_size, netlist_t *LUT_netlist, netlist_t *CLUSTER_netlist) { char *ace_file_name = (char*)malloc(sizeof(char)*(strlen(output_filename)+4+1)); char *ac2_file_name = (char*)malloc(sizeof(char)*(strlen(output_filename)+4+1)); char *function_file_name = (char*)malloc(sizeof(char)*(strlen(output_filename)+4+1)); int i, j, k, l; FILE *ace_out; FILE *ac2_out; FILE *function_out; long sc_spot; nnode_t *lut_node; activation_t *act_data; sprintf(ace_file_name, "%s.ace", output_filename); sprintf(ac2_file_name, "%s.ac2", output_filename); sprintf(function_file_name, "%s.fun", output_filename); ace_out = fopen(ace_file_name, "w"); if (ace_out == NULL) { error_message(ACTIVATION_ERROR, -1, -1, "Could not open output file %s\n", ace_file_name); } ac2_out = fopen(ac2_file_name, "w"); if (ac2_out == NULL) { error_message(ACTIVATION_ERROR, -1, -1, "Could not open output file %s\n", ac2_file_name); } function_out = fopen(function_file_name, "w"); if (function_out == NULL) { error_message(ACTIVATION_ERROR, -1, -1, "Could not open output file %s\n", function_file_name); } /* Go through the LUT netlist and print out the ace files */ for (i = 0; i < LUT_netlist->num_forward_levels; i++) { for (j = 0; j < LUT_netlist->num_at_forward_level[i]; j++) { /* initialize the activation data */ nnode_t *current_node = LUT_netlist->forward_levels[i][j]; activation_t *act_data = (activation_t*)current_node->node_data; if (current_node->type != OUTPUT_NODE) { for (k = 0; k < current_node->num_output_pins; k++) { if (current_node->output_pins[0]->net->num_fanout_pins != 0) { /* IF this node fans out */ fprintf(ace_out, "%s %f %f\n", current_node->name, act_data->static_probability[k], act_data->transition_density[k]); } } } else { fprintf(ace_out, "out:%s %f %f\n", current_node->name, act_data->static_probability[0], act_data->transition_density[0]); } } } fclose(ace_out); /* now create the ac2 file and function file */ /* first we spit out the clocks */ for (i = 0; i < CLUSTER_netlist->num_clocks; i++) { nnode_t *cluster_node = CLUSTER_netlist->clocks[i]; fprintf (ac2_out, "global_net_probability %s 0.5\n", cluster_node->name); fprintf (ac2_out, "global_net_density %s 2.0\n", cluster_node->name); } /* next we make the intercluster probabilities for inputs */ for (i = 0; i < CLUSTER_netlist->num_top_input_nodes; i++) { nnode_t *cluster_node = CLUSTER_netlist->top_input_nodes[i]; if (cluster_node->type == CLOCK_NODE) { continue; } /* find the equivalent blif point */ if ((sc_spot = sc_lookup_string(LUT_netlist->nodes_sc, cluster_node->name)) == -1) { warning_message(ACTIVATION_ERROR, -1, -1, "Could not find %s INPUT in LUT netlist ...\n", cluster_node->name); continue; } lut_node = (nnode_t *)LUT_netlist->nodes_sc->data[sc_spot]; act_data = (activation_t*)lut_node->node_data; oassert(lut_node->num_output_pins == 1); /* assumption now, but will change with heterognenous blocks */ fprintf (ac2_out, "intercluster_net_probability %s %f\n", cluster_node->name, act_data->static_probability[0]); fprintf (ac2_out, "intercluster_net_density %s %f\n", cluster_node->name, act_data->transition_density[0]); } /* next we make the intercluster probabilities for inputs */ for (i = 0; i < CLUSTER_netlist->num_top_output_nodes; i++) { nnode_t *cluster_node = CLUSTER_netlist->top_output_nodes[i]; /* find the equivalent blif point */ if ((sc_spot = sc_lookup_string(LUT_netlist->nodes_sc, cluster_node->name)) == -1) { warning_message(ACTIVATION_ERROR, -1, -1, "Could not find %s OUTPUT in LUT netlist ...\n", cluster_node->name); continue; } lut_node = (nnode_t *)LUT_netlist->nodes_sc->data[sc_spot]; act_data = (activation_t*)lut_node->node_data; oassert(lut_node->num_output_pins == 0); /* assumption now, but will change with heterognenous blocks */ fprintf (ac2_out, "intercluster_net_probability %s %f\n", (cluster_node->name+4), act_data->static_probability[0]); /* +4 to skip "out:" that isn't needed in output */ fprintf (ac2_out, "intercluster_net_density %s %f\n", (cluster_node->name+4), act_data->transition_density[0]); } /* next we make the intercluster probabilities */ for (i = 0; i < CLUSTER_netlist->num_internal_nodes; i++) { nnode_t *cluster_node = CLUSTER_netlist->internal_nodes[i]; netlist_t* internal_subblocks = cluster_node->internal_netlist; if (internal_subblocks == NULL) { /* INPUT/OUTPUT pins and globals (clocks) have no subblocks */ continue; } /* now we process the internal structure of the node, which represents the subblocks. This is stored in an internall netlist. */ for (k = 0; k < internal_subblocks->num_internal_nodes; k++) { nnode_t *current_subblock = internal_subblocks->internal_nodes[k]; char *output_search_name = (char*)malloc(sizeof(char)*(strlen(current_subblock->name)+1+4)); sprintf(output_search_name, "out:%s", current_subblock->name); if ((sc_spot = sc_lookup_string(internal_subblocks->nodes_sc, output_search_name)) != -1) { /* IF - this is an output of the cluster then we need inter cluster info */ /* now find this node */ /* find the equivalent blif point */ if ((sc_spot = sc_lookup_string(LUT_netlist->nodes_sc, current_subblock->name)) == -1) { error_message(ACTIVATION_ERROR, -1, -1, "Could not find %s in LUT netlist ...\n", current_subblock->name); } lut_node = (nnode_t *)LUT_netlist->nodes_sc->data[sc_spot]; act_data = (activation_t*)lut_node->node_data; /* Finally, put in th output switching values */ fprintf (ac2_out, "intercluster_net_probability %s %f\n", current_subblock->name, act_data->static_probability[0]); fprintf (ac2_out, "intercluster_net_density %s %f\n", current_subblock->name, act_data->transition_density[0]); } free(output_search_name); } } /* next we process the subblocks */ for (i = 0; i < CLUSTER_netlist->num_internal_nodes; i++) { nnode_t *cluster_node = CLUSTER_netlist->internal_nodes[i]; netlist_t* internal_subblocks = cluster_node->internal_netlist; if (internal_subblocks == NULL) { /* INPUT/OUTPUT pins and globals (clocks) have no subblocks */ oassert(FALSE); continue; } /* now we process the internal structure of the node, which represents the subblocks. This is stored in an internall netlist. */ for (k = 0; k < internal_subblocks->num_internal_nodes; k++) { nnode_t *current_subblock = internal_subblocks->internal_nodes[k]; char probability_string[4096]; char density_string[4096]; int input_active_count = 0; short is_clock = FALSE; int input_index = 0; sprintf(probability_string, "subblock_probability %s", current_subblock->name); sprintf(density_string, "subblock_density %s", current_subblock->name); /* first get all the input values */ for (l = 0; l < lut_size+1; l++) { if (current_subblock->input_pins[input_index] != NULL) { nnode_t *input_node = current_subblock->input_pins[input_index]->net->driver_pin->node; /* find the equivalent blif point */ if ((sc_spot = sc_lookup_string(LUT_netlist->nodes_sc, input_node->name)) == -1) { error_message(ACTIVATION_ERROR, -1, -1, "Could not find %s in LUT netlist ...\n", input_node->name); } lut_node = (nnode_t *)LUT_netlist->nodes_sc->data[sc_spot]; act_data = (activation_t*)lut_node->node_data; if (lut_node->type == CLOCK_NODE) { /* IF - the clock spot */ if (l == lut_size) { /* only print it out if this is the last spot */ sprintf(probability_string, "%s %f", probability_string, act_data->static_probability[0]); sprintf(density_string, "%s %f", density_string, act_data->transition_density[0]); is_clock = TRUE; } else { sprintf(probability_string, "%s 0.0", probability_string); sprintf(density_string, "%s 0.0", density_string); } } else { sprintf(probability_string, "%s %f", probability_string, act_data->static_probability[0]); sprintf(density_string, "%s %f", density_string, act_data->transition_density[0]); input_index++; } input_active_count ++; } else { /* No connection to this input */ sprintf(probability_string, "%s 0.0", probability_string); sprintf(density_string, "%s 0.0", density_string); } } if (is_clock == FALSE) { /* IF - there is no clock meaning this is just a LUT, output the probabilities */ sprintf(probability_string, "%s 0.0", probability_string); sprintf(density_string, "%s 0.0", density_string); } /* now find this node */ /* find the equivalent blif point */ if ((sc_spot = sc_lookup_string(LUT_netlist->nodes_sc, current_subblock->name)) == -1) { error_message(ACTIVATION_ERROR, -1, -1, "Could not find %s in LUT netlist ...\n", current_subblock->name); } lut_node = (nnode_t *)LUT_netlist->nodes_sc->data[sc_spot]; act_data = (activation_t*)lut_node->node_data; /* find the values of the switching between LUT and FF */ if ((lut_node->type == FF_NODE) && (input_active_count > 0)) { /* LUT + FF */ /* IF - this is a FF node and has more than 1 input, then it's a LUT-FF */ activation_t *input_node_to_ff_act_data = (activation_t *)lut_node->input_pins[0]->net->driver_pin->node->node_data; sprintf(probability_string, "%s %f", probability_string, input_node_to_ff_act_data->static_probability[0]); sprintf(density_string, "%s %f", density_string, input_node_to_ff_act_data->transition_density[0]); /* print out the function of this node based on it's inputs function */ oassert (lut_node->input_pins[0]->net->driver_pin->node->associated_function != NULL) fprintf(function_out, "subblock_function %s ", lut_node->name); for (l = 0; l < pow2(lut_size); l++) { fprintf(function_out, "%d", lut_node->input_pins[0]->net->driver_pin->node->associated_function[l]); } fprintf(function_out, "\n"); } else if (lut_node->type == FF_NODE) { /* FF */ /* ELSE - this is a FF_NODE only */ sprintf(probability_string, "%s 0.0", probability_string); sprintf(density_string, "%s 0.0", density_string); /* output function is just a buffer since this is just a FF */ fprintf(function_out, "subblock_function %s ", lut_node->name); for (l = 0; l < pow2(lut_size); l++) { if (l % 2 == 0) { fprintf(function_out, "0"); } else { fprintf(function_out, "1"); } } fprintf(function_out, "\n"); } else { /* LUT */ /* print out the function of this node based on it's just a LUT */ oassert (lut_node->associated_function != NULL) fprintf(function_out, "subblock_function %s ", lut_node->name); for (l = 0; l < pow2(lut_size); l++) { fprintf(function_out, "%d", lut_node->associated_function[l]); } fprintf(function_out, "\n"); } /* Finally, put in th output switching values */ sprintf(probability_string, "%s %f", probability_string, act_data->static_probability[0]); sprintf(density_string, "%s %f", density_string, act_data->transition_density[0]); /* output the values created for the subblock */ fprintf(ac2_out, "%s\n", probability_string); fprintf(ac2_out, "%s\n", density_string); } } fclose(function_out); fclose(ac2_out); }