Cordic算法FPGA实现距离计算distance=√(x^2+y^2 )(含python和verilog代码)-FPGA常见问题社区-FPGA CPLD-ChipDebug

Cordic算法FPGA实现距离计算distance=√(x^2+y^2 )(含python和verilog代码)

“ 上一篇文章Cordic算法FPGA实现cos,sin讲解了Cordic算法实现sin,cos等函数,本篇讲解Cordic算法实现distance=√(x^2+y^2 ),即根据直角三角形两直角边求斜边边长。”

如果对Cordic算法的核心思想不了解或者想得到更好的理解,可以先阅读上一篇文章“Cordic算法实现sin,cos”。

从上一篇文章,可知Cordic算法其实就是一个循环迭代的思想。

仍然借助上一篇文章的基础,旋转迭代16次,每次迭代的角度如下(为何取这些迭代角度,见“Cordic算法实现sin,cos”):

`define angle0  45.0                             
`define angle1  26.56505117707799                
`define angle2  14.036243467926479               
`define angle3  7.125016348901798                
`define angle4  3.576334374997351                
`define angle5  1.789910608246069               
`define angle6  0.895173710211074               
`define angle7  0.44761417086055               
`define angle8  0.22381050036853          
`define angle9  0.11190567706620       
`define angle10 0.05595289189380      
`define angle11 0.02797645261700        
`define angle12 0.01398822714226            
`define angle13 0.00699411367535          
`define angle14 0.00349705685070           
`define angle15 0.00174852842698

根据当(x1,y1)转过θ角之后,到达点(x2,y2),有如下等式关系(根据三角函数的角度加减运算推导一下就出来了)。
x2 = rcos(θ0+θ) = x1cosθ-y1sinθ = cosθ(x1 - y1tanθ)
y2 = rsin(θ0+θ) = x1sinθ+y1cosθ = cosθ(y1 + x1tanθ)

在上一篇根据角度求sin,cos值时,我们以旋转的角度作为下次旋转方向的判断,即每次迭代旋转的角度都减半,旋转之后如果大于所要求的角度值,就顺时钟回转,否则逆时钟转动,最终其就会向我们所要求的角度值位置逼近。初始化x=1,y=0,旋转16次后得到的x,y就是对应的cos,sin值。

这次我们是要求distance=√(x^2+y^2 ),即直角三角形斜边长度。旋转迭代逼近思想如下。

根据两直角边x,y的值确定其初始位置,然后将其向x轴旋转逼近,最终得到的x值就是就是原直线的的长度,即直角边长度,演示视屏如下(初始x=100,y = 400,迭代16次后得到y = 0,x = 412.310562即√(x^2+y^2 ))
图片[1]-Cordic算法FPGA实现距离计算distance=√(x^2+y^2 )(含python和verilog代码)-FPGA常见问题社区-FPGA CPLD-ChipDebug

##01 python软件模型

for i in range(0,16) :
    arctan_value[i] = (1/2)**i
angle_e = np.degrees(np.arctan(arctan_value))
cos_e = np.cos(angle_e*np.pi/180)
k = 1
for i in range(0,16):
    k = cos_e[i]*k
x = 100
y = 400
angle = 0
x_p1 = np.zeros((17,2))
y_p1 = np.zeros((17,2))
for i in range(0,16):
    #get picture of x,y
    x_p1[i] = [0,x]
    y_p1[i] = [0,y]
    if y < 0:
        x_h = x - y*arctan_value[i]
        y_h = y + x*arctan_value[i]
        angle = angle - angle_e[i]
    else :
        x_h = x + y*arctan_value[i]
        y_h = y - x*arctan_value[i]
        angle = angle + angle_e[i]
    x = x_h
    y = y_h
    print(angle)
distance = x*k
print(distance)

02 verilog硬件实现

采用16级流水结构。为了避免浮点数的运算,将原始数据都扩大了2^16,不过运算结果distance就是真正的√(x^2+y^2 )。

请登录后发表评论