00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "torc/bitstream/Virtex.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* Virtex::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
00038 const char* Virtex::sOpcodeName[eOpcodeCount] = {
00039 "[UNKNOWN OP 0]", "READ", "WRITE", "[UNKNOWN OP 3]"
00040 };
00041
00042 const char* Virtex::sRegisterName[eRegisterCount] = {
00043 "CRC", "FAR", "FDRI", "FDRO", "CMD", "CTL", "MASK", "STAT", "LOUT", "COR", "[UNKNOWN REG 0]", "FLR"
00044 };
00045
00046 const char* Virtex::sCommandName[eCommandCount] = {
00047 "[UNKNOWN CMD 0]", "WCFG", "", "LFRM", "RCFG", "START", "RCAP", "RCRC", "AGHIGH", "SWITCH"
00048 };
00049
00050 #define VALUES (const char*[])
00051
00052
00053 const Bitstream::Subfield Virtex::sCOR[] = {
00054 {0x00000007, 0, "GSR_cycle", "GSR_CYCLE", 5,
00055
00056
00057 VALUES{"[UNDEFINED 0]", "2", "3", "4", "5", "6", "[UNDEFINED 6]", "[UNDEFINED 7]", 0}},
00058 {0x00000038, 3, "GWE_cycle", "GWE_CYCLE", 5,
00059
00060
00061 VALUES{"[UNDEFINED 0]", "2", "3", "4", "5", "6", "[UNDEFINED 6]", "[UNDEFINED 7]", 0}},
00062 {0x000001c0, 6, "GTS_cycle", "GTS_CYCLE", 4,
00063
00064
00065 VALUES{"[UNDEFINED 0]", "2", "3", "4", "5", "6", "[UNDEFINED 6]", "[UNDEFINED 7]", 0}},
00066 {0x00000e00, 9, "LCK_cycle", "LCK_CYCLE", 7,
00067
00068
00069 VALUES{"1", "2", "3", "4", "5", "6", "[UNDEFINED 6]", "NoWait", 0}},
00070 {0x00007000, 12, "DONE_cycle", "DONE_CYCLE", 3,
00071
00072
00073 VALUES{"[UNDEFINED 0]", "2", "3", "4", "5", "6", "[UNDEFINED 6]", "[UNDEFINED 7]", 0}},
00074 {0x00008000, 15, "", "SHUTDOWN", 0,
00075
00076 VALUES{"0", "1", 0}},
00077 {0x000f0000, 16, "", "LOCK_WAIT", 0,
00078
00079 VALUES{"1", "2", "3", "4", 0}},
00080 {0x00300000, 20, "StartupClk", "SSCLKSRC", 0,
00081
00082
00083 VALUES{"Cclk", "UserClk", "JtagClk", "JtagClk", 0}},
00084 {0x0fc00000, 22, "ConfigRate", "OSCFSEL", 2,
00085
00086
00087 VALUES{
00088 "[UNKNOWN 0]", "[UNKNOWN 1]", "[UNKNOWN 2]", "[UNKNOWN 3]",
00089 "[UNKNOWN 4]", "[UNKNOWN 5]", "[UNKNOWN 6]", "[UNKNOWN 7]",
00090 "[UNKNOWN 8]", "[UNKNOWN 9]", "[UNKNOWN 10]", "[UNKNOWN 11]",
00091 "[UNKNOWN 12]", "[UNKNOWN 13]", "[UNKNOWN 14]", "[UNKNOWN 15]",
00092 "[UNKNOWN 16]", "[UNKNOWN 17]", "[UNKNOWN 18]", "[UNKNOWN 19]",
00093 "[UNKNOWN 20]", "[UNKNOWN 21]", "[UNKNOWN 22]", "[UNKNOWN 23]",
00094 "[UNKNOWN 24]", "[UNKNOWN 25]", "[UNKNOWN 26]", "[UNKNOWN 27]",
00095 "[UNKNOWN 28]", "[UNKNOWN 29]", "[UNKNOWN 30]", "[UNKNOWN 31]",
00096 0}},
00097 {0x10000000, 28, "Capture", "SINGLE", 0,
00098
00099
00100 VALUES{"Continuous", "OneShot", 0}},
00101 {0x20000000, 29, "DriveDone", "DRIVE_DONE", 0,
00102
00103
00104 VALUES{"No", "Yes", 0}},
00105 {0x40000000, 30, "DonePipe", "DONE_PIPE", 0,
00106
00107
00108 VALUES{"No", "Yes", 0}},
00109 {0, 0, 0, 0, 0, 0}
00110 };
00111
00112
00113
00114 const Bitstream::Subfield Virtex::sSTAT[] = {
00115 {0x00000001, 0, "CRC_error", "CRC_ERROR", 0,
00116
00117
00118 VALUES{"No", "Yes", 0}},
00119 {0x00000002, 1, "TR_locked", "TR_LOCK", 0,
00120
00121
00122
00123 VALUES{"0", "1", 0}},
00124 {0x00000004, 2, "TL_locked", "TL_LOCK", 0,
00125
00126
00127
00128 VALUES{"0", "1", 0}},
00129 {0x00000008, 3, "BR_locked", "BR_LOCK", 0,
00130
00131
00132
00133 VALUES{"0", "1", 0}},
00134 {0x00000010, 4, "BL_locked", "BL_LOCK", 0,
00135
00136
00137
00138 VALUES{"No", "Yes", 0}},
00139 {0x00000020, 5, "IN_error", "IN_ERROR", 0,
00140
00141
00142 VALUES{"0", "1", 0}},
00143 {0x00000040, 6, "GTS_cfg", "GTS_CFG", 0,
00144
00145
00146 VALUES{"0", "1", 0}},
00147 {0x00000080, 7, "GWE_B", "GWE_B", 0,
00148
00149
00150 VALUES{"0", "1", 0}},
00151 {0x00000100, 8, "GSR_B", "GSR_B", 0,
00152
00153
00154 VALUES{"0", "1", 0}},
00155 {0x00000200, 9, "GHIGH_B", "GHIGH_B", 0,
00156
00157
00158 VALUES{"0", "1", 0}},
00159 {0x000001c0, 10, "MODE", "MODE", 0,
00160
00161
00162 VALUES{"MasterSerial", "SlaveSelectMap32", "[UNDEFINED 2]", "MasterSelectMap",
00163 "[UNDEFINED 3]", "JTAG", "SlaveSelectMap8", "[UNDEFINED 6]", "SlaveSerial", 0}},
00164 {0x00002000, 13, "INIT", "INIT", 0,
00165
00166
00167 VALUES{"Deasserted", "Asserted", 0}},
00168 {0x00004000, 14, "DONE", "DONE", 0,
00169
00170
00171 VALUES{"NotDone", "Done", 0}},
00172 {0, 0, 0, 0, 0, 0}
00173 };
00174
00175
00176 const Bitstream::Subfield Virtex::sCTL[] = {
00177 {0x00000001, 0, "GTS_USER_B", "GTS_USER_B", 0,
00178
00179
00180 VALUES{"IoDisabled", "IoActive", 0}},
00181 {0x00000040, 6, "Persist", "PERSIST", 0,
00182
00183
00184 VALUES{"No", "Yes", 0}},
00185 {0x00000180, 7, "Security", "SBITS", 0,
00186
00187
00188
00189 VALUES{"None", "Level1", "Level2", "Level2", 0}},
00190 {0, 0, 0, 0, 0, 0}
00191 };
00192
00193
00194 const Bitstream::Subfield Virtex::sMASK[] = {
00195 {0x00000001, 0, "GTS_USER_B", "GTS_USER_B", 0, VALUES{"Protected", "Writable", 0}},
00196 {0x00000040, 6, "Persist", "PERSIST", 0, VALUES{"Protected", "Writable", 0}},
00197 {0x00000180, 7, "Security", "SBITS", 0,
00198 VALUES{"Protected", "[UNKNOWN 1]", "[UNKNOWN 2]", "Writable", 0}},
00199 {0, 0, 0, 0, 0, 0}
00200 };
00201
00202
00203 uint32_t Virtex::makeSubfield(ERegister inRegister, const std::string& inSubfield,
00204 const std::string& inSetting) {
00205 const Subfield* subfields;
00206 switch(inRegister) {
00207 case eRegisterCOR: subfields = sCOR; break;
00208 case eRegisterSTAT: subfields = sSTAT; break;
00209 case eRegisterCTL: subfields = sCTL; break;
00210 case eRegisterMASK: subfields = sMASK; break;
00211 default: return 0;
00212 }
00213 for(uint32_t field = 0; subfields[field].mMask != 0; field++) {
00214 const Subfield& subfield = subfields[field];
00215 if(inSubfield != subfield.mBitgenName && inSubfield != subfield.mConfigGuideName)
00216 continue;
00217 const char** ptr = subfield.mValues;
00218 for(uint32_t i = 0; *ptr != 0; i++, ptr++) {
00219 if(inSetting == *ptr) return (i << subfield.mShift) & subfield.mMask;
00220 }
00221 }
00222 return 0;
00223 }
00224
00225
00226
00227 #ifndef GENERATE_STATIC_DEVICE_INFO
00228
00229 extern DeviceInfo xcv50;
00230 extern DeviceInfo xcv100;
00231 extern DeviceInfo xcv150;
00232 extern DeviceInfo xcv200;
00233 extern DeviceInfo xcv300;
00234 extern DeviceInfo xcv400;
00235 extern DeviceInfo xcv600;
00236 extern DeviceInfo xcv800;
00237 extern DeviceInfo xcv1000;
00238
00239 void Virtex::initializeDeviceInfo(const std::string& inDeviceName) {
00240 using namespace torc::common;
00241 switch(mDevice) {
00242 case eXCV50: setDeviceInfo(xcv50); break;
00243 case eXCV100: setDeviceInfo(xcv100); break;
00244 case eXCV150: setDeviceInfo(xcv150); break;
00245 case eXCV200: setDeviceInfo(xcv200); break;
00246 case eXCV300: setDeviceInfo(xcv300); break;
00247 case eXCV400: setDeviceInfo(xcv400); break;
00248 case eXCV600: setDeviceInfo(xcv600); break;
00249 case eXCV800: setDeviceInfo(xcv800); break;
00250 case eXCV1000: setDeviceInfo(xcv1000); break;
00251 default: break;
00252 }
00253
00254 }
00255
00256 #else
00257
00258 void Virtex::initializeDeviceInfo(const std::string& inDeviceName) {
00259
00260 typedef torc::architecture::xilinx::TileCount TileCount;
00261 typedef torc::architecture::xilinx::TileRow TileRow;
00262 typedef torc::architecture::xilinx::TileCol TileCol;
00263 typedef torc::architecture::xilinx::TileTypeIndex TileTypeIndex;
00264 typedef torc::architecture::xilinx::TileTypeCount TileTypeCount;
00265
00266
00267 torc::architecture::DDB ddb(inDeviceName);
00268 const torc::architecture::Tiles& tiles = ddb.getTiles();
00269 uint32_t tileCount = tiles.getTileCount();
00270 uint16_t rowCount = tiles.getRowCount();
00271 uint16_t colCount = tiles.getColCount();
00272 ColumnTypeVector columnTypes;
00273
00274
00275 typedef std::map<TileTypeIndex, std::string> TileTypeIndexToName;
00276 typedef std::map<std::string, TileTypeIndex> TileTypeNameToIndex;
00277 TileTypeIndexToName tileTypeIndexToName;
00278 TileTypeNameToIndex tileTypeNameToIndex;
00279 TileTypeCount tileTypeCount = tiles.getTileTypeCount();
00280 for(TileTypeIndex tileTypeIndex(0); tileTypeIndex < tileTypeCount; tileTypeIndex++) {
00281 const std::string tileTypeName = tiles.getTileTypeName(tileTypeIndex);
00282 tileTypeIndexToName[tileTypeIndex] = tileTypeName;
00283 tileTypeNameToIndex[tileTypeName] = tileTypeIndex;
00284 TileTypeNameToColumnType::iterator ttwp = mTileTypeNameToColumnType.find(tileTypeName);
00285 TileTypeNameToColumnType::iterator ttwe = mTileTypeNameToColumnType.end();
00286 if(ttwp != ttwe) mTileTypeIndexToColumnType[tileTypeIndex] = EColumnType(ttwp->second);
00287 }
00288
00289
00290 columnTypes.resize(colCount);
00291 uint32_t frameCount = 0;
00292 for(uint32_t blockType = 0; blockType < Virtex::eFarBlockTypeCount; blockType++) {
00293 for(TileCol col; col < colCount; col++) {
00294 bool found = false;
00295 columnTypes[col] = eColumnTypeEmpty;
00296 TileTypeIndexToColumnType::iterator ttwe = mTileTypeIndexToColumnType.end();
00297 TileTypeIndexToColumnType::iterator ttwp = ttwe;
00298 for(TileRow row; row < rowCount; row++) {
00299
00300 const torc::architecture::TileInfo& tileInfo
00301 = tiles.getTileInfo(tiles.getTileIndex(row, col));
00302 TileTypeIndex tileTypeIndex = tileInfo.getTypeIndex();
00303
00304 ttwp = mTileTypeIndexToColumnType.find(tileTypeIndex);
00305 if(ttwp != ttwe) {
00306 uint32_t width = mColumnDefs[ttwp->second][blockType];
00307 frameCount += width;
00308
00309
00310 columnTypes[col] = static_cast<EColumnType>(ttwp->second);
00311 found = true;
00312 break;
00313 }
00314 }
00315 (void) found;
00316 }
00317
00318 if(blockType == 2) break;
00319 }
00320
00321 boost::filesystem::path workingPath = torc::common::DirectoryTree::getWorkingPath();
00322 boost::filesystem::path generatedMap = workingPath / (inDeviceName + ".map.csv");
00323 std::fstream tilemapStream(generatedMap.string().c_str(), std::ios::out);
00324 for(TileRow row; row < rowCount; row++) {
00325 for(TileCol col; col < colCount; col++) {
00326 const torc::architecture::TileInfo& tileInfo
00327 = tiles.getTileInfo(tiles.getTileIndex(row, col));
00328 TileTypeIndex tileTypeIndex = tileInfo.getTypeIndex();
00329 tilemapStream << tiles.getTileTypeName(tileTypeIndex);
00330 if(col + 1 < colCount) tilemapStream << ",";
00331 }
00332 tilemapStream << std::endl;
00333 }
00334 tilemapStream.close();
00335
00336
00337 setDeviceInfo(DeviceInfo(tileCount, rowCount, colCount, columnTypes));
00338
00339 }
00340
00341 #endif
00342
00343 void Virtex::initializeFrameMaps(void) {
00344
00345 bool debug = 0;
00346 int center = 0;
00347 int frameIndex = 0;
00348 int frameCount = 0;
00349 int farMajor = 0;
00350 int width = 0;
00351 ColumnIndex col;
00352 for(uint32_t i = 0; i < Virtex::eFarBlockTypeCount; i++) {
00353 farMajor = 0;
00354 EFarBlockType blockType = Virtex::EFarBlockType(i);
00355 mFrameIndexBounds = 0;
00356
00357 uint32_t bitIndex = 0;
00358 uint32_t xdlIndex = 0;
00359 mBitColumnIndexes[i].push_back(bitIndex);
00360 mXdlColumnIndexes[i].push_back(xdlIndex);
00361 uint16_t finalColumn = mDeviceInfo.getColCount()-1;
00362 uint32_t xdlColumnCount = 0;
00363 uint32_t bitColumnCount = 0;
00364
00365 center = mDeviceInfo.getColCount() / 2;
00366 col = center;
00367 prepareFrames(col, frameCount, frameIndex, blockType, farMajor, width);
00368 int numBrams = 2;
00369 int numIobs = 2;
00370 int numClocks = 1;
00371 int numClbs = mDeviceInfo.getColCount() - numClocks - numBrams - numIobs;
00372
00373 for (int j = 1; j <= numClbs / 2; j++) {
00374 for (int k = -1; k < 2; k += 2) {
00375 col = center - (j * k);
00376 prepareFrames(col, frameCount, frameIndex, blockType, farMajor, width);
00377
00378 if(mDeviceInfo.getColumnTypes()[col] != Virtex::eColumnTypeEmpty) {
00379 mXdlIndexToBitIndex[bitColumnCount] = xdlColumnCount;
00380 bitColumnCount++;
00381 bitIndex += width;
00382 mBitColumnIndexes[i].push_back(bitIndex);
00383 if(col == finalColumn) {
00384 bitIndex += mColumnDefs[mDeviceInfo.getColumnTypes()[col]][i];
00385 mBitColumnIndexes[i].push_back(bitIndex);
00386 }
00387 }
00388
00389
00390 xdlIndex += width;
00391 mXdlColumnIndexes[i].push_back(xdlIndex);
00392 xdlColumnCount++;
00393 if(col == finalColumn)
00394 {
00395 xdlIndex += mColumnDefs[mDeviceInfo.getColumnTypes()[col]][i];
00396 mXdlColumnIndexes[i].push_back(xdlIndex);
00397 }
00398 }
00399 }
00400
00401 for (int j = center; j < (center + 1); j++) {
00402 for (int k = -1; k < 2; k += 2) {
00403 col = center - (j * k);
00404 prepareFrames(col, frameCount, frameIndex, blockType, farMajor, width);
00405
00406 if(mDeviceInfo.getColumnTypes()[col] != Virtex::eColumnTypeEmpty) {
00407 mXdlIndexToBitIndex[bitColumnCount] = xdlColumnCount;
00408 bitColumnCount++;
00409 bitIndex += width;
00410 mBitColumnIndexes[i].push_back(bitIndex);
00411 if(col == finalColumn) {
00412 bitIndex += mColumnDefs[mDeviceInfo.getColumnTypes()[col]][i];
00413 mBitColumnIndexes[i].push_back(bitIndex);
00414 }
00415 }
00416
00417
00418 xdlIndex += width;
00419 mXdlColumnIndexes[i].push_back(xdlIndex);
00420 xdlColumnCount++;
00421 if(col == finalColumn)
00422 {
00423 xdlIndex += mColumnDefs[mDeviceInfo.getColumnTypes()[col]][i];
00424 mXdlColumnIndexes[i].push_back(xdlIndex);
00425 }
00426 }
00427 }
00428
00429 for (int j = (center - 1); j < center; j++) {
00430 for (int k = -1; k < 2; k += 2) {
00431 col = center - (j * k);
00432 prepareFrames(col, frameCount, frameIndex, blockType, farMajor, width);
00433
00434 if(mDeviceInfo.getColumnTypes()[col] != Virtex::eColumnTypeEmpty) {
00435 mXdlIndexToBitIndex[bitColumnCount] = xdlColumnCount;
00436 bitColumnCount++;
00437 bitIndex += width;
00438 mBitColumnIndexes[i].push_back(bitIndex);
00439 if(col == finalColumn) {
00440 bitIndex += mColumnDefs[mDeviceInfo.getColumnTypes()[col]][i];
00441 mBitColumnIndexes[i].push_back(bitIndex);
00442 }
00443 }
00444
00445
00446 xdlIndex += width;
00447 mXdlColumnIndexes[i].push_back(xdlIndex);
00448 xdlColumnCount++;
00449 if(col == finalColumn)
00450 {
00451 xdlIndex += mColumnDefs[mDeviceInfo.getColumnTypes()[col]][i];
00452 mXdlColumnIndexes[i].push_back(xdlIndex);
00453 }
00454 }
00455 }
00456
00457 mBlockFrameIndexBounds[i] = mFrameIndexBounds;
00458 if (debug) std::cout << "***Block frame index bounds: " << mBlockFrameIndexBounds[i] << std::endl;
00459 }
00460
00461 if (debug) {
00462 for(uint32_t i = 0; i < Virtex::eFarBlockTypeCount; i++) {
00463 for(uint32_t j = 0; j < mBitColumnIndexes[i].size(); j++)
00464 std::cout << "Bit Value at index: (" << i << ", " << j << ") : " << mBitColumnIndexes[i][j] << std::endl;
00465 for(uint32_t k = 0; k < mXdlColumnIndexes[i].size(); k++)
00466 std::cout << "Xdl Value at index: (" << i << ", " << k << ") : " << mXdlColumnIndexes[i][k] << std::endl;
00467 }
00468 }
00469 }
00470
00471 void Virtex::prepareFrames(ColumnIndex &inCol, int &inFrameCount, int &inFrameIndex, EFarBlockType &inBlockType, int &inFarMajor, int &inWidth) {
00472 inWidth = mColumnDefs[mDeviceInfo.getColumnTypes()[inCol]][inBlockType];
00473 if (inWidth == 0) return;
00474 inFrameCount += inWidth;
00475 for(int farMinor = 0; farMinor < inWidth; farMinor++) {
00476 Virtex::FrameAddress far(inBlockType, inFarMajor, farMinor);
00477
00478 mFrameIndexToAddress[inFrameIndex] = far;
00479 mFrameAddressToIndex[far] = inFrameIndex;
00480 inFrameIndex++;
00481 mFrameIndexBounds++;
00482 }
00483 if (inWidth > 0) inFarMajor++;
00484 return;
00485 }
00486
00487
00488 void Virtex::initializeFullFrameBlocks (void) {
00489 boost::shared_array<uint32_t> frameWords;
00490
00491 Virtex::iterator p = begin();
00492 Virtex::iterator e = end();
00493 while (p < e) {
00494 const VirtexPacket& packet = *p++;
00495 if (packet.isType2() && packet.isWrite())
00496 frameWords = packet.getWords();
00497 }
00498 uint32_t index = 0;
00499 for (uint32_t i = 0; i < VirtexFrameBlocks::eBlockTypeCount; i++) {
00500
00501 for (uint32_t j = 0; j < mBlockFrameIndexBounds[i]; j++) {
00502 mFrameBlocks.mBlock[i].push_back(VirtexFrameSet::FrameSharedPtr
00503 (new VirtexFrame(getFrameLength(), &frameWords[index])));
00504 index += getFrameLength();
00505 }
00506 }
00507 }
00508
00509
00510 VirtexFrameBlocks Virtex::getBitstreamFrames (uint32_t blockCount, uint32_t bitCol) {
00511
00512
00513 int32_t bitColumnIndex [blockCount];
00514 int32_t bitColumnBound [blockCount];
00515
00516 for (uint32_t i = 0; i < blockCount; i++) {
00517
00518 bitColumnIndex[i] = mBitColumnIndexes[i][bitCol];
00519
00520 bitColumnBound[i] = mColumnDefs[mDeviceInfo.getColumnTypes()
00521 [mXdlIndexToBitIndex[bitCol]]][i];
00522 }
00523
00524 VirtexFrameBlocks frameBlocks;
00525 for (uint32_t i = 0; i < blockCount; i++) {
00526 int startIndex = bitColumnIndex[i];
00527 for (int j = 0; j < bitColumnBound[i]; j++)
00528 frameBlocks.mBlock[i].push_back(mFrameBlocks.mBlock[i][startIndex+j]);
00529 }
00530 return frameBlocks;
00531 }
00532
00533 VirtexFrameBlocks Virtex::getXdlFrames (uint32_t blockCount, uint32_t xdlCol) {
00534
00535
00536 int32_t xdlColumnIndex [blockCount];
00537 int32_t xdlColumnBound [blockCount];
00538 for (uint32_t i = 0; i < blockCount; i++) {
00539
00540 xdlColumnIndex[i] = mXdlColumnIndexes[i][xdlCol];
00541
00542 xdlColumnBound[i] = mColumnDefs[mDeviceInfo.getColumnTypes()[xdlCol]][i];
00543 }
00544
00545 VirtexFrameBlocks frameBlocks;
00546 for (uint32_t i = 0; i < blockCount; i++) {
00547 int startIndex = xdlColumnIndex[i];
00548 for (int j = 0; j < xdlColumnBound[i]; j++)
00549 frameBlocks.mBlock[i].push_back(mFrameBlocks.mBlock[i][startIndex+j]);
00550 }
00551 return frameBlocks;
00552 }
00553 }
00554 }