aboutsummaryrefslogtreecommitdiffstats
path: root/benchmarks/getTanh/getTanh.cpp
blob: b30f561d8d2c819ed6a0bdd789a75c05b81173bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*

	Function Name: getTanh
	Description: This function takes one input array and generates getTanh result for each elements.
	
*/

void getTanh(int A[1000], int atanh[12], int sinh[5], int cosh[5]){
    int i;

    // the result is positive or negative
    int is_neg;
    // Input angle
    int beta;
    // Output of the hyperbolic CORDIC block
    int outputcosh, outputsinh;
    // Result of tanh, sinh and cosh
    int result;
    // Token for the repetition of the 4th iteration
    //char token4 = 0;
    // Approximation of cosh(beta) and sinh(beta)
    int x = 0x1351;
    int y = 0;
    int x_new;
    int j, k;
    int index_trigo;
    int  result_cosh, result_sinh;

  for (i = 0; i < 1000; i++){
       beta = A[i];

        // Implement approximate range of the hyperbolic CORDIC block
        if (beta >= 20480) {
          result = 4096; // Saturation effect
        } else {
	  if (beta >= 16384) {
            index_trigo = 4;
          } else if (beta >= 12288) {
            index_trigo = 3;
          } else if (beta >= 8192) {
            index_trigo = 2;
          } else if (beta >= 4096) {
            index_trigo = 1;
          } else {
            index_trigo = 0;
          }
          beta = beta - index_trigo * 4096;
          // Call to the hyperbolic CORDIC block
          x = 0x1351;
          y = 0;
          fp_hyp_cordic:
          for (k = 1; k <= 12; k++) {
            // force the 3k+1 th iteration to be repeated
            if (((k%3)==1) &&( k!=1 )){
              for (j=1;j<=2;j++){
                // beta<0 anti-clockwise rotation
                if (beta < 0) {
                  x_new = x - (y >> k);
                  y -= x >> k;
                  beta += atanh[k - 1];
                }
                // beta>0 clockwise rotation
                else {
                  x_new = x + (y >> k);
                  y += (x >> k);
                  beta -= atanh[k - 1];
                }
                x = x_new;
              }
            }
          else {
              if (beta < 0) {
                x_new = x - (y >> k);
                y -= x >> k;
                beta += atanh[k - 1];
              }
              // beta>0 clockwise rotation
              else {
                x_new = x + (y >> k);
                y += (x >> k);
                beta -= atanh[k - 1];
              }
              x = x_new;
            }
          }
	  outputcosh = x;
          outputsinh = y;

          // Trigonometric rules application
          result_cosh = (sinh[index_trigo] * outputcosh + cosh[index_trigo] * outputsinh);
          result_sinh = (cosh[index_trigo] * outputcosh + sinh[index_trigo] * outputsinh) >> 12;
          result = result_cosh / result_sinh;
        }

        A[i] = result;
  }

}

int main(){

    int atanh[12] = { 0x08C9, 0x0416, 0x0202, 0x0100, 0x0080, 0x0064, 0x0032, 0x0010, 0x0008, 0x0004, 0x0002, 0x0001 };
    int cosh[5] = { 0x1000, 0x18B0, 0x3C31, 0xA115, 0x1B4EE};
    int sinh[5] = { 0x0, 0x12CD, 0x3A07, 0xA049, 0x1B4A3};
    
    int A[1000];

    for (int i = 0; i < 1000; i++)
        A[i] = i; 	// here you can change your input data as you wish.
    

    getTanh(A, atanh, sinh, cosh);
    
}