torc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SpartanPacket.hpp
Go to the documentation of this file.
1 // Torc - Copyright 2011-2013 University of Southern California. All Rights Reserved.
2 // $HeadURL$
3 // $Id$
4 
5 // This program is free software: you can redistribute it and/or modify it under the terms of the
6 // GNU General Public License as published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
10 // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
11 // the GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License along with this program. If
14 // not, see <http://www.gnu.org/licenses/>.
15 
16 /// \file
17 /// \brief Header for the SpartanPacket class.
18 
19 #ifndef TORC_BITSTREAM_SPARTANPACKET_HPP
20 #define TORC_BITSTREAM_SPARTANPACKET_HPP
21 
22 #include "torc/common/Endian.hpp"
23 #include <boost/smart_ptr.hpp>
24 #include <vector>
25 #include <istream>
26 #include <cstdio>
27 
28 namespace torc {
29 namespace bitstream {
30 
31 namespace bitstream { class SpartanPacketUnitTest; }
32 
33  /// \brief Bitstream packet constants for Spartan class architectures.
35  public:
36  // enumerations
37  /// \brief Packet type enumeration.
38  /// \see packet type: XAPP452, v1.1, June 25, 2008, Figure 6, 7.
40  //
41  /// \brief Packet opcode enumeration.
43  /// \brief Packet subfields.
44  /// \see type 1 packet format: XAPP452, v1.1, June 25, 2008, Figure 6.
45  /// \see type 2 packet format: XAPP452, v1.1, June 25, 2008, Figure 7.
46  enum EPacket {
47  // generic packet subfields
48  ePacketMaskType = 0xe0000000, ePacketShiftType = 29,
50  // type 1 packet subfields
54  // type 2 packet subfields
56  };
57  //
58  /// \brief Synchronization words.
59  /// \see Configuration Sequence: XAPP452, v1.1, June 25, 2008, Table 9.
61  eSynchronizationDummy = 0xffffffff,
62  eSynchronizationSync = 0xaa995566,
65  };
66  };
67 
68  /// \brief Bitstream packet for Spartan class architectures.
71  protected:
72  // typedefs
73  /// \brief Imported type name.
74  typedef boost::uint32_t uint32_t;
75  /// \brief Word shared array type.
76  typedef boost::shared_array<uint32_t> WordSharedArray;
77  // functions
78  void initialize(void) {
81  if(mType == ePacketType1)
83  }
84  public:
85  //protected:
86  // members
93  int mAddress;
94  /// \brief Packet type names.
95  static const char* sPacketTypeName[ePacketTypeCount];
96  /// \brief Packet opcode names.
97  static const char* sOpcodeName[eOpcodeCount];
98  public:
99  // constructors
100  /// \brief Null constructor.
101  SpartanPacket(void) : mHeader(0), mCount(0), mWord(0), mWords(), mType(EPacketType(0)),
102  mOpcode(eOpcodeNOP), mAddress(0) {}
103  /// \brief Full constructor.
104  SpartanPacket(uint32_t inHeader, uint32_t inCount, uint32_t inWord, uint32_t* inWords)
105  : mHeader(inHeader), mCount(inCount), mWord(inWord), mWords(WordSharedArray(inWords)),
107  initialize();
108  }
109  /// \brief Header plus single word constructor.
110  SpartanPacket(uint32_t inHeader, uint32_t inWord) : mHeader(inHeader), mCount(1),
111  mWord(inWord), mWords(), mType(EPacketType(0)), mOpcode(eOpcodeNOP), mAddress(0) {
112  initialize();
113  }
114  /// \brief Header only constructor.
115  SpartanPacket(uint32_t inHeader) : mHeader(inHeader), mCount(0), mWord(0), mWords(),
117  initialize();
118  }
119  /// \brief Copy constructor.
122  mAddress(0) {
123  initialize();
124  }
125  // functions
126  /// \brief Read a packet.
127  static SpartanPacket read(std::istream& inStream) {
128  uint32_t count = 0;
129  uint32_t header = 0;
130  uint32_t word = 0;
131  uint32_t* raw_words = 0;
132  //bool debug = true;
133  // read the header
134  inStream.read((char*) &header, sizeof(header));
135  header = ntohl(header);
136  // process synchronization packets
137  if(header == eSynchronizationDummy || header == eSynchronizationSync
138  || header == eSynchronizationBusWidthSync
139  || header == eSynchronizationBusWidthDetect) {
140  //if(debug) printf("Header in sync: %x\n", header) ;
141  return SpartanPacket(header, 0, 0, 0);
142  }
143  // determine the payload length
145  switch(type) {
146  case ePacketType1:
147  count = (header & ePacketMaskType1Count) >> ePacketShiftType1Count;
148  //if(debug) printf("Type 1: Packet Header: %x\n", header);
149  //if(debug) std::cout << "Type 1: Packet Count: " << count << std::endl;
150  break;
151  case ePacketType2:
152  count = (header & ePacketMaskType2Count) >> ePacketShiftType2Count;
153  //if(debug) std::cout << "Type 2: Packet Count: " << count << std::endl;
154  break;
155  default:
156  /// \todo we should throw an exception on invalid packet types
157  count = 0;
158  break;
159  }
160  // read the packet payload
161  if(count == 1) {
162  inStream.read((char*) &word, sizeof(word));
163  word = ntohl(word);
164  } else if(count > 1) {
165  raw_words = new uint32_t[count];
166  inStream.read((char*) raw_words, count << 2);
167  //if(debug) printf("Packet Count: %x\n", count);
168  uint32_t* wordPtr = raw_words;
169  for(uint32_t i = 0; i < count; i++, wordPtr++) *wordPtr = ntohl(*wordPtr);
170  }
171  // create and return the packet
172  return SpartanPacket(header, count, word, raw_words);
173  }
174  /// \brief Write a packet.
175  void write(std::ostream& inStream) const {
176  uint32_t size = getWordSize();
177  for(uint32_t i = 0; i < size; i++) {
178  uint32_t word = htonl(operator[](i));
179  inStream.write((char*) &word, sizeof(word));
180  }
181  }
182  /// \brief Construct a null type 1 write packet.
183  /// \details A type 1 write packet to the FDRI register is generally only useful to specify
184  /// the current register in preparation for a type 2 write. The type 2 write header
185  /// includes a size but specifies no target register, hence the prior null type 1
186  /// packet.
188  return SpartanPacket(makeHeader(ePacketType1, eOpcodeWrite, inAddress, 0), 0, 0, 0);
189  }
190  /// \brief Construct a type 1 write packet.
191  static SpartanPacket makeType1Write(uint32_t inAddress, uint32_t inWord) {
192  return SpartanPacket(makeHeader(ePacketType1, eOpcodeWrite, inAddress, 1), 1, inWord,
193  0);
194  }
195  /// \brief Construct a type 2 write packet.
196  static SpartanPacket makeType2Write(uint32_t inCount, uint32_t* inWords) {
197  return SpartanPacket(makeHeader(ePacketType2, eOpcodeWrite, 0, inCount), inCount, 0,
198  inWords);
199  }
200 // /// \brief Construct a type 1 write packet header.
201 // static uint32_t makeType1WriteHeader(uint32_t inAddress, uint32_t inCount) {
202 // return makeHeader(ePacketType1, eOpcodeWrite, inAddress, inCount);
203 // }
204 // /// \brief Construct a type 2 write packet header.
205 // static uint32_t makeType2WriteHeader(uint32_t inCount) {
206 // return makeHeader(ePacketType2, eOpcodeWrite, 0, inCount);
207 // }
208  /// \brief Construct a packet header.
209  static uint32_t makeHeader(EPacketType inType, EOpcode inOpcode, uint32_t inAddress,
210  uint32_t inCount) {
211  // type 1 packets
212  if(inType == ePacketType1) return
213  ((inType << ePacketShiftType) & ePacketMaskType) |
214  ((inOpcode << ePacketShiftOpcode) & ePacketMaskOpcode) |
217  // type 2 packets
218  else if(inType == ePacketType2) return
219  ((inType << ePacketShiftType) & ePacketMaskType) |
220  ((inOpcode << ePacketShiftOpcode) & ePacketMaskOpcode) |
222  // undefined packet types
223  else
224  /// \todo Generate an error or throw an exception on invalid packet types?
225  return 0;
226  }
227  // operators
228  uint32_t operator[] (size_t inIndex) const {
229  if(inIndex == 0) return mHeader;
230  if(inIndex == 1 && mCount == 1) return mWord;
231  if(inIndex <= mCount) return mWords[inIndex-1];
232  return 0;
233  }
234  // accessors
235  EPacketType getType(void) const { return mType; }
236  EOpcode getOpcode(void) const { return mOpcode; }
237  int getAddress(void) const { return mAddress; }
238  uint32_t getHeader(void) const { return mHeader; }
239  /// \brief Returns the number of payload words in the packet, excluding the header word.
240  uint32_t getWordCount(void) const { return mCount; }
241  /// \brief Returns the total number of words in the packet, including the header word.
242  uint32_t getWordSize(void) const { return mCount + 1; }
243 // const uint32_t* getWords(void) const { return mWords; }
244  // tests
245  bool isType1(void) const { return mType == ePacketType1; }
246  bool isType2(void) const { return mType == ePacketType2; }
247  bool isNop(void) const { return mOpcode == eOpcodeNOP; }
248  bool isReserved(void) const { return mOpcode == eOpcodeReserved; }
249  bool isRead(void) const { return mOpcode == eOpcodeRead; }
250  bool isWrite(void) const { return mOpcode == eOpcodeWrite; }
251  bool isDummyWord(void) const { return mHeader == eSynchronizationDummy; }
252  bool isSyncWord(void) const { return mHeader == eSynchronizationSync; }
255  };
256 
257  /// \brief Vector of Spartan packets.
258  typedef std::vector<SpartanPacket> SpartanPacketVector;
259 
260 } // namespace bitstream
261 } // namespace torc
262 
263 #endif // TORC_BITSTREAM_SPARTANPACKET_HPP
SpartanPacket(uint32_t inHeader, uint32_t inWord)
Header plus single word constructor.
EOpcode getOpcode(void) const
Bitstream packet constants for Spartan class architectures.
EPacketType getType(void) const
bool isBusWidthSyncWord(void) const
static const char * sOpcodeName[eOpcodeCount]
Packet opcode names.
boost::shared_array< uint32_t > WordSharedArray
Word shared array type.
static SpartanPacket makeType2Write(uint32_t inCount, uint32_t *inWords)
Construct a type 2 write packet.
static const char * sPacketTypeName[ePacketTypeCount]
Packet type names.
std::vector< SpartanPacket > SpartanPacketVector
Vector of Spartan packets.
boost::uint32_t uint32_t
Imported type name.
EPacketType
Packet type enumeration.
EOpcode
Packet opcode enumeration.
static uint32_t makeHeader(EPacketType inType, EOpcode inOpcode, uint32_t inAddress, uint32_t inCount)
Construct a packet header.
SpartanPacket(const SpartanPacket &rhs)
Copy constructor.
SpartanPacket(void)
Null constructor.
void write(std::ostream &inStream) const
Write a packet.
uint32_t getHeader(void) const
static SpartanPacket makeNullType1Write(uint32_t inAddress)
Construct a null type 1 write packet.
static SpartanPacket makeType1Write(uint32_t inAddress, uint32_t inWord)
Construct a type 1 write packet.
SpartanPacket(uint32_t inHeader, uint32_t inCount, uint32_t inWord, uint32_t *inWords)
Full constructor.
Bitstream packet for Spartan class architectures.
SpartanPacket(uint32_t inHeader)
Header only constructor.
static SpartanPacket read(std::istream &inStream)
Read a packet.
uint32_t getWordSize(void) const
Returns the total number of words in the packet, including the header word.
uint32_t operator[](size_t inIndex) const
uint32_t getWordCount(void) const
Returns the number of payload words in the packet, excluding the header word.
Header for endian conversion.
friend class torc::bitstream::bitstream::SpartanPacketUnitTest
bool isBusWidthDetectWord(void) const