Suponiendo que su número está normalizado, es positivo y no es un NaN o infinito o algún otro patrón no convertible, debe tomar la mantisa, agregar un bit "1" a la izquierda y tomar tantos bits de Es como dice el valor en el exponente. El número resultante es la versión entera de su número.
Para redondearlo, verifique el primer bit descartado (el que se encuentra a la derecha del último bit tomado de la mantisa) y agréguelo al entero (usando la suma de enteros)
Algo como esto:
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
He usado esto para probar el módulo. Solo use esta página web para encontrar la representación hexadecimal de un número dado y colóquela en el código fuente del banco de pruebas. Simule el circuito y obtendrá el valor binario simple del entero más cercano a su número doble:
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