A hierarchical netlist keeps submodule instances, so counts span the modules. Flattening dissolves the instances into the parent while gate totals stay the same.
The script below builds two instances of one AND submodule under an OR. It pins the instance count, flattens, and pins the counts again.
read_verilog <<EOV
module sub(input a, b, output y);
assign y = a & b;
endmodule
module top(input a, b, c, output y);
wire n1, n2;
sub u1 (.a(a), .b(b), .y(n1));
sub u2 (.a(a), .b(c), .y(n2));
assign y = n1 | n2;
endmodule
EOV
hierarchy -check -top top
select -assert-count 2 t:sub
select -assert-count 1 t:$or
stat
flatten
select -assert-none t:sub
select -assert-count 2 t:$and
select -assert-count 1 t:$or
stat
log PASS: flatten dissolves instances and keeps gate countsFanout counts how many gate inputs one net drives. High fanout means heavy load, which later stages must buffer.
The calc block counts loads on the flattened design above. Input a is shared by both instances, so it leads.
flattened loads:
a -> u1.a, u2.a : fanout 2
b -> u1.b : fanout 1
c -> u2.b : fanout 1
n1 -> OR input : fanout 1
n2 -> OR input : fanout 1
maximum fanout = 2 on net a
gate input pins = 2 + 2 + 2 = 6 across 3 gatesNets without a declared name get a tool-generated one. Those names shift with small edits, so scripts and constraints must use stable ports and hierarchical names instead.
Constant pins fold away during optimisation. Tying an input to 1 or 0 removes the gate instead of building it, as the script below proves.
read_verilog <<EOV
module top(input a, b, output y, output z);
assign y = a & 1'b1;
assign z = b | 1'b0;
endmodule
EOV
hierarchy -check -top top
opt
select -assert-none t:$and
select -assert-none t:$or
stat
log PASS: tied constants fold away leaving no gatesThe block below is an illustrative layout, numbers invented for this lesson. Undriven pins deserve the same suspicion: a missing driver usually means a missing connection, so confirm each one.
illustrative layout, numbers invented for this lesson (names stand in for generated ones):
net n1 (declared) drives 1 load
net GEN_042 (generated stand-in for an unnamed net) drives 1 load
port a (shared by two instances) drives 2 loadsFanout 2. Net a is the maximum; every other net drives exactly one load.
Generated names are unstable across edits. The script should reference stable ports and hierarchy instead.