分分钟看懂cordic算法【实例运用】

从一个小实例出发,来说说我这个cordic算法除了能做些干什么! (圆周模式)

   有很多同学知道可以用来做DDS 但是对于现在这个“内存过剩”的年代,采用运算的方式实现DDS远远不如LUT来得方便。。。。PScordic算法提出的年代,那是在遥远的20世纪五六十年代,那时候内存非常的宝贵!)于是乎我也就不介绍DDS实现方式。。。

众所周知想要得到FFT的运算结果前一步必须取模,这里取模运算包括了平方,相加,开根这三个基本运算,其中前两个运算没啥问题,关键是开根!单片机通过调用数学函数可以解决这个问题,但是FPGA实现就没这么容易了,需要自己写这套取模的电路。

 

   于是乎我就搬来了大杀器(圆周系统之向量模式):

仔细观察这个得到结果,不要有畏惧心理。发现得到的xn正是我们想要的答案!有同学会说不是还要乘上一个An?放心An约等于一个常数1.64676到时候除去就行。另外再仔细观察学过通信基础的可以发现这个公式很眼熟,稍微改改不就可以求相位了么。。。做过载波同步的同学笑了。。。

 

接下来我们理理思路开始考虑如何编写硬件电路,好,首先我们知道在这个向量模式下初始角度为0,并输入向量值假定他为(1,2随后观察上述运算公式发现这是个迭代的过程,这就好办了,如果是C的话就用for循环好了,在verilog里面为了提高运算速度,把运算一次作为一个运算单元,然后输入输出相连,把n的结果作为n+1的初始值,循环往复。

   最后在运算的过程中,存在tan-1这个值那我们做查找表好了,在做查找表的过程中我们要对其进行定点化,45/1   45/2   45/4  45/8…把这些数通通乘上256保证其精度。然后带入其中运算。

   好下面给出一个运算单元的veriliog,其余大家复制粘贴,你懂得。。。

always @ (posedge clk or negedge rst_n)  //cell 2

begin

  if(!rst_n)

    begin

       x1_buf <= 16'd0;

        y1_buf <= 16'd0;

        z1_buf <= 16'd0;

      end

  else

    begin

      if (y0_buf[15]==1'b1)

            begin

                x1_buf <= x0_buf - (y0_buf >>> 1);

                y1_buf <= y0_buf + (x0_buf >>> 1);

                z1_buf <= z0_buf - 16'sd6801;

            end

        else

            begin

                x1_buf <= x0_buf + (y0_buf >>> 1);

                y1_buf <= y0_buf - (x0_buf >>> 1);

                z1_buf <= z0_buf + 16'sd6801;

            end

     end

end

这段小程序很快就能分析清楚,通过判断y的符号位,来得到其旋转方向。

你可能感兴趣的:(Verilog)