View Single Post
  #1 (permalink)  
Old 06-03-2009, 10:45 PM
pallav
Guest
 
Posts: n/a
Default 64-bit comparator.

I am designing a simple FPU comparison unit for 32/64 bit floating
point. My RTL code is simulating OK and now I'm trying to improve the
code to make it more efficient. I'm trying to improve a 64-bit
comparison. In my unit, the comparison can be either 31 bits (single-
precision) or 63 bits (double precision), excluding sign bit. Right
now, what I do is put a 32-bit multiplexer in front of the comparator
and zero pad the single-precision value to make it 63 bits. Is there a
way to recode this to get ride of these multiplexers to handle both
cases? I've been able to do it pretty easily for detecting A == B == 0
or A != 0, B != 0.

My code is below. The line in question is "assign altb64 = ...."

Thanks for any ideas.

Kind regards.


////////////////////////////////////////////////////////////////////////////////
// FPU Compare Unit
////////////////////////////////////////////////////////////////////////////////
module fpucmpU(/*AUTOARG*/
// Outputs
aeqb, aleb, altb, invalidexception,
// Inputs
srcA, srcB, sp, eqop
);

input [63:0] srcA, srcB; // operands A/B
input sp; // 1 - float32, 0 - float64
input eqop; // if this is strictly a == b
operation
output aeqb, aleb, altb; // a == b, a <= b, a < b
output invalidexception; // if invalid exception is thrown

/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module
outputs)
wire aNaN; // From cmpnan of
fpuNaNU.v
wire asigNaN; // From cmpnan of
fpuNaNU.v
wire bNaN; // From cmpnan of
fpuNaNU.v
wire bsigNaN; // From cmpnan of
fpuNaNU.v
// End of automatics

wire aorbNaN, aorbsigNaN;
wire equal, less;
wire signmismatch, aandbzero32, aandbzero64;
wire aeqb32, aeqb64, altb64;

fpuNaNU cmpnan(/*AUTOINST*/
// Outputs
.aNaN (aNaN),
.bNaN (bNaN),
.asigNaN (asigNaN),
.bsigNaN (bsigNaN),
// Inputs
.srcA (srcA[63:0]),
.srcB (srcB[63:0]),
.sp (sp));

// if A or B is a NaN / signaling NAN.
assign aorbNaN = aNaN | bNaN;
assign aorbsigNaN = asigNaN | bsigNaN;

// IEEE standard states that equality comparison don't throw an
invalid
// exception unless the operand is a signaling NaN. for <=/<, the
exception
// is thrown if atleast one of the operands is NaN.
assign invalidexception = eqop ? aorbsigNaN : aorbNaN;

// determine if A/B have same sign.
assign signmismatch = sp ? srcA[31] ^ srcB[31] : srcA[63] ^ srcB
[63];

// determine if A == B == 0 for single/double precision.
assign aandbzero32 = ~(| (srcA[30:0] | srcB[30:0]));
assign aandbzero64 = aandbzero32 & ~(| (srcA[62:31] | srcB
[62:31]));

// determine if A == B for single/double precision.
assign aeqb32 = (srcA[30:0] == srcB[30:0]);
assign aeqb64 = aeqb32 & (srcA[62:31] == srcB[62:31]);

// assign aleb32 = (srcA[30:0] < srcB[30:0]);
// assign aeqb64 = aleb32 & (

assign altb64 = {sp ? 32'b0 : srcA[62:31], srcA[30:0]} < {sp ?
32'b0 : srcB[62:31], srcB[30:0]};

// check for equality.
// a) if signs of A/B mismatch, A == B == 0.
// b) if signs match, A == B if all the bits are equal.
assign equal = sp ? (signmismatch & aandbzero32) | (~signmismatch &
aeqb32)
: (signmismatch & aandbzero64) | (~signmismatch &
aeqb64);

// check for less than.
// a) if signs of A/B mismatch, A < B if A.sign == 1 and A != 0 and
B != 0.
// b) if signs match, A < B, if (sign ^ (A < B)).
assign less = sp ? (signmismatch & srcA[31] & ~aandbzero32) |
(~signmismatch & ~equal & (srcA[31] ^ /*(srcA
[30:0] < srcB[30:0])*/ altb64))
: (signmismatch & srcA[63] & ~aandbzero64) |
(~signmismatch & ~equal & (srcA[63] ^ /*(srcA
[62:0] < srcB[62:0])*/ altb64));

// determine the relations.
assign aeqb = ~(aorbNaN | aorbsigNaN) & equal;
assign altb = ~aorbNaN & less;
assign aleb = ~aorbNaN & (aeqb | altb);
endmodule // fpucompareU
Reply With Quote