Hardware Mailbox

The Hardware Mailbox provides symmetric FIFO-based message queues for inter-CPU communication. Each channel carries 32-bit messages independently. CPU A conventionally sends on channel 0 and receives on channel 1; CPU B does the opposite. Both CPUs access the same register map.

Features

  • Configurable number of symmetric channels (default: 2)

  • Configurable FIFO depth per channel (small / medium / large presets)

  • 32-bit message width matching the bus data width

  • Per-channel status flags (empty, full) and occupancy counter

  • Per-channel interrupt sources: not-empty (data arrived) and not-full (space available)

  • Single combined interrupt output — asserted when any enabled channel interrupt fires

Interrupt Architecture

Each channel has independent irq_pending and irq_mask registers. An interrupt source bit is set when its condition is true and the corresponding mask bit is enabled. The hardware ORs all masked pending bits across all channels into a single interrupt output signal.

In the interrupt service routine, software must read the per-channel irq_pending registers to identify which channel fired, service the condition, and write 1 to the corresponding pending bit to clear it.

Protocol

Send (push):

Write the 32-bit message payload to the channel’s write register. If the FIFO is full, the write is silently dropped. Software should check the full flag in the status register before writing to avoid data loss.

Receive (pop):

Read the channel’s read register to pop one message from the FIFO. The returned value is the message payload. If the FIFO is empty, the read returns stale data. Software should check the empty flag in the status register before reading.

Configuration

Available bus architectures:

  • APB3

  • TileLink

  • Wishbone

By default, all buses are defined with 8 bit address and 32 bit data width.

Parameter

MailboxCtrl.Parameter

Name

Type

Description

Default

depth

Int

FIFO depth per channel. Must be between 1 and 255.

8

channelCount

Int

Number of channels. Must be at least 2.

2

MailboxCtrl.Parameter has predefined presets for common use cases.

object Parameter {
  def small()  = Parameter(depth = 4)
  def medium() = Parameter(depth = 8)
  def large()  = Parameter(depth = 16)
}

Register Mapping

IP Identification:

The register map starts with an IP Identification block to provide all information about the underlying IP core to software drivers. This allows to provide backwards compatible drivers.

IP Identification Registers

Address

Bit

Field

Default

Permission

Description

0x000

31 - 24

API

0x0

Rx

API version of the implemented IP Identification.

23 - 16

Length

0x8

Rx

Length of the IP Identification block in Bytes.

15 - 0

ID

0xF

Rx

IP value of this IP core.

0x004

31 - 24

Major Version

0x1

Rx

Major number if this IP core. Version schema is major.minor.patch.

23 - 16

Minor Version

0x0

Rx

Minor number if this IP core. Version schema is major.minor.patch.

15 - 0

Patch Version

0x0

Rx

Patch number if this IP core. Version schema is major.minor.patch.

Self Disclosure:

Self Disclosure Register

Address

Bit

Field

Default

Permission

Description

0x008

15 - 8

depth

Rx

FIFO depth per channel.

7 - 0

channels

2

Rx

Number of channels.

Status Register:

Status Register

Address

Bit

Field

Default

Permission

Description

0x00C

3

full[1]

0

Rx

Channel 1 FIFO full.

2

full[0]

0

Rx

Channel 0 FIFO full.

1

empty[1]

1

Rx

Channel 1 FIFO empty.

0

empty[0]

1

Rx

Channel 0 FIFO empty.

The status register layout scales with channelCount. Bits [channelCount-1:0] hold the empty flags and bits [2*channelCount-1:channelCount] hold the full flags.

Channel Registers:

Two sets of identical registers, one per channel. Channel 0 starts at 0x010; channel 1 starts at 0x024. The stride between channels is 0x14.

Channel Registers (per channel, base = 0x010 + channel × 0x14)

Address

Bit

Field

Default

Permission

Description

base + 0x00

31 - 0

write

xW

Push a 32-bit message into the channel FIFO. Dropped silently if full.

base + 0x04

31 - 0

read

Rx

Pop a 32-bit message from the channel FIFO. Returns stale data if empty.

base + 0x08

7 - 0

occupancy

0

Rx

Number of messages currently stored in the FIFO.

base + 0x0C

1 - 0

irq_pending

0

RW

Interrupt pending flags. Write 1 to a bit to clear it. Bit 0 = not-empty, bit 1 = not-full. All enabled pending bits across all channels are ORed into the single hardware interrupt output.

base + 0x10

1 - 0

irq_mask

0

RW

Interrupt enable mask. Set a bit to enable the corresponding interrupt source. Bit 0 = not-empty, bit 1 = not-full.