torc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
VirtexUnitTest.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 Virtex 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 
38 /// \brief Unit test for the Virtex class.
39 BOOST_AUTO_TEST_CASE(VirtexUnitTest) {
40 
41  // enums tested:
42  // EPacket
43  // EFar
44  boost::uint32_t mask;
45  // type 1 packet subfield masks
49  BOOST_CHECK_EQUAL(mask, 0xFFFFFFFFu);
50  // type 2 packet subfield masks
53  BOOST_CHECK_EQUAL(mask, 0xFFFFFFFFu);
54  // frame address register subfield masks
57  BOOST_CHECK_EQUAL(mask, 0x07FFFE00u);
58 
59  // members tested:
60  // Virtex::sPacketTypeName and EPacketTypeName
61  BOOST_CHECK_EQUAL(Virtex::sPacketTypeName[0], "[UNKNOWN TYPE 0]");
62  BOOST_CHECK_EQUAL(Virtex::sPacketTypeName[Virtex::ePacketType1], "TYPE1");
63  BOOST_CHECK_EQUAL(Virtex::sPacketTypeName[Virtex::ePacketType2], "TYPE2");
64  BOOST_CHECK_EQUAL(Virtex::sPacketTypeName[3], "[UNKNOWN TYPE 3]");
65  BOOST_CHECK_EQUAL(Virtex::sPacketTypeName[4], "[UNKNOWN TYPE 4]");
66  BOOST_CHECK_EQUAL(Virtex::sPacketTypeName[5], "[UNKNOWN TYPE 5]");
67  BOOST_CHECK_EQUAL(Virtex::sPacketTypeName[6], "[UNKNOWN TYPE 6]");
68  BOOST_CHECK_EQUAL(Virtex::sPacketTypeName[7], "[UNKNOWN TYPE 7]");
69 
70  // members tested:
71  // Virtex::sOpcodeName and EOpcode
72  BOOST_CHECK_EQUAL(Virtex::sOpcodeName[Virtex::eOpcodeRead], "READ");
73  BOOST_CHECK_EQUAL(Virtex::sOpcodeName[Virtex::eOpcodeWrite], "WRITE");
74 
75  // members tested:
76  // Virtex::sRegisterName and ERegister
77  BOOST_CHECK_EQUAL(Virtex::sRegisterName[Virtex::eRegisterCRC], "CRC");
78  BOOST_CHECK_EQUAL(Virtex::sRegisterName[Virtex::eRegisterFAR], "FAR");
79  BOOST_CHECK_EQUAL(Virtex::sRegisterName[Virtex::eRegisterFDRI], "FDRI");
80  BOOST_CHECK_EQUAL(Virtex::sRegisterName[Virtex::eRegisterFDRO], "FDRO");
81  BOOST_CHECK_EQUAL(Virtex::sRegisterName[Virtex::eRegisterCMD], "CMD");
82  BOOST_CHECK_EQUAL(Virtex::sRegisterName[Virtex::eRegisterCTL], "CTL");
83  BOOST_CHECK_EQUAL(Virtex::sRegisterName[Virtex::eRegisterMASK], "MASK");
84  BOOST_CHECK_EQUAL(Virtex::sRegisterName[Virtex::eRegisterSTAT], "STAT");
85  BOOST_CHECK_EQUAL(Virtex::sRegisterName[Virtex::eRegisterLOUT], "LOUT");
86  BOOST_CHECK_EQUAL(Virtex::sRegisterName[Virtex::eRegisterCOR], "COR");
87  BOOST_CHECK_EQUAL(Virtex::sRegisterName[Virtex::eRegisterFLR], "FLR");
88 
89  // members tested:
90  // Virtex::sCommandName and ECommand
91  BOOST_CHECK_EQUAL(Virtex::sCommandName[Virtex::eCommandWCFG], "WCFG");
92  BOOST_CHECK_EQUAL(Virtex::sCommandName[Virtex::eCommandLFRM], "LFRM");
93  BOOST_CHECK_EQUAL(Virtex::sCommandName[Virtex::eCommandRCFG], "RCFG");
94  BOOST_CHECK_EQUAL(Virtex::sCommandName[Virtex::eCommandSTART], "START");
95  BOOST_CHECK_EQUAL(Virtex::sCommandName[Virtex::eCommandRCAP], "RCAP");
96  BOOST_CHECK_EQUAL(Virtex::sCommandName[Virtex::eCommandRCRC], "RCRC");
97  BOOST_CHECK_EQUAL(Virtex::sCommandName[Virtex::eCommandAGHIGH], "AGHIGH");
98  BOOST_CHECK_EQUAL(Virtex::sCommandName[Virtex::eCommandSWITCH], "SWITCH");
99 
100 
101  // build the file paths
103  / "torc" / "bitstream" / "VirtexUnitTest.reference.bit";
105  / "regression" / "VirtexUnitTest.generated.bit";
106 
107  // read the bitstream
108  std::fstream fileStream(referencePath.string().c_str(), std::ios::binary | std::ios::in);
109  BOOST_REQUIRE(fileStream.good());
110  Virtex bitstream;
111  bitstream.read(fileStream, false);
112  // write the bitstream digest to the console
113  std::cout << bitstream << std::endl;
114 
115  std::string designName = bitstream.getDesignName();
116  std::string deviceName = bitstream.getDeviceName();
117  std::string designDate = bitstream.getDesignDate();
118  std::string designTime = bitstream.getDesignTime();
119  torc::common::DeviceDesignator deviceDesignator(deviceName);
120  std::cout << "family of " << deviceName << " is " << deviceDesignator.getFamily() << std::endl;
121 
122  // write the bitstream back out
123  std::fstream outputStream(generatedPath.string().c_str(), std::ios::binary | std::ios::out);
124  BOOST_REQUIRE(outputStream.good());
125  bitstream.write(outputStream);
126  outputStream.flush();
127 
128  // compare the reference and generated XDL
129  BOOST_CHECK(torc::common::fileContentsAreEqual(generatedPath, referencePath));
130 }
131 
132 
133 
134 
135 
136 
137 
138 
139 
140 
141 
142 
143 
144 
145 
146 
147 
148 
149 
150 
151 
152 
153 
154 
155 
156 
157 
158 
159 
160 
161 
162 
163 
164 
165 
166 
167 
168 
169 
170 
171 void testVirtexDevice(const std::string& inDeviceName, const boost::filesystem::path& inWorkingPath);
172 
173 /// \brief Unit test for the Virtex class Frame Address Register mapping.
174 BOOST_AUTO_TEST_CASE(VirtexFarUnitTest) {
175 
176  // look up the command line arguments
177  int& argc = boost::unit_test::framework::master_test_suite().argc;
178  char**& argv = boost::unit_test::framework::master_test_suite().argv;
179  // make sure that we at least have the name under which we were invoked
180  BOOST_REQUIRE(argc >= 1);
181  // resolve symbolic links if applicable
182  torc::common::DirectoryTree directoryTree(argv[0]);
183 
184  // iterate over the devices
186  torc::common::DeviceVector::const_iterator dp = devices.begin();
187  torc::common::DeviceVector::const_iterator de = devices.end();
188  while(dp < de) {
189  const std::string& device = *dp++;
190  if(device.empty()) break;
191 //std::cout << "device " << ": " << device << std::endl;
193  }
194 }
195 
196 /*
197  class TileTypeWidths {
198  public:
199  uint32_t mWidth[8];
200  TileTypeWidths(uint32_t in0 = 0, uint32_t in1 = 0, uint32_t in2 = 0, uint32_t in3 = 0,
201  uint32_t in4 = 0, uint32_t in5 = 0, uint32_t in6 = 0, uint32_t in7 = 0) {
202  int i = 0;
203  mWidth[i++] = in0; mWidth[i++] = in1; mWidth[i++] = in2; mWidth[i++] = in3;
204  mWidth[i++] = in4; mWidth[i++] = in5; mWidth[i++] = in6; mWidth[i++] = in7;
205  }
206  void clear(void) { for(int i = 0; i < 8; i++) mWidth[i] = 0; }
207  uint32_t operator[] (int inIndex) const { return mWidth[inIndex]; }
208  };
209 */
210 
211 void testVirtexDevice(const std::string& inDeviceName, const boost::filesystem::path& inWorkingPath) {
212 
213  // build the file paths
214  boost::filesystem::path debugBitstreamPath = inWorkingPath / "torc" / "bitstream" / "regression";
215  //boost::filesystem::path generatedPath = debugBitstreamPath / (inDeviceName + ".debug.bit");
216  boost::filesystem::path referencePath = debugBitstreamPath / (inDeviceName + ".debug.bit");
217 std::cerr << "TRYING TO FIND " << referencePath << std::endl;
218 
219  // read the bitstream
220  std::fstream fileStream(referencePath.string().c_str(), std::ios::binary | std::ios::in);
221  std::cerr << "Trying to read: " << referencePath << std::endl;
222  BOOST_REQUIRE(fileStream.good());
223  Virtex bitstream;
224  bitstream.read(fileStream, false);
225  // write the bitstream digest to the console
226 // std::cout << bitstream << std::endl;
227 
228 // // initialize the bitstream frame maps
229 // boost::filesystem::path deviceColumnsPath = inWorkingPath / "regression"
230 // / (inDeviceName + ".cpp");
231 // std::fstream deviceColumnsStream(deviceColumnsPath.string().c_str(), std::ios::out);
232  bitstream.initializeDeviceInfo(inDeviceName);
233  bitstream.initializeFrameMaps();
234 
235  // iterate through the packets, and extract all of the FARs
236  Virtex::FrameAddressToIndex farRemaining = bitstream.mFrameAddressToIndex;
237  Virtex::FrameAddressToIndex farVisited;
238  {
239  bool first = true;
240  Virtex::const_iterator p = bitstream.begin();
241  Virtex::const_iterator e = bitstream.end();
244  while(p < e) {
245  const VirtexPacket& packet = *p++;
246  if(packet.getHeader() != header) continue;
247  if(first) { first = false; continue; }
248  Virtex::FrameAddress far = packet[1];
249  //std::cout << std::endl << "Debug Far Address: " << Hex32(packet[1]) << std::endl;
250  farVisited[far] = 0;
251  Virtex::FrameAddressToIndex::iterator found = farRemaining.find(far);
252  if(found != farRemaining.end()) {
253  farRemaining.erase(found);
254  } else {
255  std::cerr << "missing " << far << " ";
256  }
257  }
258  }
259  // verify that we have visited all of the expected FARs and no others
260  std::cout << "Device: " << inDeviceName << std::endl;
261  std::cout << "Size of farRemaining: " << farRemaining.size() << std::endl;
262  std::cout << "Size of farVisited: " << farVisited.size() << std::endl;
263  BOOST_REQUIRE_EQUAL(bitstream.mFrameAddressToIndex.size(), farVisited.size());
264  BOOST_REQUIRE_EQUAL(farRemaining.size(), 0u);
265 
266 return;
267 /*
268  // iterate through the debug bitstream packets, and extract all of the FARs
269  // this isn't currently being used, but it may come in handy for debugging
270  for(int half = 0; half < 2; half++) {
271  for(uint32_t row = 0; row < 2; row++) {
272  typedef std::map<uint32_t, uint32_t> ColumnMaxFrame;
273  ColumnMaxFrame maxFrames[Virtex::eFarBlockTypeCount];
274  Virtex::const_iterator p = bitstream.begin();
275  Virtex::const_iterator e = bitstream.end();
276  uint32_t header = VirtexPacket::makeHeader(VirtexPacket::ePacketType1,
277  VirtexPacket::eOpcodeWrite, Virtex::eRegisterLOUT, 1);
278  while(p < e) {
279  const VirtexPacket& packet = *p++;
280  if(packet.getHeader() != header) continue;
281  Virtex::FrameAddress far = packet[1];
282 // uint32_t far = packet[1];
283 // std::cerr << Hex32(far) << " ";
284  if(far.mTopBottom == half && far.mRow == row) {
285 // std::cerr << far << " ";
286  ColumnMaxFrame::iterator i = maxFrames[far.mBlockType].find(far.mMajor);
287  if(i == maxFrames[far.mBlockType].end()) {
288  maxFrames[far.mBlockType][far.mMajor] = 0;
289  } else {
290  if(maxFrames[far.mBlockType][far.mMajor] < far.mMinor)
291  maxFrames[far.mBlockType][far.mMajor] = far.mMinor;
292  }
293  }
294  }
295  std::cerr << std::endl;
296  uint32_t frameCount = 0;
297  for(uint32_t i = 0; i < Virtex::eFarBlockTypeCount; i++) {
298  Virtex::EFarBlockType blockType = Virtex::EFarBlockType(i);
299  uint32_t majorCount = maxFrames[blockType].size();
300  for(uint32_t major = 0; major < majorCount; major++) {
301  frameCount += maxFrames[blockType][major] + 1;
302  std::cerr << blockType << "(" << major << "): "
303  << (maxFrames[blockType][major] + 1) << " (" << frameCount << ")"
304  << std::endl;
305  }
306  }
307  }
308  }
309 
310 */
311 }
312 
313 void testVirtexFullMapping(const boost::filesystem::path& inWorkingPath);
314 
315 /// \brief Unit test for the Virtex bitstream to bitmap conversion.
316 BOOST_AUTO_TEST_CASE(VirtexMapUnitTest) {
317  // look up the command line arguments
318  int& argc = boost::unit_test::framework::master_test_suite().argc;
319  char**& argv = boost::unit_test::framework::master_test_suite().argv;
320  // make sure that we at least have the name under which we were invoked
321  BOOST_REQUIRE(argc >= 1);
322  // resolve symbolic links if applicable
323  torc::common::DirectoryTree directoryTree(argv[0]);
325 }
326 
327 
328 void testVirtexFullMapping(const boost::filesystem::path& inWorkingPath) {
329  // build the file paths
331  / "torc" / "bitstream" / "VirtexUnitTest.reference.bit";
333  / "regression" / "VirtexMapUnitTest.generated.bit";
334 
335  // read the bitstream
336  std::fstream fileStream(referencePath.string().c_str(), std::ios::binary | std::ios::in);
337  BOOST_REQUIRE(fileStream.good());
338  // read and gather bitstream frames
339  Virtex bitstream;
340  bitstream.read(fileStream, false);
341 
342  // initialize frame map
343  bitstream.initializeDeviceInfo("xcv50");
344  bitstream.initializeFrameMaps();
345 
346  // load bitstream frames in data structure
347  bitstream.initializeFullFrameBlocks();
348 
349  // write full bitstream from frame blocks data structure
350  uint32_t frameLength = bitstream.getFrameLength();
351  typedef boost::shared_array<uint32_t> WordSharedArray;
352  Virtex::iterator p = bitstream.begin();
353  Virtex::iterator e = bitstream.end();
354  while(p < e) {
355  const VirtexPacket& packet = *p++;
356  if(packet.isType2()) {
357  WordSharedArray words = packet.getWords();
358  uint32_t* ptr = words.get();
359  for(uint32_t block = 0; block < 8; block++) {
360  for(uint32_t frame = 0; frame < bitstream.mBlockFrameIndexBounds[block]; frame++) {
361  VirtexFrameBlocks::word_t* words = const_cast<VirtexFrameBlocks::word_t*>(bitstream.mFrameBlocks.mBlock[block][frame]->getWords());
362  for(uint32_t index = 0; index < frameLength; index++) {
363  *ptr++ = words[index];
364  }
365  }
366  }
367  }
368  }
369  // write the test bitstream back out
370  std::fstream outputStream(generatedPath.string().c_str(), std::ios::binary | std::ios::out);
371  BOOST_REQUIRE(outputStream.good());
372  bitstream.write(outputStream);
373  outputStream.flush();
374  BOOST_REQUIRE(torc::common::fileContentsAreEqual(referencePath, generatedPath));
375 
376  return;
377 }
378 
379 BOOST_AUTO_TEST_SUITE_END()
380 
381 } // namespace bitstream
382 } // namespace torc
Header for torc::bitstream output stream helpers.
Encapsulation of a device designator and its constituent elements.
Header for the DeviceInfoHelper class.
std::map< Virtex::FrameAddress, uint32_t > FrameAddressToIndex
Map from frame address to frame index.
Definition: Virtex.hpp:204
const EFamily & getFamily(void) const
Returns the device family.
Header for the DirectoryTree class.
static const char * sOpcodeName[eOpcodeCount]
Packet opcode names.
Definition: Virtex.hpp:87
Header for the DeviceDesignator class.
static const char * sRegisterName[eRegisterCount]
Configuration register names.
Definition: Virtex.hpp:89
std::string string
Header for Boost.Test helper functions.
VirtexFrame::word_t word_t
FrameSet word type.
Definition: FrameSet.hpp:85
Encapsulation of filesystem paths that are used by the library.
Header for the Devices class.
boost::filesystem::path path
Header for the Virtex class.
void testVirtexFullMapping(const boost::filesystem::path &inWorkingPath)
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.
Virtex bitstream.
Definition: Virtex.hpp:40
static const char * sPacketTypeName[ePacketTypeCount]
Packet type names.
Definition: Virtex.hpp:85
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 const DeviceVector & getVirtexDevices(void)
Returns the Virtex devices.
Definition: Devices.hpp:181
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 char * sCommandName[eCommandCount]
Configuration command names.
Definition: Virtex.hpp:91
static const boost::filesystem::path & getExecutablePath(void)
Returns the absolute path to the executable directory.
uint32_t getHeader(void) const
void testVirtexDevice(const std::string &inDeviceName, const boost::filesystem::path &inWorkingPath)