数字电路设计之GoldSchmidt除法的verilog实现

2019-04-14 15:44发布

             若a和b均有.1xxxxxx的形式,这是二进制表示(a,b在0.5到1之间)。那么有(a*r0*r1*r2...)/(b*r0*r1*r2...) = a/b。x0 = a,y0 = b,r0 = 2 - y0。              通过推导可得:
                     x(i+1)= x(i)*r(i);                      y(i+1)= y(i)*r(i);                      r(i+1) = 2 - y(i + 1);
代码实现: ////////////////////////////////////////////////////////////////////////////////// // Company: SMIE // Engineer: Chen Yu // Create Date: 12:58:27 10/06/2014 // Design Name: divider // Module Name: goldschmidt // Project Name: divide // Revision: 1.0 // Address: http://blog.csdn.net/c602273091 // Revision 0.01 - File Created ////////////////////////////////////////////////////////////////////////////////// module goldschmidt(a,b,q,times,clk,stt,rst,busy,ready); input [31:0] a,b; //input a/b input clk,stt,rst; //control signal input [4:0] times; //to control iteration times output [31:0] q; //output result a/b output busy,ready; reg busy; reg busy2; reg [33:0] temp_a,temp_b; reg [4:0] cnt; wire ready; wire [66:0] mul_a; wire [66:0] mul_b; wire [33:0] yi_2; wire [31:0] q; always@(posedge clk) begin if(rst) begin busy <= 1'b0; busy2 <= 1'b0; temp_a<= 34'b0; temp_b<= 34'b0; cnt <= 5'b0; end else if(stt) begin busy <= 1'b1; busy2 <= busy; temp_a<= {1'b0,a,1'b0}; temp_b<= {1'b0,b,1'b0}; cnt <= 5'b0; end else begin temp_a <= mul_a[66:33]; temp_b <= mul_b[66:33]; busy2 <= busy; if(cnt == times) busy <= 0; else; cnt <= cnt + 5'b1; end end assign mul_a = temp_a*yi_2; assign yi_2 = (~temp_b) + 1'b1; assign mul_b = temp_b*yi_2; assign ready = (~busy)&busy2; assign q = temp_a[33:2] + (temp_a[0] | temp_a[1]); endmodule
综合结果:

仿真代码: module test_gold; // Inputs reg [31:0] a; reg [31:0] b; reg [4:0] times; reg clk; reg stt; reg rst; // Outputs wire [31:0] q; wire busy; wire ready; // Instantiate the Unit Under Test (UUT) goldschmidt uut ( .a(a), .b(b), .q(q), .times(times), .clk(clk), .stt(stt), .rst(rst), .busy(busy), .ready(ready) ); always #5 clk = !clk; initial begin // Initialize Inputs a = 32'hCF00_0000; b = 32'hC010_0000; times = 5; clk = 1; stt = 0; rst = 1; // Wait 100 ns for global reset to finish #10; rst = 0; stt = 1; #10; stt = 0; #100; // Add stimulus here $finish; end endmodule
仿真结果: