原创 【博客大赛】DSP in FPGA:开方运算

2012-8-22 09:19 3466 20 21 分类: FPGA/CPLD 文集: DSP in FPGA

专题五:开方运算

开方运算虽然不像加法、乘法那么常用,但是也有其用武之地。在去年的一个项目中,笔者负责的模块中就使用了开方运算,开始时使用的是Altera的IP Core,验证模块使用没有问题;但是因为平台转换,需要转换到Xilinx的平台,许多IP Core也需要转移,最后干脆自己写一个得了,包括前几个专题中的乘法器、除法器。

开方运算模块也使用与除法器类似的NonRestoring算法,包含输入D、输出开方结果Q和余数R;在FPGA中实现,则采用迭代方式一步步逼近结果,其中每一级的迭代式为:Ti+1=Ti(3 – Ti2)/2,Ti是1/Q的近似值。

Verilog HDL代码如下:

module sqrt

#( parameter d_width=32,

             q_width=d_width/2,

             r_width=q_width + 1)

(

    input clk,

    input rst,

    input [d_width-1:0] D,

    output reg [q_width-1:0] Q,

    output reg [r_width-1:0] R,

    input ivalid,

    output reg ovalid

 );

 

reg [d_width-1:0] D_t[q_width:1];

reg [q_width-1:0] Q_t[q_width:1];

reg signed [r_width-1:0] R_t[q_width:1];

reg ivalid_t[q_width:1];

 

always@(posedge clk)

begin

         if(rst)

         begin

                   R_t[q_width]<={r_width{1'b0}};

    D_t[q_width]<={d_width{1'b0}};

    Q_t[q_width]<={q_width{1'b0}};

    ivalid_t[q_width]<=1'b0;

         end

         else

         begin

    if(ivalid)

    begin

      R_t[q_width]<={R[r_width-3:0],D[d_width-1:d_width-2]} - {{q_width-1{1'b0}},2'b01};

      D_t[q_width]<=D;

      Q_t[q_width]<={q_width{1'b0}};

      ivalid_t[q_width]<=1'b1;

    end

    else

    begin

      R_t[q_width]<={r_width{1'b0}};

      D_t[q_width]<={d_width{1'b0}};

      Q_t[q_width]<={q_width{1'b0}};

      ivalid_t[q_width]<=1'b0;

    end

         end

end

        

generate

genvar i;

for(i=q_width-1;i>=1;i=i-1)

begin:U

         always@(posedge clk)

         begin

                   if(rst)

                   begin

                            Q_t<={q_width{1'b0}};

                            R_t<={r_width{1'b0}};

             D_t<={d_width{1'b0}};

             ivalid_t<=1'b0;

                   end

                   else

                   begin

                            if(ivalid_t[i+1])

                            begin

                                     if(R_t[i+1]>=0)

                                     begin

                                               Q_t<={Q_t[i+1][q_width-2:0],1'b1};

                                               R_t<={R_t[i+1][r_width-3:0],D_t[i+1][2*i-1:2*i-2]} - {1'b0,Q_t[i+1][q_width-4:0],1'b1,2'b01};

                                D_t<=D_t[i+1];

                                ivalid_t<=1'b1;

                              end

                              else

                              begin

                                   Q_t<={Q_t[i+1][q_width-2:0],1'b0};

                                               R_t<={R_t[i+1][r_width-3:0],D_t[i+1][2*i-1:2*i-2]} + {1'b0,Q_t[i+1][q_width-4:0],1'b0,2'b11};

                                D_t<=D_t[i+1];

                                ivalid_t<=1'b1;

                              end

                     end

                     else

                     begin

                          Q_t<={q_width{1'b0}};

                                     R_t<={r_width{1'b0}};

                       D_t<={d_width{1'b0}};

                       ivalid_t<=1'b0;

                     end

                   end

         end

end

endgenerate

 

always@(posedge clk)

begin

         if(rst)

         begin

                   Q<={q_width{1'b0}};

                   R<={r_width{1'b0}};

                   ovalid<=1'b0;

         end

         else

         begin

                   if(ivalid_t[1])

                   begin

                            if(R_t[1]>=0)   

                            begin

                                     Q<={Q_t[1][q_width-2:0],1'b1};

                                     R<=R_t[1];

                            end

                            else

                            begin

                                     Q<={Q_t[1][q_width-2:0],1'b0};

                                     R<=R_t[1] + {1'b0,Q_t[1][q_width-3:0],1'b0,1'b1};

                            end

                            ovalid<=1'b1;

                   end

                   else

                   begin

                            Q<={q_width{1'b0}};

                            R<={r_width{1'b0}};

                            ovalid<=1'b0;

                   end

         end

end

 

endmodule

         综合结果如下:

Number of Slice Registers:             677

Number of Slice LUTs:                 1105

Minimum period: 3.726ns (Maximum Frequency: 268.384MHz)

         如图1所示为仿真图:

snap1.jpg

图1

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户437960 2013-6-25 11:25

{q_width{1'b0}}这种表示代表什么意思?真心不懂啊~~~~~~~
相关推荐阅读
Hoki 2017-01-11 17:35
LX9开发板呼吸灯实现
对LX9开发板硬件评测后,从这一节开始真正进入FPGA开发的世界。很多开发板的例程中必有跑马灯实验,老跑马也没意思,咱来把新潮的,整一个呼吸灯。 呼吸灯最初是出现在apple公司的笔记本产品中,当合上...
Hoki 2017-01-11 16:47
LX9的microblaze配置
虽然XC6SLX9芯片资源比较少,但是嵌一个microblaze还是搓搓有余的,这一节就来评测一下在XC6SLX9上microblaze的配置。 有两种方法配置microblaze,一是在ISE软件中...
Hoki 2017-01-11 16:32
zynq评测
Zynq芯片是业界第一款在FPGA中集成ARM核的芯片,由FPGA的发明者xilinx公司推出的。Zynq严格来说不能以FPGA来定义它,因为其是以处理器为中心的平台,能够在单芯片上提供软、硬件和 I...
Hoki 2017-01-11 16:19
u-boot
Zyny芯片启动加载分为3步: 1. 芯片上电启动,首先读取BootROM中的程序,初始化一些必要的外设,然后根据专用引脚电平判断该从何处启动first stage Bootloader(FSBL),...
Hoki 2017-01-11 16:09
基于zynq的交叉编译平台
Zynq芯片的最大特点是其集成了双ARM Cortex-A9处理器,因此zynq的应用基本是以这个ARM核为核心,再配合FPGA逻辑作为协处理器,几乎能实现所有较复杂的应用。并且在ARM上可以跑操作系...
Hoki 2017-01-11 15:54
u-boot image生成
这节介绍一下如何生成u-boot image文件,在SDK软件中点击Xilinx Tools→Create Boot Image工具即可生成,但是生成image文件需要首先集齐3个文件:u-boot....
我要评论
1
20
关闭 站长推荐上一条 /3 下一条