[ZT] cordic算法的Verilog实现---申请酷帖
本帖最后由 418478935 于 2012-3-26 22:20 编辑转自 博客园 齐威王
这个cordic写的比较易懂,我就是通过这篇博文理解了cordic的verilog实现。
现在转过来给大家看看。
module cordic
#(parameter DATA_WIDTH=8)
(
input clk,
input rst_n,
input ena,
input phase_in,
output reg sin_out,
output reg cos_out,
output reg eps
);
localparam PIPELINE=8;
reg phase_in_reg;
reg x0,y0,z0;
reg x1,y1,z1;
reg x2,y2,z2;
reg x3,y3,z3;
reg x4,y4,z4;
reg x5,y5,z5;
reg x6,y6,z6;
reg x7,y7,z7;
reg quadrant ;
integer i;
always @(posedge clk,negedge rst_n)
begin
if(!rst_n)
phase_in_reg <= 8'b0;
else
if(ena)
begin
case(phase_in)
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==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==1'b0)
begin
x2 <= x1-{y1,y1};
y2 <= y1+{x1,x1};
z2 <=z1-8'h12;//26deg
end
else
begin
x2<= x1+{y1,y1};
y2<= y1-{x1,x1};
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==1'b0)
begin
x3 <= x2-{{2{y2}},y2};
y3 <= y2+{{2{x2}},x2};
z3 <=z2-8'h09;//14deg
end
else
begin
x3<= x2+{{2{y2}},y2};
y3<= y2-{{2{x2}},x2};
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==1'b0)
begin
x4 <= x3-{{3{y3}},y3};
y4 <= y3+{{3{x3}},x3};
z4 <= z3-8'h04;//7deg
end
else
begin
x4<= x3+{{3{y3}},y3};
y4<= y3-{{3{x3}},x3};
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==1'b0)
begin
x5 <= x4-{{4{y4}},y4};
y5 <= y4+{{4{x4}},x4};
z5 <= z4-8'h02;//4deg
end
else
begin
x5<= x4+{{4{y4}},y4};
y5<= y4-{{4{x4}},x4};
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==1'b0)
begin
x6 <= x5-{{5{y5}},y5};
y6 <= y5+{{5{x5}},x5};
z6 <= z5-8'h01;//2deg
end
else
begin
x6<= x5+{{5{y5}},y5};
y6<= y5-{{5{x5}},x5};
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==1'b0)
begin
x7 <= x6-{{6{y6}},y6};
y7 <= y6+{{6{x6}},x6};
z7 <= z6-8'h00;//2deg
end
else
begin
x7<= x6+{{6{y6}},y6};
y7<= y6-{{6{x6}},x6};
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<=quadrant;
quadrant<=phase_in;
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)
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 然后是测试文件
// 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 phase;
// wires
wire cosine_out;
wire eps_out;
wire 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 跑一下,看看效果如何 http://pic002.cnblogs.com/images/2010/128091/2010122110555635.jpg
最后上图 不错,很不错 bu cuomark~ mark,最近正在搞这个算法
页:
[1]