En Verilog, xpm_cdc_pulse es un módulo de cruce de dominio de reloj (CDC) dentro de las macros paramétricas de Xilinx (XPM), diseñado específicamente para la transferencia segura de señales de pulso de un solo ciclo entre diferentes dominios de reloj.
Introducción Técnica
La macro xpm_cdc_pulse garantiza que cada pulso de un solo ciclo en el dominio de reloj de origen se transfiera correctamente al dominio de reloj de destino, generando un pulso correspondiente de un solo ciclo en el destino sin pérdidas ni duplicaciones.
Sintaxis Básica
// Instanciación en Verilog
xpm_cdc_pulse #(
.DEST_SYNC_FF(3), // Rango: 2-10
.INIT_SYNC_FF(0), // 0-1
.REG_OUTPUT(1), // 0-1
.RST_USED(1), // 0-1
.SIM_ASSERT_CHK(1) // 0-1
)
pulse_cdc_unit (
.origen_clk(origen_clk), // Reloj de origen
.origen_rst(origen_rst), // Reset de origen (opcional)
.pulso_origen(pulso_origen), // Entrada de pulso de origen
.destino_clk(destino_clk), // Reloj de destino
.destino_rst(destino_rst), // Reset de destino (opcional)
.pulso_destino(pulso_destino) // Salida de pulso de destino
);
Parámetros Principales
DEST_SYNC_FF(por defecto=2): Número de etapas de registros sincronizadores en el dominio de destinoREG_OUTPUT(por defecto=0): Indica si se añade un registro de salida en el dominio de destinoRST_USED(por defecto=0): Controla si se uttilizan las señales de resetINIT_SYNC_FF(por defecto=0): Valor inicial de los registros sincronizadoresSIM_ASSERT_CHK(por defecto=0): Habilita comprobaciones de aserción durante simulación
Ejemplos de Implementación
Ejemplo 1: Transferencia Básica de Pulso
module transferencia_pulso (
input wire reloj_origen,
input wire reloj_destino,
input wire pulso_entrada,
output wire pulso_salida
);
xpm_cdc_pulse #(
.DEST_SYNC_FF(2), // 2 etapas de sincronización
.RST_USED(0) // Sin señales de reset
) sincronizador_pulso (
.origen_clk(reloj_origen),
.origen_rst(1'b0), // Sin reset
.pulso_origen(pulso_entrada),
.destino_clk(reloj_destino),
.destino_rst(1'b0),
.pulso_destino(pulso_salida)
);
endmodule
Ejemplo 2: Sincronización con Señales de Reset
module sincro_con_reset (
input wire clk_fuente,
input wire clk_destino,
input wire reset_fuente,
input wire reset_destino,
input wire pulso_disparo,
output wire pulso_sincronizado
);
xpm_cdc_pulse #(
.DEST_SYNC_FF(4), // Mayor confiabilidad con 4 etapas
.RST_USED(1), // Uso de señales de reset
.REG_OUTPUT(1) // Registro de salida habilitado
) cdc_con_reset (
.origen_clk(clk_fuente),
.origen_rst(reset_fuente),
.pulso_origen(pulso_disparo),
.destino_clk(clk_destino),
.destino_rst(reset_destino),
.pulso_destino(pulso_sincronizado)
);
endmodule
Mecanismo de Funcionamiento
El funcionamiento interno de xpm_cdc_pulse sigue estos pasos:
- Detección del pulso de origen: El módulo detecta el flanco ascendente del pulso en el dominio de origen
- Conversión a nivel: El pulso se convierte a una señal de nivel estable
- Sincronización cruzada: La señal de nivel se pasa al dominio de destino mediante una cadena de registros sincronizadores
- Regeneración de pulso: En el dominio de destino, se detecta el cambio de nivel para regenerar un pulso de un solo ciclo
Casos de Aplicación Práctica
1. Sincronización de Señales de Inicio
module sincro_senal_inicio (
input wire clk_configuracion,
input wire clk_procesamiento,
input wire iniciar_configuracion,
output wire iniciar_procesamiento
);
xpm_cdc_pulse cdc_inicio (
.origen_clk(clk_configuracion),
.origen_rst(1'b0),
.pulso_origen(iniciar_configuracion),
.destino_clk(clk_procesamiento),
.destino_rst(1'b0),
.pulso_destino(iniciar_procesamiento)
);
endmodule
2. Propagación de Solicitudes de Interrupción
module sincro_interrupcion (
input wire clk_periferico,
input wire clk_cpu,
input wire peticion_irq,
output wire irq_sincronizada
);
xpm_cdc_pulse #(
.DEST_SYNC_FF(3),
.REG_OUTPUT(1) // Salida limpia y estable
) cdc_interrupcion (
.origen_clk(clk_periferico),
.origen_rst(1'b0),
.pulso_origen(peticion_irq),
.destino_clk(clk_cpu),
.destino_rst(1'b0),
.pulso_destino(irq_sincronizada)
);
endmodule
3. Disparo entre Múltiples Dominios de Reloj
module disparo_multidominio (
input wire clk_lento, // Reloj lento (ej. configuración)
input wire clk_rapido, // Reloj rápido (ej. procesamiento)
input wire disparo_lento, // Disparo en dominio lento
output wire disparo_rapido // Disparo en dominio rápido
);
xpm_cdc_pulse #(
.DEST_SYNC_FF(4) // Máxima seguridad
) cdc_disparo (
.origen_clk(clk_lento),
.origen_rst(1'b0),
.pulso_origen(disparo_lento),
.destino_clk(clk_rapido),
.destino_rst(1'b0),
.pulso_destino(disparo_rapido)
);
endmodule
4. Sincronización de Señales de Depuración
module sincro_debug (
input wire clk_pruebas,
input wire clk_sistema,
input wire disparo_debug,
output wire pulso_debug_sistema
);
xpm_cdc_pulse cdc_debug (
.origen_clk(clk_pruebas),
.origen_rst(1'b0),
.pulso_origen(disparo_debug),
.destino_clk(clk_sistema),
.destino_rst(1'b0),
.pulso_destino(pulso_debug_sistema)
);
endmodule
Configuración Completa de Parámetros
xpm_cdc_pulse #(
.DEST_SYNC_FF(3), // Etapas de sincronización en destino
.INIT_SYNC_FF(0), // Valor inicial de registros
.REG_OUTPUT(1), // Registro de salida (0=desactivado, 1=activado)
.RST_USED(1), // Uso de reset (0=no, 1=sí)
.SIM_ASSERT_CHK(1) // Comprobaciones en simulación
)
Características de Temporalización
Comportamiento del Pulso
- Pulso de origen: Debe ser de un solo ciclo en el dominio de origen
- Pulso de destino: Genera un pulso de un solo ciclo en el dominio de destino
- Espaciado mínimo: Los pulsos de origen deben tener un espaciado suficiente para evitar pérdidas
Atraso Típico
Pulso origen → [1 ciclo reloj origen] → Inicio sincronización → [DEST_SYNC_FF ciclos reloj destino] → Pulso destino
Comportamiento con Reset
Cuando RST_USED = 1
xpm_cdc_pulse #(.RST_USED(1)) cdc_con_reset (
.origen_clk(reloj_a),
.origen_rst(reset_a), // Reset de origen, asíncrono o síncrono
.pulso_origen(pulso_entrada),
.destino_clk(reloj_b),
.destino_rst(reset_b), // Reset de destino, asíncrono o síncrono
.pulso_destino(pulso_salida)
);
Uso en Vivado
Reconocimiento Automático
Vivado identifica automáticamente los módulos XPM CDC y aplica las restricciones de temporización apropiadas.
Sugerencias de Restricciones
# Configurar grupos de reloj asíncronos
set_clock_groups -asynchronous \
-group [get_clocks reloj_a] \
-group [get_clocks reloj_b]
# Establecer restricciones de retraso máximo si es necesario
set_max_delay -from [get_cells pulso_origen_reg] \
-to [get_cells xpm_cdc_pulse_inst/*sincro*] \
-datapath_only 1.2
Ventajas
- Fiabilidad: Específicamente optimizado para señales de pulso
- Integridad: Garantiza que cada pulso de origen genere un pulso correspondiente en destino
- Simplicidad: Elimina la necesidad de implementar manualmente lógica CDC compleja
- Configurabilidad: Parámetros ajustables para diferentes requisitos
Precauciones de Uso
Implementación Correcta
// Correcto: Pulso de un solo ciclo con espaciado adecuado
reg generador_pulso;
always @(posedge reloj_origen) begin
if (condicion) generador_pulso <= 1'b1;
else generador_pulso <= 1'b0;
end
xpm_cdc_pulse cdc_correcto (
.origen_clk(reloj_origen),
.pulso_origen(generador_pulso), // Pulso de un ciclo
.destino_clk(reloj_destino),
.pulso_destino(pulso_salida)
);
Errores Comunes
// Error 1: Pulso de múltiples ciclos
wire pulso_multiple_ciclo = condicion; // Puede durar múltiples ciclos
// Error 2: Pulsos consecutivos (posible pérdida)
always @(posedge reloj_origen) begin
generador_pulso <= ~generador_pulso; // Pulsos rápidos consecutivos
end
// Error 3: Entrada asíncrona
wire pulso_asincrono = senal_externa; // Debe sincronizarse primero al reloj de origen
Requisitos de Espaciado
Espaciado mínimo = DEST_SYNC_FF + 2 ciclos del reloj de origen
// Ejemplo: DEST_SYNC_FF=2 → espaciado mínimo de 4 ciclos del reloj de origen
Otros Módulos XPM CDC Relacionados
xpm_cdc_single: Transferencia de señales de un solo bitxpm_cdc_handshake: Transferencia de datos múltiples con protocolo de handshakexpm_cdc_gray: Transferencia de contadores usando código Gray
La macro xpm_cdc_pulse es la solución ideal para transferir señales de pulso de un solo ciclo entre dominios de reloj diferentes, especialmente útil en aplicaciones como disparos de inicio, solicitudes de interrupción y transmisión de comandos.