Enabling one feature grows the block from 1600 to 1920 library units. Timing still passes, so the growth is pure overhead.
Areas here are units of the fictional teaching library, not a process. One 2:1 mux bit costs 5 units and one flop costs 8.
Block | Cells | Area (library units) |
|---|---|---|
Baseline datapath | As mapped before | 1600 |
Byte-enable mask | 32 AND2 at 3 units | 96 |
Debug observability mux | 32 MUX2 at 5 units | 160 |
Configuration flops | 8 DFF at 8 units | 64 |
New total | Baseline plus 320 | 1920 |
Break the growth down by hierarchy first. A flat total hides whether one block or every block grew.
Rank the causes by how often each one explains a step change. Replicated logic tops the list after a feature lands.
Rank | Likely cause | How to confirm |
|---|---|---|
1 | Replicated logic in a generate loop | Compare instance counts per module. |
2 | Widened muxes on the datapath | Compare mux input counts before and after. |
3 | Debug logic left enabled | Check the debug parameter value. |
4 | Missed sharing of one operator | Look for duplicate adders on exclusive paths. |
The program below rechecks the quoted split. Masking is 30 percent, the debug mux is 50 percent, config flops are 20 percent.
added = 96 + 160 + 64 = 320 library units
new total = 1600 + 320 = 1920 library units
rise = 320 / 1600 = 0.20 = 20.0%
mask share = 96 / 320 = 30%
debug mux share = 160 / 320 = 50%
config share = 64 / 320 = 20%
30 + 50 + 20 = 100import sys
BASE = 1600.0
MASK = 32.0 * 3.0
MUX = 32.0 * 5.0
CFG = 8.0 * 8.0
def close(got, want):
return abs(got - want) < 1e-9
added = MASK + MUX + CFG
total = BASE + added
rise = added / BASE * 100.0
shares = MASK / added * 100.0 + MUX / added * 100.0 + CFG / added * 100.0
bad = 0
if not close(added, 320.0):
bad = bad + 1
if not close(total, 1920.0):
bad = bad + 1
if not close(rise, 20.0):
bad = bad + 1
if not close(shares, 100.0):
bad = bad + 1
if bad != 0:
print("FAIL: area split broke on " + str(bad) + " checks")
sys.exit(1)
print("PASS: added 320 units over 1600 is a 20.0 percent rise")Put the debug mux behind a parameter so it compiles out of the production build. That alone removes 160 of the 320 units.
Share the mask across bytes only if the bytes truly share timing. Sharing saves area but adds fanout and wire length, which varies by floorplan.
30 percent. The debug mux is 50 percent and config flops are 20 percent, summing to 100 percent.
Total 1760 units. Rise 160 over 1600, which is 10.0 percent.