Punto flotante TMS320 (DSP de Texas Instruments del '98)

8

Background

¿Hay alguien aquí que sea un experto en EE con experiencia en programación que haya trabajado con el DSP de la serie TMS320 C3X de Texas Instruments? Actualmente estoy trabajando con el C3X para un proyecto. Mi objetivo aquí es convertir los valores de punto flotante con formato C3X hexadecimal al formato IEEE 754. El código que tengo funciona correctamente para:

DondexeslaentradasinglenúmerohexadecimalC3Xdepuntoflotante(representadocomounUInt32).

Elproblemaescuandointentousarunnúmerocomo0.123.ParecequesiempreobtengounvalordeNaNcomoresultado.Actualmenteestoyusando este fragmento de código de la Universidad de Florida que he portado a C #.

Procedure

  1. Cambia los campos de signo y exponente para pasar de C3X a IEEE. No mostraré este código (a menos que se me solicite) ya que creo que es muy sencillo para cualquiera que haya trabajado con este DSP.
  2. Realice el algoritmo de la Universidad de Florida (vinculado arriba), que creo que no entiendo completamente.
  3. Combine el signo, el exponente y la mantisa en un punto flotante IEEE 754 de precisión simple.

Implementación de C #

Aquí está el código utilizado para implementar el algoritmo para cuando el número flotante de C3X está entre 0 y 1 (donde ocurre el problema). El objeto c30 representa el número de punto flotante de C3X. El objeto ieee representa el número de punto flotante IEEE 754.

EDITAR: A petición popular, aquí hay un ejemplo de código que no es horrible. Este ejemplo es la versión que funciona correctamente, donde volcamos en 15,913.35 ... (como C3X hexadecimal).

C30Float c30 = null;
UInt32 bias = 127;
Int32 mantissa = 0;
Int32 digit = 0;
double fraction = 0;
double exponent = 0;
double fpValue = 0;
double sign = 0;

// 1. Declare the new C3X floating point value.
c30 = new C30Float(0x0D78A56B);

// 2. Get the sign bit value.
sign = c30.GetSign();

// 3. Decide whether or not to do the flip.
if (sign == 1)
{
    // flip
    mantissa = c30.GetMantissa();
    mantissa = mantissa + 1;
    mantissa = (~mantissa) & 0x007FFFFF; // the first 9 bits have nothing to do with the mantissa
}
else
{
    mantissa = c30.GetMantissa();
}

// 4. Obtain part of the fraction (do the swim!).
for (int i = -1; i > -24; i--)
{
    // mantissa index
    int currentDigit = i + 23; // n = -23 + 23 => n = 0

    // shift forward (get the digit)
    digit = mantissa;
    digit = digit & (1 << currentDigit);

    // shift back (get the digit into the lowest place)
    digit = digit >> currentDigit;

    // apply the digit to the fraction
    fraction += digit * Math.Pow(2, i);
}

// 5. Obtain the exponential part of the number.
exponent = c30.GetExponent() + 0x7F;

// 6. Get the floating point number.
fpValue = Math.Pow(-1, sign);
fpValue *= (1 + fraction) * Math.Pow(2, exponent - bias);

Sé que no proporcioné los detalles de implementación para lo siguiente:

GetMantissa()
GetExponent()
GetSign()

o ...

SetMantissa()
SetExponent()
SetSign()

La razón de esto es que todo lo que están haciendo es ingresar / jalar los números a / desde sus campos respectivos como se especifica en la Guía del usuario de TMS320 C3X . Quién sabe, tal vez es donde me equivoco, pero por ahora me gustaría comenzar donde creo que comienza el alcance del problema. Si alguno de ustedes cree que el problema no está aquí, no dude en preguntar acerca de esta implementación y le proporcionaré más detalles según sea necesario.

Pregunta

Mi problema es aparentemente con números entre 0 y 1. Entonces, si alguien ha conocido los valores hexadecimales de C3X y sus contrapartes / reales conocidos de la contraparte, puedo conectarlos y pedirlos, eso sería genial, así que puedo solucionar este algoritmo.

Nota: No tenemos el DSP frente a nosotros por lo que estamos haciendo y no podemos simplemente sacar los números.

    
pregunta Snoop

1 respuesta

1

La Guía del usuario de TMS320C3x enumera algunos valores de prueba:

  • Valor hexadecimal del valor flotante C3X interpretado como uint32 ~~ Valor de punto flotante correspondiente
  • 0x02400000 ~~ +6.0 (consulte las páginas 5-10)
  • 0x01C00000 ~~ -3.0 (consulte la página 5-11)
  • 0xFB400000 ~~ (+3/64) (vea p. 5-11)

Supongo que quieres código algo más como:

/*
Convert from single-precision TMS C3x floating point
to single-precision IEEE floating point.
2016-07-11: minor tweaks by David Cary
2016-03-21: StevieV

(see
http://electronics.stackexchange.com/questions/223832/tms320-floating-point-texas-instruments-dsp-from-98
http://etd.fcla.edu/UF/UFE0005060/tmsieeeconv.c
http://etd.fcla.edu/UF/UFE0005060/tmsieeeconv.h
)
*/

C30Float c30 = null;
Int32 mantissa = 0;
double exponent = 0;
double sign = 0;
double fpValue = 0;

// 1. Declare the new single precision C3X floating point value.
c30 = new C30Float(0x0D78A56B);

/*
We could have followed page 5-21 in the TMS320C3x User's Guide
http://www.ti.com/lit/ug/spru031f/spru031f.pdf
for C3X-->IEEE conversion.

But it seemed simpler to follow page 5-9
in the TMS320C3x User's Guide
"5.3.5 Determining the Decimal Equivalent of a TMS320C3x Floating-Point Format"
http://www.ti.com/lit/ug/spru031f/spru031f.pdf
*/

// 2. Break up the C3X floating value into its components
// (Assume that these 3 functions deal with endianness).
sign = c30.GetSign(); // either 0 (positive) or 1 (negative)
exponent = c30.GetExponent(); // a signed 8-bit integer, -128 to +127.
mantissa = c30.GetMantissa(); // a 23-bit unsigned integer

// insert implied most significant bit to the left of MSB of the mantissa.
mantissa = ((1 + sign) << 23) + mantissa;

// 6. Get the floating point number.
// Move the binary point left 22 places,
// then adjust further based on exponent.
// (Possibly something like ldexp() or BitConverter.ToSingle()
// would be more efficient).
fpValue = (-sign) * mantissa * Math.Pow(2, exponent - 22);
return fpValue;
    
respondido por el davidcary

Lea otras preguntas en las etiquetas