Oops.  You are right about that.  I've made appropriate adjustments.

On Mon, Jan 7, 2013 at 9:58 AM, Mark Marshall <[email protected]>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)
>>
>
>


-- 
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)

Reply via email to