1 /*
2  * CCvcDb.hh
3  *
4  * Copyright 2014-2020 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 #ifndef CCVCDB_HH_
25 #define CCVCDB_HH_
26 
27 #include "Cvc.hh"
28 
29 class CCvcDb;
30 #include "CInstance.hh"
31 #include "CCircuit.hh"
32 #include "CModel.hh"
33 #include "CPower.hh"
34 #include "CEventQueue.hh"
35 #include "CVirtualNet.hh"
36 #include "CCvcParameters.hh"
37 #include "CConnectionCount.hh"
38 #include "CConnection.hh"
39 #include "CDependencyMap.hh"
40 #include "gzstream.h"
41 
42 extern char RESISTOR_TEXT[];
43 extern CNetIdSet EmptySet;
44 
45 class CShortVector : public vector<pair<netId_t, string> > {
46 public:
47 };
48 
49 class CNetMap : public unordered_map<netId_t, forward_list<netId_t>> {
50 public:
CNetMap(float theLoadFactor=DEFAULT_LOAD_FACTOR)51 	CNetMap(float theLoadFactor = DEFAULT_LOAD_FACTOR) {max_load_factor(theLoadFactor);}
52 };
53 
54 class CCvcDb {
55 public:
56 	int	cvcArgIndex = 1;
57 	int	cvcArgCount;
58 
59 	bool detectErrorFlag;  //!< skip error processing if false
60 
61 	CCvcParameters	cvcParameters;
62 	CCircuitPtrList	cvcCircuitList;
63 
64 	CCircuit *	topCircuit_p;
65 	//CShortVector	short_v;
66 
67 	CInstancePtrVector instancePtr_v;
68 
69 	// parent instance.	 Use offset from first in instance to find name, etc.
70 	// [*] = instance
71 	CInstanceIdVector	netParent_v;
72 	CInstanceIdVector	deviceParent_v;
73 
74 	// [device] = device
75 	CDeviceIdVector	nextSource_v;
76 	CDeviceIdVector	nextGate_v;
77 	CDeviceIdVector	nextDrain_v;
78 //	CDeviceIdVector	nextBulk_v;
79 
80 	// [net] = device
81 	CDeviceIdVector	firstSource_v;
82 	CDeviceIdVector	firstGate_v;
83 	CDeviceIdVector	firstDrain_v;
84 //	CDeviceIdVector	firstBulk_v;
85 
86 	// [device] = net
87 	CNetIdVector	sourceNet_v;
88 	CNetIdVector	gateNet_v;
89 	CNetIdVector	drainNet_v;
90 	CNetIdVector	bulkNet_v;
91 
92 	vector<modelType_t> deviceType_v;
93 
94 	// [device] = status
95 	CStatusVector	deviceStatus_v;
96 	// [net] = status
97 	CStatusVector	netStatus_v;
98 
99 	// [net] = virtualNet
100 	CVirtualNetVector	minNet_v;
101 	CVirtualNetVector	simNet_v;
102 	CVirtualNetVector	maxNet_v;
103 
104 	bool isDeviceModelSet = false;
105 	bool isFixedMinNet, isFixedSimNet, isFixedMaxNet;
106 	bool leakVoltageSet;
107 	bool isValidShortData;
108 	returnCode_t modelFileStatus, powerFileStatus, fuseFileStatus;
109 
110 	// [net] = CConnection
111 	CConnectionCountVector	connectionCount_v;
112 
113 	// [net] = CPower
114 	CPowerPtrVector	netVoltagePtr_v;
115 	CPowerPtrVector	leakVoltagePtr_v;
116 	CPowerPtrVector	initialVoltagePtr_v;
117 //	CPowerPtrVector	logicVoltagePtr_v;
118 
119 	bool	isFixedEquivalentNet;
120 	CNetIdVector	equivalentNet_v;
121 	CNetIdVector	inverterNet_v; // inverterNet_v[1] = 2 means 2 -|>o- 1
122 	vector<bool>	highLow_v;
123 
124 	CEventQueue	maxEventQueue;
125 	CEventQueue minEventQueue;
126 	CEventQueue simEventQueue;
127 
128 	unordered_set<deviceId_t> mosDiodeSet;
129 	unordered_set<string> unknownGateSet;
130 
131 	uintmax_t	deviceCount;
132 	uintmax_t	subcircuitCount;
133 	uintmax_t	netCount;
134 
135 	unsigned int	lineLength = 0;
136 
137 	CTextResistanceMap	parameterResistanceMap;
138 
139 	voltage_t	minPower = MAX_VOLTAGE;
140 	voltage_t	maxPower = MIN_VOLTAGE;
141 
142 	size_t	errorCount[ERROR_TYPE_COUNT];
143 
144 	CDependencyMap minConnectionDependencyMap;
145 	CDependencyMap maxConnectionDependencyMap;
146 
147 	map<netId_t, string> calculatedResistanceInfo_v;
148 
149 	unordered_map<string, deviceId_t> cellErrorCountMap;
150 
151 	forward_list<string> inverterInputOutputCheckList;  // list of nets to check for matched input/output
152 	forward_list<pair<string, string>> oppositeLogicList;  // list of nets to check for opposite logic
153 
154 	ogzstream errorFile;
155 	ofstream logFile;
156 	teestream reportFile;  // simultaneous output to stdout and logFile
157 	ogzstream debugFile;
158 
159 	string lockFile;
160 	string reportPrefix;
161 
162 	typedef struct mos_data {
163 		netId_t gate;
164 		netId_t source;
165 		deviceId_t id;
166 	} mosData_t;
167 
168 	// CCvcDb_main.cc
169 	/// Main Loop: Verify circuits using settings in each verification resource file.
170 	void VerifyCircuitForAllModes(int argc, const char * argv[]);
171 
172 	// CCvcDb-init.cc
173 	CCvcDb(int argc, const char * argv[]);
174 	~CCvcDb();
175 	void CountObjectsAndLinkSubcircuits();
176 
177 	void AssignGlobalIDs();
178 	void ResetMinSimMaxAndQueues();
179 	CPower * SetMasterPower(netId_t theFirstNet, netId_t theSecondNet, bool & theSamePowerFlag);
180 	netId_t MasterPowerNet(netId_t theFirstNetId, netId_t theSecondNetId);
181 	void MakeEquivalentNets(CNetMap & theNetMap, netId_t theFirstNetId, netId_t theSecondNetId, deviceId_t theDeviceId);
182 	void SetEquivalentNets();
183 	void LinkDevices();
184 	returnCode_t SetDeviceModels();
185 	void DumpConnectionList(string theHeading, CDeviceIdVector& theFirstDevice_v, CDeviceIdVector& theNextDevice_v);
186 
187 	void DumpConnectionLists(string theHeading);
188 
189 	void MergeConnectionListByTerminals(netId_t theFromNet, netId_t theToNet, deviceId_t theIgnoreDeviceId,
190 			CDeviceIdVector& theFirstDevice_v, CDeviceIdVector& theNextDevice_v, CNetIdVector& theTerminal_v);
191 	deviceId_t RecountConnections(netId_t theNetId, CDeviceIdVector& theFirstDevice_v, CDeviceIdVector& theNextDevice_v);
192 	void MergeConnectionLists(netId_t theFromNet, netId_t theToNet, deviceId_t theIgnoreDeviceId);
193 //	void ResetMosFuse();
194 	void OverrideFuses();
195 
196 	deviceId_t FindUniqueSourceDrainConnectedDevice(netId_t theNetId);
197 	void ShortNonConductingResistor(deviceId_t theDeviceId, netId_t theFirstNet, netId_t theSecondNet, shortDirection_t theDirection);
198 	void ShortNonConductingResistors();
199 	void SetResistorVoltagesForMosSwitches();
200 	forward_list<instanceId_t> FindInstanceIds(string theHierarchy, instanceId_t theParent = 0);
201 	set<netId_t> * FindUniqueNetIds(string thePowerSignal, instanceId_t theParent = 0);
202 	forward_list<netId_t> * FindNetIds(string thePowerSignal, instanceId_t theParent = 0);
203 	returnCode_t SetModePower();
204 	returnCode_t SetInstancePower();
205 	returnCode_t SetExpectedPower();
206 	bool LockReport(bool theInteractiveFlag);
207 	void RemoveLock();
208 	void SetSCRCPower();
209 	size_t SetSCRCGatePower(netId_t theNetId, CDeviceIdVector & theFirstSource_v, CDeviceIdVector & theNextSource_v, CNetIdVector & theDrain_v,
210 			size_t & theSCRCSignalCount, size_t & theSCRCIgnoreCount, bool theNoCheckFlag);
211 	void SetSCRCParentPower(netId_t theNetId, deviceId_t theDeviceId, bool theExpectedHighInput, size_t & theSCRCSignalCount, size_t & theSCRCIgnoreCount);
212 	bool IsSCRCLogicNet(netId_t theNetId);
213 	bool IsSCRCPower(CPower * thePower_p);
214 	bool SetLatchPower(int thePassCount, vector<bool> & theIgnoreNet_v, CNetIdSet & theNewNetSet);
215 	void FindLatchDevices(netId_t theNetId, mosData_t theNmosData_v[], mosData_t thePmosData_v[], int & theNmosCount, int & thePmosCount,
216 		voltage_t theMinVoltage, voltage_t theMaxVoltage,
217 		CDeviceIdVector & theFirstDrain_v, CDeviceIdVector & theNextDrain_v, CNetIdVector & theSourceNet_v);
218 	bool IsOppositeLogic(netId_t theFirstNet, netId_t theSecondNet);
219 	void PrintInputNetsWithMinMaxSuggestions(netId_t theNetId);
220 	void PrintNetSuggestions();
221 	returnCode_t	LoadCellErrorLimits();
222 	void LoadCellChecksums();
223 	void LoadNetChecks();
224 	void LoadModelChecks();
225 
226 	// error
227 	void PrintFuseError(netId_t theTargetNetId, CConnection & theConnections);
228 	void PrintMinVoltageConflict(netId_t theTargetNetId, CConnection & theMinConnections, voltage_t theExpectedVoltage, float theLeakCurrent);
229 	void PrintMaxVoltageConflict(netId_t theTargetNetId, CConnection & theMaxConnections, voltage_t theExpectedVoltage, float theLeakCurrent);
230 	void FindVbgError(ogzstream & theErrorFile, voltage_t theParameter, CFullConnection & theConnections, instanceId_t theInstance_p, string theDisplayParameter);
231 	void FindVbsError(ogzstream & theErrorFile, voltage_t theParameter, CFullConnection & theConnections, instanceId_t theInstance_p, string theDisplayParameter);
232 	void FindVdsError(ogzstream & theErrorFile, voltage_t theParameter, CFullConnection & theConnections, instanceId_t theInstance_p, string theDisplayParameter);
233 	void FindVgsError(ogzstream & theErrorFile, voltage_t theParameter, CFullConnection & theConnections, instanceId_t theInstance_p, string theDisplayParameter);
234 	void FindModelError(ogzstream & theErrorFile, CModelCheck &theCheck, CFullConnection & theConnections, instanceId_t theInstanceId);
235 	void PrintOverVoltageError(ogzstream & theErrorFile, CFullConnection & theConnections, cvcError_t theErrorIndex, string theExplanation, instanceId_t theInstance_p);
236 	void PrintModelError(ogzstream & theErrorFile, CFullConnection & theConnections, CModelCheck & theCheck, instanceId_t theInstanceId);
237 	void FindAllOverVoltageErrors();
238 	void AppendErrorFile(string theTempFileName, string theHeading, int theErrorSubIndex);
239 	void FindNmosGateVsSourceErrors();
240 	void FindPmosGateVsSourceErrors();
241 	void FindNmosSourceVsBulkErrors();
242 	void FindPmosSourceVsBulkErrors();
243 	void FindForwardBiasDiodes();
244 	void FindNmosPossibleLeakErrors();
245 	void FindPmosPossibleLeakErrors();
246 	void FindFloatingInputErrors();
247 	void CheckExpectedValues();
248 	void FindLDDErrors();
249 	void CheckInverterIO(modelType_t theType);
250 	void CheckOppositeLogic(modelType_t theType);
251 
252 	//
253 	void ReportSimShort(deviceId_t theDeviceId, voltage_t theMainVoltage, voltage_t theShortVoltage, string theCalculation);
254 	void ReportShort(deviceId_t theDeviceId);
255 	bool VoltageConflict(CEventQueue& theEventQueue, deviceId_t theDeviceId, CConnection& theConnections);
256 	bool BulkError(eventQueue_t theQueueType, CDevice * theDevice_p, netId_t theBulkId, voltage_t theVoltage);
257 	bool LastNmosConnection(deviceStatus_t thePendingBit, netId_t theNetId);
258 	bool LastPmosConnection(deviceStatus_t thePendingBit, netId_t theNetId);
259 	bool IsIrrelevant(CEventQueue& theEventQueue, deviceId_t theDeviceId, CConnection& theConnections, voltage_t theVoltage, queueStatus_t theStatus);
260 	string AdjustMaxPmosKey(CConnection& theConnections, netId_t theDrainId, voltage_t theMaxSource, eventKey_t& theEventKey, queuePosition_t& theQueuePosition);
261 	string AdjustMaxNmosKey(CConnection& theConnections, voltage_t theSimGate, voltage_t theMaxSource, eventKey_t& theEventKey, queuePosition_t& theQueuePosition,
262 			bool theWarningFlag);
263 	string AdjustMinNmosKey(CConnection& theConnections, netId_t theDrainId, voltage_t theMinSource, eventKey_t& theEventKey, queuePosition_t& theQueuePosition);
264 	string AdjustMinPmosKey(CConnection& theConnections, voltage_t theSimGate, voltage_t theMinSource, eventKey_t& theEventKey, queuePosition_t& theQueuePosition,
265 			bool theWarningFlag);
266 	string AdjustKey(CEventQueue& theEventQueue, deviceId_t theDeviceId, CConnection& theConnections, eventKey_t& theEventKey, queuePosition_t& theQueuePosition,
267 			shortDirection_t theDirection, bool theWarningFlag);
268 	string AdjustSimVoltage(CEventQueue& theEventQueue, deviceId_t theDeviceId, CConnection& theConnections, voltage_t& theVoltage, shortDirection_t theDirection,
269 			propagation_t thePropagationType);
270 	bool TopologicallyOffMos(eventQueue_t theQueueType, modelType_t theModelType, CConnection& theConnections);
271 
272 	bool IsOffMos(eventQueue_t theQueueType, deviceId_t theDeviceId, CConnection& theConnections, voltage_t theVoltage);
273 	void EnqueueAttachedDevicesByTerminal(CEventQueue& theEventQueue, netId_t theNetId, CDeviceIdVector& theFirstDevice_v, CDeviceIdVector& theNextDevice_v, eventKey_t theEventKey);
274 	void EnqueueAttachedDevices(CEventQueue& theEventQueue, netId_t theNetId, eventKey_t theEventKey);
275 	void PropagateMinMaxVoltages(CEventQueue& theEventQueue);
276 	bool CheckEstimateDependency(CDependencyMap& theDependencyMap, size_t theEstimateType, list<netId_t>& theDependencyList);
277 	void CheckEstimateDependencies();
278 	void SetTrivialMinMaxPower();
279 	void ResetMinMaxActiveStatus();
280 	void SetInitialMinMaxPower();
281 	void ShiftVirtualNets(CEventQueue& theEventQueue, netId_t theNetId, CVirtualNet& theLastVirtualNet, resistance_t theNewResistance, resistance_t theOldResistance);
282 	void RecalculateFinalResistance(CEventQueue& theEventQueue, netId_t theNewNetId, bool theRecursingFlag = false);
283 
284 
285 	void EnqueueAttachedResistorsByTerminal(CEventQueue& theEventQueue, netId_t theNetId, CDeviceIdVector& theFirstDevice_v, CDeviceIdVector& theNextDevice_v, eventKey_t theEventKey, queuePosition_t theQueuePosition);
286 	void EnqueueAttachedResistors(CEventQueue& theEventQueue, netId_t theNetId, eventKey_t theEventKey, queuePosition_t theQueuePosition);
287 	bool CheckConnectionReroute(CEventQueue& theEventQueue, CConnection& theConnections, shortDirection_t theDirection);
288 	bool IsPriorityDevice(CEventQueue& theEventQueue, modelType_t theModel);
289 	void AlreadyShorted(CEventQueue& theEventQueue, deviceId_t theDeviceId, CConnection& theConnections);
290 	void ShortNets(CEventQueue& theEventQueue, deviceId_t theDeviceId, CConnection& theConnections, shortDirection_t theDirection);
291 	void ShortNets(CEventQueue& theEventQueue, deviceId_t theDeviceId, CConnection& theConnections, shortDirection_t theDirection, voltage_t theVoltage, string theCalculation);
292 	void ShortSimNets(CEventQueue& theEventQueue, deviceId_t theDeviceId, CConnection& theConnections, shortDirection_t theDirection, voltage_t theVoltage, string theCalculation);
293 	void PropagateResistorVoltages(CEventQueue& theEventQueue);
294 	void PropagateConnectionType(CVirtualNetVector& theVirtualNet_v, CStatus theSourceDrainType, netId_t theNetId);
295 	void PropagateSimVoltages(CEventQueue& theEventQueue, propagation_t thePropagationType);
296 	void CalculateResistorVoltage(netId_t theNetId, voltage_t theMinVoltage, resistance_t theMinResistance,
297 			voltage_t theMaxVoltage, resistance_t theMaxResistance );
298 	void PropagateResistorCalculations(netId_t theNetId, CDeviceIdVector& theFirstDevice_v, CDeviceIdVector& theNextDevice_v);
299 	void CalculateResistorVoltages();
300 	void SetResistorVoltagesByPower();
301 	void ResetMinMaxPower();
302 	void SetAnalogNets();
303 	void PropagateAnalogNetType(netId_t theNetId, int theGateCount);
304 	void PropagateAnalogNetTypeByTerminal(netId_t theNetId, CDeviceIdVector& theFirstDevice_v, CDeviceIdVector& theNextDevice_v, int theGateCount);
305 	void IgnoreUnusedDevices();
306 	void SetSimPower(propagation_t thePropagationType, CNetIdSet & theNewNetSet = EmptySet);
307 
308 	void SetInverterHighLow(netId_t theNetId, netId_t theMaxNetId);
309 	netId_t SetInverterInput(netId_t theNetId, netId_t theMaxNetId);
310 	void SetInverters();
311 
312 	// CCvcDb-utility
313 	voltage_t MinVoltage(netId_t theNetId, bool theSkipHiZFlag = false);
314 	voltage_t MinSimVoltage(netId_t theNetId);
315 	resistance_t MinResistance(netId_t theNetId);
316 	voltage_t MinLeakVoltage(netId_t theNetId);
317 	voltage_t SimVoltage(netId_t theNetId);
318 	bool IsAlwaysOnCandidate(deviceId_t theDeviceId, shortDirection_t theDirection);
319 	resistance_t SimResistance(netId_t theNetId);
320 	voltage_t MaxVoltage(netId_t theNetId, bool theSkipHiZFlag = false);
321 	voltage_t MaxSimVoltage(netId_t theNetId);
322 	resistance_t MaxResistance(netId_t theNetId);
323 	voltage_t MaxLeakVoltage(netId_t theNetId);
324 	netId_t GetGreatestEquivalentNet(netId_t theNetId);
325 	netId_t GetLeastEquivalentNet(netId_t theNetId);
326 	netId_t GetEquivalentNet(netId_t theNetId);
327 	list<string> * SplitHierarchy(string theFullPath);
328 	void SaveMinMaxLeakVoltages();
329 	void SaveInitialVoltages();
330 	list<string> * ExpandBusNet(string theBusName);
331 
332 	text_t DeviceParameters(const deviceId_t theDeviceId);
333 
334 	void SetDeviceNets(CInstance * theInstance_p, CDevice * theDevice_p, netId_t& theSourceId, netId_t& theGateId, netId_t& theDrainId, netId_t& theBulkId);
335 	void SetDeviceNets(deviceId_t theDeviceId, CDevice * theDevice_p, netId_t& theSourceId, netId_t& theGateId, netId_t& theDrainId, netId_t& theBulkId);
336 	void MapDeviceNets(deviceId_t theDeviceId, CEventQueue& theEventQueue, CConnection& theConnections);
337 	void MapDeviceNets(deviceId_t theDeviceId, CFullConnection& theConnections);
338 	void MapDeviceSourceDrainNets(deviceId_t theDeviceId, CFullConnection& theConnections);
339 	void MapDeviceNets(CInstance * theInstance_p, CDevice * theDevice_p, CFullConnection& theConnections);
340 
341 	void IgnoreDevice(deviceId_t theDeviceId);
342 	bool EqualMasterNets(CVirtualNetVector& theVirtualNet_v, netId_t theFirstNetId, netId_t theSecondNetId);
343 	bool GateEqualsDrain(CConnection& theConnections);
IsFloatingGate(CFullConnection & myConnections)344 	inline bool IsFloatingGate(CFullConnection& myConnections) { return (myConnections.minGateVoltage == UNKNOWN_VOLTAGE || myConnections.minGatePower_p->type[HIZ_BIT]
345 		|| myConnections.maxGateVoltage == UNKNOWN_VOLTAGE || myConnections.maxGatePower_p->type[HIZ_BIT]); };
IsVerifiedPower(netId_t theNetId)346 	inline bool IsVerifiedPower(netId_t theNetId) {return ! (netStatus_v[theNetId][NEEDS_MIN_CHECK] || netStatus_v[theNetId][NEEDS_MIN_CONNECTION]
347 		|| netStatus_v[theNetId][NEEDS_MAX_CHECK] || netStatus_v[theNetId][NEEDS_MAX_CONNECTION]); }
348 	voltage_t DefaultMinVoltage(CPower * thePower_p);
349 	voltage_t DefaultMaxVoltage(CPower * thePower_p);
350 	bool HasLeakPath(CFullConnection& theConnections);
351 	void RestoreQueue(CEventQueue& theBaseEventQueue, CEventQueue& theSavedEventQueue, deviceStatus_t theStatusBit);
352 	void CheckConnections();
353 	bool PathContains(CVirtualNetVector& theSearchVector, netId_t theSearchNet, netId_t theTargetNet);
354 	bool PathCrosses(CVirtualNetVector& theSearchVector, netId_t theSearchNet, CVirtualNetVector& theTargetVector, netId_t theTargetNet);
355 	bool HasActiveConnection(netId_t theNet);
356 	size_t IncrementDeviceError(deviceId_t theDeviceId, int theErrorIndex);
357 	eventKey_t SimKey(eventKey_t theCurrentKey, resistance_t theIncrement);
358 	bool IsDerivedFromFloating(CVirtualNetVector& theVirtualNet_v, netId_t theNetId);
359 	bool HasActiveConnections(netId_t theNetId);
360 	size_t InstanceDepth(instanceId_t theInstanceId);
361 	bool IsSubcircuitOf(instanceId_t theInstanceId, instanceId_t theParentId);
362 	void RemoveInvalidPower(netId_t theNetId, size_t & theRemovedCount);
363 	calculationType_t GetCalculationType(CPower * thePower_p, eventQueue_t theQueueType);
364 	deviceId_t GetSeriesConnectedDevice(deviceId_t theDeviceId, netId_t theNetId);
365 	void Cleanup();
366 	deviceId_t CountBulkConnections(netId_t theNetId);
367 	bool IsAnalogNet(netId_t theNetId);
368 	bool IsAlwaysOff(CFullConnection& theConnections);
369 	bool IsOneConnectionNet(netId_t theNetId);
370 	void SetDiodeConnections(pair<int, int> diode_pit, CFullConnection & myConnections, CFullConnection & myDiodeConnections);
371 	int CalculateMFactor(instanceId_t theInstanceId);
372 	deviceId_t GetAttachedDevice(netId_t theNetId, modelType_t theType, terminal_t theTerminal);
373 	deviceId_t FindInverterDevice(netId_t theInputNet, netId_t theOutputNet, modelType_t theType);
374 	returnCode_t FindUniqueMosInputs(netId_t theOutputNet, netId_t theGroundNet, netId_t thePowerNet,
375 		CDeviceIdVector &theFirst_v, CDeviceIdVector &theNext_v, CNetIdVector &theSourceNet_v, CNetIdVector &theDrainNet_v,
376 		netId_t &theNmosInput, netId_t &thePmosInput);
377 	deviceId_t FindInverterInput(netId_t theOutputNet);
378 	bool IsOnGate(deviceId_t theDevice, CPower * thePower_p);
379 	netId_t OppositeNet(deviceId_t theDevice, netId_t theNet);
380 	deviceId_t GetNextInSeries(deviceId_t theDevice, netId_t theNet);
381 	bool IsInstanceNet(netId_t theNetId, instanceId_t theInstance);
382 	instanceId_t FindNetInstance(netId_t theNetId, instanceId_t theInstance);
383 	bool IsInternalNet(netId_t theNetId, instanceId_t theInstance);
384 	text_t GetLocalNetName(instanceId_t theInstance, netId_t theNet);
385 
386 	// CCvcDb-print
387 	void SetOutputFiles(string theReportFile);
388 	string NetAlias(netId_t theNetId, bool thePrintCircuitFlag);
389 	string NetName(CPower * thePowerPtr, bool thePrintCircuitFlag, bool thePrintHierarchyFlag = PRINT_HIERARCHY_ON);
390 	string NetName(const netId_t theNetId, bool thePrintCircuitFlag = PRINT_CIRCUIT_OFF, bool thePrintHierarchyFlag = PRINT_HIERARCHY_ON);
391 	string HierarchyName(const instanceId_t theInstanceId, bool thePrintCircuitFlag = PRINT_CIRCUIT_OFF, bool thePrintHierarchyFlag = PRINT_HIERARCHY_ON);
392 	string DeviceName(const deviceId_t theDeviceId, bool thePrintCircuitFlag = PRINT_CIRCUIT_OFF, bool thePrintHierarchyFlag = PRINT_HIERARCHY_ON);
393 	string DeviceName(string theName, const instanceId_t theParentId, bool thePrintCircuitFlag = PRINT_CIRCUIT_OFF, bool thePrintHierarchyFlag = PRINT_HIERARCHY_ON);
394 
395 	void PrintEquivalentNets(string theIndentation);
396 	void PrintInverterNets(string theIndentation);
397 	void PrintFlatCdl();
398 	void PrintHierarchicalCdl(CCircuit *theCircuit, unordered_set<text_t> & thePrintedList, ostream & theCdlFile);
399 	void PrintNewCdlLine(const string theData, ostream & theOutput = cout);
400 	void PrintNewCdlLine(const text_t theData, ostream & theOutput = cout);
401 	void PrintNewCdlLine(const char theData, ostream & theOutput = cout);
402 	void PrintSourceDrainConnections(CStatus& theConnectionStatus, string theIndentation);
403 	void PrintConnections(deviceId_t theDeviceCount, deviceId_t theDeviceId, CDeviceIdVector& theNextDeviceId_v, string theIndentation = "", string theHeading = "Connections>");
404 	void PrintBulkConnections(netId_t theNetId, string theIndentation, string theHeading);
405 
406 	void PrintCdlLine(const string theData, ostream & theOutput = cout, const unsigned int theMaxLength = 80);
407 	void PrintCdlLine(const char * theData, ostream & theOutput = cout, const unsigned int theMaxLength = 80);
408 	string StatusString(const CStatus& theStatus);
409 
410 	void Print(const string theIndentation = "", const string theHeading = "CVC Database");
411 	void PrintPowerList(ostream & theOutputStream, string theHeading = "", string theIndentation = "");
412 	template <class TVirtualNetVector> void PrintVirtualNet(TVirtualNetVector& theVirtualNet_v, netId_t theNetId, string theTitle, ostream & theOutputFile);
413 	void PrintVirtualNets(CVirtualNetVector& theVirtualNet_v, string theTitle = "", string theIndentation = "");
414 	template <class TVirtualNetVector> void PrintAllVirtualNets(TVirtualNetVector& theMinNet_v, CVirtualNetVector& theSimNet_v, TVirtualNetVector& theMaxNet_v, string theTitle = "", string theIndentation = "", bool theUseLeak = false);
415 	string PrintVoltage(voltage_t theVoltage);
416 	string PrintVoltage(voltage_t theVoltage, CPower * thePower_p);
417 
418 	void PrintDeviceWithAllConnections(instanceId_t theInstanceId, CFullConnection& theConnections, ogzstream& theErrorFile, bool theIncludeLeakVoltage = false);
419 	void PrintDeviceWithSimConnections(instanceId_t theParentId, CFullConnection& theConnections, ogzstream& theErrorFile);
420 
421 	void PrintAllTerminalConnections(terminal_t theTerminal, CFullConnection& theConnections, ogzstream& theErrorFile, bool theIncludeLeakVoltage = false);
422 	void PrintSimTerminalConnections(terminal_t theTerminal, CFullConnection& theConnections, ogzstream& theErrorFile);
423 	void PrintErrorTotals();
424 	//void PrintShortedNets(string theShortFileName);
425 	string NetVoltageSuffix(string theDelimiter, string theVoltage, resistance_t theResistance, string theLeakVoltage = "");
426 	void PrintResistorOverflow(netId_t theNet, ofstream& theOutputFile);
427 	void PrintClassSizes();
428 	void PrintNetWithModelCounts(netId_t theNetId, int theTerminals);
429 	void PrintBackupNet(CVirtualNetVector& theVirtualNet_v, netId_t theNetId, string theTitle, ostream& theOutputFile);
430 	void PrintLargeCircuits();
431 
432 	// CCvcDb-interactive
433 	void FindInstances(string theSubcircuit, bool thePrintCircuitFlag);
434 	void FindNets(string theName, instanceId_t theInstanceId, bool thePrintCircuitFlag);
435 	void ShowNets(size_t & theNetCount, regex & theSearchPattern, instanceId_t theInstanceId, bool thePrintCircuitFlag);
436 	CCircuit * FindSubcircuit(string theSubcircuit);
437 	void PrintSubcircuitCdl(string theSubcircuit);
438 	instanceId_t FindHierarchy(instanceId_t theCurrentInstanceId, string theHierarchy, bool theAllowPartialMatch = false, bool thePrintUnmatchFlag = true);
439 	string ShortString(netId_t theNetId, bool thePrintSubcircuitNameFlag);
440 	string LeakShortString(netId_t theNetId, bool thePrintSubcircuitNameFlag);
441 	void PrintParallelInstance(instanceId_t theInstanceId, bool thePrintSubcircuitNameFlag);
442 	void PrintNets(instanceId_t theCurrentInstanceId, string theFilter, bool thePrintSubcircuitNameFlag, bool theIsValidPowerFlag);
443 	void PrintDevices(instanceId_t theCurrentInstanceId, string theFilter, bool thePrintSubcircuitNameFlag, bool theIsValidModelFlag);
444 	void PrintInstances(instanceId_t theCurrentInstanceId, string theFilter, bool thePrintSubcircuitNameFlag);
445 	//void ReadShorts(string theShortFileName);
446 	netId_t FindNet(instanceId_t theCurrentInstanceId, string theNetName, bool theDisplayErrorFlag = true);
447 	deviceId_t FindDevice(instanceId_t theCurrentInstanceId, string theDeviceName);
448 	returnCode_t InteractiveCvc(int theCurrentStage);
449 	void DumpFuses(string theFileName);
450 	void DumpAnalogNets(string theFileName, bool thePrintCircuitFlag);
451 	void DumpUnknownLogicalPorts(instanceId_t theCurrentInstanceId, string theFilter, string theFileName, bool thePrintCircuitFlag);
452 	void DumpUnknownLogicalNets(string theFileName, bool thePrintCircuitFlag);
453 	void DumpLevelShifters(string theFileName, bool thePrintCircuitFlag);
454 	returnCode_t CheckFuses();
455 	void CreateDebugCvcrcFile(ofstream & theOutputFile, instanceId_t theInstanceId, string theMode, int theCurrentStage);
456 	void PrintInstancePowerFile(instanceId_t theInstanceId, string thePowerFileName, int theCurrentStage);
457 
458 };
459 
460 template <class TVirtualNetVector>
PrintVirtualNet(TVirtualNetVector & theVirtualNet_v,netId_t theNetId,string theTitle,ostream & theOutputFile)461 void CCvcDb::PrintVirtualNet(TVirtualNetVector& theVirtualNet_v, netId_t theNetId, string theTitle, ostream& theOutputFile) {
462 	theOutputFile << theTitle << endl;
463 	theOutputFile << NetName(theNetId) << endl;
464 	netId_t myNetId = GetEquivalentNet(theNetId);
465 	if ( myNetId != theNetId ) cout << "=>" << NetName(myNetId) << endl;
466 	while ( myNetId != theVirtualNet_v[myNetId].nextNetId ) {
467 		theOutputFile << "->" << NetName(theVirtualNet_v[myNetId].nextNetId) << " r=" << theVirtualNet_v[myNetId].resistance << endl;
468 		myNetId = theVirtualNet_v[myNetId].nextNetId;
469 	}
470 	if ( netVoltagePtr_v[myNetId].full ) netVoltagePtr_v[myNetId].full->Print(theOutputFile);
471 	theOutputFile << endl;
472 }
473 
474 template <class TVirtualNetVector>
PrintAllVirtualNets(TVirtualNetVector & theMinNet_v,CVirtualNetVector & theSimNet_v,TVirtualNetVector & theMaxNet_v,string theTitle,string theIndentation,bool theUseLeak)475 void CCvcDb::PrintAllVirtualNets(TVirtualNetVector& theMinNet_v, CVirtualNetVector& theSimNet_v, TVirtualNetVector& theMaxNet_v, string theTitle, string theIndentation, bool theUseLeak) {
476 	cout << theIndentation << "VirtualNetVector" << theTitle << "> start " << netCount << endl;
477 	netId_t myEquivalentNet, myFinalNet;
478 	for ( netId_t net_it = 0; net_it < netCount; net_it++ ) {
479 		cout << net_it << ": ";
480 		myEquivalentNet = GetEquivalentNet(net_it);
481 		myFinalNet = theMinNet_v[myEquivalentNet].nextNetId;
482 		if ( net_it == myFinalNet ) {
483 			if ( netVoltagePtr_v[net_it].full && netVoltagePtr_v[net_it].full->minVoltage != UNKNOWN_VOLTAGE ) {
484 				cout << netVoltagePtr_v[net_it].full->minVoltage;
485 				if ( theUseLeak && MinLeakVoltage(net_it) != netVoltagePtr_v[net_it].full->minVoltage ) {
486 					cout << "(" << MinLeakVoltage(net_it) << ")";
487 				}
488 			} else {
489 				cout << "??";
490 				if ( theUseLeak && MinLeakVoltage(net_it) != UNKNOWN_VOLTAGE ) {
491 					cout << "(" << MinLeakVoltage(net_it) << ")";
492 				}
493 			}
494 		} else {
495 			cout << myFinalNet << "@" << theMinNet_v[myEquivalentNet].resistance;
496 			if ( theUseLeak && MinLeakVoltage(myEquivalentNet) != MinVoltage(myEquivalentNet) ) {
497 				cout << "(" << MinLeakVoltage(myEquivalentNet) << ")";
498 			}
499 		}
500 		cout << "/";
501 		myFinalNet = theSimNet_v[myEquivalentNet].nextNetId;
502 		if ( net_it == myFinalNet ) {
503 			if ( netVoltagePtr_v[net_it].full && netVoltagePtr_v[net_it].full->simVoltage != UNKNOWN_VOLTAGE ) {
504 				cout << netVoltagePtr_v[net_it].full->simVoltage;
505 			} else {
506 				cout << "??";
507 			}
508 		} else {
509 			cout << myFinalNet << "@" << theSimNet_v[myEquivalentNet].resistance;
510 		}
511 		cout << "/";
512 		myFinalNet = theMaxNet_v[myEquivalentNet].nextNetId;
513 		if ( net_it == myFinalNet ) {
514 			if ( netVoltagePtr_v[net_it].full && netVoltagePtr_v[net_it].full->maxVoltage != UNKNOWN_VOLTAGE ) {
515 				cout << netVoltagePtr_v[net_it].full->maxVoltage;
516 				if ( theUseLeak && MaxLeakVoltage(net_it) != netVoltagePtr_v[net_it].full->maxVoltage ) {
517 					cout << "(" << MaxLeakVoltage(net_it) << ")";
518 				}
519 			} else {
520 				cout << "??";
521 				if ( theUseLeak && MaxLeakVoltage(net_it) != UNKNOWN_VOLTAGE ) {
522 					cout << "(" << MaxLeakVoltage(net_it) << ")";
523 				}
524 			}
525 		} else {
526 			cout << myFinalNet << "@" << theMaxNet_v[myEquivalentNet].resistance;
527 			if ( theUseLeak && MaxLeakVoltage(myEquivalentNet) != MaxVoltage(myEquivalentNet) ) {
528 				cout << "(" << MaxLeakVoltage(myEquivalentNet) << ")";
529 			}
530 		}
531 		cout << endl;
532 	}
533 	cout << theIndentation << "VirtualNetVector" << theTitle << "> end" << endl;
534 }
535 
536 #define CheckResistorOverflow_(theResistance, theId, theLog) if ( theResistance == MAX_RESISTANCE ) PrintResistorOverflow(theId, theLog)
537 
538 #define RERUN_NG 0
539 #define RERUN_OK 1
540 
541 #define SetConnections_(theConnections, theDeviceId) (\
542 		theConnections.sourceId = sourceNet_v[theDeviceId],\
543 		theConnections.gateId = gateNet_v[theDeviceId],\
544 		theConnections.drainId = drainNet_v[theDeviceId],\
545 		theConnections.bulkId = bulkNet_v[theDeviceId]\
546 		)
547 
548 #define ExceedsLeakLimit_(theLeakCurrent) (rint(((theLeakCurrent) - cvcParameters.cvcLeakLimit) * 1e9) / 1e9 > 0)
549 
550 #endif /* CCVCDB_HH_ */
551