您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > 北邮-FPGA-实验三
1北京邮电大学实验报告信号与信息处理综合实验(FPGA实验)实验三CORDIC算法学院:信息与通信工程学院班级:学号:姓名:2一实验目的掌握FPGA设计中的流水线技术;掌握CORDIC算法的基本原理及其实现方法;了解通过在片内生成ROM的方式进行在板模块测试的方法。二实验内容1)按实验指导书所给出的步骤,在FPGA上实现CORDIC算法用于计算sin(x);2)修改程序使其能够用于计算√𝑥2+𝑦2。三实验过程3.1CORDIC算法原理CORDIC算法的全称是CoordinateRotationDigitalComputer,可以用于实现对多种超越函数的运算。CORDIC算法将多种难以用硬件电路直接实现的复杂运算分解为统一的简单移位-加法的迭代运算形式,结构规则、运算周期可以预测、适合于集成电路实现。所谓的超越函数是指变量之间的关系不能用有限次加、减、乘、除、乘方、开方运算表示的函数。如指数函数、对数函数、三角函数和反三角函数等都是超越函数。最初的CORDIC算法由J.D.Volder于1959年提出,用于计算三角函数。1971年,Walther提出了统一的CORDIC算法,引入了参数m将CORDIC实现的三种迭代模式:圆周、双曲和线性变换统一于一个表达式下。CORDIC算法目前使用非常广泛,被称为算法中的瑞士军刀。下面我们首先介绍CORDIC算法的基本原理。笛卡尔坐标系中的旋转变换可以表示为:x′=𝑥𝑐𝑜𝑠𝜙−𝑦𝑠𝑖𝑛𝜙𝑦′=𝑦𝑐𝑜𝑠𝜙+𝑥𝑠𝑖𝑛𝜙提取𝑐𝑜𝑠𝜙变成𝑥′=𝑐𝑜𝑠𝜙(𝑥−𝑦𝑡𝑎𝑛𝜙)𝑥′=𝑐𝑜𝑠𝜙(𝑦+𝑥𝑡𝑎𝑛𝜙)如果在这一表达式中限制𝑡𝑎𝑛𝜙=±2−𝑖,则括号内部分不包含乘法运算,移位相加即可实现。实际上,任意角度的旋转都可以转化为一系列角度满足𝑡𝑎𝑛𝜙=±2−𝑖旋转的组合,假定总共旋转𝑁次,第𝑖次旋转角度满足𝑡𝑎𝑛𝜙=±2−𝑖,那么𝑐𝑜𝑠𝜙为一系列常数。由此可知,每次旋转角度的绝对值是事先确知的,只是旋转方向不同。基于这种限制,将第𝑖次旋转的方程转化为:𝑥𝑖+1=𝐾𝑖[𝑥𝑖−𝑦𝑖∙𝑑𝑖∙2−𝑖]𝑦𝑖+1=𝐾𝑖[𝑦𝑖+𝑥𝑖∙𝑑𝑖∙2−𝑖]𝐾𝑖=𝑐𝑜𝑠(𝑡𝑎𝑛−12−𝑖)=1/√1+2−2𝑖𝑑𝑖=±13去掉𝐾𝑖则每次运算只包含移位和加法运算。当𝑁趋于无穷大时,𝐾𝑖的连乘积:𝐾=∏cos[𝑎𝑟𝑐𝑡𝑎𝑛(12𝑛)]≈0.607253∞0即算法本身存在增益𝐴𝑛=1.647实际实现中N不可能很大,因此这一增益与次数有关:𝐴𝑛=∏√1+2−2𝑖𝑛若事先确定迭代次数,则增益为一确定值,旋转角度由一系列{+1,−1}所决定角度累加方程:zi+1=𝑧𝑖−𝑑𝑖∙tan−1(2−𝑖)与方程𝑥𝑖+1=𝐾𝑖[𝑥𝑖−𝑦𝑖∙𝑑𝑖∙2−𝑖]𝑦𝑖+1=𝐾𝑖[𝑦𝑖+𝑥𝑖∙𝑑𝑖∙2−𝑖]一起构成三个迭代方程。CORDIC算法有两种工作模式,一种称为旋转模式,另一种称为向量模式。旋转模式就是将输入的复向量旋转指定的角度;向量模式则将输入向量旋转到x轴上,并记录旋转方向向量。旋转模式下,每次旋转方向的确定由残留角的符号决定,其工作模式为:𝑥𝑖+1=𝑥𝑖−𝑦𝑖∙𝑑𝑖∙2−𝑖𝑦𝑖+1=𝑦𝑖+𝑥𝑖∙𝑑𝑖∙2−𝑖zi+1=𝑧𝑖−𝑑𝑖∙tan−1(2−𝑖)Where𝑑𝑖=−1𝑖𝑓𝑧𝑖0,+1𝑜𝑡ℎ𝑒𝑟𝑤𝑖𝑠𝑒旋转模式的目标是使𝑧𝑛=0。如果采用向量模式,则旋转角度不预先确定,目标是使𝑦𝑛=0,即将输入向量旋转到𝑥轴上,旋转方向由残留𝑦值的正负决定。𝑥𝑖+1=𝑥𝑖−𝑦𝑖∙𝑑𝑖∙2−𝑖𝑦𝑖+1=𝑦𝑖+𝑥𝑖∙𝑑𝑖∙2−𝑖zi+1=𝑧𝑖−𝑑𝑖∙tan−1(2−𝑖)Where𝑑𝑖=+1𝑖𝑓𝑦𝑖0,−1𝑜𝑡ℎ𝑒𝑟𝑤𝑖𝑠𝑒向量模式结果𝑥𝑛=𝐴𝑛√𝑥02+𝑦02𝑦𝑛=0𝑧𝑛=𝑧0+𝑡𝑎𝑛−1(𝑦0/𝑥0)𝐴𝑛=∏√1+2−2𝑖𝑛4适当选择初始值和工作模式,能直接计算𝑠𝑖𝑛(∙),𝑐𝑜𝑠(∙),arctan(∙),复向量幅度,极坐标和笛卡尔坐标的变换等。例如𝑠𝑖𝑛𝑥和𝑐𝑜𝑠𝑥的计算可以通过旋转模式得到,选择初值:𝑦0=0,x0=1/𝐴𝑛𝑧0设为待求角度,则𝑥𝑛=𝐴𝑛∙𝑥0𝑐𝑜𝑠𝑧0𝑦𝑛=𝐴𝑛∙𝑥0𝑠𝑖𝑛𝑧0向量模式可用于计算arctan(∙),要求输入以两个数的商形式给出,同时能计算复向量幅度𝑧𝑛=𝑧0+𝑡𝑎𝑛−1(𝑦0/𝑥0)𝑥𝑛=𝐴𝑛√𝑥02+𝑦02实际上,CORDIC算法还可以推广到双曲线和直线上𝑥𝑖+1=𝑥𝑖−𝑦𝑖∙𝑑𝑖∙2−𝑖𝑦𝑖+1=𝑦𝑖+𝑥𝑖∙𝑑𝑖∙2−𝑖zi+1=𝑧𝑖−𝑑𝑖∙tan−1(2−𝑖)Where𝑑𝑖=−1𝑖𝑓𝑧𝑖0,+1𝑜𝑡ℎ𝑒𝑟𝑤𝑖𝑠𝑒𝑥𝑛=𝐴𝑛[𝑥0𝑐𝑜𝑠ℎ𝑧0+𝑦0𝑠𝑖𝑛ℎ𝑧0)]𝑦𝑛=𝐴𝑛[𝑦0𝑐𝑜𝑠ℎ𝑧0+𝑥0𝑠𝑖𝑛ℎ𝑧0)]𝑧0=0𝐴𝑛=∑√1−2−2𝑖𝑛𝑥𝑛=𝐴𝑛√𝑥02−𝑦02𝑦0=0𝑧𝑛=𝑧0+𝑡𝑎𝑛ℎ−1(𝑦0/𝑥0)𝐴𝑛=∑√1−2−2𝑖𝑛三种情况下的CORDIC可以统一到以下框架下:xi+1=𝑥𝑖−𝑚∙𝑦𝑖∙𝑑𝑖∙2−𝑖yi+1=𝑦𝑖+𝑥𝑖∙𝑑𝑖∙2−𝑖zi+1=𝑧𝑖−𝑑𝑖∙𝑒𝑖流水线方式下的统一CORDIC实现方式如下图所示:53.2用CORDIC算法计算𝐬𝐢𝐧(𝐱)1)建立工程,并将压缩包中的Cordic.v添加到工程中;2)为该文件设计测试文件,并进行功能仿真和时序仿真,观察并分析从一个角度值x的输入到它对应的sin(x)输出所对应的时间;3)按以下步骤在工程中添加一个ROMIPCore;输入IPcore文件名并点击Next,选择下的,并点击Next。存储器类型选择单口ROM6点击Next,在第二个页面上设置RAM的位宽和深度,例如:点击Next,在第3个配置页面上找到下图所示位置:此处需要加载用于初始化存储器的文件。根据文件中注释所提供的量化规则设置一些角度值存在一个.coe文件中,.coe文件的样例见压缩包中的angle.coe,可用任一文本编辑器打开,文件以“memory_initialization_radix=16;memory_initialization_vector=“开头,其后的数据以十六进制表示,数据之间以空格或逗号分割,文件的长度和数据位宽应与ROM的设置保持一致。其他选项保持为默认选项,点击Generate按钮生成IPcore。此时在工程目录下的ipcore_dir文件夹中会产生一系列与设定的IPcore同名的文件,其中包含一个.v文件和一个.xco文件,xco文件是包含IPcore配置信息的核心文件,.V文件的格式与verilogmodule相同,其内容较为复杂,对使用者而言通常只关注它的模块头,作为实例化时的参考。4)产生一个用于在板测试的顶层文件,将cordic模块和ROM模块在该文件中进行实例化,参加压缩包中的cordic_top.v5)添加约束文件,参见压缩包中的cordic.ucf文件。自行设置Chipscope中的信号连接,用Chipscope工具进行在板测试,记录数据,并计算迭代次数为8次时的平均误差。;6)修改迭代次数为10次,重新进行仿真和测试。3.3用CORDIC算法计算√𝒙𝟐+𝒚𝟐将程序修改为计算√𝑥2+𝑦2的工作模式,重复上述测试。7四实验分析4.1用CORDIC算法计算𝐬𝐢𝐧(𝐱)(8次迭代)4.1.1.实验原理8次迭代的输入角度值和输出函数值均采用10位二进制数表示用0000000000~1111111111表示0~2π,因此200H表示π,100H表示π/2;用0000000000~1111111111表示函数值−1~+1;此时采用补码形式,0~511对应0~+1,512~1024对应−1~0;x0初值为2^9∗1𝐴𝑛=134𝐻设输入的角度值为16进制表示数X,将X换算成带符号的十进制数x,则与角度值之间的换算关系为α=x512∙π设CORDIC算法计算得到的输出函数值为Y,将Y换算成10进制带符号数y,则计算结果的10进制表示为𝑠𝑖𝑛𝑥=𝑦5124.1.2.实验描述本程序中所有角度和函数值都是采用二进制表示,具体描述如下:1)模块名:Cordic;2)角度值:采用10位二进制表示,用0000000000~1111111111表示0~2π,因此200H表示π,100H表示π/2;3)函数值:采用10位二进制补码表示,用0000000000~1111111111表示函数值−1~+1;此时采用补码形式,0~511对应0~+1,512~1024对应−1~0;4)输入及输出参数:clk:时钟信号;rst:重置信号;ena:启动信号,该信号置1时系统开始运算过程;phase_in(10位二进制数):输入的角度值;sin_out(10位二进制数):输出的𝑠𝑖𝑛(∙)函数值;5)函数变量cos_out(10位二进制数):计算得到的𝑐𝑜𝑠(∙)函数值,与sin_out同时产生但不输出;phase_in_reg(10位二进制数):程序中实际参与运算的角度值,下面会进行说明;x0-x8、y0-y8、z0-z8(均为10位二进制数):在迭代算法中使用的临时参数,x和y参数存储三角函数值,z存储角度值。x0、y0、z0存储初值,其它参数存储88次迭代的临时值;quadrant(10个1位存储器):存储输入角度值的相位信息,具体用处见下面说明;PIPELINE:流水线,必须和数据位长相同。本程序使用10级流水线。4.1.3.主要工作流程下面进行算法当中数据变化的详细说明:1)初值问题这里置𝑥0=1/𝐴𝑛其原因是xn=An∙𝑥0∙𝑠𝑖𝑛𝑧02)迭代运算此段代码是程序的主要部分,简单的说就是实现CORDIC算法的旋转模式:𝑥𝑖+1=𝑥𝑖−𝑦𝑖∙𝑑𝑖∙2−𝑖𝑦𝑖+1=𝑦𝑖+𝑥𝑖∙𝑑𝑖∙2−𝑖zi+1=𝑧𝑖−𝑑𝑖∙tan−1(2−𝑖)Where𝑑𝑖=−1𝑖𝑓𝑧𝑖0,+1𝑜𝑡ℎ𝑒𝑟𝑤𝑖𝑠𝑒它采用二进制位运算,对一些复杂地方进行相应说明:①zi(𝑑𝑖)正负的判断:通过判断符号位(首位);②2−𝑖的实现:即每次迭代时对𝑥𝑖或𝑦𝑖作除2操作具体实现方法为把原二进制值向右移动一位,移出的空位补0;③每次迭代时,𝑧的值要减去的角度值满足公式tan−12−𝑖3)结果处理利用三角函数性质,由于结果是在角度位于第一象限情况下获得的,因此作如下处理:输入角度在第一象限:𝑠𝑖𝑛𝑥值不变,𝑐𝑜𝑠𝑥值不变;输入角度在第二象限:𝑠𝑖𝑛𝑥值不变,𝑐𝑜𝑠𝑥值取反;输入角度在第三象限:𝑠𝑖𝑛𝑥值取反,𝑐𝑜𝑠𝑥值取反;输入角度在第四象限:𝑠𝑖𝑛𝑥值取反,𝑐𝑜𝑠𝑥值不变;取负方法:所有二进制位取反加一(补码)。4.2用CORDIC算法计算𝐬𝐢𝐧(𝐱)(10次迭代)这个程序是对8次迭代的程序进行修改后获得的,基本代码与工作流程完全相同,以下只说明修改的地方。1)数据位长度:由上述公式可得,每次、和的变化范围随迭代次数增加而减小,若仍采用原先的10位二进制数存储数据,到了较高次迭代时
本文标题:北邮-FPGA-实验三
链接地址:https://www.777doc.com/doc-5545289 .html