#include "espresso.h"
Go to the source code of this file.
Functions | |
map_dcset (pPLA PLA) | |
map_output_symbolic (pPLA PLA) | |
find_inputs (pcover A, pPLA PLA, symbolic_list_t *list, int base, int value, pcover *newF, pcover *newD) | |
map_symbolic (pPLA PLA) | |
pcover | map_symbolic_cover (pcover T, symbolic_list_t *list, int base) |
form_bitvector (pset p, int base, int value, symbolic_list_t *list) | |
symbolic_hack_labels (pPLA PLA, symbolic_t *list, pset compress, int new_size, int old_size, int size_added) | |
static pcover | fsm_simplify (pcover F) |
disassemble_fsm (pPLA PLA, int verbose_mode) |
disassemble_fsm | ( | pPLA | PLA, | |
int | verbose_mode | |||
) |
Definition at line 479 of file hack.c.
00482 { 00483 int nin, nstates, nout; 00484 int before, after, present_state, next_state, i, j; 00485 pcube next_state_mask, present_state_mask, state_mask, p, p1, last; 00486 pcover go_nowhere, F, tF; 00487 00488 /* We make the DISGUSTING assumption that the first 'n' outputs have 00489 * been created by .symbolic-output, and represent a one-hot encoding 00490 * of the next state. 'n' is the size of the second-to-last multiple- 00491 * valued variable (i.e., before the outputs 00492 */ 00493 00494 if (cube.num_vars - cube.num_binary_vars != 2) { 00495 (void) fprintf(stderr, 00496 "use .symbolic and .symbolic-output to specify\n"); 00497 (void) fprintf(stderr, 00498 "the present state and next state field information\n"); 00499 fatal("disassemble_pla: need two multiple-valued variables\n"); 00500 } 00501 00502 nin = cube.num_binary_vars; 00503 nstates = cube.part_size[cube.num_binary_vars]; 00504 nout = cube.part_size[cube.num_vars - 1]; 00505 if (nout < nstates) { 00506 (void) fprintf(stderr, 00507 "use .symbolic and .symbolic-output to specify\n"); 00508 (void) fprintf(stderr, 00509 "the present state and next state field information\n"); 00510 fatal("disassemble_pla: # outputs < # states\n"); 00511 } 00512 00513 00514 present_state = cube.first_part[cube.num_binary_vars]; 00515 present_state_mask = new_cube(); 00516 for(i = 0; i < nstates; i++) { 00517 set_insert(present_state_mask, i + present_state); 00518 } 00519 00520 next_state = cube.first_part[cube.num_binary_vars+1]; 00521 next_state_mask = new_cube(); 00522 for(i = 0; i < nstates; i++) { 00523 set_insert(next_state_mask, i + next_state); 00524 } 00525 00526 state_mask = set_or(new_cube(), next_state_mask, present_state_mask); 00527 00528 F = new_cover(10); 00529 00530 00531 /* 00532 * check for arcs which go from ANY state to state #i 00533 */ 00534 for(i = 0; i < nstates; i++) { 00535 tF = new_cover(10); 00536 foreach_set(PLA->F, last, p) { 00537 if (setp_implies(present_state_mask, p)) { /* from any state ! */ 00538 if (is_in_set(p, next_state + i)) { 00539 tF = sf_addset(tF, p); 00540 } 00541 } 00542 } 00543 before = tF->count; 00544 if (before > 0) { 00545 tF = fsm_simplify(tF); 00546 /* don't allow the next state to disappear ... */ 00547 foreach_set(tF, last, p) { 00548 set_insert(p, next_state + i); 00549 } 00550 after = tF->count; 00551 F = sf_append(F, tF); 00552 if (verbose_mode) { 00553 printf("# state EVERY to %d, before=%d after=%d\n", 00554 i, before, after); 00555 } 00556 } 00557 } 00558 00559 00560 /* 00561 * some 'arcs' may NOT have a next state -- handle these 00562 * we must unravel the present state part 00563 */ 00564 go_nowhere = new_cover(10); 00565 foreach_set(PLA->F, last, p) { 00566 if (setp_disjoint(p, next_state_mask)) { /* no next state !! */ 00567 go_nowhere = sf_addset(go_nowhere, p); 00568 } 00569 } 00570 before = go_nowhere->count; 00571 go_nowhere = unravel_range(go_nowhere, 00572 cube.num_binary_vars, cube.num_binary_vars); 00573 after = go_nowhere->count; 00574 F = sf_append(F, go_nowhere); 00575 if (verbose_mode) { 00576 printf("# state ANY to NOWHERE, before=%d after=%d\n", before, after); 00577 } 00578 00579 00580 /* 00581 * minimize cover for all arcs from state #i to state #j 00582 */ 00583 for(i = 0; i < nstates; i++) { 00584 for(j = 0; j < nstates; j++) { 00585 tF = new_cover(10); 00586 foreach_set(PLA->F, last, p) { 00587 /* not EVERY state */ 00588 if (! setp_implies(present_state_mask, p)) { 00589 if (is_in_set(p, present_state + i)) { 00590 if (is_in_set(p, next_state + j)) { 00591 p1 = set_save(p); 00592 set_diff(p1, p1, state_mask); 00593 set_insert(p1, present_state + i); 00594 set_insert(p1, next_state + j); 00595 tF = sf_addset(tF, p1); 00596 set_free(p1); 00597 } 00598 } 00599 } 00600 } 00601 before = tF->count; 00602 if (before > 0) { 00603 tF = fsm_simplify(tF); 00604 /* don't allow the next state to disappear ... */ 00605 foreach_set(tF, last, p) { 00606 set_insert(p, next_state + j); 00607 } 00608 after = tF->count; 00609 F = sf_append(F, tF); 00610 if (verbose_mode) { 00611 printf("# state %d to %d, before=%d after=%d\n", 00612 i, j, before, after); 00613 } 00614 } 00615 } 00616 } 00617 00618 00619 free_cube(state_mask); 00620 free_cube(present_state_mask); 00621 free_cube(next_state_mask); 00622 00623 free_cover(PLA->F); 00624 PLA->F = F; 00625 free_cover(PLA->D); 00626 PLA->D = new_cover(0); 00627 00628 setdown_cube(); 00629 FREE(cube.part_size); 00630 cube.num_binary_vars = nin; 00631 cube.num_vars = nin + 3; 00632 cube.part_size = ALLOC(int, cube.num_vars); 00633 cube.part_size[cube.num_binary_vars] = nstates; 00634 cube.part_size[cube.num_binary_vars+1] = nstates; 00635 cube.part_size[cube.num_binary_vars+2] = nout - nstates; 00636 cube_setup(); 00637 00638 foreach_set(PLA->F, last, p) { 00639 kiss_print_cube(stdout, PLA, p, "~1"); 00640 } 00641 }
find_inputs | ( | pcover | A, | |
pPLA | PLA, | |||
symbolic_list_t * | list, | |||
int | base, | |||
int | value, | |||
pcover * | newF, | |||
pcover * | newD | |||
) |
Definition at line 190 of file hack.c.
00196 { 00197 pcover S, S1; 00198 register pset last, p; 00199 00200 /* 00201 * A represents th 'input' values for which the outputs assume 00202 * the integer value 'value 00203 */ 00204 if (list == NIL(symbolic_list_t)) { 00205 /* 00206 * Simulate these inputs against the on-set; then, insert into the 00207 * new on-set a 1 in the proper position 00208 */ 00209 S = cv_intersect(A, PLA->F); 00210 foreach_set(S, last, p) { 00211 set_insert(p, base + value); 00212 } 00213 *newF = sf_append(*newF, S); 00214 00215 /* 00216 * 'simulate' these inputs against the don't-care set 00217 S = cv_intersect(A, PLA->D); 00218 *newD = sf_append(*newD, S); 00219 */ 00220 00221 } else { 00222 /* intersect and recur with the OFF-set */ 00223 S = cof_output(PLA->R, cube.first_part[cube.output] + list->pos); 00224 if (A != NIL(set_family_t)) { 00225 S1 = cv_intersect(A, S); 00226 free_cover(S); 00227 S = S1; 00228 } 00229 find_inputs(S, PLA, list->next, base, value*2, newF, newD); 00230 free_cover(S); 00231 00232 /* intersect and recur with the ON-set */ 00233 S = cof_output(PLA->F, cube.first_part[cube.output] + list->pos); 00234 if (A != NIL(set_family_t)) { 00235 S1 = cv_intersect(A, S); 00236 free_cover(S); 00237 S = S1; 00238 } 00239 find_inputs(S, PLA, list->next, base, value*2 + 1, newF, newD); 00240 free_cover(S); 00241 } 00242 }
form_bitvector | ( | pset | p, | |
int | base, | |||
int | value, | |||
symbolic_list_t * | list | |||
) |
Definition at line 380 of file hack.c.
00385 { 00386 if (list == NIL(symbolic_list_t)) { 00387 set_insert(p, base + value); 00388 } else { 00389 switch(GETINPUT(p, list->variable)) { 00390 case ZERO: 00391 form_bitvector(p, base, value*2, list->next); 00392 break; 00393 case ONE: 00394 form_bitvector(p, base, value*2+1, list->next); 00395 break; 00396 case TWO: 00397 form_bitvector(p, base, value*2, list->next); 00398 form_bitvector(p, base, value*2+1, list->next); 00399 break; 00400 default: 00401 fatal("bad cube in form_bitvector"); 00402 } 00403 } 00404 }
static pcover fsm_simplify | ( | pcover | F | ) | [static] |
Definition at line 466 of file hack.c.
00468 { 00469 pcover D, R; 00470 D = new_cover(0); 00471 R = complement(cube1list(F)); 00472 F = espresso(F, D, R); 00473 free_cover(D); 00474 free_cover(R); 00475 return F; 00476 }
map_dcset | ( | pPLA | PLA | ) |
Definition at line 12 of file hack.c.
00014 { 00015 int var, i; 00016 pcover Tplus, Tminus, Tplusbar, Tminusbar; 00017 pcover newf, term1, term2, dcset, dcsetbar; 00018 pcube cplus, cminus, last, p; 00019 00020 if (PLA->label == NIL(char *) || PLA->label[0] == NIL(char)) 00021 return; 00022 00023 /* try to find a binary variable named "DONT_CARE" */ 00024 var = -1; 00025 for(i = 0; i < cube.num_binary_vars * 2; i++) { 00026 if (strncmp(PLA->label[i], "DONT_CARE", 9) == 0 || 00027 strncmp(PLA->label[i], "DONTCARE", 8) == 0 || 00028 strncmp(PLA->label[i], "dont_care", 9) == 0 || 00029 strncmp(PLA->label[i], "dontcare", 8) == 0) { 00030 var = i/2; 00031 break; 00032 } 00033 } 00034 if (var == -1) { 00035 return; 00036 } 00037 00038 /* form the cofactor cubes for the don't-care variable */ 00039 cplus = set_save(cube.fullset); 00040 cminus = set_save(cube.fullset); 00041 set_remove(cplus, var*2); 00042 set_remove(cminus, var*2 + 1); 00043 00044 /* form the don't-care set */ 00045 EXEC(simp_comp(cofactor(cube1list(PLA->F), cplus), &Tplus, &Tplusbar), 00046 "simpcomp+", Tplus); 00047 EXEC(simp_comp(cofactor(cube1list(PLA->F), cminus), &Tminus, &Tminusbar), 00048 "simpcomp-", Tminus); 00049 EXEC(term1 = cv_intersect(Tplus, Tminusbar), "term1 ", term1); 00050 EXEC(term2 = cv_intersect(Tminus, Tplusbar), "term2 ", term2); 00051 EXEC(dcset = sf_union(term1, term2), "union ", dcset); 00052 EXEC(simp_comp(cube1list(dcset), &PLA->D, &dcsetbar), "simplify", PLA->D); 00053 EXEC(newf = cv_intersect(PLA->F, dcsetbar), "separate ", PLA->F); 00054 free_cover(PLA->F); 00055 PLA->F = newf; 00056 free_cover(Tplus); 00057 free_cover(Tminus); 00058 free_cover(Tplusbar); 00059 free_cover(Tminusbar); 00060 free_cover(dcsetbar); 00061 00062 /* remove any cubes dependent on the DONT_CARE variable */ 00063 (void) sf_active(PLA->F); 00064 foreach_set(PLA->F, last, p) { 00065 if (! is_in_set(p, var*2) || ! is_in_set(p, var*2+1)) { 00066 RESET(p, ACTIVE); 00067 } 00068 } 00069 PLA->F = sf_inactive(PLA->F); 00070 00071 /* resize the cube and delete the don't-care variable */ 00072 setdown_cube(); 00073 for(i = 2*var+2; i < cube.size; i++) { 00074 PLA->label[i-2] = PLA->label[i]; 00075 } 00076 for(i = var+1; i < cube.num_vars; i++) { 00077 cube.part_size[i-1] = cube.part_size[i]; 00078 } 00079 cube.num_binary_vars--; 00080 cube.num_vars--; 00081 cube_setup(); 00082 PLA->F = sf_delc(PLA->F, 2*var, 2*var+1); 00083 PLA->D = sf_delc(PLA->D, 2*var, 2*var+1); 00084 }
map_output_symbolic | ( | pPLA | PLA | ) |
Definition at line 86 of file hack.c.
00088 { 00089 pset_family newF, newD; 00090 pset compress; 00091 symbolic_t *p1; 00092 symbolic_list_t *p2; 00093 int i, bit, tot_size, base, old_size; 00094 00095 /* Remove the DC-set from the ON-set (is this necessary ??) */ 00096 if (PLA->D->count > 0) { 00097 sf_free(PLA->F); 00098 PLA->F = complement(cube2list(PLA->D, PLA->R)); 00099 } 00100 00101 /* tot_size = width added for all symbolic variables */ 00102 tot_size = 0; 00103 for(p1=PLA->symbolic_output; p1!=NIL(symbolic_t); p1=p1->next) { 00104 for(p2=p1->symbolic_list; p2!=NIL(symbolic_list_t); p2=p2->next) { 00105 if (p2->pos<0 || p2->pos>=cube.part_size[cube.output]) { 00106 fatal("symbolic-output index out of range"); 00107 /* } else if (p2->variable != cube.output) { 00108 fatal("symbolic-output label must be an output");*/ 00109 } 00110 } 00111 tot_size += 1 << p1->symbolic_list_length; 00112 } 00113 00114 /* adjust the indices to skip over new outputs */ 00115 for(p1=PLA->symbolic_output; p1!=NIL(symbolic_t); p1=p1->next) { 00116 for(p2=p1->symbolic_list; p2!=NIL(symbolic_list_t); p2=p2->next) { 00117 p2->pos += tot_size; 00118 } 00119 } 00120 00121 /* resize the cube structure -- add enough for the one-hot outputs */ 00122 old_size = cube.size; 00123 cube.part_size[cube.output] += tot_size; 00124 setdown_cube(); 00125 cube_setup(); 00126 00127 /* insert space in the output part for the one-hot output */ 00128 base = cube.first_part[cube.output]; 00129 PLA->F = sf_addcol(PLA->F, base, tot_size); 00130 PLA->D = sf_addcol(PLA->D, base, tot_size); 00131 PLA->R = sf_addcol(PLA->R, base, tot_size); 00132 00133 /* do the real work */ 00134 for(p1=PLA->symbolic_output; p1!=NIL(symbolic_t); p1=p1->next) { 00135 newF = new_cover(100); 00136 newD = new_cover(100); 00137 find_inputs(NIL(set_family_t), PLA, p1->symbolic_list, base, 0, 00138 &newF, &newD); 00139 /* 00140 * Not sure what this means 00141 find_dc_inputs(PLA, p1->symbolic_list, 00142 base, 1 << p1->symbolic_list_length, &newF, &newD); 00143 */ 00144 free_cover(PLA->F); 00145 PLA->F = newF; 00146 /* 00147 * retain OLD DC-set -- but we've lost the don't-care arc information 00148 * (it defaults to branch to the zero state) 00149 free_cover(PLA->D); 00150 PLA->D = newD; 00151 */ 00152 free_cover(newD); 00153 base += 1 << p1->symbolic_list_length; 00154 } 00155 00156 /* delete the old outputs, and resize the cube */ 00157 compress = set_full(newF->sf_size); 00158 for(p1=PLA->symbolic_output; p1!=NIL(symbolic_t); p1=p1->next) { 00159 for(p2=p1->symbolic_list; p2!=NIL(symbolic_list_t); p2=p2->next) { 00160 bit = cube.first_part[cube.output] + p2->pos; 00161 set_remove(compress, bit); 00162 } 00163 } 00164 cube.part_size[cube.output] -= newF->sf_size - set_ord(compress); 00165 setdown_cube(); 00166 cube_setup(); 00167 PLA->F = sf_compress(PLA->F, compress); 00168 PLA->D = sf_compress(PLA->D, compress); 00169 if (cube.size != PLA->F->sf_size) fatal("error"); 00170 00171 /* Quick minimization */ 00172 PLA->F = sf_contain(PLA->F); 00173 PLA->D = sf_contain(PLA->D); 00174 for(i = 0; i < cube.num_vars; i++) { 00175 PLA->F = d1merge(PLA->F, i); 00176 PLA->D = d1merge(PLA->D, i); 00177 } 00178 PLA->F = sf_contain(PLA->F); 00179 PLA->D = sf_contain(PLA->D); 00180 00181 free_cover(PLA->R); 00182 PLA->R = new_cover(0); 00183 00184 symbolic_hack_labels(PLA, PLA->symbolic_output, 00185 compress, cube.size, old_size, tot_size); 00186 set_free(compress); 00187 }
map_symbolic | ( | pPLA | PLA | ) |
Definition at line 285 of file hack.c.
00287 { 00288 symbolic_t *p1; 00289 symbolic_list_t *p2; 00290 int var, base, num_vars, num_binary_vars, *new_part_size; 00291 int new_size, size_added, num_deleted_vars, num_added_vars, newvar; 00292 pset compress; 00293 00294 /* Verify legal values are in the symbolic lists */ 00295 for(p1 = PLA->symbolic; p1 != NIL(symbolic_t); p1 = p1->next) { 00296 for(p2=p1->symbolic_list; p2!=NIL(symbolic_list_t); p2=p2->next) { 00297 if (p2->variable < 0 || p2->variable >= cube.num_binary_vars) { 00298 fatal(".symbolic requires binary variables"); 00299 } 00300 } 00301 } 00302 00303 /* 00304 * size_added = width added for all symbolic variables 00305 * num_deleted_vars = # binary variables to be deleted 00306 * num_added_vars = # new mv variables 00307 * compress = a cube which will be used to compress the set families 00308 */ 00309 size_added = 0; 00310 num_added_vars = 0; 00311 for(p1 = PLA->symbolic; p1 != NIL(symbolic_t); p1 = p1->next) { 00312 size_added += 1 << p1->symbolic_list_length; 00313 num_added_vars++; 00314 } 00315 compress = set_full(PLA->F->sf_size + size_added); 00316 for(p1 = PLA->symbolic; p1 != NIL(symbolic_t); p1 = p1->next) { 00317 for(p2=p1->symbolic_list; p2!=NIL(symbolic_list_t); p2=p2->next) { 00318 set_remove(compress, p2->variable*2); 00319 set_remove(compress, p2->variable*2+1); 00320 } 00321 } 00322 num_deleted_vars = ((PLA->F->sf_size + size_added) - set_ord(compress))/2; 00323 00324 /* compute the new cube constants */ 00325 num_vars = cube.num_vars - num_deleted_vars + num_added_vars; 00326 num_binary_vars = cube.num_binary_vars - num_deleted_vars; 00327 new_size = cube.size - num_deleted_vars*2 + size_added; 00328 new_part_size = ALLOC(int, num_vars); 00329 new_part_size[num_vars-1] = cube.part_size[cube.num_vars-1]; 00330 for(var = cube.num_binary_vars; var < cube.num_vars-1; var++) { 00331 new_part_size[var-num_deleted_vars] = cube.part_size[var]; 00332 } 00333 00334 /* re-size the covers, opening room for the new mv variables */ 00335 base = cube.first_part[cube.output]; 00336 PLA->F = sf_addcol(PLA->F, base, size_added); 00337 PLA->D = sf_addcol(PLA->D, base, size_added); 00338 PLA->R = sf_addcol(PLA->R, base, size_added); 00339 00340 /* compute the values for the new mv variables */ 00341 newvar = (cube.num_vars - 1) - num_deleted_vars; 00342 for(p1 = PLA->symbolic; p1 != NIL(symbolic_t); p1 = p1->next) { 00343 PLA->F = map_symbolic_cover(PLA->F, p1->symbolic_list, base); 00344 PLA->D = map_symbolic_cover(PLA->D, p1->symbolic_list, base); 00345 PLA->R = map_symbolic_cover(PLA->R, p1->symbolic_list, base); 00346 base += 1 << p1->symbolic_list_length; 00347 new_part_size[newvar++] = 1 << p1->symbolic_list_length; 00348 } 00349 00350 /* delete the binary variables which disappear */ 00351 PLA->F = sf_compress(PLA->F, compress); 00352 PLA->D = sf_compress(PLA->D, compress); 00353 PLA->R = sf_compress(PLA->R, compress); 00354 00355 symbolic_hack_labels(PLA, PLA->symbolic, compress, 00356 new_size, cube.size, size_added); 00357 setdown_cube(); 00358 FREE(cube.part_size); 00359 cube.num_vars = num_vars; 00360 cube.num_binary_vars = num_binary_vars; 00361 cube.part_size = new_part_size; 00362 cube_setup(); 00363 set_free(compress); 00364 }
pcover map_symbolic_cover | ( | pcover | T, | |
symbolic_list_t * | list, | |||
int | base | |||
) |
Definition at line 367 of file hack.c.
00371 { 00372 pset last, p; 00373 foreach_set(T, last, p) { 00374 form_bitvector(p, base, 0, list); 00375 } 00376 return T; 00377 }
symbolic_hack_labels | ( | pPLA | PLA, | |
symbolic_t * | list, | |||
pset | compress, | |||
int | new_size, | |||
int | old_size, | |||
int | size_added | |||
) |
Definition at line 407 of file hack.c.
00412 { 00413 int i, base; 00414 char **oldlabel; 00415 symbolic_t *p1; 00416 symbolic_label_t *p3; 00417 00418 /* hack with the labels */ 00419 if ((oldlabel = PLA->label) == NIL(char *)) 00420 return; 00421 PLA->label = ALLOC(char *, new_size); 00422 for(i = 0; i < new_size; i++) { 00423 PLA->label[i] = NIL(char); 00424 } 00425 00426 /* copy the binary variable labels and unchanged mv variable labels */ 00427 base = 0; 00428 for(i = 0; i < cube.first_part[cube.output]; i++) { 00429 if (is_in_set(compress, i)) { 00430 PLA->label[base++] = oldlabel[i]; 00431 } else { 00432 if (oldlabel[i] != NIL(char)) { 00433 FREE(oldlabel[i]); 00434 } 00435 } 00436 } 00437 00438 /* add the user-defined labels for the symbolic outputs */ 00439 for(p1 = list; p1 != NIL(symbolic_t); p1 = p1->next) { 00440 p3 = p1->symbolic_label; 00441 for(i = 0; i < (1 << p1->symbolic_list_length); i++) { 00442 if (p3 == NIL(symbolic_label_t)) { 00443 PLA->label[base+i] = ALLOC(char, 10); 00444 (void) sprintf(PLA->label[base+i], "X%d", i); 00445 } else { 00446 PLA->label[base+i] = p3->label; 00447 p3 = p3->next; 00448 } 00449 } 00450 base += 1 << p1->symbolic_list_length; 00451 } 00452 00453 /* copy the labels for the binary outputs which remain */ 00454 for(i = cube.first_part[cube.output]; i < old_size; i++) { 00455 if (is_in_set(compress, i + size_added)) { 00456 PLA->label[base++] = oldlabel[i]; 00457 } else { 00458 if (oldlabel[i] != NIL(char)) { 00459 FREE(oldlabel[i]); 00460 } 00461 } 00462 } 00463 FREE(oldlabel); 00464 }