HLS_Byte_Serializer/sources/top_converters/type_strmlen_endian_from_bytes_tb.cpp.in
2022-05-12 18:00:52 +02:00

143 lines
5 KiB
C++

/*
* Copyright or © or Copr. Université de Bretagne-Sud, Lab-STICC, Bordeaux-INP, IMS
* Contributor(s) : Camille Monière (2022)
*
* camille.moniere@univ-ubs.fr, camille.moniere@ims-bordeaux.fr
*
* This software is a computer program whose purpose is to simulate and implement C-type
* to bytes FPGA IPs.
*
* This software is governed by the CeCILL-B license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-B
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-B license and that you accept its terms.
*/
#include "top_converters/@TYPE@_@STRMLEN@_@ENDIAN@_from_bytes.hpp"
#include <cmath>
#include <cstdio>
#include <random>
#include <string>
#include <cstring>
using namespace std;
using namespace hls;
namespace {
#if @ENDIAN@ == BE
void bytes2@TYPE@_cpp(const uint8_t * __restrict in, @TYPE@ & out) {
constexpr size_t sizeofT = sizeof(@TYPE@);
@TYPE@ buffer = @TYPE@(0);
for (uint8_t byte = 0; byte < sizeofT; byte++) {
buffer |= @TYPE@(in[byte]) << ((sizeofT - byte - 1) * 8);
}
out = buffer;
}
#elif @ENDIAN@ == LE
void bytes2@TYPE@_cpp(const uint8_t * __restrict in, @TYPE@ & out) {
constexpr size_t sizeofT = sizeof(@TYPE@);
@TYPE@ buffer = @TYPE@(0);
for (uint8_t byte = 0; byte < sizeofT; byte++) {
buffer |= @TYPE@(in[byte]) << (byte * 8);
}
out = buffer;
}
#else
#error "Endianess (currently: @ENDIAN@) can be LE (true) or BE (false)"
#endif
} // namespace
int main(int argc, char * argv[]) {
constexpr uint64_t rand_seed = 147689;
mt19937_64 rng(rand_seed);
uniform_int_distribution<uint8_t> uniform_dist(numeric_limits<uint8_t>::min(), numeric_limits<uint8_t>::max());
constexpr uint64_t n_data = uint64_t(1e6f);
constexpr size_t sizeofT = sizeof(@TYPE@);
constexpr int64_t min_runs = int64_t(1);
constexpr int64_t max_runs = int64_t(1e6f / float(@STRMLEN@));
int64_t n_runs = max_runs;
if (argc > 1) {
n_runs = std::max(std::min(int64_t(stoi(string(argv[1]))) / int64_t(@STRMLEN@), max_runs), min_runs);
}
uint8_t * data_in = new uint8_t[n_data * sizeofT];
@TYPE@ * results = new @TYPE@[n_data];
hls::stream<uint8_t> strm_in;
hls::stream<@TYPE@> strm_out;
int counted_errors = 0;
for (int64_t u = 0; u < n_runs; u++) {
for (uint64_t v = 0; v < @STRMLEN@; v++) {
const uint64_t local_idx = u * @STRMLEN@ + v;
for (uint8_t byte = 0; byte < sizeofT; byte++) {
data_in[local_idx * sizeofT + byte] = uniform_dist(rng);
}
bytes2@TYPE@_cpp(data_in + local_idx * sizeofT, results[local_idx]);
for (uint8_t byte = 0; byte < sizeofT; byte++) {
strm_in.write(data_in[local_idx * sizeofT + byte]);
}
}
@TYPE@_@STRMLEN@_@ENDIAN@_from_bytes(strm_in, strm_out);
for (uint64_t v = 0; v < @STRMLEN@; v++) {
const uint64_t local_idx = u * @STRMLEN@ + v;
const @TYPE@ processed = strm_out.read();
if (results[local_idx] != processed) {
counted_errors++;
if (counted_errors < 100) {
char cformat[128];
sprintf(cformat, "0x%%0%1lullx != 0x%%0%1lullx\n", sizeofT * 2, sizeofT * 2);
fprintf(stderr, cformat, results[local_idx], processed);
} else if (counted_errors == 100) {
fprintf(stderr, "Too much errors to be reported on terminal.\n");
}
}
}
}
delete[] data_in;
delete[] results;
printf("RESULTS %s, %d errors for %lu runs.\n", counted_errors == 0 ? "SUCCESS" : "FAILURE", counted_errors, n_runs);
return counted_errors;
}