基于coridc算法的定点小数除法器的实现
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 15:09:32 06/13/2017 // Design Name: // Module Name: inv_cordivision // Project Name: // Target Devices: // Tool versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module inv_cordivision #( parameter DATA_SIZE = 16, parameter PIPELINE_LEN = 13 ) ( input clk, input nd, input [DATA_SIZE-1 : 0] x_in, input [DATA_SIZE-1 : 0] y_in, input [DATA_SIZE-1 : 0] z_in, output rdy, output[DATA_SIZE-1 : 0] x_out, output[DATA_SIZE-1 : 0] y_out, output[DATA_SIZE-1 : 0] z_out ); generate wire rdy_temp [PIPELINE_LEN : 0]; wire [DATA_SIZE-1 : 0] x_temp [PIPELINE_LEN : 0]; wire [DATA_SIZE-1 : 0] y_temp [PIPELINE_LEN : 0]; wire [DATA_SIZE-1 : 0] z_temp [PIPELINE_LEN : 0]; assign rdy_temp[0] = nd; assign x_temp[0] = x_in; assign y_temp[0] = y_in; assign z_temp[0] = z_in; assign rdy = rdy_temp[PIPELINE_LEN]; assign x_out = x_temp[PIPELINE_LEN]; assign y_out = y_temp[PIPELINE_LEN]; assign z_out = z_temp[PIPELINE_LEN]; genvar i; for(i=0;i<(PIPELINE_LEN);i=i+1) begin : unit inv_cordivision_unit #( .DATA_SIZE ( DATA_SIZE ), .FRAC_SIZE ( DATA_SIZE-2 ), .LEVEL ( i ) ) i2 ( .clk(clk), .nd(rdy_temp[i]), .x_in(x_temp[i]), .y_in(y_temp[i]), .z_in(z_temp[i]), .rdy(rdy_temp[i+1]), .x_out(x_temp[i+1]), .y_out(y_temp[i+1]), .z_out(z_temp[i+1]) ); end endgenerate endmodule module inv_cordivision_unit #( parameter DATA_SIZE = 16, parameter FRAC_SIZE = 14, parameter LEVEL = 0 ) ( input clk, input nd, input signed [DATA_SIZE-1:0] x_in, input signed [DATA_SIZE-1:0] y_in, input signed [DATA_SIZE-1:0] z_in, output reg rdy, output reg signed [DATA_SIZE-1:0] x_out, output reg signed [DATA_SIZE-1:0] y_out, output reg signed [DATA_SIZE-1:0] z_out ); parameter[DATA_SIZE-1:0] ONE = 2**(FRAC_SIZE); reg signed [DATA_SIZE-1:0] x_w=0,y_w=0,z_w=0; //时序逻辑 always @( posedge clk )begin rdy <= nd; x_out <= x_w; y_out <= y_w; z_out <= z_w; end //组合逻辑 always @( * ) begin x_w = x_in; if( y_in[DATA_SIZE-1] != x_in[DATA_SIZE-1] ) begin y_w = y_in + (x_in>>>(LEVEL)); z_w = z_in - (ONE>>(LEVEL)); end else begin y_w = y_in - (x_in>>>(LEVEL)); z_w = z_in + (ONE>>(LEVEL)); end end endmodule
测试代码:
`timescale 1ns / 1ps //////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 16:25:28 06/13/2017 // Design Name: inv_cordivision // Module Name: F:/INV/ise/inv/inv_cordivision_tst.v // Project Name: inv // Target Device: // Tool versions: // Description: // // Verilog Test Fixture created by ISE for module: inv_cordivision // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // //////////////////////////////////////////////////////////////////////////////// module inv_cordivision_tst; // Inputs reg clk; reg nd; reg [15:0] x_in; reg [15:0] y_in; reg [15:0] z_in; // Outputs wire rdy; wire [15:0] x_out; wire [15:0] y_out; wire [15:0] z_out; // Instantiate the Unit Under Test (UUT) inv_cordivision uut ( .clk(clk), .nd(nd), .x_in(x_in), .y_in(y_in), .z_in(z_in), .rdy(rdy), .x_out(x_out), .y_out(y_out), .z_out(z_out) ); parameter PERIOD = 10; initial begin clk = 1'b0; #(PERIOD/2); forever #(PERIOD/2) clk = ~clk; end initial begin // Initialize Inputs nd <= 0; x_in <= 0; y_in <= 0; z_in <= 0; // Wait 100 ns for global reset to finish #100; // Add stimulus here nd <= 1; x_in <= 4000; y_in <= 1000; z_in <= 0; end endmodule
测试结果:

浙公网安备 33010602011771号