Six months after tapeout, marketing asks for a second DMA channel and twice the SRAM. If the map planned for that, the change is a reserved slot, one spare interrupt input, one clock-enable bit and regenerated headers. If it did not, every driver base address shifts and the software team discovers the map was load-bearing. NanoSoC is small enough to show the whole growth story on one table: where the second DMA goes, how the SRAMs split traffic, and why the map never remaps at boot.
Growth has a strict order of preference. First, fill reserved space: hole H3 holds nine free 4 KB slots, so a second DMA takes slot 7 at 0x4000_7000 with no other row touched. Second, grow inside stranded space: each peripheral slot wastes most of its 4 KB (the DMA uses 256 bytes in its first image), so register blocks can grow inside their slots without moving; the SRAM windows are exactly full and cannot grow inside their windows at all. Third, add a new top-level window above 0x4001_0000, which only costs a new row in the interconnect decoder. What never happens is moving an existing base: software, headers and verification all derive from the map, and a moved base breaks all of them at once.
Banking is the memory side of the same idea. NanoSoC already splits 128 KB into two 64 KB banks, SRAM0 and SRAM1, each with its own single port at 361.4 MB/s sustained for long bursts. When a copy's source and destination sit in different banks, each direction gets the full rate; when both sit in the same bank they share one port and the copy runs at half rate, 180.7 MB/s per stream. Striping a transfer across the boundary at 0x2001_0000 uses both banks and is exactly what a fast copy wants. The rule for software follows directly: put a copy's source in one bank and its destination in the other, and remember that SRAM1 is secure-only, so the stream bridge must be programmed with its security bit cleared (NS = 0) before it may use SRAM1 at all.
# not-run: NanoSoC growth arithmetic, NanoSoC teaching values
Second DMA: slot 7 at 0x4000_7000 (first free slot in H3), needs one APB slot,
one interrupt (inputs 6 and 7 are reserved spares), one clock-enable bit,
and a second stream bridge (or an arbiter), because the DMA is stream-only.
SRAM banks: 2 x 64 KB, one port each at 361.4 MB/s sustained (burst 16).
Source and destination in different banks: 361.4 each.
Both in the same bank: 361.4 / 2 = 180.7 MB/s per stream.
SRAM1 is secure-only: the SBR needs NS = 0 (set by secure software) to use it.Some chips alias the boot ROM at address zero and remap SRAM there after boot, which adds a remap bit, a boot-mode strap and a famous failure mode when the alias is never removed. NanoSoC chose the fixed alternative: the ROM lives at zero forever, the SRAMs live at 0x2000_0000 forever, and there is no remap control to forget. A fixed map costs one design decision up front, that the reset vector really belongs in ROM, and removes an entire class of boot bugs. Prefer it whenever the architecture allows.
The map carries a version, and every generated file names it: the header has a comment with the map revision, the decoder file is generated with the same stamp, and the integration review checks that all stamps match before signoff. Adding a region bumps the minor version; moving or deleting one, which should never happen, bumps the major version and forces every consumer to re-qualify. The version costs one line in the map table and repays it the first time two teams argue about which map a failing test used.
The next two peripherals and the next memory doubling already have named places that move nothing existing.
DMA buffer placement keeps CPU and DMA traffic on separate banks in the common case.
All generated consumers carry the same map version stamp, and the review record quotes it.
Re-run the alignment and overlap checker with the new rows added: a second DMA at 0x4000_7000 must pass alignment and must not overlap the SBR. Then confirm the interrupt plan: the second DMA needs a free controller input, and inputs 6 and 7 are the spares. If growth ever demands moving a base, stop and re-plan; the cost of the move lands on every software image already built.
Keep both 64 KB banks where they are and add a 128 KB SRAM2 at 0x2002_0000, inside hole H2. The base is a multiple of 0x2_0000 so it is aligned, it overlaps nothing, and neither existing base moves. Widening SRAM0 in place is forbidden precisely because SRAM1 sits right above it.