• (转载)FPGA实现开发运算verilog


    http://bbs.ednchina.com/BLOG_ARTICLE_3003247.HTM

    专题五:开方运算

    开方运算虽然不像加法、乘法那么常用,但是也有其用武之地。在去年的一个项目中,笔者负责的模块中就使用了开方运算,开始时使用的是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_1];

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

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

    reg ivalid_t[q_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[i]<={q_width{1'b0}};

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

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

                 ivalid_t[i]<=1'b0;

                       end

                       else

                       begin

                                if(ivalid_t[i+1])

                                begin

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

                                         begin

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

                                                   R_t[i]<={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[i]<=D_t[i+1];

                                    ivalid_t[i]<=1'b1;

                                  end

                                  else

                                  begin

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

                                                   R_t[i]<={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[i]<=D_t[i+1];

                                    ivalid_t[i]<=1'b1;

                                  end

                         end

                         else

                         begin

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

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

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

                           ivalid_t[i]<=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

    写那些自己遇到的问题,然后解决的方式,不断吸取经验,坚持直到看见成功.
  • 相关阅读:
    jqueryeasyui1.2.3学习
    继续干IT的十个理由
    设计模式建造者模式(Builder Pattern)
    一段不错的视频
    第十一章:配置和安全IntelliMorph
    第十一章:配置和安全许可和配置
    物理库存和财务库存浅析
    第十一章:配置和安全概述
    IE6 双倍边距的解决方法
    asp实现关键词不区分大小写搜索并高亮显示
  • 原文地址:https://www.cnblogs.com/constanto/p/5391163.html
Copyright © 2020-2023  润新知