在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 2686|回复: 6

[讨论] CORDIC 算法

[复制链接]
发表于 2017-5-14 00:37:23 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
我现在写着一个CORDIC 的 verilog 代码,但在逻辑上遇到问题。  https://www.edaplayground.com/x/3tHk , 为何 y[2] == 0 ?

cordic.zip (1.01 KB, 下载次数: 4 ) --> verilog 代码
Cordic_octave.zip (482 Bytes, 下载次数: 4 ) --> octave/matlab 代码





  1. module cordic(z0, xn, yn);
  2.   
  3.   input [21:0] z0;
  4.   output [16:0] xn, yn;

  5.   parameter N= 10; // number of iterations
  6.   
  7.   reg [(N-1):0] d;
  8.   reg [16:0] x [(N-1):0];
  9.   reg [16:0] y [(N-1):0];
  10.   reg [21:0] z [(N-1):0];
  11.   reg [21:0] arctan [(N-1):0];

  12.   initial begin
  13.    
  14.         x[0] = 'b10011011011101001;  // 0.60725 in binary
  15.           y[0] = 0;

  16.     arctan[0] = 45.0;
  17.     arctan[1] = 26.6;
  18.     arctan[2] = 14.0;
  19.     arctan[3] =  7.1;
  20.     arctan[4] =  3.6;
  21.     arctan[5] =  1.8;
  22.     arctan[6] =  0.9;
  23.     arctan[7] =  0.4;
  24.     arctan[8] =  0.2;
  25.     arctan[9] =  0.1;
  26.   end

  27.   integer i;

  28.   always @(*)
  29.     begin           z[0] = z0;
  30.       for(i=0; i<N; i=i+1)
  31.       begin
  32.         d[i] = (z[i][16] == 0) ? 0 : 1;

  33.         if(d[i] == 0) begin
  34.           x[i+1] = x[i] - y[i] >> i;
  35.           y[i+1] = y[i] + x[i] >> i;
  36.           z[i+1] = z[i] - arctan[i];
  37.         end
  38.         
  39.         else begin
  40.           x[i+1] = x[i] + y[i] >> i;
  41.           y[i+1] = y[i] - x[i] >> i;
  42.           z[i+1] = z[i] + arctan[i];
  43.         end
  44.         
  45.         $display("i=%2d, x[i]=%b, y[i]=%b, z[i]=%b, d[i]=%2d, arctan[i]=%b", i,x[i],y[i],z[i],d[i],arctan[i]);
  46.       end
  47.   end

  48.   assign xn = x[N-1]; // xn = cos(z0)
  49.   assign yn = y[N-1]; // yn = sin(z0)

  50. endmodule


复制代码





  1. `timescale 1ns/100ps

  2. module cordic_tb;

  3. reg[21:0] z0;
  4. wire[16:0] xn, yn;

  5. cordic C1
  6. (
  7.     .z0(z0), .xn(xn), .yn(yn)
  8. );

  9. initial begin
  10.     $dumpfile("cordic.vcd");
  11.     $dumpvars(0, cordic_tb);

  12.     #10 z0 = 30;
  13. end

  14. endmodule


复制代码


Screenshot from 2017-05-13 22-43-34.png



i= 0, x=10011011011101001, y=00000000000000000, z=0000000000000000011110, d= 0, arctan=0000000000000000101101
i= 1, x=10011011011101001, y=10011011011101001, z=1111111111111111110001, d= 1, arctan=0000000000000000011011
i= 2, x=00011011011101001, y=00000000000000000, z=0000000000000000001100, d= 0, arctan=0000000000000000001110
i= 3, x=00000110110111010, y=00000110110111010, z=1111111111111111111110, d= 1, arctan=0000000000000000000111
i= 4, x=00000001101101110, y=00000000000000000, z=0000000000000000000101, d= 0, arctan=0000000000000000000100
i= 5, x=00000000000110110, y=00000000000110110, z=0000000000000000000001, d= 0, arctan=0000000000000000000010
i= 6, x=00000000000000000, y=00000000000000011, z=1111111111111111111111, d= 1, arctan=0000000000000000000001
i= 7, x=00000000000000000, y=00000000000000000, z=0000000000000000000000, d= 0, arctan=0000000000000000000000
i= 8, x=00000000000000000, y=00000000000000000, z=0000000000000000000000, d= 0, arctan=0000000000000000000000
i= 9, x=00000000000000000, y=00000000000000000, z=0000000000000000000000, d= 0, arctan=0000000000000000000000
Done

发表于 2017-5-15 00:17:10 | 显示全部楼层
本帖最后由 andyme 于 2017-5-15 00:18 编辑

这是纯simulation 用途的代码?atan表没有定点化?
 楼主| 发表于 2017-5-15 17:00:39 | 显示全部楼层
回复 2# andyme


   上面纯组合逻辑电路的代码已经完成了。关于arctan 定点化,我会做的。放心。

今天,我还做了流水线的相对的代码。但是在初始化 parameterized 模块时遇到问题。 https://www.edaplayground.com/x/4ymA

为何 error: identifier `arctan` is not a parameter in cordic_pipelined_tb.C1.$gen1[0]. ??





  1. `timescale 1ns/100ps

  2. module cordic_pipelined(clk, z0, xn, yn);
  3.   
  4.   input clk;
  5.   input [9:0] z0;
  6.   output [16:0] xn, yn;
  7.   
  8.   parameter N=10;
  9.   
  10.   wire [16:0] x [(N-1):0];
  11.   wire [16:0] y [(N-1):0];
  12.   wire [ 9:0] z [(N-1):0];
  13.   
  14.   reg [ 9:0] arctan [(N-1):0];
  15.   
  16.   initial begin
  17.    
  18.     x[0] = 'b10011011011101001;  // 0.60725 in binary
  19.     y[0] = 0; z[0] = z0;
  20.    
  21.     arctan[0] = 'b101101_0000; // 45.0;
  22.     arctan[1] = 'b011010_1001; // 26.6;
  23.     arctan[2] = 'b001110_0000; // 14.0;
  24.     arctan[3] = 'b000111_0001; // 7.1;
  25.     arctan[4] = 'b000011_1001; // 3.6;
  26.     arctan[5] = 'b000001_1100; // 1.8;
  27.     arctan[6] = 'b000000_1110; // 0.9;
  28.     arctan[7] = 'b000000_0110; // 0.4;
  29.     arctan[8] = 'b000000_0011; // 0.2;
  30.     arctan[9] = 'b000000_0001; // 0.1;
  31.   end

  32.   genvar i;
  33.   generate
  34.     for(i=0; i<N; i=i+1)
  35.       begin
  36.         cordic_stage #(.atan(arctan[i]), .i(i)) stage_i
  37.         (
  38.           .clk(clk),
  39.           .x_i(x[i]), .x_o(x[i+1]),
  40.           .y_i(y[i]), .y_o(y[i+1]),
  41.           .z_i(z[i]), .z_o(z[i+1])
  42.         );
  43.       end
  44.   endgenerate

  45.   assign xn = x[N-1]; // xn = cos(z0)
  46.   assign yn = y[N-1]; // yn = sin(z0)

  47. endmodule


复制代码





  1. `timescale 1ns/100ps

  2. module cordic_stage(clk, x_i, y_i, z_i, x_o, y_o, z_o);
  3.   
  4.   parameter atan=0, i=0;
  5.   
  6.   input clk;
  7.   input [16:0] x_i, y_i;
  8.   input [9:0] z_i;
  9.   output [16:0] x_o, y_o;
  10.   output [9:0] z_o;
  11.   
  12.   reg d;
  13.   reg [16:0] x_o, x_next;
  14.   reg [16:0] y_o, y_next;
  15.   reg [9:0] z_o, z_next;
  16.   
  17.   always @ (posedge clk)
  18.     begin
  19.       x <= x_next;
  20.       y <= y_next;
  21.       z <= z_next;
  22.     end

  23.   always @(*)
  24.     begin   

  25.       d = (z_i[9] == 0) ? 0 : 1;

  26.         if(d == 0) begin
  27.           x_next = x_i - (y_i >>> i);
  28.           y_next = y_i + (x_i >>> i);
  29.           z_next = z_i - arctan;
  30.         end
  31.         
  32.         else begin
  33.           x_next = x_i + (y_i >>> i);
  34.           y_next = y_i - (x_i >>> i);
  35.           z_next = z_i + arctan;
  36.         end
  37.       
  38.       $display("i=%2d, x_i=%b, y_i=%b, z_i=%b, z_next=%b, d=%2d, arctan[i]=%b", i,x_i,y_i,z_i,z_next,d,arctan);

  39.   end

  40. endmodule


复制代码





  1. `timescale 1ns/100ps

  2. module cordic_pipelined_tb;

  3.   reg clk;
  4.   reg[9:0] z0;
  5.   wire[16:0] xn, yn;

  6.   cordic_pipelined C1
  7.   (
  8.     .clk(clk), .z0(z0), .xn(xn), .yn(yn)
  9.   );

  10.   initial begin
  11.     $dumpfile("cordic_pipelined.vcd");
  12.     $dumpvars(0, cordic_pipelined_tb);
  13.        
  14.     clk = 0;
  15.      z0 = 45;
  16.     #120 $finish;
  17.   end
  18.   
  19.   always #5 clk = !clk;

  20. endmodule


复制代码
发表于 2017-5-16 19:17:12 | 显示全部楼层
本帖最后由 加油99 于 2017-5-16 21:50 编辑

cordic_stage例化问题。链接中那样处理就很好。
 楼主| 发表于 2017-5-17 00:39:41 | 显示全部楼层
我已经实现了三个版本的cordic算法:

组合:https://www.edaplayground.com/x/449A
时钟:https://www.edaplayground.com/x/4MQN
流水线:https://www.edaplayground.com/x/4ymA

综合以前,我试图解决一些未知状态(z = xxxxxxxxxxx)。 一旦成功合成和硬件测试,我将在这直接上传所有三个版本的源代码。

为什么 https://www.diffchecker.com/9YTcSxXK 右边的代码会有未知状态(z = xxxxxxxxxxx),而左边的不会呢?

Screenshot from 2017-05-17 00-33-24.png
 楼主| 发表于 2017-5-17 11:52:40 | 显示全部楼层
我把 initial block 改成 parameter  来初始化, iverilog 有 syntax error, vcs 却没有 ?

https://www.edaplayground.com/x/449A
第15行: error: syntax error in parameter list.



  parameter [10:0] arctan [9:0] =
  {
    11'b000_0000_0001, 11'b000_0000_0011, 11'b000_0000_0110, 11'b000_0000_1110, 11'b000_0001_1100,
    11'b000_0011_1001, 11'b000_0111_0001, 11'b000_1110_0000, 11'b001_1010_1001, 11'b010_1101_0000
  };  

 楼主| 发表于 2017-5-18 20:24:54 | 显示全部楼层
解决了。发现 纯verilog 没能处理这个,systemverilog 反而可以。

以下的代码能称得上是 multi-cycle 的形式吗 ?





  1. module cordic_clocked(clk, rst, z0, xn, yn);
  2.   
  3.   input clk, rst;
  4.   input [10:0] z0;
  5.   output [16:0] xn, yn;

  6.   parameter N= 10; // number of iterations
  7.   
  8.   reg [(N-1):0] d;
  9.   reg [16:0] x [N:0];
  10.   reg [16:0] y [N:0];
  11.   reg [10:0] z [N:0];
  12.   wire [10:0] arctan [(N-1):0];       
  13.    
  14.   assign arctan[0] = 'b010_1101_0000; // 45.0;
  15.   assign arctan[1] = 'b001_1010_1001; // 26.6;
  16.   assign arctan[2] = 'b000_1110_0000; // 14.0;
  17.   assign arctan[3] = 'b000_0111_0001; // 7.1;
  18.   assign arctan[4] = 'b000_0011_1001; // 3.6;
  19.   assign arctan[5] = 'b000_0001_1100; // 1.8;
  20.   assign arctan[6] = 'b000_0000_1110; // 0.9;
  21.   assign arctan[7] = 'b000_0000_0110; // 0.4;
  22.   assign arctan[8] = 'b000_0000_0011; // 0.2;
  23.   assign arctan[9] = 'b000_0000_0001; // 0.1;

  24.   reg [3:0] i;

  25.   always @(posedge clk)
  26.     begin          
  27.       if(rst) begin
  28.               x[0] <= 'b0_10011_0110_1110_1001;  // 0.60725 in binary
  29.               y[0] <= 0;
  30.               z[0] <= z0;
  31.         i <= 0;
  32.       end
  33.       
  34.       else begin
  35.         d[i] = (z[i][10] == 0) ? 0 : 1;

  36.         if(d[i] == 0) begin
  37.           x[i+1] <= x[i] - (y[i] >> i);
  38.           y[i+1] <= y[i] + (x[i] >> i);
  39.           z[i+1] <= z[i] - arctan[i];
  40.         end
  41.         
  42.         else begin
  43.           x[i+1] <= x[i] + (y[i] >> i);
  44.           y[i+1] <= y[i] - (x[i] >> i);
  45.           z[i+1] <= z[i] + arctan[i];
  46.         end
  47.         
  48.         i <= i + 1;
  49.       end  
  50.       
  51.       $display("rst=%1b, i=%2d, x[i]=%b, y[i]=%b, z[i]=%b, d[i]=%2d, arctan[i]=%b",rst, i,x[i],y[i],z[i],d[i],arctan[i]);

  52.   end

  53.   assign xn = x[N]; // xn = cos(z0)
  54.   assign yn = y[N]; // yn = sin(z0)

  55. endmodule


复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条

X

小黑屋| 手机版| 关于我们| 联系我们| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2025-6-22 12:33 , Processed in 0.022072 second(s), 9 queries , Gzip On, MemCached On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表