/* ICD.ULH (ICD) -- User Language IC Design Utilities */ /* ICD.ULH (ICD) -- User Language IC Design-Utilities */ /* // Copyright (c) 1993-2013 Bartels System GmbH, Muenchen // Author: Roman Ludwig // Changes History: // rl (131029) RELEASED FOR BAE V8.0. // rl (120427) RELEASED FOR BAE V7.8. // rl (101019) RELEASED FOR BAE V7.6. // rl (091020) 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 (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 (020207) BUGFIX: // Fixed problem with alternate rule database file name // specified by environment variable BAE_RULELIB. // mb (010914) CHANGE: // Redundant functions removed. // rl (010803) ORIGINAL CODING. DERIVED FROM LAY.ULH. // // DESCRIPTION // // The definitions and declarations from the icd.ulh include file // are compatible with the IC Design Chip Editor interpreter // environment of the Bartels AutoEngineer. icd.ulh provides // utilities for analytical geometry, IC Design element copy, // layer name query, Chip Efitor workarea manipulation, etc. // icd.ulh also provides utilities for accessing and applying // the Bartels Rule System features in the BAE IC Design system. // // FUNCTIONS // // Analytic geometry: // icdangle -- Get the angle of a circle arc point // icddist -- Get the distance between two points // icdsegmentlen -- Get the length of a polygon segment // // IC Design database element access: // icdcopyelem -- Copy an IC layout element with all references // // IC Design layer name handling: // icdlayername -- Get layer name from layer number // // IC Design Rule System: // Rule System error handling: // rsi_error -- Issue Rule System error and end program on error // Rule name query: // rsi_database -- Get the Rule System database path name // rsi_getfigrules -- Get rules attached to specific figure list element // rsi_getplanrules -- Get rules attached to current plan // rsi_getpoolrules -- Get rules attached to specific pool element // rsi_getrules -- Get rules stored to Rule System database // rsi_isfigrule -- Check if specific rule is attached to figure element // rsi_isplanrule -- Check if specific rule is attached to current plan // rsi_ispoolrule -- Check if specific rule is attached to pool element // rsi_isrule -- Test if specific rule is defined/available // rsi_selectrule -- Select a rule from the Rule System database */ // Avoid multiple inclusion #ifndef INCLUDE_ICD #define INCLUDE_ICD // Includes #include "std.ulh" // User Language standard include // Layer number definitions #define LAYERINV (-0x4000) // Invalid layer code #define STDLAYMAX 100 // Maximum standard layer count // Rule system object class codes #define RSI_OCINV (-1) // Invalid/unknown object #define RSI_OCPLAN 0 // Plan/current element/object #define RSI_OCFIG 1 // Figure list element/object #define RSI_OCPOOL 2 // Pool list element/object // Connection part status bits #define CPART_PLC 0x01 // Connection part placed flag #define CPART_SEL 0x02 // Connection part selection flag // Rule system names #define RSI_ICDSUBJ "icd_rules" // Rule system PCB subject name #define RSI_GROUPNAME "grpname" // Rule system group name predicate //__________________________________________________________________ // Start library-specific source code #ifndef USELIB #ifndef LIBICD //__________________________________________________________________ // Analytic geometry double icdangle(double cx,double cy,double x,double y) /* // Get the angle of a circle arc point // Return value : // resulting angle value (in radians; 0..2*PI) // Parameters : // double cx : Circle center X coordinate // double cy : Circle center Y coordinate // double x : Circle arc point X coordinate // double y : Circle arc point Y coordinate */ { double res; // Result value // Get arc tangent of angle defined by circle point res=atan2(y-cy,x-cx); // Test the result if (res<0.0) // Get "absolute" angle value res+=2.0*cvtangle(180.0,1,2); // Return result value return(res); } double icdsegmentlen(int pc,int t,double x,double y, int t1,double x1,double y1,int t2, double x2,double y2,int sc) /* // Get the length of a polygon segment // Return value : // segment length in meter // Parameters : // int pc : Point counter // int t : Current point type // double x : Current point X coordinate // double y : Current point Y coordinate // int t1 : Previous point type // double x1 : Previous point X coordinate // double y1 : Previous point Y coordinate // int t2 : Pre-previous point type // double x2 : Pre-previous point X coordinate // double y2 : Pre-previous point Y coordinate // int sc : Segment count */ { double res; // Result value // Test if segment not yet completed if (pc<2) { // Move current to previous point x1=x; y1=y; t1=t; // Return zero length return(0.0); } // Increment segment count sc++; // Test if 2 point segment if (pc==2) { // Test on straight segment if (t==0) { // Get the straight segment length res=dist(x1,y1,x,y); // Move current to previous point x1=x; y1=y; t1=t; // Reset point counter pc=1; // Return result value return(res); } // Arc center assumed // Move previous to pre-previous point x2=x1; y2=y1; t2=t1; // Move current to previous point x1=x; y1=y; t1=t; // Return zero length return(0.0); } // Arc segment type assumed // Evaluate center (previous) point type if (t1==1) // Left arc; get arc length (current<-pre-previous) res=icdarclen(dist(x1,y1,x,y), icdangle(x1,y1,x2,y2),icdangle(x1,y1,x,y)); else if (t1==2) // Right arc; get arc length (pre-previous<-current) res=icdarclen(dist(x1,y1,x,y), icdangle(x1,y1,x,y),icdangle(x1,y1,x2,y2)); // Move current to previous point t1=t; x1=x; y1=y; // Reset point counter pc=1; // Return result value return(res); } static double icdarclen(double r,double a1,double a2) /* // Get arc segment length by radius and start-/end-point angle // Return value : // resulting arc segment length value // Parameters : // double r : Radius // double a1 : Start point angle (in radians) // double a2 : End point angle (in radians) */ { // Arc; "absolute" angle between start and end point double arc = a1<=a2 ? a2-a1 : 2.0*cvtangle(180.0,1,2)+a2-a1; // Get and return arc segment length return(arc*r); } //__________________________________________________________________ // IC Layout database element access int icdcopyelem(int class, string sfn,string dfn,string sen,string den,int mrgsrc) /* // Copy an IC layout element with all references // Return value : // zero if done, ( 1) if macro missing, (-1) on error // Parameters : // int class : Element DDB class // string sfn : Source file name // string dfn : Destination file name // string sen : Source element name // string den : Destination element name // int mrgsrc : Merge source flag */ { #define BAKEXT ".bak" // Backup file extension string bfn; // Backup file name index I_MACRO mac; // Macro index struct { // Macro descriptor string n; // Macro name int c; // Macro class } macs[]; // Macro list int macn = 0; // Macro count int macmissing = 0; // Macro missing flag // Check if UL system function can be used if (sen==den && sfn!=dfn) { // Copy element to backup file, ignore errors ddbcopyelem(dfn,bfn,class,sen,1); // Copy DDB element; return completion status return(ddbcopyelem(sfn,dfn,class,sen,mrgsrc)<0 ? (-1) : 0); } // Check the DDB plan class switch (class) { // Valid classes case DDBCLILAY : case DDBCLICELL : case DDBCLIPIN : break; // Invalid class default : return(-1); } // Test if copy must be done if (!mrgsrc && ddbcheck(dfn,class,den)==0 || dfn==sfn && den==sen) // Do not overcopy existing destination element return(0); // Copy (load & store) the element if (bae_loadelem(sfn,sen,class)==(-1) || bae_storeelem(dfn,den)) // Copy error return(-1); // Test if equal files if (sfn==dfn) // Copy done return(0); // Get all macros forall (mac) { // Check if source element exists if (ddbcheck(sfn,mac.CLASS,mac.NAME)) { // Macro missing; continue macmissing=1; continue; } // Test if macro exists if (mrgsrc || ddbcheck(dfn,mac.CLASS,mac.NAME)) { // Store the macro macs[macn].c=mac.CLASS; macs[macn].n=mac.NAME; macn++; } } // Copy all macros while ((macn--)>0) { // Copy (load & store) the element if (bae_loadelem(sfn,macs[macn].n,macs[macn].c)==(-1) || bae_storeelem(dfn,macs[macn].n)) // Copy error return(-1); } // Return macro missing flag return(macmissing); } //__________________________________________________________________ // Layout layer name handling string icdlayername(int layer) /* // Get layer name from layer number // Return value : // layer name string or empty string if invalid layer number // Parameters : // int layer : Layer number */ { // IC Design layer/display item strings string ITMLAYSTD = M("Standardlage " ,"Standard Layer " ); string ITMLAYALL = M("Alle Lagen" ,"All Layers" ); string ITMLAYBRD = M("Umrandung" ,"Board Outline" ); string ITMLAYUNR = M("Unroutes" ,"Airlines" ); string ITMDSPWA = M("Arbeitsbereich" ,"Workarea" ); string ITMDSPORG = M("Nullpunkt" ,"Origin" ); string ITMDSPERR = M("Fehler" ,"Error" ); string ITMDSPHL = M("Highlight" ,"Highlight" ); string ITMUNDEF = M("*** UNDEFINIERT ***","*** UNDEFINED ***"); // Test if signal layer if (layer>=0 && layer=0;i--) if (icd_getrulename(RSI_OCPLAN,0,i,rl[i])) rsi_error(0); // Return rule count return(rc); } int rsi_getfigrules(index I_FIGURE fig,STRINGS rl) /* // Get rules attached to specific figure list element // Return value : // rule count // Parameters : // index I_FIGURE fig : Figure list element index // STRINGS rl : Rule name list */ { int rc; // Rule count int i; // Loop control variable // Get rule count if ((rc=icd_getrulecnt(RSI_OCFIG,fig))<0) // Issue other than no rules found errors rsi_error(0); // Get and store rule names for (rl=IINITSTRL(),i=rc-1;i>=0;i--) if (icd_getrulename(RSI_OCFIG,fig,i,rl[i])) rsi_error(0); // Return rule count return(rc); } int rsi_getpoolrules(index I_POOL pool,STRINGS rl) /* // Get rules attached to specific pool element // Return value : // rule count // Parameters : // index I_POOL pool : Pool list element index // STRINGS rl : Rule name list */ { int rc; // Rule count int i; // Loop control variable // Get rule count if ((rc=icd_getrulecnt(RSI_OCPOOL,pool))<0) // Issue other than no rules found errors rsi_error(0); // Get and store rule names for (rl=IINITSTRL(),i=rc-1;i>=0;i--) if (icd_getrulename(RSI_OCPOOL,pool,i,rl[i])) rsi_error(0); // Return rule count return(rc); } int rsi_isplanrule(string rulename) /* // Check if specific rule is attached to current plan // Return value : // ( 0) if not defined/attached, // ( 1) if attached and defined/available, // (-1) if attached and undefined/unavailable // Parameters : // string rulename : Rule name */ { int rc; // Rule count string rn; // Rule name buffer int i; // Loop control variable // Get rule count if ((rc=icd_getrulecnt(RSI_OCPLAN,0))>0) { // Scan rule name list for (i=0;i0) { // Scan rule name list for (i=0;i0) { // Scan rule name list for (i=0;i