1 /*
2  * CConnectionCount.cc
3  *
4  * Copyright 2014-2020 D. Mitch Bailey  cvc at shuharisystem dot com
5  *
6  * This file is part of cvc.
7  *
8  * cvc is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * cvc is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with cvc.  If not, see <http://www.gnu.org/licenses/>.
20  *
21  * You can download cvc from https://github.com/d-m-bailey/cvc.git
22  */
23 
24 #include "CConnectionCount.hh"
25 
26 #include "CCvcDb.hh"
27 
CDeviceCount(netId_t theNetId,CCvcDb * theCvcDb_p,instanceId_t theInstanceId)28 CDeviceCount::CDeviceCount(netId_t theNetId, CCvcDb * theCvcDb_p, instanceId_t theInstanceId) {
29 // count devices attached to theNet
30 	netId = theNetId;
31 	for ( auto device_it = theCvcDb_p->firstSource_v[theNetId]; device_it != UNKNOWN_DEVICE; device_it = theCvcDb_p->nextSource_v[device_it] ) {
32 		if ( theCvcDb_p->IsSubcircuitOf(theCvcDb_p->deviceParent_v[device_it], theInstanceId) ) {
33 			switch( theCvcDb_p->deviceType_v[device_it] ) {
34 			case NMOS:
35 			case LDDN: {
36 				nmosCount++;
37 				if ( theCvcDb_p->equivalentNet_v[theCvcDb_p->gateNet_v[device_it]] != theCvcDb_p->equivalentNet_v[theCvcDb_p->drainNet_v[device_it]] ) {
38 					activeNmosCount++;
39 				}
40 				break;
41 			}
42 			case PMOS:
43 			case LDDP: {
44 				pmosCount++;
45 				if ( theCvcDb_p->equivalentNet_v[theCvcDb_p->gateNet_v[device_it]] != theCvcDb_p->equivalentNet_v[theCvcDb_p->drainNet_v[device_it]] ) {
46 					activePmosCount++;
47 				}
48 				break;
49 			}
50 			case RESISTOR: { resistorCount++; break; }
51 			case CAPACITOR: { capacitorCount++; break; }
52 			case DIODE: { diodeCount++; break; }
53 			default: break;
54 			}
55 		}
56 	}
57 	for ( auto device_it = theCvcDb_p->firstDrain_v[theNetId]; device_it != UNKNOWN_DEVICE; device_it = theCvcDb_p->nextDrain_v[device_it] ) {
58 		if ( theCvcDb_p->IsSubcircuitOf(theCvcDb_p->deviceParent_v[device_it], theInstanceId) ) {
59 			if ( theCvcDb_p->equivalentNet_v[theCvcDb_p->sourceNet_v[device_it]] != theCvcDb_p->equivalentNet_v[theCvcDb_p->drainNet_v[device_it]] ) {
60 				// only count devices with source != drain (avoid double count)
61 				switch( theCvcDb_p->deviceType_v[device_it] ) {
62 				case NMOS:
63 				case LDDN: {
64 					nmosCount++;
65 					if ( theCvcDb_p->equivalentNet_v[theCvcDb_p->gateNet_v[device_it]] != theCvcDb_p->equivalentNet_v[theCvcDb_p->sourceNet_v[device_it]] ) {
66 						activeNmosCount++;
67 					}
68 					break;
69 				}
70 				case PMOS:
71 				case LDDP: {
72 					pmosCount++;
73 					if ( theCvcDb_p->equivalentNet_v[theCvcDb_p->gateNet_v[device_it]] != theCvcDb_p->equivalentNet_v[theCvcDb_p->sourceNet_v[device_it]] ) {
74 						activePmosCount++;
75 					}
76 					break;
77 				}
78 				case RESISTOR: { resistorCount++; break; }
79 				case CAPACITOR: { capacitorCount++; break; }
80 				case DIODE: { diodeCount++; break; }
81 				default: break;
82 				}
83 			}
84 		}
85 	}
86 	for ( auto device_it = theCvcDb_p->firstGate_v[theNetId]; device_it != UNKNOWN_DEVICE; device_it = theCvcDb_p->nextGate_v[device_it] ) {
87 		if ( theCvcDb_p->IsSubcircuitOf(theCvcDb_p->deviceParent_v[device_it], theInstanceId) ) {
88 			if ( theCvcDb_p->equivalentNet_v[theCvcDb_p->sourceNet_v[device_it]] != theCvcDb_p->equivalentNet_v[theCvcDb_p->drainNet_v[device_it]] ) {
89 				// does not count mos capacitors
90 				switch( theCvcDb_p->deviceType_v[device_it] ) {
91 				case NMOS:
92 				case LDDN: { nmosGateCount++; break; }
93 				case PMOS:
94 				case LDDP: { pmosGateCount++; break; }
95 				default: break;
96 				}
97 			}
98 		}
99 	}
100 /*
101 	for ( auto device_it = theCvcDb_p->firstBulk_v[theNetId]; device_it != UNKNOWN_DEVICE; device_it = theCvcDb_p->nextBulk_v[device_it] ) {
102 		if ( theCvcDb_p->IsSubcircuitOf(theCvcDb_p->deviceParent_v[device_it], theInstanceId) ) {
103 			switch( theCvcDb_p->deviceType_v[device_it] ) {
104 			case NMOS:
105 			case LDDN: { nmosBulkCount++; break; }
106 			case PMOS:
107 			case LDDP: { pmosBulkCount++; break; }
108 			default: break;
109 			}
110 		}
111 	}
112 */
113 }
114 
Print(CCvcDb * theCvcDb_p)115 void CDeviceCount::Print(CCvcDb * theCvcDb_p) {
116 	cout << "Device counts for net " << theCvcDb_p->NetName(netId) << endl;
117 	cout << "Source/Drain counts" << endl;
118 	cout << "NMOS: " << activeNmosCount << "/" << nmosCount << "; PMOS: " << activePmosCount << "/" << pmosCount;
119 	cout << "; RESISTOR: " << resistorCount << "; CAPACITOR: " << capacitorCount << "; DIODE: " << diodeCount << endl;
120 	cout << "Gate counts" << endl;
121 	cout << "NMOS: " << nmosGateCount << "; PMOS: " << pmosGateCount << endl;
122 //	cout << "Bulk counts" << endl;
123 //	cout << "NMOS: " << nmosBulkCount << "; PMOS: " << pmosBulkCount << endl;
124 }
125