BIN a BCD
Este es un algoritmo para decodificar de binario a decimal decodificado en binario.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity binary_bcd is
generic(N: positive := 8);
Port(
clk, reset: in std_logic;
binary_in: in std_logic_vector(N-1 downto 0);
bcd0, bcd1, bcd2: out std_logic_vector(3 downto 0)
);
end binary_bcd ;
architecture behaviour of binary_bcd is
type states is (start, shift, done);
signal state, state_next: states;
signal binary, binary_next: std_logic_vector(N-1 downto 0);
signal bcds, bcds_reg, bcds_next: std_logic_vector(11 downto 0);
-- output register keep output constant during conversion
signal bcds_out_reg, bcds_out_reg_next: std_logic_vector(11 downto 0);
-- need to keep track of shifts
signal shift_counter, shift_counter_next: natural range 0 to N;
begin
process(clk, reset)
begin
if reset = '1' then
binary <= (others => '0');
bcds <= (others => '0');
state <= start;
bcds_out_reg <= (others => '0');
shift_counter <= 0;
elsif falling_edge(clk) then
binary <= binary_next;
bcds <= bcds_next;
state <= state_next;
bcds_out_reg <= bcds_out_reg_next;
shift_counter <= shift_counter_next;
end if;
end process;
convert:
process(state, binary, binary_in, bcds, bcds_reg, shift_counter)
begin
state_next <= state;
bcds_next <= bcds;
binary_next <= binary;
shift_counter_next <= shift_counter;
case state is
when start =>
state_next <= shift;
binary_next <= binary_in;
bcds_next <= (others => '0');
shift_counter_next <= 0;
when shift =>
if shift_counter = N then
state_next <= done;
else
binary_next <= binary(N-2 downto 0) & 'L';
bcds_next <= bcds_reg(10 downto 0) & binary(N-1);
shift_counter_next <= shift_counter + 1;
end if;
when done =>
state_next <= start;
end case;
end process;
bcds_reg(11 downto 8) <= bcds(11 downto 8) + 3 when bcds(11 downto 8) > 4 else
bcds(11 downto 8);
bcds_reg(7 downto 4) <= bcds(7 downto 4) + 3 when bcds(7 downto 4) > 4 else
bcds(7 downto 4);
bcds_reg(3 downto 0) <= bcds(3 downto 0) + 3 when bcds(3 downto 0) > 4 else
bcds(3 downto 0);
bcds_out_reg_next <= bcds when state = done else
bcds_out_reg;
bcd2 <= bcds_out_reg(11 downto 8);
bcd1 <= bcds_out_reg(7 downto 4);
bcd0 <= bcds_out_reg(3 downto 0);
end behaviour;
El algoritmo tiene como objetivo transformar un numero binario a la
representación en binario de un número decimal. El decimal decodificado
en binario se refiere a sus dígitos en segmentos de 4 bits.
Para esto se realizan 3 pasos:
-
Se recorre el número binario un bit a la izquierda (entrando al
número BCD). -
Si cualquiera de los dígitos del número BCD (fragmentos de 4 bits),
es mayor o igual a 5, se le suma 3. -
Se repiten los pasos anteriores la cantidad de bits del número
binario que se quiere convertir.
A continuación se explica el código.
En el código se ocupan 3 entradas, “clk” y “reset”, estas son el reloj y
la señal de resteo del sistema, el vector de entrada “binary_in”, es el
número en binario que queremos codificar a código bcd; bcd0, bcd1 y bcd2
son las salidas de unidades, decenas y centenas codificadas en código
bcd.
``` {.vhdl frame=”single” framesep=”10pt”}
entity binary_bcd is
generic(N: positive := 8);
Port(
clk, reset: in std_logic;
binary_in: in std_logic_vector(N-1 downto 0);
bcd0, bcd1, bcd2: out std_logic_vector(3 downto 0)
);
end binary_bcd ;
Para realizar la decodificación definimos los nombres de los estados de
nuestra maquina que son: “start”, “shift” y “done”, para la descripción
de los estados presente y siguiente de la maquina de estados utilizamos
las palabras “state” y “state\_next” y por ultimo definimos signals que
serán los registros que nos permiten realizar el corrimiento de nuestros
datos recibidos.
``` {.vhdl frame="single" framesep="10pt"}
architecture behaviour of binary_bcd is
type states is (start, shift, done);
signal state, state_next: states;
signal binary, binary_next: std_logic_vector(N-1 downto 0);
signal bcds, bcds_reg, bcds_next: std_logic_vector(11 downto 0);
-- output register keep output constant during conversion
signal bcds_out_reg, bcds_out_reg_next: std_logic_vector(11 downto 0);
-- need to keep track of shifts
signal shift_counter, shift_counter_next: natural range 0 to N;
En esta parte del código se ejecutan los cambios de estado y el
corrimiento hacia la izquierda del código bcd y del número que se está
codificando (solo se ejecuta lo que ya se estableció en las siguientes
lineas).
``` {.vhdl frame=”single” framesep=”10pt”}
begin
process(clk, reset)
begin
if reset = '1' then
binary <= (others => '0');
bcds <= (others => '0');
state <= start;
bcds_out_reg <= (others => '0');
shift_counter <= 0;
elsif falling_edge(clk) then
binary <= binary_next;
bcds <= bcds_next;
state <= state_next;
bcds_out_reg <= bcds_out_reg_next;
shift_counter <= shift_counter_next;
end if;
end process; ```
Se definen los cambios de estado y se realiza el proceso de recorrer en
el vector bcd concatenándolo con el ultimo bit del vector a codificar,
también se recorre el vector a codificar para poder realizar la
siguiente repetición.
``` {.vhdl frame=”single” framesep=”10pt”}
process(state, binary, binary_in, bcds, bcds_reg, shift_counter)
begin
state_next <= state;
bcds_next <= bcds;
binary_next <= binary;
shift_counter_next <= shift_counter;
case state is
when start =>
state_next <= shift;
binary_next <= binary_in;
bcds_next <= (others => '0');
shift_counter_next <= 0;
when shift =>
if shift_counter = N then
state_next <= done;
else
--Aqui concatena los primero 6 bits con un cero para completar
--el tamaño del vector
binary_next <= binary(N-2 downto 0) & 'L';
--Aqui recorre el registro y le concatena el msb de la entrada
bcds_next <= bcds_reg(10 downto 0) & binary(N-1);
shift_counter_next <= shift_counter + 1;
end if;
when done =>
state_next <= start;
end case;
end process; ```
Una vez realizado el corrimiento de nuestro vector se realiza el segundo
paso mencionado anteriormente. Definimos la misma condición para cada
fragmento de 4 bits de nuestro dato.
``` {.vhdl frame=”single” framesep=”10pt”}
bcds_reg(11 downto 8) <= bcds(11 downto 8) + 3 when bcds(11 downto 8) > 4 else
bcds(11 downto 8);
bcds_reg(7 downto 4) <= bcds(7 downto 4) + 3 when bcds(7 downto 4) > 4 else
bcds(7 downto 4);
bcds_reg(3 downto 0) <= bcds(3 downto 0) + 3 when bcds(3 downto 0) > 4 else
bcds(3 downto 0);
Se establece lo que se va a realizar en el ultimo estado, que es asignar
el resultado del algoritmo a un vector, este vector se divide por
segmentos de 4 bits y se le asigna a las salidas correspondientes.
``` {.vhdl frame="single" framesep="10pt"}
bcds_out_reg_next <= bcds when state = done else
bcds_out_reg;
bcd2 <= bcds_out_reg(11 downto 8);
bcd1 <= bcds_out_reg(7 downto 4);
bcd0 <= bcds_out_reg(3 downto 0);