Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutRoadmapCareersInternshipsFAQContactPrivacyTerms
Skip to lesson

Course contents

  • How to Use This Course
  • The NanoSoC Tour
  • Reading Path
  • SoC Glossary10
  • SoC Metrics Reference
  • SoC Cheatsheet
  • What SoC Integration Is12
  • Architecture and Budgets21
  • Memory Maps and Address Decode26
  • Interconnect and Bus Fabrics26
  • Clock and Reset Architecture24
  • Power Architecture21
  • Interrupts, DMA and Peripherals15
  • Memories, Boot and Security21
  • IP Integration and Handoff21
  • Top-Level Verification and Bring-up21
    • SoC Verification Strategy
    • Integration and Connectivity Tests
      • Register Access Sweeps
      • Address-Map and Interrupt Wiring Checks
      • Reset, Clock and Power Sanity
    • Firmware Co-Simulation
    • Performance Verification
    • Gate-Level and Power-Aware Simulation
    • Emulation and FPGA Prototyping
    • Bring-Up Readiness
  • Package, Pads and I/O18
  • Chip Signoff and Tapeout18
  • SoC Interview Prep16
  • Capstone: Integrate NanoSoC14
Loading lesson

←Integration and Connectivity Tests
  1. Topics
  2. SoC Design
  3. Top-Level Verification and Bring-up
  4. Integration and Connectivity Tests
  5. Register Access Sweeps
On this page

    Part 10 of 14, lesson 4 of 21Part 10 of 14/Top-Level Verification and Bring-up/Lesson 4 of 21All levels

    Register Access Sweeps

    Reset values, access types and the three DMA traps, swept per register with a checker script.

    Why it matters

    The first driver ever written for NanoSoC talks to the DMA, and three of its traps are easy to miss because nothing reports them: LEN and KEY writes vanish while BUSY with no error, a stale ERR holds the interrupt high after DONE is cleared, and writing CTRL with 0x1 clears the interrupt enable as a side effect. A register sweep finds all three in microseconds by reading back everything the register tables promise. Its one job is the sweep method: what to touch, in what order, and what each mismatch means.

    The core idea

    A sweep visits every implemented register three times. First reset values: after any reset, read each register and compare against the documented value — DMA CTRL reads 0x0 with bit 0 always zero, STATUS 0, LEN 0, KEY 0, COUNT 0, SBR CTRL 0x4 with NS set, UART BAUDDIV 0xD, CLK_EN 0x3. Second access types: write 1 to each W1C bit and confirm only that bit clears, write to each read-only field and confirm nothing changes, and write LEN and KEY while BUSY to confirm they are silently ignored — the ignored write is correct behaviour, and the sweep documents it instead of tripping on it. Third the traps: start a zero-length job and confirm DONE without BUSY, then clear DONE and ERR with 0x6 and confirm the interrupt drops only when both are gone.

    The sweep also has a price, which the plan uses: a DMA or SBR register access is 125 ns from the CPU, a clk_per register (INTC, GPIO, UART, SPI, RSTPWR) is 281.25 ns, so a 40-register sweep of the mixed set is about 7.5 microseconds of simulated time. The sweep order matters because registers have side effects: read STATUS before clearing it, and never sweep CTRL bit 0 (GO) with a real LEN loaded unless the test means to start a job. Unmapped offsets must answer PSLVERR — offsets 0x14 to 0xFF in the DMA slot, the reserved APB slots — and the sweep proves a sample of them rather than assuming the decoder.

    example.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    # Register sweep against a behavioural model of the DMA registers (register
    # map). The sweep is a function of the device, so it can be run on a
    # faulty device and must fail. NanoSoC teaching values.
    EXPECT_RESET = {0x00: 0x0, 0x04: 0x0, 0x08: 0x0, 0x0C: 0x0, 0x10: 0x0}
    class Dma:
        def __init__(self, reset_key=0, ignore_busy_len=True):
            self.irq_en, self.busy, self.done, self.err = 0, 0, 0, 0
            self.len, self.key, self.count = 0, reset_key, 0
            self.ignore_busy_len = ignore_busy_len
        def read(self, off):
            if off == 0x00: return self.irq_en << 1
            if off == 0x04: return self.busy | self.done << 1 | self.err << 2
            if off == 0x08: return self.len
            if off == 0x0C: return self.key
            if off == 0x10: return self.count
            return "PSLVERR"
        def write(self, off, val):
            if off == 0x00:
                self.irq_en = (val >> 1) & 1 # every write copies bit 1
                if val & 1 and not self.busy and self.len:
                    self.busy, self.done, self.count = 1, 0, 0
            elif off == 0x04:
                if val & 2: self.done = 0
                if val & 4: self.err = 0
            elif off == 0x08 and not (self.busy and self.ignore_busy_len):
                self.len = val & 0xFFFF
            elif off == 0x0C and not self.busy:
                self.key = val
    def sweep(dut):
        bad = [hex(o) for o, want in EXPECT_RESET.items() if dut.read(o) != want]
        bad += [hex(o) for o in (0x01, 0x14, 0x20, 0xFF) if dut.read(o) != "PSLVERR"]
        dut.write(0x08, 64); dut.write(0x00, 0x3) # LEN, then GO with IRQ_EN
        if dut.read(0x04) & 1 != 1: bad.append("busy-after-go")
        dut.write(0x08, 8) # LEN write while BUSY must be silently ignored
        if dut.read(0x08) != 64: bad.append("len-write-while-busy")
        dut.write(0x00, 0x1) # GO with bit 1 clear: IRQ_EN is rewritten to 0
        if dut.read(0x00) != 0: bad.append("ctrl-mirror")
        return bad
    assert sweep(Dma()) == []
    assert sweep(Dma(reset_key=1)) == ["0xc"] # a reset-value fault names its register
    assert "len-write-while-busy" in sweep(Dma(ignore_busy_len=False))
    print("PASS: sweep clean on the model; a wrong KEY reset and an accepted BUSY write are caught")

    What the review looks for

    • The sweep table lists every register with reset value, access type and side effect, each traced to the register tables.

    • BUSY-ignored writes and the sticky ERR are asserted as correct behaviour, not flagged as failures.

    • A sample of unmapped offsets proves PSLVERR, including one alias-image address used only by the sweep.

    Verify and debug

    A reset-value mismatch names its field: check the reset branch of the RTL for that flop, then the synchronised release that should have cleared it. If all values read as zero, suspect the read path rather than the resets — a dead PREADY or a gated clock returns zeros that look like correct resets. If only one block mismatches, check that block's reset net membership before suspecting its logic.

    Address truncation and byte-offset wiring, planted bug 4: the integrator connects word addresses where the DMA decodes byte offsets, so every register except CTRL answers PSLVERR. The sweep catches it on the first read of any register but CTRL; the fix is apb_paddr bits 7 down to 0 into the DMA, with a lint rule against width mismatch.

    If asked what a register sweep proves, answer reset values, access types and error responses — then volunteer the DMA triple: silent BUSY writes, sticky ERR, and the CTRL mirror that rewrites IRQ_EN on every write.

    Check yourself The sweep reads DMA STATUS as 0x4 after a job that ended early. What does a driver write to STATUS after every job, and why that value?

    0x6: write 1 to clear to bits 1 and 2, clearing DONE and ERR together whichever outcome occurred. Clearing only DONE leaves a stale ERR set and the interrupt asserted, which is planted bug 9 in its interrupt form.

    Related topics

    • Next: Address-Map and Interrupt Wiring Checks

    • Memory Maps: Address and Register Sweeps

    • UVM: Reg Adapter reg2bus and bus2reg

    • Verification First Principles: SoC and Software-Driven Tests

    Previous

    196 / 289

    Next: Address-Map and Interrupt Wiring Checks

    Up next

    Up nextAddress-Map and Interrupt Wiring Checks

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error

    See also

    • Reset, Clock and Power Sanity