Puede crear tantos relojes como desee, y puede usar PLL o DCM para crear relojes arbitrarios. La pregunta es si lo necesita o si debería hacerlo de otra manera.
Encuentro que termino ejecutando tanta lógica en una frecuencia de reloj común o "central", digamos los 54MHz que estás usando, pero necesito activar ciertos procesos para que se ejecuten periódicamente. Diga una idea de rebote de 100 ms, una actualización de PWM de 10 kHz, una marca de 1s del temporizador para el reloj de pared, se le ocurre la idea. En lugar de generar estos relojes, en lugar de eso, ejecuto todo a la frecuencia central del reloj y genero señales de habilitación de reloj arbitrarias.
Por lo general, no desea crear relojes divididos por varias razones. Los relojes generados por lógica están inestables, las herramientas pueden terminar enrutando estas señales de "reloj" a lo largo de las rutas de enrutamiento destinadas a la lógica (ya que se generan a partir de la lógica) y, como se mencionó anteriormente, otros PLL y DCM son opciones mucho mejores si usted Realmente necesito generar un reloj diferente.
Reloj gating es lo que quieres. Las primitivas del dispositivo tienen una señal de habilitación de reloj adicional que "bloquea" la señal de reloj, lo que permite propagarse hacia la primitiva o no. Cuando se anula la habilitación del reloj, el FF no ve el reloj y mantiene efectivamente su estado como si el pulso del reloj nunca hubiera ocurrido. Cuando se activa la señal de habilitación del reloj, el FF ve el reloj normalmente y las cosas continúan como se espera. Las habilitaciones de reloj están diseñadas específicamente para controlar el acceso de un FF a su reloj y, como tal, no tienen problemas con la generación de relojes runt. Tampoco ocupan ningún recurso adicional, así que úsalos.
por ejemplo Generando un reloj en lógica. Esto es malo, no hagas esto:
process gen_100ms_clk (clk, rst)
variable ctr: integer range 0 to 5399999;
begin
if rst = '1' then
ctr := 0;
out <= '0';
elsif rising_edge(clk) then
if ctr = ctr'high then
out <= not out;
ctr := 0;
else
ctr := ctr + 1;
end if;
end if;
end process gen_100ms_clk;
Este código tiene el estado de alternancia de señal out
cada 100 ms; Esta señal sería una mala elección para usar como la señal de reloj de un nuevo proceso, como aquí:
process do_100ms(out, rst)
begin
if rising_edge(out) then
...
end if;
end process do_100ms;
Esto es malo porque las FF en el proceso do_100ms()
están usando una señal creada a través de la lógica en el proceso gen_100ms_clk()
.
En su lugar, use un reloj habilitar , como se muestra aquí:
process gen_100ms_ce (clk, rst)
variable ctr: integer range 0 to 5399999;
begin
if rst = '1' then
ctr := 0;
out <= '0';
elsif rising_edge(clk) then
if ctr = ctr'high then
out <= '1';
ctr := 0;
else
out <= '0';
ctr := ctr + 1;
end if;
end if;
end process gen_100ms_clk;
Ahora gen_100ms_ce()
crea una señal out
que es alta para 1T cada 100 ms. Esta es una excelente manera de indicar a su código que es hora de hacer algo:
process do_100ms(clk, rst)
begin
if rising_edge(clk) then
if out = '1' then
...
end if;
end if;
end process do_100ms;
Ahora su proceso do_100ms()
se está ejecutando en el mismo reloj de 54MHz que todo lo demás y utiliza una habilitación de reloj adecuada para activar lo que quiera que ocurra cada 100 ms.
Eche un vistazo a la salida RTL de su conjunto de herramientas; verá que la primitiva utilizada en su proceso do_100ms()
usará su señal de habilitación de reloj.
Este método también logra un ahorro de energía ya que habrá grandes franjas de lógica que permanecerán "estáticas" durante largos períodos de tiempo, aunque la red global del reloj se esté alejando a 54MHz en su caso. Una vez cada 100 ms en mi ejemplo anterior, todos los relojes que están sincronizados con la habilitación de 100 ms se activan para 1T y luego vuelven a ser estáticos durante otros 99.9999815 ms. :-) El CMOS consume muy poca energía cuando no está cambiando de estado, por lo que el único consumo de energía en la lógica con el reloj cerrado está en las corrientes de fuga de su lógica.
Puede extender esto a un medio completo de administración de energía. Usted crea habilitaciones de reloj para todos los subsistemas y su administrador de energía niega la habilitación de reloj para cualquiera de las subsecciones que no quiere que tengan alimentación.