torc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Virtex4UnitTest.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 Virtex4 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 Virtex4 class.
38 BOOST_AUTO_TEST_CASE(Virtex4UnitTest) {
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, 0x007FFFFFu);
57 
58  // members tested:
59  // Virtex4::sPacketTypeName and EPacketTypeName
60  BOOST_CHECK_EQUAL(Virtex4::sPacketTypeName[0], "[UNKNOWN TYPE 0]");
61  BOOST_CHECK_EQUAL(Virtex4::sPacketTypeName[Virtex4::ePacketType1], "TYPE1");
62  BOOST_CHECK_EQUAL(Virtex4::sPacketTypeName[Virtex4::ePacketType2], "TYPE2");
63  BOOST_CHECK_EQUAL(Virtex4::sPacketTypeName[3], "[UNKNOWN TYPE 3]");
64  BOOST_CHECK_EQUAL(Virtex4::sPacketTypeName[4], "[UNKNOWN TYPE 4]");
65  BOOST_CHECK_EQUAL(Virtex4::sPacketTypeName[5], "[UNKNOWN TYPE 5]");
66  BOOST_CHECK_EQUAL(Virtex4::sPacketTypeName[6], "[UNKNOWN TYPE 6]");
67  BOOST_CHECK_EQUAL(Virtex4::sPacketTypeName[7], "[UNKNOWN TYPE 7]");
68 
69  // members tested:
70  // Virtex4::sOpcodeName and EOpcode
71  BOOST_CHECK_EQUAL(Virtex4::sOpcodeName[Virtex4::eOpcodeNOP], "NOP");
72  BOOST_CHECK_EQUAL(Virtex4::sOpcodeName[Virtex4::eOpcodeRead], "READ");
73  BOOST_CHECK_EQUAL(Virtex4::sOpcodeName[Virtex4::eOpcodeWrite], "WRITE");
74  BOOST_CHECK_EQUAL(Virtex4::sOpcodeName[Virtex4::eOpcodeReserved], "RESERVED");
75 
76  // members tested:
77  // Virtex4::sRegisterName and ERegister
78  BOOST_CHECK_EQUAL(Virtex4::sRegisterName[Virtex4::eRegisterCRC], "CRC");
79  BOOST_CHECK_EQUAL(Virtex4::sRegisterName[Virtex4::eRegisterFAR], "FAR");
80  BOOST_CHECK_EQUAL(Virtex4::sRegisterName[Virtex4::eRegisterFDRI], "FDRI");
81  BOOST_CHECK_EQUAL(Virtex4::sRegisterName[Virtex4::eRegisterFDRO], "FDRO");
82  BOOST_CHECK_EQUAL(Virtex4::sRegisterName[Virtex4::eRegisterCMD], "CMD");
83  BOOST_CHECK_EQUAL(Virtex4::sRegisterName[Virtex4::eRegisterCTL], "CTL");
84  BOOST_CHECK_EQUAL(Virtex4::sRegisterName[Virtex4::eRegisterMASK], "MASK");
85  BOOST_CHECK_EQUAL(Virtex4::sRegisterName[Virtex4::eRegisterSTAT], "STAT");
86  BOOST_CHECK_EQUAL(Virtex4::sRegisterName[Virtex4::eRegisterLOUT], "LOUT");
87  BOOST_CHECK_EQUAL(Virtex4::sRegisterName[Virtex4::eRegisterCOR], "COR");
88  BOOST_CHECK_EQUAL(Virtex4::sRegisterName[Virtex4::eRegisterMFWR], "MFWR");
89  BOOST_CHECK_EQUAL(Virtex4::sRegisterName[Virtex4::eRegisterCBC], "CBC");
90  BOOST_CHECK_EQUAL(Virtex4::sRegisterName[Virtex4::eRegisterIDCODE], "IDCODE");
91  BOOST_CHECK_EQUAL(Virtex4::sRegisterName[Virtex4::eRegisterAXSS], "AXSS");
92 
93  // members tested:
94  // Virtex4::sCommandName and ECommand
95  BOOST_CHECK_EQUAL(Virtex4::sCommandName[Virtex4::eCommandNULL], "NULL");
96  BOOST_CHECK_EQUAL(Virtex4::sCommandName[Virtex4::eCommandWCFG], "WCFG");
97  BOOST_CHECK_EQUAL(Virtex4::sCommandName[Virtex4::eCommandMFWR], "MFWR");
98  BOOST_CHECK_EQUAL(Virtex4::sCommandName[Virtex4::eCommandLFRM], "LFRM");
99  BOOST_CHECK_EQUAL(Virtex4::sCommandName[Virtex4::eCommandRCFG], "RCFG");
100  BOOST_CHECK_EQUAL(Virtex4::sCommandName[Virtex4::eCommandSTART], "START");
101  BOOST_CHECK_EQUAL(Virtex4::sCommandName[Virtex4::eCommandRCAP], "RCAP");
102  BOOST_CHECK_EQUAL(Virtex4::sCommandName[Virtex4::eCommandRCRC], "RCRC");
103  BOOST_CHECK_EQUAL(Virtex4::sCommandName[Virtex4::eCommandAGHIGH], "AGHIGH");
104  BOOST_CHECK_EQUAL(Virtex4::sCommandName[Virtex4::eCommandSWITCH], "SWITCH");
105  BOOST_CHECK_EQUAL(Virtex4::sCommandName[Virtex4::eCommandGRESTORE], "GRESTORE");
106  BOOST_CHECK_EQUAL(Virtex4::sCommandName[Virtex4::eCommandSHUTDOWN], "SHUTDOWN");
107  BOOST_CHECK_EQUAL(Virtex4::sCommandName[Virtex4::eCommandGCAPTURE], "GCAPTURE");
108  BOOST_CHECK_EQUAL(Virtex4::sCommandName[Virtex4::eCommandDESYNC], "DESYNC");
109 
110  // verify conversion to and from FrameAddress objects
111  uint32_t u1 = 0xffffffff & mask;
112  BOOST_CHECK_EQUAL(uint32_t(Virtex4::FrameAddress(u1)), u1);
113  uint32_t u2 = 0xffff0000 & mask;
114  BOOST_CHECK_EQUAL(uint32_t(Virtex4::FrameAddress(u2)), u2);
115  uint32_t u3 = 0xff00ff00 & mask;
116  BOOST_CHECK_EQUAL(uint32_t(Virtex4::FrameAddress(u3)), u3);
117  uint32_t u4 = 0xf0f0f0f0 & mask;
118  BOOST_CHECK_EQUAL(uint32_t(Virtex4::FrameAddress(u4)), u4);
119  uint32_t u5 = 0xcccccccc & mask;
120  BOOST_CHECK_EQUAL(uint32_t(Virtex4::FrameAddress(u5)), u5);
121  uint32_t u6 = 0xaaaaaaaa & mask;
122  BOOST_CHECK_EQUAL(uint32_t(Virtex4::FrameAddress(u6)), u6);
123 
124  // build the file paths
126  / "torc" / "bitstream" / "Virtex4UnitTest.reference.bit";
128  / "regression" / "Virtex4UnitTest.generated.bit";
129 
130  // read the bitstream
131  std::fstream fileStream(referencePath.string().c_str(), std::ios::binary | std::ios::in);
132  BOOST_REQUIRE(fileStream.good());
133  Virtex4 bitstream;
134  bitstream.read(fileStream, false);
135  // write the bitstream digest to the console
136  std::cout << bitstream << std::endl;
137 
138  std::string designName = bitstream.getDesignName();
139  std::string deviceName = bitstream.getDeviceName();
140  std::string designDate = bitstream.getDesignDate();
141  std::string designTime = bitstream.getDesignTime();
142  torc::common::DeviceDesignator deviceDesignator(deviceName);
143  std::cout << "family of " << deviceName << " is " << deviceDesignator.getFamily() << std::endl;
144 
145  // write the bitstream back out
146  std::fstream outputStream(generatedPath.string().c_str(), std::ios::binary | std::ios::out);
147  BOOST_REQUIRE(outputStream.good());
148  bitstream.write(outputStream);
149  outputStream.flush();
150 
151  // compare the reference and generated XDL
152  BOOST_CHECK(torc::common::fileContentsAreEqual(generatedPath, referencePath));
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 
192 
193 
194 void testVirtex4Device(const std::string& inDeviceName, const boost::filesystem::path& inWorkingPath);
195 
196 /// \brief Unit test for the Virtex4 class Frame Address Register mapping.
197 BOOST_AUTO_TEST_CASE(Virtex4FarUnitTest) {
198 
199  // look up the command line arguments
200  int& argc = boost::unit_test::framework::master_test_suite().argc;
201  char**& argv = boost::unit_test::framework::master_test_suite().argv;
202  // make sure that we at least have the name under which we were invoked
203  BOOST_REQUIRE(argc >= 1);
204  // resolve symbolic links if applicable
205  torc::common::DirectoryTree directoryTree(argv[0]);
206 
207  // iterate over the devices
209  torc::common::DeviceVector::const_iterator dp = devices.begin();
210  torc::common::DeviceVector::const_iterator de = devices.end();
211  while(dp < de) {
212  const std::string& device = *dp++;
213  if(device.empty()) break;
214 //std::cout << "device " << ": " << device << std::endl;
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 testVirtex4Device(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 std::cerr << "TRYING TO FIND " << referencePath << std::endl;
241 
242  // read the bitstream
243  std::fstream fileStream(referencePath.string().c_str(), std::ios::binary | std::ios::in);
244  std::cerr << "Trying to read: " << referencePath << std::endl;
245  BOOST_REQUIRE(fileStream.good());
246  Virtex4 bitstream;
247  bitstream.read(fileStream, false);
248  // write the bitstream digest to the console
249 // std::cout << bitstream << std::endl;
250 
251 // // initialize the bitstream frame maps
252 // boost::filesystem::path deviceColumnsPath = inWorkingPath / "regression"
253 // / (inDeviceName + ".cpp");
254 // std::fstream deviceColumnsStream(deviceColumnsPath.string().c_str(), std::ios::out);
255  bitstream.initializeDeviceInfo(inDeviceName);
256  bitstream.initializeFrameMaps();
257 
258  // iterate through the packets, and extract all of the FARs
259  Virtex4::FrameAddressToIndex farRemaining = bitstream.mFrameAddressToIndex;
260  Virtex4::FrameAddressToIndex farVisited;
261  {
262  bool first = true;
263  Virtex4::const_iterator p = bitstream.begin();
264  Virtex4::const_iterator e = bitstream.end();
267  while(p < e) {
268  const VirtexPacket& packet = *p++;
269  if(packet.getHeader() != header) continue;
270  if(first) { first = false; continue; }
271  Virtex4::FrameAddress far = packet[1];
272  farVisited[far] = 0;
273  Virtex4::FrameAddressToIndex::iterator found = farRemaining.find(far);
274  if(found != farRemaining.end()) {
275  farRemaining.erase(found);
276  } else {
277  std::cerr << "missing " << far << " ";
278  }
279  }
280  }
281  // verify that we have visited all of the expected FARs and no others
282  std::cout << "Device: " << inDeviceName << std::endl;
283  std::cout << "Size of farRemaining: " << farRemaining.size() << std::endl;
284  std::cout << "Size of farVisited: " << farVisited.size() << std::endl;
285  BOOST_REQUIRE_EQUAL(bitstream.mFrameAddressToIndex.size(), farVisited.size());
286  BOOST_REQUIRE_EQUAL(farRemaining.size(), 0u);
287 
288 return;
289 
290  // iterate through the debug bitstream packets, and extract all of the FARs
291  // this isn't currently being used, but it may come in handy for debugging
292  for(int half = 0; half < 2; half++) {
293  for(uint32_t row = 0; row < 2; row++) {
294  typedef std::map<uint32_t, uint32_t> ColumnMaxFrame;
295  ColumnMaxFrame maxFrames[Virtex4::eFarBlockTypeCount];
296  Virtex4::const_iterator p = bitstream.begin();
297  Virtex4::const_iterator e = bitstream.end();
300  while(p < e) {
301  const VirtexPacket& packet = *p++;
302  if(packet.getHeader() != header) continue;
303  Virtex4::FrameAddress far = packet[1];
304 // uint32_t far = packet[1];
305 // std::cerr << Hex32(far) << " ";
306  if(far.mTopBottom == half && far.mRow == row) {
307 // std::cerr << far << " ";
308  ColumnMaxFrame::iterator i = maxFrames[far.mBlockType].find(far.mMajor);
309  if(i == maxFrames[far.mBlockType].end()) {
310  maxFrames[far.mBlockType][far.mMajor] = 0;
311  } else {
312  if(maxFrames[far.mBlockType][far.mMajor] < far.mMinor)
313  maxFrames[far.mBlockType][far.mMajor] = far.mMinor;
314  }
315  }
316  }
317  std::cerr << std::endl;
318  uint32_t frameCount = 0;
319  for(uint32_t i = 0; i < Virtex4::eFarBlockTypeCount; i++) {
321  uint32_t majorCount = maxFrames[blockType].size();
322  for(uint32_t major = 0; major < majorCount; major++) {
323  frameCount += maxFrames[blockType][major] + 1;
324  std::cerr << blockType << "(" << major << "): "
325  << (maxFrames[blockType][major] + 1) << " (" << frameCount << ")"
326  << std::endl;
327  }
328  }
329  }
330  }
331 
332 }
333 
334 void testVirtex4FullMapping(const boost::filesystem::path& inWorkingPath);
335 void testVirtex4PartialMapping(const boost::filesystem::path& inWorkingPath);
336 
337 /// \brief Unit test for the Virtex4 bitstream to bitmap conversion.
338 BOOST_AUTO_TEST_CASE(Virtex4MapUnitTest) {
339  // look up the command line arguments
340  int& argc = boost::unit_test::framework::master_test_suite().argc;
341  char**& argv = boost::unit_test::framework::master_test_suite().argv;
342  // make sure that we at least have the name under which we were invoked
343  BOOST_REQUIRE(argc >= 1);
344  // resolve symbolic links if applicable
345  torc::common::DirectoryTree directoryTree(argv[0]);
347  //testVirtex4PartialMapping(torc::common::DirectoryTree::getWorkingPath());
348 }
349 
350 
352  // build the file paths
354  / "torc" / "bitstream" / "Virtex4UnitTest.reference.bit";
356  / "regression" / "Virtex4MapUnitTest.generated.bit";
357 
358  // read the bitstream
359  std::fstream fileStream(referencePath.string().c_str(), std::ios::binary | std::ios::in);
360  BOOST_REQUIRE(fileStream.good());
361  // read and gather bitstream frames
362  Virtex4 bitstream;
363  bitstream.read(fileStream, false);
364 
365  // initialize frame map
366  bitstream.initializeDeviceInfo("xc4vlx15");
367  bitstream.initializeFrameMaps();
368 
369  // load bitstream frames in data structure
370  bitstream.readFramePackets();
371 
372  // write full bitstream from frame blocks data structure
373  uint32_t frameLength = bitstream.getFrameLength();
374  typedef boost::shared_array<uint32_t> WordSharedArray;
375  Virtex4::iterator p = bitstream.begin();
376  Virtex4::iterator e = bitstream.end();
377  while(p < e) {
378  const VirtexPacket& packet = *p++;
379  if(packet.isType2()) {
380  WordSharedArray words = packet.getWords();
381  uint32_t* ptr = words.get();
382  for(uint32_t block = 0; block < 8; block++) {
383  for(uint32_t frame = 0; frame < bitstream.mBlockFrameIndexBounds[block]; frame++) {
384  VirtexFrameBlocks::word_t* words = const_cast<VirtexFrameBlocks::word_t*>(bitstream.mFrameBlocks.mBlock[block][frame]->getWords());
385  for(uint32_t index = 0; index < frameLength; index++) {
386  *ptr++ = words[index];
387  }
388  }
389  }
390  }
391  }
392  // write the test bitstream back out
393  std::fstream outputStream(generatedPath.string().c_str(), std::ios::binary | std::ios::out);
394  BOOST_REQUIRE(outputStream.good());
395  bitstream.write(outputStream);
396  outputStream.flush();
397  BOOST_REQUIRE(torc::common::fileContentsAreEqual(referencePath, generatedPath));
398 
399  return;
400 }
401 
402 BOOST_AUTO_TEST_SUITE_END()
403 
404 } // namespace bitstream
405 } // namespace torc
Header for torc::bitstream output stream helpers.
static const char * sOpcodeName[eOpcodeCount]
Packet opcode names.
Definition: Virtex4.hpp:101
Encapsulation of a device designator and its constituent elements.
Header for the Virtex4 class.
Header for the DeviceInfoHelper class.
const EFamily & getFamily(void) const
Returns the device family.
Header for the DirectoryTree class.
Header for the DeviceDesignator class.
static const char * sPacketTypeName[ePacketTypeCount]
Packet type names.
Definition: Virtex4.hpp:99
std::map< Virtex4::FrameAddress, uint32_t > FrameAddressToIndex
Map from frame address to frame index.
Definition: Virtex4.hpp:265
static const char * sCommandName[eCommandCount]
Configuration command names.
Definition: Virtex4.hpp:105
std::string string
Header for Boost.Test helper functions.
static const char * sRegisterName[eRegisterCount]
Configuration register names.
Definition: Virtex4.hpp:103
VirtexFrame::word_t word_t
FrameSet word type.
Definition: FrameSet.hpp:85
EFarBlockType
Frame Address Register block type constants.
Definition: Virtex4.hpp:79
Encapsulation of filesystem paths that are used by the library.
static const DeviceVector & getVirtex4Devices(void)
Returns the Virtex4 devices.
Definition: Devices.hpp:189
Header for the Devices class.
boost::filesystem::path path
void testVirtex4PartialMapping(const boost::filesystem::path &inWorkingPath)
Virtex4 bitstream.
Definition: Virtex4.hpp:40
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.
Header for the DDB class.
void testVirtex4FullMapping(const boost::filesystem::path &inWorkingPath)
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.
void testVirtex4Device(const std::string &inDeviceName, const boost::filesystem::path &inWorkingPath)
static const boost::filesystem::path & getExecutablePath(void)
Returns the absolute path to the executable directory.
uint32_t getHeader(void) const