Skip to content

Commit

Permalink
Changes for version 0.17.9 and 0.17.10
Browse files Browse the repository at this point in the history
Added setup option to list models and power setting suggestions
No unrelated short checks when short tolerance > 0
Use leak limit with limited to sim shorts (fixed comparison bug)
  • Loading branch information
d-m-bailey committed Feb 8, 2019
1 parent 57d36db commit e6aa59a
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 16 deletions.
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.69])
AC_INIT(CVC, [0.17.8], [cvc@shuharisystem.com])
AC_INIT(CVC, [0.17.10], [cvc@shuharisystem.com])
AC_CONFIG_SRCDIR(src)
AC_CONFIG_HEADERS([config.h])
AC_USE_SYSTEM_EXTENSIONS
Expand Down
10 changes: 6 additions & 4 deletions src/CCvcDb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,16 @@ void CCvcDb::ReportShort(deviceId_t theDeviceId) {
(IsPmos_(deviceType_v[theDeviceId]) && myConnections.simGateVoltage - myMaxVoltage == myConnections.device_p->model_p->Vth);
myLeakCurrent = myConnections.EstimatedCurrent(myVthFlag);
}
bool myUnrelatedFlag = ! myConnections.simSourcePower_p->IsRelatedPower(myConnections.simDrainPower_p, netVoltagePtr_v, simNet_v, simNet_v, true);
bool myUnrelatedFlag = cvcParameters.cvcShortErrorThreshold == 0
&& ! myConnections.simSourcePower_p->IsRelatedPower(myConnections.simDrainPower_p, netVoltagePtr_v, simNet_v, simNet_v, true); // no unrelated checks for real sim checks
bool myCheckLeakLimit = cvcParameters.cvcShortErrorThreshold == 0 || myMaxVoltage - myMinVoltage > cvcParameters.cvcShortErrorThreshold;
if ( ( myCheckLeakLimit && ExceedsLeakLimit_(myLeakCurrent) ) // flag leaks with large current
|| myUnrelatedFlag // flag leaks between unrelated power
|| ( myMaxVoltage != myMinVoltage && ! myVthFlag // ignore leaks between same voltages or at Vth
&& ( ( IsExternalPower_(myConnections.simSourcePower_p)
&& IsExternalPower_(myConnections.simDrainPower_p)
&& myMaxVoltage - myMinVoltage > cvcParameters.cvcShortErrorThreshold ) // flag leaks between power nets
&& myMaxVoltage - myMinVoltage > cvcParameters.cvcShortErrorThreshold
&& ( cvcParameters.cvcShortErrorThreshold == 0 || ExceedsLeakLimit_(myLeakCurrent) )) // flag leaks between power nets
|| myConnections.simSourcePower_p->flagAllShorts || myConnections.simDrainPower_p->flagAllShorts ) ) ) { // flag nets for calculated logic levels
// errorCount[LEAK]++;
if ( cvcParameters.cvcCircuitErrorLimit == 0 || IncrementDeviceError(theDeviceId, LEAK) < cvcParameters.cvcCircuitErrorLimit ) {
Expand Down Expand Up @@ -1086,7 +1088,7 @@ string CCvcDb::AdjustSimVoltage(CEventQueue& theEventQueue, deviceId_t theDevice
myCalculation = " Limited sim to min" + myCalculation;
debugFile << myCalculation << " " << NetName(myTargetNet) << endl;
if ( thePropagationType != POWER_NETS_ONLY && myOriginalVoltage < myMinTargetVoltage
&& theConnections.EstimatedCurrent(theVoltage, myMinTargetVoltage, mySourceResistance, myMinTargetResistance) < cvcParameters.cvcLeakLimit ) {
&& theConnections.EstimatedCurrent(theVoltage, myMinTargetVoltage, mySourceResistance, myMinTargetResistance) > cvcParameters.cvcLeakLimit ) {
ReportSimShort(theDeviceId, theVoltage, myMinTargetVoltage, myCalculation);
}
// voltage drops in first pass are skipped, only report original voltage limits
Expand All @@ -1096,7 +1098,7 @@ string CCvcDb::AdjustSimVoltage(CEventQueue& theEventQueue, deviceId_t theDevice
myCalculation = " Limited sim to max" + myCalculation;
debugFile << myCalculation << " " << NetName(myTargetNet) << endl;
if ( thePropagationType != POWER_NETS_ONLY && myOriginalVoltage > myMaxTargetVoltage
&& theConnections.EstimatedCurrent(theVoltage, myMaxTargetVoltage, mySourceResistance, myMaxTargetResistance) < cvcParameters.cvcLeakLimit ) {
&& theConnections.EstimatedCurrent(theVoltage, myMaxTargetVoltage, mySourceResistance, myMaxTargetResistance) > cvcParameters.cvcLeakLimit ) {
ReportSimShort(theDeviceId, theVoltage, myMaxTargetVoltage, myCalculation);
}
// voltage drops in first pass are skipped, only report original voltage limits
Expand Down
1 change: 1 addition & 0 deletions src/CCvcDb.hh
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ public:
voltage_t theMinVoltage, voltage_t theMaxVoltage,
CDeviceIdVector & theFirstDrain_v, CDeviceIdVector & theNextDrain_v, CNetIdVector & theSourceNet_v);
bool IsOppositeLogic(netId_t theFirstNet, netId_t theSecondNet);
void PrintNetSuggestions();

// error
void PrintFuseError(netId_t theTargetNetId, CConnection & theConnections);
Expand Down
149 changes: 144 additions & 5 deletions src/CCvcDb_init.cc
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ CCvcDb::CCvcDb(int argc, const char * argv[]) :
if ( ! IsAlphanumeric(reportPrefix) ) throw EFatalError("invalid prefix " + reportPrefix);
} else if ( strcmp(argv[cvcArgIndex], "-v") == 0 || strcmp(argv[cvcArgIndex], "--version") == 0 ) {
cout << "CVC: Circuit Validation Check Version " << CVC_VERSION << endl;
} else if ( strcmp(argv[cvcArgIndex], "-s") == 0 || strcmp(argv[cvcArgIndex], "--setup") == 0 ) {
cout << "CVC: Creating setup files " << endl;
gSetup_cvc = true;
} else {
cout << "WARNING: unrecognized option " << argv[cvcArgIndex] << endl;
}
Expand Down Expand Up @@ -545,8 +548,10 @@ returnCode_t CCvcDb::SetDeviceModels() {
// parameterModelPtrMap[myDevice_p->parameters] = myDevice_p->model_p;
// }
if ( myDevice_p->model_p == NULL ) {
reportFile << "ERROR: No model match " << (*circuit_ppit)->name << "/" << myDevice_p->name;
reportFile << " " << myDevice_p->parameters << endl;
if ( ! gSetup_cvc ) {
reportFile << "ERROR: No model match " << (*circuit_ppit)->name << "/" << myDevice_p->name;
reportFile << " " << myDevice_p->parameters << endl;
}
string myParameterString = trim_(string(myDevice_p->parameters));
myErrorModelSet.insert(myParameterString.substr(0, myParameterString.find(" ", 2)));
myModelError = true;
Expand Down Expand Up @@ -581,12 +586,14 @@ returnCode_t CCvcDb::SetDeviceModels() {
isDeviceModelSet = true;
if ( myModelError ) {
if ( ! myErrorModelSet.empty() ) {
reportFile << "Missing models" << endl;
reportFile << "Missing models" << endl << endl;
for ( auto model_pit = myErrorModelSet.begin(); model_pit != myErrorModelSet.end(); model_pit++) {
reportFile << *model_pit << endl;
reportFile << model_pit->substr(2) << " " << model_pit->substr(0,1) << endl;
}
}
reportFile << "ERROR: Model file problem" << endl;
if ( ! gSetup_cvc ) {
reportFile << endl << "ERROR: Model file problem" << endl;
}
return(FAIL);
} else {
return (cvcParameters.cvcModelListMap.SetVoltageTolerances(reportFile, cvcParameters.cvcPowerMacroPtrMap));
Expand Down Expand Up @@ -1698,3 +1705,135 @@ bool CCvcDb::IsOppositeLogic(netId_t theFirstNet, netId_t theSecondNet) {
return (inverterNet_v[theFirstNet] == theSecondNet || theFirstNet == inverterNet_v[theSecondNet]);
}

void CCvcDb::PrintNetSuggestions() {
reportFile << "CVC: Possible power definitions" << endl;
unordered_map<netId_t, pair<deviceId_t, deviceId_t>> myBulkCount;
CDeviceIdVector myNextBulk_v;
ResetVector<CDeviceIdVector>(myNextBulk_v, deviceCount, UNKNOWN_DEVICE);
for (deviceId_t device_it = 0; device_it < deviceCount; device_it++) {
if ( bulkNet_v[device_it] == UNKNOWN_NET ) continue;
if ( IsMos_(deviceType_v[device_it]) && sourceNet_v[device_it] != drainNet_v[device_it] ) { // only count non-capacitor mosfet
if ( myBulkCount[bulkNet_v[device_it]].first++ > 0 ) {
myNextBulk_v[device_it] = myBulkCount[bulkNet_v[device_it]].second;
}
myBulkCount[bulkNet_v[device_it]].second = device_it;
}
}
map<string, deviceId_t> myDeviceCount;
for (CModelListMap::iterator keyModelListPair_pit = cvcParameters.cvcModelListMap.begin(); keyModelListPair_pit != cvcParameters.cvcModelListMap.end(); keyModelListPair_pit++) {
for (CModelList::iterator model_pit = keyModelListPair_pit->second.begin(); model_pit != keyModelListPair_pit->second.end(); model_pit++) {
myDeviceCount[model_pit->name] = 0;
}
}
reportFile << "CVC: Bulk > SD" << endl << endl;
for( auto net_it = 0; net_it < netCount; net_it++ ) {
if ( netVoltagePtr_v[net_it] ) continue;
if ( myBulkCount.count(net_it) && myBulkCount[net_it].first > connectionCount_v[net_it].SourceDrainCount() ) {
reportFile << NetName(net_it, PRINT_CIRCUIT_ON) << " SD/bulk " << connectionCount_v[net_it].SourceDrainCount() << "/" << myBulkCount[net_it].first;
for ( auto count_pit = myDeviceCount.begin(); count_pit != myDeviceCount.end(); count_pit++ ) {
count_pit->second = 0;
}
deviceId_t device_it = myBulkCount[net_it].second;
while ( device_it != UNKNOWN_DEVICE ) {
CInstance * myInstance_p = instancePtr_v[deviceParent_v[device_it]];
deviceId_t myDeviceOffset = device_it - myInstance_p->firstDeviceId;
myDeviceCount[myInstance_p->master_p->devicePtr_v[myDeviceOffset]->model_p->name]++;
device_it = myNextBulk_v[device_it];
}
for ( auto count_pit = myDeviceCount.begin(); count_pit != myDeviceCount.end(); count_pit++ ) {
if ( count_pit->second > 0 ) {
reportFile << " " << count_pit->first << "(" << count_pit->second << ")";
}
}
reportFile << endl;
}
/*
if ( myBulkCount.count(net_it) && myBulkCount[net_it] > connectionCount_v[net_it].SourceDrainCount() ) {
reportFile << NetName(net_it, PRINT_CIRCUIT_ON) << " SD/bulk " << connectionCount_v[net_it].SourceDrainCount() << "/" << myBulkCount[net_it];
for (CModelListMap::iterator keyModelListPair_pit = cvcParameters.cvcModelListMap.begin(); keyModelListPair_pit != cvcParameters.cvcModelListMap.end(); keyModelListPair_pit++) {
deviceId_t myDeviceCount = 0;
string myModelName;
for (CModelList::iterator model_pit = keyModelListPair_pit->second.begin(); model_pit != keyModelListPair_pit->second.end(); model_pit++) {
if ( IsMos_(model_pit->type) ) {
myModelName = model_pit->name;
CDevice * myDevice_p = model_pit->firstDevice_p;
while (myDevice_p) {
CCircuit * myParent_p = myDevice_p->parent_p;
deviceId_t myLocalDeviceId = myDevice_p->offset;
for (instanceId_t instance_it = 0; instance_it < myParent_p->instanceId_v.size(); instance_it++) {
CInstance * myInstance_p = instancePtr_v[myParent_p->instanceId_v[instance_it]];
deviceId_t myDeviceId = myInstance_p->firstDeviceId + myLocalDeviceId;
if ( bulkNet_v[myDeviceId] == net_it ) {
myDeviceCount++;
}
}
myDevice_p = myDevice_p->nextDevice_p;
}
}
}
if ( myDeviceCount > 0 ) {
reportFile << " " << myModelName << "(" << myDeviceCount << ")";
}
}
reportFile << endl;
}
*/
}
reportFile << endl;
reportFile << "CVC: INPUT PORTS" << endl << endl;
for( auto net_it = 0; net_it < topCircuit_p->portCount; net_it++ ) {
if ( netVoltagePtr_v[net_it] ) continue;
unordered_set<netId_t> myCheckedNets;
unordered_set<netId_t> myUncheckedNets;
myUncheckedNets.insert(net_it);
bool myIsPossibleInput = true;
bool myHasGateConnection = false;
if ( firstGate_v[net_it] == UNKNOWN_DEVICE && firstSource_v[net_it] == UNKNOWN_DEVICE && firstDrain_v[net_it] == UNKNOWN_DEVICE ) {
reportFile << NetName(net_it, PRINT_CIRCUIT_ON) << " NO_CONNECTIONS" << endl;
}
while( ! myUncheckedNets.empty() && myUncheckedNets.size() < 10 && myIsPossibleInput ) { // 10 is arbitrary limit to prevent runaway
netId_t myCheckNet = *(myUncheckedNets.begin());
myCheckedNets.insert(myCheckNet);
myUncheckedNets.erase(myUncheckedNets.begin());
if ( firstGate_v[myCheckNet] != UNKNOWN_DEVICE ) {
myHasGateConnection = true;
}
//cout << "checked " << myCheckedNets.size() << " unchecked " << myUncheckedNets.size() << endl;
for ( deviceId_t device_it = firstSource_v[myCheckNet]; device_it != UNKNOWN_DEVICE && myIsPossibleInput; device_it = nextSource_v[device_it] ) {
netId_t mySearchNet = drainNet_v[device_it];
if ( ( IsMos_(deviceType_v[device_it]) && mySearchNet != gateNet_v[device_it] )
|| ( ! IsMos_(device_it) && netVoltagePtr_v[mySearchNet] ) ) {
myIsPossibleInput = false;
} else if ( ! IsMos_(deviceType_v[device_it]) ) {
if ( myCheckedNets.count(mySearchNet) == 0 && myUncheckedNets.count(mySearchNet) == 0 ) {
if ( myUncheckedNets.size() < 10 ) {
myUncheckedNets.insert(mySearchNet);
} else {
myIsPossibleInput = false;
}
}
}
}
for ( deviceId_t device_it = firstDrain_v[myCheckNet]; device_it != UNKNOWN_DEVICE && myIsPossibleInput; device_it = nextDrain_v[device_it] ) {
netId_t mySearchNet = sourceNet_v[device_it];
if ( ( IsMos_(deviceType_v[device_it]) && mySearchNet != gateNet_v[device_it] )
|| ( ! IsMos_(device_it) && netVoltagePtr_v[mySearchNet] ) ) {
myIsPossibleInput = false;
} else if ( ! IsMos_(deviceType_v[device_it]) ) {
if ( myCheckedNets.count(mySearchNet) == 0 && myUncheckedNets.count(mySearchNet) == 0 ) {
if ( myUncheckedNets.size() < 10 ) {
myUncheckedNets.insert(mySearchNet);
} else {
myIsPossibleInput = false;
}
}
}
}
}
if ( myIsPossibleInput && myHasGateConnection ) {
reportFile << NetName(net_it, PRINT_CIRCUIT_ON) << endl;
}
}
reportFile << endl;
}

12 changes: 11 additions & 1 deletion src/CCvcDb_main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,11 @@ void CCvcDb::VerifyCircuitForAllModes(int argc, const char * argv[]) {
if ( gInteractive_cvc && --gContinueCount < 1
&& InteractiveCvc(STAGE_START) == SKIP ) continue;
if ( modelFileStatus != OK || powerFileStatus != OK || fuseFileStatus != OK ) {
reportFile << "ERROR: skipped due to problems in model/power/fuse files" << endl;
if ( gSetup_cvc ) {
reportFile << endl << "CVC: Setup check complete." << endl;
} else {
reportFile << "ERROR: skipped due to problems in model/power/fuse files" << endl;
}
continue;
}

Expand All @@ -145,6 +149,9 @@ void CCvcDb::VerifyCircuitForAllModes(int argc, const char * argv[]) {
cvcParameters.cvcPowerPtrList.SetPowerLimits(maxPower, minPower);
LinkDevices();
OverrideFuses();
if ( gSetup_cvc ) {
PrintNetSuggestions();
}
reportFile << PrintProgress(&lastSnapshot, "EQUIV ") << endl;
reportFile << "Power nets " << CPower::powerCount << endl;
// DumpStatistics(parameterModelPtrMap, "parameter->model map", logFile);
Expand All @@ -154,6 +161,9 @@ void CCvcDb::VerifyCircuitForAllModes(int argc, const char * argv[]) {
if ( gInteractive_cvc && --gContinueCount < 1 && InteractiveCvc(STAGE_LINK) == SKIP ) {
continue;
}
if ( gSetup_cvc ) {
continue;
}

/// Stage 3) Calculate voltages across resistors
/// - Calculated resistance
Expand Down
16 changes: 12 additions & 4 deletions src/CCvcParameters.cc
Original file line number Diff line number Diff line change
Expand Up @@ -328,8 +328,12 @@ returnCode_t CCvcParameters::LoadModels() {
cvcModelListMap.Clear();
cvcModelListMap.filename = cvcModelFilename;
if ( myModelFile.fail() ) {
reportFile << "ERROR: Could not open " << cvcModelFilename << endl;
return (FAIL);
if ( gSetup_cvc ) {
return(OK);
} else {
reportFile << "ERROR: Could not open " << cvcModelFilename << endl;
return (FAIL);
}
// throw EFatalError("Could not open " + cvcModelFilename);
// exit(1);
}
Expand Down Expand Up @@ -385,8 +389,12 @@ returnCode_t CCvcParameters::LoadPower() {
cvcPowerFamilyMap.clear();
cvcPowerMacroPtrMap.clear();
if ( myPowerFile.fail() ) {
reportFile << "ERROR: Could not open " << cvcPowerFilename << endl;
return (FAIL);
if ( gSetup_cvc ) {
return(OK);
} else {
reportFile << "ERROR: Could not open " << cvcPowerFilename << endl;
return (FAIL);
}
// throw EFatalError("Could not open " + cvcPowerFilename);
// exit(1);
}
Expand Down
3 changes: 2 additions & 1 deletion src/Cvc.hh
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@
#ifndef CVC_H_
#define CVC_H_

#define CVC_VERSION "0.17.8"
#define CVC_VERSION "0.17.10"

extern bool gDebug_cvc;
extern bool gSetup_cvc;
extern bool gInterrupted;
extern bool gInteractive_cvc;

Expand Down
1 change: 1 addition & 0 deletions src/cvc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ char vv_suffix[2], vv_trailer[2];
///@}

bool gDebug_cvc = false;
bool gSetup_cvc = false;
bool gInterrupted = false; //!< for detecting interrupts

HIST_ENTRY **gHistoryList; //!< readline history
Expand Down

0 comments on commit e6aa59a

Please sign in to comment.