/* EDIFOUT (GED) -- EDIF 2.0 Netlist Data Output */ /* EDIFOUT (GED) -- EDIF 2.0 Netzlistenausgabe */ /* // Copyright (c) 1997-2012 Oliver Bartels F+E, Muenchen // Author: Oliver Bartels // Changes History: // 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 (010625) RELEASED FOR BAE V5.0. // rl (010409) ENHANCEMENT: // Added optional parameter settings from bae.ini file. // rl (000508) RELEASED FOR BAE V4.6. // rl (991115) RELEASED FOR BAE V4.4. // ob (980923) ADAPTED TO BAE V4.2. // ob (980923) ENHANCEMENT: // Dynamic multi-language support introduced. // ob (970202) ORIGINAL CODING. // // DESCRIPTION // // The edifout User Language program generates an EDIF 2.0 // netlist for external PLD layout/fitter programs. // edifout reads a (logical) netlist and automatically creates // a layout worksheet to extract the required data. // The EDIF netlist consists of an external library reference, // an interface description, and the actual netlist. // The output is directed to a file with extension ".edf". */ // Includes #include "pop.ulh" // User Language popup utilities // Disable undo state request #pragma ULCALLERNOUNDO // Messages string UPRDDBFILE = M("Jobdatei ? ","Job File ? "); string REPSTART = M("EDIF-Netzlisten Ausgabe...", "EDIF netlist output..."); string REPDONE = M("EDIF-Netzliste ausgegeben auf Datei '%s'.", "EDIF netlist written to file '%s'."); string ERRDDBACC = M("Fehler beim Lesen der Design Datenbank!", "Error reading design database!"); // INI file parameter name definitions #define PAR_EDFOFEXT "EDFOFEXT_GED" // EDIF file name extension #define PAR_EDFOEXTL "EDFOEXTL_GED" // External library name #define PAR_EDFOPPATT "EDFOPPATT_GED" // Port net name pattern #define PAR_EDFOPPIN "EDFOPPIN_GED" // Port pin spec. #define PAR_EDFOPINDIR "EDFOPINDIR_GED" // Pin direction attr. name // Global constants string EDFEXT = bae_inistrval(PAR_EDFOFEXT,".edf") /* EDIF file name extension */; string EXTLIBNAME = bae_inistrval(PAR_EDFOEXTL,"Lattice") /* External library name */; string PORTPATT = bae_inistrval(PAR_EDFOPPATT,"[??]*") /* Port net name pattern */; string PORTPIN = bae_inistrval(PAR_EDFOPPIN,"pin") /* Port pin spec. */; string PINDIRATT = bae_inistrval(PAR_EDFOPINDIR,"$dir") /* Pin direction attribute name */; // Global variables int nlfile; // Netlist file handle struct logpdef { // Logical part definition string llname; // Logical library part name index L_CPART cpart; // Sample netlist part } lpartl[]; // Logical library part list int lpartn = 0; // Logical library part count int inslogidx; // Logical lib. part insert index void main() // Main program { string jobfname; // Job file name string jobename; // Job element name string placefname; // Place file name string msgbuf; // Message buffer // Perform BAE Demo check with abort option BAE_Demo_check(2); // Abort if invalid interpreter type if (uliptype()!=ULIPGED) error_class(); // Get the plan file and element name if (bae_askddbfname(jobfname,1,UPRDDBFILE) || bae_askddbename(jobename,jobfname,DDBCLPCON,"")) // Abort error_abort(); // Build the EDIF netlist file name placefname=convstring(jobfname,0)+EDFEXT; // Start output bae_prtdialog(REPSTART); // Open the EDIF netlist file nlfile=fopen(placefname,1); // Write the edif header writeedifheader(); // Create the library worksheet switch (existddbelem(jobfname,DDBCLLAY,jobename)) { // Layout not found case 0 : createlay(jobfname,jobename); break; // Layout does already exist case 1 : bae_loadelem(jobfname,jobename,DDBCLLAY); break; // File access failed default : error(ERRDDBACC); } // Create the cell definition list creacelllist(); // Write the logical library list writelogdef(); // Write the design writedesign(); // Write the output done message sprintf(msgbuf,REPDONE,placefname); bae_prtdialog(msgbuf); } static void createlay(string filename,string elemname) /* // Create the layout sheet for the netlist // Parameters: // string filename : Layout file name // string elemname : Layout element name */ { // Insert the new element parameters bae_clriactqueue(); bae_storemenuiact(1,0,LMB); bae_storetextiact(1,filename); bae_storetextiact(1,elemname); bae_storetextiact(1,"10"); bae_storetextiact(1,"10"); // Call the create new element menu function if (bae_callmenu(MNU_GEDCREELEM)) // Parameter store failed error(ERRDDBACC); } static void creacelllist() /* // Create the logical cell library list */ { index L_CPART cpart; // Connection part index index L_ATTRIBUTE attr; // Attribute index string logname; // Logical library part name forall (cpart) { // Get the logical library part name forall (attr of cpart where attr.NAME=="$llname") { // Store the logical library part name logname=attr.VALUE; strupper(logname); break; } // Update logical library part list fclogp(logname,cpart); } } static void fclogp(string llname,index L_CPART cpart) /* // Find or create a logical library part name entry */ { int logidx; // Cur. log. part index int i; // Loop control variable // Test if this log. part exists if ((logidx=findlog(llname))>=0) // Log. library part exists return; // Allocate new log. part entry lpartn++; // Copy old data entries to new position for (i=(lpartn-1)-1;i>=inslogidx;i--) lpartl[i+1]=lpartl[i]; // Insert new data lpartl[inslogidx].llname=llname; lpartl[inslogidx].cpart=cpart; } static int findlog(string llname) /* // Search a log. part entry // Return value : // log. part index or (-1) if not of found // Parameters : // string log. part : Name of log. part searched */ { int slb=0; // Search lower boundary int sub=lpartn-1; // Search upper boundary int sidx; // Search index int compres; // Compare result // Loop until search area empty while (slb<=sub) { // Get the search index sidx=(slb+sub)>>1; // Compare entries compres=strcmp(llname,lpartl[sidx].llname); // Test if log. part found if (compres==0) // Log. part found return(sidx); // Update the search area if (compres<0) sub=sidx-1; else slb=sidx+1; } // Store the insert log. part index inslogidx=slb; // Log. part not found return(-1); } static void writeedifheader() /* // Write the EDIF header */ { int year,month,day; // Date int hour,min,sec; // Time // Get date and time get_date(day,month,year); get_time(hour,min,sec); // Write the header fprintf(nlfile,"(edif BAE_edif (edifVersion 2 0 0) (edifLevel 0)\n"); fprintf(nlfile," (keywordMap (keywordLevel 0))\n"); fprintf(nlfile," (status\n"); fprintf(nlfile," (written (timeStamp %d %d %d %d %02d %02d)\n", year+1900,month+1,day,hour,min,sec); fprintf(nlfile," (program \"BAE EDIF Output\" (Version \"%s\"))\n", bae_swversion(0)); fprintf(nlfile," (dataOrigin \"BAE\") (author \"O. Bartels\")\n"); fprintf(nlfile," )\n"); fprintf(nlfile," )\n"); } static void writelogdef() /* // Write the logical library definitions */ { index L_CPART cpart; // Connection part index index L_CPIN cpin; // Connection pin index index L_ATTRIBUTE attr; // Attribute index string pinname; // Pin name string dirname; // Direction name int i; // Loop control variable fprintf(nlfile," (external %s (edifLevel 0)",EXTLIBNAME); fprintf(nlfile," (technology (numberDefinition))\n"); // Loop for all log. library parts for (i=0;i