zoukankan      html  css  js  c++  java
  • 学习cordic算法所得(流水线结构、Verilog标准)

    最近学习cordic算法,并利用FPGA实现,在整个学习过程中,对cordic算法原理、FPGA中流水线设计、Verilog标准有了更加深刻的理解。

    首先,cordic算法的基本思想是通过一系列固定的、与运算基数有关的角度的不断偏,摆以逼近所需的旋转角度。

    yuanli1.jpg
    为了避免复杂的乘法运算,用一系列微旋转来处理,第i次旋转可表示为:
    yl3.jpg
    yl4.jpg
    yl5.jpg
    yl7.jpg
    yl7.jpg
    由式(7)可知:xn,yn分别为输入角H的余弦和正弦值。
    在Verilog实现上,主要体会到了流水线设计的重要性。流水线设计的本质是将一个时钟周期完成的较大的组合逻辑(也可理解为一个逻辑需要多个时钟周期,使得数据不能再每个时钟都有输出)通过合理的切割分由多个时钟周期完成(每个时钟都有数据输出),以n=14为例,若不采用流水线设计,则旋转一个角度就需要14个时钟周期,这样输出正余弦波的最大频率变为Fclk/(2N*14),若采用流水线设计,则输出最大频率变为Fclk/2N,N为输出数据位宽,所以流水线设计具有非常重要的意义。
    在reg型变量移位过程中,也对Verilog语言标准有了更新的了解,见:http://www.cnblogs.com/tshell/p/3236476.html
    module Test(clk,rst,Phase_Word,Sin_Val,Cos_Val);
    
    input clk,rst;
    input[15:0] Phase_Word;
    output reg [16:0] Sin_Val,Cos_Val;
    
    parameter Data_Width=16;  //输出数据宽度
    parameter Itera_Num=14;
    parameter Kn = 16'h4DBA;  //Kn为旋转后缩放比例因子系数,Kn=0.607253*2^16
    `define Rot_Angle0 8192
    `define Rot_Angle1 4836
    `define Rot_Angle2 2555
    `define Rot_Angle3 1297
    `define Rot_Angle4 651
    `define Rot_Angle5 326
    `define Rot_Angle6 163
    `define Rot_Angle7 81
    `define Rot_Angle8 41
    `define Rot_Angle9 20
    `define Rot_Angle10 10
    `define Rot_Angle11 5
    `define Rot_Angle12 3
    `define Rot_Angle13 1
    
    reg  [Data_Width:0] X[Itera_Num:0];  //X轴坐标值,最终对应cos
    reg  [Data_Width:0] Y[Itera_Num:0];  //Y轴坐标值,最终对应sin
    reg  [Data_Width:0] Z[Itera_Num:0];  //角度累加器
    
    reg[1:0] quadrant[Itera_Num:0];  //象限,00:第一象限;01,10,11分别为二、三、四象限
    
    /*****************************************************
    功能:流水线实现cordic算法
    说明:Itera_Num=0
    *****************************************************/    
    always @(posedge clk or negedge rst)
    if(!rst)
      begin
         X[0] <= 0;
         Y[0] <= 0;
         Z[0] <= 0;
      end
    else
      begin
         X[0] <= {1'b0,Kn}; 
         Y[0] <= 0;
         Z[0] <= {3'b0,Phase_Word[13:0]};//相位控制在(0-Pi/2),注意Phase_word需为reg signed类型。
      end
    /*****************************************************
    功能:流水线实现cordic算法
    说明:Itera_Num=1
    *****************************************************/    
    always @(posedge clk or negedge rst)
    if(!rst)
      begin
         X[1] <= 0;
         Y[1] <= 0;
         Z[1] <= 0;
      end
    else
      begin
         X[1] <= X[0] - Y[0]; 
         Y[1] <= X[0] + Y[0];
         Z[1] <= Z[0] - `Rot_Angle0;//第一次默认逆时针旋转45度
      end
    /*****************************************************
    功能:流水线实现cordic算法
    说明:Itera_Num=2
    *****************************************************/    
    always @(posedge clk or negedge rst)
    if(!rst)
      begin
         X[2] <= 0;
         Y[2] <= 0;
         Z[2] <= 0;
      end
    else
      begin
        if(Z[1][16])
           begin
              X[2] <= X[1] + {{1{Y[1][16]}},Y[1][16:1]};
              Y[2] <= Y[1] - {{1{X[1][16]}},X[1][16:1]};
              Z[2] <= Z[1] + `Rot_Angle1;  //顺时针旋转
            end
         else
           begin
              X[2] <= X[1] - {{1{Y[1][16]}},Y[1][16:1]};
              Y[2] <= Y[1] + {{1{X[1][16]}},X[1][16:1]};
              Z[2] <= Z[1] - `Rot_Angle1;  //逆时针旋转
           end
      end
    /*****************************************************
    功能:流水线实现cordic算法
    说明:Itera_Num=3
    *****************************************************/    
    always @(posedge clk or negedge rst)
    if(!rst)
      begin
         X[3] <= 0;
         Y[3] <= 0;
         Z[3] <= 0;
      end
    else
      begin
        if(Z[2][16])
           begin
              X[3] <= X[2] + {{2{Y[2][16]}},Y[2][16:2]};
              Y[3] <= Y[2] - {{2{X[2][16]}},X[2][16:2]};
              Z[3] <= Z[2] + `Rot_Angle2;  //顺时针旋转
            end
         else
           begin
              X[3] <= X[2] - {{2{Y[2][16]}},Y[2][16:2]};
              Y[3] <= Y[2] + {{2{X[2][16]}},X[2][16:2]};
              Z[3] <= Z[2] - `Rot_Angle2;  //逆时针旋转
           end
      end
    /*****************************************************
    功能:流水线实现cordic算法
    说明:Itera_Num=4
    *****************************************************/    
    always @(posedge clk or negedge rst)
    if(!rst)
      begin
         X[4] <= 0;
         Y[4] <= 0;
         Z[4] <= 0;
      end
    else
      begin
        if(Z[3][16])
           begin
              X[4] <= X[3] + {{3{Y[3][16]}},Y[3][16:3]};
              Y[4] <= Y[3] - {{3{X[3][16]}},X[3][16:3]};
              Z[4] <= Z[3] + `Rot_Angle3;  //顺时针旋转
            end
         else
           begin
              X[4] <= X[3] - {{3{Y[3][16]}},Y[3][16:3]};
              Y[4] <= Y[3] + {{3{X[3][16]}},X[3][16:3]};
              Z[4] <= Z[3] - `Rot_Angle3;  //逆时针旋转
           end
      end
    /*****************************************************
    功能:流水线实现cordic算法
    说明:Itera_Num=5
    *****************************************************/    
    always @(posedge clk or negedge rst)
    if(!rst)
      begin
         X[5] <= 0;
         Y[5] <= 0;
         Z[5] <= 0;
      end
    else
      begin
        if(Z[4][16])
           begin
              X[5] <= X[4] + {{4{Y[4][16]}},Y[4][16:4]};
              Y[5] <= Y[4] - {{4{X[4][16]}},X[4][16:4]};
              Z[5] <= Z[4] + `Rot_Angle4;  //顺时针旋转
            end
         else
           begin
              X[5] <= X[4] - {{4{Y[4][16]}},Y[4][16:4]};
              Y[5] <= Y[4] + {{4{X[4][16]}},X[4][16:4]};
              Z[5] <= Z[4] - `Rot_Angle4;  //逆时针旋转
           end
      end
    /*****************************************************
    功能:流水线实现cordic算法
    说明:Itera_Num=6
    *****************************************************/    
    always @(posedge clk or negedge rst)
    if(!rst)
      begin
         X[6] <= 0;
         Y[6] <= 0;
         Z[6] <= 0;
      end
    else
      begin
        if(Z[5][16])
           begin
              X[6] <= X[5] + {{5{Y[5][16]}},Y[5][16:5]};
              Y[6] <= Y[5] - {{5{X[5][16]}},X[5][16:5]};
              Z[6] <= Z[5] + `Rot_Angle5;  //顺时针旋转
            end
         else
           begin
              X[6] <= X[5] - {{5{Y[5][16]}},Y[5][16:5]};
              Y[6] <= Y[5] + {{5{X[5][16]}},X[5][16:5]};
              Z[6] <= Z[5] - `Rot_Angle5;  //逆时针旋转
           end
      end
    /*****************************************************
    功能:流水线实现cordic算法
    说明:Itera_Num=7
    *****************************************************/    
    always @(posedge clk or negedge rst)
    if(!rst)
      begin
         X[7] <= 0;
         Y[7] <= 0;
         Z[7] <= 0;
      end
    else
      begin
        if(Z[6][16])
           begin
              X[7] <= X[6] + {{6{Y[6][16]}},Y[6][16:6]};
              Y[7] <= Y[6] - {{6{X[6][16]}},X[6][16:6]};
              Z[7] <= Z[6] + `Rot_Angle6;  //顺时针旋转
            end
         else
           begin
              X[7] <= X[6] - {{6{Y[6][16]}},Y[6][16:6]};
              Y[7] <= Y[6] + {{6{X[6][16]}},X[6][16:6]};
              Z[7] <= Z[6] - `Rot_Angle6;  //逆时针旋转
           end
      end  
    /*****************************************************
    功能:流水线实现cordic算法
    说明:Itera_Num=8
    *****************************************************/    
    always @(posedge clk or negedge rst)
    if(!rst)
      begin
         X[8] <= 0;
         Y[8] <= 0;
         Z[8] <= 0;
      end
    else
      begin
        if(Z[7][16])
           begin
              X[8] <= X[7] + {{7{Y[7][16]}},Y[7][16:7]};
              Y[8] <= Y[7] - {{7{X[7][16]}},X[7][16:7]};
              Z[8] <= Z[7] + `Rot_Angle7;  //顺时针旋转
            end
         else
           begin
              X[8] <= X[7] - {{7{Y[7][16]}},Y[7][16:7]};
              Y[8] <= Y[7] + {{7{X[7][16]}},X[7][16:7]};
              Z[8] <= Z[7] - `Rot_Angle7;  //逆时针旋转
           end
      end  
    /*****************************************************
    功能:流水线实现cordic算法
    说明:Itera_Num=9
    *****************************************************/    
    always @(posedge clk or negedge rst)
    if(!rst)
      begin
         X[9] <= 0;
         Y[9] <= 0;
         Z[9] <= 0;
      end
    else
      begin
        if(Z[8][16])
           begin
              X[9] <= X[8] + {{8{Y[8][16]}},Y[8][16:8]};
              Y[9] <= Y[8] - {{8{X[8][16]}},X[8][16:8]};
              Z[9] <= Z[8] + `Rot_Angle8;  //顺时针旋转
            end
         else
           begin
              X[9] <= X[8] - {{8{Y[8][16]}},Y[8][16:8]};
              Y[9] <= Y[8] + {{8{X[8][16]}},X[8][16:8]};
              Z[9] <= Z[8] - `Rot_Angle8;  //逆时针旋转
           end
      end  
    /*****************************************************
    功能:流水线实现cordic算法
    说明:Itera_Num=10
    *****************************************************/    
    always @(posedge clk or negedge rst)
    if(!rst)
      begin
         X[10] <= 0;
         Y[10] <= 0;
         Z[10] <= 0;
      end
    else
      begin
        if(Z[9][16])
           begin
              X[10] <= X[9] + {{9{Y[9][16]}},Y[9][16:9]};
              Y[10] <= Y[9] - {{9{X[9][16]}},X[9][16:9]};
              Z[10] <= Z[9] + `Rot_Angle9;  //顺时针旋转
            end
         else
           begin
              X[10] <= X[9] - {{9{Y[9][16]}},Y[9][16:9]};
              Y[10] <= Y[9] + {{9{X[9][16]}},X[9][16:9]};
              Z[10] <= Z[9] - `Rot_Angle9;  //逆时针旋转
           end
      end  
    /*****************************************************
    功能:流水线实现cordic算法
    说明:Itera_Num=11
    *****************************************************/    
    always @(posedge clk or negedge rst)
    if(!rst)
      begin
         X[11] <= 0;
         Y[11] <= 0;
         Z[11] <= 0;
      end
    else
      begin
        if(Z[10][16])
           begin
              X[11] <= X[10] + {{10{Y[10][16]}},Y[10][16:10]};
              Y[11] <= Y[10] - {{10{X[10][16]}},X[10][16:10]};
              Z[11] <= Z[10] + `Rot_Angle10;  //顺时针旋转
            end
         else
           begin
              X[11] <= X[10] - {{10{Y[10][16]}},Y[10][16:10]};
              Y[11] <= Y[10] + {{10{X[10][16]}},X[10][16:10]};
              Z[11] <= Z[10] - `Rot_Angle10;  //逆时针旋转
           end
      end  
    /*****************************************************
    功能:流水线实现cordic算法
    说明:Itera_Num=12
    *****************************************************/    
    always @(posedge clk or negedge rst)
    if(!rst)
      begin
         X[12] <= 0;
         Y[12] <= 0;
         Z[12] <= 0;
      end
    else
      begin
        if(Z[11][16])
           begin
              X[12] <= X[11] + {{11{Y[11][16]}},Y[11][16:11]};
              Y[12] <= Y[11] - {{11{X[11][16]}},X[11][16:11]};
              Z[12] <= Z[11] + `Rot_Angle11;  //顺时针旋转
            end
         else
           begin
              X[12] <= X[11] - {{11{Y[11][16]}},Y[11][16:11]};
              Y[12] <= Y[11] + {{11{X[11][16]}},X[11][16:11]};
              Z[12] <= Z[11] - `Rot_Angle11;  //逆时针旋转
           end
      end  
    /*****************************************************
    功能:流水线实现cordic算法
    说明:Itera_Num=13
    *****************************************************/    
    always @(posedge clk or negedge rst)
    if(!rst)
      begin
         X[13] <= 0;
         Y[13] <= 0;
         Z[13] <= 0;
      end
    else
      begin
        if(Z[12][16])
           begin
              X[13] <= X[12] + {{12{Y[12][16]}},Y[12][16:12]};
              Y[13] <= Y[12] - {{12{X[12][16]}},X[12][16:12]};
              Z[13] <= Z[12] + `Rot_Angle12;  //顺时针旋转
            end
         else
           begin
              X[13] <= X[12] - {{12{Y[12][16]}},Y[12][16:12]};
              Y[13] <= Y[12] + {{12{X[12][16]}},X[12][16:12]};
              Z[13] <= Z[12] - `Rot_Angle12;  //逆时针旋转
           end
      end  
    /*****************************************************
    功能:流水线实现cordic算法
    说明:Itera_Num=14
    *****************************************************/    
    always @(posedge clk or negedge rst)
    if(!rst)
      begin
         X[14] <= 0;
         Y[14] <= 0;
         Z[14] <= 0;
      end
    else
      begin
        if(Z[13][16])
           begin
              X[14] <= X[13] + {{13{Y[13][16]}},Y[13][16:13]};
              Y[14] <= Y[13] - {{13{X[13][16]}},X[13][16:13]};
              Z[14] <= Z[13] + `Rot_Angle13;  //顺时针旋转
            end
         else
           begin
              X[14] <= X[13] - {{13{Y[13][16]}},Y[13][16:13]};
              Y[14] <= Y[13] + {{13{X[13][16]}},X[13][16:13]};
              Z[14] <= Z[13] - `Rot_Angle13;  //逆时针旋转
           end
      end  
    /*****************************************************
    功能:获取象限信息
    *****************************************************/    
    always @ (posedge clk or negedge rst)
    begin
      if(!rst) 
        begin
           quadrant[0] <= 0;
            quadrant[1] <= 0;
            quadrant[2] <= 0;
            quadrant[3] <= 0;
            quadrant[4] <= 0;
            quadrant[5] <= 0;
            quadrant[6] <= 0;
            quadrant[7] <= 0;
            quadrant[8] <= 0;
            quadrant[9] <= 0;
            quadrant[10] <= 0;
            quadrant[11] <= 0;
            quadrant[12] <= 0;
            quadrant[13] <= 0;
            quadrant[14] <= 0;
         end
      else
        begin
              quadrant[0] <= Phase_Word[15:14];
              quadrant[1] <= quadrant[0];
              quadrant[2] <= quadrant[1];
              quadrant[3] <= quadrant[2];
              quadrant[4] <= quadrant[3];
              quadrant[5] <= quadrant[4];
              quadrant[6] <= quadrant[5];
              quadrant[7] <= quadrant[6];
              quadrant[8] <= quadrant[7];
              quadrant[9] <= quadrant[8];
              quadrant[10] <= quadrant[9];
              quadrant[11] <= quadrant[10];
              quadrant[12] <= quadrant[11];
              quadrant[13] <= quadrant[12];
              quadrant[14] <= quadrant[13];
        end
    end
    /*****************************************************
    功能:根据象限确定输出值
    说明:当角度A=theta+pi/2在(pi/2~pi)时,
         cos(theta+pi/2)=-sin(theta).其中,theta为第一象限角
          二进制中,负数等于整数取反再加一
    *****************************************************/    
    always @ (posedge clk or negedge rst)
    begin
      if(!rst)
        begin
           Sin_Val <= 0;
            Cos_Val <= 0;
         end
      else
        begin
           case(quadrant[14])
            2'b00:begin
                        Cos_Val <= X[14];
                        Sin_Val <= Y[14];
                    end
            2'b01:begin
                        Cos_Val <= ~Y[14] + 1'b1;
                        Sin_Val <= X[14];
                    end
            2'b10:begin
                        Cos_Val <= ~X[14] + 1'b1;
                        Sin_Val <= ~Y[14] + 1'b1;
                    end
            2'b11:begin
                        Cos_Val <= Y[14];
                        Sin_Val <= ~X[14] + 1'b1;
                    end
          endcase
         end
    end
    
      
    endmodule
    View Code

    整个源码设计主要参考了aikimi7的设计,连接:http://www.cnblogs.com/aikimi7/p/3929592.html

     
  • 相关阅读:
    《Google 软件测试之道》摘录
    UIRecorder环境搭建及录制实现
    网易《人性的哲学与科学》笔记
    网易《公正:该如何做是好?》笔记(不定时更新)
    自助饮料机实现
    网易《社会心理学》笔记(不定时更新)
    uiautomator +python 安卓UI自动化尝试
    doc
    doc
    doc
  • 原文地址:https://www.cnblogs.com/yangjun1219/p/4981057.html
Copyright © 2011-2022 走看看