00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "torc/architecture/DDB.hpp"
00020 #include "torc/architecture/DigestStream.hpp"
00021 #include "torc/common/DirectoryTree.hpp"
00022 #include "torc/architecture/OutputStreamHelpers.hpp"
00023 #include <boost/filesystem/convenience.hpp>
00024 #include <boost/algorithm/string.hpp>
00025 #include <iostream>
00026 #include <fstream>
00027
00028 namespace torc {
00029 namespace architecture {
00030
00031 void DDB::initialize(const string& inDeviceName, const string& inPackageName) {
00032
00033
00034 using std::string;
00035 using std::cout;
00036 using std::cerr;
00037 using std::clog;
00038 using std::endl;
00039 using std::fstream;
00040 using boost::uint32_t;
00041
00042 try {
00043
00044
00045 uint32_t familyDatabaseBytesRead = 0;
00046 uint32_t deviceDatabaseBytesRead = 0;
00047
00048
00049 mDeviceName = inDeviceName;
00050 string deviceFilename = inDeviceName + ".db";
00051 boost::to_lower(deviceFilename);
00052 boost::filesystem::path devicePath
00053 = torc::common::DirectoryTree::getDevicesPath() / deviceFilename;
00054 clog << "Reading device " << inDeviceName << " (" << devicePath << ")..." << endl;
00055 DigestStream deviceDatabaseStream(devicePath);
00056 deviceDatabaseStream.exceptions(fstream::eofbit | fstream::failbit | fstream::badbit);
00057 deviceDatabaseBytesRead += mDeviceVersion.readVersions(deviceDatabaseStream, true);
00058 deviceDatabaseBytesRead += readFamilyName(deviceDatabaseStream);
00059
00060
00061 boost::filesystem::path familyPath = devicePath.parent_path() / (mFamilyName + ".db");
00062 cout << "\tReading family " << mFamilyName << " (" << familyPath << ")..." << endl;
00063 DigestStream familyDatabaseStream(familyPath);
00064 familyDatabaseStream.exceptions(fstream::eofbit | fstream::failbit | fstream::badbit);
00065
00066
00067 familyDatabaseBytesRead += mFamilyVersion.readVersions(familyDatabaseStream, false);
00068 familyDatabaseBytesRead += mTiles.readTileTypes(familyDatabaseStream);
00069 familyDatabaseBytesRead += mTiles.readTileWireInfo(familyDatabaseStream);
00070 deviceDatabaseBytesRead += readSpeedGrades(deviceDatabaseStream);
00071 deviceDatabaseBytesRead += mSites.readPackages(deviceDatabaseStream);
00072 deviceDatabaseBytesRead += mTiles.readTileMap(deviceDatabaseStream);
00073 deviceDatabaseBytesRead += mSegments.readTilewireSegments(deviceDatabaseStream);
00074 bool extendedAnchorTileCount
00075 = mDeviceVersion.getFormat() == torc::common::DottedVersion(1, 0, 1);
00076 deviceDatabaseBytesRead
00077 += mSegments.readSegments(deviceDatabaseStream, extendedAnchorTileCount);
00078 deviceDatabaseBytesRead += mSegments.readIrregularArcs(deviceDatabaseStream);
00079 familyDatabaseBytesRead += mSites.readPrimitiveTypes(familyDatabaseStream);
00080 familyDatabaseBytesRead += mSites.readPrimitivePinMaps(familyDatabaseStream);
00081 deviceDatabaseBytesRead += mSites.readSites(deviceDatabaseStream);
00082 cout << "Read " << familyDatabaseBytesRead << " bytes from " << mFamilyName << endl;
00083 cout << "Read " << deviceDatabaseBytesRead << " bytes from " << mDeviceName << endl;
00084
00085 mWireUsage.autosize();
00086 mArcUsage.autosize();
00087
00088
00089 if(inPackageName.length()) mSites.activatePackage(inPackageName);
00090 }
00091
00092 catch(fstream::failure f) {
00093 cerr << "An unprocessed ifstream::failure exception was thrown: " << f.what() << endl;
00094 throw;
00095 }
00096
00097 }
00098
00099 size_t DDB::readFamilyName(DigestStream& inStream) {
00100
00101 size_t bytesReadOffset = inStream.getBytesRead();
00102 char scratch[1 << 10];
00103 boost::uint16_t nameLength = 0;
00104
00105
00106 string sectionName;
00107 inStream.readSectionHeader(sectionName);
00108
00109 if(sectionName != ">>>> Family >>>>") throw -1;
00110
00111
00112 inStream.read(nameLength);
00113 if(nameLength > sizeof(scratch)) throw -1;
00114 inStream.read(scratch, nameLength);
00115 scratch[nameLength] = 0;
00116 mFamilyName = scratch;
00117
00118
00119 return inStream.getBytesRead() - bytesReadOffset;
00120 }
00121
00122 size_t DDB::readSpeedGrades(DigestStream& inStream) {
00123
00124 size_t bytesReadOffset = inStream.getBytesRead();
00125 char scratch[1 << 10];
00126 uint16_t nameLength = 0;
00127
00128
00129 string sectionName;
00130 inStream.readSectionHeader(sectionName);
00131
00132 if(sectionName != ">>>> Speeds >>>>") throw -1;
00133
00134
00135 uint16_t speedGradeCount;
00136 inStream.read(speedGradeCount);
00137 std::cout << "\tReading " << speedGradeCount << " speed grade"
00138 << (speedGradeCount != 1 ? "s" : "") << " (";
00139
00140 for(uint16_t i = 0; i < speedGradeCount; i++) {
00141
00142 inStream.read(nameLength);
00143 if(nameLength > sizeof(scratch)) throw -1;
00144 inStream.read(scratch, nameLength);
00145 scratch[nameLength] = 0;
00146 mSpeedGrades.push_back(scratch);
00147 std::cout << scratch << (i + 1 < speedGradeCount ? ", " : "");
00148 }
00149 std::cout << ") ... " << std::endl;
00150
00151
00152 return inStream.getBytesRead() - bytesReadOffset;
00153 }
00154
00155 void DDB::expandSegment(const Tilewire& inTilewire, TilewireVector& outTilewires,
00156 EExpandDirection inExpandDirection) {
00157
00158
00159 WireIndex wireIndex = inTilewire.getWireIndex();
00160 TileIndex tileIndex = inTilewire.getTileIndex();
00161 const Segments::SegmentReference& compactSegmentReference
00162 = mSegments.getTilewireSegment(inTilewire);
00163
00164 if(!compactSegmentReference.isDefined()) return;
00165
00166
00167 Array<Segments::CompactSegmentTilewire> trivialSegmentReference;
00168 if(compactSegmentReference.isTrivial()) {
00169 trivialSegmentReference.setSize(1);
00170 trivialSegmentReference[0] = Segments::CompactSegmentTilewire(wireIndex,
00171 TileOffset(tileIndex));
00172 }
00173 const Array<Segments::CompactSegmentTilewire>& segmentReference
00174 = compactSegmentReference.isTrivial() ? trivialSegmentReference
00175 : mSegments.mCompactSegments[compactSegmentReference.getCompactSegmentIndex()];
00176
00177
00178 TileIndex anchorTileIndex = compactSegmentReference.getAnchorTileIndex();
00179 Array<Segments::CompactSegmentTilewire>::const_iterator csp
00180 = segmentReference.begin();
00181 Array<Segments::CompactSegmentTilewire>::const_iterator cse
00182 = segmentReference.end();
00183 bool sinkward = (inExpandDirection & eExpandDirectionSinkward) != 0;
00184 bool sourceward = (inExpandDirection & eExpandDirectionSourceward) != 0;
00185 while(csp < cse) {
00186
00187 const Segments::CompactSegmentTilewire& compactSegmentTilewire = *csp++;
00188 WireIndex csWireIndex = compactSegmentTilewire.getWireIndex();
00189 TileOffset csTileOffset = compactSegmentTilewire.getTileOffset();
00190 TileIndex csTileIndex = csTileOffset + anchorTileIndex;
00191
00192 outTilewires.push_back(Tilewire(csTileIndex, csWireIndex));
00193
00194 const TileInfo& tileInfo = mTiles.getTileInfo(csTileIndex);
00195 const WireInfo& wireInfo = mTiles.getWireInfo(tileInfo.getTypeIndex(), csWireIndex);
00196
00197 if(sinkward) {
00198 const WireArray& tiedSinks = wireInfo.getTiedSinks();
00199 WireArray::const_iterator p = tiedSinks.begin();
00200 WireArray::const_iterator e = tiedSinks.end();
00201 while(p < e) expandSegment(Tilewire(csTileIndex, *p++), outTilewires,
00202 inExpandDirection);
00203 }
00204
00205 if(sourceward) {
00206 const WireArray& tiedSources = wireInfo.getTiedSources();
00207 WireArray::const_iterator p = tiedSources.begin();
00208 WireArray::const_iterator e = tiedSources.end();
00209 while(p < e) expandSegment(Tilewire(csTileIndex, *p++), outTilewires,
00210 inExpandDirection);
00211 }
00212 }
00213 }
00214
00215 void DDB::expandTilewireSinks(const Tilewire& inTilewire, TilewireVector& outSinks,
00216 bool inUseTied, bool inUseRegular, bool inUseIrregular, bool inUseRoutethrough) {
00217
00218 WireIndex wireIndex = inTilewire.getWireIndex();
00219 TileIndex tileIndex = inTilewire.getTileIndex();
00220 const TileInfo& tileInfo = mTiles.getTileInfo(tileIndex);
00221 const WireInfo& wireInfo = mTiles.getWireInfo(tileInfo.getTypeIndex(), wireIndex);
00222
00223
00224 if(inUseRegular) {
00225 const WireArray& sinks = wireInfo.getSinks();
00226 WireArray::const_iterator sp = sinks.begin();
00227 WireArray::const_iterator se = sinks.end();
00228 while(sp < se) outSinks.push_back(Tilewire(tileIndex, *sp++));
00229 }
00230
00231
00232 if(inUseIrregular) {
00233 const WireArray& irregularSinks = wireInfo.getIrregularSinks();
00234 WireArray::const_iterator isp = irregularSinks.begin();
00235 WireArray::const_iterator ise = irregularSinks.end();
00236 while(isp < ise) {
00237 WireIndex sinkWireIndex = *isp++;
00238
00239 const Segments::SegmentReference& segment
00240 = mSegments.getTilewireSegment(Tilewire(tileIndex, sinkWireIndex));
00241 if(!segment.isDefined()) continue;
00242
00243 const Segments::IrregularArc* irregularArc = mSegments.getIrregularArc(tileIndex,
00244 wireIndex, sinkWireIndex);
00245 if(irregularArc != 0 && !segment.isDefined()) {
00246 std::cerr << "WARNING: Irregular arc " << inTilewire << " >> "
00247 << Tilewire(tileIndex, sinkWireIndex)
00248 << " is defined, but the sink segment is undefined." << std::endl;
00249 }
00250 if(irregularArc == 0) continue;
00251
00252 outSinks.push_back(Tilewire(tileIndex, sinkWireIndex));
00253 }
00254 }
00255
00256
00257 if(inUseRoutethrough) {
00258 const WireArray& routethroughSinks = wireInfo.getRoutethroughSinks();
00259 WireArray::const_iterator rsp = routethroughSinks.begin();
00260 WireArray::const_iterator rse = routethroughSinks.end();
00261 while(rsp < rse) outSinks.push_back(Tilewire(tileIndex, *rsp++));
00262 }
00263 }
00264
00265 void DDB::expandTilewireSources(const Tilewire& inTilewire, TilewireVector& outSources,
00266 bool inUseTied, bool inUseRegular, bool inUseIrregular, bool inUseRoutethrough) {
00267
00268 WireIndex wireIndex = inTilewire.getWireIndex();
00269 TileIndex tileIndex = inTilewire.getTileIndex();
00270 const TileInfo& tileInfo = mTiles.getTileInfo(tileIndex);
00271 const WireInfo& wireInfo = mTiles.getWireInfo(tileInfo.getTypeIndex(), wireIndex);
00272
00273
00274 if(inUseRegular) {
00275 const WireArray& sources = wireInfo.getSources();
00276 WireArray::const_iterator sp = sources.begin();
00277 WireArray::const_iterator se = sources.end();
00278 while(sp < se) outSources.push_back(Tilewire(tileIndex, *sp++));
00279 }
00280
00281
00282 if(inUseIrregular) {
00283 const WireArray& irregularSources = wireInfo.getIrregularSources();
00284 WireArray::const_iterator isp = irregularSources.begin();
00285 WireArray::const_iterator ise = irregularSources.end();
00286 while(isp < ise) {
00287 WireIndex sourceWireIndex = *isp++;
00288
00289 const Segments::SegmentReference& segment
00290 = mSegments.getTilewireSegment(Tilewire(tileIndex, sourceWireIndex));
00291 if(!segment.isDefined()) continue;
00292
00293 const Segments::IrregularArc* irregularArc = mSegments.getIrregularArc(tileIndex,
00294 sourceWireIndex, wireIndex);
00295 if(irregularArc != 0 && !segment.isDefined()) {
00296 std::cerr << "WARNING: Irregular arc " << inTilewire << " >> "
00297 << Tilewire(tileIndex, sourceWireIndex)
00298 << " is defined, but the source segment is undefined." << std::endl;
00299 }
00300 if(irregularArc == 0) continue;
00301
00302 outSources.push_back(Tilewire(tileIndex, sourceWireIndex));
00303 }
00304 }
00305
00306
00307 if(inUseRoutethrough) {
00308 const WireArray& routethroughSources = wireInfo.getRoutethroughSources();
00309 WireArray::const_iterator rsp = routethroughSources.begin();
00310 WireArray::const_iterator rse = routethroughSources.end();
00311 while(rsp < rse) outSources.push_back(Tilewire(tileIndex, *rsp++));
00312 }
00313 }
00314
00315 void DDB::expandSegmentSinks(const Tilewire& inTilewire, ArcVector& outArcs,
00316 EExpandDirection inExpandDirection, bool inUseTied, bool inUseRegular,
00317 bool inUseIrregular, bool inUseRoutethrough) {
00318
00319 TilewireVector segment;
00320 expandSegment(inTilewire, segment, inExpandDirection);
00321
00322 TilewireVector::const_iterator sep = segment.begin();
00323 TilewireVector::const_iterator see = segment.end();
00324 while(sep < see) {
00325
00326 const Tilewire& tilewire = *sep++;
00327 TilewireVector sinks;
00328 expandTilewireSinks(tilewire, sinks, inUseTied, inUseRegular, inUseIrregular,
00329 inUseRoutethrough);
00330
00331 TilewireVector::const_iterator sip = sinks.begin();
00332 TilewireVector::const_iterator sie = sinks.end();
00333 while(sip < sie) outArcs.push_back(Arc(tilewire, *sip++));
00334 }
00335 }
00336
00337 void DDB::expandSegmentSources(const Tilewire& inTilewire, ArcVector& outArcs,
00338 EExpandDirection inExpandDirection, bool inUseTied, bool inUseRegular,
00339 bool inUseIrregular, bool inUseRoutethrough) {
00340
00341 TilewireVector segment;
00342 expandSegment(inTilewire, segment, inExpandDirection);
00343
00344 TilewireVector::const_iterator sep = segment.begin();
00345 TilewireVector::const_iterator see = segment.end();
00346 while(sep < see) {
00347
00348 const Tilewire& tilewire = *sep++;
00349 TilewireVector sources;
00350 expandTilewireSources(tilewire, sources, inUseTied, inUseRegular, inUseIrregular,
00351 inUseRoutethrough);
00352
00353 TilewireVector::const_iterator sop = sources.begin();
00354 TilewireVector::const_iterator soe = sources.end();
00355 while(sop < soe) outArcs.push_back(Arc(*sop++, tilewire));
00356 }
00357 }
00358
00359 }
00360 }