00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef TORC_BITSTREAM_VIRTEXPACKET_HPP
00020 #define TORC_BITSTREAM_VIRTEXPACKET_HPP
00021
00022 #include "torc/common/Endian.hpp"
00023 #include <boost/smart_ptr.hpp>
00024 #include <vector>
00025 #include <istream>
00026
00027 #include <iostream>
00028
00029 namespace torc {
00030 namespace bitstream {
00031
00032 namespace bitstream { class VirtexPacketUnitTest; }
00033
00034
00035 class VirtexPacketConstants {
00036 public:
00037
00038
00039
00040
00041 enum EPacketType { ePacketType1 = 1, ePacketType2, ePacketTypeCount = 8 };
00042
00043
00044
00045 enum EOpcode { eOpcodeNOP = 0, eOpcodeRead, eOpcodeWrite, eOpcodeReserved, eOpcodeCount };
00046
00047
00048
00049
00050
00051 enum EPacket {
00052
00053 ePacketMaskType = 0xe0000000, ePacketShiftType = 29,
00054 ePacketMaskOpcode = 0x18000000, ePacketShiftOpcode = 27,
00055
00056 ePacketMaskType1Address = 0x07ffe000, ePacketShiftType1Address = 13,
00057 ePacketMaskType1Reserved = 0x00001800, ePacketShiftType1Reserved = 11,
00058 ePacketMaskType1Count = 0x000007ff, ePacketShiftType1Count = 0,
00059
00060 ePacketMaskType2Count = 0x07ffffff, ePacketShiftType2Count = 0
00061 };
00062
00063
00064
00065
00066
00067 enum ESynchronization {
00068 eSynchronizationDummy = 0xffffffff,
00069 eSynchronizationSync = 0xaa995566,
00070 eSynchronizationBusWidthSync = 0x000000bb,
00071 eSynchronizationBusWidthDetect = 0x11220044
00072 };
00073 };
00074
00075
00076 class VirtexPacket : public VirtexPacketConstants {
00077 friend class torc::bitstream::bitstream::VirtexPacketUnitTest;
00078 protected:
00079
00080
00081 typedef boost::uint32_t uint32_t;
00082
00083 typedef boost::shared_array<uint32_t> WordSharedArray;
00084
00085 void initialize(void) {
00086 mType = EPacketType((mHeader & ePacketMaskType) >> ePacketShiftType);
00087 mOpcode = EOpcode((mHeader & ePacketMaskOpcode) >> ePacketShiftOpcode);
00088 if(mType == ePacketType1)
00089 mAddress = (mHeader & ePacketMaskType1Address) >> ePacketShiftType1Address;
00090 }
00091 public:
00092
00093
00094 uint32_t mHeader;
00095 uint32_t mCount;
00096 uint32_t mWord;
00097 WordSharedArray mWords;
00098 EPacketType mType;
00099 EOpcode mOpcode;
00100 int mAddress;
00101
00102 static const char* sPacketTypeName[ePacketTypeCount];
00103
00104 static const char* sOpcodeName[eOpcodeCount];
00105 public:
00106
00107
00108 VirtexPacket(void) : mHeader(0), mCount(0), mWord(0), mWords(0), mType(EPacketType(0)),
00109 mOpcode(eOpcodeNOP), mAddress(0) {}
00110
00111 VirtexPacket(uint32_t inHeader, uint32_t inCount, uint32_t inWord, uint32_t* inWords)
00112 : mHeader(inHeader), mCount(inCount), mWord(inWord), mWords(WordSharedArray(inWords)),
00113 mType(EPacketType(0)), mOpcode(eOpcodeNOP), mAddress(0) {
00114 initialize();
00115 }
00116
00117 VirtexPacket(uint32_t inHeader, uint32_t inWord) : mHeader(inHeader), mCount(1),
00118 mWord(inWord), mWords(0), mType(EPacketType(0)), mOpcode(eOpcodeNOP), mAddress(0) {
00119 initialize();
00120 }
00121
00122 VirtexPacket(uint32_t inHeader) : mHeader(inHeader), mCount(0), mWord(0), mWords(0),
00123 mType(EPacketType(0)), mOpcode(eOpcodeNOP), mAddress(0) {
00124 initialize();
00125 }
00126
00127 VirtexPacket(const VirtexPacket& rhs) : mHeader(rhs.mHeader), mCount(rhs.mCount),
00128 mWord(rhs.mWord), mWords(rhs.mWords), mType(EPacketType(0)), mOpcode(eOpcodeNOP),
00129 mAddress(0) {
00130 initialize();
00131 }
00132
00133
00134 static VirtexPacket read(std::istream& inStream) {
00135 uint32_t count = 0;
00136 uint32_t header = 0;
00137 uint32_t word = 0;
00138 uint32_t* raw_words = 0;
00139
00140 inStream.read((char*) &header, sizeof(header));
00141 header = ntohl(header);
00142
00143 if(header == eSynchronizationDummy || header == eSynchronizationSync
00144 || header == eSynchronizationBusWidthSync
00145 || header == eSynchronizationBusWidthDetect) {
00146 return VirtexPacket(header, 0, 0, 0);
00147 }
00148
00149 EPacketType type = EPacketType((header & ePacketMaskType) >> ePacketShiftType);
00150 switch(type) {
00151 case ePacketType1:
00152 count = (header & ePacketMaskType1Count) >> ePacketShiftType1Count;
00153 break;
00154 case ePacketType2:
00155 count = (header & ePacketMaskType2Count) >> ePacketShiftType2Count;
00156 break;
00157 default:
00158
00159 count = 0;
00160 break;
00161 }
00162
00163 if(count == 1) {
00164 inStream.read((char*) &word, sizeof(word));
00165 word = ntohl(word);
00166 } else if(count > 1) {
00167 raw_words = new uint32_t[count];
00168 inStream.read((char*) raw_words, count << 2);
00169 uint32_t* wordPtr = raw_words;
00170 for(uint32_t i = 0; i < count; i++, wordPtr++) *wordPtr = ntohl(*wordPtr);
00171 }
00172
00173 return VirtexPacket(header, count, word, raw_words);
00174 }
00175
00176 void write(std::ostream& inStream) const {
00177 uint32_t size = getWordSize();
00178 for(uint32_t i = 0; i < size; i++) {
00179 uint32_t word = htonl(operator[](i));
00180 inStream.write((char*) &word, sizeof(word));
00181 }
00182 }
00183
00184
00185
00186
00187
00188 static VirtexPacket makeNullType1Write(uint32_t inAddress) {
00189 return VirtexPacket(makeHeader(ePacketType1, eOpcodeWrite, inAddress, 0), 0, 0, 0);
00190 }
00191
00192 static VirtexPacket makeType1Write(uint32_t inAddress, uint32_t inWord) {
00193 return VirtexPacket(makeHeader(ePacketType1, eOpcodeWrite, inAddress, 1), 1, inWord, 0);
00194 }
00195
00196 static VirtexPacket makeType2Write(uint32_t inCount, uint32_t* inWords) {
00197 return VirtexPacket(makeHeader(ePacketType2, eOpcodeWrite, 0, inCount), inCount, 0,
00198 inWords);
00199 }
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 static uint32_t makeHeader(EPacketType inType, EOpcode inOpcode, uint32_t inAddress,
00210 uint32_t inCount) {
00211
00212 if(inType == ePacketType1) return
00213 ((inType << ePacketShiftType) & ePacketMaskType) |
00214 ((inOpcode << ePacketShiftOpcode) & ePacketMaskOpcode) |
00215 ((inAddress << ePacketShiftType1Address) & ePacketMaskType1Address) |
00216 ((inCount << ePacketShiftType1Count) & ePacketMaskType1Count);
00217
00218 else if(inType == ePacketType2) return
00219 ((inType << ePacketShiftType) & ePacketMaskType) |
00220 ((inOpcode << ePacketShiftOpcode) & ePacketMaskOpcode) |
00221 ((inCount << ePacketShiftType2Count) & ePacketMaskType2Count);
00222
00223 else
00224
00225 return 0;
00226 }
00227
00228 uint32_t operator[] (size_t inIndex) const {
00229 if(inIndex == 0) return mHeader;
00230 if(inIndex == 1 && mCount == 1) return mWord;
00231 if(inIndex <= mCount) return mWords[inIndex-1];
00232 return 0;
00233 }
00234
00235 EPacketType getType(void) const { return mType; }
00236 EOpcode getOpcode(void) const { return mOpcode; }
00237 int getAddress(void) const { return mAddress; }
00238 uint32_t getHeader(void) const { return mHeader; }
00239
00240 uint32_t getWordCount(void) const { return mCount; }
00241
00242 uint32_t getWordSize(void) const { return mCount + 1; }
00243
00244 const WordSharedArray getWords(void) const { return mWords; }
00245
00246 bool isType1(void) const { return mType == ePacketType1; }
00247 bool isType2(void) const { return mType == ePacketType2; }
00248 bool isNop(void) const { return mOpcode == eOpcodeNOP; }
00249 bool isReserved(void) const { return mOpcode == eOpcodeReserved; }
00250 bool isRead(void) const { return mOpcode == eOpcodeRead; }
00251 bool isWrite(void) const { return mOpcode == eOpcodeWrite; }
00252 bool isDummyWord(void) const { return mHeader == eSynchronizationDummy; }
00253 bool isSyncWord(void) const { return mHeader == eSynchronizationSync; }
00254 bool isBusWidthSyncWord(void) const { return mHeader == eSynchronizationBusWidthSync; }
00255 bool isBusWidthDetectWord(void) const { return mHeader == eSynchronizationBusWidthDetect; }
00256 };
00257
00258
00259 typedef std::vector<VirtexPacket> VirtexPacketVector;
00260
00261 }
00262 }
00263
00264 #endif // TORC_BITSTREAM_VIRTEXPACKET_HPP