VHDL - Convierta de binario / entero a BCD y visualícelo en la pantalla de 7 segmentos

0

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;
    
pregunta Tudor Ciotlos

1 respuesta

1

En VHDL (y HDLs en general) un bucle for no denota ejecución secuencial como lo hace en un lenguaje de programación de software, denota la construcción de múltiples instancias paralelas del hardware descrito en el cuerpo del bucle.

En su caso, tiene muchas asignaciones a la misma variable BCD / bcd , y estas están en conflicto entre sí. Si realmente tiene la intención de construir un sistema basado en dos registros de turnos (un binario, un bcd) que requiera 14 períodos de reloj para realizar la conversión, debe describir el hardware de esa manera y configurar una máquina de estados para controlarlo.

Por otra parte, si realmente desea hacerlo de manera combinatoria, entonces necesita crear diferentes variables intermedias (por ejemplo, matrices indexadas por la variable de control de bucle) para mantener los resultados en cada etapa.

    
respondido por el Dave Tweed

Lea otras preguntas en las etiquetas