OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [sw/] [example/] [bitmanip_test/] [main.c] - Blame information for rev 73

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 63 zero_gravi
// #################################################################################################
2 66 zero_gravi
// # << NEORV32 - RISC-V Bit-Manipulation 'B' Extension Test Program >>                            #
3 63 zero_gravi
// # ********************************************************************************************* #
4
// # BSD 3-Clause License                                                                          #
5
// #                                                                                               #
6 71 zero_gravi
// # Copyright (c) 2022, Stephan Nolting. All rights reserved.                                     #
7 63 zero_gravi
// #                                                                                               #
8
// # Redistribution and use in source and binary forms, with or without modification, are          #
9
// # permitted provided that the following conditions are met:                                     #
10
// #                                                                                               #
11
// # 1. Redistributions of source code must retain the above copyright notice, this list of        #
12
// #    conditions and the following disclaimer.                                                   #
13
// #                                                                                               #
14
// # 2. Redistributions in binary form must reproduce the above copyright notice, this list of     #
15
// #    conditions and the following disclaimer in the documentation and/or other materials        #
16
// #    provided with the distribution.                                                            #
17
// #                                                                                               #
18
// # 3. Neither the name of the copyright holder nor the names of its contributors may be used to  #
19
// #    endorse or promote products derived from this software without specific prior written      #
20
// #    permission.                                                                                #
21
// #                                                                                               #
22
// # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS   #
23
// # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF               #
24
// # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE    #
25
// # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     #
26
// # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
27
// # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED    #
28
// # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING     #
29
// # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED  #
30
// # OF THE POSSIBILITY OF SUCH DAMAGE.                                                            #
31
// # ********************************************************************************************* #
32
// # The NEORV32 Processor - https://github.com/stnolting/neorv32              (c) Stephan Nolting #
33
// #################################################################################################
34
 
35
 
36
/**********************************************************************//**
37
 * @file bitmanip_test/main.c
38
 * @author Stephan Nolting
39 66 zero_gravi
 * @brief Test program for the NEORV32 'B` extension using pseudo-random
40 63 zero_gravi
 * data as input; compares results from hardware against pure-sw reference functions.
41
 **************************************************************************/
42
 
43
#include <neorv32.h>
44
#include "neorv32_b_extension_intrinsics.h"
45
 
46
/**********************************************************************//**
47
 * @name User configuration
48
 **************************************************************************/
49
/**@{*/
50
/** UART BAUD rate */
51
#define BAUD_RATE      (19200)
52
//** Number of test cases for each instruction */
53
#define NUM_TEST_CASES (1000000)
54 71 zero_gravi
//** Enable Zbb tests when 1 */
55
#define ENABLE_ZBB     (1)
56
//** Enable Zba tests when 1 */
57
#define ENABLE_ZBA     (1)
58
//** Enable Zbs tests when 1 */
59
#define ENABLE_ZBS     (1)
60
//** Enable Zbc tests when 1 */
61
#define ENABLE_ZBC     (1)
62 63 zero_gravi
/**@}*/
63
 
64
 
65
// Prototypes
66
uint32_t xorshift32(void);
67
uint32_t check_result(uint32_t num, uint32_t opa, uint32_t opb, uint32_t ref, uint32_t res);
68
void print_report(int num_err, int num_tests);
69
 
70
 
71
/**********************************************************************//**
72 71 zero_gravi
 * Main function; test all available operations of the NEORV32 'B' extension
73 63 zero_gravi
 * using bit manipulation intrinsics and software-only reference functions (emulation).
74
 *
75 66 zero_gravi
 * @note This program requires the bit-manipulation CPU extension.
76 63 zero_gravi
 *
77
 * @return Irrelevant.
78
 **************************************************************************/
79
int main() {
80
 
81
  uint32_t opa = 0, opb = 0, res_hw = 0, res_sw = 0;
82
  uint32_t i = 0, err_cnt = 0;
83
  const uint32_t num_tests = (int)NUM_TEST_CASES;
84
 
85
  // capture all exceptions and give debug info via UART
86
  neorv32_rte_setup();
87
 
88 71 zero_gravi
  // init UART at default baud rate, no parity bits, no hw flow control
89 65 zero_gravi
  neorv32_uart0_setup(BAUD_RATE, PARITY_NONE, FLOW_CONTROL_NONE);
90 63 zero_gravi
 
91
// Disable compilation by default
92
#ifndef RUN_CHECK
93
  #warning Program HAS NOT BEEN COMPILED! Use >>make USER_FLAGS+=-DRUN_CHECK clean_all exe<< to compile it.
94
 
95
  // inform the user if you are actually executing this
96 65 zero_gravi
  neorv32_uart0_printf("ERROR! Program has not been compiled. Use >>make USER_FLAGS+=-DRUN_CHECK clean_all exe<< to compile it.\n");
97 63 zero_gravi
 
98
  return 1;
99
#endif
100
 
101
  // intro
102 71 zero_gravi
  neorv32_uart0_printf("<<< NEORV32 Bit-Manipulation Extension ('B') Test >>>\n\n");
103 63 zero_gravi
 
104
  // check available hardware extensions and compare with compiler flags
105
  neorv32_rte_check_isa(0); // silent = 0 -> show message if isa mismatch
106
 
107 71 zero_gravi
  // check if B extension is implemented at all
108 66 zero_gravi
  if ((neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_B)) == 0) {
109 71 zero_gravi
    neorv32_uart0_print("Error! B extension not synthesized!\n");
110 63 zero_gravi
    return 1;
111
  }
112
 
113 66 zero_gravi
  neorv32_uart0_printf("Starting bit-manipulation extension tests (%i test cases per instruction)...\n\n", num_tests);
114 63 zero_gravi
 
115 71 zero_gravi
#if (ENABLE_ZBB != 0)
116
  neorv32_uart0_printf("--------------------------------------------\n");
117 66 zero_gravi
  neorv32_uart0_printf("Zbb - Basic bit-manipulation instructions\n");
118 71 zero_gravi
  neorv32_uart0_printf("--------------------------------------------\n");
119 66 zero_gravi
 
120 63 zero_gravi
  // ANDN
121 65 zero_gravi
  neorv32_uart0_printf("\nANDN:\n");
122 63 zero_gravi
  err_cnt = 0;
123
  for (i=0;i<num_tests; i++) {
124
    opa = xorshift32();
125
    opb = xorshift32();
126
    res_sw = riscv_emulate_andn(opa, opb);
127
    res_hw = riscv_intrinsic_andn(opa, opb);
128
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
129
  }
130
  print_report(err_cnt, num_tests);
131
 
132
  // ORN
133 65 zero_gravi
  neorv32_uart0_printf("\nORN:\n");
134 63 zero_gravi
  err_cnt = 0;
135
  for (i=0;i<num_tests; i++) {
136
    opa = xorshift32();
137
    opb = xorshift32();
138
    res_sw = riscv_emulate_orn(opa, opb);
139
    res_hw = riscv_intrinsic_orn(opa, opb);
140
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
141
  }
142
  print_report(err_cnt, num_tests);
143
 
144
  // XNOR
145 65 zero_gravi
  neorv32_uart0_printf("\nXNOR:\n");
146 63 zero_gravi
  err_cnt = 0;
147
  for (i=0;i<num_tests; i++) {
148
    opa = xorshift32();
149
    opb = xorshift32();
150
    res_sw = riscv_emulate_xnor(opa, opb);
151
    res_hw = riscv_intrinsic_xnor(opa, opb);
152
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
153
  }
154
  print_report(err_cnt, num_tests);
155
 
156
 
157
 
158
  // CLZ
159 65 zero_gravi
  neorv32_uart0_printf("\nCLZ:\n");
160 63 zero_gravi
  err_cnt = 0;
161
  for (i=0;i<num_tests; i++) {
162
    opa = xorshift32();
163
    res_sw = riscv_emulate_clz(opa);
164
    res_hw = riscv_intrinsic_clz(opa);
165
    err_cnt += check_result(i, opa, 0, res_sw, res_hw);
166
  }
167
  print_report(err_cnt, num_tests);
168
 
169
  // CTZ
170 65 zero_gravi
  neorv32_uart0_printf("\nCTZ:\n");
171 63 zero_gravi
  err_cnt = 0;
172
  for (i=0;i<num_tests; i++) {
173
    opa = xorshift32();
174
    res_sw = riscv_emulate_ctz(opa);
175
    res_hw = riscv_intrinsic_ctz(opa);
176
    err_cnt += check_result(i, opa, 0, res_sw, res_hw);
177
  }
178
  print_report(err_cnt, num_tests);
179
 
180
 
181
 
182
  // CPOP
183 65 zero_gravi
  neorv32_uart0_printf("\nCPOP:\n");
184 63 zero_gravi
  err_cnt = 0;
185
  for (i=0;i<num_tests; i++) {
186
    opa = xorshift32();
187
    res_sw = riscv_emulate_cpop(opa);
188
    res_hw = riscv_intrinsic_cpop(opa);
189
    err_cnt += check_result(i, opa, 0, res_sw, res_hw);
190
  }
191
  print_report(err_cnt, num_tests);
192
 
193
 
194
 
195
  // MAX
196 65 zero_gravi
  neorv32_uart0_printf("\nMAX:\n");
197 63 zero_gravi
  err_cnt = 0;
198
  for (i=0;i<num_tests; i++) {
199
    opa = xorshift32();
200
    opb = xorshift32();
201
    res_sw = riscv_emulate_max(opa, opb);
202
    res_hw = riscv_intrinsic_max(opa, opb);
203
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
204
  }
205
  print_report(err_cnt, num_tests);
206
 
207
  // MAXU
208 65 zero_gravi
  neorv32_uart0_printf("\nMAXU:\n");
209 63 zero_gravi
  err_cnt = 0;
210
  for (i=0;i<num_tests; i++) {
211
    opa = xorshift32();
212
    opb = xorshift32();
213
    res_sw = riscv_emulate_maxu(opa, opb);
214
    res_hw = riscv_intrinsic_maxu(opa, opb);
215
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
216
  }
217
  print_report(err_cnt, num_tests);
218
 
219
  // MIN
220 65 zero_gravi
  neorv32_uart0_printf("\nMIN:\n");
221 63 zero_gravi
  err_cnt = 0;
222
  for (i=0;i<num_tests; i++) {
223
    opa = xorshift32();
224
    opb = xorshift32();
225
    res_sw = riscv_emulate_min(opa, opb);
226
    res_hw = riscv_intrinsic_min(opa, opb);
227
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
228
  }
229
  print_report(err_cnt, num_tests);
230
 
231
  // MINU
232 65 zero_gravi
  neorv32_uart0_printf("\nMINU:\n");
233 63 zero_gravi
  err_cnt = 0;
234
  for (i=0;i<num_tests; i++) {
235
    opa = xorshift32();
236
    opb = xorshift32();
237
    res_sw = riscv_emulate_minu(opa, opb);
238
    res_hw = riscv_intrinsic_minu(opa, opb);
239
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
240
  }
241
  print_report(err_cnt, num_tests);
242
 
243
 
244
 
245
  // SEXT.B
246 65 zero_gravi
  neorv32_uart0_printf("\nSEXT.B:\n");
247 63 zero_gravi
  err_cnt = 0;
248
  for (i=0;i<num_tests; i++) {
249
    opa = xorshift32();
250
    res_sw = riscv_emulate_sextb(opa);
251
    res_hw = riscv_intrinsic_sextb(opa);
252
    err_cnt += check_result(i, opa, 0, res_sw, res_hw);
253
  }
254
  print_report(err_cnt, num_tests);
255
 
256
  // SEXT.H
257 65 zero_gravi
  neorv32_uart0_printf("\nSEXT.H:\n");
258 63 zero_gravi
  err_cnt = 0;
259
  for (i=0;i<num_tests; i++) {
260
    opa = xorshift32();
261
    res_sw = riscv_emulate_sexth(opa);
262
    res_hw = riscv_intrinsic_sexth(opa);
263
    err_cnt += check_result(i, opa, 0, res_sw, res_hw);
264
  }
265
  print_report(err_cnt, num_tests);
266
 
267
  // ZEXT.H
268 65 zero_gravi
  neorv32_uart0_printf("\nZEXT.H:\n");
269 63 zero_gravi
  err_cnt = 0;
270
  for (i=0;i<num_tests; i++) {
271
    opa = xorshift32();
272
    res_sw = riscv_emulate_zexth(opa);
273
    res_hw = riscv_intrinsic_zexth(opa);
274
    err_cnt += check_result(i, opa, 0, res_sw, res_hw);
275
  }
276
  print_report(err_cnt, num_tests);
277
 
278
 
279
 
280
  // ROL
281 65 zero_gravi
  neorv32_uart0_printf("\nROL:\n");
282 63 zero_gravi
  err_cnt = 0;
283
  for (i=0;i<num_tests; i++) {
284
    opa = xorshift32();
285
    opb = xorshift32();
286
    res_sw = riscv_emulate_rol(opa, opb);
287
    res_hw = riscv_intrinsic_rol(opa, opb);
288
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
289
  }
290
  print_report(err_cnt, num_tests);
291
 
292
  // ROR
293 65 zero_gravi
  neorv32_uart0_printf("\nROR:\n");
294 63 zero_gravi
  err_cnt = 0;
295
  for (i=0;i<num_tests; i++) {
296
    opa = xorshift32();
297
    opb = xorshift32();
298
    res_sw = riscv_emulate_ror(opa, opb);
299
    res_hw = riscv_intrinsic_ror(opa, opb);
300
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
301
  }
302
  print_report(err_cnt, num_tests);
303
 
304
  // RORI
305 65 zero_gravi
  neorv32_uart0_printf("\nRORI (imm=20):\n"); // FIXME: static immediate
306 63 zero_gravi
  err_cnt = 0;
307
  for (i=0;i<num_tests; i++) {
308
    opa = xorshift32();
309
    res_sw = riscv_emulate_ror(opa, 20);
310
    res_hw = riscv_intrinsic_rori20(opa);
311
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
312
  }
313
  print_report(err_cnt, num_tests);
314
 
315
 
316
 
317
  // ORC.B
318 65 zero_gravi
  neorv32_uart0_printf("\nORCB:\n");
319 63 zero_gravi
  err_cnt = 0;
320
  for (i=0;i<num_tests; i++) {
321
    opa = xorshift32();
322
    res_sw = riscv_emulate_orcb(opa);
323
    res_hw = riscv_intrinsic_orcb(opa);
324
    err_cnt += check_result(i, opa, 0, res_sw, res_hw);
325
  }
326
  print_report(err_cnt, num_tests);
327
 
328
 
329
 
330
  // REV8
331 65 zero_gravi
  neorv32_uart0_printf("\nREV8:\n");
332 63 zero_gravi
  err_cnt = 0;
333
  for (i=0;i<num_tests; i++) {
334
    opa = xorshift32();
335
    res_sw = riscv_emulate_rev8(opa);
336
    res_hw = riscv_intrinsic_rev8(opa);
337
    err_cnt += check_result(i, opa, 0, res_sw, res_hw);
338
  }
339
  print_report(err_cnt, num_tests);
340 71 zero_gravi
#endif
341 63 zero_gravi
 
342
 
343 71 zero_gravi
#if (ENABLE_ZBA != 0)
344 66 zero_gravi
  neorv32_uart0_printf("\n\n");
345 71 zero_gravi
  neorv32_uart0_printf("--------------------------------------------\n");
346
  neorv32_uart0_printf("Zba - Address-generation instructions\n");
347
  neorv32_uart0_printf("--------------------------------------------\n");
348 66 zero_gravi
 
349
  // SH1ADD
350
  neorv32_uart0_printf("\nSH1ADD:\n");
351
  err_cnt = 0;
352
  for (i=0;i<num_tests; i++) {
353
    opa = xorshift32();
354
    opb = xorshift32();
355
    res_sw = riscv_emulate_sh1add(opa, opb);
356
    res_hw = riscv_intrinsic_sh1add(opa, opb);
357
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
358
  }
359
  print_report(err_cnt, num_tests);
360
 
361
  // SH2ADD
362
  neorv32_uart0_printf("\nSH2ADD:\n");
363
  err_cnt = 0;
364
  for (i=0;i<num_tests; i++) {
365
    opa = xorshift32();
366
    opb = xorshift32();
367
    res_sw = riscv_emulate_sh2add(opa, opb);
368
    res_hw = riscv_intrinsic_sh2add(opa, opb);
369
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
370
  }
371
  print_report(err_cnt, num_tests);
372
 
373
  // SH2ADD
374
  neorv32_uart0_printf("\nSH3ADD:\n");
375
  err_cnt = 0;
376
  for (i=0;i<num_tests; i++) {
377
    opa = xorshift32();
378
    res_sw = riscv_emulate_sh3add(opa, opb);
379
    res_hw = riscv_intrinsic_sh3add(opa, opb);
380
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
381
  }
382
  print_report(err_cnt, num_tests);
383 71 zero_gravi
#endif
384 66 zero_gravi
 
385
 
386 71 zero_gravi
#if (ENABLE_ZBS != 0)
387
  neorv32_uart0_printf("\n\n");
388
  neorv32_uart0_printf("--------------------------------------------\n");
389
  neorv32_uart0_printf("Zbs - Single-bit instructions\n");
390
  neorv32_uart0_printf("--------------------------------------------\n");
391 63 zero_gravi
 
392 71 zero_gravi
  // BCLR
393
  neorv32_uart0_printf("\nBCLR:\n");
394
  err_cnt = 0;
395
  for (i=0;i<num_tests; i++) {
396
    opa = xorshift32();
397
    opb = xorshift32();
398
    res_sw = riscv_emulate_bclr(opa, opb);
399
    res_hw = riscv_intrinsic_bclr(opa, opb);
400
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
401
  }
402
  print_report(err_cnt, num_tests);
403
 
404
  // BCLRI
405
  neorv32_uart0_printf("\nBCLRI (imm=20):\n"); // FIXME: static immediate
406
  err_cnt = 0;
407
  for (i=0;i<num_tests; i++) {
408
    opa = xorshift32();
409
    res_sw = riscv_emulate_bclr(opa, 20);
410
    res_hw = riscv_intrinsic_bclri20(opa);
411
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
412
  }
413
  print_report(err_cnt, num_tests);
414
 
415
 
416
 
417
  // BEXT
418
  neorv32_uart0_printf("\nBEXT:\n");
419
  err_cnt = 0;
420
  for (i=0;i<num_tests; i++) {
421
    opa = xorshift32();
422
    opb = xorshift32();
423
    res_sw = riscv_emulate_bext(opa, opb);
424
    res_hw = riscv_intrinsic_bext(opa, opb);
425
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
426
  }
427
  print_report(err_cnt, num_tests);
428
 
429
  // BEXTI
430
  neorv32_uart0_printf("\nBEXTI (imm=20):\n"); // FIXME: static immediate
431
  err_cnt = 0;
432
  for (i=0;i<num_tests; i++) {
433
    opa = xorshift32();
434
    res_sw = riscv_emulate_bext(opa, 20);
435
    res_hw = riscv_intrinsic_bexti20(opa);
436
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
437
  }
438
  print_report(err_cnt, num_tests);
439
 
440
 
441
 
442
  // BINV
443
  neorv32_uart0_printf("\nBINV:\n");
444
  err_cnt = 0;
445
  for (i=0;i<num_tests; i++) {
446
    opa = xorshift32();
447
    opb = xorshift32();
448
    res_sw = riscv_emulate_binv(opa, opb);
449
    res_hw = riscv_intrinsic_binv(opa, opb);
450
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
451
  }
452
  print_report(err_cnt, num_tests);
453
 
454
  // BINVI
455
  neorv32_uart0_printf("\nBINVI (imm=20):\n"); // FIXME: static immediate
456
  err_cnt = 0;
457
  for (i=0;i<num_tests; i++) {
458
    opa = xorshift32();
459
    res_sw = riscv_emulate_binv(opa, 20);
460
    res_hw = riscv_intrinsic_binvi20(opa);
461
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
462
  }
463
  print_report(err_cnt, num_tests);
464
 
465
 
466
 
467
  // BSET
468
  neorv32_uart0_printf("\nBSET:\n");
469
  err_cnt = 0;
470
  for (i=0;i<num_tests; i++) {
471
    opa = xorshift32();
472
    opb = xorshift32();
473
    res_sw = riscv_emulate_bset(opa, opb);
474
    res_hw = riscv_intrinsic_bset(opa, opb);
475
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
476
  }
477
  print_report(err_cnt, num_tests);
478
 
479
  // BSETI
480
  neorv32_uart0_printf("\nBSETI (imm=20):\n"); // FIXME: static immediate
481
  err_cnt = 0;
482
  for (i=0;i<num_tests; i++) {
483
    opa = xorshift32();
484
    res_sw = riscv_emulate_bset(opa, 20);
485
    res_hw = riscv_intrinsic_bseti20(opa);
486
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
487
  }
488
  print_report(err_cnt, num_tests);
489
#endif
490
 
491
 
492
#if (ENABLE_ZBC != 0)
493
  neorv32_uart0_printf("\n\n");
494
  neorv32_uart0_printf("--------------------------------------------\n");
495
  neorv32_uart0_printf("Zbc - Carry-less multiplication instructions\n");
496
  neorv32_uart0_printf("--------------------------------------------\n");
497
 
498
  neorv32_uart0_printf("\nNOTE: The emulation functions will take quite some time to execute.\n");
499
 
500
  // CLMUL
501
  neorv32_uart0_printf("\nCLMUL:\n");
502
  err_cnt = 0;
503
  for (i=0;i<num_tests; i++) {
504
    opa = xorshift32();
505
    opb = xorshift32();
506
    res_sw = riscv_emulate_clmul(opa, opb);
507
    res_hw = riscv_intrinsic_clmul(opa, opb);
508
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
509
  }
510
  print_report(err_cnt, num_tests);
511
 
512
  // CLMULH
513
  neorv32_uart0_printf("\nCLMULH:\n");
514
  err_cnt = 0;
515
  for (i=0;i<num_tests; i++) {
516
    opa = xorshift32();
517
    opb = xorshift32();
518
    res_sw = riscv_emulate_clmulh(opa, opb);
519
    res_hw = riscv_intrinsic_clmulh(opa, opb);
520
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
521
  }
522
  print_report(err_cnt, num_tests);
523
 
524
  // CLMULR
525
  neorv32_uart0_printf("\nCLMULR:\n");
526
  err_cnt = 0;
527
  for (i=0;i<num_tests; i++) {
528
    opa = xorshift32();
529
    opb = xorshift32();
530
    res_sw = riscv_emulate_clmulr(opa, opb);
531
    res_hw = riscv_intrinsic_clmulr(opa, opb);
532
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
533
  }
534
  print_report(err_cnt, num_tests);
535
#endif
536
 
537
 
538
  neorv32_uart0_printf("\n\nB extension tests completed.\n");
539 63 zero_gravi
  return 0;
540
}
541
 
542
 
543
/**********************************************************************//**
544 71 zero_gravi
 * Pseudo-Random Number Generator (to generate deterministic test vectors).
545 63 zero_gravi
 *
546
 * @return Random data (32-bit).
547
 **************************************************************************/
548
uint32_t xorshift32(void) {
549
 
550
  static uint32_t x32 = 314159265;
551
 
552
  x32 ^= x32 << 13;
553
  x32 ^= x32 >> 17;
554
  x32 ^= x32 << 5;
555
 
556
  return x32;
557
}
558
 
559
 
560
/**********************************************************************//**
561
 * Check results (reference (SW) vs actual hardware).
562
 *
563
 * @param[in] num Test case number
564
 * @param[in] opa Operand 1
565
 * @param[in] opb Operand 2
566
 * @param[in] ref Software reference
567
 * @param[in] res Actual results
568
 * @return zero if results are equal.
569
 **************************************************************************/
570
uint32_t check_result(uint32_t num, uint32_t opa, uint32_t opb, uint32_t ref, uint32_t res) {
571
 
572
  if (ref != res) {
573 65 zero_gravi
    neorv32_uart0_printf("%u: opa = 0x%x, opb = 0x%x : ref = 0x%x vs res = 0x%x ", num, opa, opb, ref, res);
574
    neorv32_uart0_printf("%c[1m[FAILED]%c[0m\n", 27, 27);
575 63 zero_gravi
    return 1;
576
  }
577
  else {
578
    return 0;
579
  }
580
}
581
 
582
 
583
/**********************************************************************//**
584
 * Print test report.
585
 *
586
 * @param[in] num_err Number or errors in this test.
587
 * @param[in] num_tests Total number of conducted tests.
588
 **************************************************************************/
589
void print_report(int num_err, int num_tests) {
590
 
591 65 zero_gravi
  neorv32_uart0_printf("Errors: %i/%i ", num_err, num_tests);
592 63 zero_gravi
 
593
  if (num_err == 0) {
594 65 zero_gravi
    neorv32_uart0_printf("%c[1m[ok]%c[0m\n", 27, 27);
595 63 zero_gravi
  }
596
  else {
597 65 zero_gravi
    neorv32_uart0_printf("%c[1m[FAILED]%c[0m\n", 27, 27);
598 63 zero_gravi
  }
599
}
600 71 zero_gravi
 
601
 
602
/**********************************************************************//**
603
 * "after-main" handler that is executed after the application's
604
 * main function returns (called by crt0.S start-up code)
605
 **************************************************************************/
606 73 zero_gravi
void __neorv32_crt0_after_main(int32_t return_code) {
607 71 zero_gravi
 
608
  if (return_code) {
609
    neorv32_uart0_printf("\n<RTE> main function returned with exit code (%i) </RTE>\n", return_code);
610
  }
611
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.