Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Industrial programming >> Verilog

Generador de reloj Verilog

Los relojes son fundamentales para construir circuitos digitales, ya que permiten sincronizar diferentes bloques entre sí.

Propiedades de un reloj

Las propiedades clave de un reloj digital son su frecuencia que determina el período de reloj , su ciclo de trabajo y la fase del reloj en relación con otros relojes.

Período de reloj

La frecuencia indica cuántos ciclos se pueden encontrar en un determinado período de tiempo. Y, por lo tanto, el período del reloj es el tiempo necesario para completar 1 ciclo.

Ciclo de trabajo del reloj

La cantidad de tiempo que el reloj está alto en comparación con su período de tiempo define el ciclo de trabajo.

Fase de reloj

Si un ciclo de un reloj se puede ver como un círculo completo con 360 grados, otro reloj se puede colocar relativamente en un lugar diferente en el círculo que ocupa una fase diferente. Por ejemplo, se puede decir que otro reloj del mismo período de tiempo que se desplaza a la derecha 1/4 de su período tiene una diferencia de fase de 90 grados.

Generador de reloj Verilog

Se requiere que las simulaciones operen en una escala de tiempo dada que tiene una precisión limitada según lo especificado por la directiva de escala de tiempo. Por lo tanto, es importante que la precisión de la escala de tiempo sea lo suficientemente buena para representar un período de reloj. Por ejemplo, si la frecuencia del reloj se establece en 640000 kHz, entonces su período de reloj será de 1,5625 ns, para lo cual una precisión de escala de tiempo de 1 ps no será suficiente porque hay un punto extra que representar. Por lo tanto, la simulación redondeará el último dígito para que encaje en la precisión de la escala de tiempo de 3 puntos. ¡Esto aumentará el período del reloj a 1,563, lo que en realidad representa 639795 kHz!

El siguiente módulo generador de reloj Verilog tiene tres parámetros para ajustar las tres propiedades diferentes como se discutió anteriormente. El módulo tiene una habilitación de entrada que permite deshabilitar y habilitar el reloj según se requiera. Cuando varios relojes están controlados por una señal de habilitación común, se pueden sincronizar con relativa facilidad.

  
  
`timescale 1ns/1ps

module clock_gen (	input      enable,
  					output reg clk);
  
  parameter FREQ = 100000;  // in kHZ
  parameter PHASE = 0; 		// in degrees
  parameter DUTY = 50;  	// in percentage 
  
  real clk_pd  		= 1.0/(FREQ * 1e3) * 1e9; 	// convert to ns
  real clk_on  		= DUTY/100.0 * clk_pd;
  real clk_off 		= (100.0 - DUTY)/100.0 * clk_pd;
  real quarter 		= clk_pd/4;
  real start_dly     = quarter * PHASE/90;
  
  reg start_clk;
  
  initial begin    
    $display("FREQ      = %0d kHz", FREQ);
    $display("PHASE     = %0d deg", PHASE);
    $display("DUTY      = %0d %%",  DUTY);
    
    $display("PERIOD    = %0.3f ns", clk_pd);    
    $display("CLK_ON    = %0.3f ns", clk_on);
    $display("CLK_OFF   = %0.3f ns", clk_off);
    $display("QUARTER   = %0.3f ns", quarter);
    $display("START_DLY = %0.3f ns", start_dly);
  end
  
  // Initialize variables to zero
  initial begin
    clk <= 0;
    start_clk <= 0;
  end
  
  // When clock is enabled, delay driving the clock to one in order
  // to achieve the phase effect. start_dly is configured to the 
  // correct delay for the configured phase. When enable is 0,
  // allow enough time to complete the current clock period
  always @ (posedge enable or negedge enable) begin
    if (enable) begin
      #(start_dly) start_clk = 1;
    end else begin
      #(start_dly) start_clk = 0;
    end      
  end
  
  // Achieve duty cycle by a skewed clock on/off time and let this
  // run as long as the clocks are turned on.
  always @(posedge start_clk) begin
    if (start_clk) begin
      	clk = 1;
      
      	while (start_clk) begin
      		#(clk_on)  clk = 0;
    		#(clk_off) clk = 1;
        end
      
      	clk = 0;
    end
  end 
endmodule

  

Banco de pruebas con diferentes frecuencias de reloj

  
  
module tb;
  wire clk1;
  wire clk2;
  wire clk3;
  wire clk4;
  reg  enable;
  reg [7:0] dly;
  
  clock_gen u0(enable, clk1);
  clock_gen #(.FREQ(200000)) u1(enable, clk2);
  clock_gen #(.FREQ(400000)) u2(enable, clk3);
  clock_gen #(.FREQ(800000)) u3(enable, clk4);
  
  initial begin
    enable <= 0;
    
    for (int i = 0; i < 10; i= i+1) begin
      dly = $random;
      #(dly) enable <= ~enable;      
      $display("i=%0d dly=%0d", i, dly);
      #50;
    end
    
    #50 $finish;
  end
endmodule

  
Registro de simulación
xcelium> run
FREQ      = 100000 kHz
PHASE     = 0 deg
DUTY      = 50 %
PERIOD    = 10.000 ns
CLK_ON    = 5.000 ns
CLK_OFF   = 5.000 ns
QUARTER   = 2.500 ns
START_DLY = 0.000 ns
FREQ      = 200000 kHz
PHASE     = 0 deg
DUTY      = 50 %
PERIOD    = 5.000 ns
CLK_ON    = 2.500 ns
CLK_OFF   = 2.500 ns
QUARTER   = 1.250 ns
START_DLY = 0.000 ns
FREQ      = 400000 kHz
PHASE     = 0 deg
DUTY      = 50 %
PERIOD    = 2.500 ns
CLK_ON    = 1.250 ns
CLK_OFF   = 1.250 ns
QUARTER   = 0.625 ns
START_DLY = 0.000 ns
FREQ      = 800000 kHz
PHASE     = 0 deg
DUTY      = 50 %
PERIOD    = 1.250 ns
CLK_ON    = 0.625 ns
CLK_OFF   = 0.625 ns
QUARTER   = 0.312 ns
START_DLY = 0.000 ns
i=0 dly=36
i=1 dly=129
i=2 dly=9
i=3 dly=99
i=4 dly=13
i=5 dly=141
i=6 dly=101
i=7 dly=18
i=8 dly=1
i=9 dly=13
Simulation complete via $finish(1) at time 1110 NS + 0

Banco de pruebas con diferentes fases de reloj

  
  
module tb;
  wire clk1;
  wire clk2;
  reg  enable;
  reg [7:0] dly;
  
  clock_gen u0(enable, clk1);
  clock_gen #(.FREQ(50000), .PHASE(90)) u1(enable, clk2);
  
  initial begin
    enable <= 0;
    
    for (int i = 0; i < 10; i=i+1) begin
      dly = $random;
      #(dly) enable <= ~enable;      
      $display("i=%0d dly=%0d", i, dly);
    end
    
    #50 $finish;
  end

endmodule

  
Registro de simulación
xcelium> run
FREQ      = 100000 kHz
PHASE     = 0 deg
DUTY      = 50 %
PERIOD    = 10.000 ns
CLK_ON    = 5.000 ns
CLK_OFF   = 5.000 ns
QUARTER   = 2.500 ns
START_DLY = 0.000 ns
FREQ      = 100000 kHz
PHASE     = 90 deg
DUTY      = 50 %
PERIOD    = 10.000 ns
CLK_ON    = 5.000 ns
CLK_OFF   = 5.000 ns
QUARTER   = 2.500 ns
START_DLY = 2.500 ns
FREQ      = 100000 kHz
PHASE     = 180 deg
DUTY      = 50 %
PERIOD    = 10.000 ns
CLK_ON    = 5.000 ns
CLK_OFF   = 5.000 ns
QUARTER   = 2.500 ns
START_DLY = 5.000 ns
FREQ      = 100000 kHz
PHASE     = 270 deg
DUTY      = 50 %
PERIOD    = 10.000 ns
CLK_ON    = 5.000 ns
CLK_OFF   = 5.000 ns
QUARTER   = 2.500 ns
START_DLY = 7.500 ns
i=0 dly=36
i=1 dly=129
i=2 dly=9
i=3 dly=99
i=4 dly=13
i=5 dly=141
i=6 dly=101
i=7 dly=18
i=8 dly=1
i=9 dly=13
Simulation complete via $finish(1) at time 1110 NS + 0

Banco de pruebas con diferentes ciclos de trabajo

  
  
module tb;
  wire clk1;
  wire clk2;
  wire clk3;
  wire clk4;
  reg  enable;
  reg [7:0] dly;
  
  clock_gen u0(enable, clk1);
  clock_gen #(.DUTY(25)) u1(enable, clk2);
  clock_gen #(.DUTY(75)) u2(enable, clk3);
  clock_gen #(.DUTY(90)) u3(enable, clk4);
  
  initial begin
    enable <= 0;
    
    for (int i = 0; i < 10; i= i+1) begin
      dly = $random;
      #(dly) enable <= ~enable;      
      $display("i=%0d dly=%0d", i, dly);
      #50;
    end
    
    #50 $finish;
  end
endmodule

  
Registro de simulación
xcelium> run
FREQ      = 100000 kHz
PHASE     = 0 deg
DUTY      = 50 %
PERIOD    = 10.000 ns
CLK_ON    = 5.000 ns
CLK_OFF   = 5.000 ns
QUARTER   = 2.500 ns
START_DLY = 0.000 ns
FREQ      = 100000 kHz
PHASE     = 0 deg
DUTY      = 25 %
PERIOD    = 10.000 ns
CLK_ON    = 2.500 ns
CLK_OFF   = 7.500 ns
QUARTER   = 2.500 ns
START_DLY = 0.000 ns
FREQ      = 100000 kHz
PHASE     = 0 deg
DUTY      = 75 %
PERIOD    = 10.000 ns
CLK_ON    = 7.500 ns
CLK_OFF   = 2.500 ns
QUARTER   = 2.500 ns
START_DLY = 0.000 ns
FREQ      = 100000 kHz
PHASE     = 0 deg
DUTY      = 90 %
PERIOD    = 10.000 ns
CLK_ON    = 9.000 ns
CLK_OFF   = 1.000 ns
QUARTER   = 2.500 ns
START_DLY = 0.000 ns
i=0 dly=36
i=1 dly=129
i=2 dly=9
i=3 dly=99
i=4 dly=13
i=5 dly=141
i=6 dly=101
i=7 dly=18
i=8 dly=1
i=9 dly=13
Simulation complete via $finish(1) at time 1110 NS + 0

Alternar habilitar para iniciar/detener relojes

La siguiente forma de onda muestra que los relojes se detienen cuando la habilitación es baja y los relojes se inician cuando la habilitación es alta.


Verilog

  1. Tutorial de Verilog
  2. Concatenación Verilog
  3. Asignaciones de Verilog
  4. Bloqueo y no bloqueo de Verilog
  5. Funciones de Verilog
  6. Tarea Verilog
  7. Funciones matemáticas de Verilog
  8. Formato de hora de Verilog
  9. Alcance de la escala de tiempo de Verilog
  10. Operaciones de E/S de archivos de Verilog
  11. Verilog Hola Mundo