1. 程式人生 > >數位電路設計之牛頓迭代法計算除法的verilog實現

數位電路設計之牛頓迭代法計算除法的verilog實現

偷笑偷笑偷笑偷笑偷笑委屈委屈委屈委屈委屈抓狂抓狂抓狂抓狂抓狂疑問疑問疑問疑問疑問得意得意得意得意得意奮鬥奮鬥奮鬥奮鬥奮鬥

        牛頓迭代法Newton's method)又稱為牛頓-拉夫遜(拉弗森)方法(Newton-Raphson method),它是牛頓在17世紀提出的一種在實數域和複數域上近似求解方程的方法。多數方程不存在求根公式,因此求精確根非常困難,甚至不可能,從而尋找方程的近似根就顯得特別重要。方法使用函式f(x)的泰勒級數的前面幾項來尋找方程f(x) = 0的根。牛頓迭代法是求方程根的重要方法之一,其最大優點是在方程f(x) = 0的單根附近具有平方收斂,而且該法還可以用來求方程的重根、復根,此時線性收斂,但是可通過一些方法變成超線性收斂。另外該方法廣泛用於計算機程式設計中。(以上摘自百度百科)

         通過令f(x)= 1/x - b;代入公式可得:x(i+1)= x(i)(2 - x(i)* b)。最後算出的值就是a/b。

程式碼:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:        SMIE
// Engineer:       Chen Yu
// Create Date:    18:11:42 10/06/2014 
// Design Name:    divider
// Module Name:    newton_raphson 
// Project Name:   newton_raphson divider
// Target Devices: spartan 6
// Revision: 1.0
// Revision 0.01 - File Created
// Additional Comments: http://blog.csdn.net/c602273091
//////////////////////////////////////////////////////////////////////////////////
module newton_raphson(a,b,q,stt,busy,ready,times,rst,clk);
	input  [31:0] a,b;            //divisor
	input         stt,clk,rst;    //control signal
	input  [5:0]  times;          //iteration times
	output [31:0] q;              //quotient:a/b
	output        busy,ready;
	reg           busy,busy2;
	reg    [5:0]  cnt;
	reg    [31:0] reg_a;
	reg    [33:0] reg_x;
	reg    [31:0] reg_b;
	
	
[email protected]
(posedge clk) begin if(!rst) begin cnt <= 6'b0; busy <= 1'b0; busy2<= 1'b0; reg_a<= 32'b0; reg_b<= 32'b0; reg_x<= 34'b0; end else if(stt) begin cnt <= 6'b0; busy <= 1'b1; busy2<= busy; reg_a<= a; reg_b<= b; reg_x<= {2'b01,x0,24'b0}; end else begin cnt <= cnt + 1'b1; busy2<= busy; reg_a<= a; reg_b<= b; reg_x<= { mux_x[66:33]}; if(times == cnt) busy <= 0; else; end end assign ready = (~busy) & busy2; assign q = mul_a_x[64:33] + {31'h0,|mul_a_x[32:0]}; //rounding wire [7:0] x0 = inition(b[31:24]); wire [64:0] mul_a_x = reg_a * reg_x; wire [64:0] mul_b_x = reg_b * reg_x; wire [33:0] _2_bxi = (~mul_b_x[64:31]) + 1'b1; wire [66:0] mux_x = reg_x * _2_bxi; function [7:0] inition; //use function to initial input [3:0]partition; begin case(partition) 4'h0: inition = 8'hf0; 4'h1: inition = 8'hd4; 4'h2: inition = 8'hba; 4'h3: inition = 8'ha4; 4'h4: inition = 8'h8f; 4'h5: inition = 8'h7d; 4'h6: inition = 8'h6c; 4'h7: inition = 8'h5c; 4'h8: inition = 8'h4e; 4'h9: inition = 8'h41; 4'ha: inition = 8'h35; 4'hb: inition = 8'h29; 4'hc: inition = 8'h1f; 4'hd: inition = 8'h15; 4'he: inition = 8'h0c; 4'hf: inition = 8'h04; endcase end endfunction endmodule

綜合圖:


Tip:在這一次的演算法中你應該學會的是進行一些初始化賦值,這和start有點不同,這裡有一個選擇的過程。