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.

Note

Originally, the address decoder was also intended to handle SD Card and SPI Flash memory types, but these have been removed as the speed gains compared to doing this in software are minimal for the use cases of these memory types (load BDOS from SPI Flash at boot, read/write file system from SD Card). Therefore, more address space is now available for SDRAM (more than I will ever need). The SPI Flash and SD Card will be accessed through I/O mapped registers (hardware SPI).

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_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 0x6FFFFFF 112 MiW @ 32 bit SDRAM Main system memory
0x7000000 0x77FFFFF N/A I/O Devices Memory-mapped peripherals
0x7800000 0x78FFFFF 1 KiW @ 32 bit ROM Boot ROM
0x7900000 0x79FFFFF 1056 W @ 32 bit VRAM32 32-bit video memory
0x7A00000 0x7AFFFFF 7138 W @ 8 bit VRAM8 8-bit video memory
0x7B00000 0x7BFFFFF 76800 W @ 8 bit VRAMPX Pixel buffer
0x7C00000 0xFFFFFFFF N/A 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_io)       ? mem_address: // For I/O we want to keep the full address to avoid confusion
    (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;