For some comparisons, check out:

http://www.gaisler.com/doc/grfpu_dasia.pdf

http://opencores.org/project,fpu

Are we looking to have full IEEE floating point, or a subset of IEEE?

Once there is enough code to do add/subtract/multiply I'd like to
write a regression test that runs a couple of floating point validation
tools.

On Mon, Jan 07, 2013 at 03:58:12PM +0100, Mark Marshall wrote:
> Hi.
> 
> I've only had a quick scan of this code, but I'm not sure I agree with it.
> 
> I thought that the exponent was an 8-bit unsigned number?  In that case
> sub_exponent is wrong - it should extend the exponents to 9 bits before
> doing the subtraction.  For example:
> 
> A = 0x88
> B = 0x03
> 
> A - B = 0x85
> 
> (A - B)[7] is 1, so your routine would report this as A < B.
> 
> Best regards,
> 
> Mark M.
> 
> On 6 January 2013 21:30, Timothy Normand Miller <[email protected]> wrote:
> 
> > I'll check this into the git repo when we have the IP stuff worked out.
> >  I've got most of the add/sub stuff worked out and some of multiply.  The
> > multiplier itself is in another module already.  I just need to wrap all
> > this into another level of hierarchy.
> >
> > Let's have a contest to see who can find the most mistakes.  :)
> >
> >
> >
> >
> > /*
> > Copyright 2013, Timothy Normand Miller, all rights reserved.
> > For now.
> > */
> >
> >
> > // Fields for normalized numbers
> > `define MANTISSA_SIZE 23
> > `define EXPONENT_SIZE 8
> > `define MANTISSA 22:0
> > `define EXPONENT 30:23
> > `define SIGN     31
> > `define FP_SIZE  32
> >
> > // Fields for denormalized numbers
> > // One extra exponent bit for exponent overflow
> > `define DEN_MANTISSA_SIZE 24
> > `define DEN_MANTISSA 23:0
> > `define DEN_EXPONENT 32:24
> > `define DEN_EXPONENT_SIZE 9
> > `define DEN_SIGN 33
> > `define DEN_FP_SIZE 34
> >
> > // Fields for denormalized numbers with GRS and overflow bits
> > `define GRS_MANTISSA_SIZE 28
> > `define GRS_MANTISSA 27:0
> > `define GRS_EXPONENT 36:28
> > `define GRS_EXPONENT_SIZE 9
> > `define GRS_SIGN 37
> > `define GRS_FP_SIZE 38
> >
> >
> > // Compare exponents and compute differences.  When subtracting, we need
> > // to know which operand is greater, so we always subtract smaller from
> > // greater.  We compare exponents by subtracting.  Which difference is
> > // negative tells us whether or not to swap, while the other difference
> > // indicates how far right to shift the lesser mantissa.
> > module sub_exponent(
> >     input clock,
> >     input [EXPONENT_SIZE-1:0] expA,
> >     input [EXPONENT_SIZE-1:0] expB,
> >     output reg [EXPONENT_SIZE-1:0] expA_m_expB,
> >     output reg [EXPONENT_SIZE-1:0] expB_m_expA,
> >     output reg A_lt_B,
> >     output reg B_lt_A);
> >
> > wire [EXPONENT_SIZE-1:0] difA, difB;
> > assign difA = expA - expB;
> > assign difB = expB - expA;
> >
> > always @(posedge clock) begin
> >     expA_m_expB <= difA;
> >     expB_m_expA <= difB;
> >     A_lt_B <= difA[EXPONENT_SIZE-1];
> >     B_lt_A <= difB[EXPONENT_SIZE-1];
> > end
> >
> > endmodule
> >
> >
> >
> >
> > // Compare mantissas.  If the exponents are equal, then we need to compare
> > // the mantissas to see which operand is smaller.  We only need one
> > difference,
> > // because we're not going to reuse the number for any other purpose.
> > module lt_mantissa(
> >     input clock,
> >     input [MANTISSA_SIZE-1:0] mantA,
> >     input [MANTISSA_SIZE-1:0] mantB,
> >     output reg AltB);
> >
> > wire [MANTISSA_SIZE-1:0] dif;
> > assign dif = mantA - mantB;
> >
> > always @(posedge clock) begin
> >     AltB <= dif[MANTISSA_SIZE-1];
> > end
> >
> > endmodule
> >
> >
> >
> >
> > // For products, need to compute new exponents and signs.
> > // We compute a 10-bit signed exponent, to detect underflow
> > module product_exponents(
> >     input clock,
> >     input [EXPONENT_SIZE-1:0] expA,
> >     input [EXPONENT_SIZE-1:0] expB,
> >     input signA,
> >     input signB,
> >     output reg [DEN_EXPONENT_SIZE-1:0] expC,
> >     output reg signC,
> >     output reg underflow);
> >
> > always @(posedge clock) begin
> >     {underflow, expC} <= (expA + expB) - 127;
> >     signC <= signA ^ signB;
> > end
> >
> > endmodule
> >
> >
> >
> >
> > // The mantissa has a hidden bit.  If the exponent is zero, that bit is
> > zero;
> > // if the exponent is nonzero, that bit is 1.
> > module denormalize(
> >     input clock,
> >     input [31:0] A,
> >     output reg signA,
> >     output reg [EXPONENT_SIZE-1:0] expA,
> >     output reg [DEN_MANTISSA_SIZE-1:0] mantA);
> >
> > wire high_bit = (0 != A[EXPONENT]);
> >
> > always @(posedge clock) begin
> >     signA <= A[SIGN];
> >     expA  <= A[EXPONENT];
> >     mantA <= {high_bit, A[MANTISSA]};
> > end
> >
> > endmodule
> >
> >
> >
> >
> > // If the "B" operand is greater, need to swap the values for stages
> > // down in the pipeline.
> > module swap(
> >     input clock,
> >     input [DEN_FP_SIZE-1:0] inA,
> >     input [DEN_FP_SIZE-1:0] inB,
> >     input expA_lt_expB,
> >     input expB_lt_expA,
> >     input mantA_lt_mantB,
> >     output reg [DEN_FP_SIZE-1:0] outA,
> >     output reg [DEN_FP_SIZE-1:0] outB);
> >
> > wire do_swap = expA_lt_expB || (!expB_lt_expA && mantA_lt_mantB);
> >
> > always @(posedge clock) begin
> >     outA <= do_swap ? inB : inA;
> >     outB <= do_swap ? inA : inB;
> > end
> >
> > endmodule
> >
> >
> >
> > // Based on the differences calculated earlier, shift the B mantissa
> > // right.  Now, both exponents are the same, so we keep track of only one.
> > module right_shift_mantissa(
> >     input clock,
> >     input [DEN_FP_SIZE-1:0] inB,
> >     input [4:0] shift_amt,
> >     input [EXPONENT_SIZE-1] expA,
> >     output reg [GRS_FP_SIZE-1:0] outB);
> >
> > wire [GRS_MANTISSA_SIZE-1:0] mantissa = {inB[DEN_MANTISSA], 3'b0};
> > wire [GRS_MANTISSA_SIZE-1:0] shifted = mantissa >> shift_amt;
> >
> > reg sticky_bit;
> > integer i;
> >
> > always @(mantissa or shift_amt) begin
> >     sticky_bit = 0;
> >     for (i=0; i<shift_amt; i=i+1) begin
> >         if (mantissa[i]) sticky_bit = 1;
> >     end
> > end
> >
> > always @(posedge clock) begin
> >     outB[GRS_MANTISSA] <= {shifted[GRS_MANTISSA_SIZE-1:1], sticky_bit};
> >     outB[GRS_EXPONENT] <= expA;
> >     outB[GRS_SIGN]     <= inB[DEN_SIGN];
> > end
> >
> > endmodule
> >
> >
> >
> > // Depending on signs and the operation, we'll add or subtract the
> > // operands.
> > module addsub_mantissas(
> >     input clock,
> >     input [GRS_MANTISSA_SIZE-1:0] mantA,
> >     input [GRS_MANTISSA_SIZE-1:0] mantB,
> >     input sub,
> >     output reg [GRS_MANTISSA_SIZE-1:0] sum);
> >
> > wire [GRS_MANTISSA_SIZE-1:0] subtrahend;
> > assign subtrahend = {GRS_MANTISSA_SIZE{sub}} ^ mantB;
> >
> > wire [GRS_MANTISSA_SIZE:0] dif;
> > assign dif = {mantA, 1'b1} + {subtrahend, sub};
> >
> > always @(posedge clock) begin
> >     sum <= dif[GRS_MANTISSA_SIZE:1];
> > end
> >
> > endmodule
> >
> >
> > // Compute the left or right shift necessary to get the highest 1 bit
> > // one to the right of the overflow bit.  On right shift, left will be
> > // invalid.
> > module compute_shift(
> >     input clock,
> >     input [GRS_MANTISSA_SIZE-1:0] inA,
> >     output reg [4:0] left,
> >     output reg right);
> >
> > integer i, shift;
> >
> > always @(inA) begin
> >     shift = 0;
> >     for (i=0; i<GRS_MANTISSA_SIZE-1; i=i+1) begin
> >         if (inA[i]) shift = GRS_MANTISSA_SIZE - 2 - i;
> >     end
> > end
> >
> > always @(posedge clock) begin
> >     right <= inA[GRS_MANTISSA_SIZE-1];
> >     left <= shift;
> > end
> >
> > endmodule
> >
> >
> >
> > // Clamp the shift amount so that we don't get a negative exponent.
> > module clamp_shift(
> >     input clock,
> >     input [4:0] left_in,
> >     input [7:0] exp_in,
> >     output [4:0] left_out);
> >
> > always @(posedge clock) begin
> >     if (left_in <= exp_in) begin
> >         left_out <= left_in;
> >     end else begin
> >         left_out <= exp_in;
> >     end
> > end
> >
> > endmodule
> >
> >
> >
> > // Shift the mantissa right or left to get highest bit into denormalization
> > // bit position.
> > module perform_shift(
> >     input clock,
> >     input [GRS_MANTISSA_SIZE-1:0] mantAin,
> >     input [GRS_EXPONENT_SIZE-1:0] expAin,
> >     input [4:0] left,
> >     input right,
> >     output reg [GRS_MANTISSA_SIZE-1:0] mantAout
> >     output reg [GRS_EXPONENT_SIZE-1:0] expAout);
> >
> > always @(posedge clock) begin
> >     if (right) begin
> >         mantAout <= mantAin[GRS_MANTISSA_SIZE-1:1];
> >         expAout <= expAin + 1;
> >     end else begin
> >         mantAout <= mantAin << left;
> >         expAout <= expAin - left;
> >     end
> > end
> >
> > endmodule
> >
> >
> >
> > // Use the GRS and lowest significant bits to compute rounding.
> > module round(
> >     input clock,
> >     input [GRS_MANTISSA_SIZE-1:0] inA,
> >     output reg [GRS_MANTISSA_SIZE-1:0] outA);
> >
> > // Round up if the GRS bits > 4.  If the GRS==4, then break tie using
> > // lowest significant bit.
> > wire do_round = (inA[2:0] > 4) || (inA[2] && inA[3]);
> >
> > always @(posedge clock) begin
> >     outA[2:0] <= 0;
> >     outA[GRS_MANTISSA_SIZE-1:3] <= inA[GRS_MANTISSA_SIZE-1:3] + do_round;
> > end
> >
> > endmodule
> >
> >
> >
> > // Rounding may have a carry out.  In this case we have to shift right
> > // once more.
> > module round_overflow_shift(
> >     input clock,
> >     input [GRS_MANTISSA_SIZE-1:0] mantAin,
> >     input [GRS_EXPONENT_SIZE-1:0] expAin,
> >     output reg [DEN_MANTISSA_SIZE-1:0] mantAout
> >     output reg [DEN_EXPONENT_SIZE-1:0] expAout);
> >
> > always @(posedge clock) begin
> >     if (mantAin[GRS_MANTISSA_SIZE-1]) begin
> >         mantAout <= mantAin[GRS_MANTISSA_SIZE-2:3];
> >         expAout <= expAin + 1;
> >     end else begin
> >         mantAout <= mantAin[GRS_MANTISSA_SIZE-1:4];
> >         expAout <= expAin;
> >     end
> > end
> >
> > endmodule
> >
> >
> >
> > // Finally, renormalize the result.  No special handling for denormalized
> > // numbers, but well turn overflows into infinities.
> > module renormalize(
> >     input clock,
> >     input [DEN_MANTISSA_SIZE-1:0] mantAin,
> >     input [DEN_EXPONENT_SIZE-1:0] expAin,
> >     output reg [MANTISSA_SIZE-1:0] mantAout
> >     output reg [EXPONENT_SIZE-1:0] expAout,
> >     output reg overflow);
> >
> > wire ovl = expAin >= 255;
> >
> > always @(posedge clock) begin
> >     overflow <= ovl;
> >     if (ovl) begin
> >         mantAout <= 0;
> >         expAout <= 255;
> >     end else begin
> >         mantAout <= mantAin;
> >         expAout <= expAin;
> >     end
> > end
> >
> > endmodule
> >
> >
> >
> > --
> > Timothy Normand Miller, PhD
> > Assistant Professor of Computer Science, Binghamton University
> > http://www.cs.binghamton.edu/~millerti/<http://www.cse.ohio-state.edu/~millerti>
> > Open Graphics Project
> >
> > _______________________________________________
> > Open-graphics mailing list
> > [email protected]
> > http://lists.duskglow.com/mailman/listinfo/open-graphics
> > List service provided by Duskglow Consulting, LLC (www.duskglow.com)
> >

> _______________________________________________
> Open-graphics mailing list
> [email protected]
> http://lists.duskglow.com/mailman/listinfo/open-graphics
> List service provided by Duskglow Consulting, LLC (www.duskglow.com)


-- 
--------------------------------------------------------------------------
Troy Benjegerdes                'da hozer'                 [email protected]

Somone asked my why I work on this free (http://www.fsf.org/philosophy/)
software & hardware (http://q3u.be) stuff and not get a real job.
Charles Shultz had the best answer:

"Why do musicians compose symphonies and poets write poems? They do it
because life wouldn't have any meaning for them if they didn't. That's why
I draw cartoons. It's my life." -- Charles Shultz
_______________________________________________
Open-graphics mailing list
[email protected]
http://lists.duskglow.com/mailman/listinfo/open-graphics
List service provided by Duskglow Consulting, LLC (www.duskglow.com)

Reply via email to