基于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

测试结果:

 

posted on 2017-06-13 16:56  gNewplayer  阅读(576)  评论(0)    收藏  举报