@@ -50,6 +50,7 @@ int main(int argc, char** argv)
50
50
cout << " -sp, --spef Read GDSII and sim input files into memory, simulate, and write solution to SPEF file." << endl;
51
51
cout << " -sc, --citi Read GDSII and sim input files into memory, simulate, and write solution to CITIfile." << endl;
52
52
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;
53
54
cout << endl << " Comments:" << endl;
54
55
cout << " The file passed after -r, --read, -p, or --parrot must be a Calma GDSII stream file." << endl;
55
56
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)
58
59
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;
59
60
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;
60
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 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;
62
64
cout << endl << " Bug reporting:" << endl;
63
65
cout << " Visit <https://github.com/purdue-onchip/gds2Para>" << endl;
64
66
}
@@ -446,6 +448,278 @@ int main(int argc, char** argv)
446
448
cerr << " Rerun with \" --help\" flag for details" << endl;
447
449
}
448
450
}
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
+ }
449
723
else
450
724
{
451
725
cerr << " Between 1 and 4 arguments are required, use \" --help\" flag for details" << endl;
0 commit comments