1 /*
2 * CCvcDb_main.cc
3 *
4 * Copyright 2014-2018 D. Mitch Bailey cvc at shuharisystem dot com
5 *
6 * This file is part of cvc.
7 *
8 * cvc is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * cvc is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with cvc. If not, see <http://www.gnu.org/licenses/>.
20 *
21 * You can download cvc from https://github.com/d-m-bailey/cvc.git
22 */
23
24 #include "Cvc.hh"
25 #include "CCdlParserDriver.hh"
26 #include "CCvcParameters.hh"
27 #include "CCircuit.hh"
28 #include "CCvcDb.hh"
29
30 #include "CDevice.hh"
31 #include "resource.hh"
32
33 /// \file
34 /// CVC main loop
35
36 /// \name interactive globals
37 ///@{
38 bool gInteractive_cvc = false; //!< interactive mode
39 int gContinueCount = 0; //!< number of stages to run before stopping; always stop after final stage
40 ///@}
41
42 rusage lastSnapshot; //!< resource usage tracking
43
44 // debugging variables for virtual net updates
45 long gVirtualNetAccessCount = 0;
46 long gVirtualNetUpdateCount = 0;
47
48 /**
49 * \brief Main Loop: Verify circuits using settings in each verification resource file.
50 *
51 * Verification resource files typically have a .cvcrc suffix.
52 */
VerifyCircuitForAllModes(int argc,const char * argv[])53 void CCvcDb::VerifyCircuitForAllModes(int argc, const char * argv[]) {
54 CCdlParserDriver cvcParserDriver;
55
56 cvcParameters.PrintDefaultEnvironment();
57 for ( ; cvcArgIndex < argc; cvcArgIndex++ ) { // loop through all cvcrc files on command line
58 /// Setup
59 gContinueCount = 0;
60 if ( ! cvcParameters.cvcPowerPtrList.empty() ) Cleanup();
61 RemoveLock();
62 detectErrorFlag = true;
63 cout << "CVC: Circuit Validation Check Version " << CVC_VERSION << endl;
64 cvcParameters.ResetEnvironment();
65 cvcParameters.LoadEnvironment(argv[cvcArgIndex], reportPrefix);
66 if ( ! LockReport(gInteractive_cvc) ) continue;
67 SetOutputFiles(cvcParameters.cvcReportFilename);
68 logFile << "CVC: Circuit Validation Check Version " << CVC_VERSION << endl;
69 reportFile << "CVC: Start: " << CurrentTime() << endl;
70 TakeSnapshot(&lastSnapshot);
71 cvcParameters.PrintEnvironment(reportFile);
72 /// Read model and power settings.
73 modelFileStatus = cvcParameters.LoadModels();
74 powerFileStatus = cvcParameters.LoadPower();
75 if ( modelFileStatus != OK || powerFileStatus != OK ) { // Catch syntax problems before reading netlist
76 if ( ! gInteractive_cvc ) {
77 reportFile << "ERROR: skipped due to problems in model/power files" << endl;
78 continue;
79 }
80 }
81
82 /// Read netlist
83 if ( cvcParameters.IsSameDatabase() ) {
84 reportFile << "CVC: Reusing " << cvcParameters.cvcTopBlock << " of "
85 << cvcParameters.cvcNetlistFilename << endl;
86 // TODO: Reset error limits for cells
87 /*
88 if ( isDeviceModelSet ) {
89 ResetMosFuse();
90 }
91 */
92 } else {
93 reportFile << "CVC: Parsing netlist " << cvcParameters.cvcNetlistFilename << endl;
94 cvcCircuitList.Clear();
95 instancePtr_v.Clear();
96 if (cvcParserDriver.parse (cvcParameters.cvcNetlistFilename, cvcCircuitList,
97 cvcParameters.cvcSOI ) != 0 ) {
98 throw EFatalError("Could not parse " + cvcParameters.cvcNetlistFilename);
99 }
100 if (cvcCircuitList.errorCount > 0 || cvcCircuitList.warningCount > 0) {
101 reportFile << "WARNING: unsupported devices in netlist" << endl;
102 }
103 cvcParameters.SaveDatabaseParameters();
104 reportFile << "Cdl fixed data size " << cvcCircuitList.cdlText.Size() << endl;
105 reportFile << PrintProgress(&lastSnapshot, "CDL") << endl;
106 LoadCellChecksums();
107 CountObjectsAndLinkSubcircuits();
108 AssignGlobalIDs();
109 LoadNetChecks();
110 LoadModelChecks();
111 PrintLargeCircuits();
112 reportFile << PrintProgress(&lastSnapshot, "DB") << endl;
113 }
114 returnCode_t myCellErrorLimitStatus = LoadCellErrorLimits();
115 if ( myCellErrorLimitStatus != OK ) {
116 throw EFatalError("Could not load " + cvcParameters.cvcCellErrorLimitFile);
117 }
118 reportFile << "CVC: " << topCircuit_p->subcircuitCount << "(" << subcircuitCount << ") instances, "
119 << topCircuit_p->netCount << "(" << netCount << ") nets, "
120 << topCircuit_p->deviceCount << "(" << deviceCount << ") devices." << endl;
121
122 /// Stage 1) Set power and model
123 if ( powerFileStatus == OK ) {
124 cout << "Setting power for mode..." << endl;
125 powerFileStatus = SetModePower();
126 }
127 if ( modelFileStatus == OK ) {
128 cout << "Setting models..." << endl;
129 modelFileStatus = SetDeviceModels();
130 }
131 if ( modelFileStatus == OK ) {
132 fuseFileStatus = CheckFuses();
133 } else {
134 fuseFileStatus = FAIL;
135 }
136 if ( gInteractive_cvc && --gContinueCount < 1
137 && InteractiveCvc(STAGE_START) == SKIP ) continue;
138 if ( modelFileStatus != OK || powerFileStatus != OK || fuseFileStatus != OK ) {
139 if ( gSetup_cvc ) {
140 reportFile << endl << "CVC: Setup check complete." << endl;
141 } else {
142 reportFile << "ERROR: skipped due to problems in model/power/fuse files" << endl;
143 }
144 continue;
145 }
146
147 /// Stage 2) Create database
148 ResetMinSimMaxAndQueues();
149 SetEquivalentNets();
150 if ( SetInstancePower() != OK || SetExpectedPower() != OK ) {
151 reportFile << "ERROR: skipped due to problems in power files" << endl;
152 continue;
153 }
154 cvcParameters.cvcPowerPtrList.SetFamilies(cvcParameters.cvcPowerFamilyMap);
155 cvcParameters.SetHiZPropagation();
156 cvcParameters.cvcModelListMap.Print(logFile);
157 PrintPowerList(logFile, "Power List");
158 cvcParameters.cvcPowerPtrList.SetPowerLimits(maxPower, minPower);
159 LinkDevices();
160 OverrideFuses();
161 mosDiodeSet.clear();
162 if ( gSetup_cvc ) {
163 PrintNetSuggestions();
164 }
165 reportFile << PrintProgress(&lastSnapshot, "EQUIV") << endl;
166 reportFile << "Power nets " << CPower::powerCount << endl;
167 // DumpStatistics(parameterModelPtrMap, "parameter->model map", logFile);
168 DumpStatistics(parameterResistanceMap, "parameter->resistance map", logFile);
169 DumpStatistics(cvcCircuitList.circuitNameMap, "text->circuit map", logFile);
170 DumpStatistics(cvcCircuitList.cdlText.fixedTextToAddressMap, "string->text map", logFile);
171 if ( gInteractive_cvc && --gContinueCount < 1 && InteractiveCvc(STAGE_LINK) == SKIP ) {
172 continue;
173 }
174
175 /// Stage 3) Calculate voltages across resistors
176 /// - Calculated resistance
177 ShortNonConductingResistors();
178 // SetResistorVoltagesForMosSwitches();
179 SetResistorVoltagesByPower();
180 reportFile << PrintProgress(&lastSnapshot, "RES") << endl;
181 reportFile << "Power nets " << CPower::powerCount << endl;
182 if ( gInteractive_cvc && --gContinueCount < 1
183 && InteractiveCvc(STAGE_RESISTANCE) == SKIP ) continue;
184
185 /// Stage 4) First min/max propagation\n
186 /// - unexpected min/max values\n
187 /// - forward bias diode errors\n
188 /// - NMOS source-bulk errors\n
189 /// - NMOS gate-source errors\n
190 /// - PMOS source-bulk errors\n
191 /// - PMOS gate-source errors\n
192 ResetMinMaxPower();
193 SetAnalogNets();
194 reportFile << PrintProgress(&lastSnapshot, "MIN/MAX1") << endl;
195 reportFile << "Power nets " << CPower::powerCount << endl;
196 if ( detectErrorFlag ) {
197 if ( ! cvcParameters.cvcLogicDiodes ) {
198 FindForwardBiasDiodes();
199 }
200 if ( ! cvcParameters.cvcSOI ) {
201 FindNmosSourceVsBulkErrors();
202 }
203 if ( ! gSetup_cvc ) {
204 FindNmosGateVsSourceErrors();
205 }
206 if ( ! cvcParameters.cvcSOI ) {
207 FindPmosSourceVsBulkErrors();
208 }
209 if ( ! gSetup_cvc ) {
210 FindPmosGateVsSourceErrors();
211 }
212 reportFile << PrintProgress(&lastSnapshot, "ERROR") << endl;
213 }
214 if ( gInteractive_cvc && --gContinueCount < 1
215 && InteractiveCvc(STAGE_FIRST_MINMAX) == SKIP ) continue;
216 if ( gSetup_cvc ) continue;
217
218 /// Stage 5) First sim propagation\n
219 /// - missing bulk connection check
220 SaveMinMaxLeakVoltages();
221 SetSimPower(POWER_NETS_ONLY);
222 cvcCircuitList.PrintAndResetCircuitErrors(this, cvcParameters.cvcCircuitErrorLimit, logFile, errorFile, "! Logic shorts 1");
223 reportFile << PrintProgress(&lastSnapshot, "SIM1") << endl;
224 reportFile << "Power nets " << CPower::powerCount << endl;
225 if ( ! cvcParameters.cvcSOI ) {
226 CheckConnections();
227 }
228 if ( gInteractive_cvc && --gContinueCount < 1
229 && InteractiveCvc(STAGE_FIRST_SIM) == SKIP ) continue;
230 SaveInitialVoltages();
231 if ( gDebug_cvc ) {
232 PrintAllVirtualNets<CVirtualNetVector>(
233 minNet_v, simNet_v, maxNet_v, "(1)");
234 }
235
236 /// Stage 6) Second sim propagation\n
237 /// - LDD connection errors
238 if ( cvcParameters.cvcSCRC ) {
239 SetSCRCPower();
240 }
241 SetSimPower(ALL_NETS_AND_FUSE);
242 reportFile << PrintProgress(&lastSnapshot, "SIM2") << endl;
243 reportFile << "Power nets " << CPower::powerCount << endl;
244 CNetIdSet myNewNetSet;
245 vector<bool> myIgnoreNet_v(simNet_v.size(), false);
246 int myPassCount = 0;
247 while ( SetLatchPower(++myPassCount, myIgnoreNet_v, myNewNetSet) ) {
248 SetSimPower(ALL_NETS_AND_FUSE, myNewNetSet);
249 reportFile << PrintProgress(&lastSnapshot, "LATCH " + to_string(myPassCount)) << endl;
250 }
251 cvcCircuitList.PrintAndResetCircuitErrors(this, cvcParameters.cvcCircuitErrorLimit, logFile, errorFile, "! Logic shorts 2");
252 if ( detectErrorFlag ) {
253 FindLDDErrors();
254 // FindForwardBiasDiodes();
255 }
256 if ( gInteractive_cvc && --gContinueCount < 1
257 && InteractiveCvc(STAGE_SECOND_SIM) == SKIP ) continue;
258
259 /// Stage 7) Second min/max propagation\n
260 /// - overvoltage errors\n
261 /// - NMOS possible leak errors\n
262 /// - PMOS possible leak errors\n
263 /// - floating gate errors\n
264 /// - expected value errors
265 ResetMinMaxPower();
266 SetInverters();
267 reportFile << PrintProgress(&lastSnapshot, "MIN/MAX2") << endl;
268 reportFile << "Power nets " << CPower::powerCount << endl;
269 if ( detectErrorFlag ) {
270 if ( cvcParameters.cvcLogicDiodes ) {
271 FindForwardBiasDiodes();
272 }
273 FindAllOverVoltageErrors();
274 FindNmosPossibleLeakErrors();
275 FindPmosPossibleLeakErrors();
276 FindFloatingInputErrors();
277 CheckExpectedValues();
278 }
279 PrintErrorTotals();
280 // PrintShortedNets(cvcParameters.cvcReportBaseFilename + ".shorts.gz");
281 reportFile << PrintProgress(&lastSnapshot, "Total") << endl;
282 if ( gDebug_cvc ) {
283 PrintAllVirtualNets<CVirtualNetVector>(minNet_v, simNet_v, maxNet_v, "(3)");
284 cvcCircuitList.Print("", "CVC Full Circuit List");
285 cvcParameters.cvcModelListMap.DebugPrint();
286 Print("", "CVC Database");
287 PrintFlatCdl();
288 }
289 reportFile << "Virtual net update/access " << gVirtualNetUpdateCount << "/"
290 << gVirtualNetAccessCount << endl;
291 reportFile << "CVC: Log output to " << cvcParameters.cvcReportFilename << endl;
292 reportFile << "CVC: End: " << CurrentTime() << endl;
293 errorFile.close();
294 debugFile.close();
295 if ( gInteractive_cvc ) InteractiveCvc(STAGE_COMPLETE);
296
297 /// Clean-up
298 logFile.close();
299 }
300 Cleanup();
301 }
302
303
304
305