μHAL (v2.7.9)
Part of the IPbus software repository
test_block.cpp
Go to the documentation of this file.
1 /*
2 ---------------------------------------------------------------------------
3 
4  This file is part of uHAL.
5 
6  uHAL is a hardware access library and programming framework
7  originally developed for upgrades of the Level-1 trigger of the CMS
8  experiment at CERN.
9 
10  uHAL is free software: you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  uHAL is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with uHAL. If not, see <http://www.gnu.org/licenses/>.
22 
23  Marc Magrans de Abril, CERN
24  email: marc.magrans.de.abril <AT> cern.ch
25 
26  Andrew Rose, Imperial College, London
27  email: awr01 <AT> imperial.ac.uk
28 
29  Tom Williams, Rutherford Appleton Laboratory, Oxfordshire
30  email: tom.williams <AT> cern.ch
31 
32 ---------------------------------------------------------------------------
33 */
34 
35 #include "uhal/uhal.hpp"
36 
38 #include "uhal/tests/fixtures.hpp"
39 #include "uhal/tests/tools.hpp"
40 
41 #include <boost/test/unit_test.hpp>
42 
43 #include <vector>
44 #include <iostream>
45 #include <cstdlib>
46 #include <typeinfo>
47 
48 
49 using namespace uhal;
50 
51 #define N_4B 1
52 #define N_1kB 1024/4
53 #define N_1MB 1024*1024/4
54 #define N_10MB 10*1024*1024/4
55 #define N_200MB 100*1024*1024/4
56 
57 
58 namespace uhal {
59 namespace tests {
60 
61 std::vector<size_t> getBlockUnitTestDepths(const size_t aMaxSize)
62 {
63  std::vector<size_t> lDepths;
64  lDepths.push_back(0);
65  lDepths.push_back(N_4B);
66  lDepths.push_back(N_1kB);
67  lDepths.push_back(10 * N_1kB);
68  lDepths.push_back(100 * N_1kB);
69  lDepths.push_back(N_1MB);
70  lDepths.push_back(N_10MB);
71  lDepths.push_back(N_200MB);
72 
73  for (std::vector<size_t>::iterator lIt=lDepths.begin(); lIt != lDepths.end(); ) {
74  if ((*lIt) > aMaxSize)
75  lIt = lDepths.erase(lIt);
76  else
77  ++lIt;
78  }
79  return lDepths;
80 }
81 
82 
83 UHAL_TESTS_DEFINE_CLIENT_TEST_CASES(BlockReadWriteTestSuite, block_write_read, DummyHardwareFixture,
84 {
85  std::vector<size_t> lDepths = getBlockUnitTestDepths(quickTest ? N_1MB : N_10MB);
86 
87  for(size_t i=0; i<lDepths.size(); i++) {
88  const size_t N = lDepths.at(i);
89  BOOST_TEST_MESSAGE(" N = " << N);
90 
91  HwInterface hw = getHwInterface();
92 
93  std::vector<uint32_t> xx;
94  xx.reserve ( N );
95  for ( size_t i=0; i!= N; ++i )
96  {
97  xx.push_back ( static_cast<uint32_t> ( rand() ) );
98  }
99 
100  hw.getNode ( "LARGE_MEM" ).writeBlock ( xx );
101  ValVector< uint32_t > mem = hw.getNode ( "LARGE_MEM" ).readBlock ( N );
102  BOOST_CHECK ( !mem.valid() );
103  BOOST_CHECK_EQUAL ( mem.size(), N );
104  if ( N > 0 )
105  {
106  BOOST_CHECK_THROW ( mem.at ( 0 ), uhal::exception::NonValidatedMemory );
107  }
108  BOOST_CHECK_THROW ( mem.value(), uhal::exception::NonValidatedMemory );
110  BOOST_CHECK ( mem.valid() );
111  BOOST_CHECK_EQUAL ( mem.size(), N );
112 
113  //This check will fail when DummyHardware::ADDRESS_MASK < N
114  if ( N < N_10MB )
115  {
116  bool correct_block_write_read = true;
117  std::vector< uint32_t >::const_iterator j=xx.begin();
118 
119  for ( ValVector< uint32_t >::const_iterator i ( mem.begin() ); i!=mem.end(); ++i , ++j )
120  {
122  }
123 
125  }
126  }
127 }
128 )
129 
130 
132 {
133  std::vector<size_t> lDepths = getBlockUnitTestDepths(quickTest ? N_1MB : N_200MB);
134 
135  for(size_t i=0; i<lDepths.size(); i++) {
136  const size_t N = lDepths.at(i);
137  BOOST_TEST_MESSAGE(" N = " << N);
138 
139  HwInterface hw = getHwInterface();
140  // Scope the large source vector so that the memory is freed up after the call to write. The data is safe, since it is copied into the send buffers.
141  std::vector<uint32_t> xx;
142  xx.reserve ( N );
143 
144  for ( size_t i=0; i!= N; ++i )
145  {
146  xx.push_back ( static_cast<uint32_t> ( rand() ) );
147  }
148 
149  hw.getNode ( "FIFO" ).writeBlock ( xx );
150  ValVector< uint32_t > mem = hw.getNode ( "FIFO" ).readBlock ( N );
151  BOOST_CHECK ( !mem.valid() );
152  BOOST_CHECK_EQUAL ( mem.size(), N );
153  if ( N > 0 )
154  {
155  BOOST_CHECK_THROW ( mem.at ( 0 ),uhal::exception::NonValidatedMemory );
156  }
157  BOOST_CHECK_THROW ( mem.value(), uhal::exception::NonValidatedMemory );
159  BOOST_CHECK ( mem.valid() );
160  BOOST_CHECK_EQUAL ( mem.size(), N );
161  //The FIFO implementation on the dummy HW is a single memory location so there is not much to check
162  }
163 }
164 )
165 
166 
167 UHAL_TESTS_DEFINE_CLIENT_TEST_CASES(BlockReadWriteTestSuite, block_offset_write_read, DummyHardwareFixture,
168 {
169  std::vector<size_t> lDepths = getBlockUnitTestDepths(quickTest ? N_1MB : N_10MB);
170 
171  for(size_t i=0; i<lDepths.size(); i++) {
172  const size_t N = lDepths.at(i);
173  BOOST_TEST_MESSAGE(" N = " << N);
174 
175  HwInterface hw = getHwInterface();
176 
177  std::vector<uint32_t> xx;
178  xx.reserve ( N );
179  std::vector<uint32_t> yy;
180  yy.reserve ( N );
181  for ( size_t i=0; i!= N; ++i )
182  {
183  xx.push_back ( static_cast<uint32_t> ( rand() ) );
184  yy.push_back ( static_cast<uint32_t> ( rand() ) );
185  }
186 
187  hw.getNode ( "LARGE_MEM" ).writeBlockOffset ( xx , 0 );
188  ValVector< uint32_t > mem = hw.getNode ( "LARGE_MEM" ).readBlockOffset ( N , 0 );
189 
190  BOOST_CHECK ( !mem.valid() );
191  BOOST_CHECK_EQUAL ( mem.size(), N );
192 
193  if ( N > 0 )
194  {
195  BOOST_CHECK_THROW ( mem.at ( 0 ),uhal::exception::NonValidatedMemory );
196  }
197  BOOST_CHECK_THROW ( mem.value(), uhal::exception::NonValidatedMemory );
198 
199 
200  hw.getNode ( "LARGE_MEM" ).writeBlockOffset ( yy , N );
201  ValVector< uint32_t > mem2 = hw.getNode ( "LARGE_MEM" ).readBlockOffset ( N , N );
202 
203  BOOST_CHECK ( !mem2.valid() );
204  BOOST_CHECK_EQUAL ( mem2.size(), N );
205 
206  if ( N > 0 )
207  {
208  BOOST_CHECK_THROW ( mem2.at ( 0 ),uhal::exception::NonValidatedMemory );
209  }
210  BOOST_CHECK_THROW ( mem2.value(), uhal::exception::NonValidatedMemory );
211 
213 
214  BOOST_CHECK ( mem.valid() );
215  BOOST_CHECK_EQUAL ( mem.size(), N );
216 
217  BOOST_CHECK ( mem2.valid() );
218  BOOST_CHECK_EQUAL ( mem2.size(), N );
219 
220 
221  //This check will fail when DummyHardware::ADDRESS_MASK < N
222  if ( N < N_10MB )
223  {
224  bool correct_block_write_read = true;
225  std::vector< uint32_t >::const_iterator j=xx.begin();
226 
227  for ( ValVector< uint32_t >::const_iterator i ( mem.begin() ); i!=mem.end(); ++i , ++j )
228  {
230  }
231 
232  j=yy.begin();
233 
234  for ( ValVector< uint32_t >::const_iterator i ( mem2.begin() ); i!=mem2.end(); ++i , ++j )
235  {
237  }
238 
240  }
241  }
242 }
243 )
244 
245 
247 {
248  HwInterface hw = getHwInterface();
249  std::vector<uint32_t> xx;
250 
251  //We allow the user to call a bulk access of size=1 to a single register
252  xx.resize ( N_4B );
255 
256  //These should all throw
257  BOOST_CHECK_THROW ( hw.getNode ( "REG" ).writeBlockOffset ( xx , 0 ) , uhal::exception::BulkTransferOffsetRequestedForSingleRegister );
258  BOOST_CHECK_THROW ( ValVector< uint32_t > mem = hw.getNode ( "REG" ).readBlockOffset ( N_1kB , 0 ) , uhal::exception::BulkTransferOffsetRequestedForSingleRegister );
259 
260  xx.resize ( N_1kB );
261  BOOST_CHECK_THROW ( hw.getNode ( "REG" ).writeBlock ( xx ) , uhal::exception::BulkTransferOnSingleRegister );
262  BOOST_CHECK_THROW ( ValVector< uint32_t > mem = hw.getNode ( "REG" ).readBlock( N_1kB ) , uhal::exception::BulkTransferOnSingleRegister );
263 
264  BOOST_CHECK_THROW ( hw.getNode ( "FIFO" ).writeBlockOffset ( xx , 1 ) , uhal::exception::BulkTransferOffsetRequestedForFifo );
265  BOOST_CHECK_THROW ( ValVector< uint32_t > mem = hw.getNode ( "FIFO" ).readBlockOffset ( N_1kB , 1 ) , uhal::exception::BulkTransferOffsetRequestedForFifo );
266 
267 }
268 )
269 
270 
271 UHAL_TESTS_DEFINE_CLIENT_TEST_CASES(BlockReadWriteTestSuite, block_bigger_than_size_attribute, MinimalFixture,
272 {
273  HwInterface hw = getHwInterface();
274  std::vector<uint32_t> xx;
275  xx.resize ( N_1MB );
276  BOOST_CHECK_THROW ( hw.getNode ( "SMALL_MEM" ).writeBlock ( xx ) , uhal::exception::BulkTransferRequestedTooLarge );
277  BOOST_CHECK_THROW ( ValVector< uint32_t > mem = hw.getNode ( "SMALL_MEM" ).readBlock ( N_1MB ) , uhal::exception::BulkTransferRequestedTooLarge );
278 }
279 )
280 
281 
283 {
284  HwInterface hw = getHwInterface();
285  std::vector<uint32_t> xx;
286  // Size OK but offset too large
287  xx.resize ( N_4B );
288  BOOST_CHECK_THROW ( hw.getNode ( "SMALL_MEM" ).writeBlockOffset ( xx , 256 ) , uhal::exception::BulkTransferRequestedTooLarge );
289  BOOST_CHECK_THROW ( ValVector< uint32_t > mem = hw.getNode ( "SMALL_MEM" ).readBlockOffset ( N_4B , 256 ) , uhal::exception::BulkTransferRequestedTooLarge );
290  // Size OK, offset OK, combination too large
291  xx.resize ( N_1kB );
292  BOOST_CHECK_THROW ( hw.getNode ( "SMALL_MEM" ).writeBlockOffset ( xx , 1 ) , uhal::exception::BulkTransferRequestedTooLarge );
293  BOOST_CHECK_THROW ( ValVector< uint32_t > mem = hw.getNode ( "SMALL_MEM" ).readBlockOffset ( N_1kB , 1 ) , uhal::exception::BulkTransferRequestedTooLarge );
294 }
295 )
296 
297 
298 } // end ns tests
299 } // end ns uhal
300 
uhal::ValVector::at
const T & at(std::size_t aIndex) const
If the memory has previously been marked as valid, give random access into memory.
Definition: ValMem.cpp:264
tools.hpp
uhal::HwInterface
A class which bundles a node tree and an IPbus client interface together providing everything you nee...
Definition: HwInterface.hpp:61
uhal::ValVector< uint32_t >
uhal::tests::block_offset_bigger_than_size_attribute
block_offset_bigger_than_size_attribute
Definition: test_block.cpp:282
uhal::Node::readBlock
ValVector< uint32_t > readBlock(const uint32_t &aSize) const
Read a block of unsigned data from a block of registers or a block-read port.
Definition: Node.cpp:606
uhal::tests::correct_block_write_read
bool correct_block_write_read
Definition: test_rawclient.cpp:111
uhal::Node::writeBlock
ValHeader writeBlock(const std::vector< uint32_t > &aValues) const
Write a block of data to a block of registers or a block-write port.
Definition: Node.cpp:516
fixtures.hpp
N_200MB
#define N_200MB
Definition: test_block.cpp:55
uhal::tests::fifo_write_read
fifo_write_read
Definition: test_block.cpp:131
uhal::ValVector::valid
bool valid()
Return whether the Validated memory is marked as valid.
Definition: ValMem.cpp:217
uhal::tests::BOOST_CHECK
BOOST_CHECK(!mem.valid())
uhal::ValVector::begin
const_iterator begin() const
If the memory has previously been marked as valid, return a const iterator to the beginning of the un...
Definition: ValMem.cpp:295
uhal::tests::BOOST_CHECK_THROW
BOOST_CHECK_THROW(hw.getNode("REG").writeBlockOffset(xx, 0), uhal::exception::BulkTransferOffsetRequestedForSingleRegister)
uhal::tests::j
std::vector< uint32_t >::const_iterator j
Definition: test_rawclient.cpp:113
N_4B
#define N_4B
Definition: test_block.cpp:51
N_10MB
#define N_10MB
Definition: test_block.cpp:54
N_1MB
#define N_1MB
Definition: test_block.cpp:53
uhal::HwInterface::dispatch
void dispatch()
Make the IPbus client issue a dispatch.
Definition: HwInterface.cpp:106
definitions.hpp
uhal
Definition: HttpResponseGrammar.hpp:49
uhal::tests::block_access_type_violations
block_access_type_violations
Definition: test_block.cpp:246
uhal::tests::hw
HwInterface hw
Definition: test_rawclient.cpp:93
uhal::tests::DummyHardwareFixture
Definition: fixtures.hpp:135
N_1kB
#define N_1kB
Definition: test_block.cpp:52
uhal::tests::xx
std::vector< uint32_t > xx
Definition: test_block.cpp:247
uhal::tests::UHAL_TESTS_DEFINE_CLIENT_TEST_CASES
UHAL_TESTS_DEFINE_CLIENT_TEST_CASES(BlockReadWriteTestSuite, block_write_read, DummyHardwareFixture, { std::vector< size_t > lDepths=getBlockUnitTestDepths(quickTest ? N_1MB :N_10MB);for(size_t i=0;i< lDepths.size();i++) { const size_t N=lDepths.at(i);BOOST_TEST_MESSAGE(" N = "<< N);HwInterface hw=getHwInterface();std::vector< uint32_t > xx;xx.reserve(N);for(size_t i=0;i!=N;++i) { xx.push_back(static_cast< uint32_t >(rand()));} hw.getNode("LARGE_MEM").writeBlock(xx);ValVector< uint32_t > mem=hw.getNode("LARGE_MEM").readBlock(N);BOOST_CHECK(!mem.valid());BOOST_CHECK_EQUAL(mem.size(), N);if(N > 0) { BOOST_CHECK_THROW(mem.at(0), uhal::exception::NonValidatedMemory);} BOOST_CHECK_THROW(mem.value(), uhal::exception::NonValidatedMemory);BOOST_CHECK_NO_THROW(hw.dispatch());BOOST_CHECK(mem.valid());BOOST_CHECK_EQUAL(mem.size(), N);if(N< N_10MB) { bool correct_block_write_read=true;std::vector< uint32_t >::const_iterator j=xx.begin();for(ValVector< uint32_t >::const_iterator i(mem.begin());i!=mem.end();++i,++j) { correct_block_write_read=correct_block_write_read &&(*i== *j);} BOOST_CHECK(correct_block_write_read);} } }) UHAL_TESTS_DEFINE_CLIENT_TEST_CASES(BlockReadWriteTestSuite
uhal::tests::getBlockUnitTestDepths
std::vector< size_t > getBlockUnitTestDepths(const size_t aMaxSize)
Definition: test_block.cpp:61
uhal::Node::writeBlockOffset
ValHeader writeBlockOffset(const std::vector< uint32_t > &aValues, const uint32_t &aOffset) const
Write a block of data to a block of registers or a block-write port.
Definition: Node.cpp:547
uhal.hpp
uhal::ValVector::value
std::vector< T > value() const
Return the value of the validated memory with check on validity.
Definition: ValMem.cpp:359
uhal::ValVector::size
std::size_t size() const
Return the size of the underlying memory.
Definition: ValMem.cpp:280
uhal::tests::BOOST_CHECK_NO_THROW
BOOST_CHECK_NO_THROW(hw.getNode("REG").writeBlock(xx))
uhal::tests::mem
ValVector< uint32_t > mem
Definition: test_rawclient.cpp:104
uhal::tests::BOOST_CHECK_EQUAL
BOOST_CHECK_EQUAL(mem.size(), N)
uhal::HwInterface::getNode
const Node & getNode() const
Retrieve the top-level node.
Definition: HwInterface.cpp:135
uhal::Node::readBlockOffset
ValVector< uint32_t > readBlockOffset(const uint32_t &aSize, const uint32_t &aOffset) const
Read a block of unsigned data from a block of registers or a block-read port.
Definition: Node.cpp:637
uhal::ValVector::end
const_iterator end() const
If the memory has previously been marked as valid, return a const iterator to the end (one past last ...
Definition: ValMem.cpp:311
uhal::tests::MinimalFixture
Definition: fixtures.hpp:64