Skip to content

Commit

Permalink
Changes for 0.17.34a
Browse files Browse the repository at this point in the history
CVC: Recognize inverters with inputs tied to power
CVC: Added opposite_logic net check
  • Loading branch information
d-m-bailey committed Sep 18, 2020
1 parent e135636 commit e73b0aa
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 67 deletions.
32 changes: 26 additions & 6 deletions src/CCvcDb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2158,14 +2158,34 @@ void CCvcDb::SetTrivialMinMaxPower() {
myNmos = UNKNOWN_DEVICE;
myPmos = UNKNOWN_DEVICE;
for ( deviceId_t device_it = firstDrain_v[net_it]; device_it != UNKNOWN_DEVICE; device_it = nextDrain_v[device_it] ) {
if ( sourceNet_v[device_it] == gateNet_v[device_it] ) continue; // skip mos diodes
if ( IsNmos_(deviceType_v[device_it]) ) myNmos = device_it;
if ( IsPmos_(deviceType_v[device_it]) ) myPmos = device_it;
//if ( sourceNet_v[device_it] == gateNet_v[device_it] ) continue; // skip mos diodes (need this for tied inverters)
if ( sourceNet_v[device_it] == drainNet_v[device_it] ) continue; // skip mos capacitors

if ( IsNmos_(deviceType_v[device_it]) ) {
if ( myNmos == UNKNOWN_DEVICE || sourceNet_v[device_it] != gateNet_v[device_it] ) { // only use tied input if nothing else is available
myNmos = device_it;
}
}
if ( IsPmos_(deviceType_v[device_it]) ) {
if ( myPmos == UNKNOWN_DEVICE || sourceNet_v[device_it] != gateNet_v[device_it] ) { // only use tied input if nothing else is available
myPmos = device_it;
}
}
}
for ( deviceId_t device_it = firstSource_v[net_it]; device_it != UNKNOWN_DEVICE; device_it = nextSource_v[device_it] ) {
if ( drainNet_v[device_it] == gateNet_v[device_it] ) continue; // skip mos diodes
if ( IsNmos_(deviceType_v[device_it]) ) myNmos = device_it;
if ( IsPmos_(deviceType_v[device_it]) ) myPmos = device_it;
//if ( drainNet_v[device_it] == gateNet_v[device_it] ) continue; // skip mos diodes (need this for tied inverters)
if ( sourceNet_v[device_it] == drainNet_v[device_it] ) continue; // skip mos capacitors

if ( IsNmos_(deviceType_v[device_it]) ) {
if ( myNmos == UNKNOWN_DEVICE || drainNet_v[device_it] != gateNet_v[device_it] ) { // only use tied input if nothing else is available
myNmos = device_it;
}
}
if ( IsPmos_(deviceType_v[device_it]) ) {
if ( myPmos == UNKNOWN_DEVICE || drainNet_v[device_it] != gateNet_v[device_it] ) { // only use tied input if nothing else is available
myPmos = device_it;
}
}
}
if ( myNmos == UNKNOWN_DEVICE ) continue;
if ( myPmos == UNKNOWN_DEVICE ) continue;
Expand Down
11 changes: 8 additions & 3 deletions src/CCvcDb.hh
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ public:
void CheckExpectedValues();
void FindLDDErrors();
void CheckInverterIO(modelType_t theType);
void CheckOppositeLogic();
void CheckOppositeLogic(modelType_t theType);

//
// void ReportBadLddConnection(CEventQueue & theEventQueue, deviceId_t theDeviceId);
Expand Down Expand Up @@ -400,9 +400,14 @@ public:
void SetDiodeConnections(pair<int, int> diode_pit, CFullConnection & myConnections, CFullConnection & myDiodeConnections);
int CalculateMFactor(instanceId_t theInstanceId);
deviceId_t GetAttachedDevice(netId_t theNetId, modelType_t theType, terminal_t theTerminal);
deviceId_t FindInverterDevice(netId_t theInputNet, netId_t theOutputNet, modelType_t theType);
deviceId_t FindInverterDevice(netId_t theInputNet, netId_t theOutputNet, modelType_t theType);
returnCode_t FindUniqueMosInputs(netId_t theOutputNet, netId_t theGroundNet, netId_t thePowerNet,
CDeviceIdVector &theFirst_v, CDeviceIdVector &theNext_v, CNetIdVector &theSourceNet_v, CNetIdVector &theDrainNet_v,
netId_t &theNmosInput, netId_t &thePmosInput);
deviceId_t FindInverterInput(netId_t theOutputNet);

bool IsOnGate(deviceId_t theDevice, CPower * thePower_p);
netId_t OppositeNet(deviceId_t theDevice, netId_t theNet);
deviceId_t GetNextInSeries(deviceId_t theDevice, netId_t theNet);

// CCvcDb-print
void SetOutputFiles(string theReportFile);
Expand Down
72 changes: 40 additions & 32 deletions src/CCvcDb_error.cc
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,7 @@ void CCvcDb::FindNmosGateVsSourceErrors() {
}
}
CheckInverterIO(NMOS);
CheckOppositeLogic(NMOS);
cvcCircuitList.PrintAndResetCircuitErrors(this, cvcParameters.cvcCircuitErrorLimit, logFile, errorFile, "! Checking nmos gate vs source errors: ");
}

Expand Down Expand Up @@ -666,6 +667,7 @@ void CCvcDb::FindPmosGateVsSourceErrors() {
}
}
CheckInverterIO(PMOS);
CheckOppositeLogic(PMOS);
cvcCircuitList.PrintAndResetCircuitErrors(this, cvcParameters.cvcCircuitErrorLimit, logFile, errorFile, "! Checking pmos gate vs source errors: ");
}

Expand Down Expand Up @@ -1233,7 +1235,6 @@ void CCvcDb::FindFloatingInputErrors() {
}
}
}
CheckOppositeLogic();
cvcCircuitList.PrintAndResetCircuitErrors(this, cvcParameters.cvcCircuitErrorLimit, logFile, errorFile, "! Checking mos floating input errors:");
// errorFile << "! Finished" << endl << endl;
}
Expand Down Expand Up @@ -1462,11 +1463,12 @@ void CCvcDb::CheckInverterIO(modelType_t theType) {
netId_t myInverterInput = FindInverterInput(*net_pit);
if ( myInverterInput == UNKNOWN_NET ) {
myInverterInput = inverterNet_v[*net_pit];
reportFile << "INFO: Couldn't calculate inverter input for " << NetName(myInverterInput, true) << endl;
reportFile << "INFO: Couldn't calculate inverter input for " << NetName(*net_pit, true) << endl;
}
if (myInverterInput == UNKNOWN_NET) {
reportFile << "Warning: expected inverter input at " << NetName(myInverterInput, true) << endl;
continue;
reportFile << "Warning: expected inverter input at " << NetName(*net_pit, true) << endl;
continue;

}
myMinInput(minNet_v, myInverterInput);
myMaxInput(maxNet_v, myInverterInput);
Expand Down Expand Up @@ -1496,51 +1498,56 @@ void CCvcDb::CheckInverterIO(modelType_t theType) {
}
}

void CCvcDb::CheckOppositeLogic() {
void CCvcDb::CheckOppositeLogic(modelType_t theType) {
for ( auto check_pit = oppositeLogicList.begin(); check_pit != oppositeLogicList.end(); check_pit++ ) {
debugFile << "DEBUG: opposite logic check " << get<0>(*check_pit) << " & " << get<1>(*check_pit) << endl;
forward_list<netId_t> * myNetIdList = FindNetIds(get<0>(*check_pit));
forward_list<netId_t> * myOppositeNetIdList = FindNetIds(get<1>(*check_pit));
for ( auto net_pit = myNetIdList->begin(), opposite_pit = myOppositeNetIdList->begin(); net_pit != myNetIdList->end(); net_pit++, opposite_pit++ ) {
CPower * myFirstPower_p = netVoltagePtr_v[*net_pit].full;
CPower * mySecondPower_p = netVoltagePtr_v[*opposite_pit].full;
CPower * myFirstPower_p = netVoltagePtr_v[GetEquivalentNet(*net_pit)].full;
CPower * mySecondPower_p = netVoltagePtr_v[GetEquivalentNet(*opposite_pit)].full;
if ( myFirstPower_p && mySecondPower_p && IsPower_(myFirstPower_p) && IsPower_(mySecondPower_p)
&& myFirstPower_p->simVoltage != mySecondPower_p->simVoltage ) continue; // ignore direct connections to different power
&& myFirstPower_p->simVoltage != mySecondPower_p->simVoltage ) continue; // ignore direct connections to different power

unordered_set<netId_t> myInvertedNets;
unordered_set<netId_t> mySameLogicNets;
netId_t inverter_it = *net_pit;
netId_t net_it = GetEquivalentNet(*net_pit);
// make sets of same logic nets and opposite logic nets for first nets
mySameLogicNets.insert(inverter_it);
while ( inverterNet_v[inverter_it] != UNKNOWN_NET && myInvertedNets.count(inverterNet_v[inverter_it]) == 0 ) {
assert(mySameLogicNets.count(inverterNet_v[inverter_it]) == 0); // oscillators

myInvertedNets.insert(inverterNet_v[inverter_it]);
inverter_it = inverterNet_v[inverter_it];
if ( inverterNet_v[inverter_it] != UNKNOWN_NET ) {
mySameLogicNets.insert(inverter_it);
inverter_it = inverterNet_v[inverter_it];
}
bool myInverted = false;
logFile << "Checking " << NetName(net_it, true) << endl;
while ( net_it != UNKNOWN_NET && mySameLogicNets.count(net_it) == 0 ) {
if ( myInverted ) {
myInvertedNets.insert(net_it);
assert(myInvertedNets.count(inverterNet_v[net_it]) == 0); // oscillators

} else {
mySameLogicNets.insert(net_it);
assert(mySameLogicNets.count(inverterNet_v[net_it]) == 0); // oscillators

}
myInverted = ! myInverted;
net_it = inverterNet_v[net_it];
}
// check second net against first net to find opposite logic
inverter_it = *opposite_pit;
while ( inverterNet_v[inverter_it] != UNKNOWN_NET && myInvertedNets.count(inverter_it) == 0 ) {
if ( mySameLogicNets.count(inverterNet_v[inverter_it]) > 0 ) { // second net is later in inverter chain
myInvertedNets.insert(inverter_it);
} else {
inverter_it = inverterNet_v[inverter_it];
if ( inverterNet_v[inverter_it] != UNKNOWN_NET ) {
inverter_it = inverterNet_v[inverter_it];
}
}
myInverted = true;
net_it = GetEquivalentNet(*opposite_pit);
while ( net_it != UNKNOWN_NET
&& ( (myInverted && myInvertedNets.count(net_it) == 0)
|| (! myInverted && mySameLogicNets.count(net_it) == 0) ) ) {
net_it = inverterNet_v[net_it];
myInverted = ! myInverted;
}
if ( myInvertedNets.count(inverter_it) > 0 ) continue; // nets are opposite
if ( net_it != UNKNOWN_NET ) continue; // nets are opposite

netId_t myErrorNet = (myFirstPower_p && IsPower_(myFirstPower_p)) ? *opposite_pit : *net_pit;
netId_t myErrorNet = (myFirstPower_p && IsPower_(myFirstPower_p)) ? GetEquivalentNet(*opposite_pit) : GetEquivalentNet(*net_pit);
int myErrorCount = 0;
for ( auto device_it = firstGate_v[myErrorNet]; device_it != UNKNOWN_DEVICE; device_it = nextGate_v[device_it]) {
if ( sourceNet_v[device_it] == drainNet_v[device_it] ) continue; // ignore inactive devices

if ( theType == PMOS && ! IsPmos_(deviceType_v[device_it]) ) continue; // ignore wrong types

if ( theType == NMOS && ! IsNmos_(deviceType_v[device_it]) ) continue; // ignore wrong types

myErrorCount++;
if ( IncrementDeviceError(device_it, HIZ_INPUT) < cvcParameters.cvcCircuitErrorLimit || cvcParameters.cvcCircuitErrorLimit == 0 ) {
CFullConnection myFullConnections;
Expand All @@ -1551,7 +1558,8 @@ void CCvcDb::CheckOppositeLogic() {
}
}
if ( myErrorCount == 0 ) {
reportFile << "Warning: No errors printed for opposite logic check at " << get<0>(*check_pit) << " & " << get<1>(*check_pit) << endl;
reportFile << "Warning: No errors printed for opposite logic check at " << get<0>(*check_pit) << " & " << get<1>(*check_pit);
reportFile << " for net " << NetName(*net_pit, true) << endl;
}
}
}
Expand Down
11 changes: 6 additions & 5 deletions src/CCvcDb_init.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1765,8 +1765,9 @@ void CCvcDb::LoadCellChecksums() {
void CCvcDb::LoadNetChecks() {
/// Load net checks from file.
///
/// Currently supports "inverter_input=output": check to verify inverter output ground/power is same as input ground/power
/// Future support for "opposite_logic": verify that 2 nets are logically opposite
/// 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);
Expand All @@ -1782,20 +1783,20 @@ void CCvcDb::LoadNetChecks() {

size_t myStringBegin = myInput.find_first_not_of(" \t");
size_t myStringEnd = myInput.find_first_of(" \t", myStringBegin);
string myNetName = myInput.substr(myStringBegin, myStringEnd);
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);
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);
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;
Expand Down
Loading

0 comments on commit e73b0aa

Please sign in to comment.