| #include <stdlib.h> |
| |
| #include "vtr_assert.h" |
| |
| #include "ace.h" |
| #include "io_ace.h" |
| |
| #include "base/abc/abc.h" |
| |
| bool check_if_fanout_is_po(Abc_Ntk_t * ntk, Abc_Obj_t * obj); |
| |
| char * hdl_name_ptr = NULL; |
| |
| bool check_if_fanout_is_po(Abc_Ntk_t * /*ntk*/, Abc_Obj_t * obj) { |
| Abc_Obj_t * fanout; |
| int i; |
| |
| if (Abc_ObjIsCo(obj)) { |
| return FALSE; |
| } |
| |
| Abc_ObjForEachFanout(obj, fanout, i) |
| { |
| if (Abc_ObjIsPo(fanout)) { |
| return TRUE; |
| } |
| } |
| |
| return FALSE; |
| } |
| |
| void ace_io_print_activity(Abc_Ntk_t * ntk, FILE * fp) { |
| Abc_Obj_t * obj; |
| Abc_Obj_t * obj_new; |
| int i; |
| |
| Abc_NtkForEachObj(ntk, obj, i) |
| { |
| VTR_ASSERT(obj->pCopy); |
| obj_new = obj->pCopy; |
| |
| Ace_Obj_Info_t * info = Ace_ObjInfo(obj); |
| //Ace_Obj_Info_t * info = malloc(sizeof(Ace_Obj_Info_t)); |
| |
| char * name = NULL; |
| |
| if (check_if_fanout_is_po(ntk, obj)) { |
| //continue; |
| } |
| |
| switch (Abc_ObjType(obj)) { |
| |
| case ABC_OBJ_PI: |
| |
| name = Abc_ObjName(Abc_ObjFanout0(obj_new)); |
| break; |
| |
| case ABC_OBJ_BO: |
| name = Abc_ObjName(Abc_ObjFanout0(obj_new)); |
| break; |
| |
| case ABC_OBJ_LATCH: |
| case ABC_OBJ_PO: |
| case ABC_OBJ_BI: |
| break; |
| |
| case ABC_OBJ_NODE: |
| name = Abc_ObjName(Abc_ObjFanout0(obj_new)); |
| //name = Abc_ObjName(obj); |
| break; |
| |
| default: |
| //printf("Unkown Type: %d\n", Abc_ObjType(obj)); |
| //VTR_ASSERT(0); |
| break; |
| } |
| |
| /* |
| if (Abc_ObjType(obj) == ABC_OBJ_BI || Abc_ObjType(obj) == ABC_OBJ_LATCH) |
| { |
| continue; |
| } |
| |
| */ |
| |
| if (name && strcmp(name, "unconn")) { |
| if (fp != NULL) { |
| //fprintf (fp, "%d-%d %s\n", Abc_ObjId(obj), Abc_ObjType(obj), name); |
| //fprintf (fp, "%d-%d %s %f %f %f\n", Abc_ObjId(obj), Abc_ObjType(obj), name, info->static_prob, info->switch_prob, info->switch_act); |
| fprintf(fp, "%s %f %f\n", name, info->static_prob, |
| info->switch_act); |
| |
| } else { |
| printf("%s %f %f\n", Abc_ObjName(obj), info->static_prob, |
| info->switch_act); |
| } |
| } |
| } |
| } |
| |
| int ace_io_parse_argv(int argc, char ** argv, FILE ** BLIF, FILE ** IN_ACT, |
| FILE ** OUT_ACT, char * blif_file_name, char * new_blif_file_name, |
| ace_pi_format_t * pi_format, double *p, double * d, int * seed, char** clk_name) { |
| int i; |
| char option; |
| |
| if (argc <= 1) { |
| printf("Error: no parameters specified.\n"); |
| ace_io_print_usage(); |
| exit(1); |
| } |
| |
| i = 1; |
| while (i < argc) { |
| if (argv[i][0] == '-') { |
| option = argv[i][1]; |
| i++; |
| switch (option) { |
| case 'b': |
| *BLIF = fopen(argv[i], "r"); |
| strncpy(blif_file_name, argv[i], BLIF_FILE_NAME_LEN - 1); |
| blif_file_name[strlen(argv[i])] = '\0'; |
| break; |
| case 'n': |
| strncpy(new_blif_file_name, argv[i], BLIF_FILE_NAME_LEN - 1); |
| new_blif_file_name[strlen(argv[i])] = '\0'; |
| break; |
| case 'o': |
| *OUT_ACT = fopen(argv[i], "w"); |
| break; |
| case 'a': |
| *pi_format = ACE_ACT; |
| *IN_ACT = fopen(argv[i], "r"); |
| break; |
| case 'v': |
| *pi_format = ACE_VEC; |
| *IN_ACT = fopen(argv[i], "r"); |
| break; |
| case 'p': |
| *pi_format = ACE_PD; |
| *p = atof(argv[i]); |
| break; |
| case 'd': |
| *pi_format = ACE_PD; |
| *d = atof(argv[i]); |
| break; |
| case 's': |
| *seed = atoi(argv[i]); |
| break; |
| case 'c': |
| *clk_name = argv[i]; |
| break; |
| default: |
| ace_io_print_usage(); |
| exit(1); |
| } |
| } |
| i++; |
| } |
| |
| if (*BLIF == NULL) { |
| printf("No BLIF file specified\n"); |
| ace_io_print_usage(); |
| exit(1); |
| } |
| |
| if (*clk_name == NULL) { |
| printf("No clock specified\n"); |
| ace_io_print_usage(); |
| exit(1); |
| } |
| return 0; |
| } |
| |
| void ace_io_print_usage() { |
| (void) fprintf(stderr, "usage: ace\n"); |
| |
| (void) fprintf(stderr, " --+\n"); |
| (void) fprintf(stderr, " -b [input circuitname.blif] | required\n"); |
| (void) fprintf(stderr, " -c [clock name] | required\n"); |
| (void) fprintf(stderr, " -n [new circuitname.blif] |\n"); |
| (void) fprintf(stderr, " --+\n"); |
| (void) fprintf(stderr, "\n"); |
| (void) fprintf(stderr, " --+\n"); |
| (void) fprintf(stderr, " -o [output activity filename] | optional\n"); |
| (void) fprintf(stderr, " --+\n"); |
| (void) fprintf(stderr, "\n"); |
| (void) fprintf(stderr, " --+\n"); |
| (void) fprintf(stderr, " -a [input activity filename] | optional\n"); |
| (void) fprintf(stderr, " or |\n"); |
| (void) fprintf(stderr, " -v [input vector filename] |\n"); |
| (void) fprintf(stderr, " or |\n"); |
| (void) fprintf(stderr, " -p [PI static probability] |\n"); |
| (void) fprintf(stderr, " -d [PI switching activity] |\n"); |
| (void) fprintf(stderr, " --+\n"); |
| } |
| |
| int ace_io_read_activity(Abc_Ntk_t * ntk, FILE * in_file_desc, |
| ace_pi_format_t pi_format, double p, double d, const char * clk_name) { |
| int error = 0; |
| int i; |
| Abc_Obj_t * obj_ptr; |
| Ace_Obj_Info_t * info; |
| Nm_Man_t * name_manager = ntk->pManName; |
| int num_Pi = Abc_NtkPiNum(ntk); |
| |
| printf("Name Manager Entries: %d\n", Nm_ManNumEntries(name_manager)); |
| |
| /* |
| int clk_pi_obj_id = Nm_ManFindIdByName(name_manager, (char *) clk_name, ABC_OBJ_PI); |
| printf ("Clk PI ID: %d\n", clk_pi_obj_id); |
| |
| Abc_Obj_t * clk_obj_ptr; |
| clk_obj_ptr = Abc_NtkObj(ntk, clk_pi_obj_id); |
| printf("Clock Fanouts: %d\n", clk_obj_ptr->vFanouts.nSize); |
| */ |
| |
| Vec_Ptr_t * node_vec; |
| node_vec = Abc_NtkDfsSeq(ntk); |
| |
| // Initialize node information structure |
| Vec_PtrForEachEntry(Abc_Obj_t*, node_vec, obj_ptr, i) |
| { |
| info = Ace_ObjInfo(obj_ptr); |
| info->static_prob = ACE_OPEN; |
| info->switch_prob = ACE_OPEN; |
| info->switch_act = ACE_OPEN; |
| } |
| |
| //info = Ace_InfoPtrGet(clk_obj_ptr); |
| //info->static_prob = 0.5; |
| //info->switch_prob = 1.0; |
| //info->switch_act = 1.0; |
| |
| if (in_file_desc == NULL) { |
| if (pi_format == ACE_ACT || pi_format == ACE_VEC) { |
| printf("Cannot open input file\n"); |
| error = ACE_ERROR; |
| } else { |
| VTR_ASSERT(p >= 0.0 && p <= 1.0); |
| VTR_ASSERT(d >= 0.0 && d <= 1.0); |
| VTR_ASSERT(d <= 2.0 * p); |
| VTR_ASSERT(d <= 2.0 * (1.0 - p)); |
| |
| Abc_NtkForEachPi(ntk, obj_ptr, i) |
| { |
| info = Ace_ObjInfo(obj_ptr); |
| |
| if (strcmp(Abc_ObjName(obj_ptr), clk_name) == 0) { |
| info->static_prob = 0.5; |
| info->switch_prob = 1; |
| info->switch_act = 2; |
| } else { |
| info->static_prob = p; |
| info->switch_prob = d; |
| info->switch_act = d; |
| } |
| } |
| } |
| } else { |
| char line[ACE_CHAR_BUFFER_SIZE]; |
| |
| if (pi_format == ACE_ACT) { |
| char pi_name[ACE_CHAR_BUFFER_SIZE]; |
| double static_prob, switch_prob; |
| Abc_Obj_t * pi_obj_ptr; |
| int pi_obj_id; |
| char* res; |
| |
| printf("Reading activity file...\n"); |
| |
| // Read real PIs activity values from file |
| res = fgets(line, ACE_CHAR_BUFFER_SIZE, in_file_desc); |
| VTR_ASSERT(res); |
| while (!feof(in_file_desc)) { |
| sscanf(line, "%s %lf %lf\n", pi_name, &static_prob, |
| &switch_prob); |
| |
| pi_obj_id = Nm_ManFindIdByName(name_manager, pi_name, |
| ABC_OBJ_PI); |
| if (pi_obj_id == -1) { |
| printf("Primary input %s does not exist\n", pi_name); |
| error = ACE_ERROR; |
| break; |
| } |
| pi_obj_ptr = Abc_NtkObj(ntk, pi_obj_id); |
| |
| VTR_ASSERT(static_prob >= 0.0 && static_prob <= 1.0); |
| VTR_ASSERT(switch_prob >= 0.0 && switch_prob <= 1.0); |
| |
| info = Ace_ObjInfo(pi_obj_ptr); |
| info->static_prob = static_prob; |
| info->switch_prob = switch_prob; |
| info->switch_act = switch_prob; |
| |
| res = fgets(line, ACE_CHAR_BUFFER_SIZE, in_file_desc); |
| VTR_ASSERT(res); |
| } |
| } else if (pi_format == ACE_VEC) { |
| printf("Reading vector file...\n"); |
| |
| int num_vec = 0; |
| int * high; |
| int * toggles; |
| int * current; |
| char vector[ACE_CHAR_BUFFER_SIZE]; |
| char* res; |
| |
| res = fgets(line, ACE_CHAR_BUFFER_SIZE, in_file_desc); |
| VTR_ASSERT(res); |
| while (!feof(in_file_desc)) { |
| res = fgets(line, ACE_CHAR_BUFFER_SIZE, in_file_desc); |
| VTR_ASSERT(res); |
| num_vec++; |
| } |
| Abc_NtkForEachPi(ntk, obj_ptr, i) |
| { |
| info = Ace_ObjInfo(obj_ptr); |
| info->values = (int *) malloc(num_vec * sizeof(int)); |
| } |
| fseek(in_file_desc, 0, SEEK_SET); |
| |
| high = (int *) calloc(num_Pi, sizeof(int)); |
| toggles = (int *) calloc(num_Pi, sizeof(int)); |
| current = (int *) calloc(num_Pi, sizeof(int)); |
| |
| |
| num_vec = 0; |
| res = fgets(line, ACE_CHAR_BUFFER_SIZE, in_file_desc); |
| VTR_ASSERT(res); |
| while (!feof(in_file_desc)) { |
| sscanf(line, "%s\n", vector); |
| |
| if (strlen(vector) != num_Pi) { |
| printf( |
| "Error: vector length (%zu) doesn't match number of inputs (%d)\n", |
| strlen(vector), num_Pi); |
| error = ACE_ERROR; |
| break; |
| } |
| VTR_ASSERT(strlen(vector) == num_Pi); |
| |
| if (num_vec == 0) { |
| Abc_NtkForEachPi(ntk, obj_ptr, i) |
| { |
| high[i] = (vector[i] == '1'); |
| toggles[i] = 0; |
| current[i] = (vector[i] == '1'); |
| } |
| } else { |
| Abc_NtkForEachPi(ntk, obj_ptr, i) |
| { |
| high[i] += (vector[i] == '1'); |
| if ((vector[i] == '0' && current[i]) |
| || (vector[i] == '1' && !current[i])) { |
| toggles[i]++; |
| } |
| current[i] = (vector[i] == '1'); |
| } |
| } |
| |
| Abc_NtkForEachPi(ntk, obj_ptr, i) |
| { |
| info = Ace_ObjInfo(obj_ptr); |
| info->values[num_vec] = (vector[i] == '1'); |
| } |
| |
| res = fgets(line, ACE_CHAR_BUFFER_SIZE, in_file_desc); |
| VTR_ASSERT(res); |
| num_vec++; |
| } |
| |
| if (!error) { |
| Abc_NtkForEachPi(ntk, obj_ptr, i) |
| { |
| VTR_ASSERT(num_vec > 0); |
| |
| info = Ace_ObjInfo(obj_ptr); |
| info->static_prob = (double) high[i] / (double) num_vec; |
| info->static_prob = MAX(0.0, info->static_prob); |
| info->static_prob = MIN(1.0, info->static_prob); |
| |
| info->switch_prob = (double) toggles[i] / (double) num_vec; |
| info->switch_prob = MAX(0.0, info->switch_prob); |
| info->switch_prob = MIN(1.0, info->switch_prob); |
| |
| info->switch_act = info->switch_prob; |
| } |
| } |
| |
| free(toggles); |
| free(high); |
| free(current); |
| } else { |
| printf("Error: Unkown activity file format.\n"); |
| error = ACE_ERROR; |
| } |
| } |
| |
| Vec_PtrFree(node_vec); |
| |
| return error; |
| } |
| |