weiqi7777的个人空间 https://blog.eetop.cn/952026 [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

Cordic的三角运算的硬件实现 – 流水线结构

已有 2738 次阅读| 2013-12-28 23:34 |个人分类:设计心得

上一篇文章中,用的是组合逻辑加一级寄存器来实现cordic的三角运算。虽然,是可行的。但是在实际中,由于组合逻辑计算单元的延迟较大,造成系统的运行最大时钟频率不高。因此就不能高速的处理。

而流水线结构,就是将有较大延迟的组合逻辑,分解成几个延迟小的组合逻辑。这样的话,可以大大提高系统的时钟频率。但是,由于分解了,因此,数据运算不是马上就可得到,而是要延迟几个周期才可得到运算的值。而延迟的周期是由设计的几级流水线决定的。

将上次实现的硬件结构,改成流水线的结构。

其代码如下:

module cordic_tri_func

  #(

    //输出cossin的位宽

         //最高位为符号位,剩下6位为数据位

       parameter W   = 17,       

         //输入的角度采用16位表示

         //最高位表示符号位,1为负数。0为正数

         //接下来的7位,表示角度的整数,可表示范围为0--127

         //最后的8位,表示小数。可表示范围为0--1

            parameter N_Z = 16         //输入角度phi的位宽

           

    )

   (

         input                 clk,

         input      [N_Z-1:0]  phi,

                    

         output     [W-1:0]    cos,

         output     [W-1:0]    sin

    );

        

         //定义中间保存迭代的寄存器值

         reg [W-1:0]    x [7:0];

         reg [W-1:0]    y [7:0];

         reg [N_Z-1:0]  z [7:0];

 

    always@( posedge clk ) begin

            x[0] <= 17'd39797; //0.60725

            y[0] <= 0;

            z[0] <= phi;

            //迭代第一次,角度偏移45°

            if(z[0][N_Z-1])  

               begin

                        x[1] <= x[0] + y[0];

                        y[1] <= y[0] - x[0];

                        z[1] <= z[0] + 16'd11520;  //45° = 0_0101101_00000000 = 11520

                     end

            else

               begin

                        x[1] <= x[0] - y[0];

                        y[1] <= y[0] + x[0];

                        z[1] <= z[0] - 16'd11520;

                     end

           //迭代第二次,角度偏移26.56°

           if(z[1][N_Z-1]) 

               begin

                        x[2] <= x[1] + {{1{y[1][W-1]}},y[1][W-1:1]};

                        y[2] <= y[1] - {{1{x[1][W-1]}},x[1][W-1:1]};

                        z[2] <= z[1] + 16'd6799;  //25.56° = 0_0011010_10001111 = 6799

                     end

            else

               begin

                        x[2] <= x[1] - {{1{y[1][W-1]}},y[1][W-1:1]};

                        y[2] <= y[1] + {{1{x[1][W-1]}},x[1][W-1:1]};

                        z[2] <= z[1] - 16'd6799;

                     end

          //迭代第三次,角度偏移14.04°

            if(z[2][N_Z-1])  

               begin

                        x[3] <= x[2] + {{2{y[2][W-1]}},y[2][W-1:2]};

                        y[3] <= y[2] - {{2{x[2][W-1]}},x[2][W-1:2]};

                        z[3] <= z[2] + 16'd3594;  //14.04° = 0_0001110_00001010 = 3594

                     end

            else

               begin

                        x[3] <= x[2] - {{2{y[2][W-1]}},y[2][W-1:2]};

                        y[3] <= y[2] + {{2{x[2][W-1]}},x[2][W-1:2]};

                        z[3] <= z[2] - 16'd3594;

                     end

           //迭代第四次,角度偏移7.13°

            if(z[3][N_Z-1]) 

               begin

                        x[4] <= x[3] + {{3{y[3][W-1]}},y[3][W-1:3]};

                        y[4] <= y[3] - {{3{x[3][W-1]}},x[3][W-1:3]};

                        z[4] <= z[3] + 16'd1825;  //7.13° = 0_0000111_00100001 = 1825

                     end

            else

               begin

                        x[4] <= x[3] - {{3{y[3][W-1]}},y[3][W-1:3]};

                        y[4] <= y[3] + {{3{x[3][W-1]}},x[3][W-1:3]};

                        z[4] <= z[3] - 16'd1825;

                     end

           //迭代第五次,角度偏移3.58°

            if(z[4][N_Z-1])  

               begin

                        x[5] <= x[4] + {{4{y[4][W-1]}},y[4][W-1:4]};

                        y[5] <= y[4] - {{4{x[4][W-1]}},x[4][W-1:4]};

                        z[5] <= z[4] + 16'd916;  //3.58° = 0_0000011_10010100 = 916

                     end

            else

               begin

                        x[5] <= x[4] - {{4{y[4][W-1]}},y[4][W-1:4]};

                        y[5] <= y[4] + {{4{x[4][W-1]}},x[4][W-1:4]};

                        z[5] <= z[4] - 16'd916;

                     end

           //迭代第六次,角度偏移1.79°

            if(z[5][N_Z-1]) 

               begin

                        x[6] <= x[5] + {{5{y[5][W-1]}},y[5][W-1:5]};

                        y[6] <= y[5] - {{5{x[5][W-1]}},x[5][W-1:5]};

                        z[6] <= z[5] + 16'd458;  //1.79° = 0_0000001_11001010 = 458

                     end

            else

               begin

                        x[6] <= x[5] - {{5{y[5][W-1]}},y[5][W-1:5]};

                        y[6] <= y[5] + {{5{x[5][W-1]}},x[5][W-1:5]};

                        z[6] <= z[5] - 16'd458;

                     end

           //迭代第七次,角度偏移0.9°

            if(z[6][N_Z-1])  

               begin

                        x[7] <= x[6] + {{6{y[6][W-1]}},y[6][W-1:6]};

                        y[7] <= y[6] - {{6{x[6][W-1]}},x[6][W-1:6]};

                        z[7] <= z[6] + 16'd230;  //0.9° = 0_0000000_11100110 = 230

                     end

            else

               begin

                        x[7] <= x[6] - {{6{y[6][W-1]}},y[6][W-1:6]};

                        y[7] <= y[6] + {{6{x[6][W-1]}},x[6][W-1:6]};

                        z[7] <= z[6] - 16'd230;

                     end

         end

   assign cos = x[7];

   assign sin = y[7];

endmodule

认真观察一下代码,发现这流水线结构的代码,和上次组合逻辑机构实现的代码基本上是一样的。唯一不一样的就是赋值的不同。组合逻辑结构用的是=赋值,而流水线结构,用的是=>赋值。

关于==>的区别,大家可以查查相关资料。前个是阻塞赋值,也就是赋值后,值就马上变化。而后者是非阻塞赋值,赋值后,不是马上就改变。关于这个非阻塞和阻塞的概念,是很重要的,各位要去查查相关资料了解一下,了解他们之间的区别。这里就不详细说了。

(主要是要画图才能讲得清楚,本人比较懒,难得画图)

接下来,就是仿真了。要有仿真的思想,在学习verilog的时候,每当写完一个模块,就记得要编写测试文件去仿真写的模块,然后验证看自己写的模块对不对。这样才能提升自己的硬件编程的水平。在高级点,就是边写程序,边想对应实现的硬件是什么,然后再自己想这实现的硬件是不是能实现我们要求的功能。这个属于高级了,我也不是很会,不过现在在开始培养。大家也可以这样试一下。毕竟,硬件和软件还是不一样的。

测试代码和上次的代码一样,仿真图,如下所示:

这大家可以看出,仿真的开始阶段,输出都是未定态(X)。因为这里采用的是7级流水线,因此,在7个时钟周期后,才开始输出真正的计算出来的值。

上面的编程其实是不规范的。流水线,编程,最好是,每一级单独用一个always来编写。而且还要加入复位信号。这样才是一个好的代码了。

 


   

   

 


点赞

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 注册

  • 关注TA
  • 加好友
  • 联系TA
  • 0

    周排名
  • 0

    月排名
  • 0

    总排名
  • 1

    关注
  • 1

    粉丝
  • 1

    好友
  • 0

    获赞
  • 5

    评论
  • 542

    访问数
关闭

站长推荐 上一条 /1 下一条

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-5-6 19:16 , Processed in 0.024540 second(s), 14 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部