Line 88... |
Line 88... |
cntlz128Reg u4 (.clk(clk), .ce(ce), .i(bcd), .o(lz) );
|
cntlz128Reg u4 (.clk(clk), .ce(ce), .i(bcd), .o(lz) );
|
|
|
always_comb
|
always_comb
|
lz4 = lz >> 2'd2;
|
lz4 = lz >> 2'd2;
|
|
|
assign wd = zeroXp - 8'd1 + 8'd25 - lz4 + 8'd9; // constant except for lz
|
assign wd = zeroXp - 8'd1 + 8'd25 - lz4 + 8'd7; // constant except for lz
|
|
|
reg [11:0] xo;
|
reg [11:0] xo;
|
|
|
always_ff @(posedge clk)
|
always_ff @(posedge clk)
|
xo <= iz ? 'd0 : wd;
|
xo <= iz ? 'd0 : wd;
|
Line 102... |
Line 102... |
// right shift is required. There are only about 114 bits of precision, but the
|
// right shift is required. There are only about 114 bits of precision, but the
|
// incoming number is allowed to be 128-bit.
|
// incoming number is allowed to be 128-bit.
|
// Rounding is required only when the number needs to be right-shifted.
|
// Rounding is required only when the number needs to be right-shifted.
|
|
|
always_ff @(posedge clk)
|
always_ff @(posedge clk)
|
if (lz4 < 8'd9)
|
if (lz4 < 8'd7)
|
simag = bcd1 >> {8'd9 - lz4,2'd0};
|
simag = bcd1 >> {8'd7 - lz4,2'd0};
|
else
|
else
|
simag = bcd1 << {lz4 - 8'd9,2'd0};
|
simag = bcd1 << {lz4 - 8'd7,2'd0};
|
|
|
wire g = bcd1[{8'd9 - lz4,2'd0}]; // guard bit (lsb)
|
wire g = bcd1[{8'd7 - lz4,2'd0}]; // guard bit (lsb)
|
wire r = bcd1[{8'd9 - lz4,2'd0}-1]; // rounding bit
|
wire r = bcd1[{8'd7 - lz4,2'd0}-1]; // rounding bit
|
wire s = |(bcd1 & (128'd1 << {8'd9 - lz4,2'd0}-2) - 2'd1); // "sticky" bit
|
wire s = |(bcd1 & (128'd1 << {8'd7 - lz4,2'd0}-2) - 2'd1); // "sticky" bit
|
reg rnd;
|
reg rnd;
|
|
|
// Compute the round bit
|
// Compute the round bit
|
always_ff @(posedge clk)
|
always_ff @(posedge clk)
|
if (lz4 < 8'd9)
|
if (lz4 < 8'd7)
|
case (rmd)
|
case (rmd)
|
3'd0: rnd = (g & r) | (r & s); // round to nearest even
|
3'd0: rnd = (g & r) | (r & s); // round to nearest even
|
3'd1: rnd = 0; // round to zero (truncate)
|
3'd1: rnd = 0; // round to zero (truncate)
|
3'd2: rnd = (r | s) & !so; // round towards +infinity
|
3'd2: rnd = (r | s) & !so; // round towards +infinity
|
3'd3: rnd = (r | s) & so; // round towards -infinity
|
3'd3: rnd = (r | s) & so; // round towards -infinity
|