Skip to content

Address decoder

The AddressDecoder module implements the optimized memory map for the B32P2 CPU, determining which memory subsystem should handle a given memory access and whether the access requires multiple cycles to complete. While this is not as flexible as a separate Memory Unit, it removes overhead for a bus interface between the CPU and Memory Unit, allowing for single cycle memory accesses for all SRAM based memory types.

Module Declaration

module AddressDecoder(
    input wire [31:0]   areg_value,      // Base address from register
    input wire [31:0]   const16,         // 16-bit signed offset constant
    input wire          rw,              // Read/write enable

    // Memory type outputs
    output wire         mem_sdram,       // SDRAM access
    output wire         mem_sdcard,      // SD card access  
    output wire         mem_spiflash,    // SPI flash access
    output wire         mem_io,          // I/O device access
    output wire         mem_rom,         // ROM access
    output wire         mem_vram32,      // 32-bit video RAM access
    output wire         mem_vram8,       // 8-bit video RAM access
    output wire         mem_vrampx,      // Pixel video RAM access

    // Timing characteristics
    output wire         mem_multicycle,  // Multi-cycle access indicator

    // Address translation
    output wire [31:0]  mem_local_address // Local address within memory region
);

Memory Map

The B32P2 implements a comprehensive 32-bit memory map covering 4GiB of addressable space:

Start Address End Address Size Memory Type Description
0x0000000 0x3FFFFFF SDRAM Main system memory
0x4000000 0x5FFFFFF SD Card Mass storage interface
0x6000000 0x6FFFFFF SPI Flash Non-volatile storage
0x7000000 0x77FFFFF I/O Devices Memory-mapped peripherals
0x7800000 0x78FFFFF ROM Boot ROM
0x7900000 0x79FFFFF VRAM32 32-bit video memory
0x7A00000 0x7AFFFFF VRAM8 8-bit video memory
0x7B00000 0x7BFFFFF VRAMPX Pixel buffer
0x7C00000 0xFFFFFFFF Unmapped Reserved/future use

Address Calculation

The effective memory address is calculated by adding the base register value and signed offset:

wire [31:0] mem_address = areg_value + const16;

This supports:

  • Base + Offset addressing: Common for array/structure access
  • Signed offsets: Range of 16 bits from base address
  • 32-bit arithmetic: Full address space coverage

Address Translation

Local addresses are generated by subtracting the base address of each memory region:

assign mem_local_address = 
    (mem_sdram)    ? mem_address - 32'h0000000 :
    (mem_sdcard)   ? mem_address - 32'h4000000 :
    (mem_spiflash) ? mem_address - 32'h6000000 :
    (mem_io)       ? mem_address - 32'h7000000 :
    (mem_rom)      ? mem_address - 32'h7800000 :
    (mem_vram32)   ? mem_address - 32'h7900000 :
    (mem_vram8)    ? mem_address - 32'h7A00000 :
    (mem_vrampx)   ? mem_address - 32'h7B00000 :
    32'h0000000;

This provides:

  • Zero-based addressing: Each memory controller sees addresses starting from 0
  • Simplified controller design: Controllers don't need to handle base addresses
  • Address range validation: Prevents out-of-bounds access