/*--------------------------------------------------------------------------------------------- * (function: *create_tree_node_long_long_number) *-------------------------------------------------------------------------------------------*/ ast_node_t *create_tree_node_long_long_number(long long number, int constant_bit_size, int line_number, int file_number) { int flag = 0; ast_node_t* new_node = create_node_w_type(NUMBERS, line_number, current_parse_file); new_node->types.number.base = LONG_LONG; new_node->types.number.value = number; if (number < 0) { flag = 1; number = number * -1; } oassert (ceil((log(number+1))/log(2)) <= constant_bit_size); new_node->types.number.binary_size = constant_bit_size; new_node->types.number.binary_string = convert_long_long_to_bit_string(number, new_node->types.number.binary_size); if (flag == 1) twos_complement(new_node->types.number.binary_string); return new_node; }
/* * A wrapper for the other string to bit string conversion functions. * Converts an arbitrary length string of base 16, 10, 8, or 2 to a * string of 1s and 0s of the given length, padding or truncating * the higher accordingly. The returned string will be little * endian. Null will be returned if the radix is invalid. * * Base 10 strings will be limited in length to a long long, but * an error will be issued if the number will be truncated. * */ char *convert_string_of_radix_to_bit_string(char *string, int radix, int binary_size) { if (radix == 16) { return convert_hex_string_of_size_to_bit_string(0, string, binary_size); } else if (radix == 10) { long long number = convert_dec_string_of_size_to_long_long(string, binary_size); return convert_long_long_to_bit_string(number, binary_size); } else if (radix == 8) { return convert_oct_string_of_size_to_bit_string(string, binary_size); } else if (radix == 2) { return convert_binary_string_of_size_to_bit_string(0, string, binary_size); } else { return NULL; } }
/*------------------------------------------------------------------------- * (function: define_logical_function) *-----------------------------------------------------------------------*/ void define_logical_function(nnode_t *node, short type, FILE *out) { int i, j; char *temp_string; int flag = 0; fprintf(out, ".names"); if (global_args.high_level_block != NULL) { /* printout all the port hookups */ for (i = 0; i < node->num_input_pins; i++) { /* now hookup the input wires with their respective ports. [1+i] to skip output spot. */ if (node->input_pins[i]->net->driver_pin->node->related_ast_node != NULL) fprintf(out, " %s^^%i-%i", node->input_pins[i]->net->driver_pin->node->name, node->input_pins[i]->net->driver_pin->node->related_ast_node->far_tag, node->input_pins[i]->net->driver_pin->node->related_ast_node->high_number); else fprintf(out, " %s", node->input_pins[i]->net->driver_pin->node->name); } /* now print the output */ if (node->related_ast_node != NULL) fprintf(out, " %s^^%i-%i", node->name, node->related_ast_node->far_tag, node->related_ast_node->high_number); else fprintf(out, " %s", node->name); } else { /* printout all the port hookups */ for (i = 0; i < node->num_input_pins; i++) { /* now hookup the input wires with their respective ports. [1+i] to skip output spot. */ /* Just print the driver_pin->name NOT driver_pin->node->name -- KEN */ nnet_t *net = node->input_pins[i]->net; if (net && net->driver_pin) { if (net->driver_pin->name != NULL) { if ((net->driver_pin->node->type == MULTIPLY) || (net->driver_pin->node->type == HARD_IP) || (net->driver_pin->node->type == MEMORY) || (net->driver_pin->node->type == ADD) || (net->driver_pin->node->type == MINUS) ) { fprintf(out, " %s", net->driver_pin->name); } } else { fprintf(out, " %s", net->driver_pin->node->name); } } else { int line_number = node->related_ast_node?node->related_ast_node->line_number:0; warning_message(NETLIST_ERROR, line_number, -1, "Net %s driving node %s is itself undriven.", net->name, node->name); fprintf(out, " %s", "unconn"); } } /* now print the output */ fprintf(out, " %s", node->name); } fprintf(out, "\n"); oassert(node->num_output_pins == 1); /* print out the blif definition of this gate */ switch (node->type) { case LOGICAL_AND: { /* generates: 111111 1 */ for (i = 0; i < node->num_input_pins; i++) { fprintf(out, "1"); } fprintf(out, " 1\n"); break; } case LOGICAL_OR: { /* generates: 1----- 1\n-1----- 1\n ... */ for (i = 0; i < node->num_input_pins; i++) { for (j = 0; j < node->num_input_pins; j++) { if (i == j) fprintf(out, "1"); else fprintf(out, "-"); } fprintf(out, " 1\n"); } break; } case LOGICAL_NAND: { /* generates: 0----- 1\n-0----- 1\n ... */ for (i = 0; i < node->num_input_pins; i++) { for (j = 0; j < node->num_input_pins; j++) { if (i == j) fprintf(out, "0"); else fprintf(out, "-"); } fprintf(out, " 1\n"); } break; } case LOGICAL_NOT: case LOGICAL_NOR: { /* generates: 0000000 1 */ for (i = 0; i < node->num_input_pins; i++) { fprintf(out, "0"); } fprintf(out, " 1\n"); break; } case LOGICAL_EQUAL: case LOGICAL_XOR: { oassert(node->num_input_pins <= 3); /* generates: a 1 when odd number of 1s */ for (i = 0; i < my_power(2, node->num_input_pins); i++) { if ((i % 8 == 1) || (i % 8 == 2) || (i % 8 == 4) || (i % 8 == 7)) { temp_string = convert_long_long_to_bit_string(i, node->num_input_pins); fprintf(out, "%s", temp_string); free(temp_string); fprintf(out, " 1\n"); } } break; } case NOT_EQUAL: case LOGICAL_XNOR: { oassert(node->num_input_pins <= 3); for (i = 0; i < my_power(2, node->num_input_pins); i++) { if ((i % 8 == 0) || (i % 8 == 3) || (i % 8 == 5) || (i % 8 == 6)) { temp_string = convert_long_long_to_bit_string(i, node->num_input_pins); fprintf(out, "%s", temp_string); free(temp_string); fprintf(out, " 1\n"); } } break; } default: oassert(FALSE); break; } fprintf(out, "\n"); if (flag == 1) output_blif_pin_connect(node, out); }
/*--------------------------------------------------------------------------------------------- * (function: create_tree_node_number) *-------------------------------------------------------------------------------------------*/ ast_node_t *create_tree_node_number(char* number, int line_number, int file_number) { ast_node_t* new_node = create_node_w_type(NUMBERS, line_number, current_parse_file); char *string_pointer = number; int index_string_pointer = 0; char *temp_string; short flag_constant_decimal = FALSE; /* find the ' character if it's a base */ for (string_pointer=number; *string_pointer; string_pointer++) { if (*string_pointer == '\'') { break; } index_string_pointer++; } if (index_string_pointer == strlen(number)) { flag_constant_decimal = TRUE; /* this is base d */ new_node->types.number.base = DEC; /* reset to the front */ string_pointer = number; /* size is the rest of the string */ new_node->types.number.size = strlen((string_pointer)); /* assign the remainder of the number to a string */ new_node->types.number.number = strdup((string_pointer)); } else { /* there is a base in the form: number[bhod]'number */ switch(tolower(*(string_pointer+1))) { case 'd': new_node->types.number.base = DEC; break; case 'h': new_node->types.number.base = HEX; break; case 'o': new_node->types.number.base = OCT; break; case 'b': new_node->types.number.base = BIN; break; default: oassert(FALSE); } /* check if the size matches the design specified size */ temp_string = strdup(number); temp_string[index_string_pointer] = '\0'; /* size is the rest of the string */ new_node->types.number.size = atoi(temp_string); free(temp_string); /* move to the digits */ string_pointer += 2; /* assign the remainder of the number to a string */ new_node->types.number.number = strdup((string_pointer)); } /* check for decimal numbers without the formal 2'd... format */ if (flag_constant_decimal == FALSE) { /* size describes how may bits */ new_node->types.number.binary_size = new_node->types.number.size; } else { /* size is for a constant that needs */ if (strcmp(new_node->types.number.number, "0") != 0) { new_node->types.number.binary_size = ceil((log(convert_dec_string_of_size_to_long_long(new_node->types.number.number, new_node->types.number.size)+1))/log(2)); } else { new_node->types.number.binary_size = 1; } } /* add in the values for all the numbers */ switch (new_node->types.number.base) { case(DEC): // This will have limited width. new_node->types.number.value = convert_dec_string_of_size_to_long_long(new_node->types.number.number, new_node->types.number.size); new_node->types.number.binary_string = convert_long_long_to_bit_string(new_node->types.number.value, new_node->types.number.binary_size); break; case(HEX): new_node->types.number.binary_size *= 4; new_node->types.number.value = strtoll(new_node->types.number.number,NULL,16); // This will have limited width. // This will have full width. new_node->types.number.binary_string = convert_hex_string_of_size_to_bit_string(new_node->types.number.number, new_node->types.number.binary_size); break; case(OCT): new_node->types.number.binary_size *= 3; new_node->types.number.value = strtoll(new_node->types.number.number,NULL,8); // This will have limited width. // This will have full width. new_node->types.number.binary_string = convert_oct_string_of_size_to_bit_string(new_node->types.number.number, new_node->types.number.binary_size); break; case(BIN): // This will have limited width. new_node->types.number.value = strtoll(new_node->types.number.number,NULL,2); // This will have full width. new_node->types.number.binary_string = convert_binary_string_of_size_to_bit_string(new_node->types.number.number, new_node->types.number.binary_size); break; } return new_node; }