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