00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef TORC_BITSTREAM_SPARTAN6PACKET_HPP
00020 #define TORC_BITSTREAM_SPARTAN6PACKET_HPP
00021
00022 #include "torc/common/Endian.hpp"
00023 #include <boost/smart_ptr.hpp>
00024 #include <vector>
00025 #include <istream>
00026 #include <iostream>
00027 #include <iomanip>
00028
00029 namespace torc {
00030 namespace bitstream {
00031
00032 namespace bitstream { class Spartan6PacketUnitTest; }
00033
00034
00035 class Spartan6PacketConstants {
00036 public:
00037
00038
00039
00040 enum EPacketType { ePacketType1 = 1, ePacketType2, ePacketTypeCount = 8 };
00041
00042
00043
00044 enum EOpcode { eOpcodeNOP = 0, eOpcodeRead, eOpcodeWrite, eOpcodeReserved, eOpcodeCount };
00045
00046
00047
00048
00049 enum EPacket {
00050
00051 ePacketMaskType = 0xe000, ePacketShiftType = 13,
00052 ePacketMaskOpcode = 0x1800, ePacketShiftOpcode = 11,
00053 ePacketMaskTypeAddress = 0x07e0, ePacketShiftTypeAddress = 5,
00054
00055 ePacketMaskType1Count = 0x001f, ePacketShiftType1Count = 0,
00056
00057 ePacketMaskType2Count0 = 0xffff, ePacketShiftType2Count0 = 0,
00058 ePacketMaskType2Count1 = 0xffff, ePacketShiftType2Count1 = 0
00059 };
00060
00061
00062
00063 enum ESynchronization {
00064 eSynchronizationDummy = 0xffff,
00065 eSynchronizationSync0 = 0xaa99,
00066 eSynchronizationSync1 = 0x5566,
00067 eSynchronizationBusWidthSync0 = 0x0000,
00068 eSynchronizationBusWidthSync1 = 0x00bb,
00069 eSynchronizationBusWidthDetect0 = 0x1122,
00070 eSynchronizationBusWidthDetect1 = 0x0044
00071 };
00072 };
00073
00074
00075 class Spartan6Packet : public Spartan6PacketConstants {
00076 friend class torc::bitstream::bitstream::Spartan6PacketUnitTest;
00077 protected:
00078
00079
00080 typedef boost::uint16_t uint16_t;
00081 typedef boost::uint32_t uint32_t;
00082
00083 typedef boost::shared_array<uint16_t> WordSharedArray;
00084
00085 void initialize(void) {
00086 mType = EPacketType((mHeader & ePacketMaskType) >> ePacketShiftType);
00087 mOpcode = EOpcode((mHeader & ePacketMaskOpcode) >> ePacketShiftOpcode);
00088 mAddress = (mHeader & ePacketMaskTypeAddress) >> ePacketShiftTypeAddress;
00089 }
00090 public:
00091
00092
00093 uint16_t mHeader;
00094 uint32_t mCount;
00095 uint16_t mWord;
00096 WordSharedArray mWords;
00097 EPacketType mType;
00098 EOpcode mOpcode;
00099 int mAddress;
00100
00101 static const char* sPacketTypeName[ePacketTypeCount];
00102
00103 static const char* sOpcodeName[eOpcodeCount];
00104 public:
00105
00106
00107 Spartan6Packet(void) : mHeader(0), mCount(0), mWord(0), mWords(0), mType(EPacketType(0)),
00108 mOpcode(eOpcodeNOP), mAddress(0) {}
00109
00110 Spartan6Packet(uint16_t inHeader, uint32_t inCount, uint16_t inWord,
00111 uint16_t* inWords) : mHeader(inHeader), mCount(inCount), mWord(inWord),
00112 mWords(WordSharedArray(inWords)), mType(EPacketType(0)), mOpcode(eOpcodeNOP), mAddress(0) {
00113 initialize();
00114 }
00115
00116 Spartan6Packet(uint16_t inHeader, uint16_t inWord) : mHeader(inHeader), mCount(1),
00117 mWord(inWord), mWords(0), mType(EPacketType(0)), mOpcode(eOpcodeNOP), mAddress(0) {
00118 initialize();
00119 }
00120
00121 Spartan6Packet(uint16_t inHeader) : mHeader(inHeader), mCount(0), mWord(0), mWords(0),
00122 mType(EPacketType(0)), mOpcode(eOpcodeNOP), mAddress(0) {
00123 initialize();
00124 }
00125
00126 Spartan6Packet(const Spartan6Packet& rhs) : mHeader(rhs.mHeader), mCount(rhs.mCount),
00127 mWord(rhs.mWord), mWords(rhs.mWords), mType(EPacketType(0)), mOpcode(eOpcodeNOP), mAddress(0) {
00128 initialize();
00129 }
00130
00131
00132 static Spartan6Packet read(std::istream& inStream) {
00133 uint32_t count = 0;
00134 uint16_t count1 = 0;
00135 uint16_t count2 = 0;
00136 uint16_t header = 0;
00137 uint16_t word = 0;
00138 uint16_t* raw_words = 0;
00139
00140 inStream.read((char*) &header, sizeof(header));
00141 header = ntohs(header);
00142
00143 if(header == eSynchronizationDummy || header == eSynchronizationSync0
00144 || header == eSynchronizationSync1 || header == eSynchronizationBusWidthSync0
00145 || header == eSynchronizationBusWidthSync1 || header == eSynchronizationBusWidthDetect0
00146 || header == eSynchronizationBusWidthDetect1) {
00147 return Spartan6Packet(header, 0, 0, 0);
00148 }
00149
00150 EPacketType type = EPacketType((header & ePacketMaskType) >> ePacketShiftType);
00151 switch(type) {
00152 case ePacketType1:
00153 count = (header & ePacketMaskType1Count) >> ePacketShiftType1Count;
00154 break;
00155 case ePacketType2:
00156 inStream.read((char*) &count2, sizeof(count2));
00157 inStream.read((char*) &count1, sizeof(count1));
00158 count2 = ntohs(count2);
00159 count1 = ntohs(count1);
00160 count = (count2 << 16) | count1;
00161 break;
00162 default:
00163
00164 count = 0;
00165 count1 = 0;
00166 count2 = 0;
00167 break;
00168 }
00169
00170
00171 if (type == ePacketType1) {
00172 if(count == 1) {
00173 inStream.read((char*) &word, sizeof(word));
00174 word = ntohs(word);
00175 } else if(count > 1) {
00176 raw_words = new uint16_t[count];
00177 inStream.read((char*) raw_words, count << 1);
00178 uint16_t* wordPtr = raw_words;
00179 for(uint32_t i = 0; i < count; i++, wordPtr++) *wordPtr = ntohs(*wordPtr);
00180 }
00181 }
00182
00183 else if (type == ePacketType2) {
00184 if(count == 1) {
00185 inStream.read((char*) &word, sizeof(word));
00186 word = ntohs(word);
00187 } else if(count > 1) {
00188 raw_words = new uint16_t[count];
00189 inStream.read((char*) raw_words, count << 1);
00190 uint16_t* wordPtr = raw_words;
00191 for(uint32_t i = 0; i < count; i++, wordPtr++) *wordPtr = ntohs(*wordPtr);
00192 }
00193 }
00194
00195
00196 return Spartan6Packet(header, count, word, raw_words);
00197 }
00198
00199 void write(std::ostream& inStream) const {
00200 uint32_t size = getWordSize();
00201 for(uint32_t i = 0; i < size; i++) {
00202 uint16_t word = htons(operator[](i));
00203 inStream.write((char*) &word, sizeof(word));
00204
00205
00206 if(i == 0 && isType2() && !isSyncWord1()) {
00207 word = htons(mCount >> 16);
00208 inStream.write((char*) &word, sizeof(word));
00209 word = htons(mCount & 0x0000ffff);
00210 inStream.write((char*) &word, sizeof(word));
00211
00212
00213 size -= 2;
00214 }
00215 }
00216 }
00217
00218
00219
00220
00221
00222 static Spartan6Packet makeNullType2Write(uint16_t inAddress) {
00223 return Spartan6Packet(makeHeader(ePacketType2, eOpcodeWrite, inAddress, 0), 0, 0, 0);
00224 }
00225
00226 static Spartan6Packet makeType1Write(uint16_t inAddress, uint16_t inWord) {
00227 return Spartan6Packet(makeHeader(ePacketType1, eOpcodeWrite, inAddress, 1), 1, inWord, 0);
00228 }
00229
00230 static Spartan6Packet makeType1Write32(uint16_t inAddress, uint32_t inWord) {
00231
00232 uint16_t* words = new uint16_t[2];
00233 words[0] = inWord >> 16;
00234 words[1] = inWord & 0x0000ffff;
00235 return Spartan6Packet(makeHeader(ePacketType1, eOpcodeWrite, inAddress, 2), 2, 0, words);
00236 }
00237
00238 static Spartan6Packet makeType1Write(uint16_t inAddress, uint16_t inWord1, uint16_t inWord2) {
00239
00240 uint16_t* words = new uint16_t[2];
00241 words[0] = inWord1;
00242 words[1] = inWord2;
00243 return Spartan6Packet(makeHeader(ePacketType1, eOpcodeWrite, inAddress, 2), 2, 0, words);
00244 }
00245
00246 static Spartan6Packet makeType1Write(uint32_t inCount, uint16_t inAddress, uint16_t* inWords) {
00247 return Spartan6Packet(makeHeader(ePacketType1, eOpcodeWrite, inAddress, inCount), inCount, 0, inWords);
00248 }
00249
00250 static Spartan6Packet makeType2Write(uint32_t inCount, uint16_t inAddress, uint16_t* inWords) {
00251 return Spartan6Packet(makeHeader(ePacketType2, eOpcodeWrite, inAddress, 0), inCount, 0, inWords);
00252 }
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 static uint16_t makeHeader(EPacketType inType, EOpcode inOpcode, uint16_t inAddress,
00263 uint32_t inCount) {
00264
00265 if(inType == ePacketType1) return
00266 ((inType << ePacketShiftType) & ePacketMaskType) |
00267 ((inOpcode << ePacketShiftOpcode) & ePacketMaskOpcode) |
00268 ((inAddress << ePacketShiftTypeAddress) & ePacketMaskTypeAddress) |
00269 ((inCount << ePacketShiftType1Count) & ePacketMaskType1Count);
00270
00271 else if(inType == ePacketType2) return
00272 ((inType << ePacketShiftType) & ePacketMaskType) |
00273 ((inOpcode << ePacketShiftOpcode) & ePacketMaskOpcode) |
00274 ((inAddress << ePacketShiftTypeAddress) & ePacketMaskTypeAddress);
00275
00276 else
00277
00278 return 0;
00279 }
00280
00281 uint16_t operator[] (size_t inIndex) const {
00282 if(inIndex == 0) return mHeader;
00283 if(inIndex == 1 && mCount == 1) return mWord;
00284 if(inIndex <= mCount) return mWords[inIndex-1];
00285 return 0;
00286 }
00287
00288 EPacketType getType(void) const { return mType; }
00289 EOpcode getOpcode(void) const { return mOpcode; }
00290 int getAddress(void) const { return mAddress; }
00291 uint16_t getHeader(void) const { return mHeader; }
00292
00293 uint32_t getWordCount(void) const { return mCount; }
00294
00295
00296 uint32_t getWordSize(void) const {
00297 if(isType2() && !isSyncWord1()) return mCount + 1 + 2;
00298 return mCount + 1;
00299 }
00300
00301 const WordSharedArray getWords(void) const { return mWords; }
00302
00303 bool isType1(void) const { return mType == ePacketType1; }
00304 bool isType2(void) const { return mType == ePacketType2; }
00305 bool isNop(void) const { return mOpcode == eOpcodeNOP; }
00306 bool isReserved(void) const { return mOpcode == eOpcodeReserved; }
00307 bool isRead(void) const { return mOpcode == eOpcodeRead; }
00308 bool isWrite(void) const { return mOpcode == eOpcodeWrite; }
00309 bool isDummyWord(void) const { return mHeader == eSynchronizationDummy; }
00310 bool isSyncWord0(void) const { return mHeader == eSynchronizationSync0; }
00311 bool isSyncWord1(void) const { return mHeader == eSynchronizationSync1; }
00312 bool isBusWidthSyncWord0(void) const { return mHeader == eSynchronizationBusWidthSync0; }
00313 bool isBusWidthSyncWord1(void) const { return mHeader == eSynchronizationBusWidthSync1; }
00314 bool isBusWidthDetectWord0(void) const { return mHeader == eSynchronizationBusWidthDetect0; }
00315 bool isBusWidthDetectWord1(void) const { return mHeader == eSynchronizationBusWidthDetect1; }
00316 };
00317
00318
00319 typedef std::vector<Spartan6Packet> Spartan6PacketVector;
00320
00321 }
00322 }
00323
00324 #endif // TORC_BITSTREAM_SPARTAN6PACKET_HPP