¿Cómo dividir un número de varios dígitos en dígitos separados en VHDL?

2

Encontré el método para el lenguaje c .Pero no sé cómo realizar esto en VHDL. Deje que un número de punto fijo (12 abajo a -19) como 3456.478396 Necesito dividir este número completamente 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 separar en un solo dígito?

UTILIZO,

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;
    
pregunta oppo

1 respuesta

4

Aquí hay un pseudocódigo.

Tomemos primero los que quedan del decimal, el número máximo es \ $ 15_ {10} \ $ = > 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 = \ $ 12_ {10} \ $ = \ $ 1100_ {2} \ $

temp <= 12
L_0 <= 12 mod 10 = 2
temp <= 12/10    = 1
L_1 <= 1 mod 10  = 1

Y luego los que están a la derecha, el número más pequeño = > 0.0625 = > 4 dígitos decimales. El mismo método que antes, solo multiplica por \ $ 625_ {10} \ $ antes de comenzar. Porque \ $ 0001_ {2} \ $ en binario se traduce a \ $. 0625_ {10} \ $ en decimal. Por lo tanto, el ancho de bits de temp debe ser \ $ ceil (log_2 (625 × 15)) = \ $ 14 bits porque \ $ 15_ {10} \ $ es \ $ 1111 _ {2} \ $, que es tu valor más alto.

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 = \ $ 0.1875_ {10} \ $ = \ $ 0011_ {2} \ $

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í:

\ $ L_1 L_0. R_0 R_1 R_2 R_3 \ $

Toda la división constante por 10 se puede reemplazar por una multiplicación con \ $ \ frac {1} {10} \ $. Así que no es demasiado ineficiente para 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. Luego, el ancho de bits para temp debe ser \ $ ceil (log2 (63 × 15625)) \ $ = 20 bits . Probablemente esta no sea la forma más eficiente, es una forma que se me ocurrió ahora mismo por mi cuenta. Debería funcionar sin mayores problemas.

Ya que esto se está haciendo en un FPGA, puedes paralelizar la multiplicación, para R3, R2, R1 y R0, multiplica su temp con 1, \ $ \ frac {1} {10} \ $, \ $ \ frac {1} {100} \ $ y \ $ \ frac {1} {1000} \ $ para que obtenga los valores de inmediato, en lugar de en serie. Y luego usa el mod 10 en ellos.

EDITAR

Mishyoshi me dio una idea de cómo esto podría resolverse de otra manera. \ $ L_0 \ $ y \ $ L_1 \ $ se resuelven como antes, pero \ $ R_ {0..3} \ $ 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 = \ $ 0.1875_ {10} \ $ = \ $ 0011_ {2} \ $

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 "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.

    
respondido por el Harry Svensson

Lea otras preguntas en las etiquetas

Comentarios Recientes

ReplyThreadLinkGranious! Tuve un problema similar con el mío. ReplyThreadLinkGranious hizo un excelente punto AARman. Todos los números clave son consecutivos y, por lo tanto, ofrece menos posibilidades de cometer errores. Un buen paso para comprender los múltiples dígitos y sobre la evaluación de la función frontends (es decir, sqlbind) oh, una solicitud de comida:) <| endoftext |> La relación entre Brian Vercellini, un estudiante de derecho de Stanford y residente del campus, y Kathy Hilton Luhn delan, de 27... Lees verder