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

Subversion Repositories sbd_sqrt_fp

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 2 to Rev 3
    Reverse comparison

Rev 2 → Rev 3

/tags/start/sbd_sqrt_fp_state_mach.v
0,0 → 1,101
/****************************************************************************
sbd_sqrt_fp_state_mach
 
- state machine for sbd_sqrt_fp32
 
Copyright (C) 2005 Samuel Brown
sam.brown@sbdesign.org
 
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
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,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
 
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
****************************************************************************/
 
 
module sbd_sqrt_fp_state_mach ( CLK,VAL_IN,INIT,LSR,ENR,ENL,EN_D,DLEFT,VAL_OUT );
parameter termval = 25;
input CLK;
input VAL_IN;
output wire INIT;
output wire LSR;
output wire ENR;
output wire ENL;
output wire EN_D;
output wire DLEFT;
output wire VAL_OUT;
 
wire begPulse;
reg terminate;
reg [6:0] currentState;
wire [6:0] nextState;
reg [5:0] countValue;
 
reg val_state_reg;
wire active;
 
initial
begin
currentState = 0;
countValue = 0;
val_state_reg = 0;
end
 
assign INIT = currentState[6];
assign LSR = currentState[5];
assign ENR = currentState[4];
assign ENL = currentState[3];
assign EN_D = currentState[2];
assign DLEFT = currentState[1];
 
assign nextState[6] = begPulse & ~terminate;
assign nextState[5] = currentState[4]; // 31 or 25
assign nextState[4] = currentState[6] | (currentState[5] & ~terminate);
assign nextState[3] = currentState[6] | (currentState[5] & ~terminate);
assign nextState[2] = currentState[4] | (currentState[5] & ~terminate);
assign nextState[1] = currentState[5] & ~terminate;
assign nextState[0] = currentState[6] | (currentState[5] & ~terminate);
 
always @ (posedge CLK)
begin:sqrtcount
if(begPulse) countValue <= 0;
else if(currentState[0]) countValue <= countValue + 1;
end
 
always @ (posedge CLK)
begin:stateReg
currentState <= nextState;
end
 
always @ (countValue, begPulse)
begin:termassign
if((countValue == termval) && ~begPulse) terminate = 1;
else terminate = 0;
end
 
//assign terminate = (countValue[4] & countValue[3] & ~countValue[2] & ~countValue[1] & countValue[0]) & ~begPulse;
 
//------------------- val in and out states ---------------------
 
always @ (posedge CLK)
begin:val_state_register
val_state_reg <= active & ~VAL_OUT;
end
 
assign begPulse = VAL_IN & ~val_state_reg;
assign active = begPulse | val_state_reg;
assign VAL_OUT = terminate & active;
 
endmodule
/tags/start/sbd_adsu.v
0,0 → 1,45
/****************************************************************************
sbd_adsu
 
- ADSU
 
Copyright (C) 2005 Samuel Brown
sam.brown@sbdesign.org
 
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
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,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
 
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
****************************************************************************/
 
module sbd_adsu(A,B,ADD,C_IN,C_OUT,S);
parameter bitlength=8;
 
input [bitlength-1:0] A;
input [bitlength-1:0] B;
input ADD;
input C_IN;
output wire C_OUT;
output wire [bitlength-1:0] S;
wire [bitlength-1:0] Bx;
wire [bitlength:0] tmp;
assign Bx = B ^ {bitlength{~ADD}};
assign tmp = A + Bx + C_IN;
 
assign S = tmp[bitlength-1:0];
assign C_OUT = tmp[bitlength];
 
endmodule
/tags/start/sbd_sqrt_fp.v
0,0 → 1,256
/****************************************************************************
sbd_sqrt_fp
 
- square root function for single or double precisons ieee 754
floating-point numbers
 
This core is capable of handling single or double precision floating-
poing numbers. For single precision, set the bitlength parameter to 32;
for double precision, set the bitlength parameter to 64. The algorithm
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
through from input to output, so if given negative input, this core
will produce a negative output corresponding to -1 * sqrt(|input|).
 
Ports: - all signals are active high
 
input [bitlength-1:0] D_IN; // single or double precison input
input VAL_IN; // Assert VAL_IN to signal a valid
input value. The module will only
accept input when RDY_IN is asserted.
If RDY_IN is low, then VAL_IN should
remain asserted until RDY_IN goes
high. VAL_IN and RDY_IN must both be
asserted for one clock cycle for
computation to begin.
output wire RDY_IN; // module is ready to accept input
input CLK; // clock
output reg [bitlength-1:0] D_OUT; // single or double precision output
output reg VAL_OUT; // VAL_OUT is asserted when the output
is valid. VAL_OUT will remain asserted
and D_OUT will persist until VAL_OUT and
RDY_OUT have both been asserted for one
clock cycle.
input RDY_OUT; // when asserted, downstream logic is
ready to accept output of module
 
This core was designed using synchronous resets, for use in FPGAs. The
synchronous resets could easily be made asynchronous for use in ASICs by
editing the always @ (posedge CLK) blocks in this and all dependant files.
 
Resource Utilization:
(synthesized with XST for Virtex4 - no architectural dependancies exist in this core
- this is merely an example)
 
Single Precision:
Slices: 155
Flip Flops: 204
4-Input LUTs: 269
 
Double Precision:
Slices: 324
Flip Flops: 417
4-Input LUTs: 566
 
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,
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
be possible with a little effort.
This module uses the following files:
 
sbd_sqrt_fp_calc_mant.v
sbd_sqrt_fp_state_mach.v
sbd_shifter_left2.v
sbd_shifter_left3_right2.v
sbd_adsu.v
 
Copyright (C) 2005 Samuel Brown
sam.brown@sbdesign.org
 
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
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,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
 
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
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 );
 
parameter bitlength = 32;
 
input [bitlength-1:0] D_IN;
input VAL_IN;
output wire RDY_IN;
input CLK;
output reg [bitlength-1:0] D_OUT;
output reg VAL_OUT;
input RDY_OUT;
 
reg [bitlength-1:0] raw_data_reg;
reg beg_in_reg;
reg d_rdy_reg;
wire mant_out;
reg mant_out_reg;
 
wire [bitlength-1:0] sqrt_final;
 
generate
if(bitlength == 32)
begin:single
 
//------------------ Single Precision --------------------------------------
 
wire [7:0] exp_off, exp_adj, exp_final;
wire non_zero_exp = ~(!raw_data_reg[30:23]);
 
wire [23:0] mant_final;
wire [22:0] mant_final_imp = mant_final[22:0];
reg [23:0] mant_adj; // mantissa with explicit leading bit - adjusted
// for even/odd exponent
 
//------------ Exponent Calculation & Mantissa Preparation --------------
 
sbd_adsu exp_offset_adsu (
.A(raw_data_reg[30:23]),
.B(8'h7F),
.ADD(1'b0),
.C_IN(1'b1),
.S(exp_off));
defparam exp_offset_adsu.bitlength = 8;
 
sbd_adsu exp_adjust_adsu (
.A(8'h7F),
.B({ exp_off[7], exp_off[7:1] }),
.ADD(1'b1),
.C_IN(1'b0),
.S(exp_adj));
defparam exp_adjust_adsu.bitlength = 8;
 
assign exp_final = exp_adj & {8{non_zero_exp}};
 
always @ (raw_data_reg, non_zero_exp)
begin:mant_adj_mux
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] };
end
 
//------------- Mantissa Calculation --------------------------------------
 
 
sbd_sqrt_fp_calc_mant mant_iterations (
.MANT_IN(mant_adj),
.CLK(CLK),
.VAL_IN(beg_in_reg),
.MANT_OUT(mant_final),
.VAL_OUT(mant_out));
defparam mant_iterations.mantlength = 24;
 
assign sqrt_final = { raw_data_reg[bitlength-1], exp_final, mant_final_imp };
 
end
else if(bitlength == 64)
begin:double
 
//------------------ Doule Precision ---------------------------------------
 
wire [10:0] exp_off, exp_adj, exp_final;
wire non_zero_exp = ~(!raw_data_reg[62:52]);
 
wire [52:0] mant_final;
wire [51:0] mant_final_imp = mant_final[51:0];
reg [52:0] mant_adj; // mantissa with explicit leading bit - adjusted
// for even/odd exponent
 
//------------ Exponent Calculation & Mantissa Preparation --------------
 
sbd_adsu exp_offset_adsu (
.A(raw_data_reg[62:52]),
.B(11'h3FF),
.ADD(1'b0),
.C_IN(1'b1),
.S(exp_off));
defparam exp_offset_adsu.bitlength = 11;
 
sbd_adsu exp_adjust_adsu (
.A(11'h3FF),
.B({ exp_off[10], exp_off[10:1] }),
.ADD(1'b1),
.C_IN(1'b0),
.S(exp_adj));
defparam exp_adjust_adsu.bitlength = 11;
 
assign exp_final = exp_adj & {11{non_zero_exp}};
 
always @ (raw_data_reg, non_zero_exp)
begin:mant_adj_mux
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] };
end
 
//------------- Mantissa Calculation --------------------------------------
 
 
sbd_sqrt_fp_calc_mant mant_iterations (
.MANT_IN(mant_adj),
.CLK(CLK),
.VAL_IN(beg_in_reg),
.MANT_OUT(mant_final),
.VAL_OUT(mant_out));
defparam mant_iterations.mantlength = 53;
 
assign sqrt_final = { raw_data_reg[bitlength-1], exp_final, mant_final_imp };
 
end
endgenerate
 
 
assign RDY_IN = ~d_rdy_reg;
wire beg_in = VAL_IN & RDY_IN;
 
initial
begin:simzero
D_OUT <= 0;
VAL_OUT <= 0;
raw_data_reg <= 0;
beg_in_reg <= 0;
d_rdy_reg <= 0;
mant_out_reg <= 0;
end
 
always @ (posedge CLK)
begin:reg_input
// input buffer
if(beg_in) raw_data_reg <= D_IN;
 
// val delay
beg_in_reg <= beg_in;
 
// RDY state
if(mant_out) d_rdy_reg <= 0;
else if(beg_in) d_rdy_reg <= 1;
 
// output registers
if(mant_out_reg) D_OUT <= sqrt_final;
if(VAL_OUT && RDY_OUT) VAL_OUT <= 0;
else if(mant_out_reg) VAL_OUT <= 1;
 
//delay output latch
mant_out_reg <= mant_out;
 
end
 
 
endmodule
/tags/start/sbd_sqrt_fp_calc_mant.v
0,0 → 1,94
/****************************************************************************
sbd_sqrt_fp_calc_mant
 
- mantissa calculation for sbd_sqrt_fp
 
Copyright (C) 2005 Samuel Brown
sam.brown@sbdesign.org
 
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
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,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
 
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
****************************************************************************/
 
module sbd_sqrt_fp_calc_mant (MANT_IN,CLK,VAL_IN,MANT_OUT,VAL_OUT);
 
parameter mantlength = 24;
input [mantlength-1:0] MANT_IN;
input CLK;
input VAL_IN;
output wire [mantlength-1:0] MANT_OUT;
output VAL_OUT;
 
wire init, lsr, enr, enl, en_d, dleft;
 
wire [1:0] shiftLeft1SerialOut;
wire [(2*mantlength)-1:0] biPOUT, adsuOutput, shiftLeft2ParallelOut;
 
sbd_shifter_left2 shiftLeft1 (
.SIN(2'b00),
.PIN(MANT_IN),
.LOAD(init),
.RST(1'b0),
.SHIFT(enl),
.CLK(CLK),
.SOUT(shiftLeft1SerialOut));
defparam shiftLeft1.bitlength = mantlength;
 
sbd_adsu adsu_inst (
.A(shiftLeft2ParallelOut),
.B(biPOUT),
.ADD(shiftLeft2ParallelOut[47]),
.C_IN(~shiftLeft2ParallelOut[47]),
.S(adsuOutput));
defparam adsu_inst.bitlength = 2*mantlength;
 
sbd_shifter_left2 shiftLeft2 (
.SIN(shiftLeft1SerialOut),
.PIN(adsuOutput),
.LOAD(lsr),
.RST(init),
.SHIFT(enr),
.CLK(CLK),
.POUT(shiftLeft2ParallelOut));
defparam shiftLeft2.bitlength = 2*mantlength;
sbd_shifter_left3_right2 shiftBI (
.SINLSB({~shiftLeft2ParallelOut[(2*mantlength)-1],shiftLeft2ParallelOut[(2*mantlength)-1],1'b1}),
.SINMSB(2'b00),
.PIN({ {2*mantlength-1{1'b0}}, 1'b1 }),
.LOAD(init),
.LR(~dleft),
.RST(1'b0),
.SHIFT(en_d),
.CLK(CLK),
.POUT(biPOUT));
defparam shiftBI.bitlength = 2*mantlength;
 
assign MANT_OUT = biPOUT[mantlength-1:0];
 
sbd_sqrt_fp_state_mach state_mach (
.CLK(CLK),
.VAL_IN(VAL_IN),
.INIT(init),
.LSR(lsr),
.ENR(enr),
.ENL(enl),
.EN_D(en_d),
.DLEFT(dleft),
.VAL_OUT(VAL_OUT));
defparam state_mach.termval = mantlength + 1;
 
endmodule
/tags/start/sbd_shifter_left2.v
0,0 → 1,56
/****************************************************************************
sbd_shifter_left2
- shift register - shifts left - towards MSB - 2 bits
 
Copyright (C) 2005 Samuel Brown
sam.brown@sbdesign.org
 
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
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,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
 
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
****************************************************************************/
 
 
 
module sbd_shifter_left2 (SIN,PIN,LOAD,RST,SHIFT,CLK,SOUT,POUT);
 
parameter bitlength = 24;
input [1:0] SIN;
input [bitlength-1:0] PIN;
input LOAD;
input RST;
input SHIFT;
input CLK;
output wire [1:0] SOUT;
output wire [bitlength-1:0] POUT;
 
reg [bitlength-1:0] writeData, readData;
 
assign POUT = readData;
assign SOUT = readData[bitlength-1:bitlength-2];
 
always @ (posedge CLK)
begin:shiftreg
if(RST) readData <= 0;
else if(SHIFT | LOAD) readData <= writeData;
end
 
always @ (readData, SIN, PIN, LOAD)
begin:shiftmux
if(LOAD) writeData = PIN;
else writeData = { readData[bitlength-3:0], SIN };
end
 
endmodule
/tags/start/sbd_shifter_left3_right2.v
0,0 → 1,59
/****************************************************************************
sbd_shifter_left3_right2
- shift register - shifts left - towards MSB - 3 bits or shifts right -
towards LSB - 2 bits
 
Copyright (C) 2005 Samuel Brown
sam.brown@sbdesign.org
 
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
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,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
 
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
****************************************************************************/
 
module sbd_shifter_left3_right2 (SINLSB,SINMSB,PIN,LOAD,LR,RST,SHIFT,CLK,POUT);
parameter bitlength = 48;
input [2:0] SINLSB;
input [1:0] SINMSB;
input [bitlength-1:0] PIN;
input LOAD;
input LR;
input RST;
input SHIFT;
input CLK;
output wire [bitlength-1:0] POUT;
 
reg [bitlength-1:0] writeData, readData;
wire [1:0] sel = { LOAD, LR };
 
assign POUT = readData;
 
always @ ( posedge CLK)
begin:shiftreg
if(RST) readData <= 0;
else if(SHIFT | LOAD) readData <= writeData;
end
 
always @ (sel, readData, SINLSB, SINMSB, PIN)
begin:loadmux
casez(sel)
2'b00: writeData = { readData[bitlength-4:0], SINLSB };
2'b01: writeData = { SINMSB, readData[bitlength-1:2] };
2'b1z: writeData = PIN;
endcase
end
 
endmodule

powered by: WebSVN 2.1.0

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