Cordic的学习之硬件实现

上图为实现Cordic的原理框图。CORDIC的实现可以采用迭代的方式实现,这意味着CORDIC会执行一次迭代n次。CORDIC可以展开实现,即上图的结构,每一个部分处理相同的迭代,执行一次迭代一次。

  1 `timescale 1ns / 1ps
  2 module Cordic_t1(clk,rst_n,ena,phase_in,sin_out,cos_out,eps);
  3 
  4 input clk;
  5 input rst_n;
  6 input ena;
  7 
  8 //输入的角度采用16位表示
  9 //最高位表示符号位,1为负数。0为正数
 10 //接下来的7位,表示角度的整数,可表示范围为0--127
 11 //最后的8位,表示小数。可表示范围为0--1
 12 input [15:0] phase_in;//16位
 13 reg  [15:0] phase_in_reg;
 14 
 15 //最高位为符号位,剩下15位为数据位
 16 output [15:0] sin_out; //17位
 17 output [15:0] cos_out;
 18 
 19 output [15:0] eps;    //最后的相角
 20 
 21 reg [15:0] sin_out;
 22 reg [15:0] cos_out;
 23 reg [15:0] eps;
 24 
 25 //七次迭代的中间存储
 26 reg  [15:0] x0,y0,z0;
 27 reg  [15:0] x1,y1,z1;
 28 reg  [15:0] x2,y2,z2;
 29 reg  [15:0] x3,y3,z3;
 30 reg  [15:0] x4,y4,z4;
 31 reg  [15:0] x5,y5,z5;
 32 reg  [15:0] x6,y6,z6;
 33 reg  [15:0] x7,y7,z7;
 34 
 35 //初始化
 36 always @(posedge clk or negedge rst_n)
 37 begin
 38    if(!rst_n)
 39       begin   
 40          x0<=16'd0;
 41          y0<=16'd0;
 42          z0<=16'd0;
 43       end
 44    else
 45       if(ena)
 46          begin
 47             x0 <= 16'd19898;//初始化 = 1/Kn = 1/1.6467=0.60725,量化成16bit表示            
 48             y0 <= 16'd0; 
 49             z0 <= phase_in_reg; 
 50          end
 51 end
 52 
 53 //level 1--迭代第一次,角度偏移45° 
 54 always @(posedge clk or negedge rst_n)
 55 begin
 56    if(!rst_n)
 57       begin
 58          x1<=16'd0;
 59          y1<=16'd0;
 60          z1<=16'd0;
 61       end
 62    else
 63       if(ena)
 64          if(z0[15]==1'b0)   //di = 1
 65             begin
 66                x1 <= x0 - y0;
 67                y1 <= y0 + x0;
 68                z1 <= z0 - 16'd11520;  //45deg
 69             end
 70          else
 71             begin
 72                x1 <= x0 + y0;
 73                y1 <= y0 - x0;
 74                z1 <= z0 + 16'd11520;  //45deg
 75             end
 76 end
 77 //level 2--迭代第二次,角度偏移26.56° 
 78 always@(posedge clk or negedge rst_n)
 79 begin 
 80     if(!rst_n)
 81         begin
 82             x2<=16'b0;
 83             y2<=16'b0;
 84             z2<=16'b0;
 85         end
 86     else if(ena)
 87         if(z1[15]==1'b0)
 88             begin
 89                 x2 <= x1-{y1[15],y1[15:1]};
 90                 y2 <= y1+{x1[15],x1[15:1]};
 91                 z2 <= z1 - 16'b0_0010110_10001111;
 92             end
 93         else
 94             begin
 95                 x2 <= x1+{y1[15],y1[15:1]};
 96                 y2 <= y1-{x1[15],x1[15:1]};
 97                 z2 <= z1 + 16'b0_0010110_10001111;
 98             end            
 99 end
100 //level 3--迭代第三次,角度偏移14.04° 
101 always@(posedge clk or negedge rst_n)
102 begin 
103     if(!rst_n)
104         begin
105             x3<=16'b0;
106             y3<=16'b0;
107             z3<=16'b0;
108         end
109     else if(ena)
110         if(z2[15]==1'b0)
111             begin
112                 x3 <= x2-{{2{y2[15]}},y2[15:2]};
113                 y3 <= y2+{{2{x2[15]}},x2[15:2]};
114                 z3 <= z2-16'b0_0001110_00001010;
115             end
116         else
117             begin
118                 x3 <= x2+{{2{y2[15]}},y2[15:2]};
119                 y3 <= y2-{{2{x2[15]}},x2[15:2]};
120                 z3 <= z2+16'b0_0001110_00001010;
121             end            
122 end          
123 //leve 4--迭代第四次,角度偏移7.13° 
124 always @(posedge clk or negedge rst_n)
125 begin 
126     if(!rst_n)
127         begin
128             x4<=16'b0;
129             y4<=16'b0;
130             z4<=16'b0;
131         end
132     else if(ena)
133         if(z3[15]==1'b0)
134             begin
135                 x4 <= x3-{{3{y3[15]}},y3[15:3]};
136                 y4 <= y3+{{3{x3[15]}},x3[15:3]};
137                 z4 <= z3-16'b0_0000111_00100001;
138             end
139         else
140             begin
141                 x4 <= x3+{{3{y3[15]}},y3[15:3]};
142                 y4 <= y3-{{3{x3[15]}},x3[15:3]};
143                 z4 <= z3+16'b0_0000111_00100001;
144             end            
145 end 
146 
147 //leve 5--迭代第五次,角度偏移3.58° 
148 always @(posedge clk or negedge rst_n)
149 begin
150    if(!rst_n)
151       begin
152          x5<=16'b0;
153          y5<=16'b0;
154          z5<=16'b0;
155       end
156    else
157       if(ena)
158          if(z4[15]==1'b0)
159             begin
160                x5 <= x4 - {{4{y4[15]}},y4[15:4]};
161                y5 <= y4 + {{4{x4[15]}},x4[15:4]};
162                z5 <= z4 - 16'b0_0000011_10010100;  //4deg
163             end
164          else
165             begin
166                x5 <= x4 + {{4{y4[15]}},y4[15:4]};
167                y5 <= y4 - {{4{x4[15]}},x4[15:4]};
168                z5 <= z4 + 16'b0_0000011_10010100;  //4deg
169             end
170 end 
171 
172 //leve 6--迭代第6次,角度偏移1.79° 
173 always @(posedge clk or negedge rst_n)
174 begin
175    if(!rst_n)
176       begin
177          x6<=16'b0;
178          y6<=16'b0;
179          z6<=16'b0;
180       end
181    else
182       if(ena)
183          if(z5[15]==1'b0)
184             begin
185                x6 <= x5 - {{5{y5[15]}},y5[15:5]};
186                y6 <= y5 + {{5{x5[15]}},x5[15:5]};
187                z6 <= z5 - 16'b0_0000001_11001010;  //2deg
188             end
189          else
190             begin
191                x6 <= x5 + {{5{y5[15]}},y5[15:5]};
192                y6 <= y5 - {{5{x5[15]}},x5[15:5]};
193                z6 <= z5 + 16'b0_0000001_11001010;  //2deg
194             end
195 end 
196 //leve 7--迭代第7次,角度偏移0.9°  
197 always @(posedge clk or negedge rst_n)
198 begin
199    if(!rst_n)
200       begin
201          x7<=16'b0;
202          y7<=16'b0;
203          z7<=16'b0;
204       end
205    else
206       if(ena)
207          if(z6[15]==1'b0)
208             begin
209                x7 <= x6 - {{6{y6[15]}},y6[15:6]};
210                y7 <= y6 + {{6{x6[15]}},x6[15:6]};
211                z7 <= z6 - 16'b0_0000000_11100110;   
212             end
213          else
214             begin
215                x7 <= x6 + {{6{y6[15]}},y6[15:6]};
216                y7 <= y6 - {{6{x6[15]}},x6[15:6]};
217                z7 <= z6 + 16'b0_0000000_11100110;   
218             end
219 end 
220 always@(posedge clk or negedge rst_n)
221 if(!rst_n)begin
222     sin_out<=16'd0;; //17位
223     cos_out<=16'd0;
224     eps<=16'd0;     
225 end
226 else
227 begin 
228     sin_out<=x7; //17位
229     cos_out<=y7;
230     eps<=z7;     
231 end
232 ////把相角象限范围限制在[0,pi/2]
233 //always @(posedge clk or negedge rst_n)
234 //begin
235 //   if(!rst_n)
236 //      phase_in_reg<=16'd0;
237 //   else
238 //      if(ena)
239 //         begin
240 //            case(phase_in[15:14])
241 //               2'b00:phase_in_reg<=phase_in;
242 //               2'b01:phase_in_reg<=phase_in - 8'h40;  //-pi/2
243 //               2'b10:phase_in_reg<=phase_in - 8'h80;  //-pi
244 //               2'b11:phase_in_reg<=phase_in - 8'hc0;  //-3pi/2
245 //               default:;
246 //            endcase
247 //         end
248 //end
249 ////remain the quadrant information for 'duiqi'
250 //integer i;
251 //reg [1:0]quadrant[15:0];
252 //always @(posedge clk or negedge rst_n)
253 //begin
254 //   if(!rst_n)
255 //      for(i=0; i<=15; i=i+1)
256 //         quadrant[i]<=2'b00;
257 //   else
258 //      if(ena)
259 //         begin
260 //            for(i=0; i<15; i=i+1)
261 //               quadrant[i+1]<=quadrant[i];
262 //               quadrant[0]<=phase_in[15:14];
263 //         end
264 //end
265 //
266 //always @(posedge clk or negedge rst_n)
267 //begin
268 //   if(!rst_n)
269 //      begin
270 //         sin_out <= 16'd0;
271 //         cos_out <= 16'd0;
272 //         eps <= 16'd0;
273 //      end
274 //   else
275 //      if(ena)
276 //         case(quadrant[15])
277 //            2'b00:begin
278 //                     sin_out <= y6; 
279 //                     cos_out <= x6;
280 //                     eps <= z6;
281 //                  end
282 //            2'b01:begin
283 //                     sin_out <= x6; 
284 //                     cos_out <= ~(y6) + 1'b1;
285 //                     eps <= z6;
286 //                  end
287 //            2'b10:begin
288 //                     sin_out <= ~(y6) + 1'b1; 
289 //                     cos_out <= ~(x6) + 1'b1;
290 //                     eps <= z6;
291 //                  end
292 //            2'b11:begin
293 //                     sin_out <= ~(x6) + 1'b1; 
294 //                     cos_out <= y6;
295 //                     eps <= z6;
296 //                  end
297 //         endcase
298 //end
299 
300 endmodule

这段代码验证的是CORDIC旋转模式下的情况,有关于旋转模式的具体细节参考网址:

http://wenku.baidu.com/view/9b70ff64783e0912a2162a5c.html

原文地址:https://www.cnblogs.com/ytfei1990/p/3658527.html