Sei sulla pagina 1di 8

De binario a siete segmentos: la conversin

En la ltima entrada, unimos la ROM con el divisor de frecuencia y obtuvimos el


metrnomo... o algo as. La verdad es que un proyecto no sirve si no podemos ver el
estado en el que se encuentra, est trabajando? ya acab? siquiera empez? o si lo
detengo pero estaba trabajando?
Imagina que llegas a tu horno de microondas, abres la compuerta e introduces tu caf (que
no te terminaste en la maana), mismo que deseas calentar durante cuarenta segundos.
Presionas el 4, pero no hay un visualizador que te muestre el tiempo. Y tampoco hubo
sonido tras presionar la tecla. Bien podra estar desconectado!
Qu tan frustrado te sentiras si tu microondas no mostrara el tiempo restante y
tuvieras que regresar cuando creyeras que hubiese terminado?
Yo estara bastante frustrado, asumo que t tambin. Por eso, en esta entrada crearemos un
componente simple pero poderoso: un convertidor de binario a siete segmentos, para
mostrar un nmero binario en lenguaje comn.
De decimal a BCD
S que eres fantico de la base 2, que prefieres leer los nmeros en binario, y puedes
convertir el nmero 0b11011 a decimal en menos de dos fracciones de segundo. Pero los
diseos deben ser lo ms amigables posibles, y eso incluye la lectura de tales cantidades
binarias.
Particularmente, no creo que una violinista prefiera saber que su ritmo es de 0b1010000
BPM en lugar de 80 BPM aunque hay cada caso... Como una lnea de LEDs no es la
solucin, pasamos a otro conjunto de LEDs ordenados: los visualizadores de siete
segmentos.
El problema es cmo separas un nmero binario en tres o cuatro dgitos de siete
segmentos?Una forma de realizar tal separacin es utilizando un cdigo, denominado BCD
(que significaDecimal Codificado en Binario).
La conversin de decimal a BCD es bastante simple: tomamos cada uno de los dgitos
decimales por separado y le asignamos su valor binario conforme a la tabla 1.
Tabla 1: Conversin de decimal a cdigo BCD natural.
DECIMAL BINARIO
0 0001
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
10-15 No importa
As que de decimal a BCD es una simple conversin del dgito a cuatro bits en binario,
excepto que las ltimas seis posiciones, de 0b1010 a 0b1111, no se utilizan. El problema,
por supuesto, es la conversin de binario a BCD.
De binario a BCD
Lamentablemente, de binario a BCD no podemos simplemente separar conjuntos de cuatro
bits y esperar a que todo funcione. Para la conversin, se requiere el uso de un algoritmo
denominado desplazar a la izquierda y sumar tres. Y lo que hace es, bueno, desplazar y
sumar tres!
En resumen, el proceso es:
1. Desplazar el nmero binario hacia la izquierda un bit.
2. Si alguno de los dgitos tiene una valor igual o mayor a cinco, sumar tres.
3. Repetir los pasos 1 y 2 la cantidad de bits del nmero binario que se quiere convertir.
En esta entrada se realiza el ejemplo del convertidor pensado para el metrnomo, la
cantidad de BPM a visualizar va de 1 a 512. Lo que implica 3 dgitos en BCD. Y las
direcciones de la ROM van de 0 a 511, cantidades que se representan en 9 bits. Por lo tanto,
el componente a ser desarrollado es un convertidor de 9 bits en binario a tres digitos en
BCD. En la tabla 2 se muestra la escructura bsica de cmo se alinearfn los datos para la
conversin: centenas, decenas, unidades, y el nmero binario inicial.
Tabla 2: Estructura bsica para la conversin.
BCD BINARIO
Centenas
(4 bits)
Decenas
(4 bits)
Unidades
(4 bits)
Nmero binario
(9 dgitos)
Ahora, siguiendo la alinacin en la tabla 2, realizaremos la conversin de un nmero
decimal entre el 1 y 512. Creo que ests pensando en el 417, es as? es as? Bueno, de
cualquier forma, haremos el ejemplo del nmero 417:
Tabla 3: Conversin de 9 bits a 4 dgitos de BCD.
OPERACIN BCD BINARIO

CENTENAS
(4 BITS)
DECENAS
(4 BITS)
UNIDADES
(4 BITS)
NMERO
BINARIO
(9 BITS)
Disposicin inicial

1 1 0 1 0 0 0 0 1
Desplazar a la
izquierda (1)
1 1 0 1 0 0 0 0 1
Desplazar a la
izquierda (2)
1 1 0 1 0 0 0 0 1
Desplazar a la
izquierda (3)
1 1 0 1 0 0 0 0 1
Sumar tres a unidades

1 0 0 1 1 0 0 0 0 1
Desplazar a la
izquierda (4)
1 0 0 1 1 0 0 0 0 1
Desplazar a la
izquierda (5)
1 0 0 1 1 0 0 0 0 1
Sumar tres a unidades

1 0 1 0 0 1 0 0 0 1
Desplazar a la
izquierda (6)
1 0 1 0 0 1 0 0 0 1
Sumar tres a decenas

1 0 0 0 0 0 1 0 0 0 1
Desplazar a la
izquierda (7)
1 0 0 0 0 0 1 0 0 0 1
Desplazar a la
izquierda (8)
1 0 0 0 0 0 1 0 0 0 1
Sumar tres a unidades 1 0 0 0 0 0 1 0 1 1 1
Desplazar a la
izquierda (9)
1 0 0 0 0 0 1 0 1 1 1

Y, al final, observamos que los tres dgitos corresponden a 417, correctamente separado. En
la tabla tres se ejemplifica el procedimiento simple, que ser la base del mdulo en VHDL:
1. Inicializamos todos los digitos BCD en 0.
2. Realizamos el siguiente procedimiento 9 veces (la cantidad de bits):
1. Desplazar el nmero binario una posicin hacia la izquierda.
2. Verificar si alguno de los dgitos BCD es mayor o igual a cinco.
3. En caso de que algn nmero en BCD cumpla (sea 5, 6, o 7), sumar tres.
Mdulo en VHDL para la conversin de binario a BCD
En la red hay varios ejemplos, como un convertidor de 8 bits a BCD, un convertidor de
binario a BCD serial o una sugerencia sobre su implementacin eficiente en ROM o
LUT. Adems, en el libro Learning by Example Using VHDL - Basic Digital Design with a
Basys FPGA Boardtambin se incluye el cdigo de un convertidor de 8 bits a BCD, cdigo
que se utiliza como base del presente mdulo.
Ya con la base del algoritmo, podemos crear el cdigo en VHDL. Antes de eso, hay que
tomar en cuenta dos consideraciones:
1. En los primeros dos desplazamientos no se puede llegar al cinco o pasar ms all de
l. Por lo tanto, es hasta el tercer desplazamiento que es necesario comprobar si se
debe sumar tres a algn dgito.
2. El cdigo BCD de las centenas representar como mximo un 5 (ya que el mximo
es 512), razn por la que la representacin BCD ser de tres bits.
Por lo tanto, disearemos un convertidor de 9 bits a tres dgitos BCD en 11 bits (con el
digito de centenas truncado). Recuerdan el ejemplo de la tabla 3? Porque exactamente eso
haremos en cdigo.
En el listado 1 se muestra el cdigo completo para el mdulo, siguiendo el algoritmo. Sus
correspondencias, por lnea, son:
1. Declaramos nuestra entrada num_bin de 9 bits, correspondiente al nmero binario, y
nuestra salida num_bcd de 11 bits, correspondiente al cdigo en BCD (lneas 7 y 8).
2. Justo como en la tabla 3, creamos una sola lnea con todos los datos. sto es, un
vector de 9 + 4 + 4 + 3 = 20 localidades. Sobre ese vector se realizarn las
operaciones de corrimiento (lnea 15).
3. Dado que en z se contienen todos los datos, debemos asegurarnos que se inicializa en
ceros (lnea 18).
4. En los primeros dos corrimientos no habr sumas, as que se realizan los primeros
tres corrimientos sin problema (lnea 20).
5. De las lneas 21 a 36 se ejecuta un ciclo para los seis desplazamientos restantes,
equivalentes a 9 bits - 3 desplazamientos ya realizados.
6. Dentro del ciclo, se separa el vector en conjuntos de cuatro bits, correspondientes a
cada dgito en BCD. Si las unidades (lneas 22 a 25), las decenas (lneas 26 a 29), o
las centenas (lneas 30 a 33), exceden cuatro, se les aplica una suma de tres.
7. Tras la adicin, se realiza el corrimiento de datos hacia la izquierda (lnea 35).
8. Finalmente, se toman los valores de los dgitos en BCD y se envan a la salida del
mdulo (lnea 38).
Convertidor de binario de 9 bits a BCD de tres dgitos en 11 bits.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity bin2bcd9 is
PORT(
num_bin: in STD_LOGIC_VECTOR(8 downto 0);
num_bcd: out STD_LOGIC_VECTOR(10 downto 0)
);
end bin2bcd9;

architecture Behavioral of bin2bcd9 is
begin
proceso_bcd: process(num_bin)
variable z: STD_LOGIC_VECTOR(19 downto 0);
begin
-- Inicializacin de datos en cero.
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
z := (others => '0');
-- Se realizan los primeros tres corrimientos.
z(11 downto 3) := num_bin;
for i in 0 to 5 loop
-- Unidades (4 bits).
if z(12 downto 9) > 4 then
z(12 downto 9) := z(12 downto 9) + 3;
end if;
-- Decenas (4 bits).
if z(16 downto 13) > 4 then
z(16 downto 13) := z(16 downto 13) + 3;
end if;
-- Centenas (3 bits).
if z(19 downto 17) > 4 then
z(19 downto 17) := z(19 downto 17) + 3;
end if;
-- Corrimiento a la izquierda.
z(19 downto 1) := z(18 downto 0);
end loop;
-- Pasando datos de variable Z, correspondiente a BCD.
num_bcd <= z(19 downto 9);
end process;
end Behavioral;

Convertidor de binario de 9 bits a BCD de 11 bits (3 dgitos)
Descargar 1.60 KB
Si necesitas modificar la cantidad de bits, quiz el cdigo del listado 2 resulte mejor para su
modificacin (aunque puede parecer un tanto confuso al haber sustituido la cantidad de bits
porGENERIC).
Listado 2: Convertidor de binario a BCD (un tanto ms genrico).
La simulacin
En el listado 3 se muestra lo relevante de la simulacin (incluida en la descarga), con los
valores esperados. En la figura 1 se muestran los resultados, que concuerdan con lo
mostrado en los comentarios del listado 3.

Convertidor de binario de 9 bits a BCD de 11 bits (3 dgitos)
Descargar 1.60 KB

Figura 1: Simulacin de mdulo de binario a BCD.
Listado 3: Algunos valores para la simulacin de binario a BCD.
1
2
3
num_bin <= "000000001"; -- 1, 000 0000 0001
wait for 10 ms;
num_bin <= "000000010"; -- 2, 000 0000 0010
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
wait for 10 ms;
num_bin <= "000000100"; -- 4, 000 0000 0100
wait for 10 ms;
num_bin <= "000001000"; -- 8, 000 0000 1000
wait for 10 ms;
num_bin <= "000010000"; -- 16, 000 0001 0110
wait for 10 ms;
num_bin <= "000100000"; -- 32, 000 0011 0010
wait for 10 ms;
num_bin <= "001000000"; -- 64, 000 0110 0100
wait for 10 ms;
num_bin <= "010000000"; -- 128, 001 0010 1000
wait for 10 ms;
num_bin <= "100000000"; -- 256, 010 0101 0110
wait;
Y ahora de BCD a siete segmentos
Antes habamos realizado un decodificador de seis bits a siete segmentos, aunque ahora
solamente ser necesario tomar en cuenta los dgitos del cero al nueve (o lo necesario para
leer solamente cuatro bits). En esta entrada solamente tomaremos prestado el cdigo del
proyecto de decodificador de cuatro bits a siete segmentos y aadiremos el convertidor
de binario a BCD.
En la figura 2 se muestra el diagrama esquemtico, que corresponde a la unin del
controlador de siete segmentos completo con decodificador de cuatro bits con el
convertidor de binario de 9 bits a BCD en 11 digitos (y ese es el nombre ahora...).

Figura 2: Diagrama esquemtico del convertidor de binario a visualizadores de siete
segmentos.
El mdulo solamente recibe la seal de reloj de 50MHz, el reset, y el nmero binario de
nueve bits a ser mostrado. Entonces la magia sucede y el valor se muestra en los cuatro
visualizadores. El cdigo para dicha magia se muestra en el listado 4.
Listado 4: Unin del convertidor de binario a BCD con los visualizadores de siete segmentos
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity bin7seg is
PORT (
clk : in STD_LOGIC; -- Reloj de entrada de 50MHz.
reset : in STD_LOGIC; -- Seal de reset.
num_bin : in STD_LOGIC_VECTOR(8 downto 0);
d7s : out STD_LOGIC_VECTOR(7 downto 0);
MUX : out STD_LOGIC_VECTOR(3 downto 0)
);
end bin7seg;

architecture Behavioral of bin7seg is
signal num_bcd: STD_LOGIC_VECTOR(10 downto 0);
signal D0, D1, D2, D3: STD_LOGIC_VECTOR(3 downto 0);
begin
d7s_i: entity work.siete_segmentos_completo(Behavioral)
PORT MAP(clk, reset, D0, D1, D2, D3, d7s, MUX);
bin2bcd9_i: entity bin2bcd9(Behavioral)
PORT MAP(num_bin, num_bcd);

D3 <= "0000"; -- Siempre en cero.
D2 <= "0" & num_bcd(10 downto 8); -- Rellenando para ser cuatro dgitos.
D1 <= num_bcd(7 downto 4);
D0 <= num_bcd(3 downto 0);
end Behavioral;
El archivo de implementacin se encuentra en la descarga. Por si an no lo tienes, aqu va
de nuevo:

Convertidor de binario de 9 bits a BCD y siete segmentos
Descargar 4.45 KB
Ahora podemos ver
Finalmente, en la figura 3 se muestra el resultado en el FPGA. Los ocho interruptores se
utilizaron como entrada de datos (falta el bit nueve, pero ese simplemente lo mandamos a
otro botn). Al mover los interruptores (el valor binario), los visualizadores cambian en
consecuencia, mostrando su valor decimal.

Figura 3: Nmero binario 0b000011111 visualizado en siete segmentos.
Segn se aprecia, los interruptores activos son cinco, correspondientes a los de menor
significancia:
0b000011111=24+23+22+21+20=16+8+4+2+1=31
Por lo que nuestro mdulo funciona y por fin podemos ver algo relevante en nuestra tarjeta
Basys2 :D. Pero eso es todo por ahora.
Pregunta rpida: cmo realizaras un convertidor de un nmero binario para utilizar los
cuatro visualizadores de la tarjeta? de cuntos bits debera ser el nmero binario?
No te olvides de compartir esta entrada si te gust el contenido. As todos sabrn que, como
yo, eres un entusiasta de los sistemas digitales.

Potrebbero piacerti anche