unsigned long val;
unsigned long res;
long diff;
+ long diff_max = 0;
unsigned int xb;
uint32_t x;
uint32_t xl;
- uint64_t yl;
+ double xf;
+ int64_t yl;
+ long count = 1;
+ long step = 1 << (30-7-18+1);
si_skspace(&ps);
if (si_ulong(&ps, &fnc, 0) < 0)
return -CMDERR_BADPAR;
si_skspace(&ps);
- if (si_ulong(&ps, &val, 0) < 0)
- return -CMDERR_BADPAR;
-
- if (fnc == 1) {
- x = val;
- xb = __builtin_clz(x);
- xl = x << xb;
+ if (!strcmp(ps, "all")) {
+ val = 0;
+ count = 0x80000000 / step;
+ if (fnc == 1) {
+ val = 1;
+ }
} else {
- xl = val;
+ if (si_ulong(&ps, &val, 0) < 0)
+ return -CMDERR_BADPAR;
}
- fpga_fncapprox_base[fnc] = xl;
-
- res = fpga_fncapprox_base[fnc];
-
- switch (fnc) {
- case 0:
- yl = xl;
- case 1:
- yl = (1LL << 62) / xl;
- break;
- case 2:
- yl = sin(xl * M_PI / 2.0 / (1UL << 30)) * (1UL << 30);
- break;
- case 3:
- yl = cos(xl * M_PI / 2.0 / (1UL << 30)) * (1UL << 30);
- break;
- default:
+ for (; count--; val += step) {
+
+ if (fnc == 1) {
+ x = val;
+ xb = __builtin_clz(x);
+ xl = x << xb;
+ } else {
+ xl = val;
+ }
+
+ fpga_fncapprox_base[fnc] = xl;
+
+ /* dummy read to provide time to function aproximator to proceed computation */
+ res = fpga_fncapprox_base[fnc];
+ res = fpga_fncapprox_base[fnc];
+
+ switch (fnc) {
+ case 0:
+ yl = xl;
+ case 1:
+ yl = (1LL << 62) / xl;
+ break;
+ case 2:
+ xf = (double)xl * M_PI / 2.0 / (1UL << 30);
+ yl = round(sin(xf) * (1UL << 16));
+ break;
+ case 3:
+ xf = (double)xl * M_PI / 2.0 / (1UL << 30);
+ yl = round(cos(xf) * (1UL << 16));
+ break;
+ default:
yl = 0;
- }
+ }
+
+ diff = yl - res;
- diff = yl - res;
+ if ((diff > 0) && (diff > diff_max))
+ diff_max = diff;
+ else if ((diff < 0) && (-diff > diff_max))
+ diff_max = -diff;
+
+ }
- printf("fnc=%ld val=0x%08lx res=0x%08lx ref=0x%08lx diff=%ld\n",
- fnc, val, res, (unsigned long)yl, diff);
+ printf("fnc=%ld val=0x%08lx res=0x%08lx ref=0x%08lx diff=%ld max %ld\n",
+ fnc, val, res, (unsigned long)yl, diff, diff_max);
return 0;
}