OpenCores
URL https://opencores.org/ocsvn/sbd_sqrt_fp/sbd_sqrt_fp/trunk

Subversion Repositories sbd_sqrt_fp

[/] [sbd_sqrt_fp/] [tags/] [start/] [sbd_sqrt_fp.v] - Diff between revs 3 and 4

Only display areas with differences | Details | Blame | View Log

Rev 3 Rev 4
/****************************************************************************
/****************************************************************************
sbd_sqrt_fp
sbd_sqrt_fp
 
 
- square root function for single or double precisons ieee 754
- square root function for single or double precisons ieee 754
   floating-point numbers
   floating-point numbers
 
 
This core is capable of handling single or double precision floating-
This core is capable of handling single or double precision floating-
poing numbers.  For single precision, set the bitlength parameter to 32;
poing numbers.  For single precision, set the bitlength parameter to 32;
for double precision, set the bitlength parameter to 64.  The algorithm
for double precision, set the bitlength parameter to 64.  The algorithm
used is iterative and will take 52 clock cycles for single precision and
used is iterative and will take 52 clock cycles for single precision and
110 clock cycles for double precision.  The sign bit is simply passed
110 clock cycles for double precision.  The sign bit is simply passed
through from input to output, so if given negative input, this core
through from input to output, so if given negative input, this core
will produce a negative output corresponding to -1 * sqrt(|input|).
will produce a negative output corresponding to -1 * sqrt(|input|).
 
 
Ports: - all signals are active high
Ports: - all signals are active high
 
 
input [bitlength-1:0]      D_IN;     // single or double precison input
input [bitlength-1:0]      D_IN;     // single or double precison input
input                      VAL_IN;   // Assert VAL_IN to signal a valid
input                      VAL_IN;   // Assert VAL_IN to signal a valid
                                        input value. The module will only
                                        input value. The module will only
                                        accept input when RDY_IN is asserted.
                                        accept input when RDY_IN is asserted.
                                        If RDY_IN is low, then VAL_IN should
                                        If RDY_IN is low, then VAL_IN should
                                        remain asserted until RDY_IN goes
                                        remain asserted until RDY_IN goes
                                        high.  VAL_IN and RDY_IN must both be
                                        high.  VAL_IN and RDY_IN must both be
                                        asserted for one clock cycle for
                                        asserted for one clock cycle for
                                        computation to begin.
                                        computation to begin.
output wire                RDY_IN;   // module is ready to accept input
output wire                RDY_IN;   // module is ready to accept input
input                      CLK;      // clock
input                      CLK;      // clock
output reg [bitlength-1:0] D_OUT;    // single or double precision output
output reg [bitlength-1:0] D_OUT;    // single or double precision output
output reg                 VAL_OUT;  // VAL_OUT is asserted when the output
output reg                 VAL_OUT;  // VAL_OUT is asserted when the output
                                        is valid.  VAL_OUT will remain asserted
                                        is valid.  VAL_OUT will remain asserted
                                        and D_OUT will persist until VAL_OUT and
                                        and D_OUT will persist until VAL_OUT and
                                        RDY_OUT have both been asserted for one
                                        RDY_OUT have both been asserted for one
                                        clock cycle.
                                        clock cycle.
input                      RDY_OUT;  // when asserted, downstream logic is
input                      RDY_OUT;  // when asserted, downstream logic is
                                        ready to accept output of module
                                        ready to accept output of module
 
 
This core was designed using synchronous resets, for use in FPGAs.  The
This core was designed using synchronous resets, for use in FPGAs.  The
synchronous resets could easily be made asynchronous for use in ASICs by
synchronous resets could easily be made asynchronous for use in ASICs by
editing the always @ (posedge CLK) blocks in this and all dependant files.
editing the always @ (posedge CLK) blocks in this and all dependant files.
 
 
Resource Utilization:
Resource Utilization:
(synthesized with XST for Virtex4 - no architectural dependancies exist in this core
(synthesized with XST for Virtex4 - no architectural dependancies exist in this core
- this is merely an example)
- this is merely an example)
 
 
Single Precision:
Single Precision:
   Slices:        155
   Slices:        155
   Flip Flops:    204
   Flip Flops:    204
   4-Input LUTs:  269
   4-Input LUTs:  269
 
 
Double Precision:
Double Precision:
   Slices:        324
   Slices:        324
   Flip Flops:    417
   Flip Flops:    417
   4-Input LUTs:  566
   4-Input LUTs:  566
 
 
Both numerical accuracy and performance of the single and double precision versions of
Both numerical accuracy and performance of the single and double precision versions of
this core have been verified in a Xilinx XC4VLX25-10 at 100MHz.  Without optimizations,
this core have been verified in a Xilinx XC4VLX25-10 at 100MHz.  Without optimizations,
the single precision core should operate at up to at least 190MHz, and the double precision
the single precision core should operate at up to at least 190MHz, and the double precision
core should operate at up to at least 134MHz in this platform.  Higher performance should
core should operate at up to at least 134MHz in this platform.  Higher performance should
be possible with a little effort.
be possible with a little effort.
 
 
This module uses the following files:
This module uses the following files:
 
 
sbd_sqrt_fp_calc_mant.v
sbd_sqrt_fp_calc_mant.v
sbd_sqrt_fp_state_mach.v
sbd_sqrt_fp_state_mach.v
sbd_shifter_left2.v
sbd_shifter_left2.v
sbd_shifter_left3_right2.v
sbd_shifter_left3_right2.v
sbd_adsu.v
sbd_adsu.v
 
 
Copyright (C) 2005 Samuel Brown
Copyright (C) 2005 Samuel Brown
sam.brown@sbdesign.org
sam.brown@sbdesign.org
 
 
This library is free software; you can redistribute it and/or
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
version 2.1 of the License, or (at your option) any later version.
 
 
This library is distributed in the hope that it will be useful,
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.
Lesser General Public License for more details.
 
 
You should have received a copy of the GNU Lesser General Public
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
 
****************************************************************************/
****************************************************************************/
 
 
module sbd_sqrt_fp ( D_IN, VAL_IN, RDY_IN, CLK, D_OUT, VAL_OUT, RDY_OUT );
module sbd_sqrt_fp ( D_IN, VAL_IN, RDY_IN, CLK, D_OUT, VAL_OUT, RDY_OUT );
 
 
parameter bitlength = 32;
parameter bitlength = 32;
 
 
input [bitlength-1:0]       D_IN;
input [bitlength-1:0]       D_IN;
input                      VAL_IN;
input                      VAL_IN;
output wire                RDY_IN;
output wire                RDY_IN;
input                      CLK;
input                      CLK;
output reg [bitlength-1:0] D_OUT;
output reg [bitlength-1:0] D_OUT;
output reg                 VAL_OUT;
output reg                 VAL_OUT;
input                      RDY_OUT;
input                      RDY_OUT;
 
 
reg [bitlength-1:0] raw_data_reg;
reg [bitlength-1:0] raw_data_reg;
reg beg_in_reg;
reg beg_in_reg;
reg d_rdy_reg;
reg d_rdy_reg;
wire mant_out;
wire mant_out;
reg mant_out_reg;
reg mant_out_reg;
 
 
wire [bitlength-1:0] sqrt_final;
wire [bitlength-1:0] sqrt_final;
 
 
generate
generate
if(bitlength == 32)
if(bitlength == 32)
begin:single
begin:single
 
 
//------------------ Single Precision --------------------------------------
//------------------ Single Precision --------------------------------------
 
 
   wire [7:0] exp_off, exp_adj, exp_final;
   wire [7:0] exp_off, exp_adj, exp_final;
   wire non_zero_exp = ~(!raw_data_reg[30:23]);
   wire non_zero_exp = ~(!raw_data_reg[30:23]);
 
 
   wire [23:0] mant_final;
   wire [23:0] mant_final;
   wire [22:0] mant_final_imp = mant_final[22:0];
   wire [22:0] mant_final_imp = mant_final[22:0];
   reg [23:0] mant_adj; // mantissa with explicit leading bit - adjusted
   reg [23:0] mant_adj; // mantissa with explicit leading bit - adjusted
                        // for even/odd exponent
                        // for even/odd exponent
 
 
   //------------ Exponent Calculation & Mantissa Preparation --------------
   //------------ Exponent Calculation & Mantissa Preparation --------------
 
 
   sbd_adsu exp_offset_adsu (
   sbd_adsu exp_offset_adsu (
      .A(raw_data_reg[30:23]),
      .A(raw_data_reg[30:23]),
      .B(8'h7F),
      .B(8'h7F),
      .ADD(1'b0),
      .ADD(1'b0),
      .C_IN(1'b1),
      .C_IN(1'b1),
      .S(exp_off));
      .S(exp_off));
      defparam exp_offset_adsu.bitlength = 8;
      defparam exp_offset_adsu.bitlength = 8;
 
 
   sbd_adsu exp_adjust_adsu (
   sbd_adsu exp_adjust_adsu (
      .A(8'h7F),
      .A(8'h7F),
      .B({ exp_off[7], exp_off[7:1] }),
      .B({ exp_off[7], exp_off[7:1] }),
      .ADD(1'b1),
      .ADD(1'b1),
      .C_IN(1'b0),
      .C_IN(1'b0),
      .S(exp_adj));
      .S(exp_adj));
      defparam exp_adjust_adsu.bitlength = 8;
      defparam exp_adjust_adsu.bitlength = 8;
 
 
      assign exp_final = exp_adj & {8{non_zero_exp}};
      assign exp_final = exp_adj & {8{non_zero_exp}};
 
 
      always @ (raw_data_reg, non_zero_exp)
      always @ (raw_data_reg, non_zero_exp)
      begin:mant_adj_mux
      begin:mant_adj_mux
         if(raw_data_reg[23]) mant_adj = { 1'b0, non_zero_exp, raw_data_reg[22:1] };
         if(raw_data_reg[23]) mant_adj = { 1'b0, non_zero_exp, raw_data_reg[22:1] };
         else mant_adj = { non_zero_exp, raw_data_reg[22:0] };
         else mant_adj = { non_zero_exp, raw_data_reg[22:0] };
      end
      end
 
 
   //------------- Mantissa Calculation --------------------------------------
   //------------- Mantissa Calculation --------------------------------------
 
 
 
 
   sbd_sqrt_fp_calc_mant mant_iterations (
   sbd_sqrt_fp_calc_mant mant_iterations (
      .MANT_IN(mant_adj),
      .MANT_IN(mant_adj),
      .CLK(CLK),
      .CLK(CLK),
      .VAL_IN(beg_in_reg),
      .VAL_IN(beg_in_reg),
      .MANT_OUT(mant_final),
      .MANT_OUT(mant_final),
      .VAL_OUT(mant_out));
      .VAL_OUT(mant_out));
      defparam mant_iterations.mantlength = 24;
      defparam mant_iterations.mantlength = 24;
 
 
   assign sqrt_final = { raw_data_reg[bitlength-1], exp_final, mant_final_imp };
   assign sqrt_final = { raw_data_reg[bitlength-1], exp_final, mant_final_imp };
 
 
end
end
else if(bitlength == 64)
else if(bitlength == 64)
begin:double
begin:double
 
 
//------------------ Doule Precision ---------------------------------------
//------------------ Doule Precision ---------------------------------------
 
 
   wire [10:0] exp_off, exp_adj, exp_final;
   wire [10:0] exp_off, exp_adj, exp_final;
   wire non_zero_exp = ~(!raw_data_reg[62:52]);
   wire non_zero_exp = ~(!raw_data_reg[62:52]);
 
 
   wire [52:0] mant_final;
   wire [52:0] mant_final;
   wire [51:0] mant_final_imp = mant_final[51:0];
   wire [51:0] mant_final_imp = mant_final[51:0];
   reg [52:0] mant_adj; // mantissa with explicit leading bit - adjusted
   reg [52:0] mant_adj; // mantissa with explicit leading bit - adjusted
                     // for even/odd exponent
                     // for even/odd exponent
 
 
   //------------ Exponent Calculation & Mantissa Preparation --------------
   //------------ Exponent Calculation & Mantissa Preparation --------------
 
 
   sbd_adsu exp_offset_adsu (
   sbd_adsu exp_offset_adsu (
      .A(raw_data_reg[62:52]),
      .A(raw_data_reg[62:52]),
      .B(11'h3FF),
      .B(11'h3FF),
      .ADD(1'b0),
      .ADD(1'b0),
      .C_IN(1'b1),
      .C_IN(1'b1),
      .S(exp_off));
      .S(exp_off));
      defparam exp_offset_adsu.bitlength = 11;
      defparam exp_offset_adsu.bitlength = 11;
 
 
   sbd_adsu exp_adjust_adsu (
   sbd_adsu exp_adjust_adsu (
      .A(11'h3FF),
      .A(11'h3FF),
      .B({ exp_off[10], exp_off[10:1] }),
      .B({ exp_off[10], exp_off[10:1] }),
      .ADD(1'b1),
      .ADD(1'b1),
      .C_IN(1'b0),
      .C_IN(1'b0),
      .S(exp_adj));
      .S(exp_adj));
      defparam exp_adjust_adsu.bitlength = 11;
      defparam exp_adjust_adsu.bitlength = 11;
 
 
      assign exp_final = exp_adj & {11{non_zero_exp}};
      assign exp_final = exp_adj & {11{non_zero_exp}};
 
 
      always @ (raw_data_reg, non_zero_exp)
      always @ (raw_data_reg, non_zero_exp)
      begin:mant_adj_mux
      begin:mant_adj_mux
         if(raw_data_reg[52]) mant_adj = { 1'b0, non_zero_exp, raw_data_reg[51:1] };
         if(raw_data_reg[52]) mant_adj = { 1'b0, non_zero_exp, raw_data_reg[51:1] };
         else mant_adj = { non_zero_exp, raw_data_reg[51:0] };
         else mant_adj = { non_zero_exp, raw_data_reg[51:0] };
      end
      end
 
 
   //------------- Mantissa Calculation --------------------------------------
   //------------- Mantissa Calculation --------------------------------------
 
 
 
 
   sbd_sqrt_fp_calc_mant mant_iterations (
   sbd_sqrt_fp_calc_mant mant_iterations (
      .MANT_IN(mant_adj),
      .MANT_IN(mant_adj),
      .CLK(CLK),
      .CLK(CLK),
      .VAL_IN(beg_in_reg),
      .VAL_IN(beg_in_reg),
      .MANT_OUT(mant_final),
      .MANT_OUT(mant_final),
      .VAL_OUT(mant_out));
      .VAL_OUT(mant_out));
      defparam mant_iterations.mantlength = 53;
      defparam mant_iterations.mantlength = 53;
 
 
   assign sqrt_final = { raw_data_reg[bitlength-1], exp_final, mant_final_imp };
   assign sqrt_final = { raw_data_reg[bitlength-1], exp_final, mant_final_imp };
 
 
end
end
endgenerate
endgenerate
 
 
 
 
assign RDY_IN = ~d_rdy_reg;
assign RDY_IN = ~d_rdy_reg;
wire beg_in = VAL_IN & RDY_IN;
wire beg_in = VAL_IN & RDY_IN;
 
 
initial
initial
begin:simzero
begin:simzero
 
 
   D_OUT <= 0;
   D_OUT <= 0;
   VAL_OUT <= 0;
   VAL_OUT <= 0;
   raw_data_reg <= 0;
   raw_data_reg <= 0;
   beg_in_reg <= 0;
   beg_in_reg <= 0;
   d_rdy_reg <= 0;
   d_rdy_reg <= 0;
   mant_out_reg <= 0;
   mant_out_reg <= 0;
 
 
end
end
 
 
always @ (posedge CLK)
always @ (posedge CLK)
begin:reg_input
begin:reg_input
   // input buffer
   // input buffer
   if(beg_in) raw_data_reg <= D_IN;
   if(beg_in) raw_data_reg <= D_IN;
 
 
   // val delay
   // val delay
   beg_in_reg <= beg_in;
   beg_in_reg <= beg_in;
 
 
   // RDY state
   // RDY state
   if(mant_out) d_rdy_reg <= 0;
   if(mant_out) d_rdy_reg <= 0;
   else if(beg_in) d_rdy_reg <= 1;
   else if(beg_in) d_rdy_reg <= 1;
 
 
   // output registers
   // output registers
   if(mant_out_reg) D_OUT <= sqrt_final;
   if(mant_out_reg) D_OUT <= sqrt_final;
   if(VAL_OUT && RDY_OUT) VAL_OUT <= 0;
   if(VAL_OUT && RDY_OUT) VAL_OUT <= 0;
   else if(mant_out_reg) VAL_OUT <= 1;
   else if(mant_out_reg) VAL_OUT <= 1;
 
 
   //delay output latch
   //delay output latch
   mant_out_reg <= mant_out;
   mant_out_reg <= mant_out;
 
 
end
end
 
 
 
 
endmodule
endmodule
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.