Skip to content

Commit

Permalink
Changes for version 1.1.0
Browse files Browse the repository at this point in the history
Added model check. (currently only Vb checks. no check_cvc support.
  • Loading branch information
d-m-bailey committed Dec 18, 2020
1 parent 38c74b0 commit c6551a0
Show file tree
Hide file tree
Showing 14 changed files with 239 additions and 66 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, [1.0.0], [[email protected]])
AC_INIT(CVC, [1.1.0], [[email protected]])
AC_CONFIG_SRCDIR(src)
AC_CONFIG_HEADERS([config.h])
AC_USE_SYSTEM_EXTENSIONS
Expand Down
4 changes: 2 additions & 2 deletions src/CCircuit.hh
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ public:
CTextVector internalSignal_v;
CDevicePtrVector devicePtr_v;
CDevicePtrVector subcircuitPtr_v;
vector<array<deviceId_t, 4>> deviceErrorCount_v;
vector<array<deviceId_t, 4>> devicePrintCount_v;
vector<array<deviceId_t, 5>> deviceErrorCount_v;
vector<array<deviceId_t, 5>> devicePrintCount_v;
CInstanceIdVector instanceId_v;
CInstanceIdVector instanceHashId_v;

Expand Down
3 changes: 3 additions & 0 deletions src/CCvcDb.hh
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ public:
returnCode_t LoadCellErrorLimits();
void LoadCellChecksums();
void LoadNetChecks();
void LoadModelChecks();

// error
void PrintFuseError(netId_t theTargetNetId, CConnection & theConnections);
Expand All @@ -230,7 +231,9 @@ public:
void FindVbsError(ogzstream & theErrorFile, voltage_t theParameter, CFullConnection & theConnections, instanceId_t theInstance_p, string theDisplayParameter);
void FindVdsError(ogzstream & theErrorFile, voltage_t theParameter, CFullConnection & theConnections, instanceId_t theInstance_p, string theDisplayParameter);
void FindVgsError(ogzstream & theErrorFile, voltage_t theParameter, CFullConnection & theConnections, instanceId_t theInstance_p, string theDisplayParameter);
void FindModelError(ogzstream & theErrorFile, CModelCheck &theCheck, CFullConnection & theConnections, instanceId_t theInstanceId);
void PrintOverVoltageError(ogzstream & theErrorFile, CFullConnection & theConnections, cvcError_t theErrorIndex, string theExplanation, instanceId_t theInstance_p);
void PrintModelError(ogzstream & theErrorFile, CFullConnection & theConnections, CModelCheck & theCheck, instanceId_t theInstanceId);
void FindAllOverVoltageErrors();
void AppendErrorFile(string theTempFileName, string theHeading, int theErrorSubIndex);
void FindNmosGateVsSourceErrors();
Expand Down
77 changes: 58 additions & 19 deletions src/CCvcDb_error.cc
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ void CCvcDb::FindVdsError(ogzstream & theErrorFile, voltage_t theParameter, CFul
}

void CCvcDb::FindVgsError(ogzstream & theErrorFile, voltage_t theParameter, CFullConnection & theConnections, instanceId_t theInstanceId, string theDisplayParameter) {
theParameter += cvcParameters.cvcOvervoltageErrorThreshold;
theParameter += cvcParameters.cvcOvervoltageErrorThreshold;
if ( ( theConnections.validMinGate && theConnections.validMaxSource
&& abs(theConnections.minGateVoltage - theConnections.maxSourceVoltage) > theParameter )
|| ( theConnections.validMaxGate && theConnections.validMinSource
Expand All @@ -186,9 +186,9 @@ void CCvcDb::FindVgsError(ogzstream & theErrorFile, voltage_t theParameter, CFul
&& abs(theConnections.minGateVoltage - theConnections.maxDrainVoltage) > theParameter )
|| ( theConnections.validMaxGate && theConnections.validMinDrain
&& abs(theConnections.maxGateVoltage - theConnections.minDrainVoltage) > theParameter ) ) {
PrintOverVoltageError(theErrorFile, theConnections, OVERVOLTAGE_VGS, "Overvoltage Error:Gate vs Source/Drain:" + theDisplayParameter, theInstanceId);
PrintOverVoltageError(theErrorFile, theConnections, OVERVOLTAGE_VGS, "Overvoltage Error:Gate vs Source/Drain:" + theDisplayParameter, theInstanceId);
} else if ( ! cvcParameters.cvcLeakOvervoltage ) {
return ;
return ;
} else if ( ( theConnections.validMinGateLeak && theConnections.validMaxSourceLeak
&& abs(theConnections.minGateLeakVoltage - theConnections.maxSourceLeakVoltage) > theParameter )
|| ( theConnections.validMaxGateLeak && theConnections.validMinSourceLeak
Expand All @@ -209,19 +209,50 @@ void CCvcDb::FindVgsError(ogzstream & theErrorFile, voltage_t theParameter, CFul
&& abs(theConnections.minSourceLeakVoltage) > theParameter )
|| ( ! theConnections.validMaxGateLeak && theConnections.validMinDrainLeak
&& abs(theConnections.minDrainLeakVoltage) > theParameter ) ) {
PrintOverVoltageError(theErrorFile, theConnections, OVERVOLTAGE_VGS, "Overvoltage Error:Gate vs Source/Drain: (logic ok)" + theDisplayParameter, theInstanceId);
PrintOverVoltageError(theErrorFile, theConnections, OVERVOLTAGE_VGS, "Overvoltage Error:Gate vs Source/Drain: (logic ok)" + theDisplayParameter, theInstanceId);
}
}

void CCvcDb::FindModelError(ogzstream & theErrorFile, CModelCheck & theCheck, CFullConnection & theConnections, instanceId_t theInstanceId) {
bool myError = false;
if ( theCheck.parameter == "Vb" ) {
if ( ! (theConnections.validMinBulk && theConnections.validMaxBulk) ) {
myError = true;
} else {
if ( ! IsEmpty(theCheck.minExclusiveText) ) {
myError |= theConnections.minBulkVoltage <= theCheck.minExclusiveVoltage;
} else if ( ! IsEmpty(theCheck.minInclusiveText) ) {
myError |= theConnections.minBulkVoltage < theCheck.minInclusiveVoltage;
}
if ( ! IsEmpty(theCheck.maxExclusiveText) ) {
myError |= theConnections.maxBulkVoltage >= theCheck.maxExclusiveVoltage;
} else if ( ! IsEmpty(theCheck.maxInclusiveText) ) {
myError |= theConnections.maxBulkVoltage > theCheck.maxInclusiveVoltage;
}
}
}
if ( myError ) {
PrintModelError(theErrorFile, theConnections, theCheck, theInstanceId);
}
}

void CCvcDb::PrintOverVoltageError(ogzstream & theErrorFile, CFullConnection & theConnections, cvcError_t theErrorIndex, string theExplanation, instanceId_t theInstanceId) {
if ( cvcParameters.cvcCircuitErrorLimit == 0 || IncrementDeviceError(theConnections.deviceId, theErrorIndex) < cvcParameters.cvcCircuitErrorLimit ) {
theErrorFile << theExplanation << endl;
bool myLeakCheckFlag = ( theExplanation.find("logic ok") < string::npos );
PrintDeviceWithAllConnections(theInstanceId, theConnections, theErrorFile, myLeakCheckFlag);
theErrorFile << endl;
}
}

void CCvcDb::PrintModelError(ogzstream & theErrorFile, CFullConnection & theConnections, CModelCheck & theCheck, instanceId_t theInstanceId) {
if ( cvcParameters.cvcCircuitErrorLimit == 0 || IncrementDeviceError(theConnections.deviceId, MODEL_CHECK) < cvcParameters.cvcCircuitErrorLimit ) {
theErrorFile << "Model error: " << theCheck.check << endl;
PrintDeviceWithAllConnections(theInstanceId, theConnections, theErrorFile, false);
theErrorFile << endl;
}
}

void CCvcDb::PrintOverVoltageError(ogzstream & theErrorFile, CFullConnection & theConnections, cvcError_t theErrorIndex, string theExplanation, instanceId_t theInstanceId) {
if ( cvcParameters.cvcCircuitErrorLimit == 0 || IncrementDeviceError(theConnections.deviceId, theErrorIndex) < cvcParameters.cvcCircuitErrorLimit ) {
theErrorFile << theExplanation << endl;
bool myLeakCheckFlag = ( theExplanation.find("logic ok") < string::npos );
PrintDeviceWithAllConnections(theInstanceId, theConnections, theErrorFile, myLeakCheckFlag);
theErrorFile << endl;
}
}

void CCvcDb::FindAllOverVoltageErrors() {
CFullConnection myConnections;
reportFile << "! Checking overvoltage errors" << endl << endl;
Expand All @@ -235,8 +266,11 @@ void CCvcDb::FindAllOverVoltageErrors() {
ogzstream myVdsErrorFile(myVdsErrorFileName);
myVdsErrorFile << "! Checking Vds overvoltage errors" << endl << endl;
string myVgsErrorFileName(tmpnam(NULL));
ogzstream myVgsErrorFile(myVgsErrorFileName);
myVgsErrorFile << "! Checking Vgs overvoltage errors" << endl << endl;
ogzstream myVgsErrorFile(myVgsErrorFileName);
myVgsErrorFile << "! Checking Vgs overvoltage errors" << endl << endl;
string myModelErrorFileName(tmpnam(NULL));
ogzstream myModelErrorFile(myModelErrorFileName);
myModelErrorFile << "! Checking Model errors" << endl << endl;

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++) {
Expand All @@ -255,7 +289,7 @@ void CCvcDb::FindAllOverVoltageErrors() {
}
if ( model_pit->maxVgs != UNKNOWN_VOLTAGE ) {
myVgsDisplayParameter = " Vgs=" + PrintToleranceParameter(model_pit->maxVgsDefinition, model_pit->maxVgs, VOLTAGE_SCALE) + " " + model_pit->ConditionString();
}
}
while (myDevice_p) {
CCircuit * myParent_p = myDevice_p->parent_p;
for (instanceId_t instance_it = 0; instance_it < myParent_p->instanceId_v.size(); instance_it++) {
Expand All @@ -268,7 +302,10 @@ void CCvcDb::FindAllOverVoltageErrors() {
if ( model_pit->maxVbg != UNKNOWN_VOLTAGE ) FindVbgError(myVbgErrorFile, model_pit->maxVbg, myConnections, myInstanceId, myVbgDisplayParameter);
if ( model_pit->maxVbs != UNKNOWN_VOLTAGE ) FindVbsError(myVbsErrorFile, model_pit->maxVbs, myConnections, myInstanceId, myVbsDisplayParameter);
if ( model_pit->maxVds != UNKNOWN_VOLTAGE ) FindVdsError(myVdsErrorFile, model_pit->maxVds, myConnections, myInstanceId, myVdsDisplayParameter);
if ( model_pit->maxVgs != UNKNOWN_VOLTAGE ) FindVgsError(myVgsErrorFile, model_pit->maxVgs, myConnections, myInstanceId, myVgsDisplayParameter);
if ( model_pit->maxVgs != UNKNOWN_VOLTAGE ) FindVgsError(myVgsErrorFile, model_pit->maxVgs, myConnections, myInstanceId, myVgsDisplayParameter);
for ( auto check_pit = model_pit->checkList.begin(); check_pit != model_pit->checkList.end(); check_pit++ ) {
FindModelError(myModelErrorFile, *check_pit, myConnections, myInstanceId);
}
}
myDevice_p = myDevice_p->nextDevice_p;
}
Expand All @@ -277,11 +314,13 @@ void CCvcDb::FindAllOverVoltageErrors() {
myVbgErrorFile.close();
myVbsErrorFile.close();
myVdsErrorFile.close();
myVgsErrorFile.close();
myVgsErrorFile.close();
myModelErrorFile.close();
AppendErrorFile(myVbgErrorFileName, "! Checking Vbg overvoltage errors", OVERVOLTAGE_VBG - OVERVOLTAGE_VBG);
AppendErrorFile(myVbsErrorFileName, "! Checking Vbs overvoltage errors", OVERVOLTAGE_VBS - OVERVOLTAGE_VBG);
AppendErrorFile(myVdsErrorFileName, "! Checking Vds overvoltage errors", OVERVOLTAGE_VDS - OVERVOLTAGE_VBG);
AppendErrorFile(myVgsErrorFileName, "! Checking Vgs overvoltage errors", OVERVOLTAGE_VGS - OVERVOLTAGE_VBG);
AppendErrorFile(myVgsErrorFileName, "! Checking Vgs overvoltage errors", OVERVOLTAGE_VGS - OVERVOLTAGE_VBG);
AppendErrorFile(myModelErrorFileName, "! Checking Model errors", MODEL_CHECK - OVERVOLTAGE_VBG);
}

void CCvcDb::AppendErrorFile(string theTempFileName, string theHeading, int theErrorSubIndex) {
Expand Down
122 changes: 89 additions & 33 deletions src/CCvcDb_init.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1740,45 +1740,101 @@ void CCvcDb::LoadNetChecks() {
///
/// Currently supports:
/// "inverter_input=output": check to verify inverter output ground/power are the same as input ground/power
/// "opposite_logic": verify that 2 nets are logically opposite
if ( IsEmpty(cvcParameters.cvcNetCheckFile) ) return;
igzstream myNetCheckFile;
myNetCheckFile.open(cvcParameters.cvcNetCheckFile);
if ( myNetCheckFile.fail() ) {
throw EFatalError("Could not open level shifter file: '" + cvcParameters.cvcNetCheckFile + "'");
/// "opposite_logic": verify that 2 nets are logically opposite
if ( IsEmpty(cvcParameters.cvcNetCheckFile) ) return;

igzstream myNetCheckFile;
myNetCheckFile.open(cvcParameters.cvcNetCheckFile);
if ( myNetCheckFile.fail() ) {
throw EFatalError("Could not open level shifter file: '" + cvcParameters.cvcNetCheckFile + "'");
exit(1);

}
string myInput;
reportFile << "CVC: Reading net checks..." << endl;
while ( getline(myNetCheckFile, myInput) ) {

}
string myInput;
reportFile << "CVC: Reading net checks..." << endl;
while ( getline(myNetCheckFile, myInput) ) {
if ( myInput.substr(0, 1) == "#" ) continue; // ignore comments

size_t myStringBegin = myInput.find_first_not_of(" \t");
size_t myStringEnd = myInput.find_first_of(" \t", myStringBegin);
string myNetName = myInput.substr(myStringBegin, myStringEnd - myStringBegin);
set<netId_t> * myNetIdList = FindUniqueNetIds(myNetName); // expands buses and hierarchy
if ( myNetIdList->empty() ) {
reportFile << "ERROR: Could not expand net " << myNetName << endl;
}
myStringBegin = myInput.find_first_not_of(" \t", myStringEnd);
myStringEnd = myInput.find_first_of(" \t", myStringBegin);
string myOperation = myInput.substr(myStringBegin, myStringEnd - myStringBegin);
if ( myOperation == "inverter_input=output" ) {
inverterInputOutputCheckList.push_front(myNetName);

size_t myStringBegin = myInput.find_first_not_of(" \t");
size_t myStringEnd = myInput.find_first_of(" \t", myStringBegin);
string myNetName = myInput.substr(myStringBegin, myStringEnd - myStringBegin);
set<netId_t> * myNetIdList = FindUniqueNetIds(myNetName); // expands buses and hierarchy
if ( myNetIdList->empty() ) {
reportFile << "ERROR: Could not expand net " << myNetName << endl;
}
myStringBegin = myInput.find_first_not_of(" \t", myStringEnd);
myStringEnd = myInput.find_first_of(" \t", myStringBegin);
string myOperation = myInput.substr(myStringBegin, myStringEnd - myStringBegin);
if ( myOperation == "inverter_input=output" ) {
inverterInputOutputCheckList.push_front(myNetName);
} else if ( myOperation == "opposite_logic" ) {
myStringBegin = myInput.find_first_not_of(" \t", myStringEnd);
myStringEnd = myInput.find_first_of(" \t", myStringBegin);
string myOpposite = myInput.substr(myStringBegin, myStringEnd - myStringBegin);
string myOpposite = myInput.substr(myStringBegin, myStringEnd - myStringBegin);
size_t myDelimiter = myNetName.find_last_of(HIERARCHY_DELIMITER);
if ( myDelimiter < myNetName.npos ) {
myOpposite = myNetName.substr(0, myDelimiter) + HIERARCHY_DELIMITER + myOpposite;
}
oppositeLogicList.push_front(make_pair(myNetName, myOpposite));
} else {
reportFile << "ERROR: unknown check " << myInput << endl;
}
}
myNetCheckFile.close();
}

oppositeLogicList.push_front(make_pair(myNetName, myOpposite));
} else {
reportFile << "ERROR: unknown check " << myInput << endl;
}
}
myNetCheckFile.close();
}

void CCvcDb::LoadModelChecks() {
/// Load model checks from file.
///
/// Currently supports:
/// "Vb": check bulk voltage
if ( IsEmpty(cvcParameters.cvcModelCheckFile) ) return;

igzstream myModelCheckFile;
myModelCheckFile.open(cvcParameters.cvcModelCheckFile);
if ( myModelCheckFile.fail() ) {
throw EFatalError("Could not open model check file: '" + cvcParameters.cvcModelCheckFile + "'");
exit(1);

}
string myInput;
reportFile << "CVC: Reading model checks..." << endl;
while ( getline(myModelCheckFile, myInput) ) {
if ( myInput.substr(0, 1) == "#" ) continue; // ignore comments

size_t myStringBegin = myInput.find_first_not_of(" \t");
size_t myStringEnd = myInput.find_first_of(" \t", myStringBegin);
string myModelName = myInput.substr(myStringBegin, myStringEnd - myStringBegin);
CModelList * myModelList_p = cvcParameters.cvcModelListMap.FindModelList(myModelName);
if ( ! myModelList_p ) {
reportFile << "WARNING: could not find model " << myModelName << " for model check '" << myInput << "'" << endl;
continue;

}
myStringBegin = myInput.find_first_not_of(" \t", myStringEnd);
myStringEnd = myInput.find_first_of(" \t", myStringBegin);
string myCheck = myInput.substr(myStringBegin, myStringEnd - myStringBegin);
myStringEnd = myInput.find_first_of(" \t=<>", myStringBegin);
string myParameter = myInput.substr(myStringBegin, myStringEnd - myStringBegin);
myStringBegin = myInput.find_first_of("=<>", myStringEnd);
myStringEnd = myInput.find_first_not_of("=<>", myStringBegin);
string myOperation = myInput.substr(myStringBegin, myStringEnd - myStringBegin);
myStringBegin = myInput.find_first_not_of("=<>", myStringEnd);
myStringEnd = myInput.find_first_of(" \t", myStringBegin);
string myValue = myInput.substr(myStringBegin, myStringEnd - myStringBegin);
if ( myParameter == "Vb" ) {
if ( myOperation != "=" ) {
reportFile << "WARNING: unknown operation '" << myOperation << "' in model check '" << myInput << "'" << endl;
continue;

}
for ( auto model_pit = myModelList_p->begin(); model_pit != myModelList_p->end(); model_pit++ ) {
model_pit->checkList.push_front(CModelCheck(myCheck, "Vb", myValue, "", myValue, ""));
}
} else {
reportFile << "WARNING: unknown parameter '" << myParameter << "' in model check '" << myInput << "'" << endl;
}
}
myModelCheckFile.close();
}

3 changes: 2 additions & 1 deletion src/CCvcDb_main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ void CCvcDb::VerifyCircuitForAllModes(int argc, const char * argv[]) {
LoadCellChecksums();
CountObjectsAndLinkSubcircuits();
AssignGlobalIDs();
LoadNetChecks();
LoadNetChecks();
LoadModelChecks();
PrintLargeCircuits();
reportFile << PrintProgress(&lastSnapshot, "DB") << endl;
}
Expand Down
1 change: 1 addition & 0 deletions src/CCvcDb_print.cc
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,7 @@ void CCvcDb::PrintErrorTotals() {
reportFile << "CVC: Overvoltage-VBS: " << errorCount[OVERVOLTAGE_VBS] << endl;
reportFile << "CVC: Overvoltage-VDS: " << errorCount[OVERVOLTAGE_VDS] << endl;
reportFile << "CVC: Overvoltage-VGS: " << errorCount[OVERVOLTAGE_VGS] << endl;
reportFile << "CVC: Model errors: " << errorCount[MODEL_CHECK] << endl;
reportFile << "CVC: Unexpected voltage : " << errorCount[EXPECTED_VOLTAGE] << endl;
} else {
reportFile << "WARNING: Error detection incomplete" << endl;
Expand Down
2 changes: 1 addition & 1 deletion src/CCvcDb_utility.cc
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,7 @@ size_t CCvcDb::IncrementDeviceError(deviceId_t theDeviceId, int theErrorIndex) {
CInstance * myInstance_p = instancePtr_v[deviceParent_v[theDeviceId]];
CCircuit * myParent_p = myInstance_p->master_p;
int myErrorSubIndex = 0;
if ( theErrorIndex >= OVERVOLTAGE_VBG && theErrorIndex <= OVERVOLTAGE_VGS ) {
if ( theErrorIndex >= OVERVOLTAGE_VBG && theErrorIndex <= MODEL_CHECK ) {
myErrorSubIndex = theErrorIndex - OVERVOLTAGE_VBG;
}
int myMFactor = CalculateMFactor(deviceParent_v[theDeviceId]);
Expand Down
Loading

0 comments on commit c6551a0

Please sign in to comment.