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

Subversion Repositories yac

[/] [yac/] [trunk/] [c_octave/] [cordic_iterative_code.m] - Blame information for rev 3

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 feddischso
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
%%%%                                                                    %%%%
3
%%%%  File           : cordic_iterative_code.m                          %%%%
4
%%%%  Project        : YAC (Yet Another CORDIC Core)                    %%%%
5
%%%%  Creation       : Feb. 2014                                        %%%%
6
%%%%  Limitations    :                                                  %%%%
7
%%%%  Platform       : Linux, Mac, Windows                              %%%%
8
%%%%  Target         : Octave, Matlab                                   %%%%
9
%%%%                                                                    %%%%
10
%%%%  Author(s):     : Christian Haettich                               %%%%
11
%%%%  Email          : feddischson@opencores.org                        %%%%
12
%%%%                                                                    %%%%
13
%%%%                                                                    %%%%
14
%%%%%                                                                  %%%%%
15
%%%%                                                                    %%%%
16
%%%%  Description                                                       %%%%
17
%%%%   Script to create VHDL and C code.                                %%%%
18
%%%%   Two functionalities are created:                                 %%%%
19
%%%%                                                                    %%%%
20
%%%%         - A division by a fixed value                              %%%%
21
%%%%           (to remove the cordic gain)                              %%%%
22
%%%%                                                                    %%%%
23
%%%%         - Atan/Atanh/Linear lookup table                           %%%%
24
%%%%%                                                                  %%%%%
25
%%%%                                                                    %%%%
26
%%%%  TODO                                                              %%%%
27
%%%%        Some documentation and function description                 %%%%
28
%%%%                                                                    %%%%
29
%%%%                                                                    %%%%
30
%%%%                                                                    %%%%
31
%%%%                                                                    %%%%
32
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33
%%%%                                                                    %%%%
34
%%%%                  Copyright Notice                                  %%%%
35
%%%%                                                                    %%%%
36
%%%% This file is part of YAC - Yet Another CORDIC Core                 %%%%
37
%%%% Copyright (c) 2014, Author(s), All rights reserved.                %%%%
38
%%%%                                                                    %%%%
39
%%%% YAC is free software; you can redistribute it and/or               %%%%
40
%%%% modify it under the terms of the GNU Lesser General Public         %%%%
41
%%%% License as published by the Free Software Foundation; either       %%%%
42
%%%% version 3.0 of the License, or (at your option) any later version. %%%%
43
%%%%                                                                    %%%%
44
%%%% YAC is distributed in the hope that it will be useful,             %%%%
45
%%%% but WITHOUT ANY WARRANTY; without even the implied warranty of     %%%%
46
%%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  %%%%
47
%%%% Lesser General Public License for more details.                    %%%%
48
%%%%                                                                    %%%%
49
%%%% You should have received a copy of the GNU Lesser General Public   %%%%
50
%%%% License along with this library. If not, download it from          %%%%
51
%%%% http://www.gnu.org/licenses/lgpl                                   %%%%
52
%%%%                                                                    %%%%
53
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
54
 
55
 
56
 
57
 
58
 
59
 
60
function cordic_iterative_code( outfile )
61
 
62
if ~exist( 'outfile', 'var' )
63
   outfile = 'autogen_code.txt';
64
end
65
 
66
fid = fopen( outfile, 'w' );
67
 
68
% TODO: calculate these values
69
K0 = 0.607252935009;
70
K1 = 0.207497067763;
71 3 feddischso
<<<<<<< HEAD
72 2 feddischso
%prod( sqrt( 1-2.^(-2 .* [ 1 : 100000 ] ) ) )
73
 
74 3 feddischso
=======
75
>>>>>>> initial commit
76 2 feddischso
 
77
signs = get_rm_gain_shifts( K0, 30 );
78
print_rm_gain_code( fid, signs, K0, 1, 1, 0 );
79
 
80
signs = get_rm_gain_shifts( K1, 30 );
81
print_rm_gain_code( fid, signs, K1, 1, 1, 1 );
82
 
83
signs = get_rm_gain_shifts( K0, 30 );
84
print_rm_gain_code( fid, signs, K0, 1, 0, 0 );
85
 
86
signs = get_rm_gain_shifts( K1, 30 );
87
print_rm_gain_code( fid, signs, K1, 1, 0, 1 );
88
 
89
MAX_A_WIDTH = 32;
90 3 feddischso
<<<<<<< HEAD
91 2 feddischso
print_angular_lut( fid, MAX_A_WIDTH );
92 3 feddischso
=======
93
print_angular_lut( fid, MAX_A_WIDTH )
94
>>>>>>> initial commit
95 2 feddischso
 
96
 
97
fclose( fid );
98
 
99
end
100
 
101
 
102
 
103
 
104
function print_angular_lut( fid, MAX_A_WIDTH )
105
 
106
 
107
    values = round( atan( 2.^-[0:MAX_A_WIDTH] ) / pi * 2^(MAX_A_WIDTH-1)  );
108
 
109
 
110
    fprintf( fid,  '-- Auto-generated function \n' );
111
    fprintf( fid,  '-- by matlab (see c_octave/cordic_iterative_code.m)\n'         );
112
    fprintf( fid,  'function angular_lut( n : integer; mode : std_logic_vector; ANG_WIDTH : natural ) return signed is\n'    );
113
    fprintf( fid,  '   variable result : signed( ANG_WIDTH-1 downto 0 );\n'   );
114
    fprintf( fid,  '   variable temp : signed( MAX_A_WIDTH-1 downto 0 );\n' );
115
    fprintf( fid,  '      begin\n' );
116
    fprintf( fid,  '      if mode = VAL_MODE_CIR then\n' );
117
    fprintf( fid,  '         case n is\n' );
118
    for x = 0 : 10
119
    val     = floor( atan( 2^-x ) * 2^(MAX_A_WIDTH+2-1) );
120
    fprintf( fid,  '            when %d => temp := "', x );
121
    fprintf( fid,  '%c',           dec2bin( val, MAX_A_WIDTH+2 ) );
122
    fprintf( fid,  '"; \t-- %d\n', val );
123
    end
124
    fprintf( fid,  '            when others => temp := to_signed( 2**(MAX_A_WIDTH-1-n), MAX_A_WIDTH );\n' );
125
    fprintf( fid,  '         end case;\n' );
126
    fprintf( fid,  '      elsif mode = VAL_MODE_HYP then\n' );
127
    fprintf( fid,  '         case n is\n' );
128
    for x = 1 : 10
129
    val = floor( atanh( 2^-x ) * 2^(MAX_A_WIDTH+2-1)  );
130
    fprintf( fid,  '            when %d => temp := "', x );
131
    fprintf( fid,  '%c', dec2bin( val, MAX_A_WIDTH+2 ) );
132
    fprintf( fid,  '"; \t-- %d\n', val);
133
    end
134
    fprintf( fid,  '            when others => temp := to_signed( 2**(MAX_A_WIDTH-1-n), MAX_A_WIDTH );\n' );
135
    fprintf( fid,  '         end case;\n' );
136
    fprintf( fid,  '      elsif mode = VAL_MODE_LIN then\n' );
137
    fprintf( fid,  '         temp := ( others => ''0'' );\n' );
138
    fprintf( fid,  '         temp( temp''high-1-n downto 0  ) := ( others => ''1'' );\n' );
139
    fprintf( fid,  '      end if;\n' );
140
    fprintf( fid,  '   result := temp( temp''high downto temp''high-result''length+1 );\n' );
141
    fprintf( fid,  '   return result;\n' );
142
    fprintf( fid,  'end function angular_lut;\n' );
143
end
144
 
145
 
146
function print_rm_gain_code( fid, signs, value, force_pos_err, c_or_vhdl, plus_one )
147
 
148
 
149
    % Default values for arguments
150
    if ~exist( 'force_pos_err', 'var' )
151
        force_neg_err = 0;
152
    end
153
 
154
    if ~exist( 'c_or_vhdl', 'var' )
155
        c_or_vhdl = 0;
156
    end
157
 
158
    val_str = sprintf( '%4.2f', value );
159
    val_str( val_str == '.' ) = ('_' );
160
 
161
    if c_or_vhdl
162
        fprintf( fid, '/*  Auto-generated procedure to multiply "x" with %f */\n', value );
163
        fprintf( fid, '/* "shifts" defines the number of shifts, which are used */\n' );
164
        fprintf( fid,  'switch( shifts )\n{\n' );
165
    end
166
    i_shift = 1;
167
    for x = 1 : length( signs )
168
        if signs( x ) ~= 0
169
 
170
            tmp     = signs( 1 : x );
171
 
172
 
173
            err = value - sum( tmp .* 2.^-( 1 : length( tmp ) ) );
174
            if force_pos_err
175
                if err < 0
176
 
177
                    if( tmp( end ) == 1 )
178
                        tmp( end+1 ) = -1;
179
                        tmp( end-1 ) = 0;
180
                    else
181
                        tmp( end-1 ) = -1;
182
                        tmp( end   ) =  0;
183
                    end
184
                end
185
                err = value - sum( tmp .* 2.^-( 1 : length( tmp ) ) );
186
            end
187
 
188
            index               = 1 : length( tmp );
189
            index( tmp == 0 )   = [];
190
            tmp( tmp == 0 )     = [];
191
            tmp2                =  cell( size ( tmp ) );
192
            tmp2( tmp ==  1 )   = { '+' };
193
            tmp2( tmp == -1 )   = { '-' };
194
 
195
            if c_or_vhdl
196
 
197
                % C-Code
198
                if plus_one
199
                    fprintf( fid,  '   case %d: x = x ', i_shift );
200
                else
201
                    fprintf( fid,  '   case %d: x = ', i_shift );
202
                end
203
 
204
                for y = 1 : length( tmp2 )
205 3 feddischso
<<<<<<< HEAD
206 2 feddischso
                    fprintf( fid,  '%c ( x >> %d ) ', tmp2{ y }, index( y ) );
207 3 feddischso
=======
208
                    fprintf( fid,  '%c ( x >> %d ) ', tmp2{ y }, index( y ) )
209
>>>>>>> initial commit
210 2 feddischso
                end
211
                fprintf( fid,  '; break; /* error: %.10f */ \n', err );
212
            else
213
 
214
                % VHDL CODE
215
 
216
                fprintf( fid, '\n\n--\n' );
217
                fprintf( fid, '-- Auto-generated procedure to multiply "a" with %f iteratively\n', value );
218
                fprintf( fid, '-- a_sh is a temporary register to store the shifted value, and \n' );
219
                fprintf( fid, '-- sum is a temporary register to sum up the result\n' );
220
                fprintf( fid, '--\n' );
221
                fprintf( fid, 'procedure mult_%s_%.2d( signal a    : in    signed; \n', val_str, i_shift );
222
                fprintf( fid, '                   signal a_sh : inout signed; \n' );
223
                fprintf( fid, '                   signal sum  : inout signed; \n' );
224
                fprintf( fid, '                          cnt  : in    natural ) is \n' );
225
                fprintf( fid, '   begin\n' );
226
                fprintf( fid, '      case cnt is\n' );
227
 
228
                if plus_one
229
                fprintf( fid, '         when   0 => sum  <= a;\n' );
230
                else
231
                fprintf( fid, '         when   0 => sum  <= to_signed( 0, sum''length );\n' );
232
                end
233
                fprintf( fid, '                     a_sh <= SHIFT_RIGHT( a, %d ); \n', index( 1 ) );
234
                fprintf( fid, '         when   1 => sum  <= sum %c a_sh; \n', tmp2{ 1 } );
235
 
236
                for y = 2 : length( tmp2 )
237
                fprintf( fid, '                 a_sh <= SHIFT_RIGHT( a, %d );\n', index( y ) );
238
                fprintf( fid, '         when %3.d => sum <= sum %c a_sh; \n', y, tmp2{ y } );
239
                end
240
                fprintf( fid, '         when others => sum <= sum;\n' );
241
                fprintf( fid, '     end case;\n' );
242
                fprintf( fid, 'end procedure mult_%s_%.2d;\n', val_str, i_shift );
243
            end
244
            i_shift = i_shift+1;
245
        end
246
 
247
    end
248
    if c_or_vhdl
249
        fprintf( fid,  '   default: x = x; break;\n}\n' );
250
    end
251
 
252
 
253
    if ~c_or_vhdl
254
        fprintf( fid, '\n\n--\n' );
255
        fprintf( fid, '-- Auto-generated procedure to multiply "a" with %f iteratively\n', value );
256
        fprintf( fid, '-- a_sh is a temporary register to store the shifted value, and \n' );
257
        fprintf( fid, '-- sum is a temporary register to sum up the result\n' );
258
        fprintf( fid, '--\n' );
259
        fprintf( fid, 'procedure mult_%s( signal   a       : in    signed; \n', val_str );
260
        fprintf( fid, '                   signal   a_sh    : inout signed; \n' );
261
        fprintf( fid, '                   signal   sum     : inout signed; \n' );
262
        fprintf( fid, '                            cnt     : in    natural; \n' );
263
        fprintf( fid, '                   constant RM_GAIN : in    natural ) is \n' );
264
        fprintf( fid, '   begin\n' );
265
        fprintf( fid, '      case RM_GAIN is\n' );
266
        for y = 1 : length( tmp2 )
267
        fprintf( fid, '         when %d => mult_%s_%.2d( a, a_sh, sum, cnt  );\n', y, val_str, y );
268
        end
269
        fprintf( fid, '         when others => mult_%s_%.2d( a, a_sh, sum, cnt  );\n', val_str, y );
270
        fprintf( fid, '      end case;\n' );
271
        fprintf( fid, 'end procedure mult_%s;\n', val_str );
272
    end
273
 
274
 
275
end
276
 
277
function signs = get_rm_gain_shifts( value, N_shifts )
278
    %N_steps = 50;
279
    %signs       = zeros( 1, N_steps );
280
    signs       = [  ];
281
    from_p_n = 1;   % comming from pos or neg
282
 
283
    prev_pos_err = inf;
284
    prev_neg_err = inf;
285
    i_shift = 0;
286
    x = 0;
287
 
288
    while i_shift < N_shifts
289
        x = x + 1;
290
        if isempty( signs )
291
            tmp = 0;
292
        else
293
            tmp = sum( signs .* 2.^-( 1 : length( signs ) ) );
294
        end;
295
 
296
        pos_err = value - ( tmp + 2^-x );
297
        neg_err = value - ( tmp - 2^-x );
298
        signs( end+1 ) = 0;
299
        if      from_p_n == 1 && pos_err < 0  ...
300
            ||  from_p_n == 0 && neg_err > 0
301
            prev_pos_err = pos_err;
302
            prev_neg_err = neg_err;
303
            continue
304
        end
305
        i_shift = i_shift+1;
306
 
307
        if from_p_n == 1 && abs( prev_pos_err ) < abs( pos_err )
308
            signs( x-1 ) = 1;
309
            from_p_n = 0;
310
            neg_err2 = value - ( tmp - 2^-x );
311
            if neg_err2 < 0
312
                signs( x ) = -1;
313
            end
314
 
315
        elseif from_p_n == 0 && abs( prev_neg_err ) < abs( neg_err )
316
            signs( x-1 ) = -1;
317
            from_p_n = 1;
318
            pos_err2 = value - ( tmp + 2^-x );
319
            if pos_err2 > 0
320
                signs( x ) =  1;
321
            end
322
 
323
 
324
        elseif from_p_n == 1 && abs( prev_pos_err ) >= abs( pos_err )
325
            signs( x ) = 1;
326
 
327
        elseif from_p_n == 0 && abs( prev_pos_err ) >= abs( pos_err )
328
            signs( x ) = -1;
329
 
330
        end
331
        prev_pos_err = pos_err;
332
        prev_neg_err = neg_err;
333
 
334
    end
335
 
336
end
337
 
338
 
339
 
340
 
341
 

powered by: WebSVN 2.1.0

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