/* UNCONPIN (LAY) -- Unconnected Pins Report */ /* UNCONPIN (LAY) -- Anzeige nicht angeschlossener Pins */ /* // Copyright (c) 1993-2012 Oliver Bartels F+E, Muenchen // Author: Manfred Baumeister // Changes History: // rl (120427) RELEASED FOR BAE V7.8. // rl (101019) RELEASED FOR BAE V7.6. // rl (100226) Change: // Introduced sorting of shortcut pins by level number/net name. // rl (091021) RELEASED FOR BAE V7.4. // rl (081014) RELEASED FOR BAE V7.2. // rl (071029) RELEASED FOR BAE V7.0. // rl (060829) RELEASED FOR BAE V6.8. // rl (050906) RELEASED FOR BAE V6.6. // rl (050125) ENHANCEMENT: // Added pin position columns to output list. // rl (040811) RELEASED FOR BAE V6.4. // rl (030904) RELEASED FOR BAE V6.2. // rl (021209) RELEASED FOR BAE V6.0. // rl (020618) RELEASED FOR BAE V5.4. // rl (011108) ENHANCEMENT: // Added net name display for routed free pins. // rl (010626) RELEASED FOR BAE V5.0. // rl (000509) RELEASED FOR BAE V4.6. // rl (990625) RELEASED FOR BAE V4.4. // rl (980910) RELEASED FOR BAE V4.2. // mb (980711) ENHANCEMENT: // Dynamic multi-language support introduced. // rl (970929) RELEASED FOR BAE V4.0. // rl (970512) IMPROVEMENT: // Added pins report for non netlist (constructive) parts. // mb (961030) IMPROVEMENT: // Levels with numbers and values included to pin report. // mb (960919) RELEASED FOR BAE V3.4. // mb (95) RELEASED FOR BAE V3.2. // mb (941129) IMPROVEMENT: // Introduced screen popup output. // Introduced feature for program abort on key hit. // mb (94) RELEASED FOR BAE V3.0. // mb (93) RELEASED FOR BAE V2.6. // mb (93) ORIGINAL CODING. // // DESCRIPTION // // The unconpin User Language program provides a list of the // unrouted pins of the currently loaded layout. The unrouted // pins report is displayed in a popup menu with file output // option. */ // Includes #include "pop.ulh" // User Language popup utilities // Disable undo state request #pragma ULCALLERNOUNDO // Messages string UPRPEXIT = M_UPRPEXIT(); string REPSCANPIN = M("Scannen Pins / Bauteil '%s'...", "Scanning pins / Part '%s'..."); string REPHEADER = M("Pin-Report (Datei '%s' / Layout '%s') :", "Pin Report (File '%s' / Layout '%s') :"); string REPPINTOT = M(" Anzahl Pins gesamt ............: %5d", " Number of Pins total ..........: %5d"); string REPPINC = M(" Anzahl Netzpins gesamt ........: %5d", " Number of Net Pins total ......: %5d"); string REPPINCUR = M(" Anzahl Netzpins ungeroutet ....: %5d", " Number of Net Pins unrouted ...: %5d"); string REPPINNC = M(" Anzahl Freipins gesamt ........: %5d", " Number of Free Pins total .....: %5d"); string REPPINNCR = M(" Anzahl Freipins geroutet ......: %5d", " Number of Free Pins routed ....: %5d"); string REPPINSC = M(" Anzahl Kurzschlusspins ........: %5d", " Number of Short Circuit Pins ..: %5d"); string REPNETCOMB = M("Zusammengefasste Netze :", "Combined Nets :"); string ITMPART = M("Bauteil","Part"); string ITMPIN = M("Pin","Pin"); string ITMNET = M("Netz","Net"); string ITMLEVEL = M("Level/ Wert","Level/ Value"); string ITMNOTE = M("Anmerkung","Note"); string ITMCR = M("Netzpin geroutet","Netlist Pin Routed"); string ITMCUR = M("Netzpin ungeroutet","Netlist Pin Unrouted"); string ITMNCR = M("Freipin geroutet","Free Pin Routed"); string ITMNCUR = M("Freipin ungeroutet","Free Pin Unrouted"); string ITMSC = M("Kurzschlussgruppe ","Short Circuit Group "); #define FMTTABHD "%-*s %-*s %8s %8s MIRROR %-*s %-*s %s" #define FMTTABUL "%.*s %.*s ======== ======== ====== %.*s %.*s %.*s" #define FMTENTRY "%-*s %-*s %8.3f %8.3f %6d %-*s %5d/%6d %s" #define FMTNENTRY " %s : %s" #define ITMULINE "==================================================" int MAXPARTNL = strlen(ITMPART) /* Max. part name length */; int MAXPINNL = strlen(ITMPIN) /* Max. pin name length */; int MAXNETNL = strlen(ITMNET) /* Max. net name length */; #define MAXLEVL 12 // Max. level entry length int MAXNOTEL = strlen(ITMCUR) /* Max. note length */; // Globals #define UNITM "[mm]" // Units designator mm #define UNITI "[\"]" // Units designator inch string UNIT /* Units designator string */; index L_CPART curpart /* Current connection part index */; string curpartname /* Current connection part name */; int curpartf /* Current con. part valid flag */; struct pindes { // Pin descriptor index L_CPART part /* Pin part */; int partf /* Pin connection part valid */; string partname /* Pin part name */; double x,y /* Pin coordinates */; int mirror /* Pin mirror flag */; index L_LEVEL level /* Pin level */; int netnum /* Pin net number */; string netname /* Net name */; string pinname /* Pin name */; int pintyp /* Pin type */; string dispstr /* Pin display string */; } pins[] /* Pin list */; int pinidxl[] /* Pin sort index list */; int pinn = 0 /* Pin count */; struct leveldes { // Level descriptor int npincnt /* Level net pin count */; int upincnt /* Level unconnected pin count */; } levels[] /* Level list */; int leveln = 0 /* Level count */; STRINGS headl /* Popup header list */; int headn /* Popup header count */; STRINGS entryl /* Popup entry list */; int entryn = 0 /* Popup entry count */; // Main program void main() { index L_CNET cnet /* Connection net index */; index L_CPART cpart /* Connection part index */; index L_CPIN cpin /* Connection pin index */; index L_LEVEL level /* Level index */; index L_LEVEL sclevel /* Short circuit level index */; index L_ATTRIBUTE attr /* Attribute index */; int scnum = 0 /* Short circuit number */; int levidx /* Level list index */; int routed /* Pin routed flag */; int freeflag /* Free pin flag */; int partf /* Connection part valid flag */; int pintyp /* Pin type pass */; int pidx /* Pin index */; string netname /* Net name buffer */; string itemstr /* Item string buffer */; int netcomb = 0 /* Net combined count */; int netpin = 0 /* Net pin count */; int netpinur = 0 /* Unrouted net pin count */; int freepin = 0 /* Free pin count */; int freepinr = 0 /* Routed free pin count */; int scpin = 0 /* Short circuit pin count */; int i /* Loop control variable */; // Abort if invalid plan class if (bae_planddbclass()!=DDBCLLAY) error_class(); // Get maximum net name length forall (cnet) MAXNETNL=maxint(MAXNETNL,strlen(cnet.NAME)); MAXNETNL+=2; // Count pins forall (cpart) forall (cpin of cpart) pinn++; forall (level) { levels[leveln].npincnt=levels[leveln].upincnt=0; leveln++; } // "Allocate" the pin list pins[pinn].pinname=""; entryl[pinn]=""; pinn=0; // Scan part pins if (lay_scanall(bae_planwsnx(),bae_planwsny(),0.0,1,1, macfunc,NULL,NULL,NULL,NULL,NULL,NULL)!=0) error_scan(); // Classify pins for (i=0;i=0 && levels[levidx].npincnt>1; else routed=(levidx=findlevel(pins[i].level))>=0 && (levels[levidx].npincnt+levels[levidx].upincnt)>1; // Get the free pin flag netname=""; freeflag=1; if (partf && pins[i].netnum>=0 && lay_gettreeidx(pins[i].level.LEVVAL,cnet)==0) { netname=cnet.NAME; freeflag=cnet.PINN<=1; } // Test free pin flag if (freeflag) ++freepin; else ++netpin; // Reset the item string buffer itemstr=""; // Designate the pin type if (pins[i].level.LEVVAL==(-1)) { pintyp=0; itemstr=ITMSC; // Short circuit pin ++scpin; // Get the net name netname=""; if (partf && lay_findconpartpin( pins[i].pinname,pins[i].part,cpin)==0) netname=cpin.CNET.NAME; } else if (!freeflag && !routed) { // Unrouted netlist pin pintyp=3; itemstr=ITMCUR; ++netpinur; } else if (freeflag) { if (routed) { // Routed free pin pintyp=1; itemstr=ITMNCR; ++freepinr; } else { // Unrouted free pin pintyp=2; itemstr=ITMNCUR; } } else { // Routed netlist pin pintyp=4; itemstr=ITMCR; } // Check if net known by connection if (netname=="" && lay_gettreeidx(pins[i].level.LEVVAL,cnet)==0) netname="("+cnet.NAME+")"; pins[i].netname=netname; // Store the pin display string sprintf(pins[i].dispstr,FMTENTRY,MAXPARTNL,pins[i].partname, MAXPINNL,pins[i].pinname,baecvtl(pins[i].x), baecvtl(pins[i].y),pins[i].mirror,MAXNETNL,netname, pins[i].level,pins[i].level.LEVVAL,itemstr); pins[i].pintyp=pintyp; } // Sort pin list quicksort(pinidxl,pinn,pincmp); // Loop thru the sorted pin list for (i=0;i=0) { // Level found; increment pin count if (curpartf) levels[levidx].npincnt++; else levels[levidx].upincnt++; } // Get the pin net number pinnet=(-1); if (curpartf) if (lay_findconpartpin(refname,curpart,pin)==0) pinnet=pin.TREE; // Store new pin data pins[pinn].pinname=refname; pins[pinn].part=curpart; pins[pinn].partname=curpartname; pins[pinn].partf=curpartf; pins[pinn].level=level; pins[pinn].netnum=pinnet; // Get coordinates lay_maccoords(x,y,0.0,m,0); pins[pinn].x=x; pins[pinn].y=y; pins[pinn].mirror=m; pins[pinn].pintyp=(-1); pinidxl[pinn]=pinn; pinn++; // Abort scan return(0); } static int pincmp(int idx1,int idx2) /* // Pin compare function // Return value : // (-1) if idx1idx2 // Parameters : // int idx1 : First compare index // int idx2 : Second compare index */ { struct pindes cmppin1, cmppin2 /* Compare pins */; int cmpres /* Compare result */; // Compare pins cmppin1=pins[idx1]; cmppin2=pins[idx2]; if ((cmpres=(cmppin1.pintyp-cmppin2.pintyp))==0) { if (cmppin1.pintyp==0) { if ((cmpres=cmppin1.level-cmppin2.level)==0 && (cmpres=numstrcmp(cmppin1.netname,cmppin2.netname))==0 && (cmpres=numstrcmp(cmppin1.partname,cmppin2.partname))==0) cmpres=numstrcmp(cmppin1.pinname,cmppin2.pinname); } else { if ((cmpres=numstrcmp(cmppin1.partname,cmppin2.partname))==0 && (cmpres=numstrcmp(cmppin1.pinname,cmppin2.pinname))==0) cmpres=cmppin1.level.LEVVAL-cmppin2.level.LEVVAL; } } return(cmpres<0 ? (-1) : 1); } int findlevel(index L_LEVEL level) /* // Find some level entry in the level list // Parameters : // index L_LEVEL level : Level index */ { // Level translates 1:1 to its index return(level); } // User Language program end