Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Industrial programming >> Verilog

Verilog Generate Blöcke meistern: Dynamische Instanziierung & Bedingtes Design

Ein generate Block ermöglicht multiple Modul-Instanzen oder bedingte Instanziierung basierend auf Verilog-Parametern. Praktisch bei wiederholten Operationen/Instanzen oder bedingtem Code-Einschluss.

generate Block darf keine Port-, Parameter-, specparam-Deklarationen oder specify Blöcke enthalten. Andere Module-Items und verschachtelte generate Blöcke erlaubt. Kodierung zwischen generate/endgenerate innerhalb eines module.

Generierte Instanziierungen: Module, Continuous Assignments, always/initial Blöcke, User-Defined Primitives. Drei Konstrukte:

Generate For Loop

Half Adder N-mal in Top-Level my_design instanziieren. Loop-Variable mit genvar deklarieren (Elaboration-Zeit Variable, nicht zur Simulationszeit verfügbar).

module ha (input a,b, output sum, cout);
    assign sum = a ^ b; assign cout = a & b;
endmodule

module my_design #(parameter N=4) (input [N-1:0] a,b, output [N-1:0] sum, cout);
    genvar i;
    generate
        for (i = 0; i < N; i = i + 1) begin
            ha u0 (a[i], b[i], sum[i], cout[i]);
        end
    endgenerate
endmodule

Testbench

Parameter N=2 → 2 Half-Adder Instanzen. a[0],b[0] → sum[0],cout[0]; a[1],b[1] → sum[1],cout[1].

Elaboriertes RTL zeigt tatsächlich zwei Half-Adder Instanzen.

Generate If-Else

Auswahl zwischen zwei Mux-Implementierungen per Parameter USE_CASE.

module mux_assign (input a,b,sel, output out);
    assign out = sel ? a : b;
    initial $display("mux_assign instantiated");
endmodule

module mux_case (input a,b,sel, output reg out);
    always @ (a or b or sel) begin
        case (sel) 0: out=a; 1: out=b; endcase
    end
    initial $display("mux_case instantiated");
endmodule

module my_design (input a,b,sel, output out);
    parameter USE_CASE = 0;
    generate
        if (USE_CASE) mux_case mc (.a(a),.b(b),.sel(sel),.out(out));
        else mux_assign ma (.a(a),.b(b),.sel(sel),.out(out));
    endgenerate
endmodule

Testbench

USE_CASE=1 → mux_case instanziiert (Simulationslog zeigt Display). USE_CASE=0 → mux_assign.

Generate Case

Instanziierung basierend auf case Expression (multiple Choices).

module ha (input a,b, output reg sum,cout);
    always @ (a or b) {cout,sum} = a+b;
    initial $display("Half adder instantiation");
endmodule

module fa (input a,b,cin, output reg sum,cout);
    always @ (a or b or cin) {cout,sum} = a+b+cin;
    initial $display("Full adder instantiation");
endmodule

module my_adder (input a,b,cin, output sum,cout);
    parameter ADDER_TYPE = 1;
    generate
        case (ADDER_TYPE)
            0: ha u0 (.a(a),.b(b),.sum(sum),.cout(cout));
            1: fa u1 (.a(a),.b(b),.cin(cin),.sum(sum),.cout(cout));
        endcase
    endgenerate
endmodule

Testbench

ADDER_TYPE=0 → Half Adder instanziiert. cin hat keine Wirkung auf Outputs (Simulationslog bestätigt).

Verilog

  1. Verilog meistern: Komplettes Tutorial für digitales Schaltungsdesign
  2. Verilog Concatenation meistern: Praktischer Leitfaden
  3. Verilog Essentials: Kurzer Überblick
  4. Verilog Assignments verstehen: Typen, Syntax und Best Practices
  5. Verilog Blocking vs. Non-Blocking: Wichtige Unterschiede erklärt
  6. Verilog Functions meistern für effizientes RTL-Design
  7. Verilog Tasks verstehen: Functions vs. Tasks, Syntax und Verwendung
  8. Verilog Clock Generator: Design & Implementierungsleitfaden
  9. Verilog Math Functions meistern für effizientes Hardware-Design
  10. Verilog $timeformat meistern: Präzision und Anzeigesteuerung