μHAL (v2.8.17)
Part of the IPbus software repository
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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
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
49using 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
58namespace uhal {
59namespace tests {
60
61std::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
83UHAL_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
167UHAL_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
271UHAL_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
A class which bundles a node tree and an IPbus client interface together providing everything you nee...
Definition: HwInterface.hpp:56
const Node & getNode() const
Retrieve the top-level node.
void dispatch()
Make the IPbus client issue a dispatch.
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:573
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:542
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:663
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:632
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:311
bool valid()
Return whether the Validated memory is marked as valid.
Definition: ValMem.cpp:217
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
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:327
std::size_t size() const
Return the size of the underlying memory.
Definition: ValMem.cpp:280
std::vector< T > value() const
Return the value of the validated memory with check on validity.
Definition: ValMem.cpp:375
BOOST_CHECK_THROW(hw.getNode("REG").writeBlockOffset(xx, 0), uhal::exception::BulkTransferOffsetRequestedForSingleRegister)
BOOST_CHECK_EQUAL(mem.size(), N)
std::vector< uint32_t >::const_iterator j
block_access_type_violations
Definition: test_block.cpp:246
BOOST_CHECK_NO_THROW(hw.getNode("REG").writeBlock(xx))
ValVector< uint32_t > mem
BOOST_CHECK(!mem.valid())
HwInterface hw
block_offset_bigger_than_size_attribute
Definition: test_block.cpp:282
std::vector< uint32_t > xx
Definition: test_block.cpp:249
std::vector< size_t > getBlockUnitTestDepths(const size_t aMaxSize)
Definition: test_block.cpp:61
bool correct_block_write_read
#define N_1kB
Definition: test_block.cpp:52
#define N_1MB
Definition: test_block.cpp:53
#define N_10MB
Definition: test_block.cpp:54
#define N_4B
Definition: test_block.cpp:51
#define N_200MB
Definition: test_block.cpp:55
#define UHAL_TESTS_DEFINE_CLIENT_TEST_CASES(test_suite_name, test_case_name, test_fixture, test_case_contents)
Definition: definitions.hpp:53