CORDIC算法计算复数相位角(含verilog源码)

前言

  截止2022年2月15日,中国科学院大学《高等数字集成电路分析及设计》课程终于完结,所以我计划分享几个自己完成的实践作业,供大家交流学习。

设计收获

  • 对cordic算法有了清晰的理解
  • 初次体验了借助verilog以外语言(这里是matlab)来对设计的电路进行验证

CORDIC算法计算复数相位角题目

  设计一个时序逻辑电路,对输入复数Z = X + Y*i,计算其归一化相位角P(取值范围[-1, 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算法向量模式。模块采用串行结构实现,对于每个有效输入,经过若干时钟周期能够输出1个有效数据。
  顶层模块名为calc_phase,输入输出功能定义:

名称方向位宽描述
clkI1系统时钟
rst_nI1系统异步复位,低电平有效
vld_inI1输入数据有效指示
xI16输入实部数据,二进制补码格式
yI16输入虚部数据,二进制补码格式
vld_outO1输出数据有效指示
pO16输出相位数据,二进制补码定点格式,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的要求。初始时,将角度累加值放大了100000倍,这里截取,又将其缩小了4倍,所以得到的p的输出为真实相位角的25000倍。

仿真(iverilog)

  对题目中给定的四组测试数据进行仿真得到如下波形:


可以看出四组数据得到的p值依次是:6250,17620,-7380,24999
  依据架构和原理中的分析,可知其对应的相位角为0.25,0.7048,-0.2952,0.99996。可知与理论值十分接近,较好控制了求解精度。(其中0.99996与理论的1也是接近的,因为相位角是周期性的,-1与1表示同一个相位)

附录

源码获取见原文底部

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值