Dudas sobre Programación en VHDL

Realmente muchas gracias amigo, tu duda me ha servido de mucho, y ahora creo que tengo que alzar la mano nuevamente y preguntar, (y disculpen pues realmente recién estoy aprendiendo esto del VHDL y aun se me complica =S) .

Bueno tome en consideración tu recomendación y efectivamente consiguió finalmente sintetizarlo, pero ahora lo que intento hacer es desarrollar un contador manual, que no necesite clock, con esta intención es que desarrolle lo siguiente:

Código:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity contadorII is port (
    en: in std_logic;
    Q    : out unsigned (3 downto 0));
end contadorII;

architecture Behavioral of contadorII is
signal Cu: unsigned (3 downto 0);
    begin
    
     
    Process (en)
        begin
            if en = '1' then
                cu <= cu + 1;
            end if;
     end process;
     Q <= cu;
end Behavioral;
Sintetiza de forma adecuada, sin embargo al momento de implementar resulta que existe un error en la etapa de place and route, estube tratando de entender el porque, pero no le doy al problema, quizá pudieras darme otra idea nuevamente, desde ya te lo agradezco muchísimo.
 
Última edición por un moderador:
Hola Sorced,
Mi recomendación es que pongas el reloj, y que dentro de la sentencia de reloj pongas la habilitación de la cuenta (en). Por otro lado, tendrás que incluir un detector de flancos para que cada vez que pulses aumente la cuenta en uno.

Vamos a analizar por qué no funciona tu circuito:
Tu circuito aumenta la cuenta en cada instante en que en='1'.
Es decir, si en='1', en el primer nanosegundo aumentará la cuenta cu<=1, en el siguiente cu<=2,... incluso en las fracciones de nanosegundo aumentaría la cuenta (teóricamente, pero por eso no se puede sintetizar).
Ten en cuenta que en la síntesis no se tiene en cuenta la lista de sensibilidad, es decir, que aunque en simulación el circuito puede parecer que funciona bien porque sólo se entra en el proceso cuando hay cambios de en , en la realidad, el circuito sintetizado realizará la suma cu <= cu + 1; durante todo el tiempo que en='1'.

Para que se pueda sintetizar, una solución sería poner la sentencia de reloj para que sólo se realice la suma con cada flanco de reloj.

Esto te arreglaría el problema de la síntesis, pero te seguiría contando mal, porque cada vez que presionamos el pulsador, habrán transcurrido miles de ciclos de reloj, por lo tanto la cuenta habrá aumentado mucho más que en una unidad.

Para solucionarlo, puedes incluir un circuito detector de flancos, que transforme la señal en en un pulso de un único ciclo de reloj.
Hacer un detector de flancos no es difícil, está explicado en el apartado 5.3.2 del libro Diseño de circuitos digitales con VHDL

Saludos
 
Muchísimas gracias, después de bastantes intentos consegui realizar lo que deseaba, gracias a su ayuda .
 
Última edición por un moderador:
Hola a todos los compañeros de foros de electrónica, por favor me podrían ayudar con un contador que tengo que hacer en los displays pero tengo que subir y bajar con el encoder rotatorio del fpga eso es lo que tengo en el código

Código:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
USE ieee.std_logic_unsigned.all;

ENTITY encoder IS
PORT(    clk        :in        Std_logic; ----- pulsantes para ajuste del reloj
        upd1: in std_logic ;-----encoder subida
        upd2: in std_logic ;------encoder bajada
        rel_seg                :out    std_logic_vector(6 downto 0); ------- segmentos
        sel_dis                :out    std_logic_vector(3 downto 0)-------- displays
    );
END encoder;


ARCHITECTURE rotar OF encoder IS

SIGNAL    cont1,cont3,cont_salida    :std_logic_vector(3 downto 0);-----llegue hasta 9
SIGNAL    cont2,cont4        :std_logic_vector(2 downto 0);---- llegue hasta 5
SIGNAL    divisor            :std_logic_vector(25 downto 0);
SIGNAL    q1,q2,q3        :std_logic_vector(1 downto 0);
signal divpul            :std_logic_vector(1 downto 0);
signal  sel                    :std_logic_vector(2 downto 0);
SIGNAL    pulsa,d,s            :std_logic;
SIGNAL  pulsh, puls1         :std_logic;
signal ayuda: std_logic:= '1' ;

BEGIN
--puls1 << a q1=00 normal clock 59 segundos
--pulsh << a q1=00 normal clock (59 segundos and 59 minutos)
--q1=01 para ajuste segundos    q1=10 para ajuste minutos   q1=11 para ajuste horas
    

    s <= divisor(12) and not d;
    process(clk)
    begin
    if clk'event and clk='1'   then ---------------------------"""""""""""""""""
            d <= divisor(12);
            if divisor=39999999 then 
                divisor<="00000000000000000000000000" ;
            if q1="00" then pulsa<='1';
                else pulsa<='0';
                end if;            
            else
                divisor<=divisor+1;
                pulsa<='0';
        end if;
        
        if (upd1='0') and (upd2='0') then
            if pulsa='1' or ((q1="01") and (q2(0)='1')) then
        --    if upd1<='1' and upd2<='1' then
                    if cont1="1001" then cont1<="0000";
                    else cont1<=cont1+1;
                    end if;
            else 
            cont1<=cont1;
            
            end if;
            else 
                cont1<=cont1-1;
        end if;
                    
        if (upd1 ='0') and (upd2 ='0') then
            if ((q1="01" and q2(0)='1'))and (cont1="1001") then
        --    if upd1<='1' and upd2<='1' then
                if cont2="101" then
                   cont2<="000";
                else cont2<=cont2+1;
                end if;
            else 
            cont2<=cont2;
            end if;
        else 
        cont2<=cont2-1;
        end if;

            if (puls1='1') or ((q1="10") and (q2(0)='1')) then
                        if (upd1='0') and (upd2='0') then
if cont3="1001" then cont3<="0000";
                else cont3<=cont3+1;
                end if;
                        elsif (upd1='1') or (upd2='1') then
                cont3<=cont3-1;
            end if;
            
else cont3<=cont3;
            end if;
            
            if (puls1='1' or (q1="10" and q2(0)='1')) and (cont3="1001") then
            if (upd1='0') and (upd2='0') then
                if cont4="101" then
                    cont4<="000";
                else cont4<=cont4+1;
                end if;
            elsif (upd1='1') or (upd2='1') then
                cont4<=cont4-1;
            end if;    
            else cont4<=cont4;
            end if;
        

            
                    
        case divpul is
                when "00" =>
                    if(divisor(19)='1') then
                         divpul<="01";
                    else divpul<="00";
                    end if;
                when "01" => 
                    divpul<="10";
                when "10" =>
                    if (divisor(19)='0') then
                         divpul<="00";
                    else divpul<="10";
                    end if;
                when others=>
            end case;
            
        --q3(0) es ajuste para el cambio del reloj
        --q2(0) es el pulsante de ajuste del reloj
        
            case q2 is
                when "00" =>
                    if( divpul(0)='1') then
                        q2<="01";
                    else q2<="00";
                    end if;
                when "01" =>
                    q2<="10";
                when "10" =>
                    if (divpul(0)='1') then
                        q2<="00";
                    else q2<="10";
                    end if;
                when "11" => q2<="00";
                when others=>
            end case;
            
            case q1 is
              when "00" =>  
                if     q3(0)='1' then  
                    q1 <= "01";
                else
                    q1<="00";
                end if;
                
              when "01"  =>   
                       if q3(0)='1' then
                        q1<="10";
                    else
                        q1<="01";
                    end if;
                    
              when "10"  => 
                    if q3(0)='1' then
                        q1 <="11";
                    else
                        q1 <="10";
                    end if;                    
                
             when  "11" =>    
                if q3(0)='1' then
                    q1 <="00";
                else
                    q1 <="11";
                end if;
           end case;
            
            
          if s='1' then 
             if sel="101" then sel <="000";
             else sel <= sel+1;
             end if;
          else   sel <= sel;
          end if;
    end if;
    
        end process;
    
    
    
    
    process (sel,cont1,cont2,cont3,cont4)
    begin        
            case sel is
                when "010" =>
                    cont_salida<='0' & cont4;
                    sel_dis<="0001";
                when "011" => 
                    cont_salida<=cont3;
                    sel_dis<="0010";
                when "100" => 
                    cont_salida<='0' & cont2;
                    sel_dis<="0100";
                when "101" => 
                    cont_salida<=cont1;
                    sel_dis<="1000";
                when others =>
                    cont_salida<=cont1;
                    sel_dis<="0000";                
            end case;
    end process;



            
   rel_seg<= "1111110" when cont_salida="0000" else--------displays
             "0110000" when cont_salida="0001" else 
             "1101101" when cont_salida="0010" else 
             "1111001" when cont_salida="0011" else 
             "0110011" when cont_salida="0100" else 
             "1011011" when cont_salida="0101" else 
             "1011111" when cont_salida="0110" else 
             "1110000" when cont_salida="0111" else 
             "1111111" when cont_salida="1000" else 
             "1111011" when cont_salida="1001" else 
             "0000000";
            



            
END rotar;
 
Última edición por un moderador:
lo que no me sale es que cuando pongo 00 si sube el contador con el encoder pero en las otras condiciones en 01,10 y 11 no hace nada y no se muestra nada en los displays
 
¿Has probado a simular? si es así incluye tambien el banco de pruebas y así miro la simulacion. Sin simulación es dificil depurar.
Si quieres que te ayude, explica con más detalle que quieres hacer y que hace cada cosa, así me es más facil ahorro tiempo.
Saludos
 
Buenas a todos. Queria preguntarles si existe alguna buena guia que describa como simular un codigo en VHDL, mas precisamente con el programa Xilinx Ise 9.2. Desde ya, muchas gracias y espero su respuesta. Saludos.
 
Hola Fms, muchas gracias por tu respuesta. Me agrada que me respondas tu, ya que se nota que tienes mucha experiencia en este lenguaje. Ahora me estoy enfocando para codificar contadores y registros de desplazamiento, y tengo este codigo de un contador ascendente/descendente con carga y reset que muestro a continuacion:

Código:
library ieee;
use ieee.std_logic_1164.all;
use work.std_arith.all;
  
entity contador is port(
clk, load, reset,arriba:in std_logic;
data:    in std_logic_vector(3 downto 0);
conta:buffer std_logic_vector(3 downto 0)
);
end contador;
  
architecture archicontador of contador is
begin
process (clk,reset)
begin
  if reset = '1' then
   conta <= "0000";
  elsif (clk'event and clk= '1') then
   if load = '1' then
    conta <= data;
   elsif arriba = '1' then
    conta <= conta + 1;
   else conta <= conta - 1;
   end if;
  end if;
end process;
end archicontador;

En primer lugar queria consultarte si seria correcto decir que este contador tiene reset asincronico, por el hecho de que la señal del reset se encuentra fuera de la condicion del if del clock (que detecta cambios a partir de su flanco ascendente). En segundo lugar, lo que necesito hacer es modificar el codigo, de forma tal de hacer que la carga paralela sea tambien asincronica... ¿Como te parece que podria implementarlo? A mi se me ocurrio sacar el "if load = '1' then conta <= data;" de la condicion del clock, y ponerlo debajo de la condicion del reset. En fin, me gustaria saber que opinas, o cual podria ser la mejor forma para hacerlo. Desde ya, muchas gracias por tu tiempo.

Saludos.

---

Edit: Ademas deberia modificar la linea de "process (clk,reset)", ¿no es cierto? Agregando la carga a la lista de sensibilidad, pero tengo la duda si añadir al parentesis ambas señales o una sola, ya que tengo "load" y "data".

"load" es una señal que, si se encuentra en "1", es decir, "habilitada", me asigna los datos al contador.

"data" es una señal donde basicamente se encuentran los datos en cuestion para ser asignados.

Espero que me puedas dar una mano. Agradezco tu ayuda. :)
 
Última edición:
Hola bur85x,
Sí, el reset es asíncrono por la razón que dices. Y para tener la carga asíncrona la solución es la que dices. Como dices, tendrás que añadir a la lista de sensibilidad del proceso las señales "load" y "data".

Del código tengo algunos comentarios:

1. usas la biblioteca, work.std_arith.all; supongo que querras usar :

use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

o bien

use ieee.numeric_std.all;

2. el puerto "conta" lo has declarado como buffer. Supongo que lo has hecho así para poderlo leer y escribir. Sería mejor declararlo como puerto de salida (out), y usar una señal auxiliar en el proceso, por ejemplo "conta_aux". Si lo haces así, fuera del proceso, como sentencia concurrente, tendrías que realizar la siguiente asignación:

conta <= conta_aux;

3. Para la señal conta, o al menos para la auxiliar conta_aux, yo la declararia como tipo unsigned. Esto permite realizar las sumas.

Si haces esto último, te podrá ser necesario convertir entre std_logic_vector y unsigned. Esto se hace con una conversión cast, por ejemplo:

conta <= std_logic_vector(conta_aux); -- conta es std_logic_vector y conta_aux unsigned

conta_aux <= unsigned(data); -- conta_aux es unsigned y data std_logic_vector

Espero que te ayude, saludos
 
Muchas gracias por tu apreciacion, Fms, realmente me sirve.

Con respecto a las librerias, en verdad deje las que se cargan por defecto cuando creo un modulo de VHDL, pero ya que tu me lo mencionas, calculo que seria mucho mas optimo utilizar solamente las que necesito en el codigo.

Ademas, me parece acertado el hecho de usar una variable auxiliar para manejar el contador.

Aprovecho para hacerte otra consulta, si es posible, en este caso sobre registros de desplazamiento. Mi profesor me envio el siguiente codigo que te muestro a continuacion, que consiste en un registro de 8 bits, bidireccional, con señal de clock ascendente, entrada de datos en serie y salida de datos en paralelo. Aqui va el codigo:

Código:
entity shift is
port (C, SI, LEFT_RIGHT : in std_logic;
      PO : out std_logic_vector (7 downto 0));
end shift;

architecture archi of shift is
  signal tmp : std_logic_vector (7 downto 0);
begin
  process (C)
    begin
      if (C'event and C='1') then
        if (LEFT_RIGHT='0') then
          tmp <= tmp (6 downto 0) & SI;
        else
          tmp <= SI & tmp (7 downto 1);
        end if;
      end if;
    end process;
  PO <= tmp;
end archi;

Lo que te queria preguntar era, mas que nada, para tratar de comprender las lineas: "tmp <= tmp (6 downto 0) & SI;" y "tmp <= SI & tmp (7 downto 1);" que basicamente hacen la "magia" del registro, pero me cuesta entender como es que funcionan, y como me doy cuenta si esta desplazando a izquierda o a derecha. Muchas gracias.
 
Última edición:
El operador "&" es el operador para concatenar
Entonces la sentencia:

tmp <= tmp (6 downto 0) & SI;

lo que hace es asignar a tmp(7 downto 0) la concatenacion de tmp (6 downto 0) con SI;. En el mismo orden de de bits: izquierda a derecha. El bit 7 se le asignaría tmp(6) y al bit 0 se le asignaría SI. Es decir, sería equivalente a relizar estas asignaciones individuales:

-- codigo desp izq
tmp(7) <= tmp(6);
tmp(6) <= tmp(5);
tmp(5) <= tmp(4);
tmp(4) <= tmp(3);
tmp(3) <= tmp(2);
tmp(2) <= tmp(1);
tmp(1) <= tmp(0);
tmp(0) <= SI;

Lo importante de entender aquí es que en los procesos las señales no actualizan el valor asignado hasta llegar al final del proceso (ésta es la principal diferencia con las variables), porque especialmente en el desplazamiento a la derecha puede dar lugar a dudas, por ejemplo:

tmp <= SI & tmp (7 downto 1);

sería equivalente a:

-- codigo desp dcha
tmp(7) <= SI;
tmp(6) <= tmp(7);
tmp(5) <= tmp(6);
tmp(4) <= tmp(5);
tmp(3) <= tmp(4);
tmp(2) <= tmp(3);
tmp(1) <= tmp(2);
tmp(0) <= tmp(1);

Al ver que SI se asigna a tmp(7), y como tmp(7) se asigna a tmp(6), tmp(6) a tmp(5), y así sucesivamente .... hasta tmp(0), podríamos pensar que al final SI se va a asignar a tmp(0), y que todo el vector tmp va a tener el valor de SI al salir del proceso.
Pero esto no ocurre, ya que al estar dentro de un proceso, tmp(7) no va a tomar el valor de SI hasta que se sale del proceso.
Por lo tanto, da igual el orden en que se pongan las asignaciones, es decir que sería equivalente a describirlo en el orden inverso:

-- codigo desp dcha 2
tmp(0) <= tmp(1);
tmp(1) <= tmp(2);
tmp(2) <= tmp(3);
tmp(3) <= tmp(4);
tmp(4) <= tmp(5);
tmp(5) <= tmp(6);
tmp(6) <= tmp(7);
tmp(7) <= SI;

Así que las descripciones codigo desp dcha y codigo desp dcha 2 serían equivalentes.

Espero haberme explicado. Es uno de los conceptos que al principio más cuesta entender del VHDL
Saludos
 
Es cierto, al principio cuesta un poco comprender el tema de los desplazamientos, pero te agradezco mucho tu explicacion, ya que me fue de gran ayuda para saber como se realizan las asignaciones a la señal, paso a paso.

Estos dias voy a aprovechar para hacer algunos ejercicios para practicar, cualquier cosa te consulto, ¿vale? :)
 
Hola, buenos dias. Hoy estuve realizando unos cuantos ejercicios en VHDL sobre contadores y registros, por eso queria hacer algunas preguntas que surgieron sobre algunos de ellos, y revisar si el procedimiento es correcto.

En el caso de la señal "cuenta", por ahora preferi dejarla declarada como buffer, dado que el profesor nos envio un modelo basico de contadores donde la señal estaba representada asi, pero mas que nada para que el despues no me invada con preguntas especificas sobre alguna modificacion adicional que haya realizado, o algo asi, jeje.

Del siguiente ejercicio, queria saber si es valida la estructura condicional asincrona formada por el reset y la carga. ¿Esta bien utilizar el elseif? ¿No puede suceder que se saltee alguna condicion que deba cumplirse?

Contador binario ascendente 4 bits c/ carga paralela asincrónica
• 1 entrada CLOCK.
• 1 entrada de indicación de carga (1bit): mientras esté activa, implica la carga paralela a salida.
• 1 entrada carga paralela (4 bits): se introduce el dato de carga
• 1 entrada Reset Asincrónico: la cuenta vuelve a 0000.
• 4 salidas (1 bit): conteo.

Código:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity contador_3 is
port (clk, carga, rst : in std_logic;
      datos : in std_logic_vector (3 downto 0);
      cuenta : buffer std_logic_vector (3 downto 0));
end contador_3;

architecture comportamiento of contador_3 is
begin
   process (clk, carga, rst, datos)
   begin
      if (rst='1') then
         cuenta<="0000";
      elsif (carga='1') then
         cuenta<=datos;
      elsif (clk'event and clk='1') then
         cuenta<=cuenta+1;
      end if;
   end process;
end comportamiento;

Ahora tenemos un contador johnson, que basicamente lo simplifique a partir de uno mucho mas complejo, que traia resets sincronos y asincronos, pero lo adapte a las condiciones que se pedian en el ejercicio. Me gustaria saber si, a simple vista, esta mas o menos bien representado, o si hay algo que te parece que pueda faltar...

Contador Johnson ascendente n bits
• 1 entrada CLOCK.
• 1 entrada de Habilitación: si no está habilitado, el contador ignora los pulsos de CLK
• n salidas (1 bit): conteo.

Código:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity johnson is
generic (n : natural := 4);
port (clk, habilitacion : in std_logic;
      cuenta : out std_logic_vector (n-1 downto 0));
end johnson;

architecture comportamiento of johnson is
signal reg_john, nxt_john : std_logic_vector (n-1 downto 0);
begin
   process (clk)
   begin
      if (clk'event and clk='1') then
         if (habilitacion='1') then
            reg_john<=nxt_john;
         end if;
      end if;
   end process;
   process (reg_john)
   begin
      nxt_john<=reg_john (n-2 downto 0) & not reg_john (n-1);
   end process;
   cuenta<=reg_john;
end comportamiento;

Finalmente, el ultimo ejercicio que resolvi es el de un registro, pero con este no tuve mayor dificultad.

Registro de desplazamiento
• Registro de desplazamiento de 8 bits
• Activo por flanco ascendente de CLOCK
• Entrada datos serie
• Salida datos PARALELO
• Entrada de HABILITACIÓN por nivel (H=0 => ignora CLK)
• Carga PARALELO de datos asincrónica

Código:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity registro_5 is
port (clk, entrada, habilitacion, carga : in std_logic;
      datos : in std_logic_vector (7 downto 0);
      salida : out std_logic_vector (7 downto 0));
end registro_5;

architecture comportamiento of registro_5 is
signal tmp : std_logic_vector (7 downto 0);
begin
   process (clk, carga, datos)
   begin
      if (carga='1') then
         tmp<=datos;
      elsif (clk'event and clk='1') then
         if (habilitacion='1') then
            tmp<=tmp (6 downto 0) & entrada;
         end if;
      end if;
   end process;
   salida<=tmp;
end comportamiento;

Lo que voy a intentar hacer es la simulacion de los ejercicios, ya que estimo que es una buena forma para chequear que la logica de cada programa se cumple para cada caso. Mil gracias por su tiempo. Saludos.

---

Hola. Estuve simulando los ejercicios de contadores y funcionaron perfecto. El unico problema lo tuve cuando simule el contador johnson, por el hecho de que, en la salida de la cuenta, me muestra todas letras 'U's, y estando la habilitacion seteada en "1" en determinados momentos. A continuacion dejo el screenshot:

ZrrVH.jpg


¿Que significaria esa 'U' que me aparece? ¿De que manera lo podria solucionar?

Tambien probe simulando el contador johnson original que tenia, y sucede lo mismo.

Espero su respuesta. Muchas gracias.

PD: La cuenta deberia ser esta.
 
Última edición:
Una manera de resolqver el problema que tenes con el contador Johnson es agregarle una entrada de reset o de carga paralela para establecer condiciones iniciales

Saludos
 
Que bueno que lo hayas resuelto
Creo que de lo que preguntabas solo te queda pendiente saber si los elsif pudieran hacer que no se cumpliese alguna condición en tu contador ascendente 4 bits con carga paralela asíncrona:
Código:
      if (rst='1') then  
         cuenta<="0000";
      elsif (carga='1') then  
         cuenta<=datos;
      elsif (clk'event and clk='1') then
         cuenta<=cuenta+1;
      end if;
Los elsif establecen prioridades de arriba a abajo dentro del mismo nivel de anidamiento, así que en tu caso, si hay reset ni se carga nada ni cuenta.
Luego, si no hay reset pero hay carga, no se cuenta.
Y por último, si no hay reset ni carga, se cuenta.
Todo esto es lógico, pues cuando reseteas o cuando cargas el dato no tiene sentido contar. De todos modos, las prioridades de las condiciones deben estar especificadas claramente, y si no lo están, o bien lo interpretas como creas, o bien lo preguntas, lo que es una mejor opción porque muchas veces ocurre que el que quiere el circuito no se ha planteado qué hacer en cada uno de los casos.
Saludos
 
Igual te aclaro que la carga asincronica es una curiosidad, no algo que se utilice en diseños reales de hoy en dia. Lo unico asincronico es el reset e incluso para este, se sincroniza la subida de la señal de reset de manera de que los datos siempre, siempre cambien en forma sincronica con el reloj.
 
Hola buenas noches,

Tengo un gran problema ya que necesito progrmar una GAL22v10 con V.H.D.L. para que me muestre las letras en 4 display´s.

ejemplo:

tiempo 1: 0 0 0 0 (estado del display)
timepo 2: 0 0 0 G
tiempo 3: 0 0 G O
tiempo 4: 0 G O A
tiempo 5: G O A L
 
Atrás
Arriba