Generación de onda cuadrada usando Veilog

1

Estoy confundido con la generación de una onda cuadrada de frecuencia específica y un ciclo de trabajo con Verilog y volcado al kit FPGA. ¿Alguien puede aclarar cómo se deriva la frecuencia del reloj? ¿Qué bit se selecciona al utilizar la frecuencia de reloj derivada?  Aquí hay un código de ejemplo para generar una onda cuadrada de 1 KHz con un ciclo de trabajo del 50%. ¿Qué modificaciones deben realizarse para generar una onda cuadrada de frecuencia de 2 KHz y un ciclo de trabajo del 40% en el presente código?

module square_wave(clk,rst,dac_out);
  input clk;
  input rst;
  output reg [0:7] dac_out;
  reg [7:0] temp;
  reg [7:0] counter;

  always @(posedge clk)
  begin
    temp <= temp + 1'b1;
  end

  always @(posedge temp[3])
  begin
    if (rst)
      begin
        counter <=0;
      end
    else
      counter<=counter + 1'b1;
  end

  always @*
  begin
  if (counter<=127)
    dac_out=8'd1;
  else
    dac_out=8'd0;
  end
endmodule
    
pregunta Anuchan

1 respuesta

2

Para una entrada de 4 MHz clk y una salida de 1 kHz reloj dac_out , necesitamos un contador que cuente

$$ n = \ frac {f_ {in}} {f_ {out}} = \ frac {4 \, MHz} {1 \, kHz} = 4000 $$

ciclos de la clave de entrada y luego se ajusta a cero, es decir, cuenta de 0 a \ $ n-1 \ $. Esto define el período del reloj de salida. Se define un ciclo de trabajo del 50% (x%) configurando la salida a alta para la primera

$$ m = \ frac {x \%} {100 \%} \ cdot n = \ frac {50 \%} {100 \%} \ cdot 4000 = 2000 $$

ciclos, y bajo para el resto del período.

He mejorado su código para una mejor comprensión:

module square_wave(clk,rst,dac_out);
   input clk; // assuming 1 MHz
   input rst;
   output reg dac_out;
   reg [11:0]  counter; // 12-bit for numbers up to 3999

   always @(posedge clk)
     begin
        if (rst == 1'b1  ||  counter == 12'd3999) // period, count from 0 to n-1
          counter <= 0;
        else
          counter <= counter + 1'b1;

        // synchronous output without glitches
        if (rst == 1'b0  &&  counter < 12'd2000) // duty cycle, m cycles high
          dac_out = 1'b1;
        else
          dac_out = 1'b0;
      end
endmodule // square_wave

Al cambiar las comprobaciones del contador marcado, puede ajustar el período y el ciclo de trabajo del reloj de salida. Por ejemplo, un período de \ $ n = 2000 \ $ ciclos y ciclo de trabajo con \ $ m = 800 \ $ da el reloj de salida requerido.

    
respondido por el Martin Zabel

Lea otras preguntas en las etiquetas