搜索
bottom↓
回复: 6

[ZT] cordic算法的Verilog实现---申请酷帖

[复制链接]

出0入0汤圆

发表于 2012-3-26 22:11:44 | 显示全部楼层 |阅读模式
本帖最后由 418478935 于 2012-3-26 22:20 编辑

转自 博客园 齐威王

这个cordic写的比较易懂,我就是通过这篇博文理解了cordic的verilog实现。

现在转过来给大家看看。

module cordic
#(parameter DATA_WIDTH=8)
(
    input clk,
    input rst_n,
    input ena,
    input [DATA_WIDTH-1:0] phase_in,
    output reg [DATA_WIDTH-1:0] sin_out,
    output reg [DATA_WIDTH-1:0] cos_out,
    output reg [DATA_WIDTH-1:0] eps
);

localparam PIPELINE=8;

reg [DATA_WIDTH-1:0] phase_in_reg;
reg [DATA_WIDTH-1:0] x0,y0,z0;
reg [DATA_WIDTH-1:0] x1,y1,z1;
reg [DATA_WIDTH-1:0] x2,y2,z2;
reg [DATA_WIDTH-1:0] x3,y3,z3;
reg [DATA_WIDTH-1:0] x4,y4,z4;
reg [DATA_WIDTH-1:0] x5,y5,z5;
reg [DATA_WIDTH-1:0] x6,y6,z6;
reg [DATA_WIDTH-1:0] x7,y7,z7;

reg [1:0] quadrant [PIPELINE:0];
integer i;

always @(posedge clk,negedge rst_n)
begin
    if(!rst_n)
        phase_in_reg <= 8'b0;
    else
        if(ena)
        begin
            case(phase_in[7:6])
                2'b00: phase_in_reg <= phase_in;
                2'b01: phase_in_reg <= phase_in-8'h40;
                2'b10: phase_in_reg <= phase_in-8'h80;
                2'b11: phase_in_reg <= phase_in-8'hc0;
                default:;
            endcase
        end
end

always @ (posedge clk,negedge rst_n)
begin
    if(!rst_n)
        begin
            x0<=8'b0;
            y0<=8'b0;
            z0<=8'b0;
        end
    else
        if(ena)
        begin
            x0 <= 8'h4D;       //0.60725*2^7
            y0 <= 8'h00;
            z0 <= phase_in_reg;
        end
end

//level 1
always @ (posedge clk,negedge rst_n)
begin
    if(!rst_n)
    begin
        x1 <=8'b0;
        y1 <=8'b0;
        z1 <=8'b0;
    end
    else
    if(ena)
        if(z0[7]==1'b0)
        begin
            x1 <= x0-y0;
            y1 <= y0+x0;
            z1 <=z0-8'h20;//45deg
        end
        else
        begin
            x1<=x0+y0;
            y1<=y0-x0;
            z1<=z0+8'h20;
        end
end
//level 2
always @ (posedge clk,negedge rst_n)
begin
    if(!rst_n)
    begin
        x2 <=8'b0;
        y2 <=8'b0;
        z2 <=8'b0;
    end
    else
    if(ena)
        if(z1[7]==1'b0)
        begin
            x2 <= x1-{y1[DATA_WIDTH-1],y1[DATA_WIDTH-1:1]};
            y2 <= y1+{x1[DATA_WIDTH-1],x1[DATA_WIDTH-1:1]};
            z2 <=z1-8'h12;//26deg
        end
        else
        begin
            x2<= x1+{y1[DATA_WIDTH-1],y1[DATA_WIDTH-1:1]};
            y2<= y1-{x1[DATA_WIDTH-1],x1[DATA_WIDTH-1:1]};
            z2<= z1+8'h12;
        end
end
//level 3
always @ (posedge clk,negedge rst_n)
begin
    if(!rst_n)
    begin
        x3 <=8'b0;
        y3 <=8'b0;
        z3 <=8'b0;
    end
    else
    if(ena)
        if(z2[7]==1'b0)
        begin
            x3 <= x2-{{2{y2[DATA_WIDTH-1]}},y2[DATA_WIDTH-1:2]};
            y3 <= y2+{{2{x2[DATA_WIDTH-1]}},x2[DATA_WIDTH-1:2]};
            z3 <=z2-8'h09;//14deg
        end
        else
        begin
            x3<= x2+{{2{y2[DATA_WIDTH-1]}},y2[DATA_WIDTH-1:2]};
            y3<= y2-{{2{x2[DATA_WIDTH-1]}},x2[DATA_WIDTH-1:2]};
            z3<= z2+8'h09;
        end
end
//level 4
always @ (posedge clk,negedge rst_n)
begin
    if(!rst_n)
    begin
        x4 <=8'b0;
        y4 <=8'b0;
        z4 <=8'b0;
    end
    else
    if(ena)
        if(z3[7]==1'b0)
        begin
            x4 <= x3-{{3{y3[DATA_WIDTH-1]}},y3[DATA_WIDTH-1:3]};
            y4 <= y3+{{3{x3[DATA_WIDTH-1]}},x3[DATA_WIDTH-1:3]};
            z4 <= z3-8'h04;//7deg
        end
        else
        begin
            x4<= x3+{{3{y3[DATA_WIDTH-1]}},y3[DATA_WIDTH-1:3]};
            y4<= y3-{{3{x3[DATA_WIDTH-1]}},x3[DATA_WIDTH-1:3]};
            z4<= z3+8'h04;
        end
end
//level 5
always @ (posedge clk,negedge rst_n)
begin
    if(!rst_n)
    begin
        x5 <=8'b0;
        y5 <=8'b0;
        z5 <=8'b0;
    end
    else
    if(ena)
        if(z4[7]==1'b0)
        begin
            x5 <= x4-{{4{y4[DATA_WIDTH-1]}},y4[DATA_WIDTH-1:4]};
            y5 <= y4+{{4{x4[DATA_WIDTH-1]}},x4[DATA_WIDTH-1:4]};
            z5 <= z4-8'h02;//4deg
        end
        else
        begin
            x5<= x4+{{4{y4[DATA_WIDTH-1]}},y4[DATA_WIDTH-1:4]};
            y5<= y4-{{4{x4[DATA_WIDTH-1]}},x4[DATA_WIDTH-1:4]};
            z5<= z4+8'h02;
        end
end
//level 6
always @ (posedge clk,negedge rst_n)
begin
    if(!rst_n)
    begin
        x6 <=8'b0;
        y6 <=8'b0;
        z6 <=8'b0;
    end
    else
    if(ena)
        if(z5[7]==1'b0)
        begin
            x6 <= x5-{{5{y5[DATA_WIDTH-1]}},y5[DATA_WIDTH-1:5]};
            y6 <= y5+{{5{x5[DATA_WIDTH-1]}},x5[DATA_WIDTH-1:5]};
            z6 <= z5-8'h01;//2deg
        end
        else
        begin
            x6<= x5+{{5{y5[DATA_WIDTH-1]}},y5[DATA_WIDTH-1:5]};
            y6<= y5-{{5{x5[DATA_WIDTH-1]}},x5[DATA_WIDTH-1:5]};
            z6<= z5+8'h01;
        end
end
//level 7
always @ (posedge clk,negedge rst_n)
begin
    if(!rst_n)
    begin
        x7 <=8'b0;
        y7 <=8'b0;
        z7 <=8'b0;
    end
    else
    if(ena)
        if(z6[7]==1'b0)
        begin
            x7 <= x6-{{6{y6[DATA_WIDTH-1]}},y6[DATA_WIDTH-1:6]};
            y7 <= y6+{{6{x6[DATA_WIDTH-1]}},x6[DATA_WIDTH-1:6]};
            z7 <= z6-8'h00;//2deg
        end
        else
        begin
            x7<= x6+{{6{y6[DATA_WIDTH-1]}},y6[DATA_WIDTH-1:6]};
            y7<= y6-{{6{x6[DATA_WIDTH-1]}},x6[DATA_WIDTH-1:6]};
            z7<= z6+8'h00;
        end
end
//-------
always @ (posedge clk,negedge rst_n)
begin
    if(!rst_n)
        for(i=0;i<=PIPELINE;i=i+1)
            quadrant<=2'b00;
    else
        if(ena)
            begin
                for(i=0;i<PIPELINE;i=i+1)
                    quadrant[i+1]<=quadrant;
                quadrant[0]<=phase_in[7:6];
            end
end
//------------
always @ (posedge clk,negedge rst_n)
begin
    if(!rst_n)
    begin
        sin_out <= 8'b0;
        cos_out <= 8'b0;
        eps     <= 8'b0;
    end
    else
        if(ena)
        case(quadrant[7])
            2'b00:
                begin
                    sin_out <= y6;
                    cos_out <= x6;
                    eps     <= z6;
                end
            2'b01:
                begin
                    sin_out <= x6;
                    cos_out <= ~(y6)+1'b1;
                    eps     <= z6;
                end
            2'b10:
                begin
                    sin_out <= ~(y6)+1'b1;
                    cos_out <= ~(x6)+1'b1;
                    eps     <= z6;
                end
            2'b11:
                begin
                    sin_out <= ~(x6)+1'b1;
                    cos_out <= y6;
                    eps     <= z6;
                end
         endcase
end

endmodule

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2012-3-26 22:12:19 | 显示全部楼层
然后是测试文件
// Generated on "05/21/2010 10:09:04"
                                                                                 
// Verilog Test Bench template for design : cordic
//
// Simulation tool : ModelSim (Verilog)
//

`timescale 1 ps/ 1 ps
module cordic_tb;
// test vector input registers
reg arst;
reg clk;
reg clken;
reg [7:0] phase;
// wires                                             
wire [7:0] cosine_out;
wire [7:0] eps_out;
wire [7:0] sine_out;
//
localparam coef=1000;
// assign statements (if any)                        
cordic i1 (
// port map - connection between master ports and signals/registers  
    .rst_n(arst),
    .clk(clk),
    .ena(clken),
    .cos_out(cosine_out),
    .eps(eps_out),
    .phase_in(phase),
    .sin_out(sine_out)
);
initial                                               
begin
  clk=0;
  clken=1;
  arst=0;
  #(30*coef) arst=1;
  #(10000*coef) $stop;                                          
end                                                   
always #(5*coef) clk=~clk;
//
always @(negedge clk)
begin
  if(!arst)
    phase=0;
  else
    phase=phase+8'b00011001;;
end                                
endmodule

出0入0汤圆

发表于 2012-3-26 22:14:14 | 显示全部楼层
跑一下,看看效果如何

出0入0汤圆

 楼主| 发表于 2012-3-26 22:14:27 | 显示全部楼层


最后上图

出0入0汤圆

发表于 2012-4-7 13:40:29 | 显示全部楼层
不错,很不错

出0入0汤圆

发表于 2012-4-30 19:24:04 | 显示全部楼层
bu cuo  mark~

出0入0汤圆

发表于 2014-6-12 11:03:48 | 显示全部楼层
mark,最近正在搞这个算法
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 03:21

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表