/* * This file is part of the cordic project. * Copyright 2026 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include "test.h" #include "hardware.h" #include "cordic.h" // amount of iterations over test #define N_TESTS 1000 static float arr[N_TESTS]; // RNG static uint32_t rand_state = 123456789; static uint32_t next_rand(){ rand_state = rand_state * 1664525 + 1013904223; return rand_state; } // fill array with random angles static void fill_random_sin_cos(){ for(int i = 0; i < N_TESTS; ++i){ // angle from -pi to +pi arr[i] = (float)(next_rand() % 62831853) / 10000000.0f - 3.14159265f; } } static void fill_random_atan(){ for(int i = 0; i < N_TESTS; ++i){ arr[i] = (float)(next_rand() % 2000000) / 1e6f - 1e6f; // [-1,1] } } static void fill_random_sqrt(){ for(int i = 0; i < N_TESTS; ++i){ arr[i] = (float)(next_rand() % 10000) / 100.0f; // [0,100] } } static void fill_random_log(){ for(int i = 0; i < N_TESTS; ++i){ arr[i] = (float)(next_rand() % 10000 + 1) / 100.0f; // [0.01, 100] } } // main test template static uint32_t run_test(void (*gen)(), float (*func)(float)){ gen(); volatile float result = 0.0f; // don't let gcc to optimize this cycle timer_start(); for(int i = 0; i < N_TESTS; ++i){ result = func(arr[i]); (void) result; } timer_stop(); return timer_read(); } static uint32_t run_test2(void (*gen)(), void (*func)(float, float*, float*)){ gen(); volatile float result1 = 0.f, result2 = 0.f; // don't let gcc to optimize this cycle timer_start(); for(int i = 0; i < N_TESTS; ++i){ func(arr[i], (float*)&result1, (float*)&result2); (void) result1; (void) result2; } timer_stop(); return timer_read(); } // ------------- math.h tests ------------- uint32_t test_math_sin(){ return run_test(fill_random_sin_cos, sinf); } uint32_t test_math_cos(){ return run_test(fill_random_sin_cos, cosf); } uint32_t test_math_atan(){ return run_test(fill_random_atan, atanf); } uint32_t test_math_sqrt(){ return run_test(fill_random_sqrt, sqrtf); } uint32_t test_math_log(){ return run_test(fill_random_log, logf); } // ------------- CORDIC tests ------------- uint32_t test_cordic_sincos(){ return run_test2(fill_random_sin_cos, cordic_sincos); } uint32_t test_cordic_sin(){ return run_test(fill_random_sin_cos, cordic_sin); } uint32_t test_cordic_cos(){ return run_test(fill_random_sin_cos, cordic_cos); } uint32_t test_cordic_atan(){ return run_test(fill_random_atan, cordic_atan); } uint32_t test_cordic_sqrt(){ return run_test(fill_random_sqrt, cordic_sqrt); } uint32_t test_cordic_log(){ return run_test(fill_random_log, cordic_log); }