Módulos

Divisor de frecuencia con VHDL

Figura 1: Resultado del banco de pruebas para el divisor.

En este breve artículo se describe un divisor de frecuencia con VHDL, así como el proceso mediante el cual se obtiene el factor de escalamiento deseado.

Por cierto, existe un generador de divisor de frecuencia basado en contadores basado en la información de este artículo (fase beta). Y, en caso de que necesites hacer muchos divisores de frecuencia, puedes probar la herramienta de cálculo de escalas para divisores de frecuencia para obtener los valores que necesitas en los contadores (también en fase beta).

[wpdm_file id=1]

Los cálculos

El divisor de frecuencia es un componente simple, cuyo objetivo es reducir la frecuencia de entrada. Éste se implementa con ayuda del factor de escalamiento y un contador. Primeramente, el factor de escalamiento es la relación entre la frecuencia de entrada y la frecuencia de salida deseada:

\(Escala = \dfrac{f_{entrada}}{f_{deseada}}\)

Asumiendo que tenemos una frecuencia de 50MHz y deseamos una salida de 200Hz, tenemos que:

\(Escala = \dfrac{50MHz}{200Hz} = 250 000\)

Por lo tanto, el contador para el divisor de frecuencia tiene como función generar la señal de salida de 200Hz cada 250000 ciclos.

El código

Sin más preámbulo, el Listado 1 muestra el código fuente para el divisor de frecuencia.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity clk200Hz is
    Port (
        entrada: in  STD_LOGIC;
        reset  : in  STD_LOGIC;
        salida : out STD_LOGIC
    );
end clk200Hz;

architecture Behavioral of clk200Hz is
    signal temporal: STD_LOGIC;
    signal contador: integer range 0 to 124999 := 0;
begin
    divisor_frecuencia: process (reset, entrada) begin
        if (reset = '1') then
            temporal <= '0';
            contador <= 0;
        elsif rising_edge(entrada) then
            if (contador = 124999) then
                temporal <= NOT(temporal);
                contador <= 0;
            else
                contador <= contador+1;
            end if;
        end if;
    end process;
    
    salida <= temporal;
end Behavioral;

Las líneas 1 y 2 equivalen a los #include de C/C++ o los import de Python. Entre las líneas 4 y 10 se declaran todas las entradas y salidas del sistema.

El proceso divisor_frecuencia, líneas 16 a 28, se encarga de generar la señal de 200Hz por medio de un contador de 0 a 124999. ¿Porqué 124999 y no 250000? Una señal de reloj se mantiene el mismo tiempo en alto que en bajo; para este caso en particular, 125000 ciclos en alto y 125000 ciclos en bajo. Dado que comenzamos a contar desde cero, el límite superior es 125000-1.

La señal de reset sirve para reiniciar el contador y es una señal indispensable en cualquier sistema digital.

La simulación

Con ayuda del software de Xilinx ISE (versión 13.1), se genera un test bench o banco de pruebas cuyo objetivo es demostrar la veracidad de lo que acábo de decir (una simulación). Por fortuna el software hace la mayoría de la tarea, de igual forma el código se muestra en el listado 2.

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

ENTITY clk200Hz_tb IS
END clk200Hz_tb;

ARCHITECTURE behavior OF clk200Hz_tb IS 
	COMPONENT clk200Hz
	PORT(
		entrada : IN  std_logic;
		reset   : IN  std_logic;
		salida  : OUT std_logic
	);
	END COMPONENT;

	-- Entradas
	signal entrada : std_logic := '0';
	signal reset   : std_logic := '0';
	-- Salidas
	signal salida  : std_logic;
	constant entrada_t : time := 20 ns; 
BEGIN 
	-- Instancia de la unidad bajo prueba.
	uut: clk200Hz PORT MAP (
		entrada => entrada,
		reset   => reset,
		salida  => salida
	);

	-- Definición del reloj.
	entrada_process :process
		begin
		entrada <= '0';
		wait for entrada_t / 2;
		entrada <= '1';
		wait for entrada_t / 2;
	end process;

	-- Procesamiento de estímulos.
	estimulos: process
	begin
		reset <= '1'; -- Condiciones iniciales.
		wait for 100 ns;
		reset <= '0'; -- ¡A trabajar!
        wait;
	end process;
END;

Para terminar, una imagen de los resultados de la simulación (véase la figura 1).

Figura 1: Resultado del banco de pruebas para el divisor.

Figura 1: Resultado del banco de pruebas para el divisor.

Conclusión

Este divisor de frecuencia constituye una pequeña introducción práctica al diseño de sistemas digitales con VHDL. En caso de necesitar ayuda con el diseño de algún componente mediante VHDL, no dudes en comentar :).

You Might Also Like

85 Comentarios

  • Responder
    JULIAN DAVID GUAQUETA BELTRAN
    noviembre 7, 2012 at 6:45 pm

    Buens noches ingeniero, necesito saber si puedo generar tal vez un bloque con el divisor de fercuencia que yo quiera elaborar, y si ademas de esto puedo generar varios de estos bloques

    • Responder
      Carlos Ramos
      noviembre 8, 2012 at 2:45 pm

      Gracias por el comentario, Julian. En la entrada del reloj digital utilicé este divisor de frecuencia como parte de otro sistema más grande. En la imagen se muestran dos divisores de frecuencia, uno de 1Hz y este de 200Hz, como bloques del reloj digital (enlazados mediante instrucciones PORT MAP).

  • Responder
    Cristian
    diciembre 4, 2012 at 5:16 pm

    como se inicia para comenzar la simulacion, es decir para obtener la imagen que mostro, gracias!!

    • Responder
      Carlos Ramos
      diciembre 4, 2012 at 9:50 pm

      Cristian, gracias por tu comentario :). Acabo de publicar esta pequeña guía, espero y te sirva.

      • Responder
        Adrian
        julio 13, 2014 at 11:13 pm

        hola, gracias por la explicacion, pero desearía saber cómo haría con el contador si es que la divisioón entre la entrada y salida sale impar….osea por ejemplo un 31….Como haría con eso de la mitad menos 1…..Gracias por tu respuesta

        • Responder
          Carlos Ramos
          julio 13, 2014 at 11:29 pm

          Buenas noches, Adrián,
          En la segunda parte del diseño de un metrónomo explico un poco sobre casos impares (e inexactos). Se reduce a hacer un redondeo al entero más próximo y contar, según tu ejemplo, 16 y 15 (o 15 y 16). Espero y te sirva para resolver tu pregunta.
          Saludos.

          • Adrian
            julio 14, 2014 at 12:18 am

            aquí ya son la 1am, gracias por tu tiempo enserio, mañana tengo examen. Saludos

          • Carlos Ramos
            julio 14, 2014 at 12:11 pm

            De nada, Adrián, un gusto ser de ayuda.

  • Responder
    Felipe
    marzo 18, 2013 at 3:52 pm

    Hola, muy buen aporte me gustaría saber si este divisor puede ser variable, es decir en vez de el rango de 0 a 124999 puede ser de 0 a G siendo G una variable.

    • Responder
      Carlos Ramos
      marzo 18, 2013 at 4:08 pm

      Felipe, gracias por tu comentario. Así es, se puede sustituir esa línea de forma que:

      constant G     : integer := 124999;
      signal counter : integer range 0 to G := 0;
      

      Y reemplazar el valor en un solo lugar en caso de mover la frecuencia. Sin embargo, G es una constante. En caso de querer un divisor de frecuencia variable, se necesitaría aceptar un vector de entrada que determinara el límite del contador.

      Espero haber respondido a tu pregunta.

      • Responder
        Felipe
        marzo 18, 2013 at 5:06 pm

        En caso de querer un divisor de frecuencia variable, se necesitaría aceptar un vector de entrada que determinara el límite del contador.

        Perdona mi ignorancia, pero a que te refieres o ¿cómo haces para integrar ese vector?

        • Responder
          Carlos Ramos
          marzo 18, 2013 at 5:50 pm

          En el listado 2 (líneas 9 y 21) de señal de control para servomotores con VHDL utilizó un vector de entrada pos que es empleado para generar el pulso de salida. El divisor de frecuencia variable se basaría en este mismo principio.

          Si me permites preguntar, ¿para qué utilizarás un divisor de frecuencia variable o cuántas frecuencias diferentes debes de tener?

          • Felipe
            marzo 18, 2013 at 5:55 pm

            En el área de música utilizamos un metrónomo, el cual sirve para tener diferentes frecuencias o golpes por minuto, el principio es que si tu presionas push boton la frecuencia suba o baje.

          • Felipe
            marzo 18, 2013 at 7:02 pm
            divisor_frecuencia: process (reset, entrada, U) begin
            	if (reset ='1') then 
            	temporal &lt;='0';
            	contador &lt;= 0;
            	elsif rising_edge(entrada) then
            	 if (U='1') then 
            	 
            	elsif(contador = 1249999-30490) then
                            temporal &lt;= NOT(temporal);
                            contador &lt;= 0;
            		else 
            		contador&lt;=contador+1;
            		
            		end if;
            		end if;
            	end process;
            

            En esta parte del código digamos que cuando apriete U se le restará una cantidad contantate para que disminuya la frecuencia de parpadeo de un led digamos.

    • Responder
      Carlos Ramos
      marzo 18, 2013 at 7:30 pm

      Puedo asistirte en el diseño del componente, pero sería necesario saber más acerca de la salida que necesitas. Por ejemplo, ¿cuántas o cuáles frecuencias se manejan para tu aplicación en el metrónomo? ¿están espaciadas regularmente (los incrementos entre frecuencias siempre son los mismos)?

      El propósito de las preguntas es obtener una mejor solución para tu problema. Una solución se basa en diseñar por separado un divisor para cada frecuencia y crear un módulo que realice la conmutación entre todos los relojes, lo cual es viable con pocas frecuencias. Otra posible solución es crear una señal a la cual se le sume o reste una frecuencia determinada para obtener el rango necesario (dependiendo de si están igualmente espaciadas o no).

      Como mencioné, puedo asistirte en el diseño, siempre y cuando éste no sea urgente. Podría tener el componente para el próximo fin de semana.

      Saludos, Felipe.

  • Responder
    Felipe
    marzo 18, 2013 at 7:51 pm

    Mira un metrónomo es un aparato que sirve para indicarnos cuantos pulsos por minuto vamos a tener.

    Negras por minuto
    40-43
    44-47
    48-51
    52-54
    55-65
    66-69
    70-95
    96-112
    113-120
    121-140
    141-175
    176-208
    Esta tabla nos muestra la cantidad de pulsos por así llamarlos en un minuto entonces estas frecuencias serían las que necesito 40 41 42 43 etc. pero estas son por minuto no se si te sirva un poco y muchas gracias por asistirme.

    • Responder
      Felipe
      marzo 18, 2013 at 8:03 pm

      Otra posible solución es crear una señal a la cual se le sume o reste una frecuencia determinada para obtener el rango necesario (dependiendo de si están igualmente espaciadas o no).

      Esta parte que dijiste lo trato de hacer pero no veo en donde o que parte tengo que sumar esa parte….

  • Responder
    Humberto
    mayo 5, 2013 at 3:55 pm

    Muy buena publicación ingeniero.
    Disculpe soy nuevo en esto y me gustaría saber como utilizar el divisor de frecuencia en un contador?

  • Responder
    oscar rincon
    mayo 14, 2013 at 1:29 pm

    carlos

    como estas.. quisiera consultar si este me sirve para realizar un divisor x 10…estoy realizando una flecha animada..adjunto link donde puedes verla, pero necesito propgramarla con xilinx… de antemano agradezco tu colaboracion

    oscar rincon

    • Responder
      Carlos Ramos
      mayo 14, 2013 at 8:39 pm

      Buenas noches, Oscar. No encuentro el vínculo que dices de la flecha animada. ¿Cuáles son los requisitos de tu diseño?

    • Responder
      Silvi
      mayo 31, 2017 at 10:20 pm

      buenas noxhes ingeniero, queria preguntarle, en caso que quiera aumentar la frecuencia como podria hacer? disculpe mi ignorancia. gracias por su respuesta

      • Responder
        Carlos Ramos
        junio 26, 2017 at 9:45 am

        Silvi, es cuestión de hacer los cálculos y obtener el numerito, que tendrías que sustituir en el listado 1, líneas 14 y 21. También puedes probar el generador de divisor de frecuencia (aunque sigue en versión beta). Saludos.

  • Responder
    María
    mayo 17, 2013 at 8:45 am

    Hola! Me gustaría saber qué valor tengo que darle al contador en caso de querer frecuencias de 1Hz. En teoría son 24999999 pero me da la sensación de que nunca consigue alcanzar ese valor :S
    Gracias de antemano

    • Responder
      Carlos Ramos
      mayo 17, 2013 at 9:42 pm

      Hola, María. Efectivamente, el valor a ser utilizado es el de 24,999,999. En la entrada del reloj digital hago uso de un divisor de frecuencia a 1Hz. ¿Qué frecuencia entrega la simulación de tu módulo?

  • Responder
    Diego Alfaro.
    junio 1, 2013 at 10:41 am

    Buenos días. Estoy diseñando un cronómetro digital, por tanto el factor de escalamiento saldría de dividir (50MHz/60Hz=833333,3333) y si no se ingresa ése número exacto, el cronómetro no sería preciso ¿Cómo podría solucionar esto?

    • Responder
      Carlos Ramos
      junio 2, 2013 at 12:00 am

      Diego, buenas tardes. Según he sabido, los cronómetros son hechos con cristales de mayor precisión o con la frecuencia necesaria. Por lo tanto, más que cálculos y módulos, dependen del oscilador con que se cuente. Si el cambio de oscilador no es una opción y es necesario implementar un cronómetro, se puede realizar un ligero ajuste cada determinado número de ciclos para reducir el error. Por ejemplo, si sabes que cada minuto se atrasa un segundo aproximadamente, le sumas esa cantidad tras los sesenta ciclos del reloj impreciso. Espero haberte ayudado y gracias por el comentario.

  • Responder
    esteban
    octubre 8, 2013 at 9:31 am

    Hola buen dia!! me sirvio mucho tu aporte pero tengo que hacer que el 2000 prende en los 4 displays con un divisor de frecuencias ya tengo el 2000 en un solo display pero mi pregunta es como hago para unir lo que hice con el divisor de frecuencia para que prenda en todos

    Gracias por tu atencion.

    • Responder
      Carlos Ramos
      octubre 8, 2013 at 10:31 am

      Buenos días, Esteban. No estoy seguro si esta entrada sirva a tus propósitos o entendí mal lo que deseas hacer. Saludos.

  • Responder
    Stivens
    octubre 14, 2013 at 1:01 pm

    Buena tarde estimado, resulta que me parece muy interesante el trabajo que realizaste en este post, sin embargo me queda una duda, vi por ahí que alguien te escribía sobre una frecuencia que no tenia un periodo exacto y por ende tenia problemas para obtener la frecuencia precisa. Tengo ese mismo detalle, a partir de una frecuencia de 50MHz debo obtener una de 3MHz, mi contador tendría que generar esos 3MHz cada 16.66666667 ciclos, cosa que tengo entendido no se puede hacer, la sugerencia de mi profesor fue aproximar este valor a 17 y luego tomar la señal de 0 durante 8 y la señal de 1 durante 9, para alcanzar estos 17 ciclos. Te parece que este bien hacer esto? Como podría hacer estas alternaciones? Agrego que este divisor de frecuencia no se usara en nada mas, solo es parte de un ejercicio de laboratorio que luego se probara sobre una Basys2. Gracias.

    • Responder
      Carlos Ramos
      octubre 15, 2013 at 5:43 pm

      Buenas tardes, Stivens, y gracias por plantear tan interesante pregunta. Para el divisor de frecuencia implementado en esta entrada asumí que el tiempo en alto y el tiempo en bajo era el mismo, cosa que se cumple para los osciladores naturales como el cristal de cuarzo. Sin embargo, en el diseño de circuitos digitales no es necesario apegarnos a tal principio y, como se menciona en Digital VLSI Systems Design, se puede crear un divisor de frecuencia con tiempos en alto y en bajo totalmente diferentes. Por lo tanto, tu divisor de frecuencia se puede implementar con dos contadores: el primero, de 0 a 17, que corresponde al tiempo total del ciclo; y el segundo, de 0 a X (puede ser ocho como mencionas), donde la primera parte estaría en alto y la segunda en bajo, con lo cual tendrías un divisor de frecuencia totalmente válido.

  • Responder
    Juan
    octubre 20, 2013 at 10:26 pm

    hola buenas noches, si necesito hacer un modulo que permita dividir la frecuencia de entrada de la FPGA en cualquier valor, y ademas permitir que ese valor sea parametrizables, como podria hacerlo

    Gracias

    • Responder
      Carlos Ramos
      octubre 22, 2013 at 10:42 am

      Buenos días, Juan. En caso de que necesites un divisor de frecuencia para cualquier valor será necesario declarar una entrada más para recibir el valor máximo del contador (en lugar de estar declarado como una constante dentro del módulo). Aún así, es necesario recordar que no puedes obtener cualquier valor de frecuencia, es decir, no puedes obtener una frecuencia de un reloj de 40MHz a partir de un reloj de 50MHz debido a que un simple contador de 0 a 1 divide la frecuencia entre dos (de 50MHZ a 25MHz).

  • Responder
    hanibal
    octubre 26, 2013 at 11:17 am

    Ingeniero muchas gracias por el aporte.
    Tengo una inquietud si deseo obtener una frecuencia de 100MHz la puedo obtener de una frecuencia de entrada de 50MHz, o debo modificar esta frecuencia de entrada; si es asi como lo puedo hacer?.

    Muchas gracias

    • Responder
      Carlos Ramos
      octubre 27, 2013 at 2:44 pm

      Buenas tardes, Hanibal. En caso de que trabajes con Xilinx puedes utilizar el componente Digital Clock Management (DCM), como se menciona en el , para hacer un multiplicador de frecuencia como el que deseas.

  • Responder
    bryan
    noviembre 26, 2013 at 6:59 pm

    muy buenas noches Ingeniero, para felicitarlo por su pagina muy interesante y util, con la pregunta si este divisor de frecuencia es general es decir lo puedo utilizar para obtener cualquier frecuencia deseada, solo bastaria con cabiar los valores establecidos en el codigo, sino me equiboco 50Mhz es la señal de clk que puede entregar una Espartan 3E, y yo deseo un señal de 1Khz bastaria con reemplazar el (124999) por el (24999) agradesco de ante mmano su ayuda.

    • Responder
      Carlos Ramos
      diciembre 4, 2013 at 7:25 pm

      Buenas noches, Bryan. Respecto a tu pregunta, sí pero no. Es decir, puedes obtener una frecuencia menor siempre y cuando el contador lo permita. Por ejemplo, no puedes obtener una frecuencia de 35 MHz a partir de un reloj de 50MHz debido a que el contador trabaja únicamente con números enteros (lo que da la frecuencia de 25MHz al contar hasta 2 en lugar de 1.4285). Quizá la herramienta generador de divisor de frecuencia en base a contadores te sea de utilidad. Saludos.

  • Responder
    Luis
    diciembre 1, 2013 at 4:18 pm

    disculpe, quisiera saber si hay una forma para nosotros poder darle una frecuencia deseada, esto con el fin de que en la salida sea de diferente escala

  • Responder
    Juan RC
    diciembre 10, 2013 at 7:05 pm

    Gracias me ayudó mucho este artículo. Yo utilizo el programa Max Plus II para VHDL. Qué programa utiliza Ud?

    • Responder
      Carlos Ramos
      diciembre 11, 2013 at 11:25 pm

      Buenas noches, Juan. Como principalmente utilizó la tarjeta Basys2, el programa que utilizo es el ISE WebPACK Design Suite. Sin embargo, recientemente llegó a mis manos una tarjeta DE2-115, por lo que empezaré a utilizar también Quartus II. Saludos.

  • Responder
    David Castiblanco
    febrero 27, 2014 at 2:55 pm

    buenas tardes, una pregunta para sumar frecuencias ¿Cómo se podría hacer?
    se podría guardar una frecuencia en una variable al igual que otras
    y se podrían sumar ??

    es que es para generar una frecuencia con su 1 y 3 armónico
    muchas gracias.

    • Responder
      Carlos Ramos
      marzo 4, 2014 at 8:46 pm

      Buenas tardes, David, ¿podrías hablarme más acerca de este proyecto? Suena bastante interesante, aunque no estoy muy seguro de comprender el funcionamiento o aplicación. Cualquier referencia al respecto será agradecida :).

  • Responder
    Felix
    marzo 25, 2014 at 12:05 pm

    Hola Ingeniero primero que nada muy buen aporte que ha publicado me sirvió de mucho, gracias.
    Ingeniero una pregunta lo que pasa es que con el divisor de frecuencia como podria agregar varios divisores de frecuencia en un mismo codigo con 3 switches ya sea que al momento de seleccionar con la entrada de los switch 000 me de una frecuencia de 4 hz de un altera de 50 MHz y al dar como como entrada 001 me de una salida de 2 Hz??? saludos, espero se respuesta

    • Responder
      Carlos Ramos
      marzo 27, 2014 at 10:09 pm

      Buenas tardes, Felix. Me agrada saber que esta entrada te ha sido de ayuda. Debido a que el sistema sería de solamente dos frecuencias (o muy pocas frecuencias distintas), se puede realizar un módulo por cada una de ellas. Posteriormente, se puede utilizar un multiplexor para seleccionar cuál de todos los módulos dará la salida (ya sea de 2 o 4 Hz, o cualquier otra frecuencia).
      Otra posible solución sería, en caso de que necesites 8 frecuencias diferentes reduciendo la escala en un factor de dos cada vez, enviar el límite superior (enviar un vector en lugar de utilizar la constante 124999). Aunque para esto es necesario obtener los datos de cada uno de los rangos de los contadores para ver una forma de minimizar los datos o tamaño de vectores utilizados.
      Si gustas puedes mandarme más detalles acerca de tu proyecto a carlos@estadofinito.com. Saludos.

  • Responder
    Danie
    marzo 30, 2014 at 5:46 pm

    Buenas tardes ingeniero necesito crear un divisor de frecuencia variable es decir de 50 Mhz que maneja la tarjeta Altera necesito reducir esa frecuencia a 4, 2, 1 ,0.25. 0.125, 0.0625 y 0 Hz, anexo el código me podría orientar si es correcto esto que hice.
    Este divisor de frecuencia lo quiero para mostrar un contador de números y con os slide switchs variar la frecuencia de la transicion de los números. Espero su respuesta,

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;

    entity divisor is
    port (
    x: in std_logic_vector(2 downto 0);
    reset : in STD_LOGIC;
    clk: in STD_LOGIC;
    salida : out STD_LOGIC
    );
    end divisor;

    architecture arq_divisor of divisor is
    signal temporal: STD_LOGIC;
    signal contador: integer range 0 to 399999999:= 0;
    begin
    divisor_frecuencia: process (reset, clk)
    begin
    if (reset = ‘1’) then
    temporal <= '0';
    contador
    if (contador = 6249999) then
    temporal <= NOT(temporal);
    contador <= 0;
    else
    contador
    if (contador = 12499999) then
    temporal <= NOT(temporal);
    contador <= 0;
    else
    contador
    if (contador = 24999999) then
    temporal <= NOT(temporal);
    contador <= 0;
    else
    contador
    if (contador = 49999999) then
    temporal <= NOT(temporal);
    contador <= 0;
    else
    contador
    if (contador = 99999999) then
    temporal <= NOT(temporal);
    contador <= 0;
    else
    contador
    if (contador = 199999999) then
    temporal <= NOT(temporal);
    contador <= 0;
    else
    contador
    if (contador = 399999999) then
    temporal <= NOT(temporal);
    contador <= 0;
    else
    contador contador <= 0000000; –no se que numero deba ir para que de 0 Hz la salida
    end case;
    end if;
    end process;
    salida <= temporal;
    end arq_divisor;

    • Responder
      Carlos Ramos
      abril 13, 2014 at 4:35 am

      Buenas tardes, Danie. Aunque un tanto más laborioso, realicé este proyecto creando un divisor de frecuencia para cada una de las frecuencias necesarias, uniéndolo todo finalmente con un multiplexor de ocho a uno. El código se encuentra en Multiplexor de frecuencias, mismo que dejo a tu disposición.

  • Responder
    Carlos
    mayo 28, 2014 at 4:12 am

    Hola, ¿cómo harías este ejercicio?

    Describir un circuito que genere un señal PWM de una freqüencia fija aproxima de 1Khz i un ciclo de trabajo correspondiere a un valor digital de 8 bits que proviene de un puerto de entrada del dispositivo. Se dispone de una señale clk de 50 Mhz.

  • Responder
    Brian Eduardo
    julio 18, 2014 at 6:36 am

    Carlos gracias por el post 😀

    tengo una duda si tengo mi Flip flop

    process (clk)
    begin
    if clk’event and clk=’1′ then
    if reset=’1′ then
    Q_bus <= Apagado;
    else
    Q_bus <= D_bus;
    end if;
    end if;
    end process;

    Siendo Q_bus y D_bus la salida y la entrada de mi flip flop respectivamente.
    como implementaria la parte del divisor de frecuencia a este codigo? muchas gracias..

    • Responder
      Carlos Ramos
      julio 18, 2014 at 9:12 pm

      Hola, Brian Eduardo,
      Dentro del código del divisor de frecuencia ya se incluye el flip-flop, que corresponde a la señal temporal. Una forma de incluir otro flip-flop sería pasando la señal temporal a través de tu flip flop (como la entrada D_bus) y posteriormente mandar Q_bus a salida.
      No sé si eso cumpla con tus requisitos, ¿qué es lo que necesitas realizar exactamente?
      Saludos.

  • Responder
    guillermo
    julio 21, 2014 at 7:49 pm

    Hola ,como puedo hacer hacer un barrel shifter de 16bits ,con el ISEwebpack y cargar los datos y control en 3 registros dos para cargar los datos (ya que el picoblaze es de 8bits) y otro para los modos de operacion ,esto se va probar en una nexiys2 con spartan3e que trabaja con 50mhz , tengo dificultad para enlazar las partes .

    • Responder
      Carlos Ramos
      julio 24, 2014 at 3:18 pm

      Buenas tardes, Guillermo. Lamentablemente no he trabajado con PicoBlaze, u otros soft-cores de la compañía de Xilinx, por lo que no te podría auxiliar realmente en la tarea que debes realizar. Saludos.

  • Responder
    José
    octubre 11, 2014 at 11:20 pm

    Hola qué tal Carlos, tu artículo me lo encontré mientras buscaba cómo diseñar un divisor de frecuencia en VHDL. Mi pregunta es la siguiente ¿Cómo puedo diseñar un divisor de frecuencia, si tan sólo me dicen que trabaja a 50 MHz, pero no me dan la frecuencia de salida para la escala, y trabaja 5 segundo para la tarjeta que voy a implementar el divisor (Spartan 3)?

    • Responder
      Carlos Ramos
      octubre 14, 2014 at 9:16 am

      Hola, José. Si trabaja a cinco segundos esa será la frecuencia de salida (o eso se infiere). En ese caso, la frecuencia de salida sería de
      \[f = \frac{1}{t} = \frac{1}{5} = 0.2 Hz = 200 mHz \]
      Lo que se puede realizar en este caso son varios divisores. Por ejemplo, para reducir la frecuencia a 200Hz y luego de 200Hz a 200mHz. Si lo intentas hacer directo quizá el factor de escalamiento sea muy grande. Además, ya a tan bajas frecuencias me he visto en algunos problemas en esas tarjetas debido a que, por alguna razón, no respetan la frecuencia de salida (aunque la simulación si da la frecuencia deseada). Saludos, José.

    • Responder
      guillermo
      octubre 14, 2014 at 5:04 pm

      Hola Pablo , el problema surgio cuando tuve que hacer un barrel shifter de 16bits en vhdl ,hice la programacion del mismo como una entidad ,y funcionaba con todo lo que me pedian salvo que no lo hacia en un ciclo de clock ,,funcionaba cerca de los 300mhz ,si hubiera utilizado una spartan 6 que funcionan mas o menos a esa frecuencia no hubiera tenido problema pero la spartan 3 anda a 50mhz ,por eso queria crear una entidad que lleve mi clock de 50mhz a 300mhz (pll en vhdl) ,en realidad tenia que haber diseñado el hardware en base a mux conectados en paralelo pero no sabia como hacerlo por eso fue mi consulta .

      carlos elli

  • Responder
    Andry
    noviembre 6, 2014 at 1:57 am

    Hola, descargué el código divisor de frecuencia de 200Hz pero al simularlo la salida se mantiene en cero, tiene algo que ver si uso el ISIM en modo lite?. Usé la versión Ise web design 13.4.

    • Responder
      Carlos Ramos
      noviembre 11, 2014 at 9:39 pm

      Hola, Andry. Ha decir verdad, en algunas ocasiones la simulación me da en ceros, o en valores no definidos. La causa es el simulador, aunque hasta la fecha no he sabido la causa. De repente, al pasar los días, resulta que la simulación “ya funciona”. Si puedes llegar a la solución concreta sería una gran ayuda. Saludos.

  • Responder
    Jhon Dairo Meche Tenza
    noviembre 21, 2014 at 12:02 pm

    Buenas tardes ingeniero, gracias por el aporte del control del servo motor, el problema que tengo es que no eh podido lograr que el servo se mantenga a la izquierda durante un determinada tiempo y luego regrese a la pocision central, como me aconsejaría que lo hiciese, muchas gracias.

    • Responder
      Carlos Ramos
      noviembre 21, 2014 at 4:51 pm

      Buenas tardes, Dairo. ¿Qué es lo que planteas? ¿que el servo se mantenga en una posición durante un tiempo fijo y luego regrese al centro y vuelva a repetir la operación? Si puedes brindarme más detalles sobre lo que debe hacerse, quizá pueda ayudarte. Saludos.

  • Responder
    MARIO LOPEZ
    noviembre 22, 2014 at 8:42 pm

    QUE TAL BUENAS NOCHES UNA PREGUNTA, COMO QUEDARIA EL CODIGO PARA GENERAR UN PWM DE 100HZ, PARA EL CUAL SE TIENE Q GENERAR UN PULSO AUMENYTE DE 5 EN 5 %
    TENIENDO COMO LIMITE SUPERIOR 95 E INFERIOR 5

    Y PARA EL CUAL LA SALIDA O LA FRECUENCIA SE DEBE MOSTRAR EN UN DISPLAY

  • Responder
    nery
    marzo 7, 2015 at 9:17 pm

    buenas ingeniero queria saber si me podria dar una idea como conectar un fpga con un adc mcp3002

    • Responder
      Carlos Ramos
      marzo 8, 2015 at 12:14 am

      Nery, según la hoja de datos del fabricante, el ADC MCP3002 usa SPI. En Open Cores puedes encontrar algunos cores para tratar con SPI. Espero te sirva como punto de inicio.

      • Responder
        nery
        marzo 9, 2015 at 12:08 am

        Le agradezco ingeniero.
        Me podría ayudar con el código VHDL

        • Responder
          Carlos Ramos
          marzo 12, 2015 at 12:17 am

          Nery, de momento me encuentro ocupado con proyctos fuera del blog. No obstante, espero que en Open Cores hayas encontrado una buena referencia. Quizá otros proyectos de ayuda se encuentren en GitHub. Saludos.

  • Responder
    Daniel
    marzo 9, 2015 at 7:06 am

    A que puertos de la Nexys3 asignas tus variables ??

    • Responder
      Carlos Ramos
      marzo 12, 2015 at 12:12 am

      Hola, Daniel. En este proyecto no trabajo con una Nexys3, sino con una tarjeta Basys2, y no creo que te sirva de mucho saber los puertos. Saludos.

  • Responder
    Anayeli
    marzo 19, 2015 at 9:43 pm

    Hola que tal! Soy algo nueva en esto y la verdad que quiero empezar comprendiendo todo y tengo la duda como determina el numero que debe contener el contador??

    • Responder
      Carlos Ramos
      marzo 20, 2015 at 1:13 am

      Hola, Anayeli. Se hace en tres pasos:

      1. Obtienes la escala necesaria: \[ Escala = \frac{f_{entrada}}{f_{deseada}} \]
      2. Una vez que tienes ese numerito, lo divides entre dos (mitad en alto, mitad en bajo): \[ ciclos_{alto} = \frac{Escala}{2} \]
      3. Finalmente, restas uno (las operaciones inician desde el cero): \[ contador_{alto} = ciclos_{alto} – 1 \]

      Saludos.

  • Responder
    Gustavo Andres Vivar Ramon
    enero 14, 2016 at 7:30 am

    Ingeniero, saludos, estoy realizando una práctica para la universidad, se trata de un frecuencímetro, mi duda es si este método del divisor de frecuencia puedo usar para realizarla.

    • Responder
      Carlos Ramos
      noviembre 14, 2016 at 11:50 am

      Hmm, más bien, necesitas la frecuencia más alta posible, y contar las veces en alto y las veces en bajo. Es un concepto similar, sí, aunque aplicado diferente.

  • Responder
    OG
    agosto 9, 2016 at 11:54 am

    ¿Cómo se le indica en Quartus, que mi placa o tarjeta electrónica utilice el reloj de 50 MHz que se incluye?

    • Responder
      Carlos Ramos
      septiembre 26, 2016 at 1:32 pm

      En el archivo de implementación, asigna el pin del reloj interno de tu tarjeta a la entrada del componente. Saludos.

  • Responder
    Alex
    septiembre 29, 2016 at 5:31 pm

    Hola buen día! Mi duda es cómo podría generar una señal asimétrica de 1Hz con $$duty cycle=\frac{20ns}{1seg}$$ de salida. Gracias.

    • Responder
      Carlos Ramos
      septiembre 29, 2016 at 9:33 pm

      Hmm. Alex, si no interpreto mal tu pregunta, me parece que la entrada sobre señal de control para servomotores te puede ser de ayuda.
      Otra posible entrada que te puede ayudar es la revisión del divisor de frecuencia para el metrónomo, donde se expone el caso con implementación impar (puedes poner un número que indique el tiempo en bajo y utilizar el otro número para el tiempo en bajo).

      • Responder
        Alex
        septiembre 30, 2016 at 7:44 pm

        Mmm no, no es eso, solo necesito hacer una simulación, dividir las señal de,50Mhz en una señal que se mantenga en alto un ciclo y los otros 49999999 en bajo, pero no logro hacerlo. Saludos

  • Responder
    gregorio arellano marin
    mayo 23, 2017 at 7:55 pm

    como puedo elegir un divisor de frecuencias para cierta bocina en que se basan para conectar un divisor., por ejemplo un na bocina woofer de 600 wats de que tamaño seria su divisor

  • Responder
    gregorio arellano marin
    mayo 23, 2017 at 7:57 pm

    como puedo elegir el divisor de frecuencias adecuado para un woofer de 600 wats, de que tamaño
    tiene que ser el divisor para ese woofer

  • Responder
    Luis pablo
    julio 24, 2017 at 12:20 pm

    Hola, me podtia decir como quedsrian los puertos de salida? Y si quiero mostrar la frecuencia con un led. Esta frec podria ser detectada por el ojo humano

  • Responder
    alex castro
    diciembre 10, 2017 at 12:09 am

    exelente la info,, no entendí bien el uso de la compuerta NOT en la linea 22 , (si el contador llega a 124999 (su tope), entonces TEMPORAL vale uno? temporal es el rising edge de mi nueva frecuencia?

    • Responder
      Carlos Ramos
      diciembre 11, 2017 at 12:58 pm

      Hola, Alex. Lo que pasa es que nuestra señal de reloj va de 0 a 1, y 1 a 0, y necesitamos cambiar su valor cada vez que se llega al límite.
      Es decir, cada vez que llegue al tope (124,999), si está en 1 va a 0. O, si está en 0, va a 1. Por lo tanto, utilizamos la compuerta NOT para cambiar el valor actual de nuestra señal.
      También podríamos decir que del 0 a 124,999 es 0, y del 125,000 a 249,999 es un 1, aunque me parece más fácil invertir el valor de la señal cada vez que se llegue al tope (independientemente de cuál sea su valor actual).
      Espero no haberte confundido más. Saludos.

  • Responder
    Sabino Cayo
    junio 28, 2018 at 12:07 pm

    Hola ingeniero, tengo que realizar un proyecto de grabar mi voz, y que se digitalize y luego se reproduzca. Mi duda es si puedo generar un clock de 80KHz con la fpga basys

    • Responder
      Carlos Ramos
      junio 28, 2018 at 10:30 pm

      Hola, Sabino. Siguiendo la metodología aquí descrita considero que sí es posible realizar el reloj de 80 KHz, y parece que de forma exacta, pues la escala quedaría en 625, haciendo un contador impar. Saludos.

  • Responder
    Andrés Fernández
    noviembre 13, 2019 at 10:33 am

    Hola, buen día. Disculpa, en este divisor, el contador llega hasta el valor del factor de escalamiento /2, pero en otros ejemplos, como el divisor de 64kHz le contador llega sólo al mismo valor del factor de escalamiento, sin dividirse entre dos. ¿A qué se debe esto?

  • Deja tu comentario