Résolution de l'erreur Vivado [Synth 8-91] : Horloge ambiguë dans le contrôle d'événement

L'erreur de synthèse Vivado [Synth 8-91] ambiguous clock in event control indique une ambiguïté dans le code Verilog concernant l'identification du signal d'horloge principal dans un bloc always. L'outil de synthèse est incapable de déterminer sans équivoque quel signal déclenche le circuit séquentiel décrit, ce qui l'empêche de générer une représentation matérielle correcte. Cette situation survient typiquement lorsque la liste de sensibilité (l'expression @(...)) contient des signaux dont le rôle n'est pas clair ou contradictoire avec leur utilisation dans le corps du bloc.

La cause la plus fréquente réside dans l'inclusion d'un signal dans la liste de sensibilité qui n'est jamais utilisé dans la logique conditionnelle du bloc always. L'outil interprète ce signal comme un déclencheur ptoentiel, mais son absence dans les opérations du registre crée une contradiction. Considérons un premier cas problématique où une horloge secondaire est listée mais ignorée.

// Exemple 1 : Signal inutilisé dans la liste de sensibilité
module ExempleAmbiguite1 (
    input wire clk_principal,
    input wire clk_secondaire, // Signal non utilisé dans la logique
    input wire reset_n_actif_bas,
    output reg [15:0] registre_etat
);

// La liste de sensibilité inclut 'clk_secondaire', mais ce signal
// n'est jamais référencé dans le corps du bloc always.
always @(posedge clk_principal or posedge clk_secondaire or negedge reset_n_actif_bas) begin
    if (!reset_n_actif_bas) begin
        registre_etat <= 16'h0000;
    end else begin
        registre_etat <= registre_etat + 1'b1;
    end
end

endmodule

La correction consiste à retirer de la liste de sensibilité tout signal qui n'agit pas comme un déclencheur asynchrone (comme un reset) ou une horloge effective. Pour le reset asynchrone, il doit être correctement référencé dans la condition. Une autre source d'ambiguïté, plus subtile, provient d'un mauvais positionnement d'un signal de contrôle dans la liste d'événements, le faisant apparaître comme une horloge alors qu'il ne l'est pas.

// Exemple 2 : Mauvaise pratique - un signal de contrôle traité comme une horloge
module ExempleAmbiguite2 (
    input wire clock_in,
    input wire load, // Signal de contrôle synchrone
    input wire [7:0] entree_donnees,
    output reg [7:0] sortie_donnees
);

// ERREUR : 'load' est placé dans une détection de front, ce qui en fait
// une "horloge" ambiguë au même titre que 'clock_in'.
always @(posedge clock_in or posedge load) begin
    if (load) begin
        sortie_donnees <= entree_donnees;
    end
end

endmodule

L'écriture ci-dessus est incorrecte pour un contrôleur synchrone. Le signal load doit être échantillonné au front de l'horloge principale, pas devenir un déclencheur indépendant. La solution est d'utiliser une détection de niveau dans la logique conditionnelle, et de n'avoir qu'une seule horloge dans la liste de sensibilité pour un design purement synchrone.

// Exemple 2 (corrigé) : Échantillonnage synchrone correct
module ExempleAmbiguite2_Corrige (
    input wire clock_in,
    input wire load,
    input wire [7:0] entree_donnees,
    output reg [7:0] sortie_donnees
);

// Le bloc est sensible uniquement au front de l'horloge.
always @(posedge clock_in) begin
    // Le signal 'load' est évalué comme une condition de niveau.
    if (load) begin
        sortie_donnees <= entree_donnees;
    end
end

endmodule

Pour les blocs combinatoires, la liste de sensibilité doit être complète, mais cela n'entraîne généralement pas une erreur d'horloge ambiguë. L'erreur [Synth 8-91] est spécifique aux blocs séquentiels. En résumé, pour éviter cette erreur : 1) N'incluez dans la liste de sensibilité d'un bloc always @(posedge...) que les signaux d'horloge et de reset asynchrone effectifs. 2) Utilisez @(*) pour les blocs combinatoires. 3) Assurez-vous que tout signal listé est véritablement exploité dans les conditions du bloc.

Étiquettes: Vivado Verilog FPGA Synthesis Clock Domain Crossing HDL Design

Publié le 19 juin à 05h53