Verilog Generate Blocks (generate / genvar)
A generate block builds hardware programmatically at elaboration time. It is how you instantiate N copies of a module, or conditionally include logic, without copy-pasting — the structural equivalent of a for loop that writes RTL for you.
generate for: replicate a slice
A genvar loop below builds an 8-bit ripple-carry adder from eight 1-bit full adders — eight real instances, created at compile time:
module fa (input a,b,cin, output s,cout);
assign s = a ^ b ^ cin;
assign cout = (a & b) | (cin & (a ^ b));
endmodule
module rca #(parameter N = 8)
(input [N-1:0] a, b, input cin, output [N-1:0] sum, output cout);
wire [N:0] c; assign c[0] = cin; assign cout = c[N];
genvar i;
generate
for (i = 0; i < N; i = i + 1) begin : stage
fa u (.a(a[i]), .b(b[i]), .cin(c[i]), .s(sum[i]), .cout(c[i+1]));
end
endgenerate
endmodule
module tb;
reg [7:0] a,b; reg cin; wire [7:0] sum; wire cout;
rca #(8) dut (.a(a), .b(b), .cin(cin), .sum(sum), .cout(cout));
initial begin
a=8'd200; b=8'd100; cin=0; #1 $display("200+100 = {cout=%b, sum=%0d}", cout, sum);
a=8'd15; b=8'd1; cin=1; #1 $display("15+1+1 = %0d", sum);
$finish;
end
endmodule200+100 = {cout=1, sum=44}
15+1+1 = 17generate if: configure at build time
A generate if on a parameter includes or omits whole blocks of hardware — for example a pipeline register that only exists when PIPELINED=1. Because the decision happens at elaboration, no multiplexer or run-time cost is added.
The named block label (: stage) is required — it gives each generated instance a hierarchical name (stage[0].u, stage[1].u, …) you can reference in waveforms and constraints.
▶ Try it in the ChipXpert Lab
Build the parameterised RCA in the lab, change #(8) to #(16) with wider stimulus, and confirm the generate loop produces a 16-bit adder with no source edits.
Check yourself
Why does a generate-for loop need a <code>genvar</code> rather than an <code>integer</code>?
A genvar is an elaboration-time index: the loop is unrolled at compile time to create real hardware instances. An integer is a run-time variable and cannot drive structural replication.
What does the block label <code>begin : stage</code> give you?
A hierarchical name for each generated instance (stage[0], stage[1] …), which you need to reference the instances in waveform viewers, assertions and timing constraints. The label is mandatory in a generate loop.
Share your question in comments or talk to our mentor team for batch guidance.
Learn Verilog with mentors, labs and placement support
This free series is maintained by the ChipXpert training team in Hyderabad & Bengaluru. Go deeper with instructor-led courses on real EDA tools.
Explore VLSI Courses