1 /*
2  * CPower.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 "CPower.hh"
25 
26 #include "CEventQueue.hh"
27 #include "CCvcDb.hh"
28 
29 netId_t CPower::powerCount = 0;
30 CFixedText CPower::powerDefinitionText;
31 
CExtraPowerData()32 CExtraPowerData::CExtraPowerData() {
33 	powerSignal = CPower::powerDefinitionText.BlankTextAddress();
34 	powerAlias = CPower::powerDefinitionText.BlankTextAddress();
35 }
36 
CPower()37 CPower::CPower() {
38 	powerId = powerCount++;
39 	definition = CPower::powerDefinitionText.BlankTextAddress();
40 }
41 
CPower(CPower * thePower_p)42 CPower::CPower(CPower * thePower_p) {
43 	// Similar to byte-wise copy, but duplicates extraData;
44 	*this = *thePower_p;
45 	if ( extraData ) {
46 		extraData = new CExtraPowerData(*(thePower_p->extraData));
47 	}
48 }
49 
CPower(CPower * thePower_p,netId_t theNetId)50 CPower::CPower(CPower * thePower_p, netId_t theNetId) {
51 	// copies power for expanding power short cuts *(cell)/net
52 	// use before family expansion
53 	powerId = powerCount++;
54 	minVoltage = thePower_p->minVoltage;
55 	maxVoltage = thePower_p->maxVoltage;
56 	simVoltage = thePower_p->simVoltage;
57 	if ( thePower_p->extraData ) {
58 		extraData = new CExtraPowerData;
59 		extraData->powerSignal = thePower_p->powerSignal();
60 		extraData->powerAlias = thePower_p->powerAlias();
61 		extraData->expectedSim = thePower_p->expectedSim();
62 		extraData->expectedMin = thePower_p->expectedMin();
63 		extraData->expectedMax = thePower_p->expectedMax();
64 		extraData->family = thePower_p->family();
65 		extraData->implicitFamily = thePower_p->implicitFamily();
66 		extraData->relativeSet = thePower_p->extraData->relativeSet;
67 	}
68 	relativeFriendly = thePower_p->relativeFriendly;
69 	type = thePower_p->type;
70 	definition = thePower_p->definition;
71 	active = thePower_p->active;
72 	netId = theNetId;
73 	minCalculationType = thePower_p->minCalculationType;
74 	simCalculationType = thePower_p->simCalculationType;
75 	maxCalculationType = thePower_p->maxCalculationType;
76 }
77 
CPower(string thePowerString,CPowerPtrMap & thePowerMacroPtrMap,CModelListMap & theModelListMap)78 CPower::CPower(string thePowerString, CPowerPtrMap & thePowerMacroPtrMap, CModelListMap & theModelListMap) {
79 	// for power definitions
80 	// Valid power definitions
81 	// # ...	<- comment
82 	// VSS 0.0	<- power definition min=sim=max=0.0
83 	// VDD 1.2	<- power definition min=sim=max=1.2
84 	// VBB -0.5	<- power definition min=sim=max=-0.5
85 	// A1 min@0.0 sim@0.6 max@1.2 <- input/output/internal signal min/sim/max.
86 	//									missing values are calculated.
87 	// O1 min@0.0 expect@1.2 max@1.2 <- input/output/internal signal min/max.
88 	//									sim value is calculated and checked against expect.
89 	//									missing min/max values are calculated.
90 	// VDDX min@0.0 max@1.2 open permit@VSS	<- cutoff power definition (floating), unknown sim definition, path to VSS ok
91 	// VSSX min@0.0 max@1.2 open permit@VDD	<- cutoff power definition (floating), unknown sim definition, path to VDD ok
92 	// VDDZ min@1.2 max@1.2 open	<- SCRC power definition, no paths permitted
93 	// VSSZ min@0.0 max@0.0 open	<- SCRC power definition, no paths permitted
94 	// active usage: only use min/max power marked as active
95 	//   sim values imply defined min/max active
96 	//   open, input also imply defined min/max active
97 	//   other min/max overrides must have path to lower/higher value to become active
98 	//   reset before min/max calculations for unknown sim values.
99 	// powerAlias: all top level power nets have alias for power families VSS->VSS  /VDDA->VDDA
100 	//   explicit overrides permitted /X7/VDD~>VDD7
101 	// TODO: add power families
102 	// VPP 2.6 permit@vdd			<- power definition with explicit permitted connections
103 	// VNWL -0.2 prohibit@VSS		<- power definition with explicit prohibited connections
104 	// family vdd VDD,VSS,...		<- family definition
105 	// sanity checks
106 	// TODO: power definitions determine default families
107 	thePowerString = trim_(thePowerString);
108 	string myParameterName;
109 	string myParameterValue;
110 	size_t	myAtIndex;
111 	size_t	myStringBegin = thePowerString.find_first_not_of(" \t");
112 	size_t	myStringEnd = thePowerString.find_first_of(" \t", myStringBegin);
113 	type = 0;
114 	powerId = powerCount++;
115 	extraData = new CExtraPowerData;
116 	size_t myAliasBegin = thePowerString.find(ALIAS_DELIMITER);
117 	extraData->powerSignal = CPower::powerDefinitionText.SetTextAddress((text_t)(thePowerString.substr(myStringBegin, min(myStringEnd, myAliasBegin))).c_str());
118 	string myDefinition = "";
119 	string myImplicitFamily = "";
120 	while (myStringEnd < thePowerString.length()) {
121 		myStringBegin = thePowerString.find_first_not_of(" \t", myStringEnd);
122 		myStringEnd = thePowerString.find_first_of(" \t", myStringBegin);
123 		myAtIndex = thePowerString.find("@", myStringBegin);
124 		if ( myAtIndex < myStringEnd ) {
125 			myParameterName = thePowerString.substr(myStringBegin, myAtIndex - myStringBegin);
126 			myParameterValue = thePowerString.substr(myAtIndex + 1, myStringEnd - (myAtIndex + 1));
127 			if ( myParameterName == "min" ) {
128 				minVoltage = thePowerMacroPtrMap.CalculateVoltage(myParameterValue, MIN_POWER, theModelListMap);
129 				myImplicitFamily += thePowerMacroPtrMap.implicitFamily;
130 				minCalculationType = NO_CALCULATION;
131 			}
132 			if ( myParameterName == "max" ) {
133 				maxVoltage = thePowerMacroPtrMap.CalculateVoltage(myParameterValue, MAX_POWER, theModelListMap);
134 				myImplicitFamily += thePowerMacroPtrMap.implicitFamily;
135 				maxCalculationType = NO_CALCULATION;
136 			}
137 			if ( myParameterName == "sim" ) {
138 				simVoltage = thePowerMacroPtrMap.CalculateVoltage(myParameterValue, SIM_POWER, theModelListMap);
139 				myImplicitFamily += thePowerMacroPtrMap.implicitFamily;
140 				simCalculationType = NO_CALCULATION;
141 			}
142 			if ( myParameterName == "expectMin" ) extraData->expectedMin = thePowerMacroPtrMap.CalculateExpectedValue(myParameterValue, MIN_POWER, theModelListMap);
143 			if ( myParameterName == "expectMax" ) extraData->expectedMax = thePowerMacroPtrMap.CalculateExpectedValue(myParameterValue, MAX_POWER, theModelListMap);
144 			if ( myParameterName == "expectSim" ) extraData->expectedSim = thePowerMacroPtrMap.CalculateExpectedValue(myParameterValue, SIM_POWER, theModelListMap);
145 			if ( myParameterName == "permit" || myParameterName == "prohibit" ) {
146 				if ( thePowerMacroPtrMap.count(myParameterValue) && ! IsEmpty(thePowerMacroPtrMap[myParameterValue]->powerAlias()) ) {
147 					extraData->family = thePowerMacroPtrMap[myParameterValue]->powerAlias();
148 				} else {
149 					extraData->family = myParameterValue;
150 				}
151 				relativeFriendly = ( myParameterName == "permit" ) ? true : false;
152 			}
153 			myDefinition += " " + myParameterName + "@" + myParameterValue;
154 		} else {
155 			myParameterName = thePowerString.substr(myStringBegin, myStringEnd - myStringBegin);
156 			myDefinition += " " + myParameterName;
157 			if ( myParameterName == "input" ) {
158 				type[INPUT_BIT] = true;
159 			} else if ( myParameterName == "power" ) {
160 				type[POWER_BIT] = true;
161 				if ( IsEmpty(powerAlias()) ) {
162 					SetPowerAlias(thePowerString, myAliasBegin);
163 				}
164 			} else if ( myParameterName == "analog" ) {
165 				type[ANALOG_BIT] = true;
166 			} else if ( myParameterName == "resistor" ) {
167 				type[RESISTOR_BIT] = true;
168 /*
169 			} else if ( myParameterName == "reference" ) {
170 				type[REFERENCE_BIT] = true;
171 */
172 			} else if ( myParameterName == "open" ) {
173 				type[HIZ_BIT] = true;
174 				simVoltage = UNKNOWN_VOLTAGE;
175 			} else if ( IsValidVoltage_(myParameterName) ) { // voltage
176 				simVoltage = String_to_Voltage(myParameterName);
177 				maxVoltage = simVoltage;
178 				minVoltage = simVoltage;
179 			} else if ( thePowerMacroPtrMap.count(myParameterName) > 0 ) { // macro
180 				minVoltage = thePowerMacroPtrMap[myParameterName]->minVoltage;
181 				maxVoltage = thePowerMacroPtrMap[myParameterName]->maxVoltage;
182 				simVoltage = thePowerMacroPtrMap[myParameterName]->simVoltage;
183 				myImplicitFamily += "," + myParameterName;
184 				if ( ! IsEmpty(thePowerMacroPtrMap[myParameterName]->family()) ) {
185 					myImplicitFamily += "," + thePowerMacroPtrMap[myParameterName]->family();
186 				}
187 				if ( thePowerMacroPtrMap[myParameterName]->extraData ) {
188 					if (! extraData) extraData = new CExtraPowerData;
189 					extraData->expectedMin = thePowerMacroPtrMap[myParameterName]->expectedMin();
190 					extraData->expectedMax = thePowerMacroPtrMap[myParameterName]->expectedMax();
191 					extraData->expectedSim = thePowerMacroPtrMap[myParameterName]->expectedSim();
192 					extraData->family = thePowerMacroPtrMap[myParameterName]->family();
193 				}
194 				relativeFriendly = thePowerMacroPtrMap[myParameterName]->relativeFriendly;
195 				type[HIZ_BIT] = thePowerMacroPtrMap[myParameterName]->type[HIZ_BIT];
196 				extraData->powerAlias = CPower::powerDefinitionText.SetTextAddress((text_t)myParameterName.c_str());
197 			} else { // formula
198 				simVoltage = thePowerMacroPtrMap.CalculateVoltage(myParameterName, SIM_POWER, theModelListMap);
199 				maxVoltage = thePowerMacroPtrMap.CalculateVoltage(myParameterName, MAX_POWER, theModelListMap);
200 				minVoltage = thePowerMacroPtrMap.CalculateVoltage(myParameterName, MIN_POWER, theModelListMap);
201 				myImplicitFamily += thePowerMacroPtrMap.implicitFamily;
202 			}
203 		}
204 	}
205 	definition = CPower::powerDefinitionText.SetTextAddress((text_t)myDefinition.c_str());
206 	if ( type[HIZ_BIT] ) {
207 		if ( IsEmpty(extraData->family) ) extraData->family = "cvc-noleak";
208 	}
209 	if ( myImplicitFamily != "" ) {
210 		extraData->implicitFamily = myImplicitFamily.substr(1);  // ,net1,net2 -> net1,net2
211 	}
212 }
213 
CPower(netId_t theNetId)214 CPower::CPower(netId_t theNetId) {
215 	// generic Power pointer for resistor propagation and calculated nets
216 	powerId = powerCount++;
217 //	powerSignal = "theNetName"; // TODO: Check literal
218 //	simVoltage = theNewVoltage;
219 //	maxVoltage = theNewVoltage;
220 //	minVoltage = theNewVoltage;
221 	netId = theNetId;
222 //	type[RESISTOR_BIT] = true;
223 //	type[MIN_CALCULATED_BIT] = true;
224 //	type[SIM_CALCULATED_BIT] = true;
225 //	type[MAX_CALCULATED_BIT] = true;
226 	definition = CPower::powerDefinitionText.BlankTextAddress();
227 }
228 
CPower(netId_t theNetId,voltage_t theSimVoltage,bool theCreateExtraData)229 CPower::CPower(netId_t theNetId, voltage_t theSimVoltage, bool theCreateExtraData) {
230 	// for set sim level to thePowerNetId
231 	powerId = powerCount++;
232 //	powerSignal = "theNetName"; // TODO: Check literal
233 	simVoltage = theSimVoltage;
234 //	maxVoltage = theNewVoltage;
235 //	minVoltage = theNewVoltage;
236 	netId = theNetId;
237 //	type[RESISTOR_BIT] = true;
238 //	type[MIN_CALCULATED_BIT] = true;
239 //	type[SIM_CALCULATED_BIT] = true;
240 //	type[MAX_CALCULATED_BIT] = true;
241 	flagAllShorts = true;
242 	simCalculationType = ESTIMATED_CALCULATION;
243 	definition = CPower::powerDefinitionText.BlankTextAddress();
244 	if ( theCreateExtraData ) extraData = new CExtraPowerData;
245 }
246 
CPower(netId_t theNetId,voltage_t theMinVoltage,voltage_t theSimVoltage,voltage_t theMaxVoltage,netId_t theDefaultMinNet,netId_t theDefaultSimNet,netId_t theDefaultMaxNet)247 CPower::CPower(netId_t theNetId, voltage_t theMinVoltage, voltage_t theSimVoltage, voltage_t theMaxVoltage, netId_t theDefaultMinNet, netId_t theDefaultSimNet, netId_t theDefaultMaxNet) {
248 	powerId = powerCount++;
249 //	powerSignal = "";
250 	simVoltage = theSimVoltage;
251 	maxVoltage = theMaxVoltage;
252 	minVoltage = theMinVoltage;
253 	defaultMinNet = theDefaultMinNet;
254 	defaultSimNet = theDefaultSimNet;
255 	defaultMaxNet = theDefaultMaxNet;
256 	netId = theNetId;
257 	definition = CPower::powerDefinitionText.BlankTextAddress();
258 	// type set in calling routine
259 //	type[MIN_CALCULATED_BIT] = true;
260 //	type[SIM_CALCULATED_BIT] = true;
261 //	type[MAX_CALCULATED_BIT] = true;
262 }
263 
~CPower()264 CPower::~CPower() {
265 	if ( extraData ) delete extraData;
266 }
267 
SetPowerAlias(string thePowerString,size_t theAliasStart)268 void CPower::SetPowerAlias(string thePowerString, size_t theAliasStart) {
269 	size_t myLastHierarchy = string(powerSignal()).find_last_of(HIERARCHY_DELIMITER);
270 	string myPowerAlias = "";
271 	if ( theAliasStart < thePowerString.length() ) {
272 		size_t myAliasEnd = thePowerString.find_first_of(" \t", theAliasStart);
273 		myPowerAlias = thePowerString.substr(theAliasStart + 2, myAliasEnd - theAliasStart - 2);
274 	} else if ( myLastHierarchy < strlen(powerSignal()) ) {
275 		if ( myLastHierarchy == 0 ) { // only set default powerAlias for top signals
276 			myPowerAlias = string(powerSignal()).substr(myLastHierarchy + 1);
277 		}
278 	} else {
279 		myPowerAlias = string(powerSignal());
280 	}
281 	size_t myBusStart = myPowerAlias.find_first_of("{[(<");
282 	if ( myBusStart < myPowerAlias.length() ) {
283 		myPowerAlias = myPowerAlias.substr(0, myBusStart);
284 	}
285 	extraData->powerAlias = CPower::powerDefinitionText.SetTextAddress((text_t)myPowerAlias.c_str());
286 }
287 
IsSamePower(CPower * theMatchPower)288 bool CPower::IsSamePower(CPower * theMatchPower) {
289 	return ( type == theMatchPower->type &&
290 			minVoltage == theMatchPower->minVoltage &&
291 			simVoltage == theMatchPower->simVoltage &&
292 			maxVoltage == theMatchPower->maxVoltage &&
293 			expectedMin() == theMatchPower->expectedMin() &&
294 			expectedSim() == theMatchPower->expectedSim() &&
295 			expectedMax() == theMatchPower->expectedMax() &&
296 			family() == theMatchPower->family() &&
297 			relativeFriendly == theMatchPower->relativeFriendly);
298 }
299 
IsValidSubset(CPower * theMatchPower,voltage_t theThreshold)300 bool CPower::IsValidSubset(CPower * theMatchPower, voltage_t theThreshold) {
301 	return ( (theMatchPower->type == NO_TYPE || (type[POWER_BIT] && theMatchPower->type[INPUT_BIT]) ) &&
302 			(theMatchPower->minVoltage == UNKNOWN_VOLTAGE || abs(minVoltage - theMatchPower->minVoltage) <= theThreshold) &&
303 			(theMatchPower->simVoltage == UNKNOWN_VOLTAGE || abs(simVoltage - theMatchPower->simVoltage) <= theThreshold) &&
304 			(theMatchPower->maxVoltage == UNKNOWN_VOLTAGE || abs(maxVoltage - theMatchPower->maxVoltage) <= theThreshold) &&
305 			theMatchPower->expectedMin() == "" &&
306 			theMatchPower->expectedSim() == "" &&
307 			theMatchPower->expectedMax() == "" &&
308 			IsRelative(theMatchPower, true, false));
309 }
310 
AddFamily(string thePowerString)311 void CPowerFamilyMap::AddFamily(string thePowerString) {
312 	// Valid power family definitions
313 	// family vdd VDD,VSS,...		<- family definition
314 	// sanity checks
315 	string myFamilyName;
316 	string myRelativeName;
317 	size_t	myStringBegin = thePowerString.find_first_not_of(" \t");
318 	size_t	myStringEnd = thePowerString.find_first_of(" \t", myStringBegin);
319 	assert(thePowerString.substr(myStringBegin, myStringEnd - myStringBegin) == "family");
320 	myStringBegin = thePowerString.find_first_not_of(" \t", myStringEnd);
321 	myStringEnd = thePowerString.find_first_of(" \t", myStringBegin);
322 	myFamilyName = thePowerString.substr(myStringBegin, myStringEnd - myStringBegin);
323 	string myDefinition = thePowerString.substr(myStringEnd);
324 	if ( this->count(myFamilyName) ) {
325 		if ( definition != myDefinition ) {
326 			cout << "DEBUG: duplicate family definition " << myFamilyName << " original " << definition << " new " << myDefinition << endl;
327 			assert(definition == myDefinition);
328 		}
329 		return;
330 	}
331 	while (myStringEnd < thePowerString.length()) {
332 		myStringBegin = thePowerString.find_first_not_of(", \t", myStringEnd);
333 		myStringEnd = thePowerString.find_first_of(",", myStringBegin);
334 		if ( myStringBegin < myStringEnd ) {
335 			myRelativeName = thePowerString.substr(myStringBegin, myStringEnd - myStringBegin);
336 			(*this)[myFamilyName].insert(CPower::powerDefinitionText.SetTextAddress((text_t)myRelativeName.c_str()));
337 		}
338 	}
339 }
340 
GetBasePower(CPowerPtrVector & theNetVoltagePtr_v,CVirtualNetVector & theNet_v)341 CPower * CPower::GetBasePower(CPowerPtrVector & theNetVoltagePtr_v, CVirtualNetVector & theNet_v) {
342 	CPower * myPower_p = this;
343 	netId_t myNetId = netId;
344 	netId_t myDefaultNet = UNKNOWN_NET;
345 	while ( myPower_p && ( myPower_p->type[theNet_v.calculatedBit] || myNetId != theNet_v[myNetId].nextNetId ) ) {
346 		switch ( theNet_v.calculatedBit ) {
347 		case MIN_CALCULATED_BIT: { myDefaultNet = myPower_p->defaultMinNet; break; }
348 		case SIM_CALCULATED_BIT: { myDefaultNet = myPower_p->defaultSimNet; break; }
349 		case MAX_CALCULATED_BIT: { myDefaultNet = myPower_p->defaultMaxNet; break; }
350 		default: break;
351 		}
352 		if ( myPower_p->type[theNet_v.calculatedBit] ) {
353 			if ( myDefaultNet != UNKNOWN_NET ) {
354 				myNetId = myDefaultNet;
355 			} else if ( myNetId == theNet_v[myNetId].nextNetId ) {  // no default net at master net
356 				break;
357 			}
358 		}
359 		while ( myNetId != theNet_v[myNetId].nextNetId ) {
360 			myNetId = theNet_v[myNetId].nextNetId;
361 		}
362 		myPower_p = theNetVoltagePtr_v[myNetId].full;
363 	}
364 	return(myPower_p);
365 }
366 
IsRelative(CPower * theTestPower_p,bool theDefault,bool theIsHiZRelative)367 bool CPower::IsRelative(CPower * theTestPower_p, bool theDefault, bool theIsHiZRelative) {
368 	if ( ! theTestPower_p ) return theDefault;
369 	if ( theIsHiZRelative && (type[HIZ_BIT] || theTestPower_p->type[HIZ_BIT]) ) return true;  // HiZ is always family for certain checks
370 
371 	CSet emptySet;
372 	CSet & myRelativeSet = (extraData) ? extraData->relativeSet : emptySet;
373 	CSet & myTestRelativeSet = (theTestPower_p->extraData) ? theTestPower_p->extraData->relativeSet : emptySet;
374 	if ( myRelativeSet.empty() && myTestRelativeSet.empty() ) return theDefault;
375 	bool myFriend = false, myEnemy = false, myTestFriend = false, myTestEnemy = false;
376 	bool myHasFriends = false, myHasEnemies = false, myTestHasFriends = false, myTestHasEnemies = false;
377 	// relative sets are for explicit and implicit connections. explicit overrides implicit. only check if explicit definition exists. ie implicit, test->implicit -> no check
378 
379 	if ( ! IsEmpty(family()) ) {
380 		bool myRelation = ( myRelativeSet.count(theTestPower_p->powerSignal())
381 				|| myRelativeSet.count(theTestPower_p->powerAlias())
382 				|| ( ! myTestRelativeSet.empty()
383 						&& myRelativeSet.Intersects(myTestRelativeSet) ) );
384 		if ( relativeFriendly ) {
385 			myHasFriends = true;
386 			myFriend = myRelation;
387 		} else {
388 			myHasEnemies = true;
389 			myEnemy = myRelation;
390 		}
391 	}
392 	if ( ! IsEmpty(theTestPower_p->family()) ) {
393 		bool myRelation = ( myTestRelativeSet.count(powerSignal())
394 				|| myTestRelativeSet.count(powerAlias())
395 				|| ( ! myRelativeSet.empty()
396 						&& myTestRelativeSet.Intersects(myRelativeSet) ) );
397 		if ( theTestPower_p->relativeFriendly ) {
398 			myTestHasFriends = true;
399 			myTestFriend = myRelation;
400 		} else {
401 			myTestHasEnemies = true;
402 			myTestEnemy = myRelation;
403 		}
404 	}
405 	if ( myHasFriends && myTestHasFriends ) return ( myFriend || myTestFriend );
406 	if ( myHasFriends && myTestHasEnemies ) {
407 		if ( myTestEnemy ) return false;
408 		if ( myFriend ) return true;
409 		return theDefault;
410 	}
411 	if ( myHasEnemies && myTestHasFriends ) {
412 		if ( myEnemy ) return false;
413 		if ( myTestFriend ) return true;
414 		return theDefault;
415 	}
416 	if ( myHasEnemies && myTestHasEnemies ) return ! ( myEnemy || myTestEnemy );
417 	if ( myHasFriends ) return myFriend;
418 	if ( myHasEnemies ) return ! myEnemy;
419 	if ( myTestHasFriends ) return myTestFriend;
420 	/*if ( myTestHasEnemies )*/ return ! myTestEnemy;
421 }
422 
IsRelatedPower(CPower * theTestPower_p,CPowerPtrVector & theNetVoltagePtr_v,CVirtualNetVector & theNet_v,CVirtualNetVector & theTestNet_v,bool theDefault,bool theIsHiZRelative)423 bool CPower::IsRelatedPower(CPower * theTestPower_p, CPowerPtrVector & theNetVoltagePtr_v, CVirtualNetVector & theNet_v, CVirtualNetVector & theTestNet_v,
424 		bool theDefault, bool theIsHiZRelative) {
425 	if ( ! theTestPower_p ) return theDefault;
426 	CPower * myPower_p = GetBasePower(theNetVoltagePtr_v, theNet_v);
427 	CPower * myTestPower_p = theTestPower_p->GetBasePower(theNetVoltagePtr_v, theTestNet_v);
428 	assert( myPower_p && myTestPower_p );
429 	if ( myPower_p == myTestPower_p ) return true;
430 	if ( ! IsEmpty(myPower_p->powerAlias())
431 			&& (myPower_p->powerAlias() == myTestPower_p->powerAlias() || myPower_p->powerAlias() == myTestPower_p->powerSignal()) ) return true;
432 	if ( ! IsEmpty(myTestPower_p->powerAlias()) && myTestPower_p->powerAlias() == myPower_p->powerSignal()) return true;
433 	return myPower_p->IsRelative(myTestPower_p, theDefault, theIsHiZRelative);
434 }
435 
Print(ostream & theLogFile,string theIndentation,string theRealPowerName)436 void CPower::Print(ostream & theLogFile, string theIndentation, string theRealPowerName) {
437 	if ( IsEmpty(theRealPowerName) || theRealPowerName == string(powerSignal()) ) {
438 		string myAlias = ( IsEmpty(powerAlias()) || powerSignal() == powerAlias() ) ? "" : ALIAS_DELIMITER + string(powerAlias());
439 		theLogFile << theIndentation << powerSignal() << myAlias;
440 	} else { // expanded net names
441 		theLogFile << theIndentation << "->" << theRealPowerName;
442 	}
443 	string myDefinition = StandardDefinition();
444 	theLogFile << definition; // for defined voltages
445 	if ( ! IsEmpty(myDefinition) && myDefinition != string(definition) ) {
446 		theLogFile << (IsCalculatedVoltage_(this) ? " =>" : " ->") << myDefinition;
447 	}
448 	if ( extraData && ! extraData->relativeSet.empty() ) {
449 		theLogFile << " family(";
450 		for ( auto relative_it = extraData->relativeSet.begin(); relative_it != extraData->relativeSet.end(); relative_it++ ) {
451 			theLogFile << *relative_it << ";";
452 		}
453 		theLogFile << ")";
454 	}
455 	theLogFile << endl;
456 }
457 
StandardDefinition()458 string CPower::StandardDefinition() {
459 	stringstream myDefinition;
460 	if ( simVoltage != UNKNOWN_VOLTAGE && minVoltage == simVoltage && simVoltage == maxVoltage && type[POWER_BIT] ) {
461 		myDefinition << " " << PrintParameter(minVoltage, VOLTAGE_SCALE);
462 	} else {
463 		if ( minVoltage != UNKNOWN_VOLTAGE ) myDefinition << " min" << (type[MIN_CALCULATED_BIT] ? "=" : "@") << PrintParameter(minVoltage, VOLTAGE_SCALE);
464 		if ( simVoltage != UNKNOWN_VOLTAGE ) myDefinition << " sim" << (type[SIM_CALCULATED_BIT] ? "=" : "@") << PrintParameter(simVoltage, VOLTAGE_SCALE);
465 		if ( maxVoltage != UNKNOWN_VOLTAGE ) myDefinition << " max" << (type[MAX_CALCULATED_BIT] ? "=" : "@") << PrintParameter(maxVoltage, VOLTAGE_SCALE);
466 	}
467 	if ( ! IsEmpty(expectedMin()) ) myDefinition << " expectMin@" << expectedMin();
468 	if ( ! IsEmpty(expectedSim()) ) myDefinition << " expectSim@" << expectedSim();
469 	if ( ! IsEmpty(expectedMax()) ) myDefinition << " expectMax@" << expectedMax();
470 	if ( type[HIZ_BIT] ) myDefinition << " open";
471 	if ( type[INPUT_BIT] ) myDefinition << " input";
472 	if ( type[POWER_BIT] ) myDefinition << " power";
473 	if ( type[RESISTOR_BIT] ) myDefinition << " resistor";
474 	if ( ! IsEmpty(family()) ) myDefinition << (relativeFriendly ? " permit@" : " prohibit@") << family();
475 	return(myDefinition.str());
476 }
477 
MaxVoltage(netId_t theNetId)478 voltage_t CPowerPtrVector::MaxVoltage(netId_t theNetId) {
479 	if ( theNetId == UNKNOWN_NET ) return UNKNOWN_VOLTAGE;
480 	if ( (*this)[theNetId].full == NULL ) return UNKNOWN_VOLTAGE;
481 	return (*this)[theNetId].full->maxVoltage;
482 }
483 
MinVoltage(netId_t theNetId)484 voltage_t CPowerPtrVector::MinVoltage(netId_t theNetId) {
485 	if ( theNetId == UNKNOWN_NET ) return UNKNOWN_VOLTAGE;
486 	if ( (*this)[theNetId].full == NULL ) return UNKNOWN_VOLTAGE;
487 	return (*this)[theNetId].full->minVoltage;
488 }
489 
SimVoltage(netId_t theNetId)490 voltage_t CPowerPtrVector::SimVoltage(netId_t theNetId) {
491 	if ( theNetId == UNKNOWN_NET ) return UNKNOWN_VOLTAGE;
492 	if ( (*this)[theNetId].full == NULL ) return UNKNOWN_VOLTAGE;
493 	return (*this)[theNetId].full->simVoltage;
494 }
495 
Clear()496 void CPowerPtrList::Clear() {
497 	while ( ! empty() ) {
498 		delete front();
499 		pop_front();
500 	}
501 }
502 
Clear(CPowerPtrVector & theLeakVoltage_v,CPowerPtrVector & theNetVoltage_v,netId_t theNetCount)503 void CPowerPtrList::Clear(CPowerPtrVector & theLeakVoltage_v, CPowerPtrVector & theNetVoltage_v, netId_t theNetCount) {
504 	while ( ! empty() ) {
505 		netId_t myNetId = front()->netId;
506 		if ( myNetId != UNKNOWN_NET && theNetCount > 0 ) {
507 			if ( theLeakVoltage_v.size() > myNetId && theLeakVoltage_v[myNetId].full && theLeakVoltage_v[myNetId].full == front() ) {
508 				theLeakVoltage_v[myNetId].full = NULL;
509 			}
510 			if ( theNetVoltage_v.size() > myNetId && theNetVoltage_v[myNetId].full && theNetVoltage_v[myNetId].full == front() ) {
511 				theNetVoltage_v[myNetId].full = NULL;
512 			}
513 		}
514 		delete front();
515 		pop_front();
516 	}
517 	CPower::powerDefinitionText.Clear();
518 }
519 
Clear()520 void CPowerPtrMap::Clear() {
521 	while ( ! empty() ) {
522 		delete begin()->second;
523 		erase(begin());
524 	}
525 }
526 
SetPowerLimits(voltage_t & theMaxPower,voltage_t & theMinPower)527 void CPowerPtrList::SetPowerLimits(voltage_t& theMaxPower, voltage_t& theMinPower) {
528 	theMaxPower = MIN_VOLTAGE;
529 	theMinPower = MAX_VOLTAGE;
530 	for ( CPowerPtrList::iterator power_ppit = begin(); power_ppit != end(); power_ppit++ ) {
531 		theMinPower = min(theMinPower, (*power_ppit)->minVoltage);
532 		theMaxPower = max(theMaxPower, (*power_ppit)->maxVoltage);
533 	}
534 }
535 
536 /*
537 CPower * CPowerPtrList::FindCalculatedPower(CEventQueue& theEventQueue, CPower * theCurrentPower_p, voltage_t theShortVoltage, netId_t theNetId, netId_t theDefaultNetId, CCvcDb * theCvcDb_p) {
538 	voltage_t myMinVoltage = UNKNOWN_VOLTAGE, mySimVoltage = UNKNOWN_VOLTAGE, myMaxVoltage = UNKNOWN_VOLTAGE;
539 	netId_t myDefaultMinNet = UNKNOWN_NET, myDefaultSimNet = UNKNOWN_NET, myDefaultMaxNet = UNKNOWN_NET;
540 	CPower * myPower_p;
541 	CStatus myStatus = 0;
542 	if ( theCurrentPower_p ) {
543 		myMinVoltage = theCurrentPower_p->minVoltage;
544 		myMaxVoltage = theCurrentPower_p->maxVoltage;
545 		mySimVoltage = theCurrentPower_p->simVoltage;
546 		myStatus = theCurrentPower_p->type;
547 	}
548 	if ( theEventQueue.queueType == MIN_QUEUE ) {
549 		if ( myMinVoltage != UNKNOWN_VOLTAGE ) throw EDatabaseError("FindCalculatedPower: Min " + to_string<voltage_t>(myMinVoltage));
550 		myMinVoltage = theShortVoltage;
551 		myDefaultMinNet = theDefaultNetId;
552 		myStatus[MIN_CALCULATED_BIT] = true;
553 	}
554 	if ( theEventQueue.queueType == MAX_QUEUE ) {
555 		if ( myMaxVoltage != UNKNOWN_VOLTAGE ) throw EDatabaseError("FindCalculatedPower: Max " + to_string<voltage_t>(myMaxVoltage));
556 		myMaxVoltage = theShortVoltage;
557 		myDefaultMaxNet = theDefaultNetId;
558 		myStatus[MAX_CALCULATED_BIT] = true;
559 	}
560 	if ( theEventQueue.queueType == SIM_QUEUE ) {
561 		if ( mySimVoltage != UNKNOWN_VOLTAGE ) throw EDatabaseError("FindCalculatedPower: Sim " + to_string<voltage_t>(mySimVoltage));
562 		mySimVoltage = theShortVoltage;
563 		myDefaultSimNet = theDefaultNetId;
564 		myStatus[SIM_CALCULATED_BIT] = true;
565 	}
566 	string myKeyString = int_to_hex<voltage_t>(myMinVoltage) + int_to_hex<voltage_t>(mySimVoltage) + int_to_hex<voltage_t>(myMaxVoltage);
567 	try {
568 		if (myMinVoltage != UNKNOWN_VOLTAGE && mySimVoltage != UNKNOWN_VOLTAGE && myMinVoltage > mySimVoltage) {
569 			cout << "WARNING: MIN > SIM " << myMinVoltage << " > " << mySimVoltage << " for " << theCvcDb_p->NetName(theNetId, PRINT_CIRCUIT_ON) << endl;
570 		}
571 		if (myMaxVoltage != UNKNOWN_VOLTAGE && mySimVoltage != UNKNOWN_VOLTAGE && myMaxVoltage < mySimVoltage) {
572 			cout << "WARNING: MAX < SIM " << myMaxVoltage << " < " << mySimVoltage << " for " << theCvcDb_p->NetName(theNetId, PRINT_CIRCUIT_ON) << endl;
573 		}
574 		myPower_p = calculatedPowerPtrMap.at(myKeyString);
575 	}
576 	catch (const out_of_range& oor_exception) {
577 		if ( debug_cvc ) cout << "DEBUG: creating power: " << myKeyString << " " << myMinVoltage << "/" << mySimVoltage << "/" << myMaxVoltage << endl;
578 		myPower_p = new CPower(myMinVoltage, mySimVoltage, myMaxVoltage, myDefaultMinNet, myDefaultSimNet, myDefaultMaxNet);
579 		myPower_p->type = myStatus;
580 		calculatedPowerPtrMap[myKeyString] = myPower_p;
581 	}
582 	return(myPower_p);
583 }
584 
585 CPower * CPowerPtrList::FindCalculatedPower(voltage_t theMinVoltage, voltage_t theSimVoltage, voltage_t theMaxVoltage, netId_t theNetId, CCvcDb * theCvcDb_p) {
586 	CPower * myPower_p;
587 	string myKeyString = int_to_hex<voltage_t>(theMinVoltage) + int_to_hex<voltage_t>(theSimVoltage) + int_to_hex<voltage_t>(theMaxVoltage);
588 	try {
589 		if (theMinVoltage != UNKNOWN_VOLTAGE && theSimVoltage != UNKNOWN_VOLTAGE && theMinVoltage > theSimVoltage) {
590 			cout << "WARNING: MIN > SIM " << theMinVoltage << " > " << theSimVoltage << " for " << theCvcDb_p->NetName(theNetId, PRINT_CIRCUIT_ON) << endl;
591 		}
592 		if (theMaxVoltage != UNKNOWN_VOLTAGE && theSimVoltage != UNKNOWN_VOLTAGE && theMaxVoltage < theSimVoltage) {
593 			cout << "WARNING: MAX < SIM " << theMaxVoltage << " < " << theSimVoltage << " for " << theCvcDb_p->NetName(theNetId, PRINT_CIRCUIT_ON) << endl;
594 		}
595 		myPower_p = calculatedPowerPtrMap.at(myKeyString);
596 	}
597 	catch (const out_of_range& oor_exception) {
598 		if ( debug_cvc ) cout << "DEBUG: creating power: " << myKeyString << endl;
599 		myPower_p = new CPower(theMinVoltage, theSimVoltage, theMaxVoltage);
600 		myPower_p->type[MIN_CALCULATED_BIT] = true;
601 		myPower_p->type[SIM_CALCULATED_BIT] = true;
602 		myPower_p->type[MAX_CALCULATED_BIT] = true;
603 		calculatedPowerPtrMap[myKeyString] = myPower_p;
604 	}
605 	return(myPower_p);
606 }
607 */
608 
609 /*
610 // Changed 2014/7/23 to always create new Power node
611 CPower * CPowerPtrList::FindCalculatedPower(CEventQueue& theEventQueue, CPower * theCurrentPower_p, voltage_t theShortVoltage, netId_t theNetId, netId_t theDefaultNetId, CCvcDb * theCvcDb_p) {
612 	voltage_t myMinVoltage = UNKNOWN_VOLTAGE, mySimVoltage = UNKNOWN_VOLTAGE, myMaxVoltage = UNKNOWN_VOLTAGE;
613 	netId_t myDefaultMinNet = UNKNOWN_NET, myDefaultSimNet = UNKNOWN_NET, myDefaultMaxNet = UNKNOWN_NET;
614 	CPower * myPower_p;
615 	CStatus myStatus = 0, myActiveStatus = 0;
616 	if ( theCurrentPower_p ) {
617 		myMinVoltage = theCurrentPower_p->minVoltage;
618 		myMaxVoltage = theCurrentPower_p->maxVoltage;
619 		mySimVoltage = theCurrentPower_p->simVoltage;
620 		myDefaultMinNet = theCurrentPower_p->defaultMinNet;
621 		myDefaultMaxNet = theCurrentPower_p->defaultMaxNet;
622 		myDefaultSimNet = theCurrentPower_p->defaultSimNet;
623 		myStatus = theCurrentPower_p->type;
624 		myActiveStatus = theCurrentPower_p->active;
625 	} else {
626 		myStatus[CALCULATED_BIT] = true;
627 	}
628 	if ( theCvcDb_p->netVoltagePtr_v[theDefaultNetId] && theCvcDb_p->netVoltagePtr_v[theDefaultNetId]->type[HIZ_BIT] ) {
629 		myStatus[HIZ_BIT] = true;
630 	}
631 	if ( theEventQueue.queueType == MIN_QUEUE ) {
632 		if ( myMinVoltage != UNKNOWN_VOLTAGE ) throw EDatabaseError("FindCalculatedPower: Min " + to_string<voltage_t>(myMinVoltage));
633 		myMinVoltage = theShortVoltage;
634 		myDefaultMinNet = theDefaultNetId;
635 		myStatus[MIN_CALCULATED_BIT] = true;
636 		myActiveStatus[MIN_ACTIVE] = true;
637 	}
638 	if ( theEventQueue.queueType == MAX_QUEUE ) {
639 		if ( myMaxVoltage != UNKNOWN_VOLTAGE ) throw EDatabaseError("FindCalculatedPower: Max " + to_string<voltage_t>(myMaxVoltage));
640 		myMaxVoltage = theShortVoltage;
641 		myDefaultMaxNet = theDefaultNetId;
642 		myStatus[MAX_CALCULATED_BIT] = true;
643 		myActiveStatus[MAX_ACTIVE] = true;
644 	}
645 	if ( theEventQueue.queueType == SIM_QUEUE ) {
646 		if ( mySimVoltage != UNKNOWN_VOLTAGE ) throw EDatabaseError("FindCalculatedPower: Sim " + to_string<voltage_t>(mySimVoltage));
647 		mySimVoltage = theShortVoltage;
648 		myDefaultSimNet = theDefaultNetId;
649 		myStatus[SIM_CALCULATED_BIT] = true;
650 	}
651 //	string myKeyString = int_to_hex<voltage_t>(myMinVoltage) + int_to_hex<voltage_t>(mySimVoltage) + int_to_hex<voltage_t>(myMaxVoltage);
652 //	try {
653 		if (myMinVoltage != UNKNOWN_VOLTAGE && mySimVoltage != UNKNOWN_VOLTAGE && myMinVoltage > mySimVoltage) {
654 			cout << "WARNING: MIN > SIM " << myMinVoltage << " > " << mySimVoltage << " for " << theCvcDb_p->NetName(theNetId, PRINT_CIRCUIT_ON) << endl;
655 		}
656 		if (myMaxVoltage != UNKNOWN_VOLTAGE && mySimVoltage != UNKNOWN_VOLTAGE && myMaxVoltage < mySimVoltage) {
657 			cout << "WARNING: MAX < SIM " << myMaxVoltage << " < " << mySimVoltage << " for " << theCvcDb_p->NetName(theNetId, PRINT_CIRCUIT_ON) << endl;
658 		}
659 //		myPower_p = calculatedPowerPtrMap.at(myKeyString);
660 //	}
661 //	catch (const out_of_range& oor_exception) {
662 //		if ( debug_cvc ) cout << "DEBUG: creating power: " << myKeyString << " " << myMinVoltage << "/" << mySimVoltage << "/" << myMaxVoltage << endl;
663 		myPower_p = new CPower(myMinVoltage, mySimVoltage, myMaxVoltage, myDefaultMinNet, myDefaultSimNet, myDefaultMaxNet);
664 		myPower_p->type = myStatus;
665 		myPower_p->active = myActiveStatus;
666 //		calculatedPowerPtrMap[myKeyString] = myPower_p;
667 //	}
668 	return(myPower_p);
669 }
670 */
671 
ResetPowerPointerVector(size_t theSize)672 void CPowerPtrVector::ResetPowerPointerVector(size_t theSize) {
673 	this->clear();
674 	this->reserve(theSize);
675 	this->resize(theSize);
676 	for ( size_t index_it = 0; index_it < theSize; index_it++ ) {
677 		(*this)[index_it].full = NULL;
678 	}
679 	this->powerPtrType_v.clear();
680 	this->powerPtrType_v.reserve(theSize);
681 	this->powerPtrType_v.resize(theSize, UNKNOWN_POWER_PTR);
682 }
683 
CalculatePower(CEventQueue & theEventQueue,voltage_t theShortVoltage,netId_t theNetId,netId_t theDefaultNetId,CCvcDb * theCvcDb_p,string theCalculation)684 void CPowerPtrVector::CalculatePower(CEventQueue& theEventQueue, voltage_t theShortVoltage, netId_t theNetId, netId_t theDefaultNetId, CCvcDb * theCvcDb_p, string theCalculation) {
685 	if ( (*this)[theNetId].full == NULL ) {
686 		(*this)[theNetId].full = new CPower(theNetId);
687 	}
688 	CPower * myPower_p = (*this)[theNetId].full;
689 	CPower * myDefaultPower_p = (*this)[theDefaultNetId].full;
690 	if ( myDefaultPower_p ) {
691 		if ( myDefaultPower_p->type[HIZ_BIT] ) {
692 			myPower_p->type[HIZ_BIT] = true;
693 		}
694 		if ( myDefaultPower_p->extraData ) {
695 			if ( ! myPower_p->extraData ) myPower_p->extraData = new CExtraPowerData;
696 			myPower_p->extraData->family = myDefaultPower_p->family();
697 			myPower_p->extraData->implicitFamily = myDefaultPower_p->implicitFamily();
698 			myPower_p->extraData->relativeSet = myDefaultPower_p->extraData->relativeSet;
699 		}
700 		myPower_p->relativeFriendly = myDefaultPower_p->relativeFriendly;
701 	}
702 	if ( theEventQueue.queueType == MIN_QUEUE ) {
703 		if ( myPower_p->minVoltage != UNKNOWN_VOLTAGE ) {
704 			cout << "DEBUG: CalculatePower: Min " << to_string<voltage_t>(myPower_p->minVoltage) << " at " << theCvcDb_p->NetName(theNetId) << endl;
705 			//throw EDatabaseError("CalculatePower: Min " + to_string<voltage_t>(myPower_p->minVoltage) + " at " + theCvcDb_p->NetName(theNetId));
706 		}
707 		myPower_p->minVoltage = theShortVoltage;
708 		myPower_p->defaultMinNet = theDefaultNetId;
709 		myPower_p->type[MIN_CALCULATED_BIT] = true;
710 		myPower_p->active[MIN_ACTIVE] = true;
711 		if ( myDefaultPower_p && myDefaultPower_p->minVoltage != UNKNOWN_VOLTAGE ) {
712 			if ( theShortVoltage < myDefaultPower_p->minVoltage ) {
713 				myPower_p->minCalculationType = DOWN_CALCULATION;
714 			} else if ( theShortVoltage > myDefaultPower_p->minVoltage ) {
715 				myPower_p->minCalculationType = UP_CALCULATION;
716 			}
717 		}
718 	}
719 	if ( theEventQueue.queueType == MAX_QUEUE ) {
720 		if ( myPower_p->maxVoltage != UNKNOWN_VOLTAGE ) {
721 			cout << "DEBUG: CalculatePower: Max " << to_string<voltage_t>(myPower_p->maxVoltage) << " at " << theCvcDb_p->NetName(theNetId) << endl;
722 			//throw EDatabaseError("CalculatePower: Max " + to_string<voltage_t>(myPower_p->maxVoltage) + " at " + theCvcDb_p->NetName(theNetId));
723 		}
724 		myPower_p->maxVoltage = theShortVoltage;
725 		myPower_p->defaultMaxNet = theDefaultNetId;
726 		myPower_p->type[MAX_CALCULATED_BIT] = true;
727 		myPower_p->active[MAX_ACTIVE] = true;
728 		if ( myDefaultPower_p && myDefaultPower_p->maxVoltage != UNKNOWN_VOLTAGE ) {
729 			if ( theShortVoltage < myDefaultPower_p->maxVoltage ) {
730 				myPower_p->maxCalculationType = DOWN_CALCULATION;
731 			} else if ( theShortVoltage > myDefaultPower_p->maxVoltage ) {
732 				myPower_p->maxCalculationType = UP_CALCULATION;
733 			}
734 		}
735 	}
736 	if ( theEventQueue.queueType == SIM_QUEUE ) {
737 		if ( myPower_p->simVoltage != UNKNOWN_VOLTAGE ) {
738 			throw EDatabaseError("CalculatePower: Sim " + to_string<voltage_t>(myPower_p->simVoltage) + " at " + theCvcDb_p->NetName(theNetId));
739 		}
740 		myPower_p->simVoltage = theShortVoltage;
741 		myPower_p->defaultSimNet = theDefaultNetId;
742 		myPower_p->type[SIM_CALCULATED_BIT] = true;
743 		if ( myPower_p->powerAlias()[0] == '\0' ) {
744 			CPower * myDefaultPower_p;
745 			if ( myPower_p->minVoltage == myPower_p->simVoltage ) {
746 				myDefaultPower_p = myPower_p->GetBasePower(theCvcDb_p->netVoltagePtr_v, theCvcDb_p->minNet_v);
747 			} else if ( myPower_p->maxVoltage == myPower_p->simVoltage ) {
748 				myDefaultPower_p = myPower_p->GetBasePower(theCvcDb_p->netVoltagePtr_v, theCvcDb_p->maxNet_v);
749 			} else {
750 				myDefaultPower_p = myPower_p->GetBasePower(theCvcDb_p->netVoltagePtr_v, theCvcDb_p->simNet_v);
751 			}
752 			if ( myDefaultPower_p && ! IsEmpty(myDefaultPower_p->powerAlias()) ) {
753 				if (gDebug_cvc) cout << "Setting alias for " << theCvcDb_p->NetName(theNetId) << " = " << myDefaultPower_p->powerAlias() << endl;
754 				if ( ! myPower_p->extraData ) myPower_p->extraData = new CExtraPowerData;
755 				myPower_p->extraData->powerAlias = myDefaultPower_p->powerAlias();
756 			}
757 		}
758 		if ( myDefaultPower_p && myDefaultPower_p->simVoltage != UNKNOWN_VOLTAGE ) {
759 			if ( theShortVoltage < myDefaultPower_p->simVoltage ) {
760 				myPower_p->simCalculationType = DOWN_CALCULATION;
761 			} else if ( theShortVoltage > myDefaultPower_p->simVoltage ) {
762 				myPower_p->simCalculationType = UP_CALCULATION;
763 			}
764 		}
765 
766 	}
767 	if (myPower_p->minVoltage != UNKNOWN_VOLTAGE && myPower_p->simVoltage != UNKNOWN_VOLTAGE && myPower_p->minVoltage > myPower_p->simVoltage) {
768 		cout << "WARNING: MIN > SIM " << myPower_p->minVoltage << " > " << myPower_p->simVoltage << " for " << theCvcDb_p->NetName(theNetId, PRINT_CIRCUIT_ON) << endl;
769 	}
770 	if (myPower_p->maxVoltage != UNKNOWN_VOLTAGE && myPower_p->simVoltage != UNKNOWN_VOLTAGE && myPower_p->maxVoltage < myPower_p->simVoltage) {
771 		cout << "WARNING: MAX < SIM " << myPower_p->maxVoltage << " < " << myPower_p->simVoltage << " for " << theCvcDb_p->NetName(theNetId, PRINT_CIRCUIT_ON) << endl;
772 	}
773 	if ( myPower_p->definition[0] == '\0' ) {
774 		myPower_p->definition = CPower::powerDefinitionText.SetTextAddress((text_t)theCalculation.c_str());
775 	}
776 	if (gDebug_cvc) cout << "INFO: Calculated voltage at net " << myPower_p->netId << " default Min/Sim/Max: " << myPower_p->defaultMinNet << "/"
777 			<< myPower_p->defaultSimNet << "/" << myPower_p->defaultMaxNet << endl;
778 }
779 
780 /*
781 CPower * CPowerPtrList::FindCalculatedPower(voltage_t theMinVoltage, voltage_t theSimVoltage, voltage_t theMaxVoltage, netId_t theNetId, CCvcDb * theCvcDb_p) {
782 	CPower * myPower_p;
783 //	string myKeyString = int_to_hex<voltage_t>(theMinVoltage) + int_to_hex<voltage_t>(theSimVoltage) + int_to_hex<voltage_t>(theMaxVoltage);
784 //	try {
785 		if (theMinVoltage != UNKNOWN_VOLTAGE && theSimVoltage != UNKNOWN_VOLTAGE && theMinVoltage > theSimVoltage) {
786 			cout << "WARNING: MIN > SIM " << theMinVoltage << " > " << theSimVoltage << " for " << theCvcDb_p->NetName(theNetId, PRINT_CIRCUIT_ON) << endl;
787 		}
788 		if (theMaxVoltage != UNKNOWN_VOLTAGE && theSimVoltage != UNKNOWN_VOLTAGE && theMaxVoltage < theSimVoltage) {
789 			cout << "WARNING: MAX < SIM " << theMaxVoltage << " < " << theSimVoltage << " for " << theCvcDb_p->NetName(theNetId, PRINT_CIRCUIT_ON) << endl;
790 		}
791 //		myPower_p = calculatedPowerPtrMap.at(myKeyString);
792 //	}
793 //	catch (const out_of_range& oor_exception) {
794 //		if ( debug_cvc ) cout << "DEBUG: creating power: " << myKeyString << endl;
795 		myPower_p = new CPower(theMinVoltage, theSimVoltage, theMaxVoltage);
796 		myPower_p->type[MIN_CALCULATED_BIT] = true;
797 		myPower_p->type[SIM_CALCULATED_BIT] = true;
798 		myPower_p->type[MAX_CALCULATED_BIT] = true;
799 //		calculatedPowerPtrMap[myKeyString] = myPower_p;
800 //	}
801 	return(myPower_p);
802 }
803 */
804 
SetFamilies(CPowerFamilyMap & thePowerFamilyMap)805 void CPowerPtrList::SetFamilies(CPowerFamilyMap & thePowerFamilyMap) {
806 	string myFamilyName;
807 	string myRelativeName;
808 	string myFamilyList;
809 	string myImplicitFamilyList;
810 	size_t	myStringBegin;
811 	size_t	myStringEnd;
812 	for ( CPowerPtrList::iterator powerPtr_ppit = begin(); powerPtr_ppit != end(); powerPtr_ppit++ ) {
813 		myFamilyList = (*powerPtr_ppit)->family();
814 		myImplicitFamilyList = (*powerPtr_ppit)->implicitFamily();
815 		if ( ! IsEmpty(myFamilyList) ) {
816 			myStringBegin = myFamilyList.find_first_not_of(",", 0);
817 			myStringEnd = myFamilyList.find_first_of(",", myStringBegin);
818 			if ( ! (*powerPtr_ppit)->extraData ) (*powerPtr_ppit)->extraData = new CExtraPowerData;
819 			while (myStringBegin < myFamilyList.length()) {
820 				myRelativeName = myFamilyList.substr(myStringBegin, myStringEnd - myStringBegin);
821 				if ( thePowerFamilyMap.count(myRelativeName) > 0 ) {
822 					(*powerPtr_ppit)->extraData->relativeSet.insert(thePowerFamilyMap[myRelativeName].begin(), thePowerFamilyMap[myRelativeName].end());
823 				} else {
824 					(*powerPtr_ppit)->extraData->relativeSet.insert(CPower::powerDefinitionText.SetTextAddress((text_t)myRelativeName.c_str()));
825 				}
826 				myStringBegin = myFamilyList.find_first_not_of(",", myStringEnd);
827 				myStringEnd = myFamilyList.find_first_of(",", myStringBegin);
828 			}
829 		// explicit family list overrides implicit list
830 		} else if ( ! IsEmpty(myImplicitFamilyList) ) {
831 			myStringBegin = myImplicitFamilyList.find_first_not_of(",", 0);
832 			myStringEnd = myImplicitFamilyList.find_first_of(",", myStringBegin);
833 			if ( ! (*powerPtr_ppit)->extraData ) (*powerPtr_ppit)->extraData = new CExtraPowerData;
834 			while (myStringBegin < myImplicitFamilyList.length()) {
835 				myRelativeName = myImplicitFamilyList.substr(myStringBegin, myStringEnd - myStringBegin);
836 				if ( thePowerFamilyMap.count(myRelativeName) > 0 ) {
837 					(*powerPtr_ppit)->extraData->relativeSet.insert(thePowerFamilyMap[myRelativeName].begin(), thePowerFamilyMap[myRelativeName].end());
838 				} else {
839 					(*powerPtr_ppit)->extraData->relativeSet.insert(CPower::powerDefinitionText.SetTextAddress((text_t)myRelativeName.c_str()));
840 				}
841 				myStringBegin = myImplicitFamilyList.find_first_not_of(",", myStringEnd);
842 				myStringEnd = myImplicitFamilyList.find_first_of(",", myStringBegin);
843 			}
844 		}
845 	}
846 }
847 
PowerDefinition()848 string CPower::PowerDefinition() {
849 	string myPowerDefinition = "";
850 	if ( minVoltage != UNKNOWN_VOLTAGE ) myPowerDefinition += " min" + ( ((type[MIN_CALCULATED_BIT]) ? "=" : "@") + to_string<voltage_t>(minVoltage));
851 	if ( simVoltage != UNKNOWN_VOLTAGE ) myPowerDefinition += " sim" + ( ((type[SIM_CALCULATED_BIT]) ? "=" : "@") + to_string<voltage_t>(simVoltage));
852 	if ( maxVoltage != UNKNOWN_VOLTAGE ) myPowerDefinition += " max" + ( ((type[MAX_CALCULATED_BIT]) ? "=" : "@") + to_string<voltage_t>(maxVoltage));
853 	if ( ! IsEmpty(expectedMin()) ) myPowerDefinition += " min?" + expectedMin();
854 	if ( ! IsEmpty(expectedSim()) ) myPowerDefinition += " sim?" + expectedSim();
855 	if ( ! IsEmpty(expectedMax()) ) myPowerDefinition += " max?" + expectedMax();
856 	if ( type[HIZ_BIT] ) myPowerDefinition += " open";
857 	if ( type[INPUT_BIT] ) myPowerDefinition += " input";
858 	if ( type[RESISTOR_BIT] ) myPowerDefinition += " resistor";
859 //	if ( definition != "" ) myPowerDefinition += " '" + definition + "'";
860 	if ( ! IsEmpty(family()) ) myPowerDefinition += " '" + family() + ((relativeFriendly) ? " allowed'" : " prohibited'");
861 	return myPowerDefinition;
862 }
863 
CalculateExpectedValue(string theEquation,netStatus_t theType,CModelListMap & theModelListMap)864 string CPowerPtrMap::CalculateExpectedValue(string theEquation, netStatus_t theType, CModelListMap & theModelListMap) {
865 	if ( theEquation == "open" ) return theEquation;
866 	if ( this->count(theEquation) > 0 ) return theEquation;
867 	if ( IsValidVoltage_(theEquation) ) return theEquation;
868 	voltage_t myVoltage = CalculateVoltage(theEquation, theType, theModelListMap);
869 	return(to_string<float>(float(myVoltage) / VOLTAGE_SCALE));
870 }
871 
872 #define UNKNOWN_TOKEN (float(MAX_VOLTAGE) * 2)
CalculateVoltage(string theEquation,netStatus_t theType,CModelListMap & theModelListMap,bool thePermitUndefinedFlag,bool theResetImplicitFlag)873 voltage_t CPowerPtrMap::CalculateVoltage(string theEquation, netStatus_t theType, CModelListMap & theModelListMap, bool thePermitUndefinedFlag, bool theResetImplicitFlag) {
874 	if ( theResetImplicitFlag) implicitFamily = "";
875 	list<string> * myTokenList_p;
876 	// exceptions cause memory leaks
877 	if ( IsValidVoltage_(theEquation) ) {
878 		myTokenList_p = new(list<string>);
879 		myTokenList_p->push_back(theEquation);
880 	} else {
881 		myTokenList_p = postfix(theEquation);
882 	}
883 	list<float> myVoltageStack;
884 	float	myVoltage;
885 	string	myOperators = "+-/*<>";
886 	for ( auto token_pit = myTokenList_p->begin(); token_pit != myTokenList_p->end(); token_pit++ ) {
887 		if ( myOperators.find(*token_pit) < myOperators.length() ) {
888 			if ( myVoltageStack.size() < 2 ) throw EPowerError("invalid equation: " + theEquation);
889 			myVoltage = myVoltageStack.back();
890 			myVoltageStack.pop_back();
891 			if ( myVoltage == UNKNOWN_TOKEN ) {
892 				if ( ( *token_pit == "<" ) || ( *token_pit == ">" ) ) {  // min/max keep value on stack
893 					;
894 				} else {  // arithmetic with invalid values gives invalid value
895 					myVoltageStack.back() = UNKNOWN_TOKEN;
896 				}
897 			} else if ( myVoltageStack.back() == UNKNOWN_TOKEN ) {
898 				if ( ( *token_pit == "<" ) || ( *token_pit == ">" ) ) {  // min/max replace with last voltage
899 					myVoltageStack.back() = myVoltage;
900 				}
901 			} else if ( *token_pit == "+" ) {
902 				myVoltageStack.back() += myVoltage;
903 			} else if ( *token_pit == "-" ) {
904 				myVoltageStack.back() -= myVoltage;
905 			} else if ( *token_pit == "*" ) {
906 				myVoltageStack.back() *= myVoltage;
907 			} else if ( *token_pit == "/" ) {
908 				myVoltageStack.back() /= myVoltage;
909 			} else if ( *token_pit == "<" ) {
910 				myVoltageStack.back() = min(myVoltageStack.back(), myVoltage);
911 			} else if ( *token_pit == ">" ) {
912 				myVoltageStack.back() = max(myVoltageStack.back(), myVoltage);
913 			} else throw EPowerError("invalid operator: " + *token_pit);
914 		} else if ( isalpha((*token_pit)[0]) ) { // power name
915 			if ( this->count(*token_pit) > 0 ) { // power definition exists
916 				if ( theType == MIN_POWER ) {
917 					if ( (*this)[*token_pit]->minVoltage == UNKNOWN_VOLTAGE ) {
918 						myVoltageStack.push_back(UNKNOWN_TOKEN);
919 					} else {
920 						myVoltageStack.push_back(float((*this)[*token_pit]->minVoltage) / VOLTAGE_SCALE);
921 					}
922 				}
923 				if ( theType == SIM_POWER ) {
924 					if ( (*this)[*token_pit]->simVoltage == UNKNOWN_VOLTAGE ) {
925 						myVoltageStack.push_back(UNKNOWN_TOKEN);
926 					} else {
927 						myVoltageStack.push_back(float((*this)[*token_pit]->simVoltage) / VOLTAGE_SCALE);
928 					}
929 				}
930 				if ( theType == MAX_POWER ) {
931 					if ( (*this)[*token_pit]->maxVoltage == UNKNOWN_VOLTAGE ) {
932 						myVoltageStack.push_back(UNKNOWN_TOKEN);
933 					} else {
934 						myVoltageStack.push_back(float((*this)[*token_pit]->maxVoltage) / VOLTAGE_SCALE);
935 					}
936 				}
937 				implicitFamily += "," + *token_pit;
938 			} else if ( (*token_pit).substr(0,4) == "Vth[" && (*token_pit).back() == ']' ){
939 				string myModelName = "M " + (*token_pit).substr(4, (*token_pit).length() - 5);
940 				if ( theModelListMap.count(myModelName) > 0 ) {
941 					if ( theModelListMap[myModelName].Vth == UNKNOWN_VOLTAGE ) {
942 						theModelListMap[myModelName].Vth = CalculateVoltage(theModelListMap[myModelName].vthDefinition, SIM_POWER, theModelListMap, false, false);
943 						// recursive call fails if contains undefined macros. does not reset implicit power list
944 					}
945 					myVoltageStack.push_back(float(theModelListMap[myModelName].Vth) / VOLTAGE_SCALE);
946 				} else {
947 					throw EModelError("power definition error: " + theEquation + " unknown Vth for " + myModelName.substr(2));
948 				}
949 			} else if ( thePermitUndefinedFlag ){
950 				myVoltageStack.push_back(UNKNOWN_TOKEN);
951 			} else {
952 				throw EPowerError("undefined macro: " + *token_pit);
953 			}
954 		} else if ( IsValidVoltage_(*token_pit) ) {
955 			myVoltageStack.push_back(from_string<float>(*token_pit));
956 		} else {
957 			throw EPowerError("invalid power calculation token: " + *token_pit);
958 		}
959 	}
960 	delete myTokenList_p;
961 	if ( myVoltageStack.size() != 1 ) throw EPowerError("invalid equation: " + theEquation);
962 	if ( myVoltageStack.front() > float(MAX_VOLTAGE) ) {
963 		cout << "Warning: equation contains undefined tokens: " << theEquation << endl;
964 		return(UNKNOWN_VOLTAGE);
965 	}
966 	return ( round(myVoltageStack.front() * VOLTAGE_SCALE + 0.1) );
967 }
968 
RelativeVoltage(CPowerPtrMap & thePowerMacroPtrMap,netStatus_t theType,CModelListMap & theModelListMap)969 voltage_t CPower::RelativeVoltage(CPowerPtrMap & thePowerMacroPtrMap, netStatus_t theType, CModelListMap & theModelListMap) {
970 	if ( ! extraData || IsEmpty(extraData->family) ) return UNKNOWN_VOLTAGE;
971 	try {
972 		return thePowerMacroPtrMap.CalculateVoltage(string(*(extraData->relativeSet.begin())), theType, theModelListMap);
973 	}
974 	catch (...) {
975 		return UNKNOWN_VOLTAGE;
976 	}
977 }
978 
CInstancePower(string theDefinition)979 CInstancePower::CInstancePower(string theDefinition) {
980 	theDefinition = trim_(theDefinition);
981 	//size_t	myAtIndex;
982 	size_t	myStringEnd = theDefinition.find_first_of(" \t");  // skip #instance
983 	size_t	myStringBegin = theDefinition.find_first_not_of(" \t", myStringEnd);
984 	myStringEnd = theDefinition.find_first_of(" \t", myStringBegin);
985 	instanceName = theDefinition.substr(myStringBegin, myStringEnd - myStringBegin);
986 	myStringBegin = theDefinition.find_first_not_of(" \t", myStringEnd);
987 	myStringEnd = theDefinition.find_first_of(" \t", myStringBegin);
988 	powerFile = theDefinition.substr(myStringBegin, myStringEnd - myStringBegin);
989 }
990