00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "torc/bitstream/Virtex2.hpp"
00020 #include <iostream>
00021
00022
00023 #include "torc/architecture/DDB.hpp"
00024 #include "torc/architecture/XilinxDatabaseTypes.hpp"
00025 #include "torc/common/DirectoryTree.hpp"
00026 #include <fstream>
00027
00028
00029 namespace torc {
00030 namespace bitstream {
00031
00032 const char* Virtex2::sPacketTypeName[ePacketTypeCount] = {
00033 "[UNKNOWN TYPE 0]", "TYPE1", "TYPE2", "[UNKNOWN TYPE 3]", "[UNKNOWN TYPE 4]",
00034 "[UNKNOWN TYPE 5]", "[UNKNOWN TYPE 6]", "[UNKNOWN TYPE 7]"
00035 };
00036
00037 const char* Virtex2::sOpcodeName[eOpcodeCount] = {
00038 "NOP", "READ", "WRITE", "RESERVED"
00039 };
00040
00041 const char* Virtex2::sRegisterName[eRegisterCount] = {
00042 "CRC", "FAR", "FDRI", "FDRO", "CMD", "CTL", "MASK", "STAT", "LOUT", "COR", "MFWR", "FLR", "KEY",
00043 "CBC", "IDCODE"
00044 };
00045
00046 const char* Virtex2::sCommandName[eCommandCount] = {
00047 "[UNKNOWN COMMAND 0]", "WCFG", "MFWR", "LFRM", "RCFG", "START", "RCAP", "RCRC", "AGHIGH", "SWITCH",
00048 "GRESTORE", "SHUTDOWN", "GCAPTURE", "DESYNCH"
00049 };
00050
00051 #define VALUES (const char*[])
00052
00053
00054 const Bitstream::Subfield Virtex2::sCOR[] = {
00055 {0x00000007, 0, "GWE_cycle", "GWE_CYCLE", 5,
00056
00057
00058 VALUES{"[UNDEFINED 0]", "2", "3", "4", "5", "6", "[UNDEFINED 6]", "[UNDEFINED 7]", 0}},
00059 {0x00000038, 3, "GTS_cycle", "GTS_CYCLE", 4,
00060
00061
00062 VALUES{"[UNDEFINED 0]", "2", "3", "4", "5", "6", "[UNDEFINED 6]", "[UNDEFINED 7]", 0}},
00063 {0x000001c0, 6, "LCK_cycle", "LOCK_CYCLE", 7,
00064
00065
00066 VALUES{"1", "2", "3", "4", "5", "6", "[UNDEFINED 6]", "NoWait", 0}},
00067 {0x00000E00, 9, "Match_cycle", "MATCH_CYCLE", 7,
00068
00069
00070 VALUES{"1", "2", "3", "4", "5", "6", "[UNDEFINED 6]", "NoWait", 0}},
00071 {0x00007000, 12, "DONE_cycle", "DONE_CYCLE", 3,
00072
00073
00074 VALUES{"[UNDEFINED 0]", "2", "3", "4", "5", "6", "[UNDEFINED 6]", "[UNDEFINED 7]", 0}},
00075 {0x00018000, 15, "StartupClk", "SSCLKSRC", 0,
00076
00077
00078 VALUES{"Cclk", "UserClk", "JtagClk", "JtagClk", 0}},
00079 {0x007e0000, 17, "ConfigRate", "OSCFSEL", 0,
00080
00081
00082 VALUES{
00083 "[UNKNOWN 0]", "[UNKNOWN 1]", "[UNKNOWN 2]", "[UNKNOWN 3]",
00084 "[UNKNOWN 4]", "[UNKNOWN 5]", "[UNKNOWN 6]", "[UNKNOWN 7]",
00085 "[UNKNOWN 8]", "[UNKNOWN 9]", "[UNKNOWN 10]", "[UNKNOWN 11]",
00086 "[UNKNOWN 12]", "[UNKNOWN 13]", "[UNKNOWN 14]", "[UNKNOWN 15]",
00087 "[UNKNOWN 16]", "[UNKNOWN 17]", "[UNKNOWN 18]", "[UNKNOWN 19]",
00088 "[UNKNOWN 20]", "[UNKNOWN 21]", "[UNKNOWN 22]", "[UNKNOWN 23]",
00089 "[UNKNOWN 24]", "[UNKNOWN 25]", "[UNKNOWN 26]", "[UNKNOWN 27]",
00090 "[UNKNOWN 28]", "[UNKNOWN 29]", "[UNKNOWN 30]", "[UNKNOWN 31]",
00091 0}},
00092 {0x00800000, 23, "Capture", "SINGLE", 0,
00093
00094
00095 VALUES{"Continuous", "OneShot", 0}},
00096 {0x01000000, 24, "DriveDone", "DRIVE_DONE", 0,
00097
00098
00099 VALUES{"No", "Yes", 0}},
00100 {0x02000000, 25, "DonePipe", "DONE_PIPE", 0,
00101
00102
00103 VALUES{"No", "Yes", 0}},
00104 {0x04000000, 26, "DCMShutDown", "SHUT_RST_DCM", 0,
00105
00106
00107
00108 VALUES{"No", "Yes", 0}},
00109 {0x20000000, 29, "CRC", "CRC_BYPASS", 0,
00110
00111
00112 VALUES{"Enable", "Disable", 0}},
00113 {0, 0, 0, 0, 0, 0}
00114 };
00115
00116
00117
00118 const Bitstream::Subfield Virtex2::sSTAT[] = {
00119 {0x00000001, 0, "CRC_error", "CRC_ERROR", 0,
00120
00121
00122 VALUES{"No", "Yes", 0}},
00123 {0x00000002, 1, "DecryptorSecuritySet", "PART_SECURED", 0,
00124
00125
00126 VALUES{"No", "Yes", 0}},
00127 {0x00000004, 2, "DCM_locked", "DCM_LOCK", 0,
00128
00129
00130 VALUES{"No", "Yes", 0}},
00131 {0x00000008, 3, "DCI_matched", "DCI_MATCH", 0,
00132
00133
00134 VALUES{"No", "Yes", 0}},
00135 {0x00000010, 4, "IN_error", "IN_ERROR", 0,
00136
00137
00138 VALUES{"No", "Yes", 0}},
00139 {0x00000020, 5, "GTS_CFG_B", "GTS_CFG_B", 0,
00140
00141
00142 VALUES{"IoDisabled", "IoEnabled", 0}},
00143 {0x00000040, 6, "GWE", "GWE", 0,
00144
00145
00146
00147 VALUES{"WriteDisabled", "WriteEnabled", 0}},
00148 {0x00000080, 7, "GHIGH_B", "GHIGH_B", 0,
00149
00150
00151 VALUES{"InterconnectDisabled", "InterconnectEnabled", 0}},
00152 {0x00000700, 8, "Mode", "MODE", 0,
00153
00154
00155 VALUES{"MasterSerial", "SlaveSelectMap32", "[UNDEFINED 2]", "MasterSelectMap",
00156 "[UNDEFINED 3]", "JTAG", "SlaveSelectMap8", "[UNDEFINED 6]", "SlaveSerial", 0}},
00157 {0x00000800, 11, "INIT", "INIT", 0,
00158
00159
00160 VALUES{"Deasserted", "Asserted", 0}},
00161 {0x00001000, 12, "Done", "DONE", 0,
00162
00163
00164 VALUES{"Deasserted", "Asserted", 0}},
00165 {0x00002000, 13, "ID_error", "ID_ERROR", 0,
00166
00167
00168 VALUES{"No", "Yes", 0}},
00169 {0x00004000, 14, "Decrypt_error", "DEC_ERROR", 0,
00170
00171
00172 VALUES{"NoError", "Error", 0}},
00173 {0x00008000, 15, "BAD_KEY_SEQ", "BAD_KEY_SEQ", 0,
00174
00175
00176
00177 VALUES{"NoError", "Error", 0}},
00178 {0, 0, 0, 0, 0, 0}
00179 };
00180
00181
00182 const Bitstream::Subfield Virtex2::sCTL[] = {
00183 {0x00000001, 0, "GTS_USER_B", "GTS_USER_B", 0,
00184
00185
00186 VALUES{"IoDisabled", "IoActive", 0}},
00187 {0x00000008, 3, "Persist", "PERSIST", 0,
00188
00189
00190 VALUES{"No", "Yes", 0}},
00191 {0x00000030, 4, "Security", "SBITS", 0,
00192
00193
00194
00195 VALUES{"None", "Level1", "Level2", "Level2", 0}},
00196 {0, 0, 0, 0, 0, 0}
00197 };
00198
00199
00200 const Bitstream::Subfield Virtex2::sMASK[] = {
00201 {0x00000001, 0, "GTS_USER_B", "GTS_USER_B", 0, VALUES{"Protected", "Writable", 0}},
00202 {0x00000008, 3, "Persist", "PERSIST", 0, VALUES{"Protected", "Writable", 0}},
00203 {0x00000080, 4, "Security", "SBITS", 0,
00204 VALUES{"Protected", "[UNKNOWN 1]", "[UNKNOWN 2]", "Writable", 0}},
00205 {0, 0, 0, 0, 0, 0}
00206 };
00207
00208
00209 uint32_t Virtex2::makeSubfield(ERegister inRegister, const std::string& inSubfield,
00210 const std::string& inSetting) {
00211 const Subfield* subfields;
00212 switch(inRegister) {
00213 case eRegisterCOR: subfields = sCOR; break;
00214 case eRegisterSTAT: subfields = sSTAT; break;
00215 case eRegisterCTL: subfields = sCTL; break;
00216 case eRegisterMASK: subfields = sMASK; break;
00217 default: return 0;
00218 }
00219 for(uint32_t field = 0; subfields[field].mMask != 0; field++) {
00220 const Subfield& subfield = subfields[field];
00221 if(inSubfield != subfield.mBitgenName && inSubfield != subfield.mConfigGuideName)
00222 continue;
00223 const char** ptr = subfield.mValues;
00224 for(uint32_t i = 0; *ptr != 0; i++, ptr++) {
00225 if(inSetting == *ptr) return (i << subfield.mShift) & subfield.mMask;
00226 }
00227 }
00228 return 0;
00229 }
00230
00231
00232
00233 #ifndef GENERATE_STATIC_DEVICE_INFO
00234
00235 extern DeviceInfo xc2v40;
00236 extern DeviceInfo xc2v80;
00237 extern DeviceInfo xc2v250;
00238 extern DeviceInfo xc2v500;
00239 extern DeviceInfo xc2v1000;
00240 extern DeviceInfo xc2v1500;
00241 extern DeviceInfo xc2v2000;
00242 extern DeviceInfo xc2v3000;
00243 extern DeviceInfo xc2v4000;
00244 extern DeviceInfo xc2v6000;
00245 extern DeviceInfo xc2v8000;
00246
00247 void Virtex2::initializeDeviceInfo(const std::string& inDeviceName) {
00248 using namespace torc::common;
00249 switch(mDevice) {
00250 case eXC2V40: setDeviceInfo(xc2v40); break;
00251 case eXC2V80: setDeviceInfo(xc2v80); break;
00252 case eXC2V250: setDeviceInfo(xc2v250); break;
00253 case eXC2V500: setDeviceInfo(xc2v500); break;
00254 case eXC2V1000: setDeviceInfo(xc2v1000); break;
00255 case eXC2V1500: setDeviceInfo(xc2v1500); break;
00256 case eXC2V2000: setDeviceInfo(xc2v2000); break;
00257 case eXC2V3000: setDeviceInfo(xc2v3000); break;
00258 case eXC2V4000: setDeviceInfo(xc2v4000); break;
00259 case eXC2V6000: setDeviceInfo(xc2v6000); break;
00260 case eXC2V8000: setDeviceInfo(xc2v8000); break;
00261 default: break;
00262 }
00263
00264
00265 }
00266
00267 #else
00268
00269 void Virtex2::initializeDeviceInfo(const std::string& inDeviceName) {
00270
00271 typedef torc::architecture::xilinx::TileCount TileCount;
00272 typedef torc::architecture::xilinx::TileRow TileRow;
00273 typedef torc::architecture::xilinx::TileCol TileCol;
00274 typedef torc::architecture::xilinx::TileTypeIndex TileTypeIndex;
00275 typedef torc::architecture::xilinx::TileTypeCount TileTypeCount;
00276
00277
00278 torc::architecture::DDB ddb(inDeviceName);
00279 const torc::architecture::Tiles& tiles = ddb.getTiles();
00280 uint32_t tileCount = tiles.getTileCount();
00281 uint16_t rowCount = tiles.getRowCount();
00282 uint16_t colCount = tiles.getColCount();
00283 ColumnTypeVector columnTypes;
00284
00285
00286 typedef std::map<TileTypeIndex, std::string> TileTypeIndexToName;
00287 typedef std::map<std::string, TileTypeIndex> TileTypeNameToIndex;
00288 TileTypeIndexToName tileTypeIndexToName;
00289 TileTypeNameToIndex tileTypeNameToIndex;
00290 TileTypeCount tileTypeCount = tiles.getTileTypeCount();
00291 for(TileTypeIndex tileTypeIndex(0); tileTypeIndex < tileTypeCount; tileTypeIndex++) {
00292 const std::string tileTypeName = tiles.getTileTypeName(tileTypeIndex);
00293 tileTypeIndexToName[tileTypeIndex] = tileTypeName;
00294 tileTypeNameToIndex[tileTypeName] = tileTypeIndex;
00295 TileTypeNameToColumnType::iterator ttwp = mTileTypeNameToColumnType.find(tileTypeName);
00296 TileTypeNameToColumnType::iterator ttwe = mTileTypeNameToColumnType.end();
00297 if(ttwp != ttwe) mTileTypeIndexToColumnType[tileTypeIndex] = EColumnType(ttwp->second);
00298 }
00299
00300
00301 columnTypes.resize(colCount);
00302 uint32_t frameCount = 0;
00303 for(uint32_t blockType = 0; blockType < Virtex2::eFarBlockTypeCount; blockType++) {
00304 for(TileCol col; col < colCount; col++) {
00305 columnTypes[col] = eColumnTypeEmpty;
00306 TileTypeIndexToColumnType::iterator ttwe = mTileTypeIndexToColumnType.end();
00307 TileTypeIndexToColumnType::iterator ttwp = ttwe;
00308 for(TileRow row; row < rowCount; row++) {
00309
00310 const torc::architecture::TileInfo& tileInfo
00311 = tiles.getTileInfo(tiles.getTileIndex(row, col));
00312 TileTypeIndex tileTypeIndex = tileInfo.getTypeIndex();
00313
00314 ttwp = mTileTypeIndexToColumnType.find(tileTypeIndex);
00315 if(ttwp != ttwe) {
00316 uint32_t width = mColumnDefs[ttwp->second][blockType];
00317 frameCount += width;
00318
00319
00320 columnTypes[col] = static_cast<EColumnType>(ttwp->second);
00321 break;
00322 }
00323 }
00324 }
00325
00326 if(blockType == 2) break;
00327 }
00328
00329 boost::filesystem::path workingPath = torc::common::DirectoryTree::getWorkingPath();
00330 boost::filesystem::path generatedMap = workingPath / (inDeviceName + ".map.csv");
00331 std::fstream tilemapStream(generatedMap.string().c_str(), std::ios::out);
00332 for(TileRow row; row < rowCount; row++) {
00333 for(TileCol col; col < colCount; col++) {
00334 const torc::architecture::TileInfo& tileInfo
00335 = tiles.getTileInfo(tiles.getTileIndex(row, col));
00336 TileTypeIndex tileTypeIndex = tileInfo.getTypeIndex();
00337 tilemapStream << tiles.getTileTypeName(tileTypeIndex);
00338 if(col + 1 < colCount) tilemapStream << ",";
00339 }
00340 tilemapStream << std::endl;
00341 }
00342 tilemapStream.close();
00343
00344
00345 setDeviceInfo(DeviceInfo(tileCount, rowCount, colCount, columnTypes));
00346
00347 }
00348 #endif
00349
00350 void Virtex2::initializeFrameMaps(void) {
00351
00352 bool debug = 0;
00353 uint32_t frameCount = 0;
00354 uint32_t frameIndex = 0;
00355 bool clockColumn = true;
00356 uint32_t width;
00357 for(uint32_t i = 0; i < Virtex2::eFarBlockTypeCount; i++) {
00358 Virtex2::EFarBlockType blockType = Virtex2::EFarBlockType(i);
00359 uint32_t blockFrameIndexBounds = 0;
00360
00361 uint32_t bitIndex = 0;
00362 uint32_t xdlIndex = 0;
00363 mBitColumnIndexes[i].push_back(bitIndex);
00364 mXdlColumnIndexes[i].push_back(xdlIndex);
00365
00366 uint32_t farMajor = 0;
00367 typedef torc::common::EncapsulatedInteger<uint16_t> ColumnIndex;
00368 uint16_t finalColumn = mDeviceInfo.getColCount()-1;
00369 uint32_t xdlColumnCount = 0;
00370 uint32_t bitColumnCount = 0;
00371 if(clockColumn) {
00372 width = mColumnDefs[eColumnTypeClock][i];
00373 clockColumn = false;
00374 for(uint32_t farMinor = 0; farMinor < width; farMinor++) {
00375 Virtex2::FrameAddress far(blockType, farMajor, farMinor);
00376 mFrameIndexToAddress[frameIndex] = far;
00377 mFrameAddressToIndex[far] = frameIndex;
00378 frameIndex++;
00379 blockFrameIndexBounds++;
00380 }
00381 if(width > 0) farMajor++;
00382 frameCount += width;
00383 }
00384 for(ColumnIndex col; col < mDeviceInfo.getColCount(); col++) {
00385 if(mDeviceInfo.getColumnTypes()[col] == eColumnTypeClock)
00386 continue;
00387 else
00388 width = mColumnDefs[mDeviceInfo.getColumnTypes()[col]][i];
00389 for(uint32_t farMinor = 0; farMinor < width; farMinor++) {
00390 Virtex2::FrameAddress far(blockType, farMajor, farMinor);
00391 mFrameIndexToAddress[frameIndex] = far;
00392 mFrameAddressToIndex[far] = frameIndex;
00393 frameIndex++;
00394 blockFrameIndexBounds++;
00395 }
00396 if(width > 0) farMajor++;
00397 frameCount += width;
00398
00399
00400 if(mDeviceInfo.getColumnTypes()[col] != Virtex2::eColumnTypeEmpty) {
00401 mXdlIndexToBitIndex[bitColumnCount] = xdlColumnCount;
00402 bitColumnCount++;
00403 bitIndex += width;
00404 mBitColumnIndexes[i].push_back(bitIndex);
00405 if(col == finalColumn) {
00406 bitIndex += mColumnDefs[mDeviceInfo.getColumnTypes()[col]][i];
00407 mBitColumnIndexes[i].push_back(bitIndex);
00408 }
00409 }
00410
00411
00412 xdlIndex += width;
00413 mXdlColumnIndexes[i].push_back(xdlIndex);
00414 xdlColumnCount++;
00415 if(col == finalColumn)
00416 {
00417 xdlIndex += mColumnDefs[mDeviceInfo.getColumnTypes()[col]][i];
00418 mXdlColumnIndexes[i].push_back(xdlIndex);
00419 }
00420 }
00421
00422 mBlockFrameIndexBounds[i] = blockFrameIndexBounds;
00423 if (debug) std::cout << "***Block frame index bounds: " << mBlockFrameIndexBounds[i] << std::endl;
00424 }
00425
00426 if (debug) {
00427 for(uint32_t i = 0; i < Virtex2::eFarBlockTypeCount; i++) {
00428 for(uint32_t j = 0; j < mBitColumnIndexes[i].size(); j++)
00429 std::cout << "Bit Value at index: (" << i << ", " << j << ") : " << mBitColumnIndexes[i][j] << std::endl;
00430 for(uint32_t k = 0; k < mXdlColumnIndexes[i].size(); k++)
00431 std::cout << "Xdl Value at index: (" << i << ", " << k << ") : " << mXdlColumnIndexes[i][k] << std::endl;
00432 }
00433 }
00434 }
00435
00436
00437 void Virtex2::initializeFullFrameBlocks (void) {
00438 boost::shared_array<uint32_t> frameWords;
00439
00440 Virtex2::iterator p = begin();
00441 Virtex2::iterator e = end();
00442 while (p < e) {
00443 const VirtexPacket& packet = *p++;
00444 if (packet.isType2() && packet.isWrite())
00445 frameWords = packet.getWords();
00446 }
00447 uint32_t index = 0;
00448 for (uint32_t i = 0; i < VirtexFrameBlocks::eBlockTypeCount; i++) {
00449
00450 for (uint32_t j = 0; j < mBlockFrameIndexBounds[i]; j++) {
00451 mFrameBlocks.mBlock[i].push_back(VirtexFrameSet::FrameSharedPtr
00452 (new VirtexFrame(getFrameLength(), &frameWords[index])));
00453 index += getFrameLength();
00454 }
00455 }
00456 }
00457
00458
00459 VirtexFrameBlocks Virtex2::getBitstreamFrames (uint32_t blockCount, uint32_t bitCol) {
00460
00461
00462 int32_t bitColumnIndex [blockCount];
00463 int32_t bitColumnBound [blockCount];
00464
00465 for (uint32_t i = 0; i < blockCount; i++) {
00466
00467 bitColumnIndex[i] = mBitColumnIndexes[i][bitCol];
00468
00469 bitColumnBound[i] = mColumnDefs[mDeviceInfo.getColumnTypes()
00470 [mXdlIndexToBitIndex[bitCol]]][i];
00471 }
00472
00473 VirtexFrameBlocks frameBlocks;
00474 for (uint32_t i = 0; i < blockCount; i++) {
00475 int startIndex = bitColumnIndex[i];
00476 for (int j = 0; j < bitColumnBound[i]; j++)
00477 frameBlocks.mBlock[i].push_back(mFrameBlocks.mBlock[i][startIndex+j]);
00478 }
00479 return frameBlocks;
00480 }
00481
00482 VirtexFrameBlocks Virtex2::getXdlFrames (uint32_t blockCount, uint32_t xdlCol) {
00483
00484
00485 int32_t xdlColumnIndex [blockCount];
00486 int32_t xdlColumnBound [blockCount];
00487 for (uint32_t i = 0; i < blockCount; i++) {
00488
00489 xdlColumnIndex[i] = mXdlColumnIndexes[i][xdlCol];
00490
00491 xdlColumnBound[i] = mColumnDefs[mDeviceInfo.getColumnTypes()[xdlCol]][i];
00492 }
00493
00494 VirtexFrameBlocks frameBlocks;
00495 for (uint32_t i = 0; i < blockCount; i++) {
00496 int startIndex = xdlColumnIndex[i];
00497 for (int j = 0; j < xdlColumnBound[i]; j++)
00498 frameBlocks.mBlock[i].push_back(mFrameBlocks.mBlock[i][startIndex+j]);
00499 }
00500 return frameBlocks;
00501 }
00502
00503 }
00504 }