Divide la frecuencia del reloj por 5 en VHDL

Quiero dividir la frecuencia del reloj entre 5. ¿Puedo hacerlo con un tipo entero o necesito algo más para ejecutar el número decimal?

library ieee;
use ieee.std_logic_1164.all;
use IEEE.NUMERIC_STD.ALL;

entity divide_clk is
port( clk: in std_logic;
 clk_out: out std_logic);
end divide_clk;

 architecture behave of divide_clk is
signal count: integer range 0 to 24999999:= 0;
signal temp : std_logic := '0';
begin
process(clk)
begin
if (clk'event and clk='1') then
 if (count = 2.5) then
 temp <= not(temp);
 count <= 0;
 else
 count <= count + 1;
 end if;
end if;
end process;
clk_out <= temp;
end behave; 
Supongo que el código es solo un ejemplo aproximado de lo que quieres lograr. ¿O cómo esperas countllegar a ser 2.5?
Primero averigüe cómo construiría esto con puertas y otros bloques de construcción. Luego descubra cómo expresar ese diseño en HDL.
¿Qué piensas hacer con la señal del reloj? ¿Lógica de conducción? ¿Conducir un pin de salida?
No estoy de acuerdo con los comentarios anteriores. Nunca debe pensar en puertas al escribir VHDL, simplemente no superará a los sintetizadores contemporáneos. Describa el comportamiento que desea a nivel de un ciclo de reloj y deje que las herramientas hagan el resto.
@DonFusili, no está de acuerdo con un punto diferente al que ThePhoton está haciendo correctamente. El circuito lógico final es lo que importa. Entonces, averigüe qué se puede hacer realmente para dividir un reloj por 5 usando lógica combinatoria y flip-flops: piense en lógica digital. Comprende lo que es posible y lo que no. No se limite a escribir VHDL lista de deseos. Photon no significa 'por qué no diseñarlo usando puertas lógicas'. Excelente consejo: ten siempre una idea de cómo será tu circuito a grandes rasgos. Esencial en un buen diseño, evita grandes contadores accidentales, muxes, etc. que retrasan el tiempo y consumen muchas puertas.
@TonyM Entendí el punto, todavía no estoy de acuerdo.
@DonFusili, claro, aunque no sé por qué, o por qué es un buen método. Si tiene una respuesta, a la luz de mis comentarios, me interesaría escucharla. Siéntase libre de configurar un chat si prefiere no tener una discusión aquí, gracias.

Respuestas (2)

Si desea generar un reloj dividido del ciclo de trabajo al 50% en VHDL, usando solo el borde ascendente del reloj, el período del reloj dividido debe ser múltiplo de 2. Dado que 5 es un número impar, también debe usar el borde descendente del reloj principal. . Debe generar dos relojes de ciclo de trabajo de 2/5 desplazados por medio período del reloj principal. Luego puede "O" para obtener el reloj requerido que es de 1/5 de frecuencia y 50% de ciclo de trabajo.

Algo como esto:

ingrese la descripción de la imagen aquí

Ejemplo de código:

architecture Behavioral of divide_by_5_counter is
signal a,b : STD_LOGIC;
signal count_a, count_b : STD_LOGIC_VECTOR(3 DOWNTO 0);
begin

process(clk_in,reset)
begin
if reset = '1' then
a <= '0';
elsif rising_edge(clk_in) then
if count_a = 5 then
count_a <= "0001";
a <= '1';
elsif count_a >= 2 then
a <= '0';
count_a <= count_a + 1;
else
a <= '1';
count_a <= count_a + 1;
end if;
end if;
end process;

process(clk_in,reset)
begin
if reset = '1' then
b <= '0';
count_b <= "0000";
elsif falling_edge(clk_in) then
if count_b = 5 then
count_b <= "0001";
b <= '1';
elsif count_b >= 2 then
b <= '0';
count_b <= count_b + 1;
else
b <= '1';
count_b <= count_b + 1;
end if;
end if;
end process;

clk_out <= a or b;

end Behavioral;
¿Se admite la combinación de flanco descendente y ascendente en un diseño? (No estoy descartando su respuesta...) En el diseño de ASIC, nuestra gente de back-end se quejaría amargamente, pero tal vez algunos/la mayoría de los FPGA lo permitan. Entiendo CTS, celdas y fracasos y no veo ninguna objeción en principio, por supuesto.
@ P2000 Es compatible con FPGA, pero ningún buen diseñador combina ambos bordes en un diseño real debido a la complejidad del tiempo y el consumo de energía (cierto tanto para FPGA como para ASIC). Entonces, el código anterior sería simplemente "académico". Si realmente desea obtener relaciones de reloj complicadas, lo que diría es usar IP dedicadas.

Trabajando únicamente en los flancos ascendentes de su reloj original, no podrá obtener un ciclo de trabajo del 50%. Muchos circuitos no requieren esto, porque la mayoría de la lógica digital está diseñada para funcionar solo en flancos ascendentes o descendentes. En ese caso, puedes optar por algo como esto:

p_main: process(clk, reset_n)
    variable r_count : integer range 0 to 4;
    variable r_clk_out_i : std_logic;
begin

  if reset_n = '0' then
    r_clk_out_i := '0';
    r_count := 0;
  elsif rising_edge(clk) then
    if r_count = 0 or r_count = 2 then
      r_clk_out_i := not r_clk_out_i;
    end if;

    if r_count = 4 then
      r_count = 0;
    else
      r_count = r_count+1;
    end if;

  end if;
  clk_out <= r_clk_out_i;

end process;

Si necesita un ciclo de trabajo del 50 %, deberá cambiar la fase de su reloj original o también trabajar en los flancos descendentes de su reloj original.

Si se necesita un ciclo de trabajo preciso del 50 %, es mejor usar la doble frecuencia y dividir primero por 5 y luego por 2. El uso de flancos ascendentes y descendentes del reloj original requiere un ciclo de trabajo del 50 % del reloj original.
@Uwe De acuerdo, pero eso supone que tiene acceso a la frecuencia del reloj doble y luego puede dividir por 10 en un solo paso, lo cual es sencillo e inmediatamente da el ciclo de trabajo del 50%.
No todos los métodos posibles para dividir un reloj por 10 en un solo paso garantizan un ciclo de trabajo del 50 % en la salida.
@Uwe No, pero lo sencillo de contar los flancos ascendentes del reloj y cambiar la polaridad de su reloj de salida en cada quinto ciclo sí lo hace. Todavía no he encontrado un entorno en el que no pueda encajar un contador de 3 bits para hacer esta estrategia. Estoy seguro de que sí, así que, según todos los informes, continúe y escriba su propia respuesta que tenga en cuenta sus propios comentarios. No estoy calificado para ponerlos en mi respuesta ya que no puedo imaginar los escenarios en los que se aplicarían sus comentarios.
Si se utiliza un contador de 4 bits y alguna lógica adicional para contar en la secuencia 0-1-2-3-4-5-6-7-8-9-0-1..., el MSB de este contador tiene 1 /10 de la frecuencia de reloj y un ciclo de trabajo de 80 a 20 %.
@Uwe Claro, y si esta fuera todavía la edad de piedra de los circuitos integrados, su solución sería relevante. Con casi todas las tecnologías contemporáneas, puede contar hasta 5 e invertir su reloj de salida. Que es lo que ya he dicho en mi anterior respuesta a tu comentario. Dado que pareces decidido a encontrar algo que haga que los hacks relevantes en los años 90 parezcan importantes en 2018, dejaré de responder a menos que digas algo de valor, si no te importa.