desktop

Dudas sobre Programación en VHDL

hola, muchas gracias por la ayuda, bueno te comento que me sirvió de mucho el código, pero lo tengo que mostrar en un display de 7 segmentos, buscando por aquí en el foro, y tratando de comprender vhdl, llegue a anexarle algo al código que me habías propuesto, te lo dejo, espero que me puedas ayudar, ya que me un error, lo que quiero es que Q ya no sea salida, si no ahora sera el display, de antemano gracias.

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

ENTITY cont9 is
    Port ( 
        clk,reset,updown: in std_logic;
        DISPLAY : out STD_LOGIC_VECTOR(6 DOWNTO 0)
        );

        ATTRIBUTE PIN_NUMBERS OF cont9 : ENTITY IS
        "DISPLAY(6):21 DISPLAY(5):20 DISPLAY(4):19 DISPLAY(3):18 "
    &    "DISPLAY(2):17 DISPLAY(1):16 DISPLAY(0):15 ";


end cont9;

architecture arqcont9 of cont9 is
begin
   process (clk,reset) begin
   
     if (clk'event and clk = '1') then                                                                                             --la asignacion de la señal de reloj
       if (updown = '1') then                                                                                                     --aqui se usa un if para la condición del updown el cual va a regir si es ascendente o descendente, en este caso cuando sea 1 sera ascendente mi contador
        Q <= Q + 1;                                                                                                             --aqui se indica la condición, Q pasara a ser Q + 1, esto significa que sumare un 1 a Q cada vez [B][COLOR=Red]qu[/COLOR][/B]e la señal de reloj este ne flanco de subida y tenga un 1 en updown
          if (reset = '1' or Q = "1001") then                                                                                     --aqui hay una condición anidada en otra condición, ya que si no se implementa, nuestro contador llegara a su máxima cuenta de cuatro bits que es '1111' o en pocas palabras 15, pero como solo la cuenta es hasta el 9, cuando pase de ese conteo se reiniciara, así que cuando Q sea igual a 9 en binario, o ('or' como esta implementado en mi condición) mi señal de reset sea igual a 1 tendrá que reiniciarse
             Q <= "0000";                                                                                                         --nuestro Q regresara al principio
     
          end if;
       else                                                                                                                     --este else indica cuando updown es igual a 0
        Q <= Q - 1;                                                                                                             --en este caso a Q se le restara 1 cada flanco de subida de nuestro reloj    
          if (Q = "0000") then                                                                                                     --aqui hay 2 if anidados, el primero me indica que si en el conteo llega a 0:
             Q <= "1001";                                                                                                         --el siguiente conteo sera a 9
             
          end if;
          if (reset = '1') then                                                                                                 --el otro if esta asignado a mi reset, cuando este vale 1:
             Q <= "0000";                                                                                                         -- Q se reiniciara en 0
            end if;
        end if;
     end if;
   end process;

  with Q select
    DISPLAY<= "0110000" when "0001",
              "1101101" when "0010",
              "1111001" when "0011",
              "0110011" when "0100",
              "1011011" when "0101",
              "1011111" when "0110",
              "1110000" when "0111",
              "1111111" when "1000",
              "1110011" when "1001",
              "0000001" when others;
end arqcont9;
 
Última edición por un moderador:
Que tal "bluecode1908":

Me da gusto de que el anterior codigo te haya funcionado. El codigo que ahora presentas tiene un error muy trivial y facil de reparar, solo tienes que declarar la entidad "Q" en "port" asi podras usar el comando "with" aunque, al declarar "Q" y "D" tendras que usar 11 pines, pero recuerda que la GAL22V10 solo tiene 10 pines de salida disponible, asi que ese codigo no cabe en tu GAL, la unica opcion es conseguir un CPLD, pero yo te ofreco otra opcion.

En este caso te presento el codigo el cual solo recurre a las salidas de tu display sin tener que usar mas salidas, la novedad de este codigo es que ya no usa la libreria arith, y su funcion es parecida a la de la maquina de estados:

Código:
library ieee;
use ieee.std_logic_1164.all;

entity contdisp is
    port(  Clk, reset, updown: in std_logic;
           D: out std_logic_vector(6 downto 0));

attribute pin_numbers of contdisp: entity is
   " D(6):21 D(5):20 D(4):19 D(3):18 D(2):17 D(1):16 D(0):15 "; 

end contdisp;

architecture arqcont of contdisp is begin
   process (clk, reset, updown) begin
   if(clk'event and clk = '1') then
         if (reset = '1') then
            D <= "0000001";
         else        
            case D is
               when "0000001" => D <= "0000001"; --0
                  if (updown = '1') then
                     D <= "1001111"; --1
                  else
                     D <= "0000100"; --9
                  end if;
               when "1001111" => D <= "1001111"; --1
                  if (updown = '1') then
                     D <= "0010010"; --2
                  else
                     D <= "0000001"; --0
                  end if;
               when "0010010" => D <= "0010010"; --2
                  if (updown = '1') then
                     D <= "0000110"; --3
                  else
                     D <= "1001111"; --1
                  end if;
               when "0000110" => D <= "0000110"; --3
                  if (updown = '1') then
                     D <= "1001100"; --4
                  else
                     D <= "0010010"; --2
                  end if;
               when "1001100" => D <= "1001100"; --4
                  if (updown = '1') then
                     D <= "0100100"; --5
                  else
                     D <= "0000110"; --3
                  end if;
               when "0100100" => D <= "0100100"; --5
                  if (updown = '1') then
                     D <= "0100000"; --6
                  else
                     D <= "1001100"; --4
                  end if;
               when "0100000" => D <= "0100000"; --6
                  if (updown = '1') then
                     D <= "0001111"; --7
                  else
                     D <= "0100100"; --5
                  end if;
               when "0001111" => D <= "0001111"; --7
                  if (updown = '1') then
                     D <= "0000000"; --8
                  else
                     D <= "0100000"; --6
                  end if;
               when "0000000" => D <= "0000000"; --8
                  if (updown = '1') then
                     D <= "0000100"; --9
                  else
                     D <= "0001111"; --7
                  end if;
               when "0000100" => D <= "0000100"; --9
                  if (updown = '1') then
                     D <= "0000001"; --0
                  else
                     D <= "0000000"; --8
                  end if;
	       when others => D <= "1111111";
            end case;       
         end if;
      end if;
   end process;
end arqcont;

En sintesis, este es un contador ascendente-descendente del 0 al 9 ya decodificado para un display anodo comun, tiene un IF primario el cual rige el reset, en la condicion de que reset sea 1, la salida "D" pasara estrictamente a "0000001" o en pocas palabras a un 0 decodificado, en el "else" se incluye el codigo de la funcion del contador, despues uso el comando "case" muy parecido a "with", pero la unica diferencia es que es de tipo secuencia, en pocas palabras tiene una jerarquia, para seguir una secuencia se usa un if anidado el cual hace la funcion del conteo cada vez que se presenta la señal de reloj, para explicar su funcion recurrire a los primeros 2 numeros, el 0 y el 1:

when "0000001" => D <= "0000001"; --0 (este muestra el primero numero "0" en "D")
if (updown = '1') then (la condicion cuando updown sea '1')
D <= "1001111"; --1 (el display pasara a ser "1" en D, asi se vincula al siguiente numero)
else (este es la condicion cuando updown sea '0')
D <= "0000100"; --9 (el display pasara a ser "9" en "D", asi se vincula al ultimo numero en el conteo descendente)
end if; (fin del IF anidado)
when "1001111" => D <= "1001111"; --1 (este codigo ahora es cuando "D" represente a "1")
if (updown = '1') then (la condicion de la ascendencia)
D <= "0010010"; --2 ("D" pasara a ser el siguiente numero "2")
else (la condicion de la descendencia)
D <= "0000001"; --0 ("D" pasara a ser el anterior numero "0")
end if; (asi sucesivamente hasta llegar al que "D" represente a "9".)

Este codigo me parece muy sencillo, ademas de que solo usa las salidas necesarias para el display. En caso de que quieras usar un display catodo comun, tendras que negar las salidas de "D" en el codigo, en pocas palabras para cuando "D" sea "0000001" en configuracion de anodo comun, ahora seria "1111110" para una configuracion de catodo comun, recuerda invertir todas las salidas en el codigo, ya que si se te pasa alguna, ya no funcionara tu contador adecuadamente.

Eso seria todo, cualquier duda recuerda dejar un mensaje, y tambien avisanos como te fue con el codigo, suerte "bluecode1908"!
 
Última edición:
de verdad te agradezco infinitamente tu ayuda amigo ZeUrO, de verdad gracias, lo compile hace unos momentos, y todo a la perfección, solo hice la modificación de anodo a catodo, lo mas simple, mañana te aviso como me fue, ya que hasta el momento solo he alambrado el circuito en protoboard, el dia de mañana grabo en mi dispositivo, y yo aviso como funciono, muchas gracias. :D
 
Alguien tiene idea de como realizar un doblador de frecuencia utilizando xilinx system generator de simulink, necesito convertir una señal de 60 Hz a 120 Hz
 
que tal, gracias a todos por sus aportes, quisiera ver si alguien podria ayudarme a que mi contador ascendente descendente (4 bits) no necesite de un seleccionador para hacer la cuenta hacia arriba o hacia abajo, que lo haga de manera automatica, es decir que de 0 suba a 15 y de 15 baje a 14 , 13, 12 y así hasta el 0, por su atencion gracias
 
Gente, necesito que me den una mano tengo que escribir un programa VHDL para diseñar una ALU para 32 bits y que realice 10 posibles operaciones lógicas y/o aritméticas.
 
Buen dia, pues como estoy en vacaciones, pues volví a este foro que tanto estimo, bueno pues a lo que va el tema, responder consultas aunque ya son antiguas, espero que sirvan aun... estaré respondiendo hasta mediados de febrero.. asi que pregunten .. y si puedo les ayudo
abraren multiplicador de frecuencia
Alguien tiene idea de como realizar un doblador de frecuencia utilizando xilinx system generator de simulink, necesito convertir una señal de 60 Hz a 120 Hz
Pues claro que hay idea como realizar un multiplicador de frecuencias, te explico: teniendo una señal de "muestreo" en mi caso 27Mhz la cual pondrá en sincronía nuestra señal de entrada (con cualquier frecuencia que quieras), esta señal de muestreo realizara un conteo en cada flanco de nuestra señal de muestreo cuando la señal de entrada este en cero, cuando nuestra entrada pase de cero a uno (primer flanco) este nos ayudara a guardar el numero contado hasta esta instancia, guardamos este numero y realizamos la división por N que es el numero multiplicador de frecuencias de esta manera realizamos el multiplicador frec(salida)= N * frec(entrada), El código vhdl esta muy extenso se puede reducir las lineas de programa. podemos cambiar a gusto el numero multiplicador en programa, también se lo podría hacer por selección externa.

-- multiplica por "n" un valor de frecuencia de entrada. salida=entrada*n
Código:
library ieee;
use ieee.std_logic_1164.all;

entity m_frec is
        generic (n: integer:=4); --Define numero N multiplicador
port (    entrada: in std_logic;
        clk_27Mhz:in std_logic;
        salida: out std_logic);
end m_frec;

architecture rtl of m_frec is 
    signal cuenta,cuenta2,div,M: integer:=0;
    signal f_in,f_sal:std_logic;
begin
process (clk_27Mhz)
    begin
    if (clk_27Mhz'event and clk_27Mhz = '1') then
    f_in <= entrada;
    end if;
end process;
process (f_in,clk_27Mhz)
    begin
    if (f_in = '1') then
    cuenta <= 0;
    elsif (clk_27Mhz'event and clk_27Mhz = '0') then
    cuenta <= cuenta + 1;
    end if;
end process;
process (f_in)
    begin
    if (f_in'event and f_in = '1') then
    M <= cuenta;
    end if;
end process;
div <= (M-1)/N;
process (clk_27Mhz)
    begin
    if (Clk_27Mhz'event and Clk_27Mhz = '1') then
        if (cuenta2 = div) then
        cuenta2 <= 0;
        f_sal <= not f_sal;
        else cuenta2 <= cuenta2 + 1;
        end if;
    end if;
end process;
salida <= f_sal;
end rtl;
generando las ondas, en el programa en quartus II, observamos que efectivamente se multiplico por 4. Ahora bien,en tu caso podemos multiplicar la frecuencia de entrada por cualquier numero n (yo lo probe con 2,3,4,...10) cuando n=7 hay un ligero error.
multiplicador_frecuencias.gif

nota:lo simule en timing, para observar un comportamiento "real"

hrdkre
que tal, gracias a todos por sus aportes, quisiera ver si alguien podria ayudarme a que mi contador ascendente descendente (4 bits) no necesite de un seleccionador para hacer la cuenta hacia arriba o hacia abajo, que lo haga de manera automatica, es decir que de 0 suba a 15 y de 15 baje a 14 , 13, 12 y así hasta el 0, por su atencion gracias
pues un contador up/down automatico pues aca te envio el codigo vhdl de esto, solo necesitas un reloj de entrada

Código:
    library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity updown is
port(
    clk: in std_logic;
    salida:out std_logic_vector(3 downto 0));
end updown;

architecture rtl of updown is
    signal cuenta:integer:=0;
    signal marcador:std_logic;
begin
process(clk)
    begin
    if (clk'event and clk='0') then
        if (cuenta = 15) then
        cuenta <= 0;
        marcador <= not marcador;
        else
        cuenta <= cuenta + 1;
        end if;
    end if;
end process;
process(marcador,cuenta)
    begin
    if (marcador='0') then
    salida<=conv_std_logic_vector(cuenta, 4);
    else
    salida<=not conv_std_logic_vector(cuenta, 4);
    end if;
end process;
end rtl;

Menta14 Gente, necesito que me den una mano tengo que escribir un programa VHDL para diseñar una ALU para 32 bits y que realice 10 posibles operaciones lógicas y/o aritméticas.
bueno compañero.. si quieres una alu de 32 bits, simplemente debes de especificar el vector de entrada sea de esta cantidad de bits, y pues vendria ser algo parecido a

Código:
    library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity alu is port (
s: in std_logic_vector(2 downto 0); -- alu de 8 operaciones
a, b: in std_logic_vector(31 downto 0); 
f: out std_logic_vector(31 downto 0)); 
end alu;

architecture behavior of alu is
begin
process(s, a, b)
begin
case s is
when "000" => -- pass a through
f <= a;
when "001" => -- and
f <= a and b;
when "010" => -- or
f <= a or b;
when "011" => -- not a
f <= not a;
when "100" => -- add
f <= a + b;
when "101" => -- subtract
f <= a - b;
when "110" => -- increment
f <= a + 1;
when others => -- decrement
f <= a - 1;
end case;
end process;
end behavior;

tienes que estudiar que operaciones desearías y .. el numero de bits en la salida
saludos
 
Última edición por un moderador:
Hola,

Soy nuevo por aquí y ando un poco desesperado la verdad.
Me hacen entrgar un ejercicio en VHDL correspondiente a un tunel de lavado de coches, es que alguien podría echarme una mano?
No tengo conocimientos en programación y estoy muy muuy perdido...

Gracias.

Un saludo
 
pues para poder resolver esto debes de especificar las acciones que tendra tu tunel de lavado de coches, y realizar un analisis de estados ya sea con mealy o moore. y tener tu circuito ejemplo de ahi describirlo en vhdl...
 
gracias por tu temprana respuesta!

es que podrías mandarme un privado (yo soy usuario reciente y no puedo) y te cuento un poco más en detalle, tampoco quiero monopolizar el foro...aunque luego puedo subir la respuesta final para compartirla por supuesto!

Muchas gracias
 
si me podrían ayudar con un seleccionador de velocidad para el clock de un contador ya que no puedo utilizar el clock que se encuentra en el FPGA, sino que tengo que variar la velocidad con dos switches.
Además recien empiezo a programar en VHDL
 
Explica un poco más lo que quieres hacer y por qué no puedes utilizar el reloj de la FPGA.
Si necesitas distintas frecuencias a la salida, puedes utilizar el reloj de la FPGA y realizar cuentas diferentes según la frecuencia de salida deseada.
 
Un contador de por si es un divisor de frecuencia. Se puede crear una logica en la que el contador divisor de frecuencia cuenta para abajo desde un valor de preset segun los dip switches. Cada vez que el contador divisor llega a cero emite un pulso y recarga el valor de preset.

El pulso de salida del divisor es utilizado como clock enable para el segundo contador.
 
Un gran saludo a todos en el Foro que desde siempre me ha ayudado mucho para mi desarrollo como estudiante de electrónica.

Actualmente me encuentro tratando de comprender el lenguaje VHDL, y encontré el diseño de un contador:
Código:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.std_arith.all;
entity contadorII is port (
    clk: in std_logic;
    Q    : inout std_logic_vector (3 downto 0));
end contadorII;

architecture Behavioral of contadorII is
    begin
    
        Process (clk)
        begin
            if (clk' event and clk = '1') then
                Q <= Q + 1;
            end if;
        end process;
    
end Behavioral;
Aparentemente es sencillo, sin embargo cuando lo quiero implementar en mi software de desarrollo (ISE project Navigator v 13.4) no reconoce la declaración de la librería: work.std_arith.all;, luego al reemplazar esa librería por use IEEE.std_logic_arith.all; reconoce la librería, sin embargo no reconoce el operador "+" estoy en una encrucijada y no puedo avanzar en mi proyecto. Si alguien pudiera darme una mano, sería de gran ayuda.
Desde ya muchas gracias.
 
Última edición por un moderador:
Hola Sorced,

Prueba a poner estas bibliotecas a ver que pasa:
Código:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

Otra alternativa más razonable es que declares Q como unsigned. Pues en realidad, un std_logic_vector no debería de poder sumarse, pues no sabes qué representación tiene: no sabes si es un entero con signo, sin signo,...

Otras cosas:

¿Por qué pones el puerto Q como inout? ponlo como out, pues es en el contador donde únicamente le vas a asignar valor.

Pero entonces no podrás asignar y leer Q, tendrás que crear una señal auxiliar que es la que realiza la cuenta.

Por ejemplo declaras la señal cuenta:

signal cuenta: unsigned (3 downto 0);

Y fuera del proceso asignas cuenta a Q:

Q <= cuenta;

Aparte, yo le pondría un reset al contador.

Si tienes más dudas, el capítulo 6 del libro Diseño de circuitos digitales con VHDL se explican los contadores.

Espero que te haya servido de ayuda

Saludos
 
Atrás
Arriba