Patterns are cheap; instances are where chips fail. NanoSoC has six wrappers worth knowing by name, and each exists because of one fact about the chip: the DMA's 8-bit port, the CLK_EN register with two enables, the synchronised release the DMA does not provide, the stream ports that carry only four signals, and the 114 isolation clamps between the switchable and always-on domains. Walking those six turns the abstract wrapper rules of the last two lessons into concrete port lists.
The DMA APB wrapper slices twelve address bits to eight and exports the truncation check the lint rule consumes: apb_paddr bits 11 down to 8 must be zero for canonical accesses, and the wrapper states the sixteen alias images as documented fact rather than wiring accident. The clock wrapper gates clk_sys into the DMA and the stream bridge from CLK_EN bits 0 and 1, through a two-flop synchroniser and the latch-based gating cell, so the clock never glitches; the register write itself is still software's responsibility. The reset wrapper feeds the synchronised rst_sys_n release into the DMA's rst_n, supplying the two-flop release the block omits. The stream link carries only TDATA, TVALID, TREADY and TLAST. The stream wrapper has no sideband ties, because neither the DMA nor the stream bridge has TKEEP, TSTRB, TID, TDEST or TUSER and there is nothing to wire; the connectivity table records the absence as one row, so a future block that adds a sideband fails the port-list diff. The interrupt wrapper carries irq_dma and irq_sbr through clamp-to-zero isolation into the always-on controller, two of the 114 cells. And the secure-filter wrapper sits at the interconnect and the APB slot decoder, enforcing AxPROT-based denial for SRAM1 and the reset controller, because the DMA has no PPROT to propagate.
// DMA APB wrapper: 12-bit slot address to the 8-bit block port.
// Complete and self-contained; the alias it creates is documented,
// and canonical accesses are flagged for the lint rule.
module nano_dma_wrap (
input logic [11:0] apb_paddr,
output logic [7:0] dma_paddr,
output logic addr_canonical
);
assign dma_paddr = apb_paddr[7:0];
assign addr_canonical = (apb_paddr[11:8] == 4'h0);
endmodule# not-run: NanoSoC wrapper census, NanoSoC teaching values
DMA APB slice: 12 bits to 8 bits, 16 alias images, canonical when bits [11:8] are zero
Clock enables: CLK_EN bit 0 (DMA), bit 1 (stream bridge), reset value 0x3 (both on)
Reset entry: rst_sys_n with two-flop synchronised release into DMA rst_n
Stream link: only TDATA, TVALID, TREADY, TLAST; no sideband on either end, absence recorded in the connectivity table
Isolation: irq_dma and irq_sbr through clamp-to-0 cells, 2 of the 114 total
Secure filter: SRAM1 and RSTPWR deny non-secure (AxPROT[1] = 1), DMA has no PPROTThe six wrappers above each present, each with the reason it exists written beside it.
The alias images drawn on the map as aliases with the canonical range marked, matching the memory-map section exactly.
The 114-cell isolation count reconciled: 47 APB-bridge outputs, 52 SRAM0 macro signals, 13 ROM signals and 2 interrupts.
Probe the alias from software: read DMA STATUS at 0x4000_0004 and at 0x4000_0204 and confirm both return the same value, then confirm the project rule forbids the second address everywhere headers and tests are generated. Toggle each CLK_EN bit and confirm the corresponding clock stops and restarts; assert reset for 16 domain cycles and confirm the synchronised release the block cannot provide itself. The clock-gating case is worth a directed test of its own (see the pitfall). Two interrupts through isolation can be checked by forcing the switchable domain off in simulation and confirming both controller inputs read zero.
The wrapper exports the canonical flag, the lint rule consumes it statically, and the connectivity test from the next topic proves no slave input depends on those bits. Software is additionally restricted to the first image, 0x4000_0000 to 0x4000_00FF.