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)
