Skip to content

Commit

Permalink
Changes for version 0.17.14
Browse files Browse the repository at this point in the history
Limit errors by cell name (trial).
bugfix: Prioritize leak through resistors over last nmos/pmos if lower/higher.
show undefined inverter power nets in setup mode.
show connected model counts for power nets in setup mode.
show undefined bias nets in setup mode.
propagate macros to instance power.
bugfix: interactive getdevice
added interactive error messages for devices/nets that can not be found.
display default min/sim/max in interactive.
looser matching of nets. allow subnet definitions
  • Loading branch information
d-m-bailey committed Mar 28, 2019
1 parent 3d4cf9e commit 5adcd02
Show file tree
Hide file tree
Showing 15 changed files with 271 additions and 35 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.13], [[email protected]])
AC_INIT(CVC, [0.17.14], [[email protected]])
AC_CONFIG_SRCDIR(src)
AC_CONFIG_HEADERS([config.h])
AC_USE_SYSTEM_EXTENSIONS
Expand Down
1 change: 1 addition & 0 deletions src/CCircuit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ void CCircuitPtrList::PrintAndResetCircuitErrors(CCvcDb * theCvcDb_p, deviceId_t
}
// theLogFile << endl << "! Finished" << endl << endl;
theErrorFile << endl<< "! Finished" << endl << endl;
theCvcDb_p->cellErrorCountMap.clear();
}

void CCircuit::AllocateInstances(CCvcDb * theCvcDb_p, instanceId_t theFirstInstanceId) {
Expand Down
1 change: 1 addition & 0 deletions src/CCircuit.hh
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class CCircuit {
static text_t lastSubcircuitMap;
static CTextDeviceIdMap localSubcircuitIdMap;
public:
deviceId_t errorLimit = UNKNOWN_DEVICE;
text_t name;
// local signal to local netID Map
CTextNetIdMap localSignalIdMap;
Expand Down
25 changes: 21 additions & 4 deletions src/CCvcDb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,9 @@ void CCvcDb::AlreadyShorted(CEventQueue& theEventQueue, deviceId_t theDeviceId,
netStatus_v[theConnections.sourceId][NEEDS_MIN_CONNECTION] = false;
if ( gDebug_cvc ) cout << "DEBUG: removed matching min connection check for net: " << theConnections.sourceId << " "
<< theConnections.sourceVoltage << endl;
} else if ( ! leakVoltageSet && IsNmos_(deviceType_v[theDeviceId]) && LastNmosConnection(MIN_PENDING, theConnections.sourceId) ) {
} else if ( ! leakVoltageSet
&& ( ( IsNmos_(deviceType_v[theDeviceId]) && LastNmosConnection(MIN_PENDING, theConnections.sourceId) )
|| theConnections.device_p->IsResistor() ) ) {
// remove calculated net and reroute to drain. only for initial power prop.
if ( ! myPower_p->extraData ) myPower_p->extraData = new CExtraPowerData;
myPower_p->extraData->pullDownVoltage = theConnections.drainVoltage;
Expand Down Expand Up @@ -263,7 +265,9 @@ void CCvcDb::AlreadyShorted(CEventQueue& theEventQueue, deviceId_t theDeviceId,
netStatus_v[theConnections.drainId][NEEDS_MIN_CONNECTION] = false;
if ( gDebug_cvc ) cout << "DEBUG: removed matching min connection check for net: " << theConnections.drainId << " "
<< theConnections.drainVoltage << endl;
} else if ( ! leakVoltageSet && IsNmos_(deviceType_v[theDeviceId]) && LastNmosConnection(MIN_PENDING, theConnections.drainId) ) {
} else if ( ! leakVoltageSet
&& ( ( IsNmos_(deviceType_v[theDeviceId]) && LastNmosConnection(MIN_PENDING, theConnections.drainId) )
|| theConnections.device_p->IsResistor() ) ) {
// remove calculated net and reroute to drain. only for initial power prop.
if ( ! myPower_p->extraData ) myPower_p->extraData = new CExtraPowerData;
myPower_p->extraData->pullDownVoltage = theConnections.sourceVoltage;
Expand Down Expand Up @@ -298,7 +302,9 @@ void CCvcDb::AlreadyShorted(CEventQueue& theEventQueue, deviceId_t theDeviceId,
netStatus_v[theConnections.sourceId][NEEDS_MAX_CONNECTION] = false;
if ( gDebug_cvc ) cout << "DEBUG: removed matching max connection check for net: " << theConnections.sourceId << " "
<< theConnections.sourceVoltage << endl;
} else if ( ! leakVoltageSet && IsPmos_(deviceType_v[theDeviceId]) && LastPmosConnection(MAX_PENDING, theConnections.sourceId) ) {
} else if ( ! leakVoltageSet
&& ( ( IsPmos_(deviceType_v[theDeviceId]) && LastPmosConnection(MAX_PENDING, theConnections.sourceId) )
|| theConnections.device_p->IsResistor() ) ) {
// remove calculated net and reroute to drain. only for initial power prop.
if ( ! myPower_p->extraData ) myPower_p->extraData = new CExtraPowerData;
myPower_p->extraData->pullUpVoltage = theConnections.drainVoltage;
Expand Down Expand Up @@ -330,7 +336,9 @@ void CCvcDb::AlreadyShorted(CEventQueue& theEventQueue, deviceId_t theDeviceId,
netStatus_v[theConnections.drainId][NEEDS_MAX_CONNECTION] = false;
if ( gDebug_cvc ) cout << "DEBUG: removed matching max connection check for net: " << theConnections.drainId << " "
<< theConnections.drainVoltage << endl;
} else if ( ! leakVoltageSet && IsPmos_(deviceType_v[theDeviceId]) && LastPmosConnection(MAX_PENDING, theConnections.drainId) ) {
} else if ( ! leakVoltageSet
&& ( ( IsPmos_(deviceType_v[theDeviceId]) && LastPmosConnection(MAX_PENDING, theConnections.drainId) )
|| theConnections.device_p->IsResistor() ) ) {
// remove calculated net and reroute to drain. only for initial power prop.
if ( ! myPower_p->extraData ) myPower_p->extraData = new CExtraPowerData;
myPower_p->extraData->pullUpVoltage = theConnections.sourceVoltage;
Expand Down Expand Up @@ -2189,6 +2197,15 @@ void CCvcDb::SetTrivialMinMaxPower() {
}
}
} else if ( gSetup_cvc ) {
CStatus myGateTypes;
for ( deviceId_t device_it = firstGate_v[net_it]; device_it != UNKNOWN_DEVICE; device_it = nextGate_v[device_it] ) {
if ( IsNmos_(deviceType_v[device_it]) ) {
myGateTypes[NMOS] = true;
} else if ( IsPmos_(deviceType_v[device_it]) ) {
myGateTypes[PMOS] = true;
}
}
if ( myGateTypes != NMOS_PMOS ) continue; // Only flag if has connections to nmos and pmos gates.
if ( ! netVoltagePtr_v[myGroundNet] && connectionCount_v[myGroundNet].SourceDrainCount() > 5 ) {
myUndefinedPowerNets.insert(NetName(myGroundNet, PRINT_CIRCUIT_ON) + " " + to_string<deviceId_t>(connectionCount_v[myGroundNet].SourceDrainCount()) );
}
Expand Down
4 changes: 4 additions & 0 deletions src/CCvcDb.hh
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ public:

map<netId_t, string> calculatedResistanceInfo_v;

unordered_map<string, deviceId_t> cellErrorCountMap;

ogzstream errorFile;
ofstream logFile;
teestream reportFile;
Expand Down Expand Up @@ -230,6 +232,7 @@ public:
CDeviceIdVector & theFirstDrain_v, CDeviceIdVector & theNextDrain_v, CNetIdVector & theSourceNet_v);
bool IsOppositeLogic(netId_t theFirstNet, netId_t theSecondNet);
void PrintNetSuggestions();
returnCode_t LoadCellErrorLimits();

// error
void PrintFuseError(netId_t theTargetNetId, CConnection & theConnections);
Expand Down Expand Up @@ -434,6 +437,7 @@ public:
string NetVoltageSuffix(string theDelimiter, string theVoltage, resistance_t theResistance, string theLeakVoltage = "");
void PrintResistorOverflow(netId_t theNet, ofstream& theOutputFile);
void PrintClassSizes();
void PrintNetWithModelCounts(netId_t theNetId, int theTerminals);

// CCvcDb-interactive
void FindInstances(string theSubcircuit, bool thePrintCircuitFlag);
Expand Down
98 changes: 90 additions & 8 deletions src/CCvcDb_error.cc
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,7 @@ void CCvcDb::FindNmosSourceVsBulkErrors() {
CFullConnection myConnections;
reportFile << "! Checking nmos source/drain vs bias errors: " << endl << endl;
errorFile << "! Checking nmos source/drain vs bias errors: " << endl << endl;
unordered_set<netId_t> myProblemNets;
for ( deviceId_t device_it = 0; device_it < deviceCount; device_it++ ) {
CInstance * myInstance_p = instancePtr_v[deviceParent_v[device_it]];
CCircuit * myParent_p = myInstance_p->master_p;
Expand All @@ -670,6 +671,8 @@ void CCvcDb::FindNmosSourceVsBulkErrors() {
if ( myConnections.sourceId == myConnections.drainId && myConnections.sourceId == myConnections.bulkId ) continue; // ignore drain = source = bulk
bool myErrorFlag = false;
bool myUnrelatedFlag = false;
bool mySourceError = false;
bool myDrainError = false;
if ( ! myConnections.minBulkPower_p
|| (myConnections.minBulkPower_p->IsRelatedPower(myConnections.minSourcePower_p, netVoltagePtr_v, minNet_v, minNet_v, true, true)
&& myConnections.minBulkPower_p->IsRelatedPower(myConnections.minDrainPower_p, netVoltagePtr_v, minNet_v, minNet_v, true, true)) ) {
Expand Down Expand Up @@ -706,13 +709,13 @@ void CCvcDb::FindNmosSourceVsBulkErrors() {
( myConnections.minSourceVoltage == myConnections.minBulkVoltage &&
cvcParameters.cvcBiasErrorThreshold == 0 &&
myConnections.masterMinSourceNet.finalResistance < myConnections.masterMinBulkNet.finalResistance) ) ) {
myErrorFlag = true;
mySourceError = true;
} else if ( myConnections.CheckTerminalMinVoltages(BULK | DRAIN) &&
( myConnections.minBulkVoltage - myConnections.minDrainVoltage > cvcParameters.cvcBiasErrorThreshold ||
( myConnections.minDrainVoltage == myConnections.minBulkVoltage &&
cvcParameters.cvcBiasErrorThreshold == 0 &&
myConnections.masterMinDrainNet.finalResistance < myConnections.masterMinBulkNet.finalResistance) ) ) {
myErrorFlag = true;
myDrainError = true;
} else if ( myConnections.CheckTerminalSimVoltages(BULK | SOURCE) &&
( myConnections.simBulkVoltage - myConnections.simSourceVoltage > cvcParameters.cvcBiasErrorThreshold ||
( myConnections.simSourceVoltage == myConnections.simBulkVoltage &&
Expand Down Expand Up @@ -753,7 +756,13 @@ void CCvcDb::FindNmosSourceVsBulkErrors() {
myErrorFlag = true; // if not relatives, always an error
myUnrelatedFlag = true;
}
if ( myErrorFlag ) {
if ( gSetup_cvc ) {
if ( myDrainError ) {
myProblemNets.insert(myConnections.drainId);
} else if ( mySourceError ) {
myProblemNets.insert(myConnections.sourceId);
}
} else if ( myErrorFlag || myDrainError || mySourceError ) {
if ( IncrementDeviceError(myConnections.deviceId, NMOS_SOURCE_BULK) < cvcParameters.cvcCircuitErrorLimit || cvcParameters.cvcCircuitErrorLimit == 0 ) {
if ( myUnrelatedFlag ) {
errorFile << "Unrelated power error" << endl;
Expand All @@ -763,13 +772,46 @@ void CCvcDb::FindNmosSourceVsBulkErrors() {
}
}
}
cvcCircuitList.PrintAndResetCircuitErrors(this, cvcParameters.cvcCircuitErrorLimit, logFile, errorFile, "! Checking nmos source/drain vs bias errors: ");
if ( gSetup_cvc ) {
reportFile << endl << "CVC SETUP: nmos bias problems" << endl << endl;
unordered_set<netId_t> myPrintedNets;
unordered_set<netId_t> myParentNets;
for ( auto net_pit = myProblemNets.begin(); net_pit != myProblemNets.end(); net_pit++ ) {
netId_t myNextNet = *net_pit;
while(myNextNet != minNet_v[myNextNet].nextNetId) {
myNextNet = minNet_v[myNextNet].nextNetId;
myParentNets.insert(myNextNet);
}
}
for ( auto net_pit = myProblemNets.begin(); net_pit != myProblemNets.end(); net_pit++ ) {
if ( myParentNets.count(*net_pit) ) continue;
netId_t traceNet_it = *net_pit;
reportFile << endl;
PrintNetWithModelCounts(traceNet_it, SOURCE | DRAIN);
while ( traceNet_it != minNet_v[traceNet_it].nextNetId ) {
traceNet_it = minNet_v[traceNet_it].nextNetId;
if ( traceNet_it == minNet_v[traceNet_it].nextNetId ) {
reportFile << NetName(traceNet_it, PRINT_CIRCUIT_ON) << endl;
} else {
PrintNetWithModelCounts(traceNet_it, SOURCE | DRAIN);
if ( myPrintedNets.count(traceNet_it) ) {
reportFile << "**********" << endl;
break;
}
myPrintedNets.insert(traceNet_it);
}
}
}
} else {
cvcCircuitList.PrintAndResetCircuitErrors(this, cvcParameters.cvcCircuitErrorLimit, logFile, errorFile, "! Checking nmos source/drain vs bias errors: ");
}
}

void CCvcDb::FindPmosSourceVsBulkErrors() {
CFullConnection myConnections;
reportFile << "! Checking pmos source/drain vs bias errors: " << endl << endl;
errorFile << "! Checking pmos source/drain vs bias errors: " << endl << endl;
unordered_set<netId_t> myProblemNets;
for ( deviceId_t device_it = 0; device_it < deviceCount; device_it++ ) {
CInstance * myInstance_p = instancePtr_v[deviceParent_v[device_it]];
CCircuit * myParent_p = myInstance_p->master_p;
Expand All @@ -779,6 +821,8 @@ void CCvcDb::FindPmosSourceVsBulkErrors() {
if ( myConnections.sourceId == myConnections.drainId && myConnections.sourceId == myConnections.bulkId ) continue; // ignore drain = source = bulk
bool myErrorFlag = false;
bool myUnrelatedFlag = false;
bool mySourceError = false;
bool myDrainError = false;
if ( ! myConnections.maxBulkPower_p
|| (myConnections.maxBulkPower_p->IsRelatedPower(myConnections.maxSourcePower_p, netVoltagePtr_v, maxNet_v, maxNet_v, true, true)
&& myConnections.maxBulkPower_p->IsRelatedPower(myConnections.maxDrainPower_p, netVoltagePtr_v, maxNet_v, maxNet_v, true, true)) ) {
Expand Down Expand Up @@ -848,19 +892,25 @@ void CCvcDb::FindPmosSourceVsBulkErrors() {
( myConnections.maxSourceVoltage == myConnections.maxBulkVoltage &&
cvcParameters.cvcBiasErrorThreshold == 0 &&
myConnections.masterMaxSourceNet.finalResistance < myConnections.masterMaxBulkNet.finalResistance) ) ) {
myErrorFlag = true;
mySourceError = true;
} else if ( myConnections.CheckTerminalMaxVoltages(BULK | DRAIN) &&
( myConnections.maxDrainVoltage - myConnections.maxBulkVoltage > cvcParameters.cvcBiasErrorThreshold ||
( myConnections.maxDrainVoltage == myConnections.maxBulkVoltage &&
cvcParameters.cvcBiasErrorThreshold == 0 &&
myConnections.masterMaxDrainNet.finalResistance < myConnections.masterMaxBulkNet.finalResistance) ) ) {
myErrorFlag = true;
myDrainError = true;
}
} else {
myUnrelatedFlag = true;
myErrorFlag = true; // if not relatives, always an error
}
if ( myErrorFlag ) {
if ( gSetup_cvc ) {
if ( myDrainError ) {
myProblemNets.insert(myConnections.drainId);
} else if ( mySourceError ) {
myProblemNets.insert(myConnections.sourceId);
}
} else if ( myErrorFlag || myDrainError || mySourceError ) {
if ( IncrementDeviceError(myConnections.deviceId, PMOS_SOURCE_BULK) < cvcParameters.cvcCircuitErrorLimit || cvcParameters.cvcCircuitErrorLimit == 0 ) {
if ( myUnrelatedFlag ) {
errorFile << "Unrelated power error" << endl;
Expand All @@ -870,7 +920,39 @@ void CCvcDb::FindPmosSourceVsBulkErrors() {
}
}
}
cvcCircuitList.PrintAndResetCircuitErrors(this, cvcParameters.cvcCircuitErrorLimit, logFile, errorFile, "! Checking pmos source/drain vs bias errors: ");
if ( gSetup_cvc ) {
reportFile << endl << "CVC SETUP: pmos bias problems" << endl << endl;
unordered_set<netId_t> myPrintedNets;
unordered_set<netId_t> myParentNets;
for ( auto net_pit = myProblemNets.begin(); net_pit != myProblemNets.end(); net_pit++ ) {
netId_t myNextNet = *net_pit;
while(myNextNet != minNet_v[myNextNet].nextNetId) {
myNextNet = minNet_v[myNextNet].nextNetId;
myParentNets.insert(myNextNet);
}
}
for ( auto net_pit = myProblemNets.begin(); net_pit != myProblemNets.end(); net_pit++ ) {
if ( myParentNets.count(*net_pit) ) continue;
netId_t traceNet_it = *net_pit;
reportFile << endl;
PrintNetWithModelCounts(traceNet_it, SOURCE | DRAIN);
while ( traceNet_it != minNet_v[traceNet_it].nextNetId ) {
traceNet_it = minNet_v[traceNet_it].nextNetId;
if ( traceNet_it == minNet_v[traceNet_it].nextNetId ) {
reportFile << NetName(traceNet_it, PRINT_CIRCUIT_ON) << endl;
} else {
PrintNetWithModelCounts(traceNet_it, SOURCE | DRAIN);
if ( myPrintedNets.count(traceNet_it) ) {
reportFile << "**********" << endl;
break;
}
myPrintedNets.insert(traceNet_it);
}
}
}
} else {
cvcCircuitList.PrintAndResetCircuitErrors(this, cvcParameters.cvcCircuitErrorLimit, logFile, errorFile, "! Checking pmos source/drain vs bias errors: ");
}
}

void CCvcDb::FindForwardBiasDiodes() {
Expand Down
44 changes: 42 additions & 2 deletions src/CCvcDb_init.cc
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,13 @@ returnCode_t CCvcDb::SetInstancePower() {
forward_list<instanceId_t> myInstanceIdList = FindInstanceIds((*instance_ppit)->instanceName); // expands buses and hierarchy
for ( auto instanceId_pit = myInstanceIdList.begin(); instanceId_pit != myInstanceIdList.end(); instanceId_pit++ ) {
CPowerPtrMap myLocalMacroPtrMap;
for (auto powerMap_pit = cvcParameters.cvcPowerMacroPtrMap.begin(); powerMap_pit != cvcParameters.cvcPowerMacroPtrMap.end(); powerMap_pit++) {
// Add top macros
netId_t myNetId = FindNet(0, powerMap_pit->first, false);
if (myNetId == UNKNOWN_NET) { // power definition does not exist, therefore this is macro
myLocalMacroPtrMap[powerMap_pit->first] = new CPower(powerMap_pit->second);
}
}
logFile << " Setting power for instance " << HierarchyName(*instanceId_pit) << endl;
for ( auto power_pit = (*instance_ppit)->powerList.begin(); power_pit != (*instance_ppit)->powerList.end(); power_pit++ ) {
CPower * myPower_p = new CPower(*power_pit, myLocalMacroPtrMap, cvcParameters.cvcModelListMap);
Expand Down Expand Up @@ -1032,8 +1039,10 @@ returnCode_t CCvcDb::SetInstancePower() {
}
} else {
if ( netVoltagePtr_v[myNetId] ) {
reportFile << "Warning: Duplicate power definition " << NetName(myNetId);
reportFile << " and " << myPower_p->powerSignal() << " of " << HierarchyName(*instanceId_pit) << " ignored" << endl;
if ( netVoltagePtr_v[myNetId]->definition != myPower_p->definition ) {
reportFile << "Warning: Duplicate power definition " << NetName(myNetId) << "(" << netVoltagePtr_v[myNetId]->definition << ")";
reportFile << " and " << myPower_p->powerSignal() << "(" << myPower_p->definition << ") of " << HierarchyName(*instanceId_pit) << " ignored" << endl;
}
} else {
cvcParameters.cvcPowerPtrList.push_back(myPower_p);
netVoltagePtr_v[myNetId] = myPower_p;
Expand Down Expand Up @@ -1534,3 +1543,34 @@ void CCvcDb::PrintNetSuggestions() {
reportFile << endl;
}

returnCode_t CCvcDb::LoadCellErrorLimits() {
if ( IsEmpty(cvcParameters.cvcCellErrorLimitFile) ) return OK;
igzstream myCellErrorLimitFile;
myCellErrorLimitFile.open(cvcParameters.cvcCellErrorLimitFile);
if ( myCellErrorLimitFile.fail() ) {
throw EFatalError("Could not open " + cvcParameters.cvcCellErrorLimitFile);
exit(1);
}
string myInput;

reportFile << "CVC: Reading cell error limit settings..." << endl;
string myCellName;
try {
while ( getline(myCellErrorLimitFile, myInput) ) {
int myCellNameStart = myInput.find_first_not_of(" \t\n");
int myCellNameEnd = myInput.find_first_of(" \t\n", myCellNameStart);
myCellName = myInput.substr(myCellNameStart, myCellNameEnd - myCellNameStart);
int myErrorLimit = from_string<int>(myInput.substr(myCellNameEnd));
CCircuit * theMaster_p = cvcCircuitList.FindCircuit(myCellName);
theMaster_p->errorLimit = myErrorLimit;
cout << "DEBUG: error limit for " << myCellName << " is " << myErrorLimit << endl;
}
}
catch (...) {
reportFile << "ERROR: Could not find error limit cell " << myCellName << " in netlist" << endl;
return FAIL;
}
myCellErrorLimitFile.close();
return OK;
}

Loading

0 comments on commit 5adcd02

Please sign in to comment.