Skip to content

Commit

Permalink
Changes for version 0.17.33
Browse files Browse the repository at this point in the history
CVC: Added opposite logic check
CVC: Split FindNetIds into FindUniqueNetIds and FindNetIds (with redundancies)
CVC: Split CheckNets into CheckInverterIO and CheckOppositeLogic
CVC: Ignore non-power in dumplevelshifter
CVC: Use power aliases when checking for level shifters
  • Loading branch information
d-m-bailey committed Aug 18, 2020
1 parent c65c5e0 commit e135636
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 25 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.32], [cvc@shuharisystem.com])
AC_INIT(CVC, [0.17.33], [cvc@shuharisystem.com])
AC_CONFIG_SRCDIR(src)
AC_CONFIG_HEADERS([config.h])
AC_USE_SYSTEM_EXTENSIONS
Expand Down
9 changes: 6 additions & 3 deletions src/CCvcDb.hh
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,8 @@ public:

unordered_map<string, deviceId_t> cellErrorCountMap;

forward_list<string> inverterInputOutputCheckList; // list of nets to check for matched input/output
forward_list<string> inverterInputOutputCheckList; // list of nets to check for matched input/output
forward_list<pair<string, string>> oppositeLogicList; // list of nets to check for opposite logic

ogzstream errorFile;
ofstream logFile;
Expand Down Expand Up @@ -220,7 +221,8 @@ public:
void ShortNonConductingResistors();
void SetResistorVoltagesForMosSwitches();
forward_list<instanceId_t> FindInstanceIds(string theHierarchy, instanceId_t theParent = 0);
set<netId_t> * FindNetIds(string thePowerSignal, instanceId_t theParent = 0);
set<netId_t> * FindUniqueNetIds(string thePowerSignal, instanceId_t theParent = 0);
forward_list<netId_t> * FindNetIds(string thePowerSignal, instanceId_t theParent = 0);
returnCode_t SetModePower();
returnCode_t SetInstancePower();
returnCode_t SetExpectedPower();
Expand Down Expand Up @@ -269,7 +271,8 @@ public:
void FindFloatingInputErrors();
void CheckExpectedValues();
void FindLDDErrors();
void CheckNets(modelType_t theType);
void CheckInverterIO(modelType_t theType);
void CheckOppositeLogic();

//
// void ReportBadLddConnection(CEventQueue & theEventQueue, deviceId_t theDeviceId);
Expand Down
70 changes: 66 additions & 4 deletions src/CCvcDb_error.cc
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ void CCvcDb::FindNmosGateVsSourceErrors() {
errorFile << endl;
}
}
CheckNets(NMOS);
CheckInverterIO(NMOS);
cvcCircuitList.PrintAndResetCircuitErrors(this, cvcParameters.cvcCircuitErrorLimit, logFile, errorFile, "! Checking nmos gate vs source errors: ");
}

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

Expand Down Expand Up @@ -1233,6 +1233,7 @@ void CCvcDb::FindFloatingInputErrors() {
}
}
}
CheckOppositeLogic();
cvcCircuitList.PrintAndResetCircuitErrors(this, cvcParameters.cvcCircuitErrorLimit, logFile, errorFile, "! Checking mos floating input errors:");
// errorFile << "! Finished" << endl << endl;
}
Expand Down Expand Up @@ -1448,11 +1449,11 @@ void CCvcDb::FindLDDErrors() {
}
*/

void CCvcDb::CheckNets(modelType_t theType) {
void CCvcDb::CheckInverterIO(modelType_t theType) {
// Checks nets loaded from cvcNetCheckFile
for ( auto check_pit = inverterInputOutputCheckList.begin(); check_pit != inverterInputOutputCheckList.end(); check_pit++ ) {
debugFile << "DEBUG: inverter input output check " << *check_pit << endl;
set<netId_t> * myNetIdList = FindNetIds(*check_pit);
set<netId_t> * myNetIdList = FindUniqueNetIds(*check_pit);
CVirtualNet myMinInput;
CVirtualNet myMaxInput;
CVirtualNet myMinOutput;
Expand Down Expand Up @@ -1493,4 +1494,65 @@ void CCvcDb::CheckNets(modelType_t theType) {
}
}
}
}

void CCvcDb::CheckOppositeLogic() {
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;
if ( myFirstPower_p && mySecondPower_p && IsPower_(myFirstPower_p) && IsPower_(mySecondPower_p)
&& 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;
// 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];
}
}
// 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];
}
}
}
if ( myInvertedNets.count(inverter_it) > 0 ) continue; // nets are opposite

netId_t myErrorNet = (myFirstPower_p && IsPower_(myFirstPower_p)) ? *opposite_pit : *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

myErrorCount++;
if ( IncrementDeviceError(device_it, HIZ_INPUT) < cvcParameters.cvcCircuitErrorLimit || cvcParameters.cvcCircuitErrorLimit == 0 ) {
CFullConnection myFullConnections;
MapDeviceNets(device_it, myFullConnections);
errorFile << "* opposite logic required " << get<0>(*check_pit) << " & " << get<1>(*check_pit) << endl;
PrintDeviceWithAllConnections(deviceParent_v[device_it], myFullConnections, errorFile);
errorFile << endl;
}
}
if ( myErrorCount == 0 ) {
reportFile << "Warning: No errors printed for opposite logic check at " << get<0>(*check_pit) << " & " << get<1>(*check_pit) << endl;
}
}
}
}
96 changes: 89 additions & 7 deletions src/CCvcDb_init.cc
Original file line number Diff line number Diff line change
Expand Up @@ -816,7 +816,8 @@ forward_list<instanceId_t> CCvcDb::FindInstanceIds(string theHierarchy, instance
return mySearchInstanceIdList;
}

set<netId_t> * CCvcDb::FindNetIds(string thePowerSignal, instanceId_t theParent) {
set<netId_t> * CCvcDb::FindUniqueNetIds(string thePowerSignal, instanceId_t theParent) {
/// Returns a list of unique net ids for expanded signals. cells, instances and signals may include wildcards.
list<string> * myHierarchyList_p = SplitHierarchy(thePowerSignal);
set<netId_t> * myNetIdSet_p = new set<netId_t>;
forward_list<instanceId_t> mySearchInstanceIdList;
Expand Down Expand Up @@ -903,6 +904,80 @@ set<netId_t> * CCvcDb::FindNetIds(string thePowerSignal, instanceId_t theParent)
return myNetIdSet_p;
}

forward_list<netId_t> * CCvcDb::FindNetIds(string thePowerSignal, instanceId_t theParent) {
/// Returns a list of non-unique net ids for expanded signals. cells and instances may include wildcards.
list<string> * myHierarchyList_p = SplitHierarchy(thePowerSignal);
forward_list<netId_t> * myNetIdList_p = new forward_list<netId_t>;
forward_list<instanceId_t> mySearchInstanceIdList;
string myInstanceName = "";
string mySignalName = "";
string myUnmatchedInstance = "";
size_t mySearchEnd = thePowerSignal.length();
do {
mySearchEnd = thePowerSignal.find_last_of(cvcParameters.cvcHierarchyDelimiters, mySearchEnd-1);
if (mySearchEnd > thePowerSignal.length()) {
mySearchEnd = 0;
myInstanceName = "";
mySignalName = thePowerSignal;
} else {
myInstanceName = thePowerSignal.substr(0, mySearchEnd);
mySignalName = thePowerSignal.substr(mySearchEnd+1);
}
mySearchInstanceIdList = FindInstanceIds(myInstanceName, theParent);
} while( mySearchInstanceIdList.empty() && myInstanceName != "" );
try {
// list<string> * myNetNameList_p = ExpandBusNet(mySignalName);
bool myCheckTopPort = false;
if ( mySignalName == thePowerSignal ) { // top port
myCheckTopPort = true;
}
// bool myFoundNetMatch = false;
// for ( auto myNetName_pit = myNetNameList_p->begin(); myNetName_pit != myNetNameList_p->end(); myNetName_pit++ ) {
string myNetName = mySignalName;
if ( ! myUnmatchedInstance.empty() ) {
myNetName = myUnmatchedInstance + HIERARCHY_DELIMITER + myNetName;
}
// string myFuzzyFilter = FuzzyFilter(myNetName);
// regex mySearchPattern(myFuzzyFilter);
netId_t myNetId;
// bool myExactMatch = true;
// bool myFuzzySearch = (myFuzzyFilter.find_first_of("^$.*+?()[]{}|\\") < myFuzzyFilter.npos);
text_t mySignalText;
try {
mySignalText = cvcCircuitList.cdlText.GetTextAddress(myNetName);
for (auto instanceId_pit = mySearchInstanceIdList.begin(); instanceId_pit != mySearchInstanceIdList.end(); instanceId_pit++) {
if ( instancePtr_v[*instanceId_pit]->IsParallelInstance() ) {
cout << "Warning: can not define nets in parallel instances " << thePowerSignal << endl;
continue;

}
CTextNetIdMap * mySignalIdMap_p = &(instancePtr_v[*instanceId_pit]->master_p->localSignalIdMap);
// if ( myExactMatch ) { // exact match
if ( mySignalIdMap_p->count(mySignalText) > 0 ) {
myNetId = instancePtr_v[*instanceId_pit]->localToGlobalNetId_v[mySignalIdMap_p->at(mySignalText)];
if ( myCheckTopPort && *instanceId_pit == 0 && myNetId >= topCircuit_p->portCount ) continue; // top signals that are not ports posing as ports
if ( ! myCheckTopPort && *instanceId_pit == 0 && myNetId < topCircuit_p->portCount ) continue; // top signals that should be ports
myNetIdList_p->push_front(myNetId);
// myFoundNetMatch = true;
}
}
}
catch (const out_of_range& oor_exception) {
throw out_of_range("signal " + myNetName + " not found");
}
}
catch (const out_of_range& oor_exception) {
reportFile << "ERROR: could not expand signal " << thePowerSignal << " " << oor_exception.what() << endl;
myNetIdList_p->clear();
}
catch (const regex_error& myError) {
reportFile << "regex_error: " << RegexErrorString(myError.code()) << endl;
myNetIdList_p->clear();
}
delete myHierarchyList_p;
return myNetIdList_p;
}

returnCode_t CCvcDb::SetModePower() {
bool myPowerError = false;
netVoltagePtr_v.ResetPowerPointerVector(netCount);
Expand All @@ -911,7 +986,7 @@ returnCode_t CCvcDb::SetModePower() {
// Normal power definitions
while( power_ppit != cvcParameters.cvcPowerPtrList.end() ) {
CPower * myPower_p = *power_ppit;
set<netId_t> * myNetIdList = FindNetIds(string(myPower_p->powerSignal())); // expands buses and hierarchy
set<netId_t> * myNetIdList = FindUniqueNetIds(string(myPower_p->powerSignal())); // expands buses and hierarchy
for (auto netId_pit = myNetIdList->begin(); netId_pit != myNetIdList->end(); netId_pit++) {
string myExpandedNetName = NetName(*netId_pit);
CPower * myOtherPower_p = netVoltagePtr_v[*netId_pit].full;
Expand Down Expand Up @@ -1040,7 +1115,7 @@ returnCode_t CCvcDb::SetInstancePower() {
myNewPower = HierarchyName(*instanceId_pit) + HIERARCHY_DELIMITER + myPower_p->powerSignal();
myPower_p->extraData->powerSignal = CPower::powerDefinitionText.SetTextAddress((text_t)myNewPower.c_str());
}
set<netId_t> * myNetIdList_p = FindNetIds(string(myPower_p->powerSignal()), *instanceId_pit);
set<netId_t> * myNetIdList_p = FindUniqueNetIds(string(myPower_p->powerSignal()), *instanceId_pit);
for ( auto net_pit = myNetIdList_p->begin(); net_pit != myNetIdList_p->end(); net_pit++ ) {
netId_t myNetId = GetEquivalentNet(*net_pit);
if ( net_pit != myNetIdList_p->begin() ) {
Expand Down Expand Up @@ -1104,7 +1179,7 @@ returnCode_t CCvcDb::SetExpectedPower() {
CPower * myPower_p = *power_ppit;
set<netId_t> * myNetIdList;
if ( myPower_p->netId == UNKNOWN_NET ) {
myNetIdList = FindNetIds(string(myPower_p->powerSignal())); // expands buses and hierarchy
myNetIdList = FindUniqueNetIds(string(myPower_p->powerSignal())); // expands buses and hierarchy
} else {
myNetIdList = new set<netId_t>;
myNetIdList->insert(myPower_p->netId);
Expand Down Expand Up @@ -1708,7 +1783,7 @@ 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);
set<netId_t> * myNetIdList = FindNetIds(myNetName); // expands buses and hierarchy
set<netId_t> * myNetIdList = FindUniqueNetIds(myNetName); // expands buses and hierarchy
if ( myNetIdList->empty() ) {
reportFile << "ERROR: Could not expand net " << myNetName << endl;
}
Expand All @@ -1717,8 +1792,15 @@ void CCvcDb::LoadNetChecks() {
string myOperation = myInput.substr(myStringBegin, myStringEnd);
if ( myOperation == "inverter_input=output" ) {
inverterInputOutputCheckList.push_front(myNetName);
} else if ( myOperation == "opposite_logic" ) {
; // not yet supported
} 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);
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;
}
Expand Down
29 changes: 20 additions & 9 deletions src/CCvcDb_interactive.cc
Original file line number Diff line number Diff line change
Expand Up @@ -839,7 +839,7 @@ returnCode_t CCvcDb::InteractiveCvc(int theCurrentStage) {
// myInputStream >> myOption, myFilter;
} else if ( myCommand == "expandnet" || myCommand == "en" ) {
if ( myInputStream >> myName ) {
set<netId_t> * myNetIdList = FindNetIds(myName); // expands buses and hierarchy
set<netId_t> * myNetIdList = FindUniqueNetIds(myName); // expands buses and hierarchy
for (auto netId_pit = myNetIdList->begin(); netId_pit != myNetIdList->end(); netId_pit++) {
netId_t myEquivalentNetId = (isFixedEquivalentNet) ? GetEquivalentNet(*netId_pit) : *netId_pit;
string myTopNet = NetName(myEquivalentNetId, myPrintSubcircuitNameFlag);
Expand All @@ -853,7 +853,7 @@ returnCode_t CCvcDb::InteractiveCvc(int theCurrentStage) {
}
} else if ( myCommand == "getsim" ) {
if ( myInputStream >> myName ) {
set<netId_t> * myNetIdList = FindNetIds(myName); // expands buses and hierarchy
set<netId_t> * myNetIdList = FindUniqueNetIds(myName); // expands buses and hierarchy
for (auto netId_pit = myNetIdList->begin(); netId_pit != myNetIdList->end(); netId_pit++) {
netId_t myEquivalentNetId = (isFixedEquivalentNet) ? GetEquivalentNet(*netId_pit) : *netId_pit;
string myTopNet = NetName(myEquivalentNetId, myPrintSubcircuitNameFlag);
Expand Down Expand Up @@ -1268,11 +1268,15 @@ void CCvcDb::DumpLevelShifters(string theFileName, bool thePrintCircuitFlag) {

myMinOutputNet(minNet_v, net_it);
myMaxOutputNet(maxNet_v, net_it);
CPower * myOutputGround_p = netVoltagePtr_v[myMinOutputNet.finalNetId].full;
CPower * myOutputPower_p = netVoltagePtr_v[myMaxOutputNet.finalNetId].full;
if ( myMinOutputNet.finalNetId == UNKNOWN_NET
|| myMaxOutputNet.finalNetId == UNKNOWN_NET
|| myMinOutputNet.finalNetId == net_it
|| myMaxOutputNet.finalNetId == net_it
|| myMinOutputNet.finalNetId == myMaxOutputNet.finalNetId ) continue; // invalid min/max
|| myMinOutputNet.finalNetId == myMaxOutputNet.finalNetId
|| ! myOutputGround_p || ! IsPower_(myOutputGround_p)
|| ! myOutputPower_p || ! IsPower_(myOutputPower_p) ) continue; // invalid min/max

deviceId_t myNmos = GetAttachedDevice(net_it, NMOS, SD);
deviceId_t myPmos = GetAttachedDevice(net_it, PMOS, SD);
Expand All @@ -1288,14 +1292,21 @@ void CCvcDb::DumpLevelShifters(string theFileName, bool thePrintCircuitFlag) {
myMinPmosInputNet(minNet_v, myPmosGate);
myMaxNmosInputNet(maxNet_v, myNmosGate);
myMaxPmosInputNet(maxNet_v, myPmosGate);
CPower * myNmosPower_p = netVoltagePtr_v[myNmosGate].full;
CPower * myPmosPower_p = netVoltagePtr_v[myPmosGate].full;
// CPower * myNmosPower_p = netVoltagePtr_v[myNmosGate].full;
// CPower * myPmosPower_p = netVoltagePtr_v[myPmosGate].full;
CPower * myNmosGround_p = netVoltagePtr_v[myMinNmosInputNet.finalNetId].full;
CPower * myNmosPower_p = netVoltagePtr_v[myMaxNmosInputNet.finalNetId].full;
CPower * myPmosGround_p = netVoltagePtr_v[myMinPmosInputNet.finalNetId].full;
CPower * myPmosPower_p = netVoltagePtr_v[myMaxPmosInputNet.finalNetId].full;
if ( ! myNmosGround_p || ! IsPower_(myNmosGround_p) || ! myNmosPower_p || ! IsPower_(myNmosPower_p)
|| ! myPmosGround_p || ! IsPower_(myPmosGround_p) || ! myPmosPower_p || ! IsPower_(myPmosPower_p) ) continue; // ignore inputs with non-power min/max

if ( ( myMinNmosInputNet.finalNetId == myMaxNmosInputNet.finalNetId // power
|| ( myMinNmosInputNet.finalNetId == myMinOutputNet.finalNetId
&& myMaxNmosInputNet.finalNetId == myMaxOutputNet.finalNetId ) )
|| ( myNmosGround_p->powerAlias() == myOutputGround_p->powerAlias()
&& myNmosPower_p->powerAlias() == myOutputPower_p->powerAlias() ) )
&& ( myMinPmosInputNet.finalNetId == myMaxPmosInputNet.finalNetId // power
|| ( myMinPmosInputNet.finalNetId == myMinOutputNet.finalNetId
&& myMaxPmosInputNet.finalNetId == myMaxOutputNet.finalNetId )) ) continue; // input = output
|| ( myPmosGround_p->powerAlias() == myOutputGround_p->powerAlias()
&& myPmosPower_p->powerAlias() == myOutputPower_p->powerAlias() )) ) continue; // input = output

if ( myMinNmosInputNet.finalNetId != myMinOutputNet.finalNetId
&& myMaxNmosInputNet.finalNetId != myMaxOutputNet.finalNetId
Expand Down
2 changes: 1 addition & 1 deletion src/Cvc.hh
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#ifndef CVC_H_
#define CVC_H_

#define CVC_VERSION "0.17.32"
#define CVC_VERSION "0.17.33"

extern bool gDebug_cvc;
extern bool gSetup_cvc;
Expand Down

0 comments on commit e135636

Please sign in to comment.