torc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Virtex6UnitTest.cpp
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 Unit test for the Virtex6 class.
18 
19 #include <boost/test/unit_test.hpp>
22 #include "torc/common/Devices.hpp"
28 #include <fstream>
29 #include <iostream>
30 #include <boost/filesystem.hpp>
31 
32 namespace torc {
33 namespace bitstream {
34 
35 BOOST_AUTO_TEST_SUITE(bitstream)
36 
37 /// \brief Unit test for the Virtex6 class.
38 BOOST_AUTO_TEST_CASE(Virtex6UnitTest) {
39 
40  // enums tested:
41  // EPacket
42  // EFar
43  boost::uint32_t mask;
44  // type 1 packet subfield masks
48  BOOST_CHECK_EQUAL(mask, 0xFFFFFFFFu);
49  // type 2 packet subfield masks
52  BOOST_CHECK_EQUAL(mask, 0xFFFFFFFFu);
53  // frame address register subfield masks
56  BOOST_CHECK_EQUAL(mask, 0x00FFFFFFu);
57 
58  // members tested:
59  // Virtex6::sPacketTypeName and EPacketTypeName
60  BOOST_CHECK_EQUAL(Virtex6::sPacketTypeName[0], "[UNKNOWN TYPE 0]");
61  BOOST_CHECK_EQUAL(Virtex6::sPacketTypeName[Virtex6::ePacketType1], "TYPE1");
62  BOOST_CHECK_EQUAL(Virtex6::sPacketTypeName[Virtex6::ePacketType2], "TYPE2");
63  BOOST_CHECK_EQUAL(Virtex6::sPacketTypeName[3], "[UNKNOWN TYPE 3]");
64  BOOST_CHECK_EQUAL(Virtex6::sPacketTypeName[4], "[UNKNOWN TYPE 4]");
65  BOOST_CHECK_EQUAL(Virtex6::sPacketTypeName[5], "[UNKNOWN TYPE 5]");
66  BOOST_CHECK_EQUAL(Virtex6::sPacketTypeName[6], "[UNKNOWN TYPE 6]");
67  BOOST_CHECK_EQUAL(Virtex6::sPacketTypeName[7], "[UNKNOWN TYPE 7]");
68 
69  // members tested:
70  // Virtex6::sOpcodeName and EOpcode
71  BOOST_CHECK_EQUAL(Virtex6::sOpcodeName[Virtex6::eOpcodeNOP], "NOP");
72  BOOST_CHECK_EQUAL(Virtex6::sOpcodeName[Virtex6::eOpcodeRead], "READ");
73  BOOST_CHECK_EQUAL(Virtex6::sOpcodeName[Virtex6::eOpcodeWrite], "WRITE");
74  BOOST_CHECK_EQUAL(Virtex6::sOpcodeName[Virtex6::eOpcodeReserved], "RESERVED");
75 
76  // members tested:
77  // Virtex6::sRegisterName and ERegister
78  BOOST_CHECK_EQUAL(Virtex6::sRegisterName[Virtex6::eRegisterCRC], "CRC");
79  BOOST_CHECK_EQUAL(Virtex6::sRegisterName[Virtex6::eRegisterFAR], "FAR");
80  BOOST_CHECK_EQUAL(Virtex6::sRegisterName[Virtex6::eRegisterFDRI], "FDRI");
81  BOOST_CHECK_EQUAL(Virtex6::sRegisterName[Virtex6::eRegisterFDRO], "FDRO");
82  BOOST_CHECK_EQUAL(Virtex6::sRegisterName[Virtex6::eRegisterCMD], "CMD");
83  BOOST_CHECK_EQUAL(Virtex6::sRegisterName[Virtex6::eRegisterCTL0], "CTL0");
84  BOOST_CHECK_EQUAL(Virtex6::sRegisterName[Virtex6::eRegisterMASK], "MASK");
85  BOOST_CHECK_EQUAL(Virtex6::sRegisterName[Virtex6::eRegisterSTAT], "STAT");
86  BOOST_CHECK_EQUAL(Virtex6::sRegisterName[Virtex6::eRegisterLOUT], "LOUT");
87  BOOST_CHECK_EQUAL(Virtex6::sRegisterName[Virtex6::eRegisterCOR0], "COR0");
88  BOOST_CHECK_EQUAL(Virtex6::sRegisterName[Virtex6::eRegisterMFWR], "MFWR");
89  BOOST_CHECK_EQUAL(Virtex6::sRegisterName[Virtex6::eRegisterCBC], "CBC");
90  BOOST_CHECK_EQUAL(Virtex6::sRegisterName[Virtex6::eRegisterIDCODE], "IDCODE");
91  BOOST_CHECK_EQUAL(Virtex6::sRegisterName[Virtex6::eRegisterAXSS], "AXSS");
92  BOOST_CHECK_EQUAL(Virtex6::sRegisterName[Virtex6::eRegisterCOR1], "COR1");
93  BOOST_CHECK_EQUAL(Virtex6::sRegisterName[Virtex6::eRegisterCSOB], "CSOB");
94  BOOST_CHECK_EQUAL(Virtex6::sRegisterName[Virtex6::eRegisterWBSTAR], "WBSTAR");
95  BOOST_CHECK_EQUAL(Virtex6::sRegisterName[Virtex6::eRegisterTIMER], "TIMER");
96  BOOST_CHECK_EQUAL(Virtex6::sRegisterName[Virtex6::eRegisterBOOTSTS], "BOOTSTS");
97  BOOST_CHECK_EQUAL(Virtex6::sRegisterName[Virtex6::eRegisterCTL1], "CTL1");
98  BOOST_CHECK_EQUAL(Virtex6::sRegisterName[Virtex6::eRegisterDWC], "DWC");
99 
100  // members tested:
101  // Virtex6::sCommandName and ECommand
102  BOOST_CHECK_EQUAL(Virtex6::sCommandName[Virtex6::eCommandNULL], "NULL");
103  BOOST_CHECK_EQUAL(Virtex6::sCommandName[Virtex6::eCommandWCFG], "WCFG");
104  BOOST_CHECK_EQUAL(Virtex6::sCommandName[Virtex6::eCommandMFW], "MFW");
105  BOOST_CHECK_EQUAL(Virtex6::sCommandName[Virtex6::eCommandLFRM], "DGHIGH/LFRM");
106  BOOST_CHECK_EQUAL(Virtex6::sCommandName[Virtex6::eCommandRCFG], "RCFG");
107  BOOST_CHECK_EQUAL(Virtex6::sCommandName[Virtex6::eCommandSTART], "START");
108  BOOST_CHECK_EQUAL(Virtex6::sCommandName[Virtex6::eCommandRCAP], "RCAP");
109  BOOST_CHECK_EQUAL(Virtex6::sCommandName[Virtex6::eCommandRCRC], "RCRC");
110  BOOST_CHECK_EQUAL(Virtex6::sCommandName[Virtex6::eCommandAGHIGH], "AGHIGH");
111  BOOST_CHECK_EQUAL(Virtex6::sCommandName[Virtex6::eCommandSWITCH], "SWITCH");
112  BOOST_CHECK_EQUAL(Virtex6::sCommandName[Virtex6::eCommandGRESTORE], "GRESTORE");
113  BOOST_CHECK_EQUAL(Virtex6::sCommandName[Virtex6::eCommandSHUTDOWN], "SHUTDOWN");
114  BOOST_CHECK_EQUAL(Virtex6::sCommandName[Virtex6::eCommandGCAPTURE], "GCAPTURE");
115  BOOST_CHECK_EQUAL(Virtex6::sCommandName[Virtex6::eCommandDESYNCH], "DESYNCH");
116  BOOST_CHECK_EQUAL(Virtex6::sCommandName[Virtex6::eCommandReserved], "Reserved");
117  BOOST_CHECK_EQUAL(Virtex6::sCommandName[Virtex6::eCommandIPROG], "IPROG");
118  BOOST_CHECK_EQUAL(Virtex6::sCommandName[Virtex6::eCommandCRCC], "CRCC");
119  BOOST_CHECK_EQUAL(Virtex6::sCommandName[Virtex6::eCommandLTIMER], "LTIMER");
120 
121  // build the file paths
123  / "torc" / "bitstream" / "Virtex6UnitTest.reference.bit";
125  / "regression" / "Virtex6UnitTest.generated.bit";
126 
127  // read the bitstream
128  std::fstream fileStream(referencePath.string().c_str(), std::ios::binary | std::ios::in);
129  BOOST_REQUIRE(fileStream.good());
130  Virtex6 bitstream;
131  bitstream.read(fileStream, false);
132  // write the bitstream digest to the console
133  //std::cout << bitstream << std::endl;
134 
135  std::string designName = bitstream.getDesignName();
136  std::string deviceName = bitstream.getDeviceName();
137  std::string designDate = bitstream.getDesignDate();
138  std::string designTime = bitstream.getDesignTime();
139  torc::common::DeviceDesignator deviceDesignator(deviceName);
140  //std::cout << "family of " << deviceName << " is " << deviceDesignator.getFamily() << std::endl;
141 
142  // write the bitstream back out
143  std::fstream outputStream(generatedPath.string().c_str(), std::ios::binary | std::ios::out);
144  BOOST_REQUIRE(outputStream.good());
145  bitstream.write(outputStream);
146  outputStream.flush();
147 
148  // compare the reference and generated XDL
149  BOOST_CHECK(torc::common::fileContentsAreEqual(generatedPath, referencePath));
150 }
151 
152 
153 
154 
155 
156 
157 
158 
159 
160 
161 
162 
163 
164 
165 
166 
167 
168 
169 
170 
171 
172 
173 
174 
175 
176 
177 
178 
179 
180 
181 
182 
183 
184 
185 
186 
187 
188 
189 
190 
191 void testVirtex6Device(const std::string& inDeviceName, const boost::filesystem::path& inWorkingPath);
192 
193 /// \brief Unit test for the Virtex6 class Frame Address Register mapping.
194 BOOST_AUTO_TEST_CASE(Virtex6FarUnitTest) {
195 
196  // look up the command line arguments
197  int& argc = boost::unit_test::framework::master_test_suite().argc;
198  char**& argv = boost::unit_test::framework::master_test_suite().argv;
199  // make sure that we at least have the name under which we were invoked
200  BOOST_REQUIRE(argc >= 1);
201  // resolve symbolic links if applicable
202  torc::common::DirectoryTree directoryTree(argv[0]);
203 
204  // iterate over the Virtex6 devices
205  {
207  torc::common::DeviceVector::const_iterator dp = devices.begin();
208  torc::common::DeviceVector::const_iterator de = devices.end();
209  while(dp < de) {
210  const std::string& device = *dp++;
211  if(device.empty()) break;
212  //std::cout << "device " << ": " << device << std::endl;
214  }
215  }
216 
217 }
218 
219 /*
220  class TileTypeWidths {
221  public:
222  uint32_t mWidth[8];
223  TileTypeWidths(uint32_t in0 = 0, uint32_t in1 = 0, uint32_t in2 = 0, uint32_t in3 = 0,
224  uint32_t in4 = 0, uint32_t in5 = 0, uint32_t in6 = 0, uint32_t in7 = 0) {
225  int i = 0;
226  mWidth[i++] = in0; mWidth[i++] = in1; mWidth[i++] = in2; mWidth[i++] = in3;
227  mWidth[i++] = in4; mWidth[i++] = in5; mWidth[i++] = in6; mWidth[i++] = in7;
228  }
229  void clear(void) { for(int i = 0; i < 8; i++) mWidth[i] = 0; }
230  uint32_t operator[] (int inIndex) const { return mWidth[inIndex]; }
231  };
232 */
233 
234 void testVirtex6Device(const std::string& inDeviceName, const boost::filesystem::path& inWorkingPath) {
235 
236  // build the file paths
237  boost::filesystem::path debugBitstreamPath = inWorkingPath / "torc" / "bitstream" / "regression";
238  //boost::filesystem::path generatedPath = debugBitstreamPath / (inDeviceName + ".debug.bit");
239  boost::filesystem::path referencePath = debugBitstreamPath / (inDeviceName + ".debug.bit");
240 
241  // read the bitstream
242  std::fstream fileStream(referencePath.string().c_str(), std::ios::binary | std::ios::in);
243  std::cerr << "Trying to read: " << referencePath << std::endl;
244  BOOST_REQUIRE(fileStream.good());
245  Virtex6 bitstream;
246  bitstream.read(fileStream, false);
247  // write the bitstream digest to the console
248 // std::cout << bitstream << std::endl;
249 
250 // // initialize the bitstream frame maps
251 // boost::filesystem::path deviceColumnsPath = inWorkingPath / "torc" / "bitstream" / "regression"
252 // / (inDeviceName + ".cpp");
253 // std::fstream deviceColumnsStream(deviceColumnsPath.string().c_str(), std::ios::out);
254  bitstream.initializeDeviceInfo(inDeviceName);
255  bitstream.initializeFrameMaps();
256 
257  // iterate through the packets, and extract all of the FARs
258  Virtex6::FrameAddressToIndex farRemaining = bitstream.mFrameAddressToIndex;
259  Virtex6::FrameAddressToIndex farVisited;
260  {
261  bool first = true;
262  Virtex6::const_iterator p = bitstream.begin();
263  Virtex6::const_iterator e = bitstream.end();
266  while(p < e) {
267  const VirtexPacket& packet = *p++;
268  if(packet.getHeader() != header) continue;
269  if(first) { first = false; continue; }
270  Virtex6::FrameAddress far = packet[1];
271  farVisited[far] = 0;
272  Virtex6::FrameAddressToIndex::iterator found = farRemaining.find(far);
273  if(found != farRemaining.end()) {
274  farRemaining.erase(found);
275  } else {
276  std::cerr << "missing " << far << " ";
277  }
278  }
279  }
280  {
281  Virtex6::FrameAddressToIndex::const_iterator p = farRemaining.begin();
282  Virtex6::FrameAddressToIndex::const_iterator e = farRemaining.end();
283  while(p != e) {
284  std::cerr << "remaining " << (*p++).first << " ";
285  }
286  std::cerr << std::endl;
287  }
288  // verify that we have visited all of the expected FARs and no others
289  std::cout << "Device: " << inDeviceName << std::endl;
290  std::cout << "Size of farRemaining: " << farRemaining.size() << std::endl;
291  std::cout << "Size of farVisited: " << farVisited.size() << std::endl;
292  BOOST_REQUIRE_EQUAL(bitstream.mFrameAddressToIndex.size(), farVisited.size());
293  BOOST_REQUIRE_EQUAL(farRemaining.size(), 0u);
294 
295 return;
296 
297  // iterate through the debug bitstream packets, and extract all of the FARs
298  // this isn't currently being used, but it may come in handy for debugging
299  for(int half = 0; half < 2; half++) {
300  for(uint32_t row = 0; row < 2; row++) {
301  typedef std::map<uint32_t, uint32_t> ColumnMaxFrame;
302  ColumnMaxFrame maxFrames[Virtex6::eFarBlockTypeCount];
303  Virtex6::const_iterator p = bitstream.begin();
304  Virtex6::const_iterator e = bitstream.end();
307  while(p < e) {
308  const VirtexPacket& packet = *p++;
309  if(packet.getHeader() != header) continue;
310  Virtex6::FrameAddress far = packet[1];
311 // uint32_t far = packet[1];
312 // std::cerr << Hex32(far) << " ";
313  if(far.mTopBottom == half && far.mRow == row) {
314 // std::cerr << far << " ";
315  ColumnMaxFrame::iterator i = maxFrames[far.mBlockType].find(far.mMajor);
316  if(i == maxFrames[far.mBlockType].end()) {
317  maxFrames[far.mBlockType][far.mMajor] = 0;
318  } else {
319  if(maxFrames[far.mBlockType][far.mMajor] < far.mMinor)
320  maxFrames[far.mBlockType][far.mMajor] = far.mMinor;
321  }
322  }
323  }
324  std::cerr << std::endl;
325  uint32_t frameCount = 0;
326  for(uint32_t i = 0; i < Virtex6::eFarBlockTypeCount; i++) {
328  uint32_t majorCount = maxFrames[blockType].size();
329  for(uint32_t major = 0; major < majorCount; major++) {
330  frameCount += maxFrames[blockType][major] + 1;
331  std::cerr << blockType << "(" << major << "): "
332  << (maxFrames[blockType][major] + 1) << " (" << frameCount << ")"
333  << std::endl;
334  }
335  }
336  }
337  }
338 
339 }
340 
341 void testVirtex6FullMapping(const boost::filesystem::path& inWorkingPath);
342 void testVirtex6PartialMapping(const boost::filesystem::path& inWorkingPath);
343 
344 /// \brief Unit test for the Virtex6 bitstream to bitmap conversion.
345 BOOST_AUTO_TEST_CASE(Virtex6MapUnitTest) {
346  // look up the command line arguments
347  int& argc = boost::unit_test::framework::master_test_suite().argc;
348  char**& argv = boost::unit_test::framework::master_test_suite().argv;
349  // make sure that we at least have the name under which we were invoked
350  BOOST_REQUIRE(argc >= 1);
351  // resolve symbolic links if applicable
352  torc::common::DirectoryTree directoryTree(argv[0]);
354  //testVirtex6PartialMapping(torc::common::DirectoryTree::getWorkingPath());
355 }
356 
357 
359  // build the file paths
361  / "torc" / "bitstream" / "Virtex6UnitTest.reference.bit";
363  / "regression" / "Virtex6MapUnitTest.generated.bit";
364 
365  // read the bitstream
366  std::fstream fileStream(referencePath.string().c_str(), std::ios::binary | std::ios::in);
367  BOOST_REQUIRE(fileStream.good());
368  // read and gather bitstream frames
369  Virtex6 bitstream;
370  bitstream.read(fileStream, false);
371 
372  // initialize frame map
373  bitstream.initializeDeviceInfo("xc6vlx75t");
374  bitstream.initializeFrameMaps();
375 
376  // load bitstream frames in data structure
377  bitstream.readFramePackets();
378 
379  // write full bitstream from frame blocks data structure
380  uint32_t frameLength = bitstream.getFrameLength();
381  typedef boost::shared_array<uint32_t> WordSharedArray;
382  Virtex6::iterator p = bitstream.begin();
383  Virtex6::iterator e = bitstream.end();
384  while(p < e) {
385  const VirtexPacket& packet = *p++;
386  if(packet.isType2()) {
387  WordSharedArray words = packet.getWords();
388  uint32_t* ptr = words.get();
389  for(uint32_t block = 0; block < 8; block++) {
390  for(uint32_t frame = 0; frame < bitstream.mBlockFrameIndexBounds[block]; frame++) {
391  VirtexFrameBlocks::word_t* words = const_cast<VirtexFrameBlocks::word_t*>(bitstream.mFrameBlocks.mBlock[block][frame]->getWords());
392  for(uint32_t index = 0; index < frameLength; index++) {
393  *ptr++ = words[index];
394  }
395  }
396  }
397  }
398  }
399  // write the test bitstream back out
400  std::fstream outputStream(generatedPath.string().c_str(), std::ios::binary | std::ios::out);
401  BOOST_REQUIRE(outputStream.good());
402  bitstream.write(outputStream);
403  outputStream.flush();
404  BOOST_REQUIRE(torc::common::fileContentsAreEqual(referencePath, generatedPath));
405 
406  return;
407 }
408 
409 BOOST_AUTO_TEST_SUITE_END()
410 
411 } // namespace bitstream
412 } // namespace torc
Header for torc::bitstream output stream helpers.
static const char * sOpcodeName[eOpcodeCount]
Packet opcode names.
Definition: Virtex6.hpp:114
static const char * sPacketTypeName[ePacketTypeCount]
Packet type names.
Definition: Virtex6.hpp:112
Encapsulation of a device designator and its constituent elements.
static const char * sRegisterName[eRegisterCount]
Configuration register names.
Definition: Virtex6.hpp:116
Header for the DeviceInfoHelper class.
Header for the DirectoryTree class.
Virtex6 bitstream.
Definition: Virtex6.hpp:41
std::map< Virtex6::FrameAddress, uint32_t > FrameAddressToIndex
Map from frame address to frame index.
Definition: Virtex6.hpp:304
Header for the Virtex6 class.
Header for the DeviceDesignator class.
void testVirtex6FullMapping(const boost::filesystem::path &inWorkingPath)
std::string string
Header for Boost.Test helper functions.
static const char * sCommandName[eCommandCount]
Configuration command names.
Definition: Virtex6.hpp:118
VirtexFrame::word_t word_t
FrameSet word type.
Definition: FrameSet.hpp:85
static const DeviceVector & getVirtex6Devices(void)
Returns the Virtex6 devices.
Definition: Devices.hpp:193
Encapsulation of filesystem paths that are used by the library.
Header for the Devices class.
boost::filesystem::path path
EFarBlockType
Frame Address Register block type constants.
Definition: Virtex6.hpp:85
static const boost::filesystem::path & getWorkingPath(void)
Returns the absolute path to the working directory.
const WordSharedArray getWords(void) const
brief Returns the raw packet words, including the header word.
void testVirtex6PartialMapping(const boost::filesystem::path &inWorkingPath)
Header for the DDB class.
bool fileContentsAreEqual(const boost::filesystem::path &inA, const boost::filesystem::path &inB)
Compare the raw contents of two files to determine whether they are identical.
Bitstream packet for Virtex class architectures.
static uint32_t makeHeader(EPacketType inType, EOpcode inOpcode, uint32_t inAddress, uint32_t inCount)
Construct a packet header.
BOOST_AUTO_TEST_CASE(hexCharacterToDec)
std::vector< std::string > DeviceVector
Vector of device names.
Definition: Devices.hpp:119
virtual void read(std::istream &inStream, bool inCleanDateAndTime=true)
Read the bitstream header and packets from a stream.
static const boost::filesystem::path & getExecutablePath(void)
Returns the absolute path to the executable directory.
uint32_t getHeader(void) const
void testVirtex6Device(const std::string &inDeviceName, const boost::filesystem::path &inWorkingPath)