@@ -45,10 +45,157 @@ T atan(T x) {
45
45
};
46
46
47
47
template <typename T>
48
- T atan2 (T x) {
49
- return (T) hls::atan2 (x);
48
+ T atan2 (T x, T y ) {
49
+ return (T) hls::atan2 (x, y );
50
50
};
51
51
52
+ template <class T , int W, int I>
53
+ void init_sincos_table (T table[1 <<(W - I - 3 )][2]) {
54
+ unsigned int NTE = 1 <<(W - I - 3 ); // No of table entries
55
+ double step = M_PI/(4 *NTE); // Interval between angles
56
+ double y = 0 ;
57
+ // double scaled_angle = 0;
58
+
59
+ for (unsigned int i=0 ; i < NTE; i++) {
60
+ table[i][0 ] = std::cos (y);
61
+ table[i][1 ] = std::sin (y);
62
+ y += step;
63
+ // scaled_angle = y/(2*M_PI);
64
+ // printf("cos(%f) = %23.22f, sin(%f) = %23.22f index = %d, scaled angle = %13.12f \n", y, cos(y), y, sin(y), i, scaled_angle);
65
+ }
66
+
67
+ }
68
+
69
+ template <class T >
70
+ void sincos_lut (const T &input, T output[2 ]) {
71
+
72
+ #pragma HLS INLINE
73
+
74
+ // This implementation is based on ac_sincos_lut.h from AC math library
75
+
76
+ static bool flag = true ;
77
+ if (flag && T::width-T::iwidth > 12 ) {
78
+ #if !defined(__SYNTHESIS__) && defined(SINCOS_LUT_DEBUG)
79
+ std::cout << " FILE : " << __FILE__ << " , LINE : " << __LINE__ << std::endl;
80
+ std::cout << " Warning: The output of sincos_lut will not be accurate" << std::endl;
81
+ #endif
82
+ flag = false ;
83
+ }
84
+ // Datatype for lookup table entries
85
+ typedef ap_ufixed <T::width, T::iwidth, AP_RND> luttype;
86
+ // Datatype for posinput which is used to handle negative inputs
87
+ typedef ap_ufixed<T::width-T::iwidth, 0 > posinputtype;
88
+
89
+ typedef ap_uint<9 > lutindextype; // 9 bits required for indexing into 512 entry table
90
+ typedef ap_uint<3 > octanttype; // 3 bits required for octant value range of 0 thru 7
91
+ T outputtemp[2 ];
92
+ lutindextype luTdex = 0 ;
93
+ posinputtype posinput = input;
94
+
95
+ // Initialize the lookup table
96
+ #ifdef __SYNTHESIS__
97
+ bool initialized = false ;
98
+ luttype sincos[512 ][2 ];
99
+ #else
100
+ static bool initialized = false ;
101
+ static luttype sincos[512 ][2 ];
102
+ #endif
103
+ if (!initialized) {
104
+ init_sincos_table<luttype, 12 , 0 >(sincos);
105
+ initialized = true ;
106
+ }
107
+
108
+ // Leaving this commented out makes the table to to BRAM
109
+ // #pragma HLS ARRAY_PARTITION variable=sincos complete dim=0
110
+
111
+ typedef ap_uint<AP_MAX (T::width-T::iwidth-3 , 1 )> lutindextype1;
112
+ // Extracting (MSB-3:LSB) bits of scaled input to determine the lookup table index
113
+ lutindextype1 luTdex1 = posinput.range (AP_MAX (T::width-T::iwidth-3 , 1 ), 0 ); // Extracting the lookup table index
114
+
115
+ if (T::width-T::iwidth>=4 && T::width-T::iwidth<=12 ) {
116
+ luTdex (8 , 12 - (T::width - T::iwidth)) = luTdex1; // stride
117
+ }
118
+ // Approximation for the scaled inputs whose number of bits are greater than 12
119
+ else if (T::width-T::iwidth>12 ) {
120
+ // Lookup table index for the scaled inputs whose number of bits are greater than 12
121
+ luTdex = luTdex1/(1 <<(AP_MAX (T::width-T::iwidth-12 , 0 )));
122
+ if ((luTdex1 % (1 <<(AP_MAX (T::width-T::iwidth-12 ,0 )))) > (1 <<(AP_MAX (T::width-T::iwidth-13 ,0 )))) {
123
+ luTdex = luTdex + 1 ;
124
+ }
125
+ typedef ap_ufixed<AP_MAX ((AP_MAX (T::width-T::iwidth-3 , 1 ) + T::width-T::iwidth-12 ), 1 ), AP_MAX (T::width-T::iwidth-3 , 1 )> datatype;
126
+ datatype x = (datatype)luTdex1;
127
+ x = x >> AP_MAX (T::width-T::iwidth-12 , 0 );
128
+ if (x > 511.5 ) { luTdex = 511 ; }
129
+ if (luTdex1 <= 1 <<(AP_MAX (T::width-T::iwidth-13 ,0 )) && luTdex1 != 0 ) { luTdex = 1 ; }
130
+ }
131
+
132
+ if (T::width-T::iwidth>=3 ) {
133
+ // Getting the octant 0-7 by extracting the first 3 bits from MSB side of scaled input where
134
+ // octant 0 corresponds to [0-PI/4),
135
+ // octant 1 corresponds to [PI/4-2PI/4),
136
+ // octant 2 corresponds to [2PI/4-3PI/4) and so on
137
+ // octanttype octant = posinput.template slc<3>(T::width-T::iwidth-3);
138
+ octanttype octant = posinput (T::width-T::iwidth-1 , T::width-T::iwidth-3 );
139
+ luTdex = (octant[0 ] == 1 )?(lutindextype)(512 -luTdex):(lutindextype)(luTdex);
140
+ // imaginary part is sine
141
+ outputtemp[1 ] = ((octant==0 ) | (octant==3 )) ? (T) sincos[luTdex][1 ]:
142
+ ((octant==2 ) | (octant==1 )) ? (T) sincos[luTdex][0 ]:
143
+ ((octant==7 ) | (octant==4 )) ? (T)-sincos[luTdex][1 ]:
144
+ (T)-sincos[luTdex][0 ];
145
+ // real part is cosine
146
+ outputtemp[0 ] = ((octant==6 ) | (octant==1 )) ? (T) sincos[luTdex][1 ]:
147
+ ((octant==3 ) | (octant==4 )) ? (T)-sincos[luTdex][0 ]:
148
+ ((octant==2 ) | (octant==5 )) ? (T)-sincos[luTdex][1 ]:
149
+ (T) sincos[luTdex][0 ];
150
+ // Below two are the cases when the output corresponds to + or - (0 or 1) for which there is no entry in the lookup table
151
+ output[1 ] = ((posinput==0.125 ) | (posinput==0.375 )) ? T ( 0.7071067811865475244008 ):
152
+ ((posinput==0.625 ) | (posinput==0.875 )) ? T (-0.7071067811865475244008 ):
153
+ outputtemp[1 ];
154
+ output[0 ] = ((posinput==0.125 ) | (posinput==0.875 )) ? T ( 0.7071067811865475244008 ):
155
+ ((posinput==0.375 ) | (posinput==0.625 )) ? T (-0.7071067811865475244008 ):
156
+ outputtemp[0 ];
157
+ }
158
+
159
+ if (T::width-T::iwidth <= 2 ) {
160
+ output[1 ] = (posinput==0 ) ? (T) 0 :
161
+ (posinput==0.25 ) ? (T) 1 :
162
+ (posinput==0.5 ) ? (T) 0 :
163
+ (posinput==0.75 ) ? (T)-1 :
164
+ outputtemp[1 ];
165
+ output[0 ] = (posinput==0 ) ? (T) 1 :
166
+ (posinput==0.25 ) ? (T) 0 :
167
+ (posinput==0.5 ) ? (T)-1 :
168
+ (posinput==0.75 ) ? (T) 0 :
169
+ outputtemp[0 ];
170
+ }
171
+
172
+ #if !defined(__SYNTHESIS__) && defined(SINCOS_LUT_DEBUG)
173
+ std::cout << " FILE : " << __FILE__ << " , LINE : " << __LINE__ << std::endl;
174
+ std::cout << " ============AP_FIXED SINCOS======================" << std::endl;
175
+ std::cout << " positive input is = " << posinput << std::endl;
176
+ std::cout << " lut index is = " << luTdex << std::endl;
177
+ std::cout << " sin value is = " << output[1 ] << std::endl;
178
+ std::cout << " cos value is = " << output[0 ] << std::endl;
179
+ std::cout << " =================================================" << std::endl;
180
+ #endif
181
+ }
182
+
183
+ template <class T >
184
+ T sin_lut (const T input) {
185
+ T sincos_res[2 ];
186
+ T scaled_input = input * ap_ufixed<16 ,0 >(0.15915494309 ); // 1/(2*pi)
187
+ sincos_lut (scaled_input, sincos_res);
188
+ return sincos_res[1 ];
189
+ }
190
+
191
+ template <class T >
192
+ T cos_lut (const T input) {
193
+ T sincos_res[2 ];
194
+ T scaled_input = input * ap_ufixed<16 ,0 >(0.15915494309 ); // 1/(2*pi)
195
+ sincos_lut (scaled_input, sincos_res);
196
+ return sincos_res[0 ];
197
+ }
198
+
52
199
}
53
200
54
- #endif
201
+ #endif
0 commit comments