torc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Virtex2PUnitTest.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 Virtex2P 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 Virtex2p class.
38 BOOST_AUTO_TEST_CASE(Virtex2PUnitTest) {
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  // Virtex2P::sPacketTypeName and EPacketTypeName
59  BOOST_CHECK_EQUAL(Virtex2P::sPacketTypeName[0], "[UNKNOWN TYPE 0]");
60  BOOST_CHECK_EQUAL(Virtex2P::sPacketTypeName[Virtex2P::ePacketType1], "TYPE1");
61  BOOST_CHECK_EQUAL(Virtex2P::sPacketTypeName[Virtex2P::ePacketType2], "TYPE2");
62  BOOST_CHECK_EQUAL(Virtex2P::sPacketTypeName[3], "[UNKNOWN TYPE 3]");
63  BOOST_CHECK_EQUAL(Virtex2P::sPacketTypeName[4], "[UNKNOWN TYPE 4]");
64  BOOST_CHECK_EQUAL(Virtex2P::sPacketTypeName[5], "[UNKNOWN TYPE 5]");
65  BOOST_CHECK_EQUAL(Virtex2P::sPacketTypeName[6], "[UNKNOWN TYPE 6]");
66  BOOST_CHECK_EQUAL(Virtex2P::sPacketTypeName[7], "[UNKNOWN TYPE 7]");
67 
68  // members tested:
69  // Virtex2P::sOpcodeName and EOpcode
70  BOOST_CHECK_EQUAL(Virtex2P::sOpcodeName[Virtex2P::eOpcodeNOP], "NOP");
71  BOOST_CHECK_EQUAL(Virtex2P::sOpcodeName[Virtex2P::eOpcodeRead], "READ");
72  BOOST_CHECK_EQUAL(Virtex2P::sOpcodeName[Virtex2P::eOpcodeWrite], "WRITE");
73  BOOST_CHECK_EQUAL(Virtex2P::sOpcodeName[Virtex2P::eOpcodeReserved], "RESERVED");
74 
75  // members tested:
76  // Virtex2P::sRegisterName and ERegister
77  BOOST_CHECK_EQUAL(Virtex2P::sRegisterName[Virtex2P::eRegisterCRC], "CRC");
78  BOOST_CHECK_EQUAL(Virtex2P::sRegisterName[Virtex2P::eRegisterFAR], "FAR");
79  BOOST_CHECK_EQUAL(Virtex2P::sRegisterName[Virtex2P::eRegisterFDRI], "FDRI");
80  BOOST_CHECK_EQUAL(Virtex2P::sRegisterName[Virtex2P::eRegisterFDRO], "FDRO");
81  BOOST_CHECK_EQUAL(Virtex2P::sRegisterName[Virtex2P::eRegisterCMD], "CMD");
82  BOOST_CHECK_EQUAL(Virtex2P::sRegisterName[Virtex2P::eRegisterCTL], "CTL");
83  BOOST_CHECK_EQUAL(Virtex2P::sRegisterName[Virtex2P::eRegisterMASK], "MASK");
84  BOOST_CHECK_EQUAL(Virtex2P::sRegisterName[Virtex2P::eRegisterSTAT], "STAT");
85  BOOST_CHECK_EQUAL(Virtex2P::sRegisterName[Virtex2P::eRegisterLOUT], "LOUT");
86  BOOST_CHECK_EQUAL(Virtex2P::sRegisterName[Virtex2P::eRegisterCOR], "COR");
87  BOOST_CHECK_EQUAL(Virtex2P::sRegisterName[Virtex2P::eRegisterMFWR], "MFWR");
88  BOOST_CHECK_EQUAL(Virtex2P::sRegisterName[Virtex2P::eRegisterFLR], "FLR");
89  BOOST_CHECK_EQUAL(Virtex2P::sRegisterName[Virtex2P::eRegisterKEY], "KEY");
90  BOOST_CHECK_EQUAL(Virtex2P::sRegisterName[Virtex2P::eRegisterCBC], "CBC");
91  BOOST_CHECK_EQUAL(Virtex2P::sRegisterName[Virtex2P::eRegisterIDCODE], "IDCODE");
92 
93  // members tested:
94  // Virtex2P::sCommandName and ECommand
95  BOOST_CHECK_EQUAL(Virtex2P::sCommandName[Virtex2P::eCommandWCFG], "WCFG");
96  BOOST_CHECK_EQUAL(Virtex2P::sCommandName[Virtex2P::eCommandMFWR], "MFWR");
97  BOOST_CHECK_EQUAL(Virtex2P::sCommandName[Virtex2P::eCommandLFRM], "LFRM");
98  BOOST_CHECK_EQUAL(Virtex2P::sCommandName[Virtex2P::eCommandRCFG], "RCFG");
99  BOOST_CHECK_EQUAL(Virtex2P::sCommandName[Virtex2P::eCommandSTART], "START");
100  BOOST_CHECK_EQUAL(Virtex2P::sCommandName[Virtex2P::eCommandRCAP], "RCAP");
101  BOOST_CHECK_EQUAL(Virtex2P::sCommandName[Virtex2P::eCommandRCRC], "RCRC");
102  BOOST_CHECK_EQUAL(Virtex2P::sCommandName[Virtex2P::eCommandAGHIGH], "AGHIGH");
103  BOOST_CHECK_EQUAL(Virtex2P::sCommandName[Virtex2P::eCommandSWITCH], "SWITCH");
104  BOOST_CHECK_EQUAL(Virtex2P::sCommandName[Virtex2P::eCommandGRESTORE], "GRESTORE");
105  BOOST_CHECK_EQUAL(Virtex2P::sCommandName[Virtex2P::eCommandSHUTDOWN], "SHUTDOWN");
106  BOOST_CHECK_EQUAL(Virtex2P::sCommandName[Virtex2P::eCommandGCAPTURE], "GCAPTURE");
107  BOOST_CHECK_EQUAL(Virtex2P::sCommandName[Virtex2P::eCommandDESYNCH], "DESYNCH");
108 
109  // build the file paths
111  / "torc" / "bitstream" / "Virtex2PUnitTest.reference.bit";
113  / "regression" / "Virtex2PUnitTest.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  Virtex2P 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 testVirtex2PDevice(const std::string& inDeviceName, const boost::filesystem::path& inWorkingPath);
180 
181 /// \brief Unit test for the Virtex2P class Frame Address Register mapping.
182 BOOST_AUTO_TEST_CASE(Virtex2PFarUnitTest) {
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 void testVirtex2PDevice(const std::string& inDeviceName, const boost::filesystem::path& inWorkingPath) {
205 
206  // build the file paths
207  boost::filesystem::path debugBitstreamPath = inWorkingPath / "torc" / "bitstream" / "regression";
208  //boost::filesystem::path generatedPath = debugBitstreamPath / (inDeviceName + ".debug.bit");
209  boost::filesystem::path referencePath = debugBitstreamPath / (inDeviceName + ".debug.bit");
210 std::cerr << "TRYING TO FIND " << referencePath << std::endl;
211 
212  // read the bitstream
213  std::fstream fileStream(referencePath.string().c_str(), std::ios::binary | std::ios::in);
214  std::cerr << "Trying to read: " << referencePath << std::endl;
215  BOOST_REQUIRE(fileStream.good());
216  Virtex2P bitstream;
217  bitstream.read(fileStream, false);
218  // write the bitstream digest to the console
219 // std::cout << bitstream << std::endl;
220 
221 // // initialize the bitstream frame maps
222 // boost::filesystem::path deviceColumnsPath = inWorkingPath / "regression"
223 // / (inDeviceName + ".cpp");
224 // std::fstream deviceColumnsStream(deviceColumnsPath.string().c_str(), std::ios::out);
225  bitstream.initializeDeviceInfo(inDeviceName);
226  bitstream.initializeFrameMaps();
227 
228  // iterate through the packets, and extract all of the FARs
229  Virtex2P::FrameAddressToIndex farRemaining = bitstream.mFrameAddressToIndex;
231  {
232  bool first = true;
233  Virtex2P::const_iterator p = bitstream.begin();
234  Virtex2P::const_iterator e = bitstream.end();
237  while(p < e) {
238  const VirtexPacket& packet = *p++;
239  if(packet.getHeader() != header) continue;
240  if(first) { first = false; continue; }
241  Virtex2P::FrameAddress far = packet[1];
242  //std::cout << std::endl << "Debug Far Address: " << Hex32(packet[1]) << std::endl;
243  farVisited[far] = 0;
244  Virtex2P::FrameAddressToIndex::iterator found = farRemaining.find(far);
245  if(found != farRemaining.end()) {
246  farRemaining.erase(found);
247  } else {
248  std::cerr << "missing " << far << " ";
249  }
250  }
251  }
252  // verify that we have visited all of the expected FARs and no others
253  std::cout << "Device: " << inDeviceName << std::endl;
254  std::cout << "Size of farRemaining: " << farRemaining.size() << std::endl;
255  std::cout << "Size of farVisited: " << farVisited.size() << std::endl;
256  BOOST_REQUIRE_EQUAL(bitstream.mFrameAddressToIndex.size(), farVisited.size());
257  BOOST_REQUIRE_EQUAL(farRemaining.size(), 0u);
258 
259 return;
260 
261 }
262 
263 void testVirtex2PFullMapping(const boost::filesystem::path& inWorkingPath);
264 
265 /// \brief Unit test for the Virtex2P bitstream to bitmap conversion.
266 BOOST_AUTO_TEST_CASE(Virtex2PMapUnitTest) {
267  // look up the command line arguments
268  int& argc = boost::unit_test::framework::master_test_suite().argc;
269  char**& argv = boost::unit_test::framework::master_test_suite().argv;
270  // make sure that we at least have the name under which we were invoked
271  BOOST_REQUIRE(argc >= 1);
272  // resolve symbolic links if applicable
273  torc::common::DirectoryTree directoryTree(argv[0]);
275 }
276 
277 
279  // build the file paths
281  / "torc" / "bitstream" / "Virtex2PUnitTest.reference.bit";
283  / "regression" / "Virtex2PMapUnitTest.generated.bit";
284 
285  // read the bitstream
286  std::fstream fileStream(referencePath.string().c_str(), std::ios::binary | std::ios::in);
287  BOOST_REQUIRE(fileStream.good());
288  // read and gather bitstream frames
289  Virtex2P bitstream;
290  bitstream.read(fileStream, false);
291 
292  // initialize frame map
293  bitstream.initializeDeviceInfo("xc2vp20");
294  bitstream.initializeFrameMaps();
295 
296  // load bitstream frames in data structure
297  bitstream.initializeFullFrameBlocks();
298 
299  // write full bitstream from frame blocks data structure
300  uint32_t frameLength = bitstream.getFrameLength();
301  typedef boost::shared_array<uint32_t> WordSharedArray;
302  Virtex2P::iterator p = bitstream.begin();
303  Virtex2P::iterator e = bitstream.end();
304  while(p < e) {
305  const VirtexPacket& packet = *p++;
306  if(packet.isType2()) {
307  WordSharedArray words = packet.getWords();
308  uint32_t* ptr = words.get();
309  for(uint32_t block = 0; block < 8; block++) {
310  for(uint32_t frame = 0; frame < bitstream.mBlockFrameIndexBounds[block]; frame++) {
311  VirtexFrameBlocks::word_t* words = const_cast<VirtexFrameBlocks::word_t*>(bitstream.mFrameBlocks.mBlock[block][frame]->getWords());
312  for(uint32_t index = 0; index < frameLength; index++) {
313  *ptr++ = words[index];
314  }
315  }
316  }
317  }
318  }
319  // write the test bitstream back out
320  std::fstream outputStream(generatedPath.string().c_str(), std::ios::binary | std::ios::out);
321  BOOST_REQUIRE(outputStream.good());
322  bitstream.write(outputStream);
323  outputStream.flush();
324  BOOST_REQUIRE(torc::common::fileContentsAreEqual(referencePath, generatedPath));
325 
326  return;
327 }
328 
329 BOOST_AUTO_TEST_SUITE_END()
330 
331 } // namespace bitstream
332 } // namespace torc
Header for torc::bitstream output stream helpers.
static const char * sOpcodeName[eOpcodeCount]
Packet opcode names.
Definition: Virtex2.hpp:88
static const DeviceVector & getVirtex2PDevices(void)
Returns the Virtex2P devices.
Definition: Devices.hpp:187
Encapsulation of a device designator and its constituent elements.
Header for the DeviceInfoHelper class.
Header for the Virtex2P class.
const EFamily & getFamily(void) const
Returns the device family.
Header for the DirectoryTree class.
void testVirtex2PDevice(const std::string &inDeviceName, const boost::filesystem::path &inWorkingPath)
Header for the DeviceDesignator class.
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
void testVirtex2PFullMapping(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.
static const char * sCommandName[eCommandCount]
Configuration command names.
Definition: Virtex2.hpp:92
Header for the DDB 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)
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
Virtex2P bitstream inherited from Virtex2 bitstream.
Definition: Virtex2P.hpp:37
static const boost::filesystem::path & getExecutablePath(void)
Returns the absolute path to the executable directory.
uint32_t getHeader(void) const