reloj en el banco de pruebas VHDL

1

Estoy usando GHDL. Después de varias actualizaciones de este hilo, bajo consejo, trato de hacer la configuración más simple de un banco de pruebas con solo una señal de reloj. El código se compila correctamente, pero cuando lo ejecuto (comando: ghdl -r entity_name) se atasca. Aquí está el código:

library ieee;

use ieee.std_logic_1164.all;

 --  A testbench has no ports.
 entity clock is
 generic (   
            clk_period : time := 2 ns -- per le tempistiche
        ); 
 end clock;



architecture clock_0 of clock is    

signal clock : std_logic := '0' ;

 begin



-- clock generation

    --process_clock : process


            --begin


            clock<=NOT clock after clk_period/2;


        --  end process;



        end clock_0;
    
pregunta Daniele

2 respuestas

2

En primer lugar, tenga en cuenta que todos los procesos se ejecutan simultáneamente entre sí. Por lo tanto, para tener un reloj que maneje sus otros procesos, usted quiere que su código esté en su propio proceso. El código dentro del proceso se ejecuta de forma secuencial, y así es como puede generar una señal de reloj con un período específico (utilizando declaraciones de 'espera'). Se ejecutará un proceso con una lista de sensibilidad siempre que cambie una de estas señales. Sin embargo, un proceso sin lista de sensibilidad siempre se estará ejecutando. Depende de usted decidir cuándo se ejecuta. Aquí es donde las declaraciones de "espera" son útiles. Como nota al margen, no puede usar declaraciones de 'espera' en un proceso con una lista de sensibilidad.

Puede implementar un simple flip-flop usando cualquiera de los dos códigos a continuación.

process (clk) is
begin
    if clk = '1' then
        Q<=D;
    end if;
end process;


process is
begin
    wait until clk = '1' and clk'event;
    Q<=D;
end process;

Observe cómo en un diseño, el proceso solo se inicia cuando hay un evento en clk, donde luego verifica el nivel. El segundo proceso se ejecuta de forma continua, pero espera un evento y un nivel alto.

Ahora, estos procesos dependen del reloj. Para simular un reloj, solo queremos que el reloj dependa de la hora. Después de la mitad del período queremos cambiar el nivel. Por lo tanto, tiene un proceso sin lista de sensibilidad y las instrucciones de espera esperan un cierto tiempo antes de cambiar el nivel del reloj.

Espero que ayude!

Nota: La sintaxis puede estar ligeramente apagada en esos ejemplos, ha pasado un tiempo desde que generé cualquier código ...

    
respondido por el Andrew
1

Para la generación de reloj concurrente, no olvides inicializar el reloj (falta en tu código y no funcionará sin él).

signal clock : std_logic := '0' ;

clock<=NOT clock AFTER clk_period/2;

¿Por qué funciona? Todas las asignaciones simultáneas se pueden convertir a un proceso equivalente extrayendo todas las señales en el lado derecho (y seleccione la expresión) y agregándolas a una lista de sensibilidad del proceso. Por lo tanto, su código anterior se convierte en:

process(clock)
begin
  clock<=NOT clock AFTER clk_period/2;
end process ;

Yendo más allá, todos los procesos se ejecutan en su totalidad durante la inicialización (fase de ejecución del ciclo 0 delta). Por lo tanto, este proceso proyecta que el reloj cambie a 1 después de la mitad del período de reloj. Cuando el nuevo valor se coloca en el reloj, el proceso se ejecuta de nuevo y programa el valor opuesto un período de medio reloj más tarde. Uno de cada cambio de reloj, el proceso (juego de palabras previsto) se repite.

Para su reloj basado en procesos:

clk_process : process
   begin
        clk <= '0';
        wait for clk_period/2;  --for 0.5 ns signal is '0'.
        clk <= '1';
        wait for clk_period/2;  --for next 0.5 ns signal is '1'.
   end process;

Esperar es simplemente un medio de control de ejecución de procesos. El proceso se ejecuta hasta una instrucción de espera, se suspende hasta que la instrucción de espera indica que se activa y luego se reanuda. Cuando llega al final, simplemente se reanuda en la parte superior del proceso hasta que llega a la siguiente declaración de espera.

Para ayudarlo a entender por qué esto se repite, considere el siguiente proceso:

process(Sel, A, B) 
begin
  case Sel is 
    when '0' => Y <= A ; 
    when '1' => Y <= B ; 
    when others => Y <= (others => 'X') ; 
  end case ; 
end process ; 

La forma en que el lenguaje se ejecuta puede describirse mediante el siguiente proceso con una instrucción de espera. La espera se encuentra al final del proceso porque durante la inicialización, el proceso con una lista de sensibilidad se ejecuta una vez.

process 
begin
  case Sel is 
    when '0' => Y <= A ; 
    when '1' => Y <= B ; 
    when others => Y <= (others => 'X') ; 
  end case ; 
  wait on Sel, A, B ; 
end process ; 

Por lo tanto, todos los procesos forman un bucle natural. Para evitar el bucle, necesita una instrucción de espera similar a la que hizo en el proceso de datos.

Si bien su proceso de datos puede ser correcto, recomiendo mejorar la legibilidad mediante el uso de un bucle en lugar de la naturaleza en bucle de un proceso:

data_process : process
    variable timedata : time;
begin
  for i in 1 to 100 loop 
    timedata := i*clk_period;
    data <= not data;
    wait for timedata;
    data <= not data;
    -- just added the following wait. 
    -- With out it, the previous assignment to data is meaningless.
    wait for timedata;  
  end loop ;

  std.env.stop ;  -- stop the testbench
  wait ; 
end process;
    
respondido por el Jim Lewis

Lea otras preguntas en las etiquetas