Métodos de división de frecuencia en FPGA con relación de trabajo del 50%

La división de señales de reloj es una operación frecuente en el diseño digital. A continuación se describen varios enfoques para lograr una relación de trabajo del 50% en señales de reloj dividido, comúnmente emplaedos en implementaciones con FPGAs.

Uso de recursos de reloj dedicados

Los FPGAs modernos suelen incluir bloques de gestión de reloj (como PLLs o MMCMs) que permiten generar múltiples frecuencias derivadas de una referencia. Aunque es la solución más limpia y precisa, estos recursos son limitados en cantidad dentro del dispostiivo, por lo que se reservan para las frecuencias más críticas del diseño.

División basada en contadores duales

Este método utiliza dos contadores separados que operan en los flancos de subida y bajada del reloj original. Al comparar sus valores se genera una señal dividida con relación de trabajo ajustable. El siguiente código ilustra esta técnica:


module divisor_reloj_contador (
    input wire clk_fuente,
    input wire rst_n,
    output reg clk_salida
);

    parameter [15:0] FACTOR_DIVISION = 16'd4;
    localparam [15:0] UMBRAL_MEDIO = FACTOR_DIVISION / 2;

    reg [15:0] contador_flanco_subida;
    reg [15:0] contador_flanco_bajada;

    always @(posedge clk_fuente or negedge rst_n) begin
        if (!rst_n)
            contador_flanco_subida <= 16'b0;
        else if (contador_flanco_subida == FACTOR_DIVISION - 1)
            contador_flanco_subida <= 16'b0;
        else
            contador_flanco_subida <= contador_flanco_subida + 16'b1;
    end

    always @(negedge clk_fuente or negedge rst_n) begin
        if (!rst_n)
            contador_flanco_bajada <= 16'b0;
        else if (contador_flanco_bajada == FACTOR_DIVISION - 1)
            contador_flanco_bajada <= 16'b0;
        else
            contador_flanco_bajada <= contador_flanco_bajada + 16'b1;
    end

    wire pulso_subida = (contador_flanco_subida < UMBRAL_MEDIO) ? 1'b0 : 1'b1;
    wire pulso_bajada = (contador_flanco_bajada < UMBRAL_MEDIO) ? 1'b0 : 1'b1;

    always @(*) begin
        if (FACTOR_DIVISION[0])
            clk_salida = pulso_subida & pulso_bajada;
        else
            clk_salida = pulso_subida;
    end
endmodule

Extracción de bits de contador

Una técnica simple para divisores de potencia de dos consiste en utilizar un contador continuo y tomar diferentes bits de su registro como salidas de reloj. Cada bit k proporciona una división por 2^(k+1). El siguiente ejemplo muestra un contador de 4 bits:


module divisor_potencia_dos (
    input wire clk_sistema,
    input wire rst_n,
    output wire [3:0] relojes_divididos
);

    reg [3:0] acumulador;

    always @(posedge clk_sistema or negedge rst_n) begin
        if (!rst_n)
            acumulador <= 4'b0;
        else
            acumulador <= acumulador + 4'b1;
    end

    assign relojes_divididos = acumulador;
endmodule

Síntesis de frecuencia mediante acumulador de fase

Este método, basado en el principio DDS (Direct Digital Synthesis), permite generar frecuencias arbitrarias mediante un acumulador y un paso de incremento programable. Es especialmente útil en módulos IP donde se reuqiere flexibilidad en la configuración de la frecuencia mediante interfaces de bus. La resolución de frecuencia viene determinada por el tamaño del acumulador.


module generador_dds (
    input wire clk_ref,
    input wire rst_n,
    input wire [31:0] paso_frecuencia,
    output wire reloj_sintetizado
);

    reg [31:0] acumulador_fase;

    always @(posedge clk_ref or negedge rst_n) begin
        if (!rst_n)
            acumulador_fase <= 32'b0;
        else
            acumulador_fase <= acumulador_fase + paso_frecuencia;
    end

    assign reloj_sintetizado = acumulador_fase[31];
endmodule

La frecuencia generada se calcula como f_salida = (paso_frecuencia * f_reloj_ref) / 2^32. La relación de trabajo no es exactamente del 50% y puede existir un pequeño error en la frecuencia, dependiendo de la resolución del sistema.

Etiquetas: FPGA división de reloj VHDL síntesis digital DDS

Publicado el 6-9 19:02