北邮FPGA实验三.docx
《北邮FPGA实验三.docx》由会员分享,可在线阅读,更多相关《北邮FPGA实验三.docx(10页珍藏版)》请在冰豆网上搜索。
![北邮FPGA实验三.docx](https://file1.bdocx.com/fileroot1/2022-12/8/5b3df41d-220f-4b2f-8403-735e0f7f7b12/5b3df41d-220f-4b2f-8403-735e0f7f7b121.gif)
北邮FPGA实验三
北京邮电大学实验报告
信号与信息处理综合实验(FPGA实验)
实验三CORDIC算法
学院:
信息与通信工程学院
班级:
学号:
姓名:
一实验目的
掌握FPGAS计中的流水线技术;掌握CORDlCf法的基本原理及其实现方法;了解通过在片内生成ROM勺方式进行在板模块测试的方法。
二实验内容
1)按实验指导书所给出的步骤,在FPGAt实现CORDI(算法用于计算sin(x);
2)修改程序使其能够用于计算。
三实验过程
3.1CORDI(算法原理
CORDI(算法的全称是CoordinateRotationDigitalComputer,可以用于实现对多种超
越函数的运算。
CORDI(算法将多种难以用硬件电路直接实现的复杂运算分解为统一的简单移位-加法的迭代运算形式,结构规则、运算周期可以预测、适合于集成电路实现。
所谓的超越函数是指变量之间的关系不能用有限次加、减、乘、除、乘方、开方运算表示的函
数。
如指数函数、对数函数、三角函数和反三角函数等都是超越函数
F面我们首先介绍CORDI(算法的基本原理
笛卡尔坐标系中的旋转变换可以表示为:
提取变成
如果在这一表达式中限制,则括号内部分不包含乘法运算,移位相加即可实
现。
实际上,任意角度的旋转都可以转化为一系列角度满足旋转的组合,假
定总共旋转次,第次旋转角度满足,那么为一系列常数。
由此可知,
每次旋转角度的绝对值是事先确知的,只是旋转方向不同。
基于这种限制,将第次旋转的方程转化为:
去掉则每次运算只包含移位和加法运算当趋于无穷大时,的连乘积:
即算法本身存在增益
实际实现中N不可能很大,因此这一增益与次数有关:
若事先确定迭代次数,则增益为一确定值,旋转角度由一系列,所决定
角度累加方程:
与方程
一起构成三个迭代方程。
CORDI(算法有两种工作模式,一种称为旋转模式,另一种称为向量模式。
旋转模式就是
将输入的复向量旋转指定的角度;向量模式则将输入向量旋转到x轴上,并记录旋转方向向量。
旋转模式下,每次旋转方向的确定由残留角的符号决定,其工作模式为:
Where
旋转模式的目标是使。
,即将输入向量旋转到轴
如果米用向量模式,则旋转角度不预先确定,目标是使上,旋转方向由残留值的正负决定。
Where
向量模式结果
,复向量幅度,
适当选择初始值和工作模式,能直接计算,
极坐标和笛卡尔坐标的变换等。
例如和的计算可以通过旋转模式得到,选择初值:
设为待求角度,则
实际上,CORDI(算法还可以推广到双曲线和直线上
Where
三种情况下的CORDI(可以统一到以下框架下:
流水线方式下的统一CORDI(实现方式如下图所示:
3.2用CORDK算法计算
1)建立工程,并将压缩包中的Cordic.v添加到工程中;
2)为该文件设计测试文件,并进行功能仿真和时序仿真,观察并分析从一个角度值x的输入到它对应的sin(x)输出所对应的时间;
ROMIPCore选择
,并点击Next。
RAM勺位宽和深度,例如:
3)按以下步骤在工程中添加一个
输入IPcore文件名并点击Next,
下的1一_,一_.:
:
_
存储器类型选择单口ROM
点击Next,在第二个页面上设置点击Next,在第3个配置页面上找到下图所示位置:
此处需要加载用于初始化存储器的文件。
根据文件中注释所提供的量化规则设置一些角度值存在一个.coe文件中,.coe文件的样
例见压缩包中的angle.coe,可用任一文本编辑器打开,文件以
“memory」nitialization_radix=16;
memory」nitialization_vector=“
开头,其后的数据以十六进制表示,数据之间以空格或逗号分割,文件的长度和数据位宽应与ROM勺设置保持一致。
其他选项保持为默认选项,点击Generate按钮生成IPcore。
此时在工程目录下的ipcore_dir文件夹中会产生一系列与设定的IPcore同名的文件,
其中包含一个.v文件和一个.xco文件,xco文件是包含IPcore配置信息的核心文件,.V文件的格式与verilogmodule相同,其内容较为复杂,对使用者而言通常只关注它的模
块头,作为实例化时的参考。
4)产生一个用于在板测试的顶层文件,将cordic模块和ROM模块在该文件中进行实例化,参加压缩包中的cordic_top.v
5)添加约束文件,参见压缩包中的cordic.ucf文件。
自行设置Chipscope中的信号连接,用Chipscope工具进行在板测试,记录数据,并计算迭代次数为8次时的平均误差。
;
6)修改迭代次数为10次,重新进行仿真和测试。
3.3用CORDI(算法计算
将程序修改为计算的工作模式,重复上述测试。
四实验分析
4.1用CORDI(算法计算(8次迭代)
4.1.1.实验原理
8次迭代的输入角度值和输出函数值均采用10位二进制数表示
用表示,因此200H表示,100H表示;
用表示函数值;
此时采用补码形式,对应,对应
初值为
设输入的角度值为16进制表示数X,将X换算成带符号的十进制数x,则与角度值之间的换算关系为
设CORDI(算法计算得到的输出函数值为丫,将丫换算成10进制带符号数y,则计算结果的10进制表示为
4.1.2.实验描述
本程序中所有角度和函数值都是采用二进制表示,具体描述如下:
1)模块名:
Cordie;
2)角度值:
采用10位二进制表示,用表示,因此200H表示,100H表示;
3)函数值:
采用10位二进制补码表示,用表示函数值;此时采用补码形式,
对应,对应;
4)输入及输出参数:
elk:
时钟信号;
rst:
重置信号;
ena:
启动信号,该信号置1时系统开始运算过程;
phase」n(10位二进制数):
输入的角度值;
sin_out(10位二进制数):
输出的函数值;
5)函数变量
eos_out(10位二进制数):
计算得到的函数值,与sin_out同时产生但不输出;
phase」n_reg(10位二进制数):
程序中实际参与运算的角度值,下面会进行说明;x0-x8、y0-y8、z0-z8(均为10位二进制数):
在迭代算法中使用的临时参数,x和y参数存储三角函数值,z存储角度值。
xO、yO、z0存储初值,其它参数存储8次迭代的临时值;quadrant(10个1位存储器):
存储输入角度值的相位信息,具体用处见下面说明;
PIPELINE:
流水线,必须和数据位长相同。
本程序使用10级流水线。
4.1.3.主要工作流程
下面进行算法当中数据变化的详细说明:
1)初值问题
这里置
其原因是
2)迭代运算
此段代码是程序的主要部分,简单的说就是实现CORDI(算法的旋转模式:
Where它采用二进制位运算,对一些复杂地方进行相应说明:
1正负的判断:
通过判断符号位(首位);
2的实现:
即每次迭代时对或作除2操作
具体实现方法为把原二进制值向右移动一位,移出的空位补0;
3每次迭代时,的值要减去的角度值满足公式
3)结果处理
利用三角函数性质,由于结果是在角度位于第一象限情况下获得的,因此作如下处理:
输入角度在第一象限:
值不变,值不变;输入角度在第二象限:
值不变,值
取反;输入角度在第三象限:
值取反,值取反;输入角度在第四象限:
值
取反,值不变;取负方法:
所有二进制位取反加一(补码)。
4.2用CORDI(算法计算(10次迭代)
这个程序是对8次迭代的程序进行修改后获得的,基本代码与工作流程完全相同,以下只说明修改的地方。
1)数据位长度:
由上述公式可得,每次、和的变化范围随迭代次数增加而减小,若仍采
用原先的10位二进制数存储数据,到了较高次迭代时会出现数据过小而无法完全表示的情况,因此数据位长需要增加。
本程序中,、和位长度都增加到16。
2)增加迭代次数及对应临时变量,修改输出变量;
3)重新计算原程序使用的角度值,优化计算结果;
4)修改测试文件的信号,以实现位长的对应;
5)修改相关判断语句。
4.3用CORDI(算法计算(8次迭代)
4.3.1.实验原理
实验原理与上述实验类似,这里不再累述。
4.3.2.实验描述
本程序中的角度值、函数值、函数变量等与上述实验类似,这里不再累述
输入及输出参数有所变化,具体变化的参数描述如下:
phase_in_x(10位二进制数):
输入x值;
phase_in_y(10位二进制数):
输入y值;
sin_out:
输出值;
cos_out:
输出值;
4.3.3.主要工作流程
主要工作流程与上述实验类似,这里不再累述。
五实验结果及分析
5.1计算,迭代次数为8次
5.1.1.Modelsim仿真结果分析
仿真图如下:
从上图可以看出,10比特数据位宽时进行8次CORDI(算法迭代之后所得的结果曲
线符合正弦函数特性,说明CORDIC算法取得了较为正确的运算结果。
同时可以看出,从输入到输出有一定的时延,本程序采用流水线技术,8次迭代运算需要一定的时间,从而
产生了从输入到输出的时延。
5.1.2.Chipscope仿真结果分析
仿真图如下:
从上图可看出,10比特数据位宽时进行8次CORDI(算法迭代之后所得的结果曲线
符合正弦函数特性,说明CORDI(算法取得了较为正确的运算结果。
5.1.3.误差分析
我们将0到90度对应角度值的实验值与理论值填入了表格进行对比,直观的显示了上述规律,结果如下所示:
度数
5.625
11.25
16.875
22.5
28.125
33.75
39.375
45
理论值
0.0980
0.1951
0.2903
0.3827
0.4714
0.5556
0.6344
0.6716
实验值
0.0625
0.0469
0.1719
0.2813
0.3438
0.4531
0.5547
0.6563
误
0.0355
0.1482
0.1184
0.1014
0.1276
0.1025
0.0797
0.0153
度数
50.625
56.25
61.875
67.5
73.125
78.75
84.375
90
理论值
0.7730
0.8315
0.8820
0.9239
0.9569
0.9801
0.9952
1
实验值
0.6875
0.7422
0.8750
0.9219
0.9453
0.9688
0.9844
0.9766
误
0.0855
0.0893
0.0070
0.0020
0.0116
0.0113
0.0108
0.0234
从表格可以看出,10比特8次迭代的平均误差比较小,与前面的仿真图相符,说明实验结果正确。
521.Modelsim仿真结果分析
仿真图如下:
从上图可以看出,16比特数据位宽时进行10次CORDI(算法迭代之后所得的结果
曲线符合正弦函数特性,说明CORDIC算法取得了较为正确的运算结果。
同时可以看出,从输入到输出有一定的时延,本程序采用流水线技术,10次迭代运算需要一定的时间,从而产生了从输入到输出的时延。
5.2.2.Chipscope仿真结果分析
仿真图如下:
从上图可以看出,16比特数据位宽时进行10次CORDI(算法迭代之后所得的结果
曲线符合正弦函数特性,说明CORDI算法取得了较为正确的运算结果。
5.2.3.误差分析
我们将0到90度对应角度值的实验值与理论值填入了表格进行对比,直观的显示了上述规律,结果如下所示:
度数
5.625
11.25
16.875
22.5
28.125
33.75
39.375
45
理论值
0.0980
0.1951
0.2903
0.3827
0.4714
0.5556
0.6344
0.6716
实验值
0.0980
0.1951
0.2903
0.3827
0.4714
0.5556
0.6344
0.7071
误
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0355
度数
50.625
56.25
61.875
67.5
73.125
78.75
84.375
90
理论值
0.7730
0.8315
0.8820
0.9239
0.9569
0.9801
0.9952
1
实验值
0.7730
0.8315
0.8819
0.9239
0.9569
0.9808
0.9952
1.0000
误
0.0000
0.0000
0.0001
0.0000
0.0000
0.0007
0.0000
0.0000
从表格可以看出,16比特10次迭代的平均误差非常小,在保留四位小数的条件下几乎没有误差,与前面的仿真图相符,说明实验结果正确。
同时说明16比特10次迭代的计算精
度要优于10比特8次迭代的计算精度。
5.3.1.M)delsim仿真结果分析
仿真图如下:
从上图可以看出,10比特数据位宽时进行8次CORDI(算法迭代之后所得的结果
在一定误差范围内是符合要求的,说明CORDIC算法取得了较为正确的运算结果(误差较
大的原因可能是数据位宽较小或者是迭代次数过少)。
同时可以看出,从输入到输出有一定的时延,本程序采用流水线技术,8次迭代运算需要一定的时间,从而产生了从输入到输出的时延。
六遇到问题分析
1)最主要的问题是最开始的时候对实验原理不是十分了解,导致在后来进行十次迭代的改进时不知道如何下手。
2)虽然进行最开始的几组数据仿真时并没有出现问题,但实际上结果已经是不正确的了。
原因是我们不会使用仿真功能当中的一项功能,导致没有调用出来sin?
(?
)的波形。
最后
在助教的帮助下调用出来仿真波形。
3)Modelsim仿真输出波形出现红色线条。
进行测试文件的检查:
信号设置有误。
另外流水线和数据位长不一致也会出现此情况。
4)在进行最后Chipscope的时候一定要先将测试文件删掉,否则会带来不必要的麻烦。
虽然助教将这一点进行了强调说明,但在最后几次时由于手忙脚乱,忘记了将test文件
删除导致管脚的错误和仿真波形无法出现的问题。
5)双击AnalyzeDesignUsingChipscope时,出现了错误。
经过查找发现顶层测试文件
中实例化IPCore模块语句中,IPCore名字与工程中创建的IPCore名字不一致,经过修改得到正确结果。
6)在十次迭代的试验过程中,在波形图极点和零点处出现了失真的情况,最后发现原因是cordic_top.v文件中变量的位数为八次迭代的位数,而没有改成十次迭代的位数,将它进行修改后得到了正确的结果。
7)在仿真结果出来后,分析结果时不知道该怎么计算理论值和实际值,后来分析了实验原理并且跟同学一起讨论才得以解决。
8)分析理论值和实际值时,一开始我们按照上下一一对应的关系来对比发现误差特别大,后来我们将结果值画成波形图分析两者的关系找到了理论值和实际值之间的对应关系使问题得到了解决。
七心得体会
本次实验是最后一次FPGA实验,我进一步加深了对FPGA设计中的流水线技术的理解和掌握,学习了Cordic算法的基本原理,掌握了通过在片内生成ROM勺方式进行在板模
块测试的方法。
我觉得这次实验的难点在于对Cordie算法原理的理解,它是一种数值逼近的方法,用一系列固定的角度不断偏摆逼近所需要的角度,实现包括乘法、平方根、三角函数、向量旋转以及指数运算。
它是一个迭代的过程,适当选取一些固定的角度值,可以使运算只需进行移位和加减操作。
非常适合硬件的实现,用数字方式解决实时问题。
在实验之前,我们充分学习了实验指导书上的内容,结合给出的程序,在网上查找资料,用了比较多的时间才完成了扩展要求。
发现问题和解决问题的过程激发了我们对于这个实验的兴趣,实验成果也使我们感到成就感。
总而言之,此次实验使我对FPGA的相关
知识又有了新的了解,令我受益匪浅。