前言
??截至2022年2月15日,中国科学院大学的高等数字集成电路分析与设计课程终于完成,因此我计划分享一些我完成的实践作业供您交流和学习。
设计收获
- 对cordic算法有了清晰的理解
- 第一次体验借助verilog外语(这里是matlab)验证设计电路
CORDIC算法计算复数相位角题
??设计时序逻辑电路,输入复数Z = X Y*i,计算其归一化相位角P(取值范围[-1, 例如:
- Z = 10 10i, P = 0.25
- Z = -3 4i,P = 0.704833
- Z = 3 – 4i,P = -0.295167
- Z = -10 0i, P = -1
??计算相角使用CORDIC算法向量模式。该模块采用串行结构实现,每个有效输入可在几个时钟周期后输出一个有效数据。 ??顶层模块叫calc_phase,输入输出功能定义:
名称 | 方向 | 位宽 | 描述 |
---|---|---|---|
clk | I | 1 | 系统时钟 |
rst_n | I | 1 | 系统异步复位,低电平有效 |
vld_in | I | 1 | 有效指示输入数据 |
x | I | 16 | 输入实数据,二进制补码格式 |
y | I | 16 | 输入虚拟数据,二进制补码格式 |
vld_out | O | 1 | 输出数据有效指示 |
p | O | 16 | 输出相位数据,二进制补码定点格式,1位符号整数位,15位小数位,取值范围[-1, 1) |
设计要求: |
- Verilog可以综合实现代码,给出综合和模拟结果。
- 适当控制计算过程,确保输出结果的准确性。
CORDIC算法计算复数相位角设计
架构和原理
??如图所示,使用状态机控制cordic求解过程。 ??其中IDLE状态等待数据的有效输入x,y输入复数的正负确定x iy并对x,y转换到第一和四象限后,给予x_r1和y_r1,作为cordic迭代开始时,设置角度累加值angle_remain初值为0; ??BUSY状态使用cordic迭代求解算法,迭代15次,迭代如下:
if (~y_r1[30]) begin x_r1 <= x_r1 (y_r1>>>counter); y_r1 <= y_r1 - (x_r1>>>counter); angle_remain <= angle_remain angle[counter 1]; end else begin x_r1 <= x_r1 - (y_r1>>>counter); y_r1 <= y_r1 (x_r1>>>counter); angle_remain <= angle_remain - angle[counter 1]; end
??原表达式中的符号标志d,借用y_r1正负判断巧妙省去了一个bit的寄存器; ??DONE状态在迭代结束后,将结果输出,这里除了依据象限标记将角度累加值angle_remain修正为p_t外,还要对p_t截取符合p输出的16bit要求。一开始角度累加值放大了1万倍,这里截取,缩小了4倍,所以P的输出是真实相位角的2.5万倍。
仿真(iverilog)
??模拟题目中给定的四组测试数据,得到以下波形:
由此可见,四组数据得到的p值是:6250,17620,-7380,2499 ??根据结构和原理的分析,相应的相位角为0.25,0.7048,-0.2952,0.9996。可以看出,它非常接近理论值,并且可以更好地控制求解的精度。.9996也接近理论1,因为相位角是周期性的,-1和1表示相位)
附录
??如需获取源码,请关注微信官方账号多读书,回复CORDIC计算复数相位角的算法。 :CORDIC算法计算复数相位角