VHDL: Recibiendo datos desde el terminal al FPGA usando TTL

0

(Publiqué misma pregunta en stackoverflow pero no obtener la respuesta correcta)

Soy novato en VHDL. Así que hoy, después de UART Tx, intenté leer los datos que provienen de la terminal de Realterm. Solo escribí códigos Rx para ver los datos. También usé la pantalla de 7 segmentos y 7 LED para ver qué datos recibí. Cuando miras los resultados de testbench, el problema es cuando el registro de 3 bits es "110" dos veces, el programa salta a rx_data_bit sin hacer rx_start_bit < = '1'

EDIT 1: Se actualizan los códigos y los resultados del banco de pruebas. Ahora el problema es que rx_data_bit nunca pasa a '0', por lo que rx_stop_bit nunca pasa a '1'

EDIT 2: Creo que el problema está aquí

             if(rx_data_bit = '1') then
                counter_del_half <= '0';
                if(half_pulse = '1')then
                   rx_reg((rx_counter)) <= in_Data_rx;  
                   if(rx_counter < 8 and baud_pulse = '1')then
                      rx_counter <= rx_counter + 1;
                      if(rx_counter = 8) then
                         rx_data_bit <= '0';
                         rx_stop_bit  <= '1';
                    end if;
                end if;
            end if;
        end if;

EDIT 3: Ahora, el contador cuenta correctamente pero tengo una pregunta aquí. ¿Debería el primer bit de rx_counter (1) durar medio bit largo o 1 bit largo? Además, rx_stop_bit debe ser '1', cuando rx_counter llega a 9.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.NUMERIC_STD.ALL;

entity UART_Rx is
port     ( 
            CLK:         in  std_logic;
            nReset:      in  std_logic;
            in_Data_Rx:  in  std_logic;
            Segment7_1:  out std_logic_vector (6 downto 0);
            Segment7_2:  out std_logic_vector (6 downto 0)
            );
end UART_Rx;

architecture Behavioral of UART_Rx is
-- CLOCK AND BUTTON SIGNALS --
constant Baudrate:       integer:= 9600;
constant CLK_Hiz:        integer:= 50000000;
constant CLK_Bit:        integer:= (CLK_Hiz / Baudrate) + 1;
signal counter_baud:     integer range 0 to (CLK_Bit - 1):= 0;
signal counter_half:     integer range 0 to ((CLK_Bit - 1)/2):= 0;
signal counter_del_baud: std_ulogic:= '0';
signal counter_del_half: std_ulogic:= '0';
signal baud_pulse:       std_ulogic:= '0';
signal half_pulse:       std_ulogic:= '0';

-- RX SIGNALS --
signal rx_reg:           std_logic_vector (7 downto 0):= (others => '0');
signal rx_reg_counter:   std_logic_vector (2 downto 0):= (others => '0');
signal rx_counter:       integer range 0 to 9:= 0;
signal rx_first_bit:     std_ulogic:= '1';
signal rx_start_bit:     std_ulogic:= '0';
signal rx_data_bit:      std_ulogic:= '0';
signal rx_stop_bit:      std_ulogic:= '0';
signal rx_data_al:       std_ulogic:= '0';

begin
-- CLOCK PROCESS --
clk_process: process(CLK,nReset)
    begin
        if(nReset = '0') then
            baud_pulse   <= '0';
            counter_baud <=  0;
            half_pulse   <= '0';
            counter_half <=  0;
            elsif(rising_edge(CLK)) then
                if(counter_baud < (CLK_Bit - 1)) then   
                    counter_baud <= counter_baud + 1;
                    baud_pulse   <= '0';        
                else    
                    counter_baud <= 0;
                    baud_pulse   <= '1'; 
                end if;

                if(counter_half < (CLK_Bit - 1)/2) then
                    counter_half <= counter_half + 1;
                    half_pulse <= '0';
                else
                    counter_half <= 0;
                    half_pulse   <= '1';
                end if;

                if(counter_del_baud = '1') then
                    counter_baud <= 0;
                end if;

               if(counter_del_half = '1') then
                    counter_half <= 0;
                end if;
            end if;         
end process;
rx_process: process(CLK, nReset)
    begin   
            if(rising_edge(CLK)) then
                rx_reg_counter <= rx_reg_counter (1 downto 0) & in_Data_Rx;
                if(rx_first_bit = '1' and rx_reg_counter (2 downto 0) = "110") then
                    counter_del_baud <= '1';
                    rx_start_bit     <= '1';
                    rx_first_bit     <= '0';
                end if;

                if(rx_start_bit = '1') then
                    counter_del_baud <= '0';
                    if(baud_pulse = '1') then
                       counter_del_baud <= '1';
                        rx_start_bit  <= '0';
                        rx_data_bit   <= '1';
                        counter_del_half <= '1';
                    end if; 
                end if;

                if(rx_data_bit = '1') then
                    counter_del_half <= '0';
                    counter_del_baud <= '0';
                    if(half_pulse = '1')then
                        rx_data_bit  <= '0';
                        rx_data_al   <= '1';
                        rx_counter   <= 1;
                    end if;
                end if;

                    if(rx_data_al = '1') then
                        rx_reg(rx_counter - 1) <= in_Data_rx;   
                        if(rx_counter > 0 and rx_counter < 9) then
                            if(baud_pulse = '1')then
                                rx_counter <= rx_counter + 1;
                                if(rx_counter = 9) then
                                    rx_data_al  <= '0';
                                    rx_stop_bit <= '1';
                                end if;
                            end if;
                        end if;
                    end if;

                if(rx_stop_bit = '1')then
                    rx_counter  <= 0;
                    if(baud_pulse = '1') then
                        rx_stop_bit    <= '0';
                        rx_reg_counter <= (others => '1');
                        rx_first_bit   <= '1';
                    end if;
                end if; 

case rx_reg(3 downto 0) is  --abcdefg--
when "0000" => segment7_1 <= "0000001";  -- '0'
when "0001" => segment7_1 <= "1001111";  -- '1'
when "0010" => segment7_1 <= "0010010";  -- '2'
when "0011" => segment7_1 <= "0000110";  -- '3'
when "0100" => segment7_1 <= "1001100";  -- '4' 
when "0101" => segment7_1 <= "0100100";  -- '5'
when "0110" => segment7_1 <= "0100000";  -- '6'
when "0111" => segment7_1 <= "0001111";  -- '7'
when "1000" => segment7_1 <= "0000000";  -- '8'
when "1001" => segment7_1 <= "0000100";  -- '9'
when "1010" => segment7_1 <= "0001000";  -- 'A'
when "1011" => segment7_1 <= "1100000";  -- 'B'
when "1100" => segment7_1 <= "0110001";  -- 'C'
when "1101" => segment7_1 <= "1000010";  -- 'D'
when "1110" => segment7_1 <= "0110000";  -- 'E' 
when "1111" => segment7_1 <= "0111000";  -- 'F'
when others => segment7_1 <= "1111111";
end case;

case rx_reg(7 downto 4) is
when "0000" => segment7_2 <= "0000001";  -- '0'
when "0001" => segment7_2 <= "1001111";  -- '1'
when "0010" => segment7_2 <= "0010010";  -- '2'
when "0011" => segment7_2 <= "0000110";  -- '3'
when "0100" => segment7_2 <= "1001100";  -- '4' 
when "0101" => segment7_2 <= "0100100";  -- '5'
when "0110" => segment7_2 <= "0100000";  -- '6'
when "0111" => segment7_2 <= "0001111";  -- '7'
when "1000" => segment7_2 <= "0000000";  -- '8'
when "1001" => segment7_2 <= "0000100";  -- '9'
when "1010" => segment7_2 <= "0001000";  -- 'A'
when "1011" => segment7_2 <= "1100000";  -- 'B'
when "1100" => segment7_2 <= "0110001";  -- 'C'
when "1101" => segment7_2 <= "1000010";  -- 'D'
when "1110" => segment7_2 <= "0110000";  -- 'E' 
when "1111" => segment7_2 <= "0111000";  -- 'F'
when others => segment7_2 <= "1111111";
end case;
rx_reg <= (others => '0');
end if;
end process;
end Behavioral;

Aquí está el código del banco de pruebas:

library ieee;
use ieee.std_logic_1164.all;

entity tb_UART_Rx is
end tb_UART_Rx;

architecture tb of tb_UART_Rx is

    component UART_Rx
        port (CLK        : in std_logic;
              nReset     : std_logic:='1';
              in_Data_Rx : std_logic:='1';
              Segment7_1 : out std_logic_vector (6 downto 0):= (others => '0');
              Segment7_2 : out std_logic_vector (6 downto 0):= (others => '0'));
    end component;

    signal CLK           :  std_logic;
    signal nReset        :  std_logic:='1';
    signal in_Data_Rx    :  std_logic:='1';
    signal rx_reg_counter:  std_logic_vector (2 downto 0):= (others => '1');
    signal Segment7_1    :  std_logic_vector (6 downto 0):= (others => '0');
    signal Segment7_2    :  std_logic_vector (6 downto 0):= (others => '0');

    constant TbPeriod : time := 20 ns; 
    signal TbSimEnded : std_logic := '0';

begin

    dut : UART_Rx
    port map (CLK        => CLK,
              nReset     => nReset,
              in_Data_Rx => in_Data_Rx,
              Segment7_1 => Segment7_1,
              Segment7_2 => Segment7_2);

    clk_process: process
     begin

    CLK <= '0';
    wait for TbPeriod/2;
    CLK <= '1';
    wait for TbPeriod/2;
     end process;

    stimuli : process
    begin

        nReset <= '0';
        wait for 100 ns;
        nReset <= '1';
        wait for 100 ns;
          in_Data_Rx <= '1';
          wait for 0.104 ms;
          in_Data_Rx <= '0';
          wait for 0.104 ms;
          in_Data_Rx <= '0';
          wait for 0.104 ms;
          in_Data_Rx <= '1';
          wait for 0.104 ms;
          in_Data_Rx <= '1';
          wait for 0.104 ms;
          in_Data_Rx <= '1';
          wait for 0.104 ms;
          in_Data_Rx <= '0';
          wait for 0.104 ms;
          in_Data_Rx <= '0';
          wait for 0.104 ms;
          in_Data_Rx <= '0';
          wait for 0.104 ms;
          in_Data_Rx <= '0';
          wait for 0.104 ms;
          in_Data_Rx <= '1';



        wait;
    end process;

end tb;


configuration cfg_tb_UART_Rx of tb_UART_Rx is
    for tb
    end for;
end cfg_tb_UART_Rx;

Aquí están los resultados del banco de pruebas:

Gracias.

    
pregunta Griffo

2 respuestas

0

A partir de la instantánea de simulación, parece que está trabajando con Xilinx FPGA.

Xilinx ofrece códigos de VHDL / verilog listos para la comunicación UART llamado kcuart. No es necesario que escriba un código por separado (ahorra 'mucho' tiempo). Solo configúralo para tus especificaciones de UART y disfruta.

    
respondido por el samjay
-1
        if(rx_first_bit <= '1' and rx_reg_counter (2 downto 0) = "110") then
            counter_del_baud <= '0';
            rx_start_bit     <= '1';
            rx_first_bit      <= '0';
            if(baud_pulse <= '1') then
                rx_start_bit  <= '0';
                rx_data_bit   <= '1';
                counter_del_half <= '1';
            end if;

Todas estas líneas de código aparecen simultáneamente, tienes rx_start_bit conducido dos veces más lejos de lo que a mí respecta cada vez que la instrucción if es verdadera.

También soy un principiante, pero tengo curiosidad de que baud_pulse <= '1' and baud_pulse = '1' sea igual.

¡Salud!

    
respondido por el zoder

Lea otras preguntas en las etiquetas