1 /*
2 * CInstance.cc
3 *
4 * Copyright 2014-2018 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 "CInstance.hh"
25
26 #include "CCvcDb.hh"
27 #include "CCircuit.hh"
28 #include "obstack.h"
29
30 #define NOT_PARALLEL false
31
32 int gHashCollisionCount;
33 int gMaxHashLength;
34
AssignTopGlobalIDs(CCvcDb * theCvcDb_p,CCircuit * theMaster_p)35 void CInstance::AssignTopGlobalIDs(CCvcDb * theCvcDb_p, CCircuit * theMaster_p) {
36
37 theMaster_p->instanceId_v.push_back(0);
38 theCvcDb_p->subcircuitCount = 1;
39 firstSubcircuitId = 1;
40 parentId = 0;
41 master_p = theMaster_p;
42 netId_t myLastNet = theMaster_p->localSignalIdMap.size();
43 localToGlobalNetId_v.reserve(myLastNet);
44 localToGlobalNetId_v.resize(myLastNet);
45 theMaster_p->internalSignal_v.clear();
46 theMaster_p->internalSignal_v.reserve(theMaster_p->localSignalIdMap.size());
47 theMaster_p->internalSignal_v.resize(theMaster_p->localSignalIdMap.size());
48 for (CTextNetIdMap::iterator textNetIdPair_pit = theMaster_p->localSignalIdMap.begin(); textNetIdPair_pit != theMaster_p->localSignalIdMap.end(); textNetIdPair_pit++) {
49 theMaster_p->internalSignal_v[textNetIdPair_pit->second] = textNetIdPair_pit->first;
50 }
51 for (netId_t globalNet_it = 0; globalNet_it < myLastNet; globalNet_it++) {
52 localToGlobalNetId_v[globalNet_it] = globalNet_it;
53 }
54 theCvcDb_p->netCount = myLastNet;
55 theCvcDb_p->subcircuitCount += theMaster_p->subcircuitPtr_v.size();
56 theCvcDb_p->deviceCount = theMaster_p->devicePtr_v.size();
57 theCvcDb_p->netParent_v.resize(theCvcDb_p->netCount, 0);
58 theCvcDb_p->deviceParent_v.resize(theCvcDb_p->deviceCount, 0);
59
60 instanceId_t myLastSubcircuitId = theMaster_p->subcircuitPtr_v.size();
61 instanceId_t myNewInstanceId;
62 for (instanceId_t subcircuit_it = 0; subcircuit_it < myLastSubcircuitId; subcircuit_it++) {
63 if (theMaster_p->subcircuitPtr_v[subcircuit_it]->master_p->deviceCount > 0) {
64 myNewInstanceId = firstSubcircuitId + subcircuit_it;
65 CDevice * mySubcircuit_p = theMaster_p->subcircuitPtr_v[subcircuit_it];
66 if ( mySubcircuit_p->master_p->instanceId_v.size() == 0 ) mySubcircuit_p->master_p->AllocateInstances(theCvcDb_p, myNewInstanceId);
67 theCvcDb_p->instancePtr_v[myNewInstanceId] = new CInstance;
68 theCvcDb_p->instancePtr_v[myNewInstanceId]->AssignGlobalIDs(theCvcDb_p, myNewInstanceId, mySubcircuit_p, 0, this, NOT_PARALLEL);
69 }
70 }
71 theCvcDb_p->netParent_v.shrink_to_fit();
72 theCvcDb_p->deviceParent_v.shrink_to_fit();
73 theCvcDb_p->debugFile << "DEBUG: netParent size " << theCvcDb_p->netParent_v.size() << "; deviceParent size " << theCvcDb_p->deviceParent_v.size() << endl;
74 theCvcDb_p->debugFile << "DEBUG: parallel collisions " << gHashCollisionCount << " max length " << gMaxHashLength << endl;
75 }
76
AssignGlobalIDs(CCvcDb * theCvcDb_p,const instanceId_t theInstanceId,CDevice * theSubcircuit_p,const instanceId_t theParentId,CInstance * theParent_p,bool isParallel)77 void CInstance::AssignGlobalIDs(CCvcDb * theCvcDb_p, const instanceId_t theInstanceId, CDevice * theSubcircuit_p, const instanceId_t theParentId,
78 CInstance * theParent_p, bool isParallel) {
79 master_p = theSubcircuit_p->master_p;
80 instanceId_t myLastSubcircuitId = master_p->subcircuitPtr_v.size();
81 firstSubcircuitId = theCvcDb_p->subcircuitCount;
82 master_p->instanceId_v.push_back(theInstanceId);
83
84 parentId = theParentId;
85 instanceId_t myParallelInstance;
86 if ( isParallel ) {
87 assert(theParent_p->IsParallelInstance());
88 CInstance * myParentParallelInstance_p = theCvcDb_p->instancePtr_v[theParent_p->parallelInstanceId];
89 int myInstanceOffset = theInstanceId - theParent_p->firstSubcircuitId;
90 parallelInstanceId = myParentParallelInstance_p->firstSubcircuitId + myInstanceOffset;
91 CInstance * myParallelInstance_p = theCvcDb_p->instancePtr_v[parallelInstanceId];
92 if ( myParallelInstance_p->IsParallelInstance() ) {
93 theCvcDb_p->instancePtr_v[myParallelInstance_p->parallelInstanceId]->parallelInstanceCount++;
94 } else {
95 myParallelInstance_p->parallelInstanceCount++;
96 }
97 theCvcDb_p->debugFile << "DEBUG: found parallel instance in parallel instance at " << theCvcDb_p->HierarchyName(theInstanceId) << endl;
98 } else {
99 if ( theSubcircuit_p->signalId_v.size() <= theCvcDb_p->cvcParameters.cvcParallelCircuitPortLimit ) {
100 myParallelInstance = theSubcircuit_p->FindParallelInstance(theCvcDb_p, theInstanceId, theParent_p->localToGlobalNetId_v);
101 if ( myParallelInstance == theInstanceId ) {
102 theCvcDb_p->instancePtr_v[theInstanceId]->parallelInstanceCount = 1;
103 } else { // skip parallel circuits
104 theCvcDb_p->instancePtr_v[myParallelInstance]->parallelInstanceCount++;
105 theCvcDb_p->debugFile << "DEBUG: found parallel instance at " << theCvcDb_p->HierarchyName(theInstanceId) << endl;
106 parallelInstanceId = myParallelInstance;
107 isParallel = true;
108 }
109 }
110 }
111 if ( ! isParallel ) { // don't expand devices/nets for parallel instances
112 firstNetId = theCvcDb_p->netCount;
113 firstDeviceId = theCvcDb_p->deviceCount;
114
115 netId_t myLastNet = master_p->localSignalIdMap.size();
116 localToGlobalNetId_v.reserve(myLastNet);
117 localToGlobalNetId_v.resize(myLastNet);
118 for (netId_t net_it = 0; net_it < master_p->portCount; net_it++) {
119 localToGlobalNetId_v[net_it] = theParent_p->localToGlobalNetId_v[theSubcircuit_p->signalId_v[net_it]];
120 }
121 for (netId_t net_it = master_p->portCount; net_it < myLastNet; net_it++) {
122 localToGlobalNetId_v[net_it] = firstNetId + net_it - master_p->portCount;
123 }
124 theCvcDb_p->netCount += master_p->LocalNetCount();
125 theCvcDb_p->deviceCount += master_p->devicePtr_v.size();
126 theCvcDb_p->netParent_v.resize(theCvcDb_p->netCount, theInstanceId);
127 theCvcDb_p->deviceParent_v.resize(theCvcDb_p->deviceCount, theInstanceId);
128 }
129
130 theCvcDb_p->subcircuitCount += master_p->subcircuitPtr_v.size();
131
132 instanceId_t myNewInstanceId;
133 for (instanceId_t subcircuit_it = 0; subcircuit_it < myLastSubcircuitId; subcircuit_it++) {
134 myNewInstanceId = firstSubcircuitId + subcircuit_it;
135 CDevice * mySubcircuit_p = master_p->subcircuitPtr_v[subcircuit_it];
136 if (mySubcircuit_p->master_p->deviceCount > 0) {
137 if ( mySubcircuit_p->master_p->instanceId_v.size() == 0 ) mySubcircuit_p->master_p->AllocateInstances(theCvcDb_p, myNewInstanceId);
138 theCvcDb_p->instancePtr_v[myNewInstanceId] = new CInstance;
139 theCvcDb_p->instancePtr_v[myNewInstanceId]->AssignGlobalIDs(theCvcDb_p, myNewInstanceId, mySubcircuit_p, theInstanceId, this, isParallel);
140 }
141 }
142 }
143
Print(const instanceId_t theInstanceId,const string theIndentation)144 void CInstance::Print (const instanceId_t theInstanceId, const string theIndentation) {
145 cout << theIndentation << "Instance> " << theInstanceId << endl;
146 string myIndentation = theIndentation + " ";
147 cout << myIndentation << "First: subcircuit: " << firstSubcircuitId;
148 cout << " net: " << firstNetId;
149 cout << " device: " << firstDeviceId << endl;
150 cout << myIndentation << "parent: " << parentId << " master: " << master_p->name << endl;
151 cout << myIndentation << "signal map:";
152 for (netId_t net_it = 0; net_it < localToGlobalNetId_v.size(); net_it++) {
153 cout << " " << net_it << ":" << localToGlobalNetId_v[net_it];
154 }
155 cout << endl;
156 }
157
Clear()158 void CInstancePtrVector::Clear() {
159 for ( auto instance_ppit = begin(); instance_ppit != end(); instance_ppit++ ) {
160 delete (*instance_ppit);
161 }
162 resize(0);
163 }
164
~CInstancePtrVector()165 CInstancePtrVector::~CInstancePtrVector() {
166 Clear();
167 }
168
169