torc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
bitstream/Bitstream.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 Bitstream class.
18 
19 #ifndef TORC_BITSTREAM_BITSTREAM_HPP
20 #define TORC_BITSTREAM_BITSTREAM_HPP
21 
22 #include "torc/common/Endian.hpp"
24 #include "torc/common/Devices.hpp"
26 #include <istream>
27 #include <ostream>
28 #include <string>
29 #include <map>
30 
31 /// \todo remove <iostream>
32 #include <iostream>
33 
34 namespace torc {
35 namespace bitstream {
36 
37 namespace bitstream { class BitstreamUnitTest; }
38 
39  /// \brief Xilinx bitstream base class.
40  class Bitstream {
42  public:
43  /// \brief The block type count is fixed at eight across all Xilinx architectures.
44  enum { eBlockTypeCount = 8 };
45  /// \brief The bitstream type to generate.
46  /// \detail Use eBitstreamFull to fully reconfigure a device, eBitstreamTypePartialActive
47  /// to partially reconfigure it while it continues to run, or
48  /// eBitstreamTypePartialShutdown to partially recongifure it after shutting it down.
51  /// \brief The frames to include in a partial bitstream.
52  /// \detail Use eFrameIncludeOnlyDirtyFrames to include only dirty frames, or
53  /// eFrameStateAllUsedFrames to include all allocated frames, dirty or not. Note that
54  /// if not all frames were allocated, eFrameStateAllUsedFrames is not the same as a
55  /// full bitstream.
57 /// \todo Bitstream access needs to be changed from public back to protected.
58 // protected: changed to run tests
59  public:
60  typedef std::string string; ///< Imported type name.
61  typedef boost::uint8_t uint8_t; ///< Imported type name.
62  typedef boost::uint16_t uint16_t; ///< Imported type name.
63  typedef boost::uint32_t uint32_t; ///< Imported type name.
64  typedef torc::common::EDevice EDevice; ///< Imported type name.
65 
66  /// \brief Write a uint8_t to the stream.
67  void write(std::ostream& inStream, uint8_t inVal) {
68  uint8_t actual = inVal;
69  inStream.write((char*) &actual, sizeof(actual));
70  }
71  /// \brief Write a uint16_t to the stream.
72  void write(std::ostream& inStream, uint16_t inVal) {
73  uint16_t actual = htons(inVal);
74  inStream.write((char*) &actual, sizeof(actual));
75  }
76  /// \brief Write a uint32_t to the stream.
77  void write(std::ostream& inStream, uint32_t inVal) {
78  uint32_t actual = htonl(inVal);
79  inStream.write((char*) &actual, sizeof(actual));
80  }
81  /// \brief Write a Xilinx-style header string to the stream.
82  void writeHeaderString(std::ostream& inStream, const string& inString) {
83  // write the string length
84  uint16_t length = inString.length() + 1;
85  write(inStream, uint16_t(length));
86  inStream.write(inString.c_str(), length);
87  }
88  /// \brief Look for the expected uint8_t in the stream and return true if it matches.
89  static bool expect(std::istream& inStream, uint8_t inExpected) {
90  // read the actual data from the stream
91  uint8_t actual = 0;
92  inStream.read((char*) &actual, sizeof(actual));
93  // return equality
94  return inExpected == actual;
95  }
96  /// \brief Look for the expected uint16_t in the stream and return true if it matches.
97  static bool expect(std::istream& inStream, uint16_t inExpected) {
98  // read the actual data from the stream
99  uint16_t actual = 0;
100  inStream.read((char*) &actual, sizeof(actual));
101  // return equality
102  return inExpected == ntohs(actual);
103  }
104  /// \brief Look for the expected uint32_t in the stream and return true if it matches.
105  static bool expect(std::istream& inStream, uint32_t inExpected) {
106  // read the actual data from the stream
107  uint32_t actual = 0;
108  inStream.read((char*) &actual, sizeof(actual));
109  // return equality
110  return inExpected == ntohl(actual);
111  }
112 // /// \brief Look for the expected string in the stream and return true if it matches.
113 // static bool expect(std::istream& inStream, const string& inExpected) {
114 // // look for the length;
115 // if(!expect(inStream, (uint16_t) inExpected.size())) return false;
116 // // create a buffer to use
117 // int adjustedLength = inExpected.size() + 1;
118 // char* buffer = new char[adjustedLength];
119 // // read the actual data from the stream
120 // inStream.read(buffer, adjustedLength);
121 // return buffer == inExpected;
122 // }
123  /// \brief Read and return a bitstream header string.
124  static void readHeaderString(std::istream& inStream, string& outString) {
125  // read the string length
126  uint16_t length = 0;
127  inStream.read((char*) &length, sizeof(length));
128  length = ntohs(length);
129  if(length > 0) {
130  // create a buffer
131  char* buffer = new char[length];
132  // read the null-terminated string
133  inStream.read(buffer, length);
134  // copy the data into the string
135  outString.assign(buffer, length - 1);
136  delete[] buffer;
137  } else {
138  outString.clear();
139  }
140  }
141  /// \brief Read a bitstream header, and return its fields.
142  static bool readHeader(std::istream& inStream, string& outDesignName,
143  string& outDeviceName, string& outDesignDate, string& outDesignTime,
144  uint32_t& outBitstreamLength, uint32_t& outHeaderLength) {
145  // assume success unless we find otherwise
146  bool success = true;
147  // read the magic length
148  success &= expect(inStream, uint16_t(0x0009));
149  // read the magic bytes
150  success &= expect(inStream, uint32_t(0x0ff00ff0));
151  success &= expect(inStream, uint32_t(0x0ff00ff0));
152  success &= expect(inStream, uint8_t(0x00));
153  // read the mysterious 0x0001
154  success &= expect(inStream, uint16_t(0x0001));
155  // read the 'a' byte
156  success &= expect(inStream, uint8_t('a'));
157  // read the design name length
158  readHeaderString(inStream, outDesignName);
159  // read the 'b' byte
160  success &= expect(inStream, uint8_t('b'));
161  // read the device name length
162  readHeaderString(inStream, outDeviceName);
163  // read the 'c' byte
164  success &= expect(inStream, uint8_t('c'));
165  // read the design date length
166  readHeaderString(inStream, outDesignDate);
167  // read the 'd' byte
168  success &= expect(inStream, uint8_t('d'));
169  // read the design time length
170  readHeaderString(inStream, outDesignTime);
171  // read the 'e' byte
172  success &= expect(inStream, uint8_t('e'));
173  // read the inStream length
174  inStream.read((char*) &outBitstreamLength, sizeof(outBitstreamLength));
175  outBitstreamLength = ntohl(outBitstreamLength);
176  // determine the header length
177  outHeaderLength = 34 + outDesignName.length() + outDeviceName.length()
178  + outDesignDate.length() + outDesignTime.length();
179  // return the result
180  return success;
181  }
182  /// \brief Clean up the header date and time by replacing embedded spaces with zeros.
183  void cleanDateAndTime(void) {
184  // some versions of the tools leave spaces inside the date and time fields
185  size_t pos = 0;
186  while((pos = mDesignDate.find(' ', pos)) != string::npos) mDesignDate[pos] = '0';
187  pos = 0;
188  while((pos = mDesignTime.find(' ', pos)) != string::npos) mDesignTime[pos] = '0';
189  }
190  // inner class
191  struct Subfield {
192  /// \brief The subfield bit mask.
194  /// \brief The subfield LSB position.
196  /// \brief The subfield name documented in bitgen.
197  const char* mBitgenName;
198  /// \brief The subfield name documented in the configuration guide.
199  const char* mConfigGuideName;
200  /// \brief The default subfield value.
202  /// \brief The allowable subfield values.
203  const char** mValues;
204  };
205  /// \brief Insert 32 bit subfield settings into an output stream.
206  static void writeSubfieldSettings(std::ostream& inStream, uint32_t inWord,
207  const Subfield* inSubfields);
208  /// \brief Insert 16 bit subfield settings into an output stream.
209  static void writeSubfieldSettings(std::ostream& inStream, uint16_t inWord,
210  const Subfield* inSubfields);
211  /// \brief Initialize the maps between frame indexes and frame addresses.
212  /// \detail This is generally only useful for internal purposes.
213  /// \todo This function should be made pure virtual.
214  virtual void initializeDeviceInfo(const std::string& inDeviceName) {}
215  /// \brief Initialize the maps between frame indexes and frame addresses.
216  /// \detail This is generally only useful for internal purposes.
217  virtual void initializeFrameMaps(void) {}
218  /// \brief Output static device information to a stream.
219  /// \details This is used to generate the static column maps for bitstream frame mapping.
220  virtual void writeDeviceInfo(std::ostream& inStream, const std::string& inDeviceName);
221  // accessors
222  /// \brief Assign static device information for the current bitstream.
223  void setDeviceInfo(const DeviceInfo& rhs) { mDeviceInfo = rhs; }
224  /// \brief Assign the device enumeration constant for the given device name.
225  void setDevice(const std::string& inDeviceName) {
227  }
228  // members
229  /// \brief Bitstream device enumeration.
231  /// \brief Header design name.
232  string mDesignName;
233  /// \brief Header device name.
234  string mDeviceName;
235  /// \brief Header design date.
236  string mDesignDate;
237  /// \brief Header design time.
238  string mDesignTime;
239  /// \brief Bitstream packet length in bytes.
240  /// \details This is the length in bytes of all the bitstream packets, without the
241  /// bitstream header.
243  /// \brief Header length in bytes.
244  /// \details This is the length of the header itself, as opposed to mBitstreamByteLength,
245  /// which is the length of bitstream reported by the header.
247  // members for frame addressing
248  /// \brief Column type widths.
250  /// \brief Mapping from tile type names to column types.
251  typedef std::map<std::string, uint32_t> TileTypeNameToColumnType;
253  /// \brief Mapping from tile indexes to column types.
254  typedef std::map<uint16_t, uint32_t> TileTypeIndexToColumnType;
256  /// \brief Device information.
258  public:
259  // constructors
260  /// \brief Basic constructor.
261  Bitstream(void) : mDevice(torc::common::eDeviceInvalid), mBitstreamByteLength(0) {}
262  /// \brief Virtual destructor.
263  virtual ~Bitstream(void) {}
264  // functions
265  /// \brief Read the bitstream header and packets from a stream.
266  virtual void read(std::istream& inStream, bool inCleanDateAndTime = true) {
267  readHeader(inStream);
268  readPackets(inStream);
269  if(inCleanDateAndTime) cleanDateAndTime();
270  }
271  /// \brief Read the bitstream packets
272  virtual void readPackets(std::istream& inStream) {}
273  /// \brief Read the bitstream header.
274  virtual void readHeader(std::istream& inStream) {
278  }
279  /// \brief Write the bitstream header and packets to a stream.
280  virtual void write(std::ostream& inStream) {
283  writeHeader(inStream);
284  writePackets(inStream);
285  }
286  /// \brief Preflight the packets.
287  virtual void preflightPackets(void) {}
288  /// \brief Update the header packet length.
289  virtual void updatePacketLength(void) {}
290  /// \brief Write the bitstream packets.
291  virtual void writePackets(std::ostream& inStream) {}
292  /// \brief Write the bitstream header to the stream.
293  virtual void writeHeader(std::ostream& inStream) {
294  // write the magic length
295  write(inStream, uint16_t(0x0009));
296  // write the magic bytes with null termination
297  write(inStream, uint32_t(0x0ff00ff0));
298  write(inStream, uint32_t(0x0ff00ff0));
299  write(inStream, uint8_t(0x00));
300  // write the mysterious 0x0001
301  write(inStream, uint16_t(0x0001));
302  // write the 'a' byte and the design name
303  write(inStream, uint8_t('a'));
304  writeHeaderString(inStream, mDesignName);
305  // write the 'b' byte and the device name
306  write(inStream, uint8_t('b'));
307  writeHeaderString(inStream, mDeviceName);
308  // write the 'c' byte and the design date
309  write(inStream, uint8_t('c'));
310  writeHeaderString(inStream, mDesignDate);
311  // write the 'd' byte and the design time
312  write(inStream, uint8_t('d'));
313  writeHeaderString(inStream, mDesignTime);
314  // write the 'e' byte and the design name
315  write(inStream, uint8_t('e'));
316  write(inStream, uint32_t(mBitstreamByteLength));
317  }
318  // inserters
319  /// \brief Insert the bitstream header into an output stream.
320  friend std::ostream& operator<< (std::ostream& os, const Bitstream& rhs);
321  // accessors
322  /// \brief Set the design name.
323  void setDesignName(const string& inDesignName) { mDesignName = inDesignName; }
324  /// \brief Set the device name.
325  void setDeviceName(const string& inDeviceName) { mDeviceName = inDeviceName; }
326  /// \brief Set the design date.
327  void setDesignDate(const string& inDesignDate) { mDesignDate = inDesignDate; }
328  /// \brief Set the design time.
329  void setDesignTime(const string& inDesignTime) { mDesignTime = inDesignTime; }
330  /// \brief Return the design name.
331  const string& getDesignName(void) const { return mDesignName; }
332  /// \brief Return the device name.
333  const string& getDeviceName(void) const { return mDeviceName; }
334  /// \brief Return the design date.
335  const string& getDesignDate(void) const { return mDesignDate; }
336  /// \brief Return the design time.
337  const string& getDesignTime(void) const { return mDesignTime; }
338  /// \brief Return the bitstream packet length in bytes.
339  /// \details The length includes all packet data, but does not include the bitstream header.
341  /// \brief Return the bitstream header length in bytes.
343  /// \brief Return the frame length for the current device.
344  virtual uint32_t getFrameLength(void) const { return 0; }
345  };
346 
347 } // namespace bitstream
348 } // namespace torc
349 
350 #endif // TORC_BITSTREAM_BITSTREAM_HPP
void setDesignTime(const string &inDesignTime)
Set the design time.
ColumnDefVector mColumnDefs
Column type widths.
static bool expect(std::istream &inStream, uint32_t inExpected)
Look for the expected uint32_t in the stream and return true if it matches.
void write(std::ostream &inStream, uint16_t inVal)
Write a uint16_t to the stream.
virtual void readHeader(std::istream &inStream)
Read the bitstream header.
const string & getDesignDate(void) const
Return the design date.
static bool readHeader(std::istream &inStream, string &outDesignName, string &outDeviceName, string &outDesignDate, string &outDesignTime, uint32_t &outBitstreamLength, uint32_t &outHeaderLength)
Read a bitstream header, and return its fields.
TileTypeNameToColumnType mTileTypeNameToColumnType
static EDevice getDeviceEnum(const string &inName)
Returns the device enumeration corresponding to the given device name.
Definition: Devices.hpp:216
void writeHeaderString(std::ostream &inStream, const string &inString)
Write a Xilinx-style header string to the stream.
string mDesignDate
Header design date.
string mDesignTime
Header design time.
EDevice
Enumeration of all supported devices.
Definition: Devices.hpp:32
torc::common::EDevice EDevice
Imported type name.
static bool expect(std::istream &inStream, uint16_t inExpected)
Look for the expected uint16_t in the stream and return true if it matches.
EFrameInclude
The frames to include in a partial bitstream. Use eFrameIncludeOnlyDirtyFrames to include only dirty...
string mDesignName
Header design name.
TileTypeIndexToColumnType mTileTypeIndexToColumnType
Static device information class for Xilinx bitstreams. This class facilitates the creation of frame ...
Definition: DeviceInfo.hpp:75
const string & getDesignTime(void) const
Return the design time.
virtual void write(std::ostream &inStream)
Write the bitstream header and packets to a stream.
void cleanDateAndTime(void)
Clean up the header date and time by replacing embedded spaces with zeros.
const string & getDeviceName(void) const
Return the device name.
uint32_t mDefault
The default subfield value.
EDevice mDevice
Bitstream device enumeration.
boost::uint8_t uint8_t
Imported type name.
std::string string
friend std::ostream & operator<<(std::ostream &os, const Bitstream &rhs)
Insert the bitstream header into an output stream.
uint32_t mShift
The subfield LSB position.
virtual void updatePacketLength(void)
Update the header packet length.
static bool expect(std::istream &inStream, uint8_t inExpected)
Look for the expected uint8_t in the stream and return true if it matches.
const char * mConfigGuideName
The subfield name documented in the configuration guide.
const string & getDesignName(void) const
Return the design name.
boost::uint32_t uint32_t
Imported type name.
void write(std::ostream &inStream, uint32_t inVal)
Write a uint32_t to the stream.
void setDesignName(const string &inDesignName)
Set the design name.
void setDesignDate(const string &inDesignDate)
Set the design date.
Xilinx bitstream base class.
uint32_t mMask
The subfield bit mask.
string mDeviceName
Header device name.
DeviceInfo mDeviceInfo
Device information.
virtual void initializeDeviceInfo(const std::string &inDeviceName)
Initialize the maps between frame indexes and frame addresses. This is generally only useful for int...
static void readHeaderString(std::istream &inStream, string &outString)
Read and return a bitstream header string.
virtual void initializeFrameMaps(void)
Initialize the maps between frame indexes and frame addresses. This is generally only useful for int...
static void writeSubfieldSettings(std::ostream &inStream, uint32_t inWord, const Subfield *inSubfields)
Insert 32 bit subfield settings into an output stream.
Definition: Bitstream.cpp:26
friend class torc::bitstream::bitstream::BitstreamUnitTest
EBitstreamType
The bitstream type to generate. Use eBitstreamFull to fully reconfigure a device, eBitstreamTypePartialActive to partially reconfigure it while it continues to run, or eBitstreamTypePartialShutdown to partially recongifure it after shutting it down.
Column definition vector.
Definition: DeviceInfo.hpp:67
Header for the Devices class.
uint32_t mBitstreamByteLength
Bitstream packet length in bytes.
void setDevice(const std::string &inDeviceName)
Assign the device enumeration constant for the given device name.
uint32_t mHeaderByteLength
Header length in bytes.
std::map< std::string, uint32_t > TileTypeNameToColumnType
Mapping from tile type names to column types.
virtual void readPackets(std::istream &inStream)
Read the bitstream packets.
const char * mBitgenName
The subfield name documented in bitgen.
void write(std::ostream &inStream, uint8_t inVal)
Write a uint8_t to the stream.
virtual uint32_t getFrameLength(void) const
Return the frame length for the current device.
std::string string
Imported type name.
boost::uint16_t uint16_t
Imported type name.
Bitstream(void)
Basic constructor.
virtual void preflightPackets(void)
Preflight the packets.
void setDeviceInfo(const DeviceInfo &rhs)
Assign static device information for the current bitstream.
std::map< uint16_t, uint32_t > TileTypeIndexToColumnType
Mapping from tile indexes to column types.
virtual void read(std::istream &inStream, bool inCleanDateAndTime=true)
Read the bitstream header and packets from a stream.
void setDeviceName(const string &inDeviceName)
Set the device name.
const char ** mValues
The allowable subfield values.
uint32_t getBitstreamByteLength(void) const
Return the bitstream packet length in bytes.
virtual void writeDeviceInfo(std::ostream &inStream, const std::string &inDeviceName)
Output static device information to a stream.
Definition: Bitstream.cpp:74
virtual ~Bitstream(void)
Virtual destructor.
Header for the EncapsulatedInteger template.
Header for endian conversion.
virtual void writeHeader(std::ostream &inStream)
Write the bitstream header to the stream.
virtual void writePackets(std::ostream &inStream)
Write the bitstream packets.
uint32_t getHeaderByteLength(void) const
Return the bitstream header length in bytes.
Header for the DeviceInfo class.