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)

Reply via email to