/* SCMPART (SCM) -- SCM Symbol/Label Functions */ /* SCMPART (SCM) -- SCM-Symbol-/Labelfunktionen */ /* -- INTENDED FOR KEY-CALL USE -- */ /* // Copyright (c) 1995-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 (091021) RELEASED FOR BAE V7.4. // rl (091007) ENHANCEMENT: // Added duplicate symbol report to name list cleanup. // rl (090728) ENHANCEMENT: // Added FPGA creation by CSV pin description file // rl (090212) ENHANCEMENT: // Added symbol and macro name upper case conversion options. // rl (081014) RELEASED FOR BAE V7.2. // rl (080402) ENHANCEMENT: // Added symbol $noplc/plot visibility consistency check function. // rl (071029) RELEASED FOR BAE V7.0. // rl (070914) ENHANCEMENT: // Sorted attribute list for part info display. // rl (070627) ENHANCEMENT: // Added orphant logical netlist scan to partlist cleanup. // rl (070109) ENHANCEMENT: // Added $rpname initial name transfer support to symbol copy. // rl (060929) RELEASED FOR BAE V6.8. // rl (060321) BUGFIX: // Fixed problem with label names in part list cleanup function. // rl (050906) RELEASED FOR BAE V6.6. // rl (050407) ENHANCEMENT: // Added FPGA symbol creation support. // rl (050308) BUGFIX: // Fixed tag reference loss problem at symbol rename. // rl (040824) RELEASED FOR BAE V6.4. // rl (040513) ENHANCEMENT: // Added attribute and type configuration through bae.ini. // rl (040331) ENHANCEMENT: // Added rule transfer to copy symbol function. // rl (030909) RELEASED FOR BAE V6.2. // rl (030909) BUGFIX: // Fixed problem with unset attributes in symbol copy. // rl (030603) ENHANCEMENT: // Added package to part list output. // rl (030417) ENHANCEMENT: // Added Copy Symbol function. // rl (021209) RELEASED FOR BAE V6.0. // rl (020822) ENHANCEMENT: // Added preservation of name/attribute move positions and // empty string attribute values in symbol rename function. // rl (020618) RELEASED FOR BAE V5.4. // rl (020528) ENHANCEMENT: // Disabled potentially hazardous name list cleanup on // pending backannotation requests. // rl (020510) BUGFIX: // Fixed problem with internal attribute setting on rename. // rl (020308) ENHANCEMENT: // Added attribute comment display in symbol query popup. // rl (010625) RELEASED FOR BAE V5.0. // rl (010525) ENHANCEMENT: // Added net name column to symbol query pin table. // rl (010328) ENHANCEMENT: // Added hierarchical symbol support functions. // rl (010214) ENHANCEMENT: // Added symbol attribute display to symbol query function. // rl (001229) ENHANCEMENT: // Enabled escape during new part name input. // rl (001006) BUGFIX: // Fixed part list cleanup bug. // rl (000525) RELEASED FOR BAE V4.6. // rl (990625) RELEASED FOR BAE V4.4. // rl (981014) RELEASED FOR BAE V4.2. // rl (981014) ENHANCEMENT: // Message system layout part placement introduced. // mb (981008) CHANGE: // Applied ddbdelelem function in partlistcleanup. // mb (980710) ENHANCEMENT: // Pulldown menu delimiters introduced. // mb (980710) ENHANCEMENT: // Dynamic multi-language support introduced. // rl (980304) ENHANCEMENT: // Part list cleanup function added. // rl (971001) ENHANCEMENT: // Symbol rename utility added. // rl (970929) RELEASED FOR BAE V4.0. // mb (961128) ENHANCEMENT: // New function "Change Part Symbol" for changing // symbol/part macros on SCM sheet level (with // attribute values copy). // mb (960919) RELEASED FOR BAE V3.4. // mb (951023) ORIGINAL CODING: // Functions provided: // o Mirror Symbols/Labels (on/off) to work on // sheet/symbol/label level // o Rotate Symbols/Labels (0,90,180,270 degrees) to work on // sheet/symbol/label level // o Rename Parts (with attribute values copy) // o Symbol/Label Query (provide placement/pin listing) // o Search Part (calls FINDSPRT UL program) // o SCM Part List displaying attribute-sorted part list // in popup menu with dump option // o SCM Cross Ref. (calls SCMCRREF UL program) // o Set Attributes (calls SSYMATTR UL program) // // DESCRIPTION // // The scmpart User Language program activates a menu with a // series of advanced symbol and label functions such as mirror // and/or rotate selectable symbols and/or labels, part renaming, // part symbol change, symbol/label query, part search, part list // generation, menu-driven attribute assignment, etc. // // WARNINGS // // The part symbol change function will not perform any compatibilty // check with respect to pin naming, pin coordinates, attribute // definitions, or logical library convenience! */ // Includes #include "popdraw.ulh" // User Language popup draw. util. #include "baeparam.ulh" // User Language BAE param. access #include "mnu.ulh" // User Language menu utilities #include "sql.ulh" // User Language SQL utilities #include "scm.ulh" // User Language SCM utilities // Disable undo state request #pragma ULCALLERNOUNDO // Messages string UPRABORT = M_UPRABORT(); string REPPART = M("SYMBOL ...........: '%s' ('%s')", "SYMBOL ...........: '%s' ('%s')"); string REPLABEL = M("LABEL ............: '%s'", "LABEL ............: '%s'"); string REPMACRO = M(" MACRO .........: '%s'", " MACRO .........: '%s'"); string REPCOORD = M(" X / Y .........: %.3f / %.3f %s", " X / Y .........: %.3f / .3f %s"); string REPANGLE = M(" WINKEL ........: %.2f", " ANGLE .........: %.2f"); string REPMIRROR = M(" MIRROR ........: %d"," MIRROR ........: %d"); string REPGROUP = M(" GRUPPE ........: %d"," GROUP .........: %d"); string REPGLUED = M(" VERANKERT .....: %d"," GLUED .........: %d"); string REPPINCNT = M(" ANZAHL PINS ...: %d"," PIN COUNT .....: %d"); string REPATTRVAR = M(" Var. %d"," Var. %d"); string REPPLCLEAN = M("%d SCM-Bauteilreferenz(en) geloescht.", "%d SCM part reference(s) deleted."); string REPORPHSYM = M("Altsymbol '%s' nicht mehr in den Eingabedaten vorhanden!", "Old symbol '%s' not contained in input file anymore!"); string REPORPHSYMP = M("Altsymbol '%s' Blatt '%s' nicht mehr in den Eingabedaten vorhanden!", "Old symbol '%s' sheet '%s' not contained in input file anymore!"); string REPREADASS = M("Lesen Assignmentdatei...", "Reading assignment file..."); string REPHD0 = M("Plotsichtbarkeitscheck","Plot Visibility Check"); string REPHD1 = M("Projektdatei .: '%s'","Project File .: '%s'"); string REPHD2 = M("Blatt ........: '%s'","Sheet ........: '%s'"); string REPDUPHD0 = M("Namensliste Cleanup","Name List Cleanup"); string REPSYMDUP = M("Symbolname '%s' auf Blaettern '%s' und '%s' verwendet!", "Symbol name '%s' used on sheet '%s' and '%s'!"); string REPSYMVIS = M("Symbol '%s' in Variante %d sichtbar trotz $noplc-Wert", "Symbol '%s' visible in variant %d dispite of $noplc value"); string REPSYMUVIS = M("Symbol '%s' in Variante %d unsichtbar aber ohne $noplc-Wert", "Symbol '%s' invisible in variant %d but no $noplc value"); string REPDONE = M("Es wurden keine Fehler festgestellt.", "Operation completed without errors."); string UPRFCT = M("Symbol-Funktion selektieren!", "Select Symbol Function!"); string UPRFCT1 = M("Symbole/Labels sp&iegeln","&Mirror Symbols/Labels"); string UPRFCT2 = M("Symbole/Labels &rotieren","&Rotate Symbols/Labels"); string UPRFCT3 = M("%Symbole &umbenennen","%R&ename Parts"); string UPRFCT4 = M("Symbole &nummerieren","Re&number Parts"); string UPRFCT5 = M("&Symbole aendern","Change Part &Symbol"); string UPRFCT6 = M("%Symbol/Label &Query","%Symbol/Label &Query"); string UPRFCT7 = M("&Bauteilsuche","Search &Part"); string UPRFCT8 = M("Na&mensliste Cleanup","P&art List Cleanup"); string UPRFCT9 = M("Symbol Br&owser","Symbol Br&owser"); string UPRFCT10 = M("%SCM-Stueck&liste","%SCM Part &List"); string UPRFCT11 = M("SCM &Cross Referenz","SCM &Cross Reference"); string UPRFCT12 = M("%Labels &pruefen","%C&heck Labels"); string UPRFCT13 = M("%A&ttribute setzen","%Set A&ttributes"); string UPRFCT14 = M("%Blockplan","%Bloc&k Sheet"); string UPRFCT15 = M("%Symbol &kopieren","%Copy Sym&bol"); string UPRFCT16 = M("%FPGA Symbol erzeugen","%Create FPGA Sym&bol"); string UPRFCT17 = M("%Layoutbauteil plat&zieren","%Place La&yout Part"); string UPRFCT18 = M("%Pruefen $noplc-Konsistenz","%Check $noplc Consitency"); string UPRMIRMODE = M("Spiegelungsmodus auswaehlen!", "Select Mirror Mode!"); string UPRMIROFF = M("Spiegeln &aus","Mirror &Off"); string UPRMIRON = M("&Spiegeln ein","&Mirror On"); string UPRROTMODE = M("Rotationsmodus auswaehlen!", "Select Rotation Angle!"); string UPRROT0 = M(" &0 Grad"," &0 Degrees"); string UPRROT1 = M(" &90 Grad links"," &90 Degrees left"); string UPRROT2 = M("1&80 Grad links","1&80 Degrees left"); string UPRROT3 = M("2&70 Grad links","2&70 Degrees left"); string UPRHIER = M("Block-Funktion selektieren!", "Select Block Function!"); string UPRHIER00 = M("Blockplan la&den","Loa&d Block Sheet"); string UPRHIER01 = M("Blocksymbol erstellen","Create Block &Symbol"); string UPRFPGAFCT = M("FPGA-Beschreibungsformat auswaehlen!", "Select FPGA Description Format!"); string UPRFPGA00 = M("&Netzliste","&Netlist"); string UPRFPGA01 = M("&CSV-Datei","&CSV File"); string UPRPRTREN = M("Bauteil/Symbol fuer Umbenennung selektieren!", "Select Part/Symbol to be renamed!"); string UPRPRTNNAM = M("%Neuer Name fuer Symbol '%s' (:'%s') ? ", "%New Name for Symbol '%s' (:'%s') ? "); string UPRPRTMNAM = M("Neuer Makroname fuer Symbol '%s' ? ", "New Macro Name for Symbol '%s' ? "); string UPRSYMCHG = M("Bauteil fuer Symboltausch selektieren!", "Select Part for Symbol change!"); string UPRSYMMAC = M("Bibliotheksteilname ('%s') ? ", "Library Element Name ('%s') ? "); string UPRSYMBASE = M("Symbolmakros Basisname ('%s') ? ", "Symbol Macros Base Name ('%s') ? "); string UPRSYMCOPY = M("Symbol fuer Kopie selektieren!", "Select Symbol to Copy!"); string UPRSELSYMB = M("Symbol selektieren!","Select Symbol!"); string UPRSELPART = M("Symbol/Label selektieren!", "Select Symbol/Label!"); string UPRSELDDB = M("SCM-Jobdatei ? ","SCM Job File ? "); string UPRBLKNAME = M("Blocksymbolname ('%s') ? ", "Block Symbol Name ('%s') ? "); string UPRECONT = M("Fehler bei der Kompilierung!", "Error compiling definition!"); string UPRWCONT = M("Warnung(en) bei der Kompilierung!", "Warning(s) compiling definition!"); string UPREDIT = M("!Neue Loglib-Definition", "!New Loglib Definition"); string UPRASSFILE = M("Assignment Datei ? ","Assignment File ? "); string UPRSYMFILE = M("Symboldefinitionsdatei ? ", "Symbol Definition File ? "); string UPRSYMDEL = M("Bestehende Symbole ueberschreiben (J/N)? ", "Overwrite existing symbols (Y/N) ? "); string UPRDFILE = M("!Zieldateiname ? ","!Destination File Name ? "); string UPRLCONDEL = M("Logische Netzliste '%s' ohne zugehoerigen Schaltplan loeschen?", "Logical netlist '%s' has no corresponding schematic sheet. Delete?"); string UPRVDDCONF = M("Variantenabhaengige Attribute und/oder Plotsichtbarkeiten gefunden. Uebernehmen?", "Found variant dependant attributes/plot visibilities. Copy ?"); string REPSYMTAG = M("Symbol Tag","Symbol Tag"); string REPPINTAG = M("Pin Tag","Pin Tag"); string REPNETTAG = M("Netz Tag","Net Tag"); string REPNPNTAG = M("Netzpin Tag","Net Pin Tag"); string REPNARTAG = M("Netzbereich Tag","Net Area Tag"); string REPPARTAG = M("Bauteilbereich Tag","Part Area Tag"); string REPUNKNOWN = M("Unbekanntes Tag","Unknown Tag"); string ERRMIRROR = M("Symbol konnte nicht gespiegelt werden!", "Error mirroring symbol!"); string ERRROTATE = M("Symbol konnte nicht gedreht werden!", "Error rotating symbol!"); string ERRDELSYM = M("Fehler beim Loeschen von Bauteil/Symbol '%s'!", "Error deleting part/symbol '%s'!"); string ERRPLCSYM = M("Fehler beim Platzieren von Bauteil/Symbol '%s'!", "Error placing part/symbol '%s'!"); string ERRPLCPIN = M("Fehler bei der Pinplatzierung '%s'/'%s' auf Symbol '%s'!", "Error placing pin '%s'/'%s' symbol '%s'!"); string ERRSYMGLUED = M("Symbol '%s' ist verankert!", "Symbol '%s' is glued!"); string ERRSETATT = M("Fehler bei Attributzuweisung an Bauteil/Symbol '%s'!", "Error setting attribute on part/symbol '%s'!"); string ERRSETTAG = M("Fehler bei Tagumleitung auf Bauteil/Symbol '%s'!", "Error redirection tag to part/symbol '%s'!"); string ERRNOLOGDEF = M("Keine logische Definition zu '%s' gefunden!", "No logical definition for '%s' found!"); string ERRNOBLKSYM = M("Symbol '%s' ist kein Blocksymbol!", "Symbol '%s' is no block symbol!"); string ERRNOHIERBLK = M("Aktueller Plan ist kein Blockplan!", "Current sheet isn't a block sheet!"); string ERRNOBLKNAME = M("Der Blockname ist noch nicht definiert!", "No block name defined yet!"); string ERRNOBLKPLAN = M("Kein Plan zu Block '%s' gefunden!", "No sheet matching block '%s' found!"); string ERRBSYMDUP = M("Blocksymbol '%s' bereits vorhanden!", "Block symbol '%s' already exists!"); string ERRSMACDUP = M("Symbolmakro '%s' bereits vorhanden!", "Symbol macro '%s' already exists!"); string ERRBACKANNOP = M("Backannotation noch nicht durchgefuehrt!", "Pending Backannotation!"); string ERRNOPICK = M_ERRNOPICK(); // INI file parameter name definitions #define PAR_ATTRCOMMP "ATTR_%s_STD" // Attribute comment pattern #define PAR_ATTRORDP "ATTR_ORD_%s_STD" // Attribute order pattern #define PAR_PLATTRL "PLATTRL_SCM" // Part list attribute list #define PAR_PLTYPL "PLTYPL_SCM" // Part list type list #define PAR_PLLINEPN "PLLINEPN_SCM" // Part list parts per line count #define PAR_PLNUPPER "PLPNUPPER_SCM" // Part name upper case conversion flag #define PAR_PLMUPPER "PLPMUPPER_SCM" // Part macro upper case conv. flag #define PAR_MAXEDIT "LLMAXLEN_SCM" // Max. logical library edit length #define PAR_PINMAC "BLKSPINM_SCM" // Block symbol pin macro #define PAR_PINSPC "BLKSPINSPC_SCM"// Block symbol pin spacing #define PAR_PINDIST "BLKSPINDST_SCM"// Block symbol pin distance #define PAR_TEXTSIZE "BLKSPINTS_SCM" // Block symbol pin text size #define PAR_PINTOFF "BLKSPINTO_SCM" // Block symbol pin text offset #define PAR_NAMESIZE "BLKSSYMNS_SCM" // Block symbol name text size #define PAR_TEXTSPC "BLKSTXTSPC_SCM"// Block symbol text spacing #define PAR_TEXTTOFF "BLKSTXTTOFF_SCM"// Block symbol top text offset #define PAR_TEXTBOFF "BLKSTXTBOFF_SCM"// Block symbol bottom text offset #define PAR_CENTWIDTH "BLKSCENTW_SCM" // Block symbol center box width #define PAR_CENTHEIGHT "BLKSCENTH_SCM" // Block symbol center box height #define PAR_PORTANG "MODPORTORI_SCM"// Module port orientation #define PAR_ASSFEXT "ASSFEXT_SCM" // Assignment file name extension #define PAR_NAMEPROMPT "NAMEPROMPT_SCM"// Name prompt mode #define PAR_RPNAMEAUPD "RPNAMEAUPD_SCM"// $rpname attr. transfer mode #define PAR_VARATTRCHK "VARATTRCHK_SCM"// Variant attribute check flag #define PAR_SYMDEFTSEP "SYMDEFSEP_SCM" // Symbol def. table field separator #define PAR_TABFEXT "SYMDEFFEXT_SCM"// Symbol def. file name extension #define PAR_TABHEAD "SYMDEFHN_SCM" // Symbol def. file header lines #define PAR_SYMDEFTSEP "SYMDEFSEP_SCM" // Symbol def. table field separator #define PAR_SYMNCOL "SYMDEFSNC_SCM" // Symbol name field #define PAR_SYMSPNCOL "SYMDEFSPNC_SCM"// Symbol schematic pin name field #define PAR_SYMSPNMODE "SYMDEFSPNM_SCM"// Symbol schematic pin name mode #define PAR_SYMLPNCOL "SYMDEFLPNC_SCM"// Symbol layout pin name field #define PAR_SYMPTCOL "SYMDEFPTC_SCM" // Symbol pin type field #define PAR_SYMPPCOL "SYMDEFPPC_SCM" // Symbol pin position field #define PAR_PLNAMECOL "SYMDEFPLN_SCM" // Symbol part library name field #define PAR_SYMLEFTL "SYMDEFLTYP_SCM"// Symbol left side type list #define PAR_SYMRIGHTL "SYMDEFRTYP_SCM"// Symbol right side type list #define PAR_SYMCOMM "SYMDEFCOMM_SCM"// Symbol comment field list #define PAR_SYMPARTAL "SYMDEFPAL_SCM" // Symbol part attribute list #define PAR_SYMPINAL "SYMDEFPIAL_SCM"// Symbol pin attribute list #define PAR_SYMTOPTXT "SYMDEFTTXT_SCM"// Symbol top text list #define PAR_SYMBOTTXT "SYMDEFBTXT_SCM"// Symbol bottom text list #define PAR_SYMDEFMPM "SYMDEFMPM_SCM" // Symbol multiple pin mode #define PAR_SYMDEFNPAT "SYMDEFNPAT_SCM"// Symbol name pattern #define PAR_CHECKPVIS "NOPLCCHK_SCM" // SCM part $noplc consistency check // Query format strings #define FMTGENERIC "%s\t%s\t%8.3f %8.3f %7.3f %d\n" #define FMTPTABH1 "%-*s %8s %8s ROTATION MIRROR %-*s %s" #define FMTPTABH2 "%.*s ======== ======== ======== ====== %.*s %.*s" #define FMTPTABF "%-*s %8.3f %8.3f %8.3f %6d %-*s %s" #define FMTATTENT " %s %.*s: '%s'" #define FMTTAGENT " %s %s %.*s: %s %s" #define FMTTTABH1 "%-*s %-*s %-*s %-*s" #define FMTTTABH2 "%.*s %.*s %.*s %.*s" #define FMTTTABF "%-*s %-*s %-*s %-*s" #define ITMPINNAMHD "PIN NAME" #define ITMTPINNAMHD "TAG PIN" #define ITMNETNAMHD "NET(S)" #define ITMATRNAMHD "ATTRIBUTE(S)" #define ITMBUSPREFIX "BUS : " #define ITMULINE "=======================================" #define ITMUDOT "......................................." int ATTFLEN = strlen(REPANGLE)-10 /* Attribute field length */; string ASSEXT = bae_inistrval(PAR_ASSFEXT,".txt") /* Assigment file name extension */; STRINGS assext = { // Assignment file name ext. list ASSEXT // Assignment extension }; string TABEXT = bae_inistrval(PAR_TABFEXT,".csv") /* Symbol def. file name extension */; STRINGS tabext = { // Symbol def. file name ext. list TABEXT // Symbol def. extension }; string FIELDSEP = bae_inistrval(PAR_SYMDEFTSEP,";") /* Symbol definition table seperator */; int SKIPLINES = bae_iniintval(PAR_TABHEAD,1) /* Symbol table header line count */; int SYMNAMECOL = bae_iniintval(PAR_SYMNCOL,1)-1 /* Symbol name column */; int SYMSPINCOL = bae_iniintval(PAR_SYMSPNCOL,2)-1 /* Symbol schematic pin name column */; int SYMSPINMODE = bae_iniintval(PAR_SYMSPNMODE,0) /* Symbol schematic pin name mode */; int SYMLPINCOL = bae_iniintval(PAR_SYMLPNCOL,3)-1 /* Symbol layout pin name column */; int SYMPINTCOL = bae_iniintval(PAR_SYMPTCOL,4)-1 /* Symbol pin type column */; int SYMPINPCOL = bae_iniintval(PAR_SYMPPCOL,0)-1 /* Symbol pin position column */; int PLNAMECOL = bae_iniintval(PAR_PLNAMECOL,0)-1 /* Part library name column */; int CHECKPVIS = bae_iniintval(PAR_CHECKPVIS,0) /* SCM part $noplc consistency check */; struct pintypdes { /* Symbol pin type descriptor */ string pattern /* Pin type pattern */; string marker /* Pin marker macro */; string edrctyp /* Pin EDRC type */; }; struct pintypdes deflefttypl[] = { /* Def. left side pin type name list */ { "l", "terminal", "" }, { "left", "terminal", "" }, { "*in*", "terminal", "in" } }; struct pintypdes lefttypl[] /* Left symbol side type name list */; int lefttypn /* Left symbol side type name count */; struct pintypdes defrighttypl[] = { /* Def. right side pin type name list */ { "r", "terminal", "" }, { "right", "terminal", "" }, { "*out*", "terminal", "out" } }; struct pintypdes righttypl[] /* Right symbol side type name list */; int righttypn /* Right symbol side type name count */; int defsymcomml[] = { 1, 6 } /* Default symbol comm. column list */; int symcomml[] /* Symbol comm. column list */; int symcommn /* Symbol comm. column count */; struct attrdes { /* Symbol attribute descriptor */ string name /* Attribute name */; int fidx /* Table field index */; }; struct attrdes partattrl[] /* Part attribute list */; int partattrn /* Part attribute count */; struct attrdes pinattrl[] /* Pin attribute list */; int pinattrn /* Pin attribute count */; struct stxtdes { /* Symbol text descriptor */ int mode /* Text mode */; int align /* Text alignment */; int typ /* Text type */; string str /* Text string name */; int fidx /* Table field index */; }; struct stxtdes deftoptxtl[] = { /* Def. symbol top text list */ { 0, 1, 0, "$", 0 } }; struct stxtdes toptxtl[] /* Symbol top text list */; int toptxtn /* Symbol top text count */; struct stxtdes defbottxtl[] = { /* Def. symbol bottom text list */ { 0, 1, 0, "$LLNAME", 0 } }; struct stxtdes bottxtl[] /* Symbol bottom text list */; int bottxtn /* Symbol bottom text count */; // Part list format strings string FMTHEAD0 = M("SCM-STUECKLISTE" ,"SCM PART TYPE LIST"); string FMTHEAD1 = M("PROJEKT .....: %s" ,"PROJECT .....: %s"); string FMTHEAD2 = M("SCM-BLATT ...: %s %s" ,"SCM SHEET ...: %s %s"); string FMTELEM = M("%4d Funktion ....: %s","%4d Function ....: %s"); #define FMTATTR " %s %s" #define FMTNL "\n" #define FMTTAB " " #define FMTLSTSEP "," // Global User Language program variables #define UL_FINDSPRT "findsprt" // ULP: Find SCM Part #define UL_SAUTONAM "sautonam" // ULP: Symbol Auto Rename #define UL_SBROWSE "sbrowse" // ULP: Symbol Browse #define UL_SCMCRREF "scmcrref" // ULP: SCM Cross Reference #define UL_SSYMATTR "ssymattr" // ULP: Set Symbol Attributes #define UL_SLABCHK "slabchk" // ULP: Label Check // SQL command definitions #define V_SELECT "select variant,name from varinfo;" // Globals double PI = cvtangle(180,1,2) /* PI value */; double DPI = cvtangle(360.0,1,2) /* Double PI value */; #define GV_SAVECALL "save_call" // Save call flag variable name #define BUSEXT 0.001 // Bus display extension #define UNITM "[mm]" // Units designator mm #define UNITI "[\"]" // Units designator inch string UNIT /* Units designator string */; int MAXPINNAMLEN /* Maximum pin name length */; int MAXNETNAMLEN /* Maximum net name length */; int MAXATRNAMLEN /* Maximum attribute name length */; struct { // Pin descriptor string pinname /* Pin name */; double x,y /* Pin coordinates */; double rotang /* Pin rotation angle */; int mirror /* Pin mirror mode */; string netname /* Pin name */; string attrlist /* Pin attribute list */; } pinl[] /* Pin list */; int pinn /* Pin count */; string curname /* Current scan part name */; string inirpname /* $rpname initial value */; int symtyp = 0 /* Sym. type (0 std, 1 main, 2 sub) */; int gatecnt = 0 /* Current gate count */; STRINGS headl /* Menu header string list */; int headn /* Menu header string count */; STRINGS entryl /* Menu entry string list */; int entryn = 0 /* Menu entry string count */; int MAXEDIT = bae_iniintval(PAR_MAXEDIT,60000); // Max. logical library edit length string PINMAC = bae_inistrval(PAR_PINMAC,"terminal") /* Block symbol pin macro name */; double PINSPC = bae_inidblval(PAR_PINSPC,0.004) /* Block symbol pin spacing */; double PINDIST = bae_inidblval(PAR_PINDIST,0.004) /* Block symbol pin distance */; double PINTOFF = bae_inidblval(PAR_PINTOFF,0.001) /* Block symbol pin text offset */; double TEXTSIZE = bae_inidblval(PAR_TEXTSIZE,0.003) /* Block symbol name text size */; double NAMESIZE = bae_inidblval(PAR_NAMESIZE,0.003) /* Block symbol name text size */; double TEXTSPC = bae_inidblval(PAR_TEXTSPC,0.001) /* Block symbol text line spacing */; double TEXTTOFF = bae_inidblval(PAR_TEXTTOFF,0.0) /* Block symbol top text line offset */; double TEXTBOFF = bae_inidblval(PAR_TEXTBOFF,0.0) /* Block symbol bottom text line off.*/; double CENTWIDTH = bae_inidblval(PAR_CENTWIDTH,0.008) /* Block symbol center box width */; double CENTHEIGHT = bae_inidblval(PAR_CENTHEIGHT,0.004) /* Block symbol center box height */; string NAMEPAT = bae_inistrval(PAR_SYMDEFNPAT,"") /* Symbol def. name pattern */; int MULTIPINM = bae_iniintval(PAR_SYMDEFMPM,0) /* Multiple pin name mode */; double PORTANG = bae_inidblval(PAR_PORTANG,0.0) /* Module port orientation */; int RPNAMEAUPD = bae_iniintval(PAR_RPNAMEAUPD,0) /* $rpname attr. transfer mode */; int VARATTRCHK = bae_iniintval(PAR_VARATTRCHK,1) /* Variant attribute check flag */; int busflag /* Current bus flag */; STRINGS varnames /* Variant names */; int curvar /* Current variant index */; int noplcflag /* $noplc text flag */; int varn = 0 /* Variant count */; // SCM part list definitions and declarations int LINEPARTS = bae_iniintval(PAR_PLLINEPN,10); // Parts per line int PARTNAMEUPPER = bae_iniintval(PAR_PLNUPPER,0); // Part name upper case conversion flag int PARTMACROUPPER = bae_iniintval(PAR_PLMUPPER,0); // Part macro upper case conv. flag struct attrdesc { // Attribute descriptor string attrname /* Attribute name */; int patternflag /* Pattern attribute flag */; int outmode /* Attribute output mode : 0 = no output 1 = output as is 2 = output uppercase 3 = output lowercase */; string attrdoc /* Attribute output docum. string */; }; // Part name is used for pattern match if no pattern attribute is defined struct attrdesc defattrl[] = { // Default attribute list /* { "$" , 0, 1, M("Bauteil .....:","Part ........:") }, */ { "$ulname" , 0, 1, M("Gehaeuse ....:","Package .....:") }, { "$type" , 0, 1, M("Typ .........:","Type ........:") }, { "$val" , 0, 1, M("Wert ........:","Value .......:") }, { "$pow" , 0, 1, M("Leistung ....:","Power .......:") }, { "$tol" , 0, 1, M("Toleranz ....:","Tolerance ...:") }, { "$comment", 0, 1, M("Bemerkung ...:","Comment .....:") } }; struct attrdesc attrl[] /* Attribute list */; int attrn /* Attribute list element count */; struct outdes { // Output field descriptor string outpattern /* Part name pattern */; string outname /* Part class name */; }; struct outdes defoutl[] = { // Def. output list (last char '*' !) { "c*" , M("Kondensatoren:","Capacitors:" ) }, { "d*" , M("Dioden:" ,"Diodes:" ) }, { "led*", M("Leuchtdioden:" ,"LED's:" ) }, { "r*" , M("Widerstaende:" ,"Resistors:" ) }, { "l*" , M("Spulen:" ,"Inductors:" ) }, { "tr*" , M("Transistoren:" ,"Transistors:") }, { "ic*" , M("ICs:" ,"IC's:" ) }, { "x*" , M("Stecker:" ,"Connectors:" ) }, { "st*" , M("Stecker:" ,"Connectors:" ) }, { "*" , M("Sonstige:" ,"Others:" ) } }; struct outdes outl[] /* Output list (last char '*'!) */; int outn /* Output list element count */; struct elemdes { // Element descriptor int elcnt /* Element count */; index C_NREF partl[] /* Element part list */; STRINGS elvall /* Element attribute value list */; string elmacname /* Element macro name */; int outflag /* Element output flag */; } eleml[] /* Element list */; int elemn = 0 /* Element list count */; STRINGS msgl /* Message list */; int msgn = 0 /* Message count */; int ddbclass = bae_planddbclass() /* SCM plan DDB class */; // Main program void main() { string h_dis = (bae_swconfig(0)==BAE_HighEnd && ddbclass==DDBCLSCM) ? "" : "," /* HighEnd functions disable */; string p_dis = ddbclass==DDBCLSCM ? "" : "," /* Plan functions disable */; // Select symbol/label function bae_defmenusel(-1); bae_promptdialog(UPRFCT); switch (bae_askmenu(19,UPRFCT1,UPRFCT2,UPRFCT3,UPRFCT4,UPRFCT5, UPRFCT6,UPRFCT7,UPRFCT8,UPRFCT9,UPRFCT10,UPRFCT11,UPRFCT12, UPRFCT13,UPRFCT14,UPRFCT15,UPRFCT16,h_dis+UPRFCT17,p_dis+UPRFCT18, UPRABORT)) { // Mirror symbols/labels case 0 : symmirror(); break; // Rotate symbols/labels case 1 : symrotate(); break; // Rename parts case 2 : symrename(); break; // Renumber parts case 3 : runulprogexit(UL_SAUTONAM); // Change part symbols case 4 : symchange(); break; // Symbol/label query case 5 : symbolquery(); break; // Search part case 6 : runulprogexit(UL_FINDSPRT); // Part list cleanup case 7 : partlistcleanup(); break; // Symbol browse case 8 : runulprogexit(UL_SBROWSE); // SCM part list display/output case 9 : scmpartlist(); break; // SCM cross reference case 10 : runulprogexit(UL_SCMCRREF); // Check labels case 11 : runulprogexit(UL_SLABCHK); // Set symbol attributes case 12 : runulprogexit(UL_SSYMATTR); // Load block sheet case 13 : // Abort if invalid plan class if (ddbclass!=DDBCLSCM) error_class(); bae_promptdialog(UPRHIER); switch (bae_askmenu(3,UPRHIER00,UPRHIER01,UPRABORT)) { // Load block sheet case 0 : scmloadblock(); break; // Create block symbol case 1 : blocksymbol(); break; } break; // Symbol copy case 14 : symbolcopy(); break; // FPGA symbol create case 15 : bae_promptdialog(UPRFPGAFCT); switch (bae_askmenu(3,UPRFPGA00,UPRFPGA01,UPRABORT)) { // Load FPGA netlist case 0 : fpganetlistread(); break; // Load FPGA CSV description case 1 : fpgadefread(); break; } break; // Place layout part for selected symbol case 16 : if (h_dis!="") break; laypartplc(); break; // $noplc consistency check case 17 : if (p_dis!="") break; noplccheck(); break; // Abort on default default : } } /*________________________________________________________________*/ // Symbol/label placement routines void symmirror() /* // Mirror mouse-selectable symbols/labels */ { index C_FIGURE fig /* Figure index */; int mirmode /* Mirror mode */; int cnt = 0 /* Element count */; // Abort if invalid plan class if (ddbclass!=DDBCLSCM && ddbclass!=DDBCLSSYM && ddbclass!=DDBCLSLAB) error_class(); // Check if call inside function check_fctactive(); varcheck(); // Ask user for mirror mode bae_defmenusel(-1); bae_promptdialog(UPRMIRMODE); if ((mirmode=bae_askmenu(3,UPRMIROFF,UPRMIRON,UPRABORT))<0 || mirmode>1) error_abort(); // Repetitively pick named references bae_prtdialog(UPRSELPART); while (scm_pickelem(fig,C_FIGNREF)==0) { if (fig.FIXED&2) errormsg(ERRSYMGLUED,fig.NAME); // Save current state for undo if (cnt==0) bae_callmenu(MNU_BAESAVESTATE); // Mirror the picked element if (scm_elemmirrchg(fig,mirmode)) error(ERRMIRROR); cnt++; } // No pick if (cnt) bae_prtdialog(ERRNOPICK); else perror(ERRNOPICK); } void symrotate() /* // Rotate mouse-selectable symbols/labels */ { index C_FIGURE fig /* Figure index */; double rotangle /* Rotation angle */; int cnt = 0 /* Element count */; // Abort if invalid plan class if (ddbclass!=DDBCLSCM && ddbclass!=DDBCLSSYM && ddbclass!=DDBCLSLAB) error_class(); // Check if call inside function check_fctactive(); varcheck(); // Ask user for mirror mode bae_defmenusel(-1); bae_promptdialog(UPRROTMODE); switch (bae_askmenu(5,UPRROT0,UPRROT1,UPRROT2,UPRROT3,UPRABORT)) { // 0 degree case 0 : rotangle=cvtangle( 0.0,1,0); break; // 90 degree left case 1 : rotangle=cvtangle( 90.0,1,0); break; // 180 degree left case 2 : rotangle=cvtangle(180.0,1,0); break; // 270 degree left case 3 : rotangle=cvtangle(270.0,1,0); break; // Abort on default default : error_abort(); } // Repetitively pick named references bae_prtdialog(UPRSELPART); while (scm_pickelem(fig,C_FIGNREF)==0) { if (fig.FIXED&2) errormsg(ERRSYMGLUED,fig.NAME); // Save current state for undo if (cnt==0) bae_callmenu(MNU_BAESAVESTATE); // Rotate the picked element if (scm_elemangchg(fig,rotangle)) error(ERRROTATE); cnt++; } // No pick if (cnt) bae_prtdialog(ERRNOPICK); else perror(ERRNOPICK); } /*________________________________________________________________*/ // Symbol/part naming routines void symrename() /* // Rename selectable SCM parts/symbols on current SCM plan */ { index C_FIGURE fig /* Figure list index */; index C_FIGURE nfig /* New figure list index */; index C_FIGURE tfig /* Tag figure list index */; index C_NREF nref /* Named reference index */; index C_ATTRIBUTE att /* Attribute index */; index C_REFTEXT rmod /* Ref. text modifier index */; index C_MACRO macro /* Macro index */; string oldname /* Old part name */; string newname /* New part name */; double x,y /* Part coordinates */; double ang /* Part rotation angle */; int mirr /* Part mirror flag */; double tang /* Text angle */; double btx, bty /* Back transf. text coords. */; double ttx, tty /* Temporary text coords. */; double asin, acos /* Angle sin, cos values */; int tmirr /* Text mirror mode */; STRINGS rl /* Rule list */; int attidx /* Attribute index */; int lastidx /* Last attribute index */; int attrerr = 0 /* Part attribute error count */; int tagerr = 0 /* Tag redirect error count */; struct tagref { // Tag reference descriptor index C_FIGURE fig /* Tag figure list element */; string pinname /* Tag pin name */; string ref1 /* Tag 1st reference name */; string ref2 /* Tag 2nd reference name */; } tagrl[],tagdl[] /* Tag reference/destination list */; int tagrn /* Tag reference count */; int tagdn /* Tag destination count */; string tpinname /* Tag pin name */; string tref1 /* Tag 1st reference name */; string tref2 /* Tag 2nd reference name */; int tpmode /* Tag pin mode */; int tpidx /* Tag pin index */; int cflag = 0 /* Change flag */; int i /* Loop control variable */; // Abort if invalid plan class if (ddbclass!=DDBCLSCM) error_class(); // Check if call inside function check_fctactive(); varcheck(); // Repetively pick part while (bae_promptdialog(UPRPRTREN),scm_pickelem(fig,C_FIGSREF)==0) { if (fig.FIXED&2) errormsg(ERRSYMGLUED,fig.NAME); // Get named reference nref=fig.NREF; // Save the part placement data x=fig.X; y=fig.Y; ang=fig.ANGLE; mirr=fig.MIRROR; macro=nref.MACRO; oldname=nref.NAME; asin=sin(mirr ? -ang : ang); acos=cos(mirr ? -ang : ang); // Get the new part name if ((newname=asknewpartname( oldname,nref.MACRO.PNAMEPAT))==UINPOPABORT) error_abort(); // Scan tag references to this part tagrn=0; forall (tfig where tfig.TYP==C_FIGNREF && tfig.NREF.MACRO.TAGSYM!=0) { // Scan tag pins tpidx=0; while (cap_gettagdata( tfig,tpidx,tpmode,tpinname,tref1,tref2)==0) { // Check if reference to renamed symbol if (tref1==oldname && (tpmode==1 || tpmode==2)) { // Store tag data tagrl[tagrn].fig=tfig; tagrl[tagrn].pinname=tpinname; tagrl[tagrn].ref2=tref2; tagrn++; } tpidx++; } } // Scan own tag pins tagdn=0; while (cap_gettagdata( fig,tagdn,tpmode,tpinname,tref1,tref2)==0) { // Store tag data tagdl[tagdn].fig=tfig; tagdl[tagdn].pinname=tpinname; tagdl[tagdn].ref1=tref1; tagdl[tagdn].ref2=tref2; tagdn++; } // Save current state for undo if (cflag==0) { bae_callmenu(MNU_BAESAVESTATE); cflag=1; } // Store new part if (scm_storepart(newname,macro.NAME,x,y,ang,mirr)) errormsg(ERRPLCSYM,newname); attidx=lastidx=0; forall (att of nref where scm_chkattrname(att.NAME)==0) lastidx++; // Copy the part attributes forall (att of nref where scm_chkattrname(att.NAME)==0) { attidx++; if (scm_setpartattrib(newname,att.NAME,att.VALUE, 4|(attidx==1 ? 1 : 0)|(attidx==lastidx ? 2 : 0))) attrerr++; } // Transfer rules if (fig.RULEOBJID>=0 && cap_nrefsearch(newname,nfig)==0) // Get rules if (rsc_getfigrules(fig,rl)>0) // Attach rules if (cap_rulefigatt(nfig,rl)) rsc_error(-1); // Transfer name moves forall (rmod of nref) if (cap_nrefsearch(newname,nfig)==0) { // Transform rel. to abs. position ttx=rmod.X-macro.MNX; tty=rmod.Y-macro.MNY; tang=rmod.ANGLE; tmirr= mirr!=rmod.MIRROR ? 1 : 0 ; if (tmirr) tang-=ang; else tang+=ang; if (mirr) tty=(-tty); asin=sin(ang); acos=cos(ang); btx=acos*ttx-asin*tty; bty=asin*ttx+acos*tty; while (tang<0.0) tang+=DPI; while (tang>=DPI) tang-=DPI; // Store the text position scm_attachtextpos(nfig,rmod.STR, x+btx,y+bty,tang,rmod.SIZE,tmirr); } // Redirect tag references from this symbol for (tpidx=0;tpidxMAXKEYLEN) continue; // Test if part name already in use if (ddbcheck(bae_planfname(),DDBCLSPLST,newname)==0) { // Test if part placed if ((planname= cap_partplan(bae_planfname(),newname))!="") { // Continue if part placed on other plan if (planname!=bae_planename()) continue; // Continue if part placed on current plan if (cap_nrefsearch(newname,fig)==0) continue; } } // Check part name for (ok=1,i=0;ok && (c=newname[i])!='\0';i++) // Reset ok flag if invalid part name character if (isspace(c) || iscntrl(c)) ok=0; // Loop until valid new part name specified } while (!ok); // Return the new part name return(newname); } /*________________________________________________________________*/ // Part symbol management routines void symchange() /* // Change symbols of selectable SCM parts on current SCM plan */ { index C_FIGURE fig /* Figure list index */; index C_FIGURE nfig /* New figure list index */; index C_NREF nref /* Named reference index */; index C_ATTRIBUTE att /* Attribute index */; string pname /* Part name */; string newmac /* New part macro name */; double x,y /* Part coordinates */; double rotang /* Part rotation angle */; int mirror /* Part mirror flag */; struct { // Attribute descriptor string anam /* Attribute name */; string aval /* Attribute value */; } attl[] /* Part attribute list */; int attn = 0 /* Part attribute count */; int robjid /* Part rule object id */; STRINGS rl /* Rule list */; int cflag = 0 /* Change flag */; int i /* Loop control variable */; // Abort if invalid plan class if (ddbclass!=DDBCLSCM) error_class(); // Check if call inside function check_fctactive(); varcheck(); // Repetively pick part while (bae_promptdialog(UPRSYMCHG),scm_pickelem(fig,C_FIGNREF)==0) { if (fig.FIXED&2) errormsg(ERRSYMGLUED,fig.NAME); // Save the part placement data nref=fig.NREF; pname=nref.NAME; x=fig.X; y=fig.Y; rotang=fig.ANGLE; mirror=fig.MIRROR; if ((robjid=fig.RULEOBJID)>=0) // Get rules if (rsc_getfigrules(fig,rl)<=0) robjid=(-1); // Save the part attribute list attn=0; forall (att of nref where scm_chkattrname(att.NAME)==0) { attl[attn].anam=att.NAME; attl[attn].aval=att.VALUE; attn++; } // Select new part symbol macro if ((newmac=askpartsymbol(nref.MACRO.NAME))=="") break; // Macro change done if no new macro selected if (newmac==nref.MACRO.NAME) continue; // Save current state for undo if (cflag==0) { bae_callmenu(MNU_BAESAVESTATE); cflag=1; } // Change the picked part symbol if (scm_delelem(fig)) errormsg(ERRDELSYM,pname); if (scm_storepart(pname,newmac,x,y,rotang,mirror)) errormsg(ERRPLCSYM,pname); // Restore the part attributes for (i=0;i=0 && cap_nrefsearch(pname,nfig)==0) // Attach rules if (cap_rulefigatt(nfig,rl)) rsc_error(-1); } } string askpartsymbol(string oldmacname) /* // Ask for part symbol macro // Return value : // part symbol macro name, or empty string on abort // Parameter : // string oldmacname : Old macro name */ { string macname = oldmacname /* Selected macro name */; // Perform the part symbol macro selection if (bae_askddbename( macname,bae_planfname(),DDBCLSSYM,msgstring(UPRPRTMNAM,oldmacname))) // Abort return(""); // Return the selected part symbol macro name return(macname); } /*________________________________________________________________*/ // Symbol/label query routines void symbolquery() /* // Get placement data of mouse-selectable symbols/labels */ { index C_FIGURE fig /* Figure list index */; index C_NREF nref /* Named reference index */; index C_ATTRIBUTE att /* Attribute index */; string attrcommn /* Attribute comment name */; string attrcommv /* Attribute comment value */; string attrname /* Attribute name */; string attruname /* Attribute upper case name */; string attrvar /* Attribute variant extension */; string attrdisp /* Attribute display string */; double nx,ny /* Origin coordinates */; int reqcols /* Required columns count */; int varnum /* Attribute variant number */; int attrord /* Attribute sort order */; int len /* Attribute name length */; struct attrdata { // Attribute data descriptor string name /* Attribute name */; string disp /* Attribute display string */; int var /* Attribute variant number */; int order /* Attribute order */; } al[] /* Attribute list */; int an = 0 /* Attribute count */; struct tagdata { // Tag data descriptor string pin /* Tag pin name */; string disp /* Tag display string */; string dst1 /* Tag 1st destination name */; string dst2 /* Tag 2nd destination name */; int typ /* Tag type */; } tl[] /* Tag list */; int tn = 0 /* Tag count */; string tagpin /* Tag pin name */; int tagtyp /* Tag type */; string tagtypname /* Tag type name */; string tagdst1, tagdst2 /* Tag destination names */; int i /* Loop control variable */; // Abort if invalid plan class if (ddbclass!=DDBCLSCM) error_class(); // Get the plan origin coordinates nx=bae_planwsnx(); ny=bae_planwsny(); // Init the header list headl[7]=headl[1]=""; // Recursively select named references while (bae_promptdialog(UPRSELPART),scm_pickelem(fig,C_FIGNREF)==0) { // Set the units designator UNIT= bae_getcoorddisp() ? UNITI : UNITM; // Get and print the element data sprintf(headl[2],REPCOORD, baecvtl(fig.X-nx),baecvtl(fig.Y-ny),UNIT); sprintf(headl[3],REPANGLE,cvtangle(fig.ANGLE,0,1)); sprintf(headl[4],REPMIRROR,fig.MIRROR); sprintf(headl[5],REPGROUP,fig.GROUP); sprintf(headl[6],REPGLUED,(fig.FIXED&2) ? 1 : 0); // Init the pin list pinn=0; // Init the maximum pin name length MAXPINNAMLEN=strlen(ITMPINNAMHD); // Init the maximum net name length MAXNETNAMLEN=strlen(ITMNETNAMHD); // Init the maximum attribute name length MAXATRNAMLEN=strlen(ITMATRNAMHD); // Scan the current element curname=fig.NAME; if (cap_scanfelem(fig,nx,ny,0.0,1, pinposscanfunc,NULL,NULL,NULL)) error_scan(); // Print pin count sprintf(headl[7],REPPINCNT,pinn); headn=8; // Scan attributes nref=fig.NREF; forall (att of nref) { // Get attribute base name attrname=att.NAME; if (strmatch(attrname,"*\003*\003")) { len=strlen(attrname); sprintf(attrvar,REPATTRVAR, atoi(strextract(attrname,len-3,len-1))); attrname[len-4]='\0'; } else { attrvar=""; } // Get upper case attribute name attruname=attrname; strupper(attruname); // Build comment variable name sprintf(attrcommn,PAR_ATTRCOMMP, strextract(attruname,1,strlen(attruname))); // Query comment variable if (varget(attrcommn,attrcommv)!=0 || attrcommv=="") // No comment available attrcommn=attrname; else // Attach comment to variable name sprintf(attrcommn,"%s %s",attrname,attrcommv); attrcommn+=attrvar; sprintf(attrdisp,FMTATTENT,attrcommn, ATTFLEN>strlen(attrcommn) ? ATTFLEN-strlen(attrcommn) : 0,ITMUDOT,att.VALUE); // Build order variable name sprintf(attrcommn,PAR_ATTRORDP, strextract(attruname,1,strlen(attruname))); // Query order variable if (varget(attrcommn,attrord)!=0) // No order id available attrord=9999; for (i=an;i>0;i--) if (al[i-1].order>attrord || (al[i-1].order==attrord && (numstrcmp(al[i-1].name,attrname)>0 || (al[i-1].name==attrname && al[i-1].var>varnum)))) al[i]=al[i-1]; else break; // Store new attribute al[i].name=attrname; al[i].disp=attrdisp; al[i].order=attrord; al[i].var=varnum; an++; } for (i=0;i(strlen(tagpin)+strlen(tagtypname)+1) ? ATTFLEN-(strlen(tagpin)+strlen(tagtypname)+1) : 0, ITMUDOT,tagdst1,tagdst2); for (i=tn;i>0;i--) if (numstrcmp(tl[i-1].pin,tagpin)>0 || (tl[i-1].pin==tagpin && (numstrcmp(tl[i-1].dst1,tagdst1)>0 || (tl[i-1].dst1==tagdst1 && numstrcmp(tl[i-1].dst2,tagdst2)>0)))) tl[i]=tl[i-1]; else break; // Store new tag reference tl[i].pin=tagpin; tl[i].disp=attrdisp; tl[i].dst1=tagdst1; tl[i].dst2=tagdst2; tn++; } for (i=0;i=0;i--) sprintf(entryl[i],FMTPTABF,MAXPINNAMLEN, pinl[i].pinname,baecvtl(pinl[i].x),baecvtl(pinl[i].y), cvtangle(pinl[i].rotang,0,1),pinl[i].mirror, MAXNETNAMLEN,pinl[i].netname,pinl[i].attrlist); // Get the required colums count for (reqcols=i=0;i>1; // Test if pin found; update the search area if ((compres=numstrcmp(pinname,pinl[sidx].pinname))<=0) sub=sidx-1; else slb=sidx+1; } // Insert new pin to pin list for (sidx=pinn;sidx>slb;sidx--) pinl[sidx]=pinl[sidx-1]; pinl[slb].pinname=pinname; pinl[slb].x=x; pinl[slb].y=y; pinl[slb].rotang=rotang; pinl[slb].mirror=mirror; pinl[slb].netname=netname; pinl[slb].attrlist=attrlist; pinn++; // Update the maximum pin name length MAXPINNAMLEN=maxint(MAXPINNAMLEN,strlen(pinname)); // Update the maximum net name length MAXNETNAMLEN=maxint(MAXNETNAMLEN,strlen(netname)); // Update the maximum attribute name length MAXATRNAMLEN=maxint(MAXATRNAMLEN,strlen(attrlist)); } /*________________________________________________________________*/ // SCM part list routines void scmpartlist() /* // Display SCM part type list for current SCM plan */ { index C_NREF nref /* Named reference index */; // Abort if invalid plan class if (ddbclass!=DDBCLSCM) error_class(); // Get the attribute list for (attrn=0;attrn<1000;attrn++) { if ((attrl[attrn].attrname=bae_inistrval( bae_inifieldvarname(PAR_PLATTRL,attrn,0),""))=="") { // Check if list defined at all if (attrn==0) { // Use default attribute list attrl=defattrl; attrn=arylength(attrl); } break; } attrl[attrn].patternflag=bae_iniintval( bae_inifieldvarname(PAR_PLATTRL,attrn,1),0); attrl[attrn].outmode=bae_iniintval( bae_inifieldvarname(PAR_PLATTRL,attrn,2),1); attrl[attrn].attrdoc=bae_inistrval( bae_inifieldvarname(PAR_PLATTRL,attrn,3),""); } // Get the type list for (outn=0;outn<1000;outn++) { if ((outl[outn].outpattern=bae_inistrval( bae_inifieldvarname(PAR_PLTYPL,outn,0),""))=="") { // Check if list defined at all if (outn==0) { // Use default type list outl=defoutl; outn=arylength(outl); } break; } outl[outn].outname=bae_inistrval( bae_inifieldvarname(PAR_PLTYPL,outn,1),""); } // Loop for all placed symbols/parts forall (nref where nref.MACRO.CLASS==DDBCLSSYM) // Update the element list updelem(nref); // Print the part list printpartlist(); // Show the part list with popup menu bae_setintpar(16,3054); mnu_poptext(msgl,0,0,-1,0,0); } void updelem(index C_NREF nref) /* // Update element list with part // Parameters : // index C_NREF nref : Named reference index */ { int slb = 0 /* Search lower boundary */; int sub = elemn-1 /* Search upper boundary */; int idx /* Search index */; int compres /* Compare result */; index C_ATTRIBUTE attr /* Atrribute index */; string val /* Atribute value */; int i /* Loop control variable */; // Loop until search area empty while (slb<=sub) { // Get the search index idx=(slb+sub)>>1; // Get and test the compare result if ((compres=strcmp( nref.MACRO.NAME,eleml[idx].elmacname))==0) { // Compare all attributes for (i=0;i0;i--) if (numstrcmp(nref.NAME, eleml[idx].partl[i-1].NAME)<0) eleml[idx].partl[i]= eleml[idx].partl[i-1]; else break; eleml[idx].partl[i]=nref; // Update element part count eleml[idx].elcnt++; return; } // Update the search area if (compres<0) sub=idx-1; else slb=idx+1; } // Insert the new entry to the part list elemn++; for (idx=elemn-2;idx>=slb;idx--) eleml[idx+1]=eleml[idx]; // Insert element data eleml[slb].outflag=0; eleml[slb].elcnt=1; eleml[slb].elmacname=nref.MACRO.NAME; eleml[slb].partl[0]=nref; // Set attribute values for (i=0;i0;i--) if (pl[i-1]>name) { pl[i]=pl[i-1]; ppl[i]=ppl[i-1]; } else break; // Insert part name into list pl[i]=name; ppl[i]=planname; if (i>0 && pl[i-1]==name) { sprintf(entryl[entryn],REPSYMDUP,name, ppl[i-1],planname); entryn++; } // Update part count pn++; } } // Scan all part list entries planname=""; i=0; while (scanddbenames(filename,DDBCLSPLST,planname)==1) { // Update scan pointer in sorted part list while (planname>pl[i] && i0;i--) if (pl[bl[i-1]].x>x) bl[i]=bl[i-1]; else break; // Store port index bl[i]=pn; if (bml0;i--) if (pl[rl[i-1]].y>y) rl[i]=rl[i-1]; else break; // Store the port index rl[i]=pn; if (rml0;i--) if (pl[tl[i-1]].x>x) tl[i]=tl[i-1]; else break; // Store the port index tl[i]=pn; if (tml0;i--) if (pl[ll[i-1]].y>y) ll[i]=ll[i-1]; else break; // Store the port index ll[i]=pn; if (lml=ln || pl[rl[ridx]].y=rn || pl[ll[lidx]].y=bn || pl[tl[tidx]].y=tn || pl[bl[bidx]].y=varn) varn=curvar+1; break; default : ; } // Return without errors return(0); } int tattrfunc(index C_TEXT textp,double tx,double ty,double tangle, int mirrflag,double tsize,string tstr,int textinws,int macclass,int varattr) /* // Get the text attributes // Return value : // zero if done or (-1) on error // Parameters : // index C_TEXT textp : Text index // double tx : Text X coordinate // double ty : Text Y coordinate // double tangle : Text angle // int mirrflag : Text mirror flag // double tsize : Text size // string tstr : Text string // int textinws : Text in workspace flag // int macclass : Text macro class // int varattr : Text variant attribute flag */ { // Check if attribute string if (textp.STR=="$noplc") noplcflag=1; // Return without errors return(0); } static void symbolcopy() /* // Place a copy of a mouse selectible symbol */ { struct refmoddes { // Reference text modifier descriptor double x,y /* Text position */; double ang /* Text angle */; double size /* Text size */; int mirr /* Text mirror flag */; string str /* Text string */; } rtml[] /* Reference text modifier lists */; int rtmn = 0 /* Reference text modifier count */; index C_FIGURE lastfig /* Figure list element */; int lastflag /* Last figure element known flag */; index C_FIGURE fig /* Figure list element */; index C_FIGURE newfig /* New figure list element */; index C_NREF nref /* Named reference index */; index C_REFTEXT rmod /* Ref. text modifier index */; index C_MACRO macro /* Macro index */; index C_ATTRIBUTE att /* Attribute index */; struct { // Attribute descriptor string anam /* Attribute name */; string aval /* Attribute value */; } attl[] /* Part attribute list */; int attn = 0 /* Part attribute count */; string attrname /* Attribute name */; string symname /* Symbol name */; STRINGS rl /* Rule list */; int rn /* Rule count */; double x, y /* Symbol position */; double btx, bty /* Transformed text position */; double ttx, tty /* Temporary text coords. */; double tangle = 0.0 /* Text rotation angle */; double asin, acos /* Angle sin, cos values */; double size /* Text size */; int tmirror = 0 /* Text mirror flag */; int mirror = 0 /* Symbol mirror flag */; int oldmirror = 0 /* Symbol old mirror flag */; double rotangle = 0.0 /* Symbol rotation angle */; double oldrotangle = 0.0 /* Symbol old rotation angle */; double mnx, mny /* Macro origin coords. */; string oldlabmacro /* Old label macro name */; string libname /* Library name */; string logldef /* Definition string */; string rlname /* $rlname attribute value */; int ksymtextpos /* Keep symbol text pos. flag */; string pprefix /* Plot visibility rule prefix */; int plen /* Plot vis. rule prefix length */; int varafound = 0 /* Variant attribute data found flag */; int varpfound = 0 /* Variant plot vis. data found flag */; int i /* Loop control variable */; // Abort if invalid plan class if (ddbclass!=DDBCLSCM) return; varcheck(); // Pick symbol bae_promptdialog(UPRSYMCOPY); if (scm_pickelem(fig,C_FIGNREF)!=0) error(ERRNOPICK); // Get symbol data oldrotangle=fig.ANGLE; oldmirror=fig.MIRROR; nref=fig.NREF; macro=nref.MACRO; rlname=macro.NAME; // Init. attribute name list attn=0; // Scan the attributes forall (att of nref where scm_chkattrname(att.NAME)==0) { attrname=att.NAME; if (scm_chkattrname(attrname)!=0 || attrname=="$spname") continue; attl[attn].anam=attrname; attl[attn].aval=att.VALUE; if (attrname=="$rpname" || attrname=="$rbname" || attrname=="$vgrp") { inirpname=""; if (cap_scanfelem(fig,0.0,0.0,0.0,1, rpmacfunc,NULL,NULL,rptextfunc)!=0) error_scan(); } if (attrname=="$rlname" && attl[attn].aval!="") rlname=attl[attn].aval; attn++; } // Get the rules rn= fig.RULEOBJID>=0 ? rsc_getfigrules(fig,rl) : 0 ; // Transfer name moves forall (rmod of nref) { // Store the text position rtml[rtmn].x=rmod.X; rtml[rtmn].y=rmod.Y; rtml[rtmn].ang=rmod.ANGLE; rtml[rtmn].size=rmod.SIZE; rtml[rtmn].mirr=rmod.MIRROR; rtml[rtmn].str=rmod.STR; rtmn++; } // Get last placed element lastflag= cap_lastfigelem(lastfig)==0 ? 1 : 0 ; bae_clriactqueue(); if (macro.CLASS!=DDBCLSLAB) { // Place symbol if (bae_iniintval(PAR_NAMEPROMPT,1)) bae_storetextiact(1,""); bae_storetextiact(1,macro.NAME); bae_storemouseiact(1,0.0,0.0,1,RMB); bae_storemenuiact(1,oldmirror ? 8 : 7,LMB); bae_storemouseiact(1,0.0,0.0,1,RMB); bae_storemenuiact(1,6,LMB); bae_storetextiact(1,ftoa(cvtangle(oldrotangle,0,1),5)); bae_callmenu(MNU_SCMADDSYM); } else { // Buffer old label macro oldlabmacro=baepar_strval(SCMPAR_LABELMACRO); // Set requested label macro bae_storetextiact(1,macro.NAME); bae_callmenu(809); // Place label bae_clriactqueue(); bae_storetextiact(1,fig.NAME); bae_storemouseiact(1,0.0,0.0,1,RMB); bae_storemenuiact(1,oldmirror ? 8 : 7,LMB); bae_storemouseiact(1,0.0,0.0,1,RMB); bae_storemenuiact(1,6,LMB); bae_storetextiact(1,ftoa(cvtangle(oldrotangle,0,1),5)); bae_callmenu(MNU_SCMADDLAB); // Restore old label macro bae_clriactqueue(); bae_storetextiact(1,oldlabmacro); bae_callmenu(809); } // Check if symbol successfully placed scm_getstrpar(macro.CLASS==DDBCLSLAB ? 2 : 1,symname); if (cap_lastfigelem(newfig)==0 && (!lastflag || newfig!=lastfig) && cap_nrefsearch("",newfig)==0 && newfig.NAME==symname) { // Check if variant specific symbol data if (VARATTRCHK) { for (i=0;i=0;i--) if (strextract(rl[i],0,plen-1)==pprefix && rl[i][plen]!='0') { rl[i]=""; rn--; } } } // Transfer all attributes for (i=0;i0 && cap_nrefsearch("",newfig)==0) // Attach rules if (cap_rulefigatt(newfig,rl)) rsc_error(-1); // Test if text position preservation if ((ksymtextpos=baepar_intval(SCMPAR_KSYMTEXTPOS))==0 || ksymtextpos==3 || rtmn==0) return; // Transfer text position changes x=newfig.X; y=newfig.Y; mirror=newfig.MIRROR; rotangle=newfig.ANGLE; macro=newfig.NREF.MACRO; mnx=macro.MNX; mny=macro.MNY; for (i=0;i=DPI) tangle-=DPI; // Store the text position scm_attachtextpos( newfig,rtml[i].str,x+btx,y+bty,tangle,size,tmirror); } } else { bae_clriactqueue(); } } int rpmacfunc(index C_MACRO macro,index C_POOL pool,int macinws, string refname,index C_LEVEL level,index C_LEVEL buslevel) /* // $rpname attribute scan macro function // Return value : // 0 if out of workspace, 1 if inside, 2 if unknown, or (-1) on error // Parameters : // index C_MACRO macro : Macro index // index C_POOL pool : Macro pool index // int macinws : Macro in workspace flag // string refname : Macro reference name // index C_LEVEL level : Macro level // index C_LEVEL buslevel : Macro bus level */ { // Check if symbol macro if (macro.CLASS==DDBCLSSYM) // Continue symbol macro scan return(1); // Abort scan for pins return(0); } int rptextfunc(index C_TEXT textp,double tx,double ty,double tangle, int mirrflag,double tsize,string tstr,int textinws,int macclass,int varattr) /* // $rpname attribute scan text function // Return value : // zero if done or (-1) on error // Parameters : // index C_TEXT textp : Text index // double tx : Text X coordinate // double ty : Text Y coordinate // double tangle : Text angle // int mirrflag : Text mirror flag // double tsize : Text size // string tstr : Text string // int textinws : Text in workspace flag // int macclass : Text macro class // int varattr : Text variant attribute flag */ { if (textp.STR=="$rpname" || textp.STR=="$rbname" || textp.STR=="$vgrp") // Query the current active default value if (cap_rulequery(RS_OCPOOL,textp,RS_SCMSUBJ,RS_INIVAL, "?s",inirpname)<1) inirpname=""; // Return without errors return(0); } void fpganetlistread() /* // Read pin assignments from assignment file */ { string destfname /* Destination file name */; string infname /* Input file name */; int ifh /* Input file handle */; string readbuf /* Input buffer */; string netname /* Net name */; string pinnumber /* Pin number */; string pindir /* Pin direction */; string symname /* Symbol name */; string symbase /* Symbol base name */; string package /* Package name */; string name /* Name string */; string logldef /* Logical library definition */; STRINGS strl /* String list */; int strn /* String count */; int len /* String length */; int first = 1 /* First item flag */; struct pindes { // Pin descriptor string name /* Pin net name */; string num /* Pin name */; int typflag /* Pin type known flag */; }; struct pindes ll[], rl[] /* Pin lists */; int ln = 0 /* Left pin count */; int lml = 0 /* Left pins max. name length */; int rn = 0 /* Right pin count */; int rml = 0 /* Right pins max. name length */; int pincnt /* Pin count */; double loff, roff /* Horizontal offsets */; double lbox, rbox /* Horizontal box sizes */; double lx, ly /* Lower pin coordinate */; double ux, uy /* Upper pin coordinate */; double pinoff /* Pin shift offset */; double width, height /* Symbol workspace size */; double orgx = 0.0 /* Origin x position */; double orgy = 0.0 /* Origin y position */; int rown /* Pin row count */; char c /* Character buffer */; int i /* Loop control variable */; // Get netlist file name if ((infname=askfile(UPRASSFILE,assext,0))=="") return; // Open netlist file ifh=bae_fopen(infname,0); // Loop for all lines bae_prtdialog(REPREADASS); while (fgets(readbuf,1024,ifh)==0) { len=strlen(readbuf); while (len>0 && ((c=readbuf[len-1])==0x0a || c==0x0d)) len--; if (len==0) continue; readbuf[len]='\0'; if (readbuf[len-1]!='|') { if (strextract(readbuf,0,7)=="PACKAGE:") package=strtrim(strextract(readbuf,9,len)); else if (strextract(readbuf,0,9)=="PART TYPE:") symname=strtrim(strextract(readbuf,11,len)); continue; } if (readbuf[0]!='|') readbuf="|"+readbuf; // Split line into separated strings if ((strn=splitnetstring(readbuf,strl,"|"))<3) // Ignore invalid input line continue; // Get pin data pinnumber=strtrim(strl[0]); strlower(pinnumber); netname=strtrim(strl[1]); strlower(netname); pindir=strtrim(strl[4]); strlower(pindir); // Check if pin used if (netname=="") continue; // Skip header entry if (first) { first=0; continue; } len=strlen(netname); switch (pindir) { case "output" : // Right side pin for (i=rn;i>0;i--) if (rl[i-1].name0;i--) if (ll[i-1].name0;i--) if (ll[i-1].namern ? ln : rn ; if (CENTHEIGHT0 && ((c=readbuf[len-1])==0x0a || c==0x0d)) len--; if (len==0) continue; readbuf[len]='\0'; // Split line into separated strings if ((strn=splitstring(readbuf,strl,FIELDSEP))<3) // Ignore invalid input line continue; // Get the symbol name symname=strl[SYMNAMECOL]; if (symname[0]=='*') { symname=strextract(symname,1,strlen(symname)); strlower(mainpart=symbase+"_"+symname); } // Check if already defined for (symidx=0;symidx=symn) { // Add new symbol symidx=symn; symn++; syml[symidx].name=symname; strlower(syml[symidx].macro=symbase+"_"+symname); syml[symidx].pn=0; syml[symidx].ttn=syml[symidx].btn=0; syml[symidx].ln=syml[symidx].rn=0; syml[symidx].lml=syml[symidx].rml=0; // Get the part attributes for (i=0;i=0 && plname=="") strlower(plname=strl[PLNAMECOL]); strlower(pintype); len=strlen(spinname); pidx=syml[symidx].pn; // Check if pin schematic name already used for (i=0;i=lefttypn) for (i=0;i=0) { pinpos=atoi(strl[SYMPINPCOL])-1; // Adjust row counters if (pinside) { if (syml[symidx].rn<=pinpos) syml[symidx].rn=pinpos+1; } else { if (syml[symidx].ln<=pinpos) syml[symidx].ln=pinpos+1; } } else { // Get next row if (pinside) { pinpos=syml[symidx].rn; syml[symidx].rn++; } else { pinpos=syml[symidx].ln; syml[symidx].ln++; } } // Adjust max. pin name length if (pinside) { if (len>syml[symidx].lml) syml[symidx].lml=len; } else { if (len>syml[symidx].rml) syml[symidx].rml=len; } // Store the pin syml[symidx].pl[pidx].sname=spinname; syml[symidx].pl[pidx].lnamel[syml[symidx].pl[pidx].lnamen]= lpinname; syml[symidx].pl[pidx].lnamen=1; syml[symidx].pl[pidx].marker=pinmarker; syml[symidx].pl[pidx].edrctyp=edrctyp; syml[symidx].pl[pidx].procflag=0; syml[symidx].pl[pidx].row=pinpos; syml[symidx].pl[pidx].side=pinside; // Get the pin attributes for (i=0;isyml[symidx].rn ? syml[symidx].ln : syml[symidx].rn ; height= (CENTHEIGHT0) { // Scan all elements of check class symname=""; while (scanddbenames(destfname,DDBCLSCM,symname)==1) { // Get the DDB element reference count refcnt=ddbelemrefcount(destfname,DDBCLSCM,symname); // List the DDB element references for (refidx=0;refidxpos1) ssl[ssn++]=strextract(s,pos1-1,pos2-2); // Update the scan start position pos1=pos2+1; } // Extract last substring if last char not delimiter if (pos10) { ssl[ssn][ssp]='\0'; ssn++; } // Remove field quotation marks for (pos=0;pos=0 && isspace(s[i])) ; // Extract and return substring return(i<0 ? "" : strextract(s,0,i)); } string strtrim(string s) /* // Trim string (skip leading and trailing white spaces) // Return value : // string without leading and trailing white spaces // Parameters : // string s : Input string */ { // Extract and return substring return(strrtrim(strltrim(s))); } // Logical library file syntax #bnf { // Loglib file libdef : "part" ident ":" optclassspec partdef ; // Part functions syntax optclassspec : "class" ident | ; partdef : mainflag defflag plnames partblk | "subpart" (p_subpart) ident partblk | "virtual" virtblk | "logical" virtblk ; mainflag : "mainpart" (p_mainpart) | ; defflag : "default" | ; plnames : plnames "," ident | ident ; partblk : "{" partcmds "}" | ";" ; partcmds : partcmds partcmd | partcmd ; partcmd : "bus" pinlist ";" | "net" netcmd ":" pinlist ";" | "pin" pinlist ";" | "swap" swapcmd swapblk ";" | "xlat" pinlist "to" xlats ";" | "xlat" "(" xlatpinass ")" ";" | "netattr" "priority" DQSTR ":" pinlist ";" | "netattr" "mindist" DQSTR ":" pinlist ";" | "netattr" "powwidth" DQSTR ":" pinlist ";" | "netattr" "routwidth" DQSTR ":" pinlist ";" | "netattr" idstr DQSTR ":" pinlist ";" | "newattr" DQSTR "=" DQSTR topinlist ";" | "comment" "=" DQSTR ";" ; virtblk : "{" virtcmds "}" | ";" ; virtcmds : virtcmds virtcmd | virtcmd ; virtcmd : "bus" pinlist ";" | "net" netcmd ":" pinlist ";" | "pin" pinlist ";" | "netattr" "priority" DQSTR ":" pinlist ";" | "netattr" "mindist" DQSTR ":" pinlist ";" | "netattr" "powwidth" DQSTR ":" pinlist ";" | "netattr" "routwidth" DQSTR ":" pinlist ";" | "netattr" idstr DQSTR ":" pinlist ";" | "newattr" DQSTR "=" DQSTR topinlist ";" | "call" ident ";" | "architecture" "{" synthprog "}" | "comment" "=" DQSTR ";" ; topinlist : "to" pinlist | ; netcmd : ident | "internal" ; swapcmd : "internal" | ; swapblk : "(" groups ")" | "(" gates ")" ; groups : groups "," "[" gates "]" | "[" gates "]" ; gates : gates "," gate | gate ; gate : "(" gateblk ")" | pin ; gateblk : gateblk "," gatepin | gatepin ; gatepin : pinlist | pin ; xlats : xlats "or" (p_xlator) pinlist | pinlist ; xlatpinass : xlatpinass "," xlpindef | xlpindef ; xlpindef : "(" pin "," xlpins ")" ; xlpins : xlpins "," (p_xlator) pin | pin ; synthprog : synthprog sprogcmd | sprogcmd ; sprogcmd : "part" ident "(" preqpinlist ")" ";" ; preqpinlist : preqpinlist "," preqpinass | preqpinass ; preqpinass : pin ":" preqdest ; preqdest : pin | "net" ident | "net" "&" ident | "&" ident ; pinlist : "(" pins ")" ; pins : pins "," pin | pin ; pin : identpt | identpt "-" identpt optstep ; optstep : ":" NUMBER | ; // Identifier expression ident : IDENT | NUMBER | SQSTR | DQSTR ; identpt : identpt idpiece | '/' idpiece | idpiece ; idpiece : IDENT | NUMBER | SQSTR | DQSTR | '.' ; idstr : IDENT | DQSTR ; } // BNF end int p_mainpart() /* // Receive a mainpart flag // Return value : // zero if done, or nonzero on error */ { symtyp=1; // Return without errors return(0); } int p_subpart() /* // Receive a subpart definition // Return value : zero if done, or nonzero on error */ { symtyp=2; // Return without errors return(0); } int p_xlator() /* // Receive a xlat or command // Return value : // zero if done, or nonzero on error */ { // Increment the current xlat or command count gatecnt++; // Return without errors return(0); } // User Language program end