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

Subversion Repositories neorv32

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

Go to most recent revision | 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
// # Copyright (c) 2021, Stephan Nolting. All rights reserved.                                     #
7
// #                                                                                               #
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
/**@}*/
55
 
56
 
57
// Prototypes
58
uint32_t xorshift32(void);
59
uint32_t check_result(uint32_t num, uint32_t opa, uint32_t opb, uint32_t ref, uint32_t res);
60
void print_report(int num_err, int num_tests);
61
 
62
 
63
/**********************************************************************//**
64
 * Main function; test all available operations of the NEORV32 'Zbb' extensions
65
 * using bit manipulation intrinsics and software-only reference functions (emulation).
66
 *
67 66 zero_gravi
 * @note This program requires the bit-manipulation CPU extension.
68 63 zero_gravi
 *
69
 * @return Irrelevant.
70
 **************************************************************************/
71
int main() {
72
 
73
  uint32_t opa = 0, opb = 0, res_hw = 0, res_sw = 0;
74
  uint32_t i = 0, err_cnt = 0;
75
  const uint32_t num_tests = (int)NUM_TEST_CASES;
76
 
77
  // capture all exceptions and give debug info via UART
78
  neorv32_rte_setup();
79
 
80
  // init UART at default baud rate, no parity bits, ho hw flow control
81 65 zero_gravi
  neorv32_uart0_setup(BAUD_RATE, PARITY_NONE, FLOW_CONTROL_NONE);
82 63 zero_gravi
 
83
// Disable compilation by default
84
#ifndef RUN_CHECK
85
  #warning Program HAS NOT BEEN COMPILED! Use >>make USER_FLAGS+=-DRUN_CHECK clean_all exe<< to compile it.
86
 
87
  // inform the user if you are actually executing this
88 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");
89 63 zero_gravi
 
90
  return 1;
91
#endif
92
 
93
  // intro
94 66 zero_gravi
  neorv32_uart0_printf("NEORV32 Bit-Manipulation Extension Test (Zba, Zbb)\n\n");
95 63 zero_gravi
 
96
  // check available hardware extensions and compare with compiler flags
97
  neorv32_rte_check_isa(0); // silent = 0 -> show message if isa mismatch
98
 
99
  // check if Zbb extension is implemented at all
100 66 zero_gravi
  if ((neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_B)) == 0) {
101
    neorv32_uart0_print("Error! <B> extension not synthesized!\n");
102 63 zero_gravi
    return 1;
103
  }
104
 
105 66 zero_gravi
  neorv32_uart0_printf("Starting bit-manipulation extension tests (%i test cases per instruction)...\n\n", num_tests);
106 63 zero_gravi
 
107 66 zero_gravi
  neorv32_uart0_printf("-----------------------------------------\n");
108
  neorv32_uart0_printf("Zbb - Basic bit-manipulation instructions\n");
109
  neorv32_uart0_printf("-----------------------------------------\n");
110
 
111 63 zero_gravi
  // ANDN
112 65 zero_gravi
  neorv32_uart0_printf("\nANDN:\n");
113 63 zero_gravi
  err_cnt = 0;
114
  for (i=0;i<num_tests; i++) {
115
    opa = xorshift32();
116
    opb = xorshift32();
117
    res_sw = riscv_emulate_andn(opa, opb);
118
    res_hw = riscv_intrinsic_andn(opa, opb);
119
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
120
  }
121
  print_report(err_cnt, num_tests);
122
 
123
  // ORN
124 65 zero_gravi
  neorv32_uart0_printf("\nORN:\n");
125 63 zero_gravi
  err_cnt = 0;
126
  for (i=0;i<num_tests; i++) {
127
    opa = xorshift32();
128
    opb = xorshift32();
129
    res_sw = riscv_emulate_orn(opa, opb);
130
    res_hw = riscv_intrinsic_orn(opa, opb);
131
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
132
  }
133
  print_report(err_cnt, num_tests);
134
 
135
  // XNOR
136 65 zero_gravi
  neorv32_uart0_printf("\nXNOR:\n");
137 63 zero_gravi
  err_cnt = 0;
138
  for (i=0;i<num_tests; i++) {
139
    opa = xorshift32();
140
    opb = xorshift32();
141
    res_sw = riscv_emulate_xnor(opa, opb);
142
    res_hw = riscv_intrinsic_xnor(opa, opb);
143
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
144
  }
145
  print_report(err_cnt, num_tests);
146
 
147
 
148
 
149
  // CLZ
150 65 zero_gravi
  neorv32_uart0_printf("\nCLZ:\n");
151 63 zero_gravi
  err_cnt = 0;
152
  for (i=0;i<num_tests; i++) {
153
    opa = xorshift32();
154
    res_sw = riscv_emulate_clz(opa);
155
    res_hw = riscv_intrinsic_clz(opa);
156
    err_cnt += check_result(i, opa, 0, res_sw, res_hw);
157
  }
158
  print_report(err_cnt, num_tests);
159
 
160
  // CTZ
161 65 zero_gravi
  neorv32_uart0_printf("\nCTZ:\n");
162 63 zero_gravi
  err_cnt = 0;
163
  for (i=0;i<num_tests; i++) {
164
    opa = xorshift32();
165
    res_sw = riscv_emulate_ctz(opa);
166
    res_hw = riscv_intrinsic_ctz(opa);
167
    err_cnt += check_result(i, opa, 0, res_sw, res_hw);
168
  }
169
  print_report(err_cnt, num_tests);
170
 
171
 
172
 
173
  // CPOP
174 65 zero_gravi
  neorv32_uart0_printf("\nCPOP:\n");
175 63 zero_gravi
  err_cnt = 0;
176
  for (i=0;i<num_tests; i++) {
177
    opa = xorshift32();
178
    res_sw = riscv_emulate_cpop(opa);
179
    res_hw = riscv_intrinsic_cpop(opa);
180
    err_cnt += check_result(i, opa, 0, res_sw, res_hw);
181
  }
182
  print_report(err_cnt, num_tests);
183
 
184
 
185
 
186
  // MAX
187 65 zero_gravi
  neorv32_uart0_printf("\nMAX:\n");
188 63 zero_gravi
  err_cnt = 0;
189
  for (i=0;i<num_tests; i++) {
190
    opa = xorshift32();
191
    opb = xorshift32();
192
    res_sw = riscv_emulate_max(opa, opb);
193
    res_hw = riscv_intrinsic_max(opa, opb);
194
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
195
  }
196
  print_report(err_cnt, num_tests);
197
 
198
  // MAXU
199 65 zero_gravi
  neorv32_uart0_printf("\nMAXU:\n");
200 63 zero_gravi
  err_cnt = 0;
201
  for (i=0;i<num_tests; i++) {
202
    opa = xorshift32();
203
    opb = xorshift32();
204
    res_sw = riscv_emulate_maxu(opa, opb);
205
    res_hw = riscv_intrinsic_maxu(opa, opb);
206
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
207
  }
208
  print_report(err_cnt, num_tests);
209
 
210
  // MIN
211 65 zero_gravi
  neorv32_uart0_printf("\nMIN:\n");
212 63 zero_gravi
  err_cnt = 0;
213
  for (i=0;i<num_tests; i++) {
214
    opa = xorshift32();
215
    opb = xorshift32();
216
    res_sw = riscv_emulate_min(opa, opb);
217
    res_hw = riscv_intrinsic_min(opa, opb);
218
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
219
  }
220
  print_report(err_cnt, num_tests);
221
 
222
  // MINU
223 65 zero_gravi
  neorv32_uart0_printf("\nMINU:\n");
224 63 zero_gravi
  err_cnt = 0;
225
  for (i=0;i<num_tests; i++) {
226
    opa = xorshift32();
227
    opb = xorshift32();
228
    res_sw = riscv_emulate_minu(opa, opb);
229
    res_hw = riscv_intrinsic_minu(opa, opb);
230
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
231
  }
232
  print_report(err_cnt, num_tests);
233
 
234
 
235
 
236
  // SEXT.B
237 65 zero_gravi
  neorv32_uart0_printf("\nSEXT.B:\n");
238 63 zero_gravi
  err_cnt = 0;
239
  for (i=0;i<num_tests; i++) {
240
    opa = xorshift32();
241
    res_sw = riscv_emulate_sextb(opa);
242
    res_hw = riscv_intrinsic_sextb(opa);
243
    err_cnt += check_result(i, opa, 0, res_sw, res_hw);
244
  }
245
  print_report(err_cnt, num_tests);
246
 
247
  // SEXT.H
248 65 zero_gravi
  neorv32_uart0_printf("\nSEXT.H:\n");
249 63 zero_gravi
  err_cnt = 0;
250
  for (i=0;i<num_tests; i++) {
251
    opa = xorshift32();
252
    res_sw = riscv_emulate_sexth(opa);
253
    res_hw = riscv_intrinsic_sexth(opa);
254
    err_cnt += check_result(i, opa, 0, res_sw, res_hw);
255
  }
256
  print_report(err_cnt, num_tests);
257
 
258
  // ZEXT.H
259 65 zero_gravi
  neorv32_uart0_printf("\nZEXT.H:\n");
260 63 zero_gravi
  err_cnt = 0;
261
  for (i=0;i<num_tests; i++) {
262
    opa = xorshift32();
263
    res_sw = riscv_emulate_zexth(opa);
264
    res_hw = riscv_intrinsic_zexth(opa);
265
    err_cnt += check_result(i, opa, 0, res_sw, res_hw);
266
  }
267
  print_report(err_cnt, num_tests);
268
 
269
 
270
 
271
  // ROL
272 65 zero_gravi
  neorv32_uart0_printf("\nROL:\n");
273 63 zero_gravi
  err_cnt = 0;
274
  for (i=0;i<num_tests; i++) {
275
    opa = xorshift32();
276
    opb = xorshift32();
277
    res_sw = riscv_emulate_rol(opa, opb);
278
    res_hw = riscv_intrinsic_rol(opa, opb);
279
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
280
  }
281
  print_report(err_cnt, num_tests);
282
 
283
  // ROR
284 65 zero_gravi
  neorv32_uart0_printf("\nROR:\n");
285 63 zero_gravi
  err_cnt = 0;
286
  for (i=0;i<num_tests; i++) {
287
    opa = xorshift32();
288
    opb = xorshift32();
289
    res_sw = riscv_emulate_ror(opa, opb);
290
    res_hw = riscv_intrinsic_ror(opa, opb);
291
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
292
  }
293
  print_report(err_cnt, num_tests);
294
 
295
  // RORI
296 65 zero_gravi
  neorv32_uart0_printf("\nRORI (imm=20):\n"); // FIXME: static immediate
297 63 zero_gravi
  err_cnt = 0;
298
  for (i=0;i<num_tests; i++) {
299
    opa = xorshift32();
300
    res_sw = riscv_emulate_ror(opa, 20);
301
    res_hw = riscv_intrinsic_rori20(opa);
302
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
303
  }
304
  print_report(err_cnt, num_tests);
305
 
306
 
307
 
308
  // ORC.B
309 65 zero_gravi
  neorv32_uart0_printf("\nORCB:\n");
310 63 zero_gravi
  err_cnt = 0;
311
  for (i=0;i<num_tests; i++) {
312
    opa = xorshift32();
313
    res_sw = riscv_emulate_orcb(opa);
314
    res_hw = riscv_intrinsic_orcb(opa);
315
    err_cnt += check_result(i, opa, 0, res_sw, res_hw);
316
  }
317
  print_report(err_cnt, num_tests);
318
 
319
 
320
 
321
  // REV8
322 65 zero_gravi
  neorv32_uart0_printf("\nREV8:\n");
323 63 zero_gravi
  err_cnt = 0;
324
  for (i=0;i<num_tests; i++) {
325
    opa = xorshift32();
326
    res_sw = riscv_emulate_rev8(opa);
327
    res_hw = riscv_intrinsic_rev8(opa);
328
    err_cnt += check_result(i, opa, 0, res_sw, res_hw);
329
  }
330
  print_report(err_cnt, num_tests);
331
 
332
 
333 66 zero_gravi
 
334
  neorv32_uart0_printf("\n\n");
335
  neorv32_uart0_printf("-----------------------------------------\n");
336
  neorv32_uart0_printf("Zba - Address generation instructions\n");
337
  neorv32_uart0_printf("-----------------------------------------\n");
338
 
339
  // SH1ADD
340
  neorv32_uart0_printf("\nSH1ADD:\n");
341
  err_cnt = 0;
342
  for (i=0;i<num_tests; i++) {
343
    opa = xorshift32();
344
    opb = xorshift32();
345
    res_sw = riscv_emulate_sh1add(opa, opb);
346
    res_hw = riscv_intrinsic_sh1add(opa, opb);
347
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
348
  }
349
  print_report(err_cnt, num_tests);
350
 
351
  // SH2ADD
352
  neorv32_uart0_printf("\nSH2ADD:\n");
353
  err_cnt = 0;
354
  for (i=0;i<num_tests; i++) {
355
    opa = xorshift32();
356
    opb = xorshift32();
357
    res_sw = riscv_emulate_sh2add(opa, opb);
358
    res_hw = riscv_intrinsic_sh2add(opa, opb);
359
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
360
  }
361
  print_report(err_cnt, num_tests);
362
 
363
  // SH2ADD
364
  neorv32_uart0_printf("\nSH3ADD:\n");
365
  err_cnt = 0;
366
  for (i=0;i<num_tests; i++) {
367
    opa = xorshift32();
368
    res_sw = riscv_emulate_sh3add(opa, opb);
369
    res_hw = riscv_intrinsic_sh3add(opa, opb);
370
    err_cnt += check_result(i, opa, opb, res_sw, res_hw);
371
  }
372
  print_report(err_cnt, num_tests);
373
 
374
 
375 65 zero_gravi
  neorv32_uart0_printf("\nBit manipulation extension tests done.\n");
376 63 zero_gravi
 
377
  return 0;
378
}
379
 
380
 
381
/**********************************************************************//**
382
 * Pseudo-Random Number Generator (to generate test vectors).
383
 *
384
 * @return Random data (32-bit).
385
 **************************************************************************/
386
uint32_t xorshift32(void) {
387
 
388
  static uint32_t x32 = 314159265;
389
 
390
  x32 ^= x32 << 13;
391
  x32 ^= x32 >> 17;
392
  x32 ^= x32 << 5;
393
 
394
  return x32;
395
}
396
 
397
 
398
/**********************************************************************//**
399
 * Check results (reference (SW) vs actual hardware).
400
 *
401
 * @param[in] num Test case number
402
 * @param[in] opa Operand 1
403
 * @param[in] opb Operand 2
404
 * @param[in] ref Software reference
405
 * @param[in] res Actual results
406
 * @return zero if results are equal.
407
 **************************************************************************/
408
uint32_t check_result(uint32_t num, uint32_t opa, uint32_t opb, uint32_t ref, uint32_t res) {
409
 
410
  if (ref != res) {
411 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);
412
    neorv32_uart0_printf("%c[1m[FAILED]%c[0m\n", 27, 27);
413 63 zero_gravi
    return 1;
414
  }
415
  else {
416
    return 0;
417
  }
418
}
419
 
420
 
421
/**********************************************************************//**
422
 * Print test report.
423
 *
424
 * @param[in] num_err Number or errors in this test.
425
 * @param[in] num_tests Total number of conducted tests.
426
 **************************************************************************/
427
void print_report(int num_err, int num_tests) {
428
 
429 65 zero_gravi
  neorv32_uart0_printf("Errors: %i/%i ", num_err, num_tests);
430 63 zero_gravi
 
431
  if (num_err == 0) {
432 65 zero_gravi
    neorv32_uart0_printf("%c[1m[ok]%c[0m\n", 27, 27);
433 63 zero_gravi
  }
434
  else {
435 65 zero_gravi
    neorv32_uart0_printf("%c[1m[FAILED]%c[0m\n", 27, 27);
436 63 zero_gravi
  }
437
}

powered by: WebSVN 2.1.0

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