tag 标签: 开方,fpga

相关博文
  • 热度 21
    2012-8-22 09:19
    3469 次阅读|
    1 个评论
    专题五:开方运算 开方运算虽然不像加法、乘法那么常用,但是也有其用武之地。在去年的一个项目中,笔者负责的模块中就使用了开方运算,开始时使用的是Altera的IP Core,验证模块使用没有问题;但是因为平台转换,需要转换到Xilinx的平台,许多IP Core也需要转移,最后干脆自己写一个得了,包括前几个专题中的乘法器、除法器。 开方运算模块也使用与除法器类似的NonRestoring算法,包含输入D、输出开方结果Q和余数R;在FPGA中实现,则采用迭代方式一步步逼近结果,其中每一级的迭代式为:T i+1 =T i (3 – T i 2 )/2,T i 是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,     output reg Q,     output reg R,     input ivalid,     output reg ovalid  );   reg D_t ; reg Q_t ; reg signed R_t ; reg ivalid_t ;   always@(posedge clk) begin          if(rst)          begin                    R_t ={r_width{1'b0}};     D_t ={d_width{1'b0}};     Q_t ={q_width{1'b0}};     ivalid_t =1'b0;          end          else          begin     if(ivalid)     begin       R_t ={R ,D } - {{q_width-1{1'b0}},2'b01};       D_t =D;       Q_t ={q_width{1'b0}};       ivalid_t =1'b1;     end     else     begin       R_t ={r_width{1'b0}};       D_t ={d_width{1'b0}};       Q_t ={q_width{1'b0}};       ivalid_t =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 )                             begin                                      if(R_t =0)                                      begin                                                Q_t ={Q_t ,1'b1};                                                R_t ={R_t ,D_t } - {1'b0,Q_t ,1'b1,2'b01};                                 D_t =D_t ;                                 ivalid_t =1'b1;                               end                               else                               begin                                    Q_t ={Q_t ,1'b0};                                                R_t ={R_t ,D_t } + {1'b0,Q_t ,1'b0,2'b11};                                 D_t =D_t ;                                 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 )                    begin                             if(R_t =0)                                begin                                      Q={Q_t ,1'b1};                                      R=R_t ;                             end                             else                             begin                                      Q={Q_t ,1'b0};                                      R=R_t + {1'b0,Q_t ,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所示为仿真图: 图1