Skip to content

Commit 1567807

Browse files
committed
Add a new Linux comand input type to accept LEF/DEF files
1) New flag -ldp -ld etc. Put LEF/DEF files at the very last of command input. Example command: -bash-4.2$ ./LayoutAnalyzer -ldp net2s_m3_alone.gds examples/net2s.sim_input test.spef confidential/asap7/aes_cipher_top.def confidential/asap7/asap7sc7p5t_24_L_4x_170912_mod.lef confidential/asap7/asap7sc7p5t_24_R_4x_170912_mod.lef confidential/asap7/asap7sc7p5t_24_SL_4x_170912_mod.lef confidential/asap7/asap7sc7p5t_24_SRAM_4x_170912_mod.lef 2) Called functions to read LEF/DEF and to generate auto ports from LEF/DEF. Main credit to Michael.
1 parent 763cdc2 commit 1567807

File tree

1 file changed

+275
-1
lines changed

1 file changed

+275
-1
lines changed

src/TestMain.cpp

+275-1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ int main(int argc, char** argv)
5050
cout << " -sp, --spef Read GDSII and sim input files into memory, simulate, and write solution to SPEF file." << endl;
5151
cout << " -sc, --citi Read GDSII and sim input files into memory, simulate, and write solution to CITIfile." << endl;
5252
cout << " -st, --touchstone Read GDSII and sim input files into memory, simulate, and write solution to Touchstone file." << endl;
53+
cout << " -ldp, --lefdefspef Read GDSII, sim input, and LEF/DEF files into memory, simulate, and write solution to SPEF file." << endl;
5354
cout << endl << "Comments:" << endl;
5455
cout << " The file passed after -r, --read, -p, or --parrot must be a Calma GDSII stream file." << endl;
5556
cout << " The file passed after -w or --write must be a blank SPEF file." << endl;
@@ -58,7 +59,8 @@ int main(int argc, char** argv)
5859
cout << " The first file passed after -s or --simulate (or -sx or --xyce) must be a Calma GDSII stream file, the second must be a sim_input file, and the third must be a blank Xyce file." << endl;
5960
cout << " The first file passed after -sp or --spef must be a Calma GDSII stream file, the second must be a sim_input file, and the third must be a blank SPEF file." << endl;
6061
cout << " The first file passed after -sc or --citi must be a Calma GDSII stream file, the second must be a sim_input file, and the third must be a blank CITIfile." << endl;
61-
cout << " The first file passed after -sc or --citi must be a Calma GDSII stream file, the second must be a sim_input file, and the third must be a blank Touchstone file." << endl;
62+
cout << " The first file passed after -st or --touchstone must be a Calma GDSII stream file, the second must be a sim_input file, and the third must be a blank Touchstone file." << endl;
63+
cout << " The first file passed after -ldp or --lefdefspef must be a Calma GDSII stream file, the second must be a sim_input file, the third must be a blank SPEF file, and all subsequent files must be LEF/DEF files." << endl;
6264
cout << endl << "Bug reporting:" << endl;
6365
cout << "Visit <https://github.com/purdue-onchip/gds2Para>" << endl;
6466
}
@@ -446,6 +448,278 @@ int main(int argc, char** argv)
446448
cerr << "Rerun with \"--help\" flag for details" << endl;
447449
}
448450
}
451+
else if (argc > 5)
452+
{
453+
if ((strcmp(argv[1], "-ld") == 0) || (strcmp(argv[1], "--lefdef") == 0) || (strcmp(argv[1], "-ldx") == 0) || (strcmp(argv[1], "--lefdefxyce") == 0) || (strcmp(argv[1], "-ldp") == 0) || (strcmp(argv[1], "--lefdefspef") == 0)) // || (strcmp(argv[1], "-ldc") == 0) || (strcmp(argv[1], "--lefdefciti") == 0) || (strcmp(argv[1], "-ldt") == 0) || (strcmp(argv[1], "--lefdeftouchstone") == 0))
454+
{
455+
// Initialize SolverDataBase, mesh, and set variables for performance tracking
456+
clock_t t1 = clock();
457+
SolverDataBase sdb;
458+
fdtdMesh sys;
459+
int status = 0; // Initialize as able to return successfully
460+
bool adbIsGood, sdbIsGood, sdbCouldDump;
461+
462+
// Get file names
463+
string inGDSIIFile = argv[2];
464+
string inSimFile = argv[3];
465+
string outFile = argv[4];
466+
string inDefFile = "";
467+
vector<string> inLefFiles = {};
468+
for (size_t indi = 5; indi < argc; indi++) {
469+
string curFile = argv[indi];
470+
size_t indExten = curFile.find_last_of(".");
471+
if (curFile.compare(indExten, indExten + 3, ".def") == 0
472+
|| curFile.compare(indExten, indExten + 3, ".DEF") == 0) {
473+
inDefFile = curFile;
474+
}
475+
if (curFile.compare(indExten, indExten + 3, ".lef") == 0
476+
|| curFile.compare(indExten, indExten + 3, ".LEF") == 0) {
477+
inLefFiles.push_back(curFile);
478+
}
479+
}
480+
if (inDefFile.size() == 0 || inLefFiles.size() == 0) {
481+
cerr << "ERROR! Both DEF and LEF files must be provided. \n";
482+
return 1;
483+
}
484+
485+
// Read GDSII file
486+
AsciiDataBase adb;
487+
adb.setFileName(inGDSIIFile);
488+
GdsParser::GdsReader adbReader(adb);
489+
adbIsGood = adbReader(inGDSIIFile.c_str());
490+
if (adbIsGood)
491+
{
492+
vector<size_t> indCellPrint = {}; // { adb.getNumCell() - 1 };
493+
adb.print(indCellPrint);
494+
cout << "GDSII file read" << endl;
495+
}
496+
else
497+
{
498+
cerr << "Unable to read in GDSII file" << endl;
499+
status = 1;
500+
return status;
501+
}
502+
503+
// Read simulation input file
504+
sdbIsGood = sdb.readSimInput(inSimFile);
505+
if (sdbIsGood)
506+
{
507+
cout << "Simulation input file read" << endl;
508+
}
509+
else
510+
{
511+
cerr << "Unable to read in simulation input file" << endl;
512+
status = 1;
513+
return status;
514+
}
515+
516+
// Read LEF/DEF files
517+
LefDataBase dbLef; // LEF
518+
bool lefStatus = LefParser::read(dbLef, inLefFiles[0]);
519+
if (lefStatus) {
520+
cout << "Successfully read in LEF file " << inLefFiles[0] << endl;
521+
}
522+
else {
523+
cerr << "Unable to read in LEF file " << inLefFiles[0] << endl;
524+
return 1;
525+
}
526+
for (int i = 1; i < inLefFiles.size(); i++) { // append cells from other LEF files to dbLef
527+
LefDataBase tempLef;
528+
lefStatus = LefParser::read(tempLef, inLefFiles[i]);
529+
if (lefStatus) {
530+
cout << "Successfully read in LEF file " << inLefFiles[i] << endl;
531+
}
532+
else {
533+
cerr << "Unable to read in LEF file " << inLefFiles[i] << endl;
534+
return 1;
535+
}
536+
dbLef.appendCellMap(tempLef.allCells);
537+
}
538+
DefDataBase dbDef; // DEF
539+
bool defStatus = DefParser::read(dbDef, inDefFile);
540+
if (defStatus) {
541+
cout << "Successfully read in DEF file " << inDefFile << endl;
542+
}
543+
else {
544+
cerr << "Unable to read in DEF file " << inDefFile << endl;
545+
return 1;
546+
}
547+
/* Verify LEF/DEF
548+
dbLef.print_allCells();
549+
dbDef.print_allComponents();
550+
dbDef.print_allDefPins();
551+
dbDef.print_allNets();
552+
dbDef.areAllNetNodesValidComponentOrValidPin();
553+
areAllComponentsInNetsValidCell(dbDef.allComponents, dbDef.allNets, dbLef.allCells);
554+
*/
555+
556+
// Set auto ports from LEF/DEF
557+
AutoPorts autoPorts;
558+
autoPorts.readLayerMap_cbk(inSimFile);
559+
//autoPorts.print_layerMap_cbk();
560+
autoPorts.getPortCoordinate(dbDef.allComponents, dbDef.allDefPins, dbDef.allNets, dbLef.allCells);
561+
//autoPorts.print_netName_to_vPortCoor();
562+
563+
// Append information so far to fdtdMesh
564+
unordered_set<double> portCoorx, portCoory;
565+
string topCellName = adb.getCell(adb.getNumCell() - 1).getCellName();
566+
adb.saveToMesh(topCellName, { 0., 0. }, strans(), &sys, sdb.findLayerIgnore()); // Recursively save GDSII conductor information to sys
567+
sdb.convertToFDTDMesh(&sys, adb.getNumCdtIn(), &portCoorx, &portCoory); // Save simulation input information to sys
568+
569+
// Mesh the domain and mark conductors
570+
unordered_map<double, int> xi, yi, zi;
571+
clock_t t2 = clock();
572+
status = meshAndMark(&sys, xi, yi, zi, &portCoorx, &portCoory);
573+
if (status == 0)
574+
{
575+
cout << "meshAndMark Success!" << endl;
576+
cout << "meshAndMark time is " << (clock() - t2) * 1.0 / CLOCKS_PER_SEC << " s" << endl << endl;
577+
}
578+
else
579+
{
580+
cerr << "meshAndMark Fail!" << endl;
581+
return status;
582+
}
583+
//sys.print();
584+
585+
// Set D_eps and D_sig
586+
clock_t t3 = clock();
587+
status = matrixConstruction(&sys);
588+
if (status == 0)
589+
{
590+
cout << "matrixConstruction Success!" << endl;
591+
cout << "matrixConstruction time is " << (clock() - t3) * 1.0 / CLOCKS_PER_SEC << " s" << endl << endl;
592+
}
593+
else {
594+
cerr << "matrixConstruction Fail!" << endl;
595+
return status;
596+
}
597+
//sys.print();
598+
599+
// Set port
600+
clock_t t4 = clock();
601+
status = portSet(&sys, xi, yi, zi);
602+
if (status == 0)
603+
{
604+
cout << "portSet Success!" << endl;
605+
cout << "portSet time is " << (clock() - t4) * 1.0 / CLOCKS_PER_SEC << " s" << endl << endl;
606+
}
607+
else
608+
{
609+
cerr << "portSet Fail!" << endl;
610+
return status;
611+
}
612+
//sys.print();
613+
614+
// Generate Stiffness Matrix
615+
#ifndef SKIP_GENERATE_STIFF
616+
clock_t t5 = clock();
617+
status = generateStiff(&sys);
618+
if (status == 0)
619+
{
620+
cout << "generateStiff Success!" << endl;
621+
cout << "generateStiff time is " << (clock() - t5) * 1.0 / CLOCKS_PER_SEC << " s" << endl << endl;
622+
}
623+
else
624+
{
625+
cerr << "generateStiff Fail!" << endl;
626+
return status;
627+
}
628+
#endif
629+
630+
// Write object sys to files
631+
#ifndef SKIP_LAYERED_FD
632+
WriteSysToFile(sys);
633+
#endif
634+
635+
// Parameter generation
636+
clock_t t6 = clock();
637+
#ifndef SKIP_LAYERED_FD // Run layered Finite-Difference solver
638+
cout << endl << endl << "Results from Layered Finite-Difference Solver: " << endl;
639+
status = solveE_Zpara_layered(&sys);
640+
//cout << endl << endl << "Results from Reference (direct backslash with PARDISO): " << endl;
641+
//solveE_Zpara_reference(&sys);
642+
#else // Run VoVh solver
643+
cout << endl << endl << "Results from V0Vh Solver: " << endl;
644+
status = paraGenerator(&sys, xi, yi, zi);
645+
#endif
646+
if (status == 0)
647+
{
648+
cout << "paraGenerator Success!" << endl;
649+
cout << "paraGenerator time is " << (clock() - t6) * 1.0 / CLOCKS_PER_SEC << " s" << endl << endl;
650+
}
651+
else
652+
{
653+
cerr << "paraGenerator Fail!" << endl;
654+
return status;
655+
}
656+
cout << "Engine time to this point: " << (clock() - t2) * 1.0 / CLOCKS_PER_SEC << " s" << endl;
657+
cout << "Total time to this point: " << (clock() - t1) * 1.0 / CLOCKS_PER_SEC << " s" << endl << endl;
658+
659+
// Network parameter storage
660+
Parasitics newPara = sdb.getParasitics(); // Start with outdated parastics to update
661+
newPara.saveNetworkParam('Z', sdb.getSimSettings().getFreqsHertz(), sys.x); // Save the Z-parameters in fdtdMesh to Parasitics class
662+
sdb.setParasitics(newPara);
663+
664+
// Select Output File Based on Control Mode
665+
cout << endl;
666+
if ((strcmp(argv[1], "-ldp") == 0) || (strcmp(argv[1], "--lefdefspef") == 0))
667+
{
668+
// Output SPEF file
669+
string outSPEFFile = argv[4];
670+
vector<size_t> indLayerPrint = { 0, 1 * sdb.getNumLayer() / 3, 2 * sdb.getNumLayer() / 3, sdb.getNumLayer() - 1 }; // {}; // Can use integer division
671+
sdb.setDesignName(adb.findNames().back());
672+
sdb.setOutSPEF(outSPEFFile);
673+
sdb.print(indLayerPrint);
674+
bool sdbCouldDump = sdb.dumpSPEF();
675+
cout << "File ready at " << outSPEFFile << endl;
676+
}
677+
/*else if ((strcmp(argv[1], "-ldc") == 0) || (strcmp(argv[1], "--lefdefciti") == 0))
678+
{
679+
// Convert to S-parameters
680+
Parasitics newPara = sdb.getParasitics(); // Start with copy of parastics to reinterpret
681+
newPara.convertParam('S');
682+
sdb.setParasitics(newPara);
683+
684+
// Output Common Instrumentation Transfer and Interchange file (CITIfile)
685+
string outCITIFile = argv[4];
686+
vector<size_t> indLayerPrint = { 0, 1 * sdb.getNumLayer() / 3, 2 * sdb.getNumLayer() / 3, sdb.getNumLayer() - 1 }; // {}; // Can use integer division
687+
sdb.setDesignName(adb.findNames().back());
688+
sdb.setOutCITI(outCITIFile);
689+
sdb.print(indLayerPrint);
690+
bool sdbCouldDump = sdb.dumpCITI();
691+
cout << "File ready at " << outCITIFile << endl;
692+
}
693+
else if ((strcmp(argv[1], "-ldt") == 0) || (strcmp(argv[1], "--lefdeftouchstone") == 0))
694+
{
695+
// Output Touchstone file
696+
string outTstoneFile = argv[4];
697+
vector<size_t> indLayerPrint = { 0, 1 * sdb.getNumLayer() / 3, 2 * sdb.getNumLayer() / 3, sdb.getNumLayer() - 1 }; // {}; // Can use integer division
698+
sdb.setDesignName(adb.findNames().back());
699+
sdb.setOutTouchstone(outTstoneFile);
700+
sdb.print(indLayerPrint);
701+
bool sdbCouldDump = sdb.dumpTouchstone();
702+
cout << "File ready at " << outTstoneFile << endl;
703+
}*/
704+
else
705+
{
706+
// Output Xyce subcircuit file
707+
string outXyceFile = argv[4];
708+
vector<size_t> indLayerPrint = { 0, sdb.getNumLayer() / 2, sdb.getNumLayer() - 1 }; // {}; // Can use integer division
709+
sdb.setDesignName(adb.findNames().back());
710+
sdb.setOutXyce(outXyceFile);
711+
sdb.print(indLayerPrint);
712+
sdbCouldDump = sdb.dumpXyce();
713+
cout << "File ready at " << outXyceFile << endl;
714+
}
715+
}
716+
else
717+
{
718+
cerr << "Must pass a GDSII file, sim_input file, a blank Xyce file to write, and LEF/DEF files after \"-ld\" or \"-ldx\" flag" << endl;
719+
cerr << "Must pass a GDSII file, sim_input file, a blank SPEF file to write, and LEF/DEF files after \"-ldp\" flag" << endl;
720+
cerr << "Rerun with \"--help\" flag for details" << endl;
721+
}
722+
}
449723
else
450724
{
451725
cerr << "Between 1 and 4 arguments are required, use \"--help\" flag for details" << endl;

0 commit comments

Comments
 (0)