00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "espresso.h"
00011
00012 map_dcset(PLA)
00013 pPLA PLA;
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
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
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
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
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
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 }
00085
00086 map_output_symbolic(PLA)
00087 pPLA PLA;
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
00096 if (PLA->D->count > 0) {
00097 sf_free(PLA->F);
00098 PLA->F = complement(cube2list(PLA->D, PLA->R));
00099 }
00100
00101
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
00108
00109 }
00110 }
00111 tot_size += 1 << p1->symbolic_list_length;
00112 }
00113
00114
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
00122 old_size = cube.size;
00123 cube.part_size[cube.output] += tot_size;
00124 setdown_cube();
00125 cube_setup();
00126
00127
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
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
00141
00142
00143
00144 free_cover(PLA->F);
00145 PLA->F = newF;
00146
00147
00148
00149
00150
00151
00152 free_cover(newD);
00153 base += 1 << p1->symbolic_list_length;
00154 }
00155
00156
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
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 }
00188
00189
00190 find_inputs(A, PLA, list, base, value, newF, newD)
00191 pcover A;
00192 pPLA PLA;
00193 symbolic_list_t *list;
00194 int base, value;
00195 pcover *newF, *newD;
00196 {
00197 pcover S, S1;
00198 register pset last, p;
00199
00200
00201
00202
00203
00204 if (list == NIL(symbolic_list_t)) {
00205
00206
00207
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
00217
00218
00219
00220
00221 } else {
00222
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
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 }
00243
00244
00245 #if 0
00246 find_dc_inputs(PLA, list, base, maxval, newF, newD)
00247 pPLA PLA;
00248 symbolic_list_t *list;
00249 int base, maxval;
00250 pcover *newF, *newD;
00251 {
00252 pcover A, S, S1;
00253 symbolic_list_t *p2;
00254 register pset p, last;
00255 register int i;
00256
00257
00258 A = NIL(set_family_t);
00259 for(p2=list; p2!=NIL(symbolic_list_t); p2=p2->next) {
00260 S = cof_output(PLA->D, cube.first_part[cube.output] + p2->pos);
00261 if (A == NIL(set_family_t)) {
00262 A = S;
00263 } else {
00264 S1 = cv_intersect(A, S);
00265 free_cover(S);
00266 free_cover(A);
00267 A = S1;
00268 }
00269 }
00270
00271 S = cv_intersect(A, PLA->F);
00272 *newF = sf_append(*newF, S);
00273
00274 S = cv_intersect(A, PLA->D);
00275 foreach_set(S, last, p) {
00276 for(i = base; i < base + maxval; i++) {
00277 set_insert(p, i);
00278 }
00279 }
00280 *newD = sf_append(*newD, S);
00281 free_cover(A);
00282 }
00283 #endif
00284
00285 map_symbolic(PLA)
00286 pPLA PLA;
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
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
00305
00306
00307
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
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
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
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
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 }
00365
00366
00367 pcover map_symbolic_cover(T, list, base)
00368 pcover T;
00369 symbolic_list_t *list;
00370 int base;
00371 {
00372 pset last, p;
00373 foreach_set(T, last, p) {
00374 form_bitvector(p, base, 0, list);
00375 }
00376 return T;
00377 }
00378
00379
00380 form_bitvector(p, base, value, list)
00381 pset p;
00382 int base;
00383 int value;
00384 symbolic_list_t *list;
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 }
00405
00406
00407 symbolic_hack_labels(PLA, list, compress, new_size, old_size, size_added)
00408 pPLA PLA;
00409 symbolic_t *list;
00410 pset compress;
00411 int new_size, old_size, size_added;
00412 {
00413 int i, base;
00414 char **oldlabel;
00415 symbolic_t *p1;
00416 symbolic_label_t *p3;
00417
00418
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
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
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
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 }
00465
00466 static pcover fsm_simplify(F)
00467 pcover F;
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 }
00477
00478
00479 disassemble_fsm(PLA, verbose_mode)
00480 pPLA PLA;
00481 int verbose_mode;
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
00489
00490
00491
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
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)) {
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
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
00562
00563
00564 go_nowhere = new_cover(10);
00565 foreach_set(PLA->F, last, p) {
00566 if (setp_disjoint(p, next_state_mask)) {
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
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
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
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 }