/* CONBAE (LAY) -- Connection List Output */ /* CONBAE (LAY) -- Netzlistenausgabe */ /* // Copyright (c) 1992-2012 Oliver Bartels F+E, Muenchen // Author: Manfred Baumeister // Changes History: // rl (120427) RELEASED FOR BAE V7.8. // rl (110607) ENHANCEMENT: // Added constructive part net pin output support. // rl (101019) RELEASED FOR BAE V7.6. // rl (091020) RELEASED FOR BAE V7.4. // rl (081014) RELEASED FOR BAE V7.2. // rl (080519) ENHANCEMENT: // Added arbitrary net attribute command output support. // rl (071029) RELEASED FOR BAE V7.0. // rl (060829) RELEASED FOR BAE V6.8. // rl (051011) ENHANCEMENT: // Added complete attribute output suppress option. // rl (050906) RELEASED FOR BAE V6.6. // rl (050729) ENHANCEMENT: // Added net highlight restricted output option. // rl (040811) RELEASED FOR BAE V6.4. // rl (040513) ENHANCEMENT: // Added test point macro configuration through bae.ini. // rl (040317) ENHANCEMENT: // Added net visibility restricted output option. // rl (030904) RELEASED FOR BAE V6.2. // rl (021209) RELEASED FOR BAE V6.0. // rl (020618) RELEASED FOR BAE V5.4. // rl (010709) RELEASED FOR BAE V5.0. // rl (010404) ENHANCEMENT: // Added optional parameter settings from bae.ini file. // rl (000512) RELEASED FOR BAE V4.6. // rl (000505) ENHANCEMENT: // Introduced dialog box parameter selection. // rl (990625) RELEASED FOR BAE V4.4. // rl (980910) RELEASED FOR BAE V4.2. // rl (980908) ENHANCEMENT/BUGFIX: // Added pin attribute output. // Net attribute output enclosed in comment. // Fixed bug in netroutwidth function. // mb (980710) ENHANCEMENT: // Dynamic multi-language support introduced. // rl (980116) RELEASED FOR BAE V4.0. // mb (960919) RELEASED FOR BAE V3.4. // mb (951017) ENHANCEMENT: // Option for adding test points implemented. // Option for generating single-pin net output implemented. // mb (951012) IMPROVEMENT: // Performing BAE_Demo_check(2) before starting output. // mb (95) RELEASED FOR BAE V3.2. // mb (950223) ENHANCEMENT: // Introduced part alternate physical library name output. // Placement data output verification only if parts placed. // mb (941115) ENHANCEMENT: // Net attributes included with netlist output. // Placement data output option implemented. // mb (94) RELEASED FOR BAE V3.0. // mb (94) IMPROVEMENT: // Introduced identifier output option (no/single/double-quoted). // mb (94) RELEASED FOR BAE V3.0. // mb (93) RELEASED FOR BAE V2.6. // mb (93) RELEASED FOR BAE V2.4. // mb (92) RELEASED FOR BAE V2.2. // mb (92) ORIGINAL CODING. // // DESCRIPTION // // The conbae User Language program generates netlist data output // for the currently loaded layout in BAE ASCII netlist format. // The output is directed to a file, whereby sorting of part and // net names is accomplished on demand. Part placement data, as // well as automatically generated test points and single-pin // nets may optionally be included with the output. // // WARNINGS // // Add test points option is only provided if none of the synthetically // to be generated test point part names ("tp_") is currently // used on the layout. The test point part macro list provided by the // add test points options is predefined and should match available part // library definitions. Test points are generated for multi-pin nets only! */ // Includes #include "pop.ulh" // User Language popup utilities #include "lay.ulh" // User Language layout utilities // Disable undo state request #pragma ULCALLERNOUNDO // Messages string UPRABORT = M_UPRABORT(); string REPSTART = M("Verbindungslisten-Ausgabe...", "Connection list output..."); string REPDONE = M("Verbindungsliste ausgegeben auf Datei '%s'.", "Connection list written to file '%s'."); string UPRQUOTYP = M("Identifier-Ausgabemodus selektieren!", "Select Identifier Output Mode!"); string UPRDQUOTYP = M("Identifier-Ausgabemodus :", "Identifier Output Mode :"); string UPRNQUOTE = M("&Keine Quotes","&No Quotes"); string UPRSQUOTE = M("&Single Quotes","&Single Quotes"); string UPRDQUOTE = M("&Double Quotes","&Double Quotes"); string UPRATTRIB = M("Bauteilattribut-Ausgabemodus selektieren!", "Select Part Attributes Output Mode!"); string UPRDATTRIB = M("Bauteilattributeausgabe :", "Part Attributes Output :"); string UPRATTCOMM = M("&Attributkommentare","&Attribute Comments"); string UPRATTCMD = M("Attribut&kommandos","Attribute &Commands"); string UPRATTNONE = M("Ke&ine Attribute","&No Attributes"); string UPRDNET = M("Netzausgabe :","Net Output :"); string UPRNETALL = M("&Alle","&All"); string UPRNETVIS = M("Nur &sichtbare Netze","Only &visible Nets"); string UPRNETHL = M("Nur &gehighlightete Netze", "Only &highlighted Nets"); string UPRPINS = M("Pin-Ausgabemodus selektieren!", "Select Pin Attributes Output Mode!"); string UPRDPINS = M("Pinausgabe :", "Pin Output :"); string UPRPIN1 = M("&Keine Single-Pin-Netze", "&No Single Pin Nets"); string UPRPINA = M("Alle &Netzpins", "All &Net Pins"); string UPRPINC = M("&Angeschlossene Konstruktive", "&Connected Constructive Pins"); string UPRPLACE = M("Platzierungsdaten ausgeben ? ", "Placement Data Output ? "); string UPRDPLACE = M("Platzierungsdatenausgabe :", "Placement Data Output :"); string UPRALTPL = M("Alternativbauformen ausgeben ? ", "Alternate Part Macro Output ? "); string UPRDALTPL = M("Alternativbauformliste :", "Alternate Part Macro Output :"); string UPRTESTPT = M("Testpunkte ausgeben ? ", "Test Points Output ? "); string UPRDTESTPT = M("Testpunkt-Bauteilmakro :", "Test Point Part Macro :"); string UPRTPMAC = M("Testpunkt-Bauteilmakro selektieren!", "Select Test Point Part Macro!"); string UPRNTESTPT = M("&Keine Testpunkte","&No Test Points"); string UPRSORT = M("Namen sortieren ? ","Sort Names ? "); string UPRDSORT = M("Namenssortierung :","Name Sorting :"); string UPRPARAMDIAL = M("Parametereinstellungen","Settings"); string UPRRBOFF = M("&Aus","O&ff"); string UPRRBON = M("&Ein","&On"); string UPRFEXISTS = M("Ausgabedatei '%s' existiert bereits. Ueberschreiben ?", "Output file '%s' already exits. Overwrite ?"); // INI file parameter name definitions #define PAR_CONOFEXT "CONOFEXT_LAY" // Connection output file name ext. #define PAR_CONMPPL "CONMPPL_LAY" // Maximum pins per line #define PAR_CONQUOM "CONQUOM_LAY" // Quoted output mode #define PAR_CONATTR "CONATTR_LAY" // Attributes output flag #define PAR_CONSINGPIN "CONSINGPIN_LAY" // Single-pin net output flag #define PAR_CONPLCOUT "CONPLCOUT_LAY" // Placement data output flag #define PAR_CONALTPL "CONALTPL_LAY" // Alternate part data output flag #define PAR_CONSORT "CONSORT_LAY" // Sort output data flag #define PAR_CONTPPREF "CONTPPREF_LAY" // Test point part name prefix #define PAR_CONTPL "CONTPL_LAY" // Test point macro name list // Output format strings #define FMTHEADER "LAYOUT %s%s%s ;\n" #define FMTPARTHD "\nPARTS\n" #define FMTPART " %s%s%s\t: %s%s%s" #define FMTALTPL ",%s%s%s" #define FMTNCPART " %s%s%s\t: %s%s%s ;\t/* Constructive Part ! */\n" #define FMTATTSTA "\t{ /* Attributes : */\n" #define FMTATTRIB "\t\"%s\"\t= \"%s\" ;\n" #define FMTATTEND "\t}" #define FMTATTCMT "\t/* \"%s\"\t= \"%s\" */\n" #define FMTCONHD "\nCONNECT\n" #define FMTCON " /%s%s%s/" #define FMTCONPR " PRIORITY(%d)" #define FMTCONMD " MINDIST(%5.3f)" #define FMTCONRW " ROUTWIDTH(%5.3f)" #define FMTCONPIN "%s%s%s%s.%s%s%s" #define FMTPINRW "(%5.3f)" #define FMTPINNL "\n\t" #define FMTPINDEL "=" #define FMTPLCHD "\nPLACE (1.0 %s 1.0 DEG)\n" #define FMTPLCPRT " %s%s%s {\n" #define FMTPLCPOS "\tPOSITION = (%10.4f,%10.4f) ;\n" #define FMTPLCROT "\tROTATION = %7.3f ;\n" #define FMTPLCMIR "\tMIRROR = %d ;\n" #define FMTPLCEND "\t}\n" #define FMTCMDTRM ";\n" #define FMTTERM "\nEND.\n" #define ITMUNITMM "MM" #define ITMUNITIN "INCH" // Globals string CLEXT = bae_inistrval(PAR_CONOFEXT,".con") /* Con. file name extension */; int MAXPPL = bae_iniintval(PAR_CONMPPL,5) /* Maximum pins per line */; int NETMODE = 0 /* Net output output mode */; int QUOMODE = bae_iniintval(PAR_CONQUOM,0) /* Quoted output mode */; string QUOSTR /* Quote character string */; int ATTRIBOUT = bae_iniintval(PAR_CONATTR,0) /* Attributes output flag */; int PINOUT = bae_iniintval(PAR_CONSINGPIN,0) /* Pin net output mode */; int PLACEOUT = bae_iniintval(PAR_CONPLCOUT,0) /* Placement data output flag */; int ALTPLFLAG = bae_iniintval(PAR_CONALTPL,1) /* Alternate part output data flag */; int SORTFLAG = bae_iniintval(PAR_CONSORT,0) /* Sort output data flag */; index L_CPART partl[] /* Part list */; int partil[] /* Part index list */; int partn = 0 /* Part count */; string curpartname /* Current part name */; int curpinnet /* Current pin net number */; int pincount /* Pin count */; int pfh /* Current part output file handle */; index L_CNET netl[] /* Net list */; int netil[] /* Net index list */; int netn = 0 /* Net count */; int TESTPOINTS /* Add test points flag */; string TPPREFIX = bae_inistrval(PAR_CONTPPREF,"tp_") /* Test point part name prefix */; string TPSYM /* Test point symbol name */; string TPPIN /* Test point pin name */; struct tpdes { // Test point symbol descriptor string m /* Test point macro name */; string p /* Test point pin name */; }; struct tpdes deftpl[] = { // Default test point symbol list {"&tp", "1"}, {"tp&in", "1"}, {"tpa&d", "1"}, {"&pin", "1"}, {"pin&1", "1"}, {"pad&08k","1"}, {"pad0&8n","1"}, {"pad10&n","1"}, {"p&ad11n" ,"1"}, {"pad13&g","1"}, {"pad1&3k","1"}, {"pad13n" ,"1"}, {"pad16&k","1"}, {"pad1&6n","1"}, {UPRABORT,""} }; struct tpdes tpl[] /* Default test point symbol list */; int tpn /* Test point symbol count */; // Main program void main() { string msg /* Message buffer */; string jobfname /* Job file name */; string jobename /* Job element name */; string confname /* Connection file name */; int confh /* Connection file handle */; index L_CPART cpart /* Connection part index */; index L_CNET cnet /* Connection net index */; index L_NREF nref /* Named reference index */; int tpidx /* Test point index */; double pcol = 23.0 /* Parameter column */; double cy /* Dialog box current y coordinate */; int repflag /* Dialog box repeat flag */; int res /* Dialog box result */; int quoidx = (-1) /* Quoted output parameter index */; int noidx = (-1) /* Net output parameter index */; int attidx = (-1) /* Attr. output parameter index */; int plcidx = (-1) /* Place output parameter index */; int aplidx = (-1) /* Alt. part output parameter index */; int pinidx = (-1) /* Pin output mode param. index */; int sortidx = (-1) /* Sorted output parameter index */; int tpoidx = (-1) /* Test point output param. index */; int varidx /* INI variable index */; // Abort if invalid plan class if (bae_planddbclass()!=DDBCLLAY) error_class(); // Perform BAE Demo check with abort option BAE_Demo_check(2); // Get the plan file and element names jobfname=bae_planfname(); jobename=bae_planename(); // Build the output file name confname=convstring(jobfname,0)+CLEXT; // Test the output file fseterrmode(0); if ((confh=fopen(confname,0))!=(-1)) { fclose(confh); fseterrmode(1); sprintf(msg,UPRFEXISTS,confname); if (bae_msgboxverify(msg,"")!=1) error_abort(); } fseterrmode(1); TESTPOINTS=!findtppart(); // Get the test point list for (tpn=0;tpn<31;tpn++) { if ((tpl[tpn].m=bae_inistrval( bae_inifieldvarname(PAR_CONTPL,tpn,0),""))=="") { // Check if list defined at all if (tpn==0) { // Use test point list tpl=deftpl; tpn=arylength(tpl); } else { tpl[tpn].m=UPRABORT; tpl[tpn].p=""; tpn++; } break; } tpl[tpn].p=bae_inistrval( bae_inifieldvarname(PAR_CONTPL,tpn,1),""); } // Check for dialog support if (bae_dialclr()) { // Select identifier output mode bae_promptdialog(UPRQUOTYP); if ((QUOMODE=bae_askmenu(4,UPRNQUOTE,UPRSQUOTE,UPRDQUOTE, UPRABORT))<0 || QUOMODE>2) error_abort(); // Select attributes output mode bae_promptdialog(UPRATTRIB); if ((ATTRIBOUT=bae_askmenu(4,UPRATTCOMM,UPRATTCMD,UPRATTNONE, UPRABORT))<0 || ATTRIBOUT>2) error_abort(); // Select pin output mode bae_promptdialog(UPRPINS); if ((PINOUT=bae_askmenu(4,UPRPIN1,UPRPINA,UPRPINC, UPRABORT))<0 || PINOUT>2) error_abort(); // Select placement data output mode if any part placed forall (nref) { PLACEOUT=verify(UPRPLACE,1); break; } // Select placement data output mode if any part placed forall (nref) { PLACEOUT=verify(UPRPLACE,1); break; } // Select alternate part output mode ALTPLFLAG=verify(UPRALTPL,1); // Select test point output mode if (TESTPOINTS && (TESTPOINTS=verify(UPRTESTPT,1))) { // Select the test point part macro bae_promptdialog(UPRTPMAC); if ((tpidx=bae_askmenu(tpn,tpl[0].m,tpl[1].m, tpl[2].m,tpl[3].m,tpl[4].m,tpl[5].m,tpl[6].m, tpl[7].m,tpl[8].m,tpl[9].m,tpl[10].m,tpl[11].m, tpl[12].m,tpl[13].m,tpl[14].m))>=tpn-1) error_abort(); // Get the test point symbol name TPSYM=bae_plainmenutext(tpl[tpidx].m); // Get the test point pin name TPPIN=tpl[tpidx].p; } // Select output sort mode SORTFLAG=verify(UPRSORT,1); } else { // Init. the y coordinate cy=DIAL_TOPMARG; // Store identifier output mode controls dial_label(0.0,cy,UPRDQUOTYP); quoidx=dial_selbox(QUOMODE,pcol,cy); dial_sbentry(0,0,UPRNQUOTE); dial_sbentry(0,1,UPRSQUOTE); dial_sbentry(0,2,UPRDQUOTE); // Store net output mode controls dial_label(0.0,cy,UPRDNET); noidx=dial_selbox(NETMODE,pcol,cy); dial_sbentry(0,0,UPRNETALL); dial_sbentry(0,1,UPRNETVIS); dial_sbentry(0,2,UPRNETHL); // Store attribute output controls dial_label(0.0,cy,UPRDATTRIB); attidx=dial_selbox(ATTRIBOUT,pcol,cy); dial_sbentry(0,0,UPRATTCOMM); dial_sbentry(0,1,UPRATTCMD); dial_sbentry(0,2,UPRATTNONE); // Store single pin net output controls dial_label(0.0,cy,UPRDPINS); pinidx=dial_selbox(PINOUT,pcol,cy); dial_sbentry(0,0,UPRPIN1); dial_sbentry(0,1,UPRPINA); dial_sbentry(0,2,UPRPINC); // Select placement data output mode if any part placed forall (nref) { // Store placement output controls dial_label(0.0,cy,UPRDPLACE); plcidx=bae_dialaddcontrol(PA_RBF,0,0,PLACEOUT,0.0,0.0, 0.0,"",0,DIAL_LEFTMARG+pcol+1.0,cy,0.0,UPRRBOFF); bae_dialaddcontrol(PA_RBN,1,0,0,0.0,0.0,0.0,"", 0,DIAL_LEFTMARG+pcol+10.0,cy,0.0,UPRRBON); cy+=DIAL_CTRVSTEP; break; } // Store alternate part output controls dial_label(0.0,cy,UPRDALTPL); aplidx=bae_dialaddcontrol(PA_RBF,0,0,ALTPLFLAG,0.0,0.0, 0.0,"",0,DIAL_LEFTMARG+pcol+1.0,cy,0.0,UPRRBOFF); bae_dialaddcontrol(PA_RBN,1,0,0,0.0,0.0,0.0,"", 0,DIAL_LEFTMARG+pcol+10.0,cy,0.0,UPRRBON); cy+=DIAL_CTRVSTEP; // Select test point mode if (TESTPOINTS) { // Store test point macro controls dial_label(0.0,cy,UPRDTESTPT); tpoidx=dial_selbox(0,pcol,cy); dial_sbentry(0,0,UPRNTESTPT); for (tpidx=0;tpidx<(tpn-1);tpidx++) dial_sbentry(0,tpidx+1,tpl[tpidx].m); } // Store output sort controls dial_label(0.0,cy,UPRDSORT); sortidx=bae_dialaddcontrol(PA_RBF,0,0,SORTFLAG,0.0,0.0,0.0,"", 0,DIAL_LEFTMARG+pcol+1.0,cy,0.0,UPRRBOFF); bae_dialaddcontrol(PA_RBN,1,0,0,0.0,0.0,0.0,"", 0,DIAL_LEFTMARG+pcol+10.0,cy,0.0,UPRRBON); cy+=DIAL_CTRVSTEP; // Store the OK and abort button with seperator dial_hsep(cy); dial_okabortini(cy,pcol+24.7,1); // Perform the dialog input loop repflag=1; do { // Call the dialog function bae_setintpar(16,4001); if ((res=bae_dialaskparams( UPRPARAMDIAL,0,DIAL_LEFTMARG+pcol+24.7,cy))<0) error_abort(); // Get data from dialog box entries bae_dialgetdata(quoidx,QUOMODE,0.0,""); bae_dialgetdata(noidx,NETMODE,0.0,""); bae_dialgetdata(attidx,ATTRIBOUT,0.0,""); bae_dialgetdata(pinidx,PINOUT,0.0,""); bae_dialgetdata(aplidx,ALTPLFLAG,0.0,""); bae_dialgetdata(sortidx,SORTFLAG,0.0,""); if (plcidx!=(-1)) bae_dialgetdata(plcidx,PLACEOUT,0.0,""); else PLACEOUT=0; if (tpoidx!=(-1)) { bae_dialgetdata(tpoidx,tpidx,0.0,""); // Check if test point selected if (tpidx==0) { TESTPOINTS=0; } else { TESTPOINTS=1; // Get the test point sym.name TPSYM=bae_plainmenutext( tpl[tpidx-1].m); // Get the test point pin name TPPIN=tpl[tpidx-1].p; } } else { TESTPOINTS=0; } if (res==1) { varidx=0; bae_iniintset(varidx,PAR_CONQUOM,QUOMODE); bae_iniintset(varidx,PAR_CONATTR,ATTRIBOUT); bae_iniintset(varidx,PAR_CONSINGPIN,PINOUT); bae_iniintset(varidx,PAR_CONALTPL,ALTPLFLAG); bae_iniintset(varidx,PAR_CONSORT,SORTFLAG); if (plcidx!=(-1)) bae_iniintset(varidx,PAR_CONPLCOUT, PLACEOUT); bae_iniwrite(varidx); continue; } repflag=0; // Stop if no further repeat requests } while (repflag); } // Check the identifier output mode switch (QUOMODE) { // Single quote case 1 : QUOSTR="'"; break; // Double quote case 2 : QUOSTR="\""; break; // No quote case 0 : default : QUOSTR=""; } bae_prtdialog(REPSTART); // Create unsorted lists forall (cpart) { partil[partn]=partn; partl[partn++]=cpart; } forall (cnet) { netil[netn]=netn; netl[netn++]=cnet; } if (SORTFLAG) { // Sort lists quicksort(partil,partn,partcmp); quicksort(netil,netn,netcmp); } // Open the output file confh=bae_fopen(confname,1); // Print the file header fprintf(confh,FMTHEADER,QUOSTR,jobename,QUOSTR); // Print the part list cpartlist(confh); // Print the net list cnetlist(confh); // Print the placement data on request if (PLACEOUT) cplacelist(confh); // Print the output file terminator fprintf(confh,FMTTERM); // Close the output file fclose(confh); // Done message(REPDONE,confname); } int findtppart() /* // Test if any synthetically generated test point part name is used // Return value : // nonzero if test point part found or zero else */ { index L_CNET cnet /* Connection net index */; index L_CPART cpart /* Connection part index */; index L_FIGURE fig /* Figure list index */; // Loop thru all nets forall (cnet where cnet.PINN>1) // Print the test point part if (lay_findconpart(TPPREFIX+cnet.NAME,cpart)==0 || lay_nrefsearch(TPPREFIX+cnet.NAME,fig)==0) return(1); // No test point part found return(0); } void cpartlist(int fh) /* // Print the connection part list // Parameters : // int fh : Output file handle */ { index L_CPART part /* Part index */; index L_ATTRIBUTE att /* Attribute index */; index L_ALTPLNAME altpl /* Alt. phys. lib. name index */; index L_NREF nref /* Named reference index */; index L_CNET cnet /* Connection net index */; int pidx /* Part list index */; int attout /* Attribute output flag */; // Print the list header fprintf(fh,FMTPARTHD); // Loop thru the part list for (pidx=0;pidx1) { // Print the test point part fprintf(fh,FMTPART,QUOSTR,TPPREFIX+cnet.NAME,QUOSTR, QUOSTR,TPSYM,QUOSTR); fprintf(fh,FMTCMDTRM); } } void cnetlist(int fh) /* // Print the connection net list // Parameters : // int fh : Output file handle */ { index L_CNET net /* Net index */; index L_CPIN pin /* Pin index */; index L_FIGURE fig /* Figure list index */; index L_CPART part /* Part index */; index L_ATTRIBUTE att /* Attribute index */; double routwidth /* Net routing width */; int nidx /* Net list index */; int hlflag /* Highlight flag */; int attout /* Attribute output flag */; // Print the list header fprintf(fh,FMTCONHD); // Loop thru all nets for (nidx=0;nidx1 ? FMTPINDEL : "", QUOSTR,pin.CPART.NAME,QUOSTR, QUOSTR,pin.NAME,QUOSTR); // Print the pin routing width if (routwidth==0.0 && pin.RWIDTH!=0.0) fprintf(fh,FMTPINRW, cvtlength(pin.RWIDTH,0,2)); // Check on part attribute output request switch (ATTRIBOUT) { case 1 : // Reset the attributes output flag attout=0; // Loop thru the pin attribute list forall (att of pin where att.NAME!="$net" && att.NAME!="$sym" && att.NAME!="$blkname" && att.NAME!="$blkrname") { // Start attribute list on request if (!attout) { fprintf(fh,FMTATTSTA); attout=1; } // Print the attribute name and value fprintf(fh,FMTATTRIB, att.NAME,att.VALUE); } // End attribute list on request if (attout) fprintf(fh,FMTATTEND); break; case 0 : // Loop thru the pin attribute list forall (att of pin where att.NAME!="$net" && att.NAME!="$sym" && att.NAME!="$blkname" && att.NAME!="$blkrname") // Print attribute name/value comment fprintf(fh,FMTATTCMT, att.NAME,att.VALUE); break; } } // Print test point pin on request if (TESTPOINTS && net.PINN>1) fprintf(fh,FMTCONPIN,FMTPINDEL, QUOSTR,TPPREFIX+net.NAME,QUOSTR, QUOSTR,TPPIN,QUOSTR); if (PINOUT==2) { pfh=fh; curpinnet=net.NUMBER; forall (fig where fig.TYP==L_FIGNREF && lay_findconpart(fig.NAME,part)!=0) { curpartname=fig.NAME; lay_scanfelem(fig,0.0,0.0,0.0,1,0, pinfunc,NULL,NULL,NULL,NULL,NULL,NULL); } } // Terminate the pin list fprintf(fh,FMTCMDTRM); } } int pinfunc(index L_MACRO macro,index L_POOL pool,int macinws, string refname,index L_LEVEL level) /* // Pin net scan function // Returns : (-1) on scan error, 0 on scan stop, 1 on scan continue // Parameters : // index L_MACRO macro : Macro index // index L_POOL pool : Macro pool element (internal) // int macinws : Macro in workspace flag // string refname : Macro reference name // index L_LEVEL level : Macro level */ { // Test if pad if (macro.CLASS==DDBCLLPAD) // Macro not of interest; return the stop scan flag return(0); // Test if padstack if (macro.CLASS==DDBCLLSTK) { if (refname!="" && level.LEVVAL==curpinnet) { // Increment and test the pin count if ((++pincount)%MAXPPL==0) // Start a new line fprintf(pfh,FMTPINNL); // Print the pin fprintf(pfh,FMTCONPIN,pincount>1 ? FMTPINDEL : "", QUOSTR,curpartname,QUOSTR,QUOSTR,refname,QUOSTR); } // Pin checked, we are done return(0); } // Continue scan return(1); } void cplacelist(int fh) /* // Print the part placement list // Parameters : // int fh : Output file handle */ { index L_NREF nref /* Named reference index */; double nx,ny /* Plan origin coordinates */; int headerout = 0 /* Header output flag */; // Get the plan origin nx=bae_planwsnx(); ny=bae_planwsny(); // Loop thru the named reference list forall (nref) { // Test if header not yet printed if (!headerout) { // Print the placement header fprintf(fh,FMTPLCHD, bae_getcoorddisp() ? ITMUNITIN : ITMUNITMM); headerout=1; } // Print the part placement entry fprintf(fh,FMTPLCPRT,QUOSTR,nref.NAME,QUOSTR); // Print the part placement coordinates fprintf(fh,FMTPLCPOS,baecvtl(nref.X-nx),baecvtl(nref.Y-ny)); // Print the part rotation angle if not default if (nref.ANGLE!=0.0) fprintf(fh,FMTPLCROT,cvtangle(nref.ANGLE,0,1)); // Print the part mirror mode if not default if (nref.MIRROR) fprintf(fh,FMTPLCMIR,nref.MIRROR); // Print the placement part terminator fprintf(fh,FMTPLCEND); } } // List sort routines static int partcmp(int idx1,int idx2) /* // Part name compare function // Return value : // (-1) if idx1idx2 // Parameters : // int idx1 : First compare index // int idx2 : Second compare index */ { // Return compare result return(numstrcmp(partl[idx1].NAME,partl[idx2].NAME)); } static int netcmp(int idx1,int idx2) /* // Net name compare function // Return value : // (-1) if idx1idx2 // Parameters : // int idx1 : First compare index // int idx2 : Second compare index */ { // Return compare result return(numstrcmp(netl[idx1].NAME,netl[idx2].NAME)); } double netroutwidth(index L_CNET net) /* // Get the routing width of a net // Return value : // routing width, or 0.0 if two pins with different width // Parameters : // index L_CNET net : Net index */ { index L_CPIN pin /* Pin index */; int pincnt = 0 /* Pin count */; double rw = 0.0 /* Rout width */; // Loop thru all pins forall (pin of net) { // Test if the pin introduces a new rout width if (pin.RWIDTH!=rw && pincnt>0) return(0.0); // Increment net pin count pincnt++; // Set the rout width rw=pin.RWIDTH; } // Return the rout width return(rw); } // User Language program end