Logique combinatoire

La logique combinatoire produit une sortie qui ne dépend que des entrées actuelles — aucune horloge, aucune mémoire d’état.

Assignation continue : assign

Le mot-clé assign relie en permanence une expression à un wire. C’est l’équivalent d’un câblage direct.

Exemples d’assignations continues
wire a, b, sel;
wire s_and, s_or, s_xor, s_not, s_mux;

assign s_and = a & b;          // porte ET
assign s_or  = a | b;          // porte OU
assign s_xor = a ^ b;          // porte XOR
assign s_not = ~a;             // inverseur
assign s_mux = sel ? a : b;    // multiplexeur 2→1

Bloc always @(*) — combinatoire conditionnel

Lorsque la logique est trop complexe pour une seule expression, on utilise always @(*). La liste de sensibilité (*) signifie : recalculer dès que n’importe quelle entrée change.

Important

Dans un always @(*), utiliser exclusivement l’affectation bloquante =, jamais <=.

Décodeur 2 vers 4 avec always combinatoire
module dec2to4 (
    input  wire [1:0] sel,
    output reg  [3:0] out
);
    always @(*) begin
        out = 4'b0000;          // valeur par défaut (évite les latches)
        case (sel)
            2'b00 : out = 4'b0001;
            2'b01 : out = 4'b0010;
            2'b10 : out = 4'b0100;
            2'b11 : out = 4'b1000;
        endcase
    end
endmodule

Warning

Toujours prévoir une valeur par défaut avant un case ou un if. Sans cela, Vivado infère des latches transparents (mémoire non intentionnelle), source de bugs difficiles à diagnostiquer.

Exemple du projet : le comparateur numérique

Dans notre chaîne de traitement, le comparateur convertit la valeur ADC 12 bits en un signal binaire 1 bit, en comparant à un seuil paramétrable. La zone d’hystérésis évite les oscillations dues au bruit.

comparator.v — seuillage avec hystérésis
module comparator #(
    parameter [11:0] THRESHOLD = 12'h800,  // seuil à 50 % (0,5 V)
    parameter [11:0] HYST      = 12'd50    // zone morte ± 50 LSB
) (
    input  wire        clk,
    input  wire [11:0] adc_val,    // valeur ADC 12 bits
    input  wire        adc_valid,  // '1' pendant 1 cycle : nouvelle mesure
    output reg         sig_bin     // signal binaire résultant
);
    always @(posedge clk) begin
        if (adc_valid) begin
            if      (adc_val >= THRESHOLD + HYST) sig_bin <= 1'b1;
            else if (adc_val <  THRESHOLD - HYST) sig_bin <= 1'b0;
            // sinon : maintien (hystérésis → pas de changement d'état)
        end
    end
endmodule

Note

Bien que la comparaison soit combinatoire, la bascule sur posedge clk re-synchronise la sortie sur l’horloge système, ce qui élimine les glitches et garantit un signal propre pour l’étage suivant.

See also

Comparateur numérique pour la version complète avec simulation.