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

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • RTL Foundations36
  • Combinational Design25
  • Sequential Design27
  • FSM & Control27
  • Timing & Clocking39
  • Reset & CDC34
  • Memory & Buses57
    • SRAM and ROM
    • Register Files
    • Valid/Ready Handshake
    • AXI-Lite
    • AXI-Stream
    • Bus Integration
      • Address Decode
      • Mux Trees and Read Paths
      • Error Paths and Timeouts
      • Arbitration
      • Integration Checklist
      • An End-to-End Bus Example
    • Synchronous FIFO
    • Register-Map and CSR RTL
    • Memory Reliability
    • Peripheral RTL Integration
    • Full AXI4: RTL Roadmap
  • Advanced RTL28
  • Senior & Interview76
  • Glossary and Notation
Loading lesson

‹Bus Integration
  1. Topics
  2. RTL Design
  3. Memory & Buses
  4. Bus Integration
  5. Address Decode

Part 7 · Memory & Buses · Intermediate

Address Decode

Base and limit pairs, one-hot selects and a default slave, proven with mapped, boundary and unmapped tests.

On this page

    Why this matters

    Two overlapping address ranges wake two slaves at once. An unmapped address with no default response leaves the master hung or reading a false zero, and adjacent ranges hide off-by-one errors.

    After this lesson you can: write base and limit address decode with a one-hot select and a default error path, and choose the addresses that expose off-by-one errors.

    Base and limit pairs

    Each slave owns an address range written as an explicit localparam base and limit pair. The pairs live in one place so the map can be reviewed against the software headers.

    Ranges must not overlap. An overlap wakes two slaves at once, which the select check below catches.

    Slave

    Base

    Limit

    Select

    UART

    32'h0000_1000

    32'h0000_1FFF

    sel0

    SPI

    32'h0000_2000

    32'h0000_2FFF

    sel1

    Default

    —

    —

    default_err

    One-hot select and the default slave

    The decoder compares the address against every pair and raises one select per slave. One-hot internal selects keep the comparison shallow on wide maps.

    Unmapped addresses need a defined error completion. The AND-OR datapath below returns zero when nothing is selected; it does not electrically float. Without default response control, the master may hang or receive a false successful zero. An electrically floating tri-state bus is a different architecture.

    The bottom three rows show which slave is selected. Slot 3 is the unmapped access.

    • Slot 0: addr 0x1000 is the UART base, so sel0 is 1.

    • Slot 1: addr 0x2000 is the SPI base, so sel1 is 1.

    • Slot 2: addr 0x1FFF is the UART limit boundary, so sel0 is still 1.

    • Slot 3: addr 0x3000 matches nothing, so sel0 and sel1 are 0 and default_err is 1.

    • Slot 4: addr 0x1004 returns to the UART range, so sel0 is 1 again.

    Common mistakes

    Common pitfall

    Adjacent ranges hide off-by-one errors: the limit of one region plus one is the base of the next. Test the limit, the base and one address past the limit, not just the middle of each range.

    Check yourself Two selects are high for one address. What is wrong?

    The base and limit pairs overlap. Exactly one select may be high for a mapped address, so an overlap is a map bug, and the testbench flags it with a one-hot check.

    Check yourself The AND-OR map has no default slave and software reads an unmapped address. What happens?

    The data mux parks at zero, but that is not a valid completion contract. Depending on control, the master hangs or mistakes zero for successful data. Supply a default error response; there is no tri-state floating wire in this datapath.

    Testbench

    The decoder plus a testbench that checks corners, sweeps 20000 addresses around the regions against a reference and asserts exactly one select on every mapped access.

    bus_decode.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // bus_decode: base and limit pairs with a one-hot select and a default-slave flag.
    module bus_decode #(
      parameter [31:0] BASE0  = 32'h0000_1000,
      parameter [31:0] LIMIT0 = 32'h0000_1FFF,
      parameter [31:0] BASE1  = 32'h0000_2000,
      parameter [31:0] LIMIT1 = 32'h0000_2FFF
    )(
      input  logic [31:0] addr,
      output logic        sel0, sel1,
      output logic        default_err
    );
      assign sel0 = (addr >= BASE0) && (addr <= LIMIT0);
      assign sel1 = (addr >= BASE1) && (addr <= LIMIT1);
      assign default_err = !(sel0 || sel1);
    endmodule
    

    Remember

    • Keep the base and limit pairs in one place so the map can be checked against the software headers.

    • Exactly one select is high for a mapped address. An overlap is a map bug.

    • An AND-OR read mux returns zero when nothing is selected. That is not a valid completion, so a default slave must return an error.

    Rule of thumb: test the limit, the base and one address past the limit, not just the middle of each range.

    Keep going

    • Practice: AXI4-Lite slave with invalid address protection

    • Interview: run a mock interview on this topic

    Related topics

    • Error Paths and Timeouts

    • Integration Checklist

    Previous

    210 / 350

    Next: Mux Trees and Read Paths

    Up next

    Up nextMux Trees and Read Paths

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Error Paths and Timeouts
    • Arbitration
    • Integration Checklist
    clkaddr100020001fff30001004sel0sel1default_err
    Decode across two mapped accesses, a limit boundary and an unmapped access