Just for the sake of completeness (since I was recently reminded about this question) I'll restate the answer that I finally settled on:
Given the following MPD snippet provided by the core vendor:
PORT IIC_DATA = "", DIR = IO, THREE_STATE=TRUE
PORT IIC_CLOCK = "", DIR = O, THREE_STATE=TRUE
I replace it with the following:
PORT IIC_DATA_I = "", DIR = I
PORT IIC_DATA_O = "", DIR = O
PORT IIC_DATA_T = "", DIR = O
PORT IIC_DATA = "", DIR = IO, THREE_STATE=TRUE, TRI_I = IIC_DATA_I, TRI_O = IIC_DATA_O, TRI_T = IIC_DATA_T
PORT IIC_CLOCK_O = "", DIR = O
PORT IIC_CLOCK_T = "", DIR = O
PORT IIC_CLOCK = "", DIR = O, THREE_STATE=TRUE, TRI_O = IIC_CLOCK_O, TRI_T = IIC_CLOCK_T
This works fine (as the underlying signals were defined in the VHDL anyway). It's a little bit of a hassle as I have to remember to do this each time I get an updated core from the vendor, but this is infrequent enough to not be a big deal. (I've been trying to persuade the vendor to add it themselves, but haven't had much luck thus far.)
First of all, this is not something you would normally do in hardware; you would do this in firmware on a microprocessor, either internal or external to the FPGA.
But if you absolutely had to design a datapath to do this, it should require nothing more than an integer adder and integer multiplier, along with a register we'll call the "integer accumulator" to handle the exponent, and an IEEE-754 adder and IEEE-754 multiplier along with an IEEE-754 accumulator register to handle the mantissa and ultimately produce the final result.
Let's get some terminology straight: In a number like 22.523×1020, the "22.523" is the mantissa and the "20" is the exponent. Let's call them the "decimal mantissa" and "decimal exponent" to distinguish them from the binary mantissa and binary exponent we'll eventually be producing.
Start by converting the decimal exponent to binary, which requires scanning its digits left-to-right, multiplying the integer accumulator by 10 before adding in the next digit. Negate the result if the exponent is negative.
Now, start converting the decimal mantissa. Again, scanning from left-to-right, we use a lookup table to convert each BCD digit to its IEEE-754 equivalent. We take the IEEE-754 accumulator, multiply it by 10, and add the converted digit to it. After we encounter the decimal point, we continue converting digits, but now we also decrement the binary version of the decimal exponent we computed in the previous paragraph once for each digit.
At this point, we have an integer representation of the decimal mantissa in the IEEE-754 accumulator, and we have a properly adjusted version of the original decimal exponent in the integer accumulator.
The final step is to look at the integer accumulator. If it is positive, you go into a loop that multiplies the IEEE-754 accumulator by 10 (again, from a lookup table) and decrements the integer accumulator until it reaches zero. If the integer accumulator was negative, you multiply the IEEE-754 accumulator by 0.1 and increment the integer accumulator until it is zero. In either case, when you finish, you have the final floating-point number in the IEEE-754 accumulator.
Oh, and if the decimal mantissa is negative, set the sign bit in the IEEE-754 number.
There are many potential ways to optimize this process, but that would depend on your exact situation. I hope this is enough to get you going.
Best 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:
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: