The specification says the ROM prints a banner over the UART during boot. That sentence hides four budgets: the baud rate the divider must produce, the error the receiver tolerates, the time the banner steals from boot, and the clock accuracy the crystal must hold. None is written down, all are load-bearing, and the integrator is the one who writes them down. The conversion below is the same every time: requirement, constraint, budget, owner, check.
Every convertible requirement passes through four steps. First, restate it as a checkable claim with a number and a condition: not fast boot but at most 20 ms from pad reset release to the application jump with an 8 KB image. Second, derive the constraint it places on hardware: the SPI load alone takes 10.928 ms at 6 Mb/s, so the rate, the image size and the command overhead are all constrained. Third, split the constraint into per-part budgets with owners: the SPI owner owns the 6 Mb/s, software owns the image size, the ROM owner owns the command bytes. Fourth, name the check that proves each budget: the rate measured on the bench, the image size asserted by the build, the boot timer in the bring-up test. A requirement that cannot pass all four steps is not a requirement yet; it is a wish, and wishes go back to the architect.
Requirement | Constraint | Budget and owner | Check |
|---|---|---|---|
Debug output readable at 115200 baud | Divider must hit the rate within receiver tolerance | BAUDDIV 13 gives 115,384.6 baud, error plus 0.16%, peripheral owner | Loopback test at temperature corners |
Second-stage image loads over SPI | 6 Mb/s with a 4-byte command | CLKDIV 1, image 8 KB, SPI and software owners | Timed load in the boot test |
Banner confirms life during boot | 16 characters at 10 bits each | 1,386.667 microseconds of boot, ROM owner | Boot timer with and without the banner |
Reset button debounces mechanically | Input low longer than any bounce | 16 peripheral clocks, 666.7 ns, integrator | Glitch-injection on the pin model |
The script below derives the three communication budgets from the 24 MHz peripheral clock and asserts the NanoSoC values: the baud rate and its error, the SPI bit rate, the 16-character banner length, and the banner's boot cost. Note the banner string: Python needs the two characters backslash-n, written with a doubled backslash inside the page source, which is the escaping rule this course follows everywhere.
CLK_PER = 24_000_000 # Hz; crystal, bypasses the PLL
bauddiv = 13 # UART reset value
baud = CLK_PER / (16 * bauddiv)
assert abs(baud - 115384.6) < 0.1, baud
err = (baud - 115200) / 115200
assert abs(err - 0.0016) < 0.0001, err # +0.16% vs 115200
clkdiv = 1 # SPI reset value
spi = CLK_PER / (2 * (clkdiv + 1))
assert spi == 6_000_000 # 6 Mb/s
banner = "NanoSoC boot ok\n" # backslash-n: 15 chars + newline
assert len(banner) == 16
banner_us = len(banner) * 10 / baud * 1e6
assert abs(banner_us - 1386.667) < 0.01, banner_us
image_us = (8192 + 4) * 8 / spi * 1e6 # 8 KB + command over SPI
assert abs(image_us - 10928.0) < 0.1, image_us
print("PASS: 115384.6 baud +0.16%; SPI 6 Mb/s; banner 16 chars, 1386.7 us")Every specification paragraph maps to at least one row of the budget ledger, or is sent back as a wish.
Every budget names an owner and a check; a budget with neither is a hope.
Derived numbers quote the NanoSoC specification or are labelled illustrative, never both and never neither.
When a budget is missed, walk back up the chain before renegotiating: remeasure the check, confirm the constraint arithmetic, and only then reopen the requirement. Most missed budgets are mismeasured checks, not wrong requirements. For workload-driven architecture context see Workload Taxonomy; for the system-level trade-offs behind the requirements see SoC Architecture Tradeoffs.
The ROM owner proposes, the integrator decides: the banner owns 1.39 ms of a 12.58 ms boot, so doubling it costs 1.39 ms against the boot requirement. If the requirement still holds, approve; otherwise shorten the banner or raise the baud rate, each with its own owner and check.