Receptor VHDL RS-232

1

He intentado diseñar un receptor RS-232 con un enfoque FSM. Admito que no tengo una comprensión muy completa de VHDL, por lo que he estado trabajando en el código sobre la marcha y aprendiendo sobre la marcha. Sin embargo, creo que he golpeado un muro de ladrillos en este punto.

Mi problema es que tengo dos procesos en mi código, uno para activar el siguiente estado y el otro para realizar la lógica combinacional. Mi código es el siguiente:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity ASyncReceiverV4 is
Port ( DataIn : in  STD_LOGIC;
              Enable : in STD_LOGIC;
           CLK : in  STD_LOGIC;
              BadData : out STD_LOGIC;
           DataOut : out  STD_LOGIC_VECTOR (7 downto 0));
end ASyncReceiverV4;

architecture Behavioral of ASyncReceiverV4 is

type states is (StartBitCheck, ReadData, StopBitCheck);
signal currentState, nextState : states;

begin

    process(CLK)
    begin
        if rising_edge(CLK) then
            currentState <= nextState;
        end if;
    end process;

    process(CLK)
    variable counter : integer := 0;
    variable dataIndex : integer := 0;
    begin
            case currentState is

                when StartBitCheck =>
                    if Enable = '1' then
                        if (DataIn = '0' and counter < 8)  then
                            counter := counter + 1;
                        elsif (DataIn = '0' and counter = 8) then
                            BadData <= '0';
                            nextState <= ReadData;
                            counter := 0;
                        else 
                            nextState <= StartBitCheck;
                        end if;
                    end if;

                when ReadData =>
                    if Enable = '1' then
                        if counter < 16 then
                            counter := counter + 1;
                        elsif (counter = 16 and dataIndex < 8) then
                            DataOut(dataIndex) <= DataIn;
                            counter := 0;
                            dataIndex := dataIndex + 1;
                        elsif dataIndex = 8 then
                            dataIndex := 0;
                            nextState <= StopBitCheck;
                        else
                            nextState <= ReadData;
                        end if;
                    end if;

                when StopBitCheck =>
                    if Enable = '1' then
                        if DataIn = '1' then
                            if counter < 16  then
                                counter := counter + 1;
                                nextState <= StopBitCheck;                          
                            elsif counter = 16 then
                                counter := 0;
                                nextState <= StartBitCheck;                         
                            end if;
                        else
                            DataOut <= "11111111";
                            BadData <= '1';
                            nextState <= StartBitCheck;
                        end if;
                    end if;

            end case;

    end process;


end Behavioral;

Por cualquier motivo, según mis simulaciones, parece que mis procesos no están sincronizados. Aunque se supone que las cosas solo ocurren en el flanco ascendente del reloj, tengo transiciones que ocurren en el flanco descendente. Además, parece que las cosas no están cambiando de acuerdo con el valor del contador.

La entrada Habilitar es alta en todas mis simulaciones. Sin embargo, esto es solo para mantenerlo simple por ahora, finalmente se alimentará con la salida de un generador de baudios de 153,600 (el generador de baudios se conectará a la entrada de habilitación). Por lo tanto, solo quiero que las cosas cambien cuando mi generador de Baud esté alto. De lo contrario, no hacer nada. ¿Estoy tomando el enfoque correcto para eso con mi código?

Puedo proporcionar una captura de pantalla de mi simulación si eso fuera útil. Tampoco estoy seguro de si estoy incluyendo las variables correctas en mi lista de sensibilidad de proceso. Además, ¿estoy tomando el enfoque correcto con mis variables de contador e índice de datos? ¿Qué sucede si las hice señales como parte de mi arquitectura antes de cualquiera de mis procesos?

¡Cualquier ayuda en esto sería muy apreciada!

    
pregunta coolDude

1 respuesta

2

Primero, use la terminología correcta: RS-232 se refiere a una especificación eléctrica (niveles de voltaje y corriente) y no tiene nada que ver con el protocolo de comunicaciones que esté usando. Lo que estás implementando es un "receptor serie asíncrono".

En su código, el segundo proceso solo incluye a CLK en su lista de sensibilidad, pero en realidad no es un proceso cronometrado. Sin embargo, el simulador le está tomando la palabra y evaluando ese proceso en cada borde del reloj. En su lugar, este proceso debe enumerar todas las señales de entrada, como currentState , Enable y DataIn , que afectan al estado siguiente.

Además, tiene variables en ese segundo proceso ( counter , dataIndex ) que parecen ser variables de estado que solo deben actualizarse en los bordes del reloj. Estas variables deben moverse al primer proceso.

    
respondido por el Dave Tweed

Lea otras preguntas en las etiquetas