Code checks out...
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
void u_to_f(uint64_t u, float *d) {
int m = 128+48-1;
uint32_t *p = (uint32_t *)d;
if(u == 0) {
*p = 0;
return;
}
if((u>>(49-24)) == 0) {
u <<= 24;
m -= 24;
}
if((u>>(49-12)) == 0) {
u <<= 12;
m -= 12;
}
if((u>>(49-6)) == 0) {
u <<= 6;
m -= 6;
}
if((u>>(49-4)) == 0) {
u <<= 4;
m -= 4;
}
if((u>>(49-2)) == 0) {
u <<= 2;
m -= 2;
}
if((u>>(49-1)) == 0) {
u <<= 1;
m -= 1;
}
*p = (m<<23) + ((u >> 25)&0x7FFFFF);
}
int main(int argc, char *argv[]) {
uint64_t u;
for(int i = 0; i < 1000; i++) {
u = rand() % 100000;
float f = u;
u_to_f(u, &f);
printf("%10lu %10.1f %10.1f\n",u,(float)u, f);
}
}
How to implement it in VHDL depends on your needs for throughput, latency, and so on.
(and of course code is broken on machines with different endian).