torc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
VirtexEUnitTest.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 VirtexE 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 VirtexE class.
39 BOOST_AUTO_TEST_CASE(VirtexEUnitTest) {
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  // VirtexE::sPacketTypeName and EPacketTypeName
61  BOOST_CHECK_EQUAL(VirtexE::sPacketTypeName[0], "[UNKNOWN TYPE 0]");
62  BOOST_CHECK_EQUAL(VirtexE::sPacketTypeName[VirtexE::ePacketType1], "TYPE1");
63  BOOST_CHECK_EQUAL(VirtexE::sPacketTypeName[VirtexE::ePacketType2], "TYPE2");
64  BOOST_CHECK_EQUAL(VirtexE::sPacketTypeName[3], "[UNKNOWN TYPE 3]");
65  BOOST_CHECK_EQUAL(VirtexE::sPacketTypeName[4], "[UNKNOWN TYPE 4]");
66  BOOST_CHECK_EQUAL(VirtexE::sPacketTypeName[5], "[UNKNOWN TYPE 5]");
67  BOOST_CHECK_EQUAL(VirtexE::sPacketTypeName[6], "[UNKNOWN TYPE 6]");
68  BOOST_CHECK_EQUAL(VirtexE::sPacketTypeName[7], "[UNKNOWN TYPE 7]");
69 
70  // members tested:
71  // VirtexE::sOpcodeName and EOpcode
72  BOOST_CHECK_EQUAL(VirtexE::sOpcodeName[VirtexE::eOpcodeRead], "READ");
73  BOOST_CHECK_EQUAL(VirtexE::sOpcodeName[VirtexE::eOpcodeWrite], "WRITE");
74 
75  // members tested:
76  // VirtexE::sRegisterName and ERegister
77  BOOST_CHECK_EQUAL(VirtexE::sRegisterName[VirtexE::eRegisterCRC], "CRC");
78  BOOST_CHECK_EQUAL(VirtexE::sRegisterName[VirtexE::eRegisterFAR], "FAR");
79  BOOST_CHECK_EQUAL(VirtexE::sRegisterName[VirtexE::eRegisterFDRI], "FDRI");
80  BOOST_CHECK_EQUAL(VirtexE::sRegisterName[VirtexE::eRegisterFDRO], "FDRO");
81  BOOST_CHECK_EQUAL(VirtexE::sRegisterName[VirtexE::eRegisterCMD], "CMD");
82  BOOST_CHECK_EQUAL(VirtexE::sRegisterName[VirtexE::eRegisterCTL], "CTL");
83  BOOST_CHECK_EQUAL(VirtexE::sRegisterName[VirtexE::eRegisterMASK], "MASK");
84  BOOST_CHECK_EQUAL(VirtexE::sRegisterName[VirtexE::eRegisterSTAT], "STAT");
85  BOOST_CHECK_EQUAL(VirtexE::sRegisterName[VirtexE::eRegisterLOUT], "LOUT");
86  BOOST_CHECK_EQUAL(VirtexE::sRegisterName[VirtexE::eRegisterCOR], "COR");
87  BOOST_CHECK_EQUAL(VirtexE::sRegisterName[VirtexE::eRegisterFLR], "FLR");
88 
89  // members tested:
90  // VirtexE::sCommandName and ECommand
91  BOOST_CHECK_EQUAL(VirtexE::sCommandName[VirtexE::eCommandWCFG], "WCFG");
92  BOOST_CHECK_EQUAL(VirtexE::sCommandName[VirtexE::eCommandLFRM], "LFRM");
93  BOOST_CHECK_EQUAL(VirtexE::sCommandName[VirtexE::eCommandRCFG], "RCFG");
94  BOOST_CHECK_EQUAL(VirtexE::sCommandName[VirtexE::eCommandSTART], "START");
95  BOOST_CHECK_EQUAL(VirtexE::sCommandName[VirtexE::eCommandRCAP], "RCAP");
96  BOOST_CHECK_EQUAL(VirtexE::sCommandName[VirtexE::eCommandRCRC], "RCRC");
97  BOOST_CHECK_EQUAL(VirtexE::sCommandName[VirtexE::eCommandAGHIGH], "AGHIGH");
98  BOOST_CHECK_EQUAL(VirtexE::sCommandName[VirtexE::eCommandSWITCH], "SWITCH");
99 
100  // build the file paths
102  / "torc" / "bitstream" / "VirtexEUnitTest.reference.bit";
104  / "regression" / "VirtexEUnitTest.generated.bit";
105 
106  // read the bitstream
107  std::fstream fileStream(referencePath.string().c_str(), std::ios::binary | std::ios::in);
108  BOOST_REQUIRE(fileStream.good());
109  VirtexE bitstream;
110  bitstream.read(fileStream, false);
111  // write the bitstream digest to the console
112  std::cout << bitstream << std::endl;
113 
114  std::string designName = bitstream.getDesignName();
115  std::string deviceName = bitstream.getDeviceName();
116  std::string designDate = bitstream.getDesignDate();
117  std::string designTime = bitstream.getDesignTime();
118  torc::common::DeviceDesignator deviceDesignator(deviceName);
119  std::cout << "family of " << deviceName << " is " << deviceDesignator.getFamily() << std::endl;
120 
121  // write the bitstream back out
122  std::fstream outputStream(generatedPath.string().c_str(), std::ios::binary | std::ios::out);
123  BOOST_REQUIRE(outputStream.good());
124  bitstream.write(outputStream);
125  outputStream.flush();
126 
127  // compare the reference and generated XDL
128  BOOST_CHECK(torc::common::fileContentsAreEqual(generatedPath, referencePath));
129 }
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 void testVirtexEDevice(const std::string& inDeviceName, const boost::filesystem::path& inWorkingPath);
171 
172 /// \brief Unit test for the VirtexE class Frame Address Register mapping.
173 BOOST_AUTO_TEST_CASE(VirtexEFarUnitTest) {
174 
175  // look up the command line arguments
176  int& argc = boost::unit_test::framework::master_test_suite().argc;
177  char**& argv = boost::unit_test::framework::master_test_suite().argv;
178  // make sure that we at least have the name under which we were invoked
179  BOOST_REQUIRE(argc >= 1);
180  // resolve symbolic links if applicable
181  torc::common::DirectoryTree directoryTree(argv[0]);
182 
183  // iterate over the devices
185  torc::common::DeviceVector::const_iterator dp = devices.begin();
186  torc::common::DeviceVector::const_iterator de = devices.end();
187  while(dp < de) {
188  const std::string& device = *dp++;
189  if(device.empty()) break;
190 //std::cout << "device " << ": " << device << std::endl;
192  }
193 }
194 
195 /*
196  class TileTypeWidths {
197  public:
198  uint32_t mWidth[8];
199  TileTypeWidths(uint32_t in0 = 0, uint32_t in1 = 0, uint32_t in2 = 0, uint32_t in3 = 0,
200  uint32_t in4 = 0, uint32_t in5 = 0, uint32_t in6 = 0, uint32_t in7 = 0) {
201  int i = 0;
202  mWidth[i++] = in0; mWidth[i++] = in1; mWidth[i++] = in2; mWidth[i++] = in3;
203  mWidth[i++] = in4; mWidth[i++] = in5; mWidth[i++] = in6; mWidth[i++] = in7;
204  }
205  void clear(void) { for(int i = 0; i < 8; i++) mWidth[i] = 0; }
206  uint32_t operator[] (int inIndex) const { return mWidth[inIndex]; }
207  };
208 */
209 
210 void testVirtexEDevice(const std::string& inDeviceName, const boost::filesystem::path& inWorkingPath) {
211 
212  // build the file paths
213  boost::filesystem::path debugBitstreamPath = inWorkingPath / "torc" / "bitstream" / "regression";
214  //boost::filesystem::path generatedPath = debugBitstreamPath / (inDeviceName + ".debug.bit");
215  boost::filesystem::path referencePath = debugBitstreamPath / (inDeviceName + ".debug.bit");
216 std::cerr << "TRYING TO FIND " << referencePath << std::endl;
217 
218  // read the bitstream
219  std::fstream fileStream(referencePath.string().c_str(), std::ios::binary | std::ios::in);
220  std::cerr << "Trying to read: " << referencePath << std::endl;
221  BOOST_REQUIRE(fileStream.good());
222  VirtexE bitstream;
223  bitstream.read(fileStream, false);
224  // write the bitstream digest to the console
225 // std::cout << bitstream << std::endl;
226 
227 // // initialize the bitstream frame maps
228 // boost::filesystem::path deviceColumnsPath = inWorkingPath / "regression"
229 // / (inDeviceName + ".cpp");
230 // std::fstream deviceColumnsStream(deviceColumnsPath.string().c_str(), std::ios::out);
231  bitstream.initializeDeviceInfo(inDeviceName);
232  bitstream.initializeFrameMaps();
233 
234  // iterate through the packets, and extract all of the FARs
235  VirtexE::FrameAddressToIndex farRemaining = bitstream.mFrameAddressToIndex;
236  VirtexE::FrameAddressToIndex farVisited;
237  {
238  bool first = true;
239  VirtexE::const_iterator p = bitstream.begin();
240  VirtexE::const_iterator e = bitstream.end();
243  while(p < e) {
244  const VirtexPacket& packet = *p++;
245  if(packet.getHeader() != header) continue;
246  if(first) { first = false; continue; }
247  VirtexE::FrameAddress far = packet[1];
248  //std::cout << std::endl << "Debug Far Address: " << Hex32(packet[1]) << std::endl;
249  farVisited[far] = 0;
250  VirtexE::FrameAddressToIndex::iterator found = farRemaining.find(far);
251  if(found != farRemaining.end()) {
252  farRemaining.erase(found);
253  } else {
254  std::cerr << "missing " << far << " ";
255  }
256  }
257  }
258  // verify that we have visited all of the expected FARs and no others
259  std::cout << "Device: " << inDeviceName << std::endl;
260  std::cout << "Size of farRemaining: " << farRemaining.size() << std::endl;
261  std::cout << "Size of farVisited: " << farVisited.size() << std::endl;
262  BOOST_REQUIRE_EQUAL(bitstream.mFrameAddressToIndex.size(), farVisited.size());
263  BOOST_REQUIRE_EQUAL(farRemaining.size(), 0u);
264 
265 return;
266 }
267 
268 void testVirtexEFullMapping(const boost::filesystem::path& inWorkingPath);
269 
270 /// \brief Unit test for the VirtexE bitstream to bitmap conversion.
271 BOOST_AUTO_TEST_CASE(VirtexEMapUnitTest) {
272  // look up the command line arguments
273  int& argc = boost::unit_test::framework::master_test_suite().argc;
274  char**& argv = boost::unit_test::framework::master_test_suite().argv;
275  // make sure that we at least have the name under which we were invoked
276  BOOST_REQUIRE(argc >= 1);
277  // resolve symbolic links if applicable
278  torc::common::DirectoryTree directoryTree(argv[0]);
280 }
281 
282 
284  // build the file paths
286  / "torc" / "bitstream" / "VirtexEUnitTest.reference.bit";
288  / "regression" / "VirtexEMapUnitTest.generated.bit";
289 
290  // read the bitstream
291  std::fstream fileStream(referencePath.string().c_str(), std::ios::binary | std::ios::in);
292  BOOST_REQUIRE(fileStream.good());
293  // read and gather bitstream frames
294  VirtexE bitstream;
295  bitstream.read(fileStream, false);
296 
297  // initialize frame map
298  bitstream.initializeDeviceInfo("xcv50e");
299  bitstream.initializeFrameMaps();
300 
301  // load bitstream frames in data structure
302  bitstream.initializeFullFrameBlocks();
303 
304  // write full bitstream from frame blocks data structure
305  uint32_t frameLength = bitstream.getFrameLength();
306  typedef boost::shared_array<uint32_t> WordSharedArray;
307  VirtexE::iterator p = bitstream.begin();
308  VirtexE::iterator e = bitstream.end();
309  while(p < e) {
310  const VirtexPacket& packet = *p++;
311  if(packet.isType2()) {
312  WordSharedArray words = packet.getWords();
313  uint32_t* ptr = words.get();
314  for(uint32_t block = 0; block < 8; block++) {
315  for(uint32_t frame = 0; frame < bitstream.mBlockFrameIndexBounds[block]; frame++) {
316  VirtexFrameBlocks::word_t* words = const_cast<VirtexFrameBlocks::word_t*>(bitstream.mFrameBlocks.mBlock[block][frame]->getWords());
317  for(uint32_t index = 0; index < frameLength; index++) {
318  *ptr++ = words[index];
319  }
320  }
321  // only block type 0 is present in this particular bitstream
322  // if we try to copy block type 1 frames into the packet, we will trash memory
323  break;
324  }
325  }
326  }
327  // write the test bitstream back out
328  std::fstream outputStream(generatedPath.string().c_str(), std::ios::binary | std::ios::out);
329  BOOST_REQUIRE(outputStream.good());
330  bitstream.write(outputStream);
331  outputStream.flush();
332  BOOST_REQUIRE(torc::common::fileContentsAreEqual(referencePath, generatedPath));
333 
334  return;
335 }
336 
337 BOOST_AUTO_TEST_SUITE_END()
338 
339 } // namespace bitstream
340 } // namespace torc
Header for torc::bitstream output stream helpers.
Header for the VirtexE class.
static const DeviceVector & getVirtexEDevices(void)
Returns the VirtexE devices.
Definition: Devices.hpp:183
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.
void testVirtexEDevice(const std::string &inDeviceName, const boost::filesystem::path &inWorkingPath)
void testVirtexEFullMapping(const boost::filesystem::path &inWorkingPath)
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
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.
static const char * sPacketTypeName[ePacketTypeCount]
Packet type names.
Definition: Virtex.hpp:85
VirtexE bitstream inherited from Virtex bitstream.
Definition: VirtexE.hpp:37
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 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