1 /*
2 * Copyright (c) D. Mitch Bailey 2014.
3 *
4 * Copyright 2014-2019 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 "CCvcParameters.hh"
25
26 #include "wordexp.h"
27 #include "gzstream.h"
28
CvcFileName()29 string CCvcParameters::CvcFileName() {
30 return cvcNetlistFilename;
31 }
32
IsSameDatabase()33 bool CCvcParameters::IsSameDatabase() {
34 return(cvcLastTopBlock == cvcTopBlock && cvcLastNetlistFilename == cvcNetlistFilename && cvcLastSOI == cvcSOI);
35 }
36
SaveDatabaseParameters()37 void CCvcParameters::SaveDatabaseParameters() {
38 cvcLastTopBlock = cvcTopBlock;
39 cvcLastNetlistFilename = cvcNetlistFilename;
40 cvcLastSOI = cvcSOI;
41 }
42
ResetEnvironment()43 void CCvcParameters::ResetEnvironment() {
44 //! Sets CVC environment variables to defaults.
45
46 // cvcLastTopBlock = cvcTopBlock;
47 // cvcLastNetlistFilename = cvcNetlistFilename;
48 // cvcLastSOI = cvcSOI;
49 /*!
50 * cvcLast* variables uniquely identify the last CDL file input.
51 * If these values are the same for the next run,
52 * the current database is used and the CDL file is NOT reread.
53 */
54 cvcTopBlock = "";
55 cvcNetlistFilename = "";
56 cvcModelFilename = "";
57 cvcPowerFilename = "";
58 cvcFuseFilename = "";
59 //! The cvcFuseFilename is an optional parameter used to override the type (fuse_on/fuse_off) of specific fuses.
60 //! The fuse file can be created from the interactive menu command 'dumpfuse filename'.
61 cvcReportFilename = "";
62 cvcReportTitle = "";
63 cvcCircuitErrorLimit = defaultErrorLimit;
64 //! Default error limit for a given error at a given device in a given circuit is cvcCircuitErrorLimit (default 100).
65 //! Once the error limit is exceeded, specific device information is NOT printed.
66 cvcLeakLimit = defaultLeakLimit;
67 //! Leak errors involving overridden or calculated voltages are flagged if the leak current is >= cvcLeakLimit (default 200uA).
68 cvcSOI = defaultSOI;
69 //! cvcSOI (Silicon-On-Insolator) is false for 4 terminal (D-G-S-B) mos.
70 //! To ignore the bulk connection and corresponding errors, set cvcSOI = true;
71 cvcSCRC = defaultSCRC;
72 //! cvcSCRC (Sub-threshhold Current Reduction Circuit)
73 //! When true, calculates expected SCRC levels after first propagation.
74 cvcVthGates = defaultVthGates;
75 //! When true, detects calculated gate-source errors at Vth. Default is to ignore calculated voltage errors at exactly Vth.
76 cvcMinVthGates = defaultMinVthGates;
77 //! When true, detect gate-source errors only if >= Vth. Default is to detect errors regardless of Vth.
78 cvcIgnoreVthFloating = defaultIgnoreVthFloating;
79 //! When true, ignore Hi-Z errors if max gate-source difference does not exceed Vth. Default is to detect errors regardless of Vth.
80 cvcIgnoreNoLeakFloating = defaultIgnoreNoLeakFloating;
81 //! When true, ignore Hi-Z errors if there is no leak. Default is to detect unconnected gates even if there is no leak path.
82 cvcLeakOvervoltage = defaultLeakOvervoltage;
83 //! When true, detects worst case overvoltage errors. Default is to flag all errors including those not possible with current mode logic.
84 cvcLogicDiodes = defaultLogicDiodes;
85 //! When true, uses logic values, if known, for diode checks. Default is to ignore logic values.
86 cvcAnalogGates = defaultAnalogGates;
87 //! When false, ignore errors from analog gates. Default is to use analog values.
88 cvcBackupResults = defaultBackupResults;
89 //! When true, backup log and error file. Default is to not create backups.
90 cvcMosDiodeErrorThreshold = defaultErrorThreshold;
91 cvcShortErrorThreshold = defaultErrorThreshold;
92 cvcBiasErrorThreshold = defaultErrorThreshold;
93 cvcForwardErrorThreshold = defaultErrorThreshold;
94 cvcFloatingErrorThreshold = defaultErrorThreshold;
95 cvcGateErrorThreshold = defaultErrorThreshold;
96 cvcLeakErrorThreshold = defaultErrorThreshold;
97 cvcExpectedErrorThreshold = defaultErrorThreshold;
98 cvcOvervoltageErrorThreshold = defaultErrorThreshold;
99 //! Ignore errors with voltage difference less than the threshold. Default is 0, flag errors regardless of voltage difference.
100 cvcParallelCircuitPortLimit = defaultParallelCircuitPortLimit;
101 //! Port count limit for parallel cell processing
102 cvcCellErrorLimitFile = defaultCellErrorLimitFile;
103 //! Name of file containing list of cells with error limits
104 cvcCellChecksumFile = defaultCellChecksumFile;
105 //! Name of file containing list of checksums for each circuit
106 cvcLargeCircuitSize = defaultLargeCircuitSize;
107 //! Minimum device count to display large circuits
108 cvcNetCheckFile = defaultNetCheckFile;
109 //! Name of file containing list of net checks
110 cvcModelCheckFile = defaultModelCheckFile;
111 //! Name of file containing list of model checks
112 }
113
PrintEnvironment(ostream & theOutputFile)114 void CCvcParameters::PrintEnvironment(ostream & theOutputFile) {
115 theOutputFile << "Using the following parameters for CVC (Circuit Validation Check) from " << cvcParamterFilename << endl;
116 theOutputFile << "CVC_TOP = '" << cvcTopBlock << "'" << endl;
117 theOutputFile << "CVC_NETLIST = '" << cvcNetlistFilename << "'" << endl;
118 theOutputFile << "CVC_MODE = '" << cvcMode << "'" << endl;
119 theOutputFile << "CVC_MODEL_FILE = '" << cvcModelFilename << "'" << endl;
120 theOutputFile << "CVC_POWER_FILE = '" << cvcPowerFilename << "'" << endl;
121 theOutputFile << "CVC_FUSE_FILE = '" << cvcFuseFilename << "'" << endl;
122 theOutputFile << "CVC_REPORT_FILE = '" << cvcReportFilename << "'" << endl;
123 theOutputFile << "CVC_REPORT_TITLE = '" << cvcReportTitle << "'" << endl;
124 theOutputFile << "CVC_CIRCUIT_ERROR_LIMIT = '" << cvcCircuitErrorLimit << "'" << endl;
125 theOutputFile << "CVC_SEARCH_LIMIT = '" << cvcSearchLimit << "'" << endl;
126 theOutputFile << "CVC_LEAK_LIMIT = '" << cvcLeakLimit << "'" << endl;
127 theOutputFile << "CVC_SOI = '" << (( cvcSOI ) ? "true" : "false") << "'" << endl;
128 theOutputFile << "CVC_SCRC = '" << (( cvcSCRC ) ? "true" : "false") << "'" << endl;
129 theOutputFile << "CVC_VTH_GATES = '" << (( cvcVthGates ) ? "true" : "false") << "'" << endl;
130 theOutputFile << "CVC_MIN_VTH_GATES = '" << (( cvcMinVthGates ) ? "true" : "false") << "'" << endl;
131 theOutputFile << "CVC_IGNORE_VTH_FLOATING = '" << (( cvcIgnoreVthFloating ) ? "true" : "false") << "'" << endl;
132 theOutputFile << "CVC_IGNORE_NO_LEAK_FLOATING = '" << (( cvcIgnoreNoLeakFloating ) ? "true" : "false") << "'" << endl;
133 theOutputFile << "CVC_LEAK_OVERVOLTAGE = '" << (( cvcLeakOvervoltage ) ? "true" : "false") << "'" << endl;
134 theOutputFile << "CVC_LOGIC_DIODES = '" << (( cvcLogicDiodes ) ? "true" : "false") << "'" << endl;
135 theOutputFile << "CVC_ANALOG_GATES = '" << (( cvcAnalogGates ) ? "true" : "false") << "'" << endl;
136 theOutputFile << "CVC_BACKUP_RESULTS = '" << (( cvcBackupResults ) ? "true" : "false") << "'" << endl;
137 theOutputFile << "CVC_MOS_DIODE_ERROR_THRESHOLD = '" << Voltage_to_float(cvcMosDiodeErrorThreshold) << "'" << endl;
138 theOutputFile << "CVC_SHORT_ERROR_THRESHOLD = '" << Voltage_to_float(cvcShortErrorThreshold) << "'" << endl;
139 theOutputFile << "CVC_BIAS_ERROR_THRESHOLD = '" << Voltage_to_float(cvcBiasErrorThreshold) << "'" << endl;
140 theOutputFile << "CVC_FORWARD_ERROR_THRESHOLD = '" << Voltage_to_float(cvcForwardErrorThreshold) << "'" << endl;
141 theOutputFile << "CVC_FLOATING_ERROR_THRESHOLD = '" << Voltage_to_float(cvcFloatingErrorThreshold) << "'" << endl;
142 theOutputFile << "CVC_GATE_ERROR_THRESHOLD = '" << Voltage_to_float(cvcGateErrorThreshold) << "'" << endl;
143 theOutputFile << "CVC_LEAK?_ERROR_THRESHOLD = '" << Voltage_to_float(cvcLeakErrorThreshold) << "'" << endl;
144 theOutputFile << "CVC_EXPECTED_ERROR_THRESHOLD = '" << Voltage_to_float(cvcExpectedErrorThreshold) << "'" << endl;
145 theOutputFile << "CVC_OVERVOLTAGE_ERROR_THRESHOLD = '" << Voltage_to_float(cvcOvervoltageErrorThreshold) << "'" << endl;
146 theOutputFile << "CVC_PARALLEL_CIRCUIT_PORT_LIMIT = '" << cvcParallelCircuitPortLimit << "'" << endl;
147 theOutputFile << "CVC_CELL_ERROR_LIMIT_FILE = '" << cvcCellErrorLimitFile << "'" << endl;
148 theOutputFile << "CVC_CELL_CHECKSUM_FILE = '" << cvcCellChecksumFile << "'" << endl;
149 theOutputFile << "CVC_LARGE_CIRCUIT_SIZE = '" << cvcLargeCircuitSize << "'" << endl;
150 theOutputFile << "CVC_NET_CHECK_FILE = '" << cvcNetCheckFile << "'" << endl;
151 theOutputFile << "CVC_MODEL_CHECK_FILE = '" << cvcModelCheckFile << "'" << endl;
152 theOutputFile << "End of parameters" << endl << endl;
153 }
154
PrintDefaultEnvironment()155 void CCvcParameters::PrintDefaultEnvironment() {
156 string myDefaultCvcrcFilename = "default.cvcrc";
157 ifstream myTemporaryCvcrc(myDefaultCvcrcFilename);
158 if ( myTemporaryCvcrc.good() ) return; // file exists, do nothing
159 ofstream myDefaultCvcrc(myDefaultCvcrcFilename);
160 if ( myDefaultCvcrc.fail() ) return; // ignore errors
161
162 cout << "Default cvcrc in " << myDefaultCvcrcFilename << endl;
163 myDefaultCvcrc << "CVC_TOP = '" << cvcTopBlock << "'" << endl;
164 myDefaultCvcrc << "CVC_NETLIST = '" << cvcNetlistFilename << "'" << endl;
165 myDefaultCvcrc << "CVC_MODE = '" << cvcMode << "'" << endl;
166 myDefaultCvcrc << "CVC_MODEL_FILE = '" << cvcModelFilename << "'" << endl;
167 myDefaultCvcrc << "CVC_POWER_FILE = '" << cvcPowerFilename << "'" << endl;
168 myDefaultCvcrc << "CVC_FUSE_FILE = '" << cvcFuseFilename << "'" << endl;
169 myDefaultCvcrc << "CVC_REPORT_FILE = '" << cvcReportFilename << "'" << endl;
170 myDefaultCvcrc << "CVC_REPORT_TITLE = '" << cvcReportTitle << "'" << endl;
171 myDefaultCvcrc << "CVC_CIRCUIT_ERROR_LIMIT = '" << cvcCircuitErrorLimit << "'" << endl;
172 myDefaultCvcrc << "CVC_SEARCH_LIMIT = '" << cvcSearchLimit << "'" << endl;
173 myDefaultCvcrc << "CVC_LEAK_LIMIT = '" << cvcLeakLimit << "'" << endl;
174 myDefaultCvcrc << "CVC_SOI = '" << (( cvcSOI ) ? "true" : "false") << "'" << endl;
175 myDefaultCvcrc << "CVC_SCRC = '" << (( cvcSCRC ) ? "true" : "false") << "'" << endl;
176 myDefaultCvcrc << "CVC_VTH_GATES = '" << (( cvcVthGates ) ? "true" : "false") << "'" << endl;
177 myDefaultCvcrc << "CVC_MIN_VTH_GATES = '" << (( cvcMinVthGates ) ? "true" : "false") << "'" << endl;
178 myDefaultCvcrc << "CVC_IGNORE_VTH_FLOATING = '" << (( cvcIgnoreVthFloating ) ? "true" : "false") << "'" << endl;
179 myDefaultCvcrc << "CVC_IGNORE_NO_LEAK_FLOATING = '" << (( cvcIgnoreNoLeakFloating ) ? "true" : "false") << "'" << endl;
180 myDefaultCvcrc << "CVC_LEAK_OVERVOLTAGE = '" << (( cvcLeakOvervoltage ) ? "true" : "false") << "'" << endl;
181 myDefaultCvcrc << "CVC_LOGIC_DIODES = '" << (( cvcLogicDiodes ) ? "true" : "false") << "'" << endl;
182 myDefaultCvcrc << "CVC_ANALOG_GATES = '" << (( cvcAnalogGates ) ? "true" : "false") << "'" << endl;
183 myDefaultCvcrc << "CVC_BACKUP_RESULTS = '" << (( cvcBackupResults ) ? "true" : "false") << "'" << endl;
184 myDefaultCvcrc << "CVC_MOS_DIODE_ERROR_THRESHOLD = '" << Voltage_to_float(cvcMosDiodeErrorThreshold) << "'" << endl;
185 myDefaultCvcrc << "CVC_SHORT_ERROR_THRESHOLD = '" << Voltage_to_float(cvcShortErrorThreshold) << "'" << endl;
186 myDefaultCvcrc << "CVC_BIAS_ERROR_THRESHOLD = '" << Voltage_to_float(cvcBiasErrorThreshold) << "'" << endl;
187 myDefaultCvcrc << "CVC_FORWARD_ERROR_THRESHOLD = '" << Voltage_to_float(cvcForwardErrorThreshold) << "'" << endl;
188 myDefaultCvcrc << "CVC_FLOATING_ERROR_THRESHOLD = '" << Voltage_to_float(cvcFloatingErrorThreshold) << "'" << endl;
189 myDefaultCvcrc << "CVC_GATE_ERROR_THRESHOLD = '" << Voltage_to_float(cvcGateErrorThreshold) << "'" << endl;
190 myDefaultCvcrc << "CVC_LEAK?_ERROR_THRESHOLD = '" << Voltage_to_float(cvcLeakErrorThreshold) << "'" << endl;
191 myDefaultCvcrc << "CVC_EXPECTED_ERROR_THRESHOLD = '" << Voltage_to_float(cvcExpectedErrorThreshold) << "'" << endl;
192 myDefaultCvcrc << "CVC_OVERVOLTAGE_ERROR_THRESHOLD = '" << Voltage_to_float(cvcOvervoltageErrorThreshold) << "'" << endl;
193 myDefaultCvcrc << "CVC_PARALLEL_CIRCUIT_PORT_LIMIT = '" << cvcParallelCircuitPortLimit << "'" << endl;
194 myDefaultCvcrc << "CVC_CELL_ERROR_LIMIT_FILE = '" << cvcCellErrorLimitFile << "'" << endl;
195 myDefaultCvcrc << "CVC_CELL_CHECKSUM_FILE = '" << cvcCellChecksumFile << "'" << endl;
196 myDefaultCvcrc << "CVC_LARGE_CIRCUIT_SIZE = '" << cvcLargeCircuitSize << "'" << endl;
197 myDefaultCvcrc << "CVC_NET_CHECK_FILE = '" << cvcNetCheckFile << "'" << endl;
198 myDefaultCvcrc << "CVC_MODEL_CHECK_FILE = '" << cvcModelCheckFile << "'" << endl;
199 myDefaultCvcrc.close();
200 }
201
LoadEnvironment(const string theEnvironmentFilename,const string theReportPrefix)202 void CCvcParameters::LoadEnvironment(const string theEnvironmentFilename, const string theReportPrefix) {
203 //! Set CVC environment variables from cvcrc file.
204 /*!
205 * CVC environment files can access and define shell environment variables.
206 */
207 ifstream myEnvironmentFile(theEnvironmentFilename);
208 if ( myEnvironmentFile.fail() ) {
209 throw EFatalError("Could not open " + theEnvironmentFilename);
210 }
211 cvcParamterFilename = theEnvironmentFilename;
212 string myTuple, myVariable, myValue;
213 char myBuffer[1024];
214
215 while ( getline(myEnvironmentFile, myTuple) ) {
216 if ( myTuple[0] == '#' ) continue; // skip comments
217 if ( myTuple.find_first_not_of(" \t\n") > myTuple.length() ) continue; // skip blank lines
218 if ( myTuple.find("=") > myTuple.length() ) {
219 cout << "Invalid environment setting: " << myTuple << endl;
220 throw EBadEnvironment();
221 }
222 myVariable = trim_(myTuple.substr(0, myTuple.find("=")));
223 myValue = trim_(myTuple.substr(myTuple.find("=") + 1));
224 string myEchoCommand = "echo " + myValue;
225 FILE * myEcho = popen(myEchoCommand.c_str(), "r");
226 fgets(myBuffer, 1024, myEcho);
227 myBuffer[strlen(myBuffer) - 1] = '\0';
228 setenv(myVariable.c_str(), myBuffer, 1);
229 pclose(myEcho);
230 if ( myVariable == "CVC_TOP" ) {
231 cvcTopBlock = myBuffer;
232 } else if ( myVariable == "CVC_NETLIST" ) {
233 cvcNetlistFilename = myBuffer;
234 } else if ( myVariable == "CVC_MODE" ) {
235 cvcMode = myBuffer;
236 } else if ( myVariable == "CVC_MODEL_FILE" ) {
237 cvcModelFilename = myBuffer;
238 } else if ( myVariable == "CVC_POWER_FILE" ) {
239 cvcPowerFilename = myBuffer;
240 } else if ( myVariable == "CVC_FUSE_FILE" ) {
241 cvcFuseFilename = myBuffer;
242 } else if ( myVariable == "CVC_REPORT_FILE" ) {
243 cvcReportFilename = myBuffer;
244 if ( cvcReportFilename.find_first_of("\\/") < cvcReportFilename.length() ) {
245 cvcReportDirectory = cvcReportFilename.substr(0, cvcReportFilename.find_last_of("\\/") + 1);
246 cvcReportName = cvcReportFilename.substr(cvcReportFilename.find_last_of("\\/") + 1);
247 } else {
248 cvcReportDirectory = "";
249 cvcReportName = cvcReportFilename;
250 }
251 } else if ( myVariable == "CVC_REPORT_TITLE" ) {
252 cvcReportTitle = myBuffer;
253 } else if ( myVariable == "CVC_CIRCUIT_ERROR_LIMIT" ) {
254 cvcCircuitErrorLimit = from_string<deviceId_t>(myBuffer);
255 } else if ( myVariable == "CVC_LEAK_LIMIT" ) {
256 cvcLeakLimit = from_string<float>(myBuffer);
257 } else if ( myVariable == "CVC_SEARCH_LIMIT" ) {
258 cvcSearchLimit = from_string<int>(myBuffer);
259 } else if ( myVariable == "CVC_SOI" ) {
260 cvcSOI = strcasecmp(myBuffer, "true") == 0;
261 } else if ( myVariable == "CVC_SCRC" ) {
262 cvcSCRC = strcasecmp(myBuffer, "true") == 0;
263 } else if ( myVariable == "CVC_VTH_GATES" ) {
264 cvcVthGates = strcasecmp(myBuffer, "true") == 0;
265 } else if ( myVariable == "CVC_MIN_VTH_GATES" ) {
266 cvcMinVthGates = strcasecmp(myBuffer, "true") == 0;
267 } else if ( myVariable == "CVC_IGNORE_VTH_FLOATING" ) {
268 cvcIgnoreVthFloating = strcasecmp(myBuffer, "true") == 0;
269 } else if ( myVariable == "CVC_IGNORE_NO_LEAK_FLOATING" ) {
270 cvcIgnoreNoLeakFloating = strcasecmp(myBuffer, "true") == 0;
271 } else if ( myVariable == "CVC_LEAK_OVERVOLTAGE" ) {
272 cvcLeakOvervoltage = strcasecmp(myBuffer, "true") == 0;
273 } else if ( myVariable == "CVC_LOGIC_DIODES" ) {
274 cvcLogicDiodes = strcasecmp(myBuffer, "true") == 0;
275 } else if ( myVariable == "CVC_ANALOG_GATES" ) {
276 cvcAnalogGates = strcasecmp(myBuffer, "true") == 0;
277 } else if ( myVariable == "CVC_BACKUP_RESULTS" ) {
278 cvcBackupResults = strcasecmp(myBuffer, "true") == 0;
279 } else if ( myVariable == "CVC_MOS_DIODE_ERROR_THRESHOLD" ) {
280 cvcMosDiodeErrorThreshold = String_to_Voltage(string(myBuffer));
281 } else if ( myVariable == "CVC_SHORT_ERROR_THRESHOLD" ) {
282 cvcShortErrorThreshold = String_to_Voltage(string(myBuffer));
283 } else if ( myVariable == "CVC_BIAS_ERROR_THRESHOLD" ) {
284 cvcBiasErrorThreshold = String_to_Voltage(string(myBuffer));
285 } else if ( myVariable == "CVC_FORWARD_ERROR_THRESHOLD" ) {
286 cvcForwardErrorThreshold = String_to_Voltage(string(myBuffer));
287 } else if ( myVariable == "CVC_FLOATING_ERROR_THRESHOLD" ) {
288 cvcFloatingErrorThreshold = String_to_Voltage(string(myBuffer));
289 } else if ( myVariable == "CVC_GATE_ERROR_THRESHOLD" ) {
290 cvcGateErrorThreshold = String_to_Voltage(string(myBuffer));
291 } else if ( myVariable == "CVC_LEAK?_ERROR_THRESHOLD" ) {
292 cvcLeakErrorThreshold = String_to_Voltage(string(myBuffer));
293 } else if ( myVariable == "CVC_EXPECTED_ERROR_THRESHOLD" ) {
294 cvcExpectedErrorThreshold = String_to_Voltage(string(myBuffer));
295 } else if ( myVariable == "CVC_OVERVOLTAGE_ERROR_THRESHOLD" ) {
296 cvcOvervoltageErrorThreshold = String_to_Voltage(string(myBuffer));
297 } else if ( myVariable == "CVC_PARALLEL_CIRCUIT_PORT_LIMIT" ) {
298 cvcParallelCircuitPortLimit = from_string<int>(myBuffer);
299 if ( cvcParallelCircuitPortLimit > MAX_PARALLEL_CIRCUIT_PORT_LIMIT ) {
300 reportFile << "Warning: Parallel circuit port limit exceeds maximum " << cvcParallelCircuitPortLimit << " > " << MAX_PARALLEL_CIRCUIT_PORT_LIMIT << endl;
301 reportFile << "Parallel circuit port limit set to " << MAX_PARALLEL_CIRCUIT_PORT_LIMIT << endl;
302 cvcParallelCircuitPortLimit = MAX_PARALLEL_CIRCUIT_PORT_LIMIT;
303 }
304 } else if ( myVariable == "CVC_CELL_ERROR_LIMIT_FILE" ) {
305 cvcCellErrorLimitFile = myBuffer;
306 } else if ( myVariable == "CVC_CELL_CHECKSUM_FILE" ) {
307 cvcCellChecksumFile = myBuffer;
308 } else if ( myVariable == "CVC_LARGE_CIRCUIT_SIZE" ) {
309 cvcLargeCircuitSize = from_string<size_t>(myBuffer);
310 } else if ( myVariable == "CVC_NET_CHECK_FILE" ) {
311 cvcNetCheckFile = myBuffer;
312 } else if ( myVariable == "CVC_MODEL_CHECK_FILE" ) {
313 cvcModelCheckFile = myBuffer;
314 }
315 }
316 if ( ! IsEmpty(theReportPrefix) ) {
317 cvcReportName = theReportPrefix + "-" + cvcReportName;
318 }
319 cvcReportFilename = cvcReportDirectory + cvcReportName;
320 cvcLockFile = cvcReportDirectory + "." + cvcReportName;
321 myEnvironmentFile.close();
322 }
323
AddTestModels()324 void CCvcParameters::AddTestModels() {
325 cvcModelListMap.AddModel("NMOS N Vth=0.3 Vgs=1.2 Vds=1.2");
326 cvcModelListMap.AddModel("PMOS P Vth=-0.4 Vgs=1.2 Vds=1.2");
327 cvcModelListMap.AddModel("NMOS MN Vth=0.35 Vgs=5.0 Vds=5.0");
328 cvcModelListMap.AddModel("PMOS MP Vth=-0.45 Vgs=5.0 Vds=5.0");
329 cvcModelListMap.AddModel("CAPACITOR CAP Vds=1.2");
330 cvcModelListMap.AddModel("RESISTOR RES");
331 cvcModelListMap.AddModel("RESISTOR RESSW model=switch_on");
332 cvcModelListMap.AddModel("RESISTOR RESWON model=switch_on");
333 cvcModelListMap.AddModel("RESISTOR RESWOFF model=switch_off");
334 cvcModelListMap.AddModel("RESISTOR FUSEON model=fuse_on");
335 cvcModelListMap.AddModel("RESISTOR FUSEOFF model=fuse_off");
336 cvcModelListMap.AddModel("CAPACITOR CAPSW model=switch_off");
337 cvcModelListMap.AddModel("DIODE DIO");
338 }
339
LoadModels()340 returnCode_t CCvcParameters::LoadModels() {
341 ifstream myModelFile(cvcModelFilename);
342 cvcModelListMap.Clear();
343 cvcModelListMap.filename = cvcModelFilename;
344 if ( myModelFile.fail() ) {
345 if ( gSetup_cvc ) {
346 return(OK);
347 } else {
348 reportFile << "ERROR: Could not open " << cvcModelFilename << endl;
349 return (FAIL);
350 }
351 }
352 string myInput, myVariable, myValue;
353
354 reportFile << "CVC: Reading device model settings..." << endl;
355 cvcModelListMap.hasError = false;
356 while ( getline(myModelFile, myInput) ) {
357 if ( myInput[0] == '#' ) continue; // skip comments
358 if ( myInput.find_first_not_of(" \t\n") > myInput.length() ) continue; // skip blank lines
359 cvcModelListMap.AddModel(myInput);
360 }
361 myModelFile.close();
362 if ( cvcModelListMap.hasError ) {
363 reportFile << "Invalid model file" << endl;
364 return(SKIP);
365 } else {
366 return(OK);
367 }
368
369 }
370
LoadPower()371 returnCode_t CCvcParameters::LoadPower() {
372 igzstream myPowerFile;
373 myPowerFile.open(cvcPowerFilename);
374 cvcPowerPtrList.Clear();
375 cvcExpectedLevelPtrList.Clear();
376 cvcPowerFamilyMap.clear();
377 cvcPowerMacroPtrMap.clear();
378 if ( myPowerFile.fail() ) {
379 if ( gSetup_cvc ) {
380 return(OK);
381 } else {
382 reportFile << "ERROR: Could not open " << cvcPowerFilename << endl;
383 return (FAIL);
384 }
385 }
386 string myInput, myVariable, myValue;
387
388 reportFile << "CVC: Reading power settings..." << endl;
389 bool myPowerErrorFlag = false;
390 bool myAutoMacroFlag = true;
391 while ( getline(myPowerFile, myInput) ) {
392 try {
393 bool myIsMacro = ( myInput.substr(0, myInput.find_first_of(" \t", 0)) == "#define" );
394 bool myIsInstance = ( myInput.substr(0, myInput.find_first_of(" \t", 0)) == "#instance" );
395 if ( myInput == "#NO AUTO MACROS" ) myAutoMacroFlag = false;
396 if ( myInput[0] == '#' && ! (myIsMacro || myIsInstance) ) continue; // skip comments
397 if ( myInput.find_first_not_of(" \t\n") > myInput.length() ) continue; // skip blank lines
398 myInput = trim_(myInput);
399 string myMacroName = "";
400 string myMacroDefinition;
401 if ( myIsMacro ) {
402 myMacroDefinition = myInput.substr(myInput.find_first_not_of(" \t\n", 7));
403 if ( myMacroDefinition.substr(0, myMacroDefinition.find_first_of(" \t", 0)) == "family" ) {
404 cvcPowerFamilyMap.AddFamily(myMacroDefinition);
405 } else {
406 myMacroName = myMacroDefinition.substr(0, myMacroDefinition.find_first_of(" \t", 0));
407 }
408 } else if ( myIsInstance ) {
409 cvcInstancePowerPtrList.push_back(new CInstancePower(myInput));
410 } else {
411 CPower * myPowerPtr = new CPower(myInput, cvcPowerMacroPtrMap, cvcModelListMap);
412 if ( ! (IsEmpty(myPowerPtr->expectedMin()) && IsEmpty(myPowerPtr->expectedSim()) && IsEmpty(myPowerPtr->expectedMax())) ) {
413 cvcExpectedLevelPtrList.push_back(new CPower(myPowerPtr)); // duplicate CPower (not a bit-wise copy)
414 }
415 if (myPowerPtr->type != NO_TYPE || myPowerPtr->minVoltage != UNKNOWN_VOLTAGE || myPowerPtr->simVoltage != UNKNOWN_VOLTAGE || myPowerPtr->maxVoltage != UNKNOWN_VOLTAGE) {
416 cvcPowerPtrList.push_back(new CPower(myPowerPtr)); // duplicate CPower (not a bit-wise copy)
417 }
418 myMacroName = string(myPowerPtr->powerSignal());
419 if ( myMacroName[0] == '/' ) { // macros for top level nets that are not ports
420 myMacroName = myMacroName.substr(1);
421 }
422 myMacroDefinition = myInput;
423 delete myPowerPtr;
424 }
425 if ( myMacroName.find_first_of("(<[}/*@+-") > myMacroName.length() && isalpha(myMacroName[0]) ) { // no special characters in macro names
426 if ( cvcPowerMacroPtrMap.count(myMacroName) > 0 ) {
427 if ( myAutoMacroFlag ) {
428 throw EPowerError("duplicate macro name: " + myMacroName);
429 } else { // Ignore duplicate macro definitions when debugging subcircuits
430 continue;
431 }
432 }
433 cvcPowerMacroPtrMap[myMacroName] = new CPower(myMacroDefinition, cvcPowerMacroPtrMap, cvcModelListMap);
434 }
435 }
436 catch (const EPowerError& myException) {
437 reportFile << myException.what() << endl;
438 myPowerErrorFlag = true;
439 }
440 }
441 for ( auto instance_ppit = cvcInstancePowerPtrList.begin(); instance_ppit != cvcInstancePowerPtrList.end(); instance_ppit++ ) {
442 ifstream myInstancePowerFile((*instance_ppit)->powerFile);
443 if ( myInstancePowerFile.fail() ) {
444 reportFile << "ERROR: Could not open " << (*instance_ppit)->powerFile << endl;
445 return (FAIL);
446 }
447 while ( getline(myInstancePowerFile, myInput) ) {
448 if ( myInput[0] == '#' ) continue; // skip comments, macros, and instances (no instance in instance)
449 if ( myInput.find_first_not_of(" \t\n") > myInput.length() ) continue; // skip blank lines
450 myInput = trim_(myInput);
451 (*instance_ppit)->powerList.push_back(myInput);
452 }
453 myInstancePowerFile.close();
454 }
455 myPowerFile.close();
456 if ( myPowerErrorFlag ) {
457 reportFile << "Invalid power file: " << cvcPowerFilename << endl;
458 return (SKIP);
459 } else {
460 return (OK);
461 }
462 }
463
SetHiZPropagation()464 void CCvcParameters::SetHiZPropagation() {
465 for ( auto power_ppit = cvcPowerPtrList.begin(); power_ppit != cvcPowerPtrList.end(); power_ppit++ ) {
466 if ( (*power_ppit)->type[HIZ_BIT] && ! IsEmpty((*power_ppit)->family()) ) {
467 if ( (*power_ppit)->RelativeVoltage(cvcPowerMacroPtrMap, MIN_POWER, cvcModelListMap) == (*power_ppit)->minVoltage ) {
468 (*power_ppit)->active[MIN_IGNORE] = true;
469 }
470 if ( (*power_ppit)->RelativeVoltage(cvcPowerMacroPtrMap, MAX_POWER, cvcModelListMap) == (*power_ppit)->maxVoltage ) {
471 (*power_ppit)->active[MAX_IGNORE] = true;
472 }
473 }
474 }
475 }
476
PrintPowerList(ostream & theLogFile,string theIndentation)477 void CCvcParameters::PrintPowerList(ostream & theLogFile, string theIndentation) {
478 string myIndentation = theIndentation + " ";
479 theLogFile << endl << theIndentation << "PowerList> filename " << cvcPowerFilename << endl;
480 for (CPowerPtrList::iterator power_ppit = cvcPowerPtrList.begin(); power_ppit != cvcPowerPtrList.end(); power_ppit++) {
481 (*power_ppit)->Print(theLogFile, myIndentation);
482 }
483 theLogFile << theIndentation << "PowerList> end" << endl << endl;
484 }
485
486