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