Encontré el método para el lenguaje c . Pero no sé cómo realizar esto en VHDL. Sea un número de punto fijo (de 12 a -19) como 3456,478396. Necesito dividir este número por completo en números separados 3456,478396 --> 3, 4, 5, 6, (punto), 4, 7, 8, 3, 9, 6. .. en 11 variables de tipo entero. ¿Cómo realizar esto en VHDL?
signal example : sfixed(4 downto -4);
--'example' contains 9.75 then it is storage as "01001.1100".
--simply example ="10011100".
--10011100 --> integer 156
¿Cómo recuperar el número 9.75 original de 156 para separarlo en un solo dígito?
SOLÍA,
library ieee;
library ieee_proposed;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee_proposed.float_pkg.ALL;
use ieee_proposed.fixed_pkg.ALL;
use ieee_proposed.fixed_float_types.ALL;
Aquí hay algo de pseudocódigo.
Tomemos primero los que quedan del decimal, el número máximo es => 2 dígitos decimales.
signal ex : sfixed(4 downto -4);
temp <= ex(4 downto 0);
L_0 <= temp mod 10;
temp <= temp/10;
L_1 <= temp mod 10;
Ejemplo:
ex=
=
temp <= 12
L_0 <= 12 mod 10 = 2
temp <= 12/10 = 1
L_1 <= 1 mod 10 = 1
Y luego los de la derecha, el número más pequeño => 0.0625 => 4 dígitos decimales. Mismo método que antes, simplemente multiplicar por antes de que empieces. Porque en binario se traduce a en decimal Entonces, el ancho de bit de la temperatura debe ser 14 bits porque es cual es su mayor valor.
signal ex : sfixed(4 downto -4);
temp <= ex(0 downto -4);
temp <= temp*625
R_3 <= temp mod 10;
temp <= temp/10;
R_2 <= temp mod 10;
temp <= temp/10;
R_1 <= temp mod 10;
temp <= temp/10;
R_0 <= temp mod 10;
Ejemplo:
ex=
=
temp <= 3 = 0011
temp <= 3*625 = 11101010011 = 1875
R_3 <= 1875 mod 10 = 5
temp <= 1875/10 = 187
R_2 <= 187 mod 10 = 7
temp <= 187/10 = 18
R_1 <= 18 mod 10 = 8
temp <= 18/10 = 1
R_0 <= 1 mod 10 = 1
Y debería mostrarse así:
Toda la división constante por 10 puede ser reemplazada por una multiplicación con . Por lo tanto, no es demasiado ineficiente de implementar. Estoy bastante seguro de que el operador de módulo viene con la biblioteca estándar.
Si usa 6 bits para el lado derecho del punto decimal. Entonces el ancho de bit para la temperatura debe ser = 20 bits . Probablemente esta no sea la forma más eficiente, es una forma que se me ocurrió ahora por mi cuenta. Debería funcionar sin mayores problemas.
Como esto se está haciendo en un FPGA, puede paralelizar la multiplicación, para R3, R2, R1 y R0, multiplique su temperatura por 1, , y para que obtenga los valores de inmediato, en lugar de en serie. Y luego usa el mod 10 en ellos.
Mishyoshi me dio una idea de cómo podría resolverse esto de otra manera. y se resuelven como antes, pero el se puede hacer de otra manera más eficiente.
signal ex : sfixed(4 downto -4);
signal temp : sfixed(4 downto -4);
//We need 4 to the left of the decimal point because then we can capture
//all the single digits
temp <= "0000" & ex(0 downto -4);
temp <= temp*10;
R_0 <= temp(3 downto 0); //Copy the 4 MSB bits
temp <= "0000" & temp(-1 downto -4); //Delete the 4 MSB bits
temp <= temp*10;
R_1 <= temp(3 downto 0);
temp <= "0000" & temp(-1 downto -4);
temp <= temp*10;
R_2 <= temp(3 downto 0);
temp <= "0000" & temp(-1 downto -4);
temp <= temp*10;
R_3 <= temp(3 downto 0);
Ejemplo:
ex=
=
signal temp : sfixed(4 downto -4);
temp <= "0000" & "0011" = 0000.0011 = 3
temp <= 3*10 = 30 = 0001.1110
R_0 <= "0001.1110"(3 downto 0) = 0001 = 1
temp <= "0000" & temp(-1 downto -4) = 0000.1110
temp <= 14*10 = 140 = 1000.1100
R_1 <= "1000.1100"(3 downto 0) = 1000 = 8
temp <= "0000" & "1100" = 0000.1100
temp <= 12*10 = 120 = 0111.1000
R_2 <= "0111.1000"(3 downto 0) = 0111 = 7
temp <= "0000" & "1000" = 0000.1000
temp <= 8*10 = 80 = 0101.0000
R_3 <= "0101.0000"(3 downto 0) = 0101 = 5
Como puede ver, se trata de llevar los bits al lugar de los "unos", los 4 bits a la izquierda del punto decimal.
Eso es mucho menos bits necesarios para esto. En esta otra solución puedes, como dijo Mishyoshi, ponerlos en una tubería.
Eugenio Sh.
Neil_ES
opuesto
Mishyoshi
harry svensson
opuesto
harry svensson