【【Verilog典型电路设计之CORDIC算法的Verilog HDL 实现】】

Verilog典型电路设计之CORDIC算法的Verilog HDL 实现

典型电路设计之CORDIC算法的Verilog HDL 实现

坐标旋转数字计算机CORDIC(Coordinate Rotation Digital Computer)算法,通过移位和加减运算,能递归计算常用函数值,如sin,cos,sinh,cosh等函数,最早用于导航系统,使得矢量的旋转和定向运算不需要做查三角函数表、乘法、开方及反三角函数等复杂运算。J.Walther在1971年用它研究了一种能计算出多种超越函数的统一算法。引入参数m将CORDIC实现的三种迭代模式:三角运算、双曲运算和线性运算统一于同一个表达式下。形成目前所用的CORDIC算法的最基本的数学基础。该算法的基本思想是通过一系列固定的、与运算基数相关的角度不断偏摆以逼近所需的旋转角度。可用下列等式进行描述。



迭代结构

简单地将CORDIC算法的公式复制到硬件描述上,就可以实现迭代的cORDIC算法,其结构如下图所示。

流水线结构

流水线结构虽然比迭代结构占用的资源多,但是它大大的提高了数据的吞吐率。流水线结构是将迭代结构展开,因此n个处理单元中的每一个都可以同时并行处理一个相同的迭代运算。其结构如下图所示。

例:用Verilog HDL设计基于7级流水结构求正余弦的CORDIC算法在CORDIC算法中有一个初始的X、Y值。输入变量Z是角度变量,首先将X、Y输入到固定移位次数的移位寄存器进行移

位,然后将结果输入到加/减就完成了一次迭代,符庥次进行下去,当达到果加减操作,这样就完成了一次迭代,将此次迭代运算进行下去,当达到所需要的迭代次数(本例为((次) 的的恢付石联的加/减法器阵列。。所以整个CORDIC处理器就是一个内部互联的加/减法器阵列。

c 复制代码
module sincos(clk,rst_n,ena,phase_in,sin_out,cos_out,eps);
parameter DATA_WIDTH=8;
parameter PIPELINE=8;
input    clk;
input    rst_n;
input     ena;
input       [DATA_WIDTH-1:0] phase_in;
output     [DATA_WIDTH-1:0] sin_out;
output     [DATA_WIDTH-1:0] cos_out;
output     [DATA_WIDTH-1:0] eps;
reg  [DATA_WIDTH-1:0] sin_out;
reg  [DATA_WIDTH-1:0] cos_out;
reg  [DATA_WIDTH-1:0] eps;
reg  [DATA_WIDTH-1:0] phase_in_reg;
reg   [DATA_WIDTH-1:0] x0,y0,z0;
wire  [DATA_WIDTH-1:0]x1,y1,z1;
wire  [DATA_WIDTH-1:0]x2,y2,z2;
wire  [DATA_WIDTH-1:0]x3,y3,z3;
wire  [DATA_WIDTH-1:0]x4,y4,z4;
wire  [DATA_WIDTH-1:0]x5,y5,z5;
wire  [DATA_WIDTH-1:0]x6,y6,z6;
wire  [DATA_WIDTH-1:0]x7,y7,z7;
reg    [1:0] quadrant[PIPELINE:0];
integer i;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
phase_in_reg<=8'b0000_0000;
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 or negedge rst_n)
begin
if(!rst_n)
begin
x0<=8'b0000_0000;
y0<=8'b0000_0000;
z0<=8'b0000_0000;
end
else
if(ena)
begin
x0<=8'h4D;
y0<=8'h00;
z0<=phase_in_reg;
end
end
lteration #(8,0,8'h20)u1(.clk(clk),.rst_n(rst_n),.ena(ena),.xO(xO),.y0(y0),.z0(zO),.x1(x1),.y1(y1),.z1(z1));
lteration #(8,1,8'h12)u2(.clk(clk),.rst_n(rst_n),.ena(ena),
.xO(×1),.yo(y1),.z0(z1),.x1(×2),.y1(y2),.z1(z2));
lteration #(8,2,8'h09)u3(.clk(clk),.rst_n(rst_n),.ena(ena),
.xO(x2),.y0(y2),.z0(z2),.x1(×3),.y1(y3),.z1(z3));
lteration#(8,3,8'h04)u4(.clk(clk),.rst_n(rst_n),.ena(ena),
.xO(x3)..yo(y3),.z0(z3),.x1(x4),.y1(y4),.Z1(z4));
lteration #(8,4,8'h02)u5(.clk(clk),..rst_n(rst_n),.ena(ena),
.x0(x4),.yo(y4),.z0(z4),.x1(×5),.y1(y5),.Z1(z5));
lteration #(8,5,8'ho1)u6(.clk(clk),.rst_n(rst_n),.ena(ena),
.x0(x5),.y0(y5),.z0(z5),.x1(x6),.y1(y6),.z1(z6));
lteration #(8,6,8'ho0)u7(.clk(clk),.rst_n(rst_n),.ena(ena),
.x0(×6),.yo(y6),.z0(z6),.x1(×7),.y1(y7),.z1(z7));
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
for(i=0;i<=PIPELINE;i=i+1)
quadrant[i]<=2'b00;
else
if(ena)
begin
for(i=0;i<=PIPELINE;i=i+1)
quadrant[i+1]<=quadrant[i];
quadrant[0]<=phase_in[7:6];
end
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
sin_out<=8'b0000_0000;
cos_out<=8'b0000_0000;
eps<=8'b0000_0000;
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
//迭代模块:
module lteration(clk,rst_n,ena,x0,y0,z0,x1,y1,z1);
parameter DATA_WIDTH=8;
parameter shift=0;
parameter constant=8'h20;
input clk,rst_n,ena;
input [DATA_WIDTH-1:0]x0,y0,z0;
output[DATA_WIDTH-1:0]x1,y1,z1;
reg [DATA_WIDTH-1:0]x1,y1,z1;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
x1<=8'b0000_0000;
y1<=8'b0000_0000;
z1<=8'b0000_0000;
end
else
if(ena)
if(z0[7]==1'b0)
begin
x1<=x0-{{shift{yO[DATA_WIDTH-1]1},y0[DATA_WIDTH-1:shift]};
y1<=y0+{[shift{xO[DATA_WIDTH-1]),x0[DATA_WiDTH-1:shift]};
z1<=z0-constant;
end
else
begin
x1<=x0+{fshift{yO[DATA_WIDTH-1],y0[DATA_WIDTH-1:shift]};
y1<=y0-f{shift{xO[DATA_WIDTH-1])}.x0[DATA_WIDTH-1:shift]};
z1<=z0+constant;
end
end
endmodule

下面是testbench

c 复制代码
module sincos_tb;
reg clk,rst_n,ena;
reg [7:0]phase_in;
wire [7:0]sin_out,cos_out,eps;
sincos U1(.clk(clk),.rst_n(rst_n),.ena(ena),.phase_in(phase_in),.sin_out(sin_out),.cos_out(cos_out),.eps(eps));
initial
begin
clk=0; 
rst_n=0;
 ena=1;
phase_in=8'b0000_0000;
#3 rst_n=1;
end
always #5 clk=~clk;
always #10
phase_in=phase_in+1;
endmodule
相关推荐
倒头就睡的小比特3 天前
算法竞赛C++常用的STL
c++·算法
小羊没烦恼!3 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
猎头南楼3 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
旖旎夜光3 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
wzdark3 天前
大规模并行计算中的负载均衡算法研究4
算法
Because_of_Her13 天前
并查集-听课笔记
笔记·算法·并查集
码流子3 天前
高速公路安全监测实践:碰撞监测预警+物联网底座,从感知到处置的闭环
大数据·人工智能·物联网·算法·架构
another heaven3 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法
wzdark3 天前
从算法设计模式看编程思维的抽象能力4
算法
2601_962218613 天前
万象生鲜系统称重自动多退少补算法解决生鲜非标品痛点
大数据·数据库·人工智能·python·算法