I want to convert the IEEE Double value computed in my code to Integer.
E.g. I have computed: X = 64'hxxxxxxxxxxxxxxxx; Now i want to use it as index of an array as: some_array[X];
How can I do it? Is there any IP-Core or any other third-party Core for this conversion? Or some synthesis-able method/algorithm?
Answer
Assuming your number is normalized, it's positive and it's not a NaN or infinity or some other non convertible pattern, you have to take the mantissa, add a "1" bit at the left of it, and take as many bits of it as the value in the exponent says. The reulting number is the integer version of your number. To round it, check the first bit discarded (the one at the right of the last bit taken from the mantissa) and add it to the integer (using integer addition)
Something like this:
module double2int(
input clk,
input rst,
input [63:0] vin,
output reg [52:0] vout,
output reg done,
output reg error
);
wire sign = vin[63];
wire [10:0] exponent = vin[62:52];
wire [51:0] binaryfraction = vin[51:0];
wire [52:0] mantissa = {1'b1,binaryfraction};
reg [5:0] cnt;
reg start = 1'b0;
reg round;
always @(posedge clk) begin
if (rst) begin
if (sign==1'b0 && exponent >= 11'd1023 && exponent <= 11'd1075) begin
// only convert positive numbers between 0 and 2^52
cnt <= 52 - (exponent - 11'd1023); // how many bits to discard from mantissa
{vout,round} <= {mantissa,1'b0};
start <= 1'b1;
done <= 1'b0;
error <= 1'b0;
end
else begin
start <= 1'b0;
error <= 1'b1;
end
end
else if (start) begin
if (cnt != 0) begin // not finished yet?
cnt <= cnt - 1; // count one bit to discard
{vout,round} <= {1'b0, vout[52:0]}; // and discard it (bit just discarded goes into "round")
end
else begin // finished discarding bits then?
if (round) // if last bit discarded was high, increment vout
vout <= vout + 1;
start <= 1'b0;
done <= 1'b1; // signal we're done
end
end
end
endmodule
I've used this to test bench the module. Just use this webpage to find the hexadecimal representation of a given number and place it into the test bench source code. Simulate the circuit and you will get the plain binary value of the closest integer to your double number:
module tb_double2int;
// Inputs
reg clk;
reg rst;
reg [63:0] vin;
// Outputs
wire [52:0] vout;
wire error;
wire done;
// Instantiate the Unit Under Test (UUT)
double2int uut (
.clk(clk),
.rst(rst),
.vin(vin),
.vout(vout),
.done(done),
.error(error)
);
initial begin
// Initialize Inputs
clk = 0;
rst = 0;
vin = 0;
// Add stimulus here
vin = 64'h4058F22D0E560419; // Example: 99.784 . Must return 100d in vout (binary 0000....00000001100100)
rst = 1;
#20;
rst = 0;
if (!error)
@(posedge done);
@(posedge clk);
$finish;
end
always begin
clk = #5 !clk;
end
endmodule
No comments:
Post a Comment