Como parte de mi proyecto para el curso de Diseño de sistemas digitales, tengo que usar un componente para mostrar en la pantalla de 7 segmentos un rango INTEGER de 0 a 9999 (o un std_logic_vector (13 downto 0)). Utilicé el algoritmo de dabble doble para convertir un número binario de 14 bits en BCD y luego extraje los 4 dígitos. Probé el componente en Active-HDL y funciona bien, pero una vez cargado en mi placa FPGA Basys2, muestra los números incorrectos. Por ejemplo, en lugar de "1770", obtengo "0064".
Estoy bastante seguro de que el problema se debe a algo del primer proceso, donde se generan los dígitos BCD, pero no pude averiguar cuál es el problema. Aquí está el código del componente:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity DISP_SOLD is
port (EN: in std_logic;
CLK_PLACA: in std_logic;
SUMA: in integer range 0 to 9999;
-- Cathodes
L18_CA: out std_logic;
F18_CB: out std_logic;
D17_CC: out std_logic;
D16_CD: out std_logic;
G14_CE: out std_logic;
J17_CF: out std_logic;
H14_CG: out std_logic;
-- Anodes
AN0_F17: out std_logic;
AN1_H17: out std_logic;
AN2_C18: out std_logic;
AN3_F15: out std_logic);
end DISP_SOLD;
architecture ARH of DISP_SOLD is
-- digit_pattern_array = current_BCD_digit
signal digit_pattern_array : std_logic_vector(6 downto 0) := "0000000";
signal current_segment : std_logic_vector(1 downto 0) := "00";
signal cathode_select : std_logic_vector(3 downto 0) := "0000";
-- count use for the clock divider
signal count : std_logic_vector(6 downto 0) := "0000000";
-- MUX_CLK is the clock resulting from the clock divider
signal MUX_CLK : std_logic;
signal cifra_mii: std_logic_vector(3 downto 0):="0000"; -- 1st digit
signal cifra_sute: std_logic_vector(3 downto 0):="0000"; -- 2nd digit
signal cifra_zeci: std_logic_vector(3 downto 0):="0000"; -- 3rd digit
signal cifra_unitati: std_logic_vector(3 downto 0):="0000"; -- 4th digit
begin
process(EN, SUMA)
variable BIN: std_logic_vector(13 downto 0);
variable BCD: std_logic_vector(15 downto 0):=(others => '0');
variable i: integer:=0;
variable CONVERTED: std_logic:='0';
begin
if EN='1' and CONVERTED='0' then
BIN := conv_std_logic_vector(SUMA, 14);
-- Convert Binary to BCD (Double Dabble algorithm)
for i in 0 to 13 loop
bcd(15 downto 1) := bcd(14 downto 0); --shifting the bits.
bcd(0) := bin(13);
bin(13 downto 1) := bin(12 downto 0);
bin(0) :='0';
if(i < 13 and bcd(3 downto 0) > "0100") then --add 3 if BCD digit is greater than 4.
bcd(3 downto 0) := bcd(3 downto 0) + "0011";
end if;
if(i < 13 and bcd(7 downto 4) > "0100") then --add 3 if BCD digit is greater than 4.
bcd(7 downto 4) := bcd(7 downto 4) + "0011";
end if;
if(i < 13 and bcd(11 downto 8) > "0100") then --add 3 if BCD digit is greater than 4.
bcd(11 downto 8) := bcd(11 downto 8) + "0011";
end if;
if(i < 13 and bcd(15 downto 12) > "0100") then --add 3 if BCD digit is greater than 4.
bcd(15 downto 12) := bcd(15 downto 12) + "0011";
end if;
end loop;
if SUMA /= 0 then
CONVERTED:='1';
end if;
cifra_mii <= BCD(15 downto 12);
cifra_sute <= BCD(11 downto 8);
cifra_zeci <= BCD(7 downto 4);
cifra_unitati <=BCD(3 downto 0);
end if;
end process;
-- CLK_PLACA: from 50MHz to MUX_CLK (~390Hz)
divizor_CLK: process(CLK_PLACA)
begin
if rising_edge(CLK_PLACA) then
count <= count + '1';
end if;
MUX_CLK <= count(6);
end process;
variable current_BCD_digit: std_logic_vector(3 downto 0);
begin
if rising_edge(MUX_CLK) then
current_segment <= current_segment + '1';
case current_segment is
when "00" => current_BCD_digit := cifra_mii;
cathode_select <= "1110";
when "01" => current_BCD_digit := cifra_sute;
cathode_select <= "1101";
when "10" => current_BCD_digit := cifra_zeci;
cathode_select <= "1011";
when "11" => current_BCD_digit := cifra_unitati;
cathode_select <= "0111";
when others => null;
end case;
case current_BCD_digit is
when "0000" => digit_pattern_array <= "0000001";
when "0001" => digit_pattern_array <= "1001111";
when "0010" => digit_pattern_array <= "0010010";
when "0011" => digit_pattern_array <= "0000110";
when "0100" => digit_pattern_array <= "1001100";
when "0101" => digit_pattern_array <= "0100100";
when "0110" => digit_pattern_array <= "0100000";
when "0111" => digit_pattern_array <= "0001111";
when "1000" => digit_pattern_array <= "0000000";
when "1001" => digit_pattern_array <= "0001100";
when others => null;
end case;
end if;
end process;
L18_CA <= digit_pattern_array(6);
F18_CB <= digit_pattern_array(5);
D17_CC <= digit_pattern_array(4);
D16_CD <= digit_pattern_array(3);
G14_CE <= digit_pattern_array(2);
J17_CF <= digit_pattern_array(1);
H14_CG <= digit_pattern_array(0);
AN0_F17 <= cathode_select(0) when EN='1' else '0';
AN1_H17 <= cathode_select(1) when EN='1' else '0';
AN2_C18 <= cathode_select(2) when EN='1' else '0';
AN3_F15 <= cathode_select(3) when EN='1' else '0';
end ARH;