Realización de UHD de VHDL

2

Intento implementar el siguiente simple receptor UART. Las simulaciones van bien (imagen adjunta). Pero encontré algunos problemas en la realización de hardware real utilizando la placa Nexys 2. Intento enviar un símbolo a través de minicom usando el siguiente protocolo 1 bit de inicio 8 bits de datos 1 bit de parada 115200 velocidad en baudios También tengo un reloj FPGA de 50 Mhz, que uso directamente como receptor de UART. El contador de UART cuenta a 434 (F = 115200 Hz - > T = 8680 ns - > T = 20 ns * 434) Por lo tanto, al registrar 233 obtendremos el centro del bit recibido. Al depurar la salida del uart, adjunté DATA_OUT desde el receptor a los leds de la placa Nexys.

Me parece que obtengo los códigos de símbolo incorrectos. Por ejemplo, cuando envío '1' (00110001) obtengo el código 10011001 y así sucesivamente

'2' 00110010 - > 10011010

'3' 00110011 - > 10011011

'4' 00110100 - > 10011000

Así que mi sugerencia es que algo está mal con el código VHDL, pero no entiendo qué es exactamente ... ¿Alguien puede ayudarme, por favor? Gracias.

entity uart_reciever is
    Port ( clk : in  STD_LOGIC;
           rx : in  STD_LOGIC;
    recieved : out std_logic;
              en : in  STD_LOGIC;
           data_out : out  STD_LOGIC_VECTOR (7 downto 0)
              );
end uart_reciever;

architecture Behavioral of uart_reciever is
    signal count : std_logic;
    signal rec : std_logic := '0';
    signal counter : integer range 0 to 433;
begin
    process (clk)
        variable state : integer range 0 to 9 := 0;
        variable data : std_logic_vector (7 downto 0);
        variable rx_p : std_logic;
        begin
            recieved <= rec;
            if rising_edge(clk) AND en = '1' then

                if (rx_p = '1' and rx = '0') then       --  
                    count <= '1';
                    rx_p := rx;
                else 
                    rx_p := rx;
                end if;

            if (counter = 216) then
                rec <= '0';
                case (state) is
                    when 0 =>
                        if (rx = '0') then      --  -
                            state := 1;     
                   else 
                            state := 0;
                     count <= '0';
                   end if;
                    when 1 => 
                        data(0) := rx;        --  
                  state := 2;
                    when 2 => 
                        data(1) := rx;
                  state := 3;
                    when 3 => 
                        data(2) := rx;
                  state := 4;
                    when 4 => 
                        data(3) := rx;
                  state := 5;
                    when 5 => 
                        data(4) := rx;
                  state := 6;
                    when 6 => 
                        data(5) := rx;
                  state := 7;
                    when 7 => 
                        data(6) := rx;
                  state := 8;
                    when 8 => 
                        data(7) := rx;
                  state := 9;
                    when 9 => 
                        state := 0;
                  count <= '0';
                        if (rx = '1') then
                            data_out <= data; 
                            rec <= '1';
                        end if;
                end case;
            end if;
        end if;
    end process;

    process (clk)
    begin
        if rising_edge(clk) then       
        if (count = '1') AND (counter < 434) then
                counter <= counter + 1; 
        else 
                counter <= 0;
        end if;
        end if;
end process;

    
pregunta Alex Hoppus

2 respuestas

1

Su implementación parece básicamente sólida. Su segundo proceso esencialmente cuenta con tiempos de bits completos; luego su primer proceso detecta el borde inicial del bit de inicio, sincroniza el contador de bits completo con ese borde y luego muestrea los datos cada vez que el punto de fase del contador de bits completo indica que ha llegado la mitad del bit. Las implementaciones varían, pero el algoritmo es clásico: vaya al centro del bit de inicio, luego muestree en los tiempos de bit regulares posteriores.

Sus ejemplos de error son interesantes sin embargo. Teniendo en cuenta que el LSB es lo primero, parece que su sistema normalmente obtiene los dos primeros, a menudo tres bits correctos. Y en todos los ejemplos, el MSB es incorrectamente '1', lo que sugiere la posibilidad de que ese '1' sea en realidad el bit de parada.

En general, parece un problema de frecuencia, específicamente, como la frecuencia de muestreo es un poco demasiado baja en comparación con la velocidad de datos real. Creo que intentaría 01000000 para un vector de prueba; Si el problema es una velocidad de muestreo lenta, es probable que lo lea como 00100000. Solo para las risas, puede intentar reducir el rango de 434 a 430 o 425 para ver qué sucede.

Y por último, en el departamento '¿has intentado desenchufarlo y volver a enchufarlo'? no es algo así como 48MHz, y (2) ha transmitido la señal de prueba a algún otro equipo que se sabe que funciona correctamente en 115.2, y comprobó que la fuente de la señal no se está ejecutando rápidamente.

    
respondido por el JustJeff
0

Mi experiencia con el UART es que algún otro aspecto es incorrecto. Los pines CTS / RTS y posiblemente algunos otros necesitan a menudo ser accionados correctamente para que funcione. Sugeriría algunas cosas:

  • Obtenga un diseño UART de OpenCores o similar (o el proveedor de FPGA puede tener un núcleo de IP para él). Conecte eso a su UART y utilícelo como un generador de estímulo de prueba. Esto le permitirá verificar su diseño en comparación con uno existente (con suerte) que funciona.
  • Obtenga un osciloscopio y eche un vistazo a los pines RX / TX, etc., y vea si los datos están saliendo de la forma que espera.
  • Hay una serie de programas de terminales en serie que brindan mucha más información y opciones de configuración que Hyperterm. Eso podría ser de alguna ayuda mientras estás depurando
  •     
    respondido por el squizzar

    Lea otras preguntas en las etiquetas