/* "WOLCOMP", a simple chip compiler, Copyright (C) 1983, 1990 California Institute of Technology. Authors: Massimo Sivilotti, Carver Mead Maintainer: John Lazzaro Maintainers's address: lazzaro@hobiecat.cs.caltech.edu; CB 425/CU Boulder/Boulder CO/80309. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation (Version 1, 1989). This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Output from p2c, the Pascal-to-C translator */ /* From input file "wolcomp.text" */ /*the line following this is special for p2c*/ #include #define WOLCOMPLIB_G #include "wolcomp.h" #ifndef GENERAL_2_H #include #endif #ifndef MYLIB_H #include #endif /*homeless orphans*/ #ifndef MISC_H #include #endif #ifndef HPIB_2_H #include #endif #ifndef NEWCI_H #include #endif /*,new_kbd*/ #define plotter 705 #define ngang 2 /*number of ganglion pairs*/ #define Version "1.10" #define Compilation_date "21 Aug 86" #define dbug false Static long i, j; /* global scratch registers */ Static long x2, y2, x3, y3, x4, y4, x5, x6, y6, xmax, ymax; /* DON'T TOUCH ! keeps mbb for current cell */ Static cel *first, *last; /* pointer to first & last cells */ Static cel *current_cell; /* cell being defined (if any)*/ Static cel *cell1, *cell2, *cell3; /* working cell pointer - re-define if needed */ Static long maxnum; /* largest cif number allocated to this point */ Static FILE *cif; /* cif output file */ Static Char cifname[201], cifxname[201]; /* cif output file name, unextended & extended */ Static Char fbox[201]; /* line of cif file */ Static Char st[201], instr[201]; /* variables for file manipulations */ Static FILE *buf; /* cif input file */ Static Char iobox[201]; /* / */ Static Char ch; Static boolean crtplt; /*plot on crt rather than on plotter*/ Static long global_llx, global_lly, global_urx, global_ury; Static boolean external_mbb; /* has the user set_MBB ? */ Static boolean mbb_found; /* does the current cell have an MBB ? */ Static long junk; Static stringlist *wire_list, *data_list, *head_list, *garbage_list, *outstr; Static long wire_width, current_wire_x, current_wire_y; Void write_cif(a) Char *a; { fputs(a, cif); } Void writeln_cif(a) Char *a; { fprintf(cif, "%s\n", a); } /******************************************/ Static Void add_cell_to_list(c) cel **c; { /* get a new composition cell, add to HEAD of list */ /*$if false$ { used to add to TAIL of list } new(c); c^.next:=nil; IF first=nil THEN first:=c ELSE last^.next:=c; last:=c; $end$*/ /* add to HEAD of list */ *c = (cel *)Malloc(sizeof(cel)); (*c)->next = first; first = *c; } /******************************************/ long lam(x) long x; { return (x * 2); /* convert x "lambda" to internal units (2lambda) */ } /******************************************/ long inpos(left, pattern, source) long left; Char *pattern, *source; { /* returns first occurence of pattern in source after character #left */ long lngth; Char STR1[256]; lngth = strlen(source); sprintf(STR1, "%.*s", (int)(lngth - left + 1), source + left - 1); return strpos2(STR1, pattern, 1); } /*inpos*/ /******************************************/ Char *fix_name(Result, fname) Char *Result, *fname; { /* Default extension: .CIF */ long lngth; Char f_name[201]; Char STR2[256]; strcpy(f_name, strltrim(strrtrim(strcpy(STR2, fname)))); /* delete leading, trailing spaces */ /*UPC(f_name);*/ /* shift lowercase to CAPS */ lngth = strlen("f_name"); if (inpos(2L, ".", f_name) == 0) /* no extension given */ strcat(f_name, ".cif"); /* =>add .CIF extension */ return strcpy(Result, f_name); } /*fix_name*/ /******************************************/ Void dumplist() { cel *scan; scan = first; while (scan != NULL) { printf("%12s %4ld x%4ld lambda.\n", scan->name, scan->lx / 2, scan->ly / 2); scan = scan->next; } } /******************************************/ Static stringlist *get_outstr() { stringlist *tmp; if (garbage_list != NULL) { tmp = garbage_list; garbage_list = garbage_list->next; } else tmp = (stringlist *)Malloc(sizeof(stringlist)); *tmp->str = '\0'; return tmp; } Static Void reclaim_list(a) stringlist **a; { stringlist *tmp; if (*a == NULL) return; tmp = *a; while (tmp->next != NULL) tmp = tmp->next; tmp->next = garbage_list; garbage_list = *a; *a = NULL; } Static Void add_wire_string(outstr) stringlist *outstr; { /* add it to the wire list */ outstr->next = wire_list; wire_list = outstr; } Static Void add_data_string(outstr) stringlist *outstr; { /* add it to the data list */ outstr->next = data_list; data_list = outstr; } Static Void add_data(fbox) Char *fbox; { stringlist *tmp; tmp = get_outstr(); strcpy(tmp->str, fbox); add_data_string(tmp); } Static Void add_head_string(outstr) stringlist *outstr; { /* add it to the head list */ outstr->next = head_list; head_list = outstr; } Static Void print_list(a) stringlist *a; { if (a != NULL) { print_list(a->next); /* sleazy way to reverse the list */ fprintf(cif, "%s\n", a->str); } } Static Void print_cell() { print_list(head_list); /* now calculate mbb */ fprintf(cif, "(MBB;\n"); fprintf(cif, "B %ld %ld %ld %ld;);\n", xmax, ymax, xmax / 2, ymax / 2); print_list(data_list); print_list(wire_list); reclaim_list(&head_list); reclaim_list(&data_list); reclaim_list(&wire_list); } /***************** WIRE STUFF ********************************/ Void width(x) long x; { wire_width = lam(x); } Void wire(layer, startx, starty) Char *layer; long startx, starty; { outstr = get_outstr(); sprintf(outstr->str, "LC%s;", layer); junk = strlen(outstr->str) + 1; add_wire_string(outstr); outstr = get_outstr(); sprintf(outstr->str, "W %ld %ld %ld", wire_width, startx, starty); junk = strlen(outstr->str) + 1; add_wire_string(outstr); current_wire_x = startx; current_wire_y = starty; } Void x(delta) long delta; { outstr = get_outstr(); sprintf(outstr->str, " %ld %ld", delta, current_wire_y); junk = strlen(outstr->str) + 1; add_wire_string(outstr); current_wire_x = delta; } Void y(delta) long delta; { outstr = get_outstr(); sprintf(outstr->str, " %ld %ld", current_wire_x, delta); junk = strlen(outstr->str) + 1; add_wire_string(outstr); current_wire_y = delta; } Void dx(delta) long delta; { outstr = get_outstr(); sprintf(outstr->str, " %ld %ld", delta + current_wire_x, current_wire_y); junk = strlen(outstr->str) + 1; add_wire_string(outstr); current_wire_x += delta; } Void dy(delta) long delta; { outstr = get_outstr(); sprintf(outstr->str, " %ld %ld", current_wire_x, delta + current_wire_y); junk = strlen(outstr->str) + 1; add_wire_string(outstr); current_wire_y += delta; } Void xy(x, y) long x, y; { outstr = get_outstr(); sprintf(outstr->str, " %ld %ld", x, y); junk = strlen(outstr->str) + 1; add_wire_string(outstr); current_wire_y = y; current_wire_x = x; } Void dxdy(deltax, deltay) long deltax, deltay; { outstr = get_outstr(); sprintf(outstr->str, " %ld %ld", current_wire_x + deltax, current_wire_y + deltay); junk = strlen(outstr->str) + 1; add_wire_string(outstr); current_wire_y += deltay; current_wire_x += deltax; } Void endwire() { outstr = get_outstr(); strcpy(outstr->str, " ;"); add_wire_string(outstr); } /******************************************/ Void set_mbb(llx, lly, urx, ury) long llx, lly, urx, ury; { /* this is used for specialized CIF to specify a MBB by hand */ global_llx = llx; global_lly = lly; global_urx = urx; global_ury = ury; /* added by MAS 7-28-89 */ xmax = urx; ymax = ury; if (llx > urx) xmax = llx; if (lly > ury) ymax = lly; external_mbb = true; mbb_found = true; } /* Local variables for getcompfile: */ struct LOC_getcompfile { Char name[201]; long x0, y0; cel *scan; } ; /* Local variables for read_cif_file: */ struct LOC_read_cif_file { struct LOC_getcompfile *LINK; long translation_in[500], translation_out[500]; /* holds local symbols */ long j, cellno; /* how many cells in local symbol table */ } ; Local Void addcell(LINK) struct LOC_read_cif_file *LINK; { /* add cell to list */ cel *c; long l, w, xc, yc, n; Char s[201]; Char STR2[256]; switch (cif_type) { case WOL: if (external_mbb) { LINK->LINK->x0 = global_llx; x1 = global_urx; LINK->LINK->y0 = global_lly; y1 = global_ury; external_mbb = false; } else { if (dbug) printf("mbbline contains: %s\n", fbox); LINK->j = strlen(fbox); sscanf(fbox + 1, "%ld%ld%ld%ld%ln", &l, &w, &xc, &yc, &LINK->j); LINK->j += 2; LINK->LINK->x0 = xc - l / 2; x1 = xc + l / 2; LINK->LINK->y0 = yc - w / 2; y1 = yc + w / 2; } break; case LYON: case TELLE: if (external_mbb) { LINK->LINK->x0 = global_llx; x1 = global_urx; LINK->LINK->y0 = global_lly; y1 = global_ury; external_mbb = false; } else printf("MUST specify an external mbb.\n"); break; }/* case */ add_cell_to_list(&c); /* new(c); c^.next:=nil; IF first=nil THEN first:=c ELSE last^.next:=c; last:=c; */ c->lx = labs(x1 - LINK->LINK->x0); c->ly = labs(y1 - LINK->LINK->y0); strcpy(c->name, strltrim(strrtrim(strcpy(STR2, LINK->LINK->name)))); /* maxnum:=maxnum+1; not necessary, since cell already defined */ c->cifnum = maxnum; *s = '\0'; n = 1; sprintf(s, "Cell %s number %ld", LINK->LINK->name, maxnum); n = strlen(s) + 1; if (strlen(LINK->LINK->name) <= 12) printf("Cell: %12s; number: %ld \n", LINK->LINK->name, maxnum); else printf("Cell: %s; number: %ld\n", LINK->LINK->name, maxnum); if (print_cells) P_writestringln(701L, strrtrim(strcpy(STR2, s))); } /*addcell*/ Local Void add_subcell(LINK) struct LOC_read_cif_file *LINK; { /* add a subcell to the local translation arrays */ long junk, newpos; Char *STR1; /* fbox now contains DS statement */ maxnum++; newpos = strpos2(fbox, " ", 1); junk = strtol(fbox + newpos - 1, &STR1, 10); newpos = STR1 - fbox + 1; if (cif_type == WOL) fprintf(cif, "DS %ld %ld 2 ;\n", maxnum, lambda); else fprintf(cif, "DS %ld%.*s\n", maxnum, (int)(strlen(fbox) - newpos + 1), fbox + newpos - 1); /*$if false$ case cif_type of WOL : writeln(cif,'DS ',(maxnum):1,' ',lambda:1,' 2 ;'); LYON : if lambda = 150 then writeln (cif,'DS ',(maxnum):1,' 1 1 ;') else if lambda = 80 then writeln (cif,'DS ',maxnum:1,' 80 150 ;') else writeln ('LYON cif only good at lambda = 0.8 and 1.5 um'); TELLE : { do something when I know what telle_cif looks like } end; $end$*/ LINK->cellno++; LINK->translation_in[LINK->cellno - 1] = strtol(fbox + 2, &STR1, 10); LINK->j = STR1 - fbox + 1; LINK->translation_out[LINK->cellno - 1] = maxnum; } Local Void read_cif_file(LINK) struct LOC_getcompfile *LINK; { /* input CIF cell file */ struct LOC_read_cif_file V; boolean defining_cell; /* has a DS statement been encountered? */ long k; /* ubiquitous index variables */ Char last_mbbline[81]; /* keeps track of last MBB line */ long called_cell, new_cell; /* temp values for symbol lookup */ Char *TEMP; Char STR1[256], *STR2, STR3[256]; long FORLIM; V.LINK = LINK; TRY(try1); if (buf != NULL) buf = freopen(instr, "r", buf); else buf = fopen(instr, "r"); if (buf == NULL) { P_escapecode = -10; P_ioresult = FileNotFound; goto _Ltry1; } defining_cell = false; V.cellno = 0; do { fgets(fbox, 201, buf); TEMP = strchr(fbox, '\n'); if (TEMP != NULL) *TEMP = 0; if (dbug) printf("> %s\n", fbox); if (strpos2(fbox, "DS", 1) == 1) { defining_cell = true; add_subcell(&V); *last_mbbline = '\0'; } else { if (strpos2(fbox, "(MBB", 1) == 1 && cif_type == WOL) { fprintf(cif, "%s\n", fbox); fgets(fbox, 201, buf); TEMP = strchr(fbox, '\n'); if (TEMP != NULL) *TEMP = 0; if (dbug) printf("> %s\n", fbox); fprintf(cif, "%s\n", fbox); /* only save the very first mbb within a cell */ if (*last_mbbline == '\0') strcpy(last_mbbline, fbox); } else { if (strpos2(fbox, "9", 1) == 1) { sscanf(fbox + 2, "%255s%ln", LINK->name, &V.j); V.j += 3; /* save cell name, if any */ if (strpos2(LINK->name, ";", 1) != 0) { /* eat semicolons */ sprintf(STR3, "%.*s", strpos2(LINK->name, ";", 1) - 1, LINK->name); strcpy(LINK->name, strrtrim(strcpy(STR1, strltrim(STR3)))); } if (dbug) printf("name = %s\n", LINK->name); fprintf(cif, "%s\n", fbox); /* search library, to see if cell has been already loaded */ if (search_library) { LINK->scan = first; while (LINK->scan != NULL && strcmp(LINK->scan->name, LINK->name)) LINK->scan = LINK->scan->next; if (LINK->scan != NULL) { /* found a match */ fprintf(cif, "C %ld T 0 0 ;\n", LINK->scan->cifnum); fprintf(cif, "DF;\n"); do { fgets(fbox, 201, buf); TEMP = strchr(fbox, '\n'); if (TEMP != NULL) *TEMP = 0; } while (strpos2(fbox, "DF;", 1) != 1); defining_cell = false; } /* else, no match, so don't do anything */ } } else { if (strpos2(fbox, "C", 1) == 1) { /* this is a call, so must do translation */ if (defining_cell) { called_cell = strtol(fbox + 1, &STR2, 10); V.j = STR2 - fbox + 1; FORLIM = V.cellno; for (V.j = 1; V.j <= FORLIM; V.j++) { if (V.translation_in[V.j - 1] == called_cell) new_cell = V.translation_out[V.j - 1]; } called_cell = strtol(fbox + 1, &STR2, 10); V.j = STR2 - fbox + 1; sprintf(STR1, "%.*s", (int)(strlen(fbox) - V.j + 1), fbox + V.j - 1); strcpy(fbox, STR1); /* get rest of string */ fprintf(cif, "C %ld%s\n", new_cell, fbox); } } else { if (strpos2(fbox, "DF", 1) == 1) { defining_cell = false; fprintf(cif, "%s\n", fbox); } else { if (strpos2(fbox, "E", 1) == 1) { strcpy(fbox, last_mbbline); if (*last_mbbline == '\0' && !external_mbb) { printf( "\n WARNING: no MBB found or specified. Set to NBS default (2090x420 lambda)\n"); printf(" Occurred while reading "); set_mbb(0L, 0L, lam(2090L), lam(420L)); } addcell(&V); } else fprintf(cif, "%s\n", fbox); } } } } /* MBB in WOL cif */ } } while (!(strpos2(fbox, "E", 1) == 1 || P_eof(buf))); /* end of cif */ RECOVER2(try1,_Ltry1); misc_printerror((long)P_escapecode, P_ioresult); ENDTRY(try1); TRY(try2); if (buf != NULL) fclose(buf); buf = NULL; RECOVER(try2); ; ENDTRY(try2); } /*read_cif_file*/ Void getcompfile(name_) Char *name_; { /* inputs a composition cell from CIF file */ /* only the outer level composition cell is added to the symbol table; however, all intermediate cells have their DS numbers changed */ struct LOC_getcompfile V; Char STR1[201]; strcpy(V.name, name_); strcpy(fbox, "0000000"); sprintf(instr, "%s%s", prefix, fix_name(STR1, V.name)); /* format file name */ if (strlen(instr) <= 16) printf("Reading: %16s .... ", instr); else printf("Reading: %s .... ", instr); read_cif_file(&V); /* CIF format */ } /*getcompfile*/ /* Local variables for load_library: */ struct LOC_load_library { Char name[201]; long x0, y0; } ; /* Local variables for read_cif_file_: */ struct LOC_read_cif_file_ { struct LOC_load_library *LINK; long translation_in[500], translation_out[500]; /* holds local symbols */ long j, cellno; /* how many cells in local symbol table */ } ; Local Void addcell_(LINK) struct LOC_read_cif_file_ *LINK; { /* add cell to list */ cel *c; long l, w, xc, yc, n; Char s[201]; Char STR3[256]; if (dbug) printf("mbbline contains: %s\n", fbox); LINK->j = strlen(fbox); sscanf(fbox + 1, "%ld%ld%ld%ld%ln", &l, &w, &xc, &yc, &LINK->j); LINK->j += 2; LINK->LINK->x0 = xc - l / 2; x1 = xc + l / 2; LINK->LINK->y0 = yc - w / 2; y1 = yc + w / 2; add_cell_to_list(&c); /* new(c); c^.next:=nil; IF first=nil THEN first:=c ELSE last^.next:=c; last:=c; */ c->lx = labs(x1 - LINK->LINK->x0); c->ly = labs(y1 - LINK->LINK->y0); strcpy(c->name, strltrim(strrtrim(strcpy(STR3, LINK->LINK->name)))); /* maxnum:=maxnum+1; not necessary, since cell already defined */ c->cifnum = maxnum; *s = '\0'; n = 1; sprintf(s, "Cell %s number %ld", LINK->LINK->name, maxnum); n = strlen(s) + 1; if (strlen(LINK->LINK->name) <= 12) printf("Cell: %12s; number: %ld \n", LINK->LINK->name, maxnum); else printf("Cell: %s; number: %ld\n", LINK->LINK->name, maxnum); if (print_cells) P_writestringln(701L, strrtrim(strcpy(STR3, s))); } /*addcell*/ Local Void add_subcell_(LINK) struct LOC_read_cif_file_ *LINK; { /* add a subcell to the local translation arrays */ long junk, newpos; Char *STR1; /* fbox now contains DS statement */ maxnum++; newpos = strpos2(fbox, " ", 1); junk = strtol(fbox + newpos - 1, &STR1, 10); newpos = STR1 - fbox + 1; if (cif_type == WOL) fprintf(cif, "DS %ld %ld 2 ;\n", maxnum, lambda); else fprintf(cif, "DS %ld%.*s\n", maxnum, (int)(strlen(fbox) - newpos + 1), fbox + newpos - 1); LINK->cellno++; LINK->translation_in[LINK->cellno - 1] = strtol(fbox + 2, &STR1, 10); LINK->j = STR1 - fbox + 1; LINK->translation_out[LINK->cellno - 1] = maxnum; } Local Void read_cif_file_(LINK) struct LOC_load_library *LINK; { /* input CIF cell file */ struct LOC_read_cif_file_ V; boolean defining_cell; /* has a DS statement been encountered? */ long k; /* ubiquitous index variables */ Char last_mbbline[81]; /* keeps track of last MBB line */ long called_cell, new_cell; /* temp values for symbol lookup */ Char *TEMP; Char STR1[256], *STR2, STR3[256]; long FORLIM; V.LINK = LINK; TRY(try3); if (buf != NULL) buf = freopen(instr, "r", buf); else buf = fopen(instr, "r"); if (buf == NULL) { P_escapecode = -10; P_ioresult = FileNotFound; goto _Ltry3; } defining_cell = false; V.cellno = 0; do { fgets(fbox, 201, buf); TEMP = strchr(fbox, '\n'); if (TEMP != NULL) *TEMP = 0; if (dbug) printf("> %s\n", fbox); if (strpos2(fbox, "DS", 1) == 1) { defining_cell = true; *last_mbbline = '\0'; add_subcell_(&V); } else { if (strpos2(fbox, "(MBB", 1) == 1 && cif_type == WOL) { fprintf(cif, "%s\n", fbox); fgets(fbox, 201, buf); TEMP = strchr(fbox, '\n'); if (TEMP != NULL) *TEMP = 0; if (dbug) printf("> %s\n", fbox); fprintf(cif, "%s\n", fbox); if (*last_mbbline == '\0') strcpy(last_mbbline, fbox); } else { if (strpos2(fbox, "9", 1) == 1) { sscanf(fbox + 2, "%255s%ln", LINK->name, &V.j); V.j += 3; /* save cell name, if any */ if (strpos2(LINK->name, ";", 1) != 0) { /* eat semicolons */ sprintf(STR3, "%.*s", strpos2(LINK->name, ";", 1) - 1, LINK->name); strcpy(LINK->name, strrtrim(strcpy(STR1, strltrim(STR3)))); } if (dbug) printf("name = %s\n", LINK->name); fprintf(cif, "%s\n", fbox); } else { if (strpos2(fbox, "C", 1) == 1) { /* this is a call, so must do translation */ if (defining_cell) { called_cell = strtol(fbox + 1, &STR2, 10); V.j = STR2 - fbox + 1; FORLIM = V.cellno; for (V.j = 1; V.j <= FORLIM; V.j++) { if (V.translation_in[V.j - 1] == called_cell) new_cell = V.translation_out[V.j - 1]; } called_cell = strtol(fbox + 1, &STR2, 10); V.j = STR2 - fbox + 1; sprintf(STR1, "%.*s", (int)(strlen(fbox) - V.j + 1), fbox + V.j - 1); strcpy(fbox, STR1); /* get rest of string */ fprintf(cif, "C %ld%s\n", new_cell, fbox); } } else { if (strpos2(fbox, "DF", 1) == 1) { defining_cell = false; fprintf(cif, "%s\n", fbox); strcpy(fbox, last_mbbline); /* if there is no mbbline, don't add the cell */ /* i.e. it was probably a composition cell created by WOLCOMP */ if (*last_mbbline != '\0') addcell_(&V); } else { if (strpos2(fbox, "E", 1) != 1) /* do not do anything */ fprintf(cif, "%s\n", fbox); /*fbox := last_mbbline; addcell; */ } } } } /* MBB in WOL cif */ } } while (!(strpos2(fbox, "E", 1) == 1 || P_eof(buf))); /* end of cif */ RECOVER2(try3,_Ltry3); misc_printerror((long)P_escapecode, P_ioresult); printf("fbox = %s\n", fbox); printf("last_mbbline = %s\n", last_mbbline); ENDTRY(try3); TRY(try4); if (buf != NULL) fclose(buf); buf = NULL; RECOVER(try4); ; ENDTRY(try4); /* eat top-level calls */ } /*read_cif_file*/ /***************************************************************************/ Void load_library(name_) Char *name_; { /* inputs a composition cell from CIF file */ /* derived from getcompfile.... the difference is that ALL cells are added to the symbol table, after having their numbers changed*/ /* NOTE: ONLY NEWOL CIF is accepted by this procedure ----------------------------- */ struct LOC_load_library V; Char STR1[201]; strcpy(V.name, name_); strcpy(fbox, "0000000"); sprintf(instr, "%s%s", prefix, fix_name(STR1, V.name)); /* format file name */ printf("Reading library: %s\n", instr); read_cif_file_(&V); /* CIF format */ putchar('\n'); } /*load_library*/ /* Local variables for getfile: */ struct LOC_getfile { Char name[201]; long j, x0, y0, y1, x1; } ; /* Local variables for read_cif_file__: */ struct LOC_read_cif_file__ { struct LOC_getfile *LINK; } ; Local Void addcell__(LINK) struct LOC_read_cif_file__ *LINK; { /* add cell to list */ cel *c; long l, w, xc, yc, n; Char s[201]; Char STR2[256]; LINK->LINK->j = strlen(fbox); sscanf(fbox + 1, "%ld%ld%ld%ld%ln", &l, &w, &xc, &yc, &LINK->LINK->j); LINK->LINK->j += 2; LINK->LINK->x0 = xc - l / 2; LINK->LINK->x1 = xc + l / 2; LINK->LINK->y0 = yc - w / 2; LINK->LINK->y1 = yc + w / 2; add_cell_to_list(&c); /* new(c); c^.next:=nil; IF first=nil THEN first:=c ELSE last^.next:=c; last:=c; replaced by above */ c->lx = labs(LINK->LINK->x1 - LINK->LINK->x0); c->ly = labs(LINK->LINK->y1 - LINK->LINK->y0); strcpy(c->name, strltrim(strrtrim(strcpy(STR2, LINK->LINK->name)))); maxnum++; c->cifnum = maxnum; *s = '\0'; n = 1; sprintf(s, "Cell %s number %ld", LINK->LINK->name, maxnum); n = strlen(s) + 1; if (strlen(LINK->LINK->name) <= 12) printf("Cell: %12s; number: %ld \n", LINK->LINK->name, maxnum); else printf("Cell: %s; number: %ld\n", LINK->LINK->name, maxnum); if (print_cells) P_writestringln(701L, strrtrim(strcpy(STR2, s))); } /*addcell*/ Local Void read_cif_file__(LINK) struct LOC_getfile *LINK; { /* input CIF cell file */ struct LOC_read_cif_file__ V; boolean named_cell; Char *TEMP; V.LINK = LINK; TRY(try5); if (buf != NULL) buf = freopen(instr, "r", buf); else buf = fopen(instr, "r"); if (buf == NULL) { P_escapecode = -10; P_ioresult = FileNotFound; goto _Ltry5; } fprintf(cif, "DS%ld %ld 2 ;\n", maxnum + 1, lambda); named_cell = false; fbox[0] = 'q'; /* dummy */ while (fbox[0] != 'B') { fgets(fbox, 201, buf); TEMP = strchr(fbox, '\n'); if (TEMP != NULL) /* first box is mbb */ *TEMP = 0; if (fbox[0] == '(' && !named_cell) fprintf(cif, "9 %s ;\n", LINK->name); if (strpos2(fbox, "DS", 1) == 0) fprintf(cif, "%s\n", fbox); /*do not transcribe the cell's DS */ if (fbox[0] == '9') { named_cell = true; sprintf(LINK->name, "%.*s", (int)(strlen(fbox) - 3L), fbox + 2); } } addcell__(&V); /* add cell to list */ while (fgets(fbox, 201, buf) != NULL) { TEMP = strchr(fbox, '\n'); if (TEMP != NULL) *TEMP = 0; LINK->j = strlen(fbox); if (fbox[0] == 'L') { if (fbox[1] == 'N') { fbox[1] = 'C'; ch = fbox[2]; /*IF ch= 'D'THEN begin fbox[3]:='I'; strinsert('S',fbox,4); end;*/ /*above line for SOS only*/ if (ch == 'I') fbox[2] = 'W'; if (ch == 'B') fbox[2] = 'S'; } } if (LINK->j > 3) { /* hack to change LCB to LCS */ ch = fbox[2]; if (ch == 'I') fbox[2] = 'W'; if ((ch == 'B') && (fbox[3] == ';')) fbox[2] = 'S'; } if (LINK->j > 0 && fbox[0] != 'E' && fbox[0] != 'C' && strpos2(fbox, "DF", 1) == 0) fprintf(cif, "%s\n", fbox); } /*while ... */ fprintf(cif, "DF;\n"); RECOVER2(try5,_Ltry5); misc_printerror((long)P_escapecode, P_ioresult); ENDTRY(try5); TRY(try6); if (buf != NULL) fclose(buf); buf = NULL; RECOVER(try6); ; ENDTRY(try6); } /*read_cif_file*/ /***************************************************************************/ Void getfile(name_) Char *name_; { /* inputs cell from CIF file */ struct LOC_getfile V; Char STR1[201]; strcpy(V.name, name_); strcpy(fbox, "0000000"); sprintf(instr, "%s%s", prefix, fix_name(STR1, V.name)); /* format file name */ if (strlen(instr) <= 16) printf("Reading: %16s ....", instr); else printf("Reading: %s ....", instr); read_cif_file__(&V); /* CIF format */ } /*getfile*/ /***************************************************************************/ Void draw(c) cel *c; { /*draws the named cell at x0,y0*/ long num; subcel *s; if (c == NULL) return; num = c->cifnum; /* writeln(cif,'C',num:1,' T ',x0:1,' ',y0:1,';'); */ outstr = get_outstr(); sprintf(outstr->str, "C%ld T %ld %ld;", num, x0, y0); junk = strlen(outstr->str) + 1; add_data_string(outstr); x1 = x0 + c->lx; y1 = y0 + c->ly; /* leaves x1 & y1 at upper right corner */ if (x1 > xmax) xmax = x1; if (y1 > ymax) /* updates mbb of current cell */ ymax = y1; if (current_cell == NULL) /*add to contents of current cell*/ return; s = (subcel *)Malloc(sizeof(subcel)); s->next = current_cell->contents; s->cell = c; current_cell->contents = s; s->x = x0; s->y = y0; s->xfrm = 0; } Void ndraw(c, drawit) cel *c; boolean drawit; { /*optionally draws the named cell at x0,y0*/ subcel *s; if (drawit) { draw(c); return; } if (c == NULL) return; x1 = x0 + c->lx; y1 = y0 + c->ly; /* leaves x1 & y1 at upper right corner */ if (x1 > xmax) xmax = x1; if (y1 > ymax) /* updates mbb of current cell */ ymax = y1; if (current_cell == NULL) /*add to contents of current cell*/ return; s = (subcel *)Malloc(sizeof(subcel)); s->next = current_cell->contents; s->cell = c; current_cell->contents = s; s->x = x0; s->y = y0; s->xfrm = 0; /* just update x0 and y0 */ } Local Char *transform(Result, i) Char *Result; long i; { switch (i) { case 0: strcpy(Result, " "); break; case 1: strcpy(Result, "R 0 1 "); break; case 2: strcpy(Result, "R -1 0 "); break; case 3: strcpy(Result, "R 0 -1 "); break; case 4: strcpy(Result, "M X "); break; case 5: strcpy(Result, "M X R 0 1 "); break; case 6: strcpy(Result, "M X R -1 0 "); break; case 7: strcpy(Result, "M X R 0 -1 "); break; } return Result; } Local Char *translate(Result, t, lx, ly) Char *Result; long t, lx, ly; { Char s[181]; long n; n = 2; *s = '\0'; switch (t) { case 0: sprintf(s, "T %ld %ld", x0, y0); n = strlen(s) + 1; break; case 1: sprintf(s, "T %ld %ld", x0 + ly, y0); n = strlen(s) + 1; break; case 2: sprintf(s, "T %ld %ld", x0 + lx, y0 + ly); n = strlen(s) + 1; break; case 3: sprintf(s, "T %ld %ld", x0, y0 + lx); n = strlen(s) + 1; break; case 4: sprintf(s, "T %ld %ld", x0 + lx, y0); n = strlen(s) + 1; break; case 5: sprintf(s, "T %ld %ld", x0 + ly, y0 + lx); n = strlen(s) + 1; break; case 6: sprintf(s, "T %ld %ld", x0, y0 + ly); n = strlen(s) + 1; break; case 7: sprintf(s, "T %ld %ld", x0, y0); n = strlen(s) + 1; break; } strrtrim(strcpy(Result, s)); return Result; } /******************************************/ Void drawx(c, tform) cel *c; long tform; { long number, dx, dy; subcel *s; Char STR2[201], STR3[201]; if (c == NULL) return; number = c->cifnum; /* writeln(cif, 'C',number:1,' ',transform(tform), translate(tform,c^.lx,c^.ly),';'); */ outstr = get_outstr(); sprintf(outstr->str, "C%ld %s%s;", number, transform(STR2, tform), translate(STR3, tform, c->lx, c->ly)); junk = strlen(outstr->str) + 1; add_data_string(outstr); if (tform & 1) { dx = c->ly; dy = c->lx; } else { dx = c->lx; dy = c->ly; } x1 = x0 + dx; y1 = y0 + dy; /* leaves x1 & y1 at upper right corner */ if (x1 > xmax) xmax = x1; if (y1 > ymax) /* updates mbb of current cell */ ymax = y1; if (current_cell == NULL) /*add to contents of current cell*/ return; s = (subcel *)Malloc(sizeof(subcel)); s->next = current_cell->contents; s->cell = c; current_cell->contents = s; s->x = x0; s->y = y0; s->xfrm = tform; } /*drawx*/ Void ndrawx(c, tform, drawit) cel *c; long tform; boolean drawit; { long dx, dy; subcel *s; if (drawit) { drawx(c, tform); return; } if (c == NULL) return; if (tform & 1) { dx = c->ly; dy = c->lx; } else { dx = c->lx; dy = c->ly; } x1 = x0 + dx; y1 = y0 + dy; /* leaves x1 & y1 at upper right corner */ if (x1 > xmax) xmax = x1; if (y1 > ymax) /* updates mbb of current cell */ ymax = y1; if (current_cell == NULL) /*add to contents of current cell*/ return; s = (subcel *)Malloc(sizeof(subcel)); s->next = current_cell->contents; s->cell = c; current_cell->contents = s; s->x = x0; s->y = y0; s->xfrm = tform; /* just update x0 and y0 */ } /* Local variables for plot: */ struct LOC_plot { long xl, yl, xh, yh, xoffset, yoffset, n; Char st[201]; double plotscale; } ; Local Void getsize(LINK) struct LOC_plot *LINK; { long i, j; Char st[201]; if (crtplt) { LINK->xh = 511; /*512*/ LINK->yh = 389; /*390*/ LINK->xl = 0; LINK->yl = 0; return; } P_writestringln((long)plotter, "IN;"); P_writestringln((long)plotter, "OH;"); P_readstring((long)plotter, st); j = strlen(st); for (i = 0; i < j; i++) { if (st[i] == ',') st[i] = ' '; } sscanf(st, "%ld%ld%ld%ld%ln", &LINK->xl, &LINK->yl, &LINK->xh, &LINK->yh, &j); j++; LINK->xh -= 100; LINK->yh -= 100; } /*getsize*/ Local Void plotbox(s, LINK) subcel s; struct LOC_plot *LINK; { Char name[201]; Char fbox[256]; long x0, y0, x1, y1, numchar; Char STR2[256]; x0 = s.x + LINK->xoffset; y0 = s.y + LINK->yoffset; LINK->n = 1; if (s.cell == NULL) { printf("Nil cell pointer\n"); return; } if (s.xfrm & 1) { x1 = x0 + s.cell->ly; y1 = y0 + s.cell->lx; } else { x1 = x0 + s.cell->lx; y1 = y0 + s.cell->ly; } sprintf(fbox, "PA%ld,%ld;PD;PA%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld;PU;", (long)floor(x0 * LINK->plotscale + 0.5), (long)floor(y0 * LINK->plotscale + 0.5), (long)floor(x0 * LINK->plotscale + 0.5), (long)floor(y1 * LINK->plotscale + 0.5), (long)floor(x1 * LINK->plotscale + 0.5), (long)floor(y1 * LINK->plotscale + 0.5), (long)floor(x1 * LINK->plotscale + 0.5), (long)floor(y0 * LINK->plotscale + 0.5), (long)floor(x0 * LINK->plotscale + 0.5), (long)floor(y0 * LINK->plotscale + 0.5)); LINK->n = strlen(fbox) + 1; P_writestringln((long)plotter, strrtrim(strcpy(STR2, fbox))); strcpy(name, s.cell->name); numchar = strlen(name); strcpy(fbox, " "); LINK->n = 1; if (numchar & 1) strcpy(LINK->st, ".5"); else *LINK->st = '\0'; sprintf(fbox, "PA%ld,%ld,CP-%ld%s,-.25;LB%s\003", (long)floor((x1 + x0) * LINK->plotscale / 2 + 0.5), (long)floor((y1 + y0) * LINK->plotscale / 2 + 0.5), numchar / 2, LINK->st, name); LINK->n = strlen(fbox) + 1; P_writestringln((long)plotter, strrtrim(strcpy(STR2, fbox))); } Local Void crtbox(s, LINK) subcel s; struct LOC_plot *LINK; { Char name[201]; long x0, y0, x1, y1, numchar; x0 = s.x + LINK->xoffset; y0 = s.y + LINK->yoffset; LINK->n = 1; if (s.cell == NULL) { printf("Nil cell pointer\n"); return; } if (s.xfrm & 1) { x1 = x0 + s.cell->ly; y1 = y0 + s.cell->lx; } else { x1 = x0 + s.cell->lx; y1 = y0 + s.cell->ly; } x0 = (long)floor(x0 * LINK->plotscale + 0.5); x1 = (long)floor(x1 * LINK->plotscale + 0.5); y0 = (long)floor(y0 * LINK->plotscale + 0.5); y1 = (long)floor(y1 * LINK->plotscale + 0.5); m_move(x0, y0); m_draw(x0, y1); m_draw(x1, y1); m_draw(x1, y0); m_draw(x0, y0); /*the line following this is special for p2c*/ XFlush(m_display); strcpy(name, s.cell->name); numchar = strlen(name); m_move((long)floor((x1 + x0) / 2.0 + 0.5) - numchar * 3, (long)floor((y1 + y0) / 2.0 + 0.5) - 4); m_displaytext(name); } /*crtbox*/ /********************************************************/ Void plot(cell) cel *cell; { struct LOC_plot V; subcel *c; double xscale, yscale, microns; Char STR1[256]; TRY(try7); getsize(&V); xscale = (double)(V.xh - V.xl) / cell->lx; printf("xscale % .5E\n", xscale); yscale = (double)(V.yh - V.yl) / cell->ly; printf("yscale % .5E\n", yscale); if (xscale < yscale) { V.plotscale = xscale; V.xoffset = 0; V.yoffset = (long)floor(((V.yh - V.yl) / xscale - cell->ly) / 2 + 0.5); } else { V.plotscale = yscale; V.yoffset = 0; V.xoffset = (long)floor(((V.xh - V.xl) / yscale - cell->lx) / 2 + 0.5); } c = cell->contents; if (c == NULL) printf("No subcells in cell %s\n", cell->name); else { microns = lambda / 200.0; if (crtplt) { m_clear(); m_color(2L); printf("%s L = %ld; H = %ld microns.\n", cell->name, (long)floor(cell->lx * microns + 0.5), (long)floor(cell->ly * microns + 0.5)); while (c != NULL) { crtbox(*c, &V); c = c->next; } } else { strcpy(fbox, " "); sprintf(fbox, "SP1;LT;PA0,%12ldLB%s L=%ld H=%ld microns\003", V.yh - 200, cell->name, (long)floor(cell->lx * microns + 0.5), (long)floor(cell->ly * microns + 0.5)); V.n = strlen(fbox) + 1; P_writestringln((long)plotter, strrtrim(strcpy(STR1, fbox))); while (c != NULL) { plotbox(*c, &V); c = c->next; } } } RECOVER(try7); misc_printerror((long)P_escapecode, P_ioresult); printf("Clearing HPIB...\n"); abort_hpib(7); ENDTRY(try7); } /***************** These procedures compose cells *************************/ cel *cell(name) Char *name; { cel *c; boolean found; long number; c = first; found = false; while (c != NULL && !found) { if (!strcmp(c->name, name) && strlen(c->name) == strlen(name)) found = true; else c = c->next; } if (c == NULL) printf("Cell %s not loaded\n", name); else number = c->cifnum; return c; } /***************************************************************************/ Void define(name) Char *name; { cel *c; long n; Char s[201]; Char STR2[256]; add_cell_to_list(&c); /* new(c); c^.next:=nil; last^.next:=c; last:=c; */ strcpy(c->name, strltrim(strrtrim(strcpy(STR2, name)))); c->contents = NULL; current_cell = c; maxnum++; c->cifnum = maxnum; c->lx = 0; c->ly = 0; x0 = 0; y0 = 0; xmax = 0; ymax = 0; /* writeln(cif,'DS',maxnum:1,' ',lambda:1,' 2 ;'); */ outstr = get_outstr(); sprintf(outstr->str, "DS%ld %ld 2 ;", maxnum, lambda); junk = strlen(outstr->str) + 1; add_head_string(outstr); /* writeln(cif,'9 ',name,' ;'); */ outstr = get_outstr(); sprintf(outstr->str, "9 %s ;", name); junk = strlen(outstr->str) + 1; add_head_string(outstr); *s = '\0'; n = 1; sprintf(s, "Cell %s number %ld", name, maxnum); n = strlen(s) + 1; printf("Cell %s number %ld\n", name, maxnum); if (print_cells) P_writestringln(701L, strrtrim(strcpy(STR2, s))); } Void endef_routing(a_) Char *a_; { Char a[201]; FILE *infile; Char *TEMP; strcpy(a, a_); infile = NULL; print_cell(); /* dump all the lists */ if (*a != '\0') { if (infile != NULL) infile = freopen(a, "r", infile); else infile = fopen(a, "r"); if (infile == NULL) _EscIO(FileNotFound); while (fgets(a, 201, infile) != NULL) { TEMP = strchr(a, '\n'); if (TEMP != NULL) *TEMP = 0; fprintf(cif, "%s\n", a); } if (infile != NULL) fclose(infile); infile = NULL; } fprintf(cif, "DF;\n"); if (current_cell != NULL) { /*replaced "last" by "current_cell" */ current_cell->lx = xmax; /*Mass and Johnw 5/13/86*/ current_cell->ly = ymax; } current_cell = NULL; if (infile != NULL) fclose(infile); } Void endef() { endef_routing(""); } /***************************************************************************/ Void box(c) Char *c; { long l, w, xc, yc, junk; stringlist *outstr; outstr = get_outstr(); sprintf(outstr->str, "LC%s;", c); add_wire_string(outstr); xc = (x0 + x1) / 2; yc = (y0 + y1) / 2; l = x1 - x0; w = y1 - y0; outstr = get_outstr(); sprintf(outstr->str, "B %ld %ld %ld %ld;", l, w, xc, yc); junk = strlen(outstr->str) + 1; add_wire_string(outstr); if (x0 > xmax) xmax = x0; if (y0 > ymax) /* updates mbb of current cell */ ymax = y0; if (x1 > xmax) xmax = x1; if (y1 > ymax) /* updates mbb of current cell */ ymax = y1; } /*$if false$ PROCEDURE box(c:strg); var l,w,xc,yc:integer; junk : integer; outstr : stringlist_ptr; begin { writeln(cif,'LC',c,';'); } outstr := get_outstr; outstr^.str := 'LC'+c+';' ; add_wire_string (outstr); xc:=(x0+x1)div 2; yc:=(y0+y1) div 2; l:=(x1-x0); w:=(y1-y0); { write(cif,'B ',l:1,' ',w:1,' ',xc:1,' ',yc:1,';'); } if w > l then begin { vertical segment } outstr := get_outstr; strwrite(outstr^.str,1, junk,'W ',l:1,' ',xc:1,' ', y0+(l div 2):1); add_wire_string (outstr); outstr := get_outstr; strwrite(outstr^.str,1, junk,' ',xc:1,' ',y1 - (l div 2):1, ';'); add_wire_string (outstr); end else begin { horizontal segment } outstr := get_outstr; strwrite(outstr^.str,1, junk,'W ',w:1,' ',x0+(w div 2):1,' ', yc:1); add_wire_string (outstr); outstr := get_outstr; strwrite(outstr^.str,1, junk,' ',x1-(w div 2):1,' ',yc:1, ';'); add_wire_string (outstr); end; IF x0>xmax THEN xmax:=x1; IF y0>ymax THEN ymax:=y1; { updates mbb of current cell } IF x1>xmax THEN xmax:=x1; IF y1>ymax THEN ymax:=y1; { updates mbb of current cell } end; $end$*/ /**************************************************************************/ Void set_up() { Char *TEMP; print_cells = false; first = NULL; last = NULL; current_cell = NULL; /* nothing in list yet */ external_mbb = false; mbb_found = false; head_list = NULL; data_list = NULL; wire_list = NULL; garbage_list = NULL; search_library = false; x0 = 0; y0 = 0; maxnum = 0; width(4L); /* default wire width */ printf("WOLCOMP Version: %s; Compiled %s\n\n", Version, Compilation_date); *prefix = '\0'; lambda = 150; /* as good a default as any */ printf("WOLCOMP initialized with lambda = %0.2f microns.\n", lambda / 100.0); cif_type = WOL; /* default is WOL cif */ if (P_argc == 2) fix_name(cifxname, P_argv[1]); else { sprintf(cifxname, "%s.cif", P_argv[0]); printf(" Output file name [%s] ? ", cifxname); fgets(cifname, 201, stdin); TEMP = strchr(cifname, '\n'); if (TEMP != NULL) *TEMP = 0; if (*cifname == '\0') strcpy(cifname, cifxname); fix_name(cifxname, cifname); /* format file name to .CIF */ } printf("Writing to: %s\n", cifxname); if (cif != NULL) cif = freopen(cifxname, "w", cif); else cif = fopen(cifxname, "w"); if (cif == NULL) _EscIO(FileNotFound); } /*set_up*/ /******************************************/ Void shut_down() { Char name[201]; Char *TEMP; print_list(data_list); fprintf(cif, "E\n"); if (cif != NULL) fclose(cif); cif = NULL; printf(" Done writing output file.\n"); if (P_argc != 1) return; do { printf(" Plot Display dataStructures Quit ? "); scanf("%c%*[^\n]", &ch); getchar(); if (ch == '\n') ch = ' '; putchar('\n'); switch (ch) { case 'd': case 'D': printf(" Cell to be plotted: "); fgets(name, 201, stdin); TEMP = strchr(name, '\n'); if (TEMP != NULL) *TEMP = 0; current_cell = cell(name); crtplt = true; printf("\f"); m_init_graphics_nopen(); if (current_cell != NULL) plot(current_cell); break; case 'p': case 'P': printf(" Cell to be plotted: "); fgets(name, 201, stdin); TEMP = strchr(name, '\n'); if (TEMP != NULL) *TEMP = 0; current_cell = cell(name); crtplt = false; if (current_cell != NULL) plot(current_cell); P_writestringln((long)plotter, "SP0;IN;"); break; case 's': case 'S': dumplist(); break; case 'q': case 'Q': printf("Normal termination of WOLCOMP.\n"); break; default: printf("Illegal command: %c\n", ch); break; }/* case */ } while (ch != 'q' && ch != 'Q'); } /* End. */