OCAH UART & Log Engine Wrapper

1. Description

The OCAH UART & Log Engine Wrapper is a hardware module that integrates an UART 16550 with a Log Engine. This wrapper is designed to facilitate communication between the UART and the log engine, allowing for logging capabilities.

2. Features

The features of this design include:

  • An UART 16550

  • An optional Log Engine

  • Configurable APB4 or AXI4-Lite register interface

3. Parameters and Ports

The parameters and ports of uart_log_engine_wrap are listed in uart_log_engine_wrap.

LOG_ENGINE_FIFO_DEPTH must be a power of 2 greater than or equal to 16.

4. Registers — LCR.DLAB=0, Read Direction

The UART 16550 follows the 8250 layout: single offsets map to different registers by access direction and by LCR.DLAB. This table is the LCR.DLAB=0 read view at wrapper offset +0x100; write-only and divisor-latch aliases at the same offsets are in the next section. When this wrapper is arrayed by uart_wrap, instance N adds a further N * 0x400.

UART Log Engine Wrapper Address Map

Composes the UART 16550 core, log engine, and their control registers for one UART instance.

Register Arrays:

  • LOG_CTRL[16]: 16 registers, base 0x240, stride 0x4

Register List:

Table 1. UART Log Engine Wrapper Address Map register list
AddressNameAccessDescription
0x0uart_log_engine_ctrl.CTRLRWControl Register
0x100RBRRReceiver Buffer Register
0x104IERRWInterrupt Enable Register
0x108IIRRInterrupt Identification Register
0x10CLCRRWLine Control Register
0x110MCRRWModem Control Register
0x114LSRRLine Status Register
0x118MSRRModem Status Register
0x11CSCRRWScratch Register
0x120ECRRWExtended Control Register
0x124ITRRWInterrupt Test Register
0x200log_engine.CTRLRWControl Register
0x204LOG_REGION_SIZERWLog Region Size Register
0x208LOG_REGION_ADDRRWLog Region Address Register
0x210LOG_WRITE_ADDRRWLog Write Address Register
0x214INTR_STATUSRWInterrupt Status Register
0x218INTR_ENABLERWInterrupt Enable Register
0x21CINTR_TESTWInterrupt Test Register
0x240 - 0x27CLOG_CTRL[16]RWLog Control Register

Register Details:

uart_log_engine_ctrl.CTRL

Table 2. uart_log_engine_wrap.uart_log_engine_ctrl.CTRL fields
BitsFieldAccessResetDescription
31:1Reserved--Reserved
0UART_ENRW0x0UART Enable. When set, the pad-mux downstream will be forced to accept UART
traffic.

RBR

Table 3. uart_log_engine_wrap.RBR fields
BitsFieldAccessResetDescription
31:8Reserved--Reserved
7:0DATAR RMOD0x0Received Data. Contains a received character. If FIFOs are enabled, this field
points to the bottom of the RX FIFO. Otherwise, this field points to a single-
byte Receiver Buffer Register.

IER

Table 4. uart_log_engine_wrap.IER fields
BitsFieldAccessResetDescription
31:5Reserved--Reserved
4EFEIRW0x0Enable FIFO Error Interrupt.
3EDSSIRW0x0Enable (Delta Status of) Modem Status Interrupt.
2ELSIRW0x0Enable (Receiver) Line Status Interrupt.
1ETBEIRW0x0Enable Transmitter Buffer Empty (Transmitter Holding Register Empty)
Interrupt.
0ERBFIRW0x0Enable Receiver Buffer Full (Received Data Ready) Interrupt.

IIR

Table 5. uart_log_engine_wrap.IIR fields
BitsFieldAccessResetDescription
31:8Reserved--Reserved
7:6FIFOS_ENABLEDR0x0FIFOs Enabled:
* `0x0` - FIFOs are disabled
* `0x3` - FIFOs are enabled
5:4Reserved--Reserved
3:1INTERRUPT_IDR0x0Interrupt ID:
* `0x7` - FIFO Error Interrupt (priority 0)
* `0x3` - Receiver Line Status Interrupt (priority 1)
* `0x6` - Reception Timeout Interrupt (priority 2)
* `0x2` - Received Data Ready Interrupt (priority 3)
* `0x1` - Transmitter Holding Register Empty Interrupt (priority 4)
* `0x0` - Modem Status Interrupt (priority 5)
0INTERRUPT_PENDINGR0x1Interrupt Pending. Active-low.

LCR

Table 6. uart_log_engine_wrap.LCR fields
BitsFieldAccessResetDescription
31:8Reserved--Reserved
7DLABRW0x0Divisor Latch Access Bit. If set, allows access to the `DLL` and `DLM` registers
when accessing addresses `0x0` and `0x4`, respectively. If unset, allows access
to the `THR`, `RBR`, and `IIR` registers.
6SET_BREAKRW0x0Set Break. If set, forces the `tx_o` output to `0` to cause a break condition
on the receiving UART.
5STICK_PARITYRW0x0Stick Parity. If set, forces the transmit and received parity bits to be `0` if
even parity is selected and `1` if odd parity is selected.
4EPSRW0x0Even Parity Select:
* `1` - even parity
* `0` - odd parity
3PENRW0x0Parity Enable.
2STBRW0x0Stop Bits:
* `0` - 1 stop bit.
* `1` - 2 stop bits (or 1.5 stop bits if word length is set to 5 bits)
1:0WLSRW0x0Word Length Select:
* `0x0` - 5 bits per character
* `0x1` - 6 bits per character
* `0x2` - 7 bits per character
* `0x3` - 8 bits per character

MCR

Table 7. uart_log_engine_wrap.MCR fields
BitsFieldAccessResetDescription
31:6Reserved--Reserved
5LINE_LOOPBACKRW0x0Line Loopback. If set, the `rx_i` input is internally connected to the
`tx_o` output.
4LOOPRW0x0System Loopback. If set, the transmitter is internally connected to the
receiver. The `tx_o` output is set to `1`.
3OUT2RW0x0User Output 2. Writing to this bit drives the `out2_no` in the opposite
polarity.
2OUT1RW0x0User Output 1. Writing to this bit drives the `out1_no` in the opposite
polarity.
1RTSRW0x0Request to Send. Writing to this bit drives the `rts_no` output in the opposite
polarity.
0DTRRW0x0Data Terminal Ready. Writing to this bit drives the `dtr_no` output in the
opposite polarity.

LSR

Table 8. uart_log_engine_wrap.LSR fields
BitsFieldAccessResetDescription
31:8Reserved--Reserved
7ERROR_IN_RCVR_FIFOR0x0Error in Receiver FIFO. When set, indicates that the receiver FIFO or (RBR in
non-FIFO mode) has the parity, framing, or break error. In other words, at
least one of the PE, FE, and BI bits is set.
6TEMTR0x1Transmitter Empty. When set, indicates that the transmitter shift register and
the transmitter FIFO (or THR in non-FIFO mode) are empty.
5THRER0x1Transmitter Holding Register Empty. When set, indicates that the TX FIFO (or
THR in non-FIFO mode) is empty. Clearing the Transmitter Holding Register Empty
Interrupt does NOT clear this bit.
4BIR RC0x0Break Interrupt. When set, indicates that the `rx_i` input is `0` for an entire
frame's time (start + data + parity + stop bits). In FIFO mode, this bit set
when the character reaches the top of the receiver FIFO. In non-FIFO mode, this
bit is set when the character enters the RBR. This bit triggers the Receiver
Line Status Interrupt.
3FER RC0x0Framing Error. When set, indicates that the received character is missing a
stop bit. In FIFO mode, this bit is set when the character reaches the top of
the FIFO. In non-FIFO mode, this bit is set when the character enters the RBR.
This bit triggers the Receiver Line Status Interrupt.
2PER RC0x0Parity Error. When set, indicates that the character at the top of the receiver
FIFO (or RBR in non-FIFO mode) has a parity error. This bit triggers the
Receiver Line Status Interrupt.
1OER RC0x0Overrun Error. When set, indicates that the RX FIFO (or Receiver Buffer
Register in Non-FIFO Mode) is full when new character is received. In FIFO Mode, the new character
is dropped. In non-FIFO mode, the existing character in the RBR is overwritten.
This bit triggers the Receiver Line Status Interrupt.
0DRR0x0Data Ready. When set, indicates that the RX FIFO (or RBR in non-FIFO
mode) contains data.

MSR

Table 9. uart_log_engine_wrap.MSR fields
BitsFieldAccessResetDescription
31:8Reserved--Reserved
7DCDR0x0Data Carrier Detect. This bit reflects the `dcd_ni` input in the opposite
polarity, so it reads `1` while a carrier is detected.
6RIR0x0Ring Indicator. This bit reflects the `ri_ni` input in the opposite polarity, so
it reads `1` while the remote modem signals an incoming call.
5DSRR0x0Data Set Ready. This bit reflects the `dsr_ni` input in the opposite polarity,
so it reads `1` while the remote modem is connected and ready.
4CTSR0x0Clear to Send. This bit reflects the `cts_ni` input in the opposite polarity, so
it reads `1` while the remote device is ready to receive data.
3DDCDR RC0x0Delta Data Carrier Detect. When set, indicates that the `DCD` bit has changed
since the last time this register was read. This bit triggers the Modem Status
Interrupt.
2TERIR RC0x0Trailing Edge Ring Indicator. When set, indicates that the `RI` bit has changed
from a `1` to a `0`. This bit triggers the Modem Status Interrupt.
1DDSRR RC0x0Delta Data Set Ready. When set, indicates that the `DSR` bit has changed since
the last time this register was read. This bit triggers the Modem Status
Interrupt.
0DCTSR RC0x0Delta Clear to Send. When set, indicates that the `CTS` bit has changed since
the last time this register was read. This bit triggers the Modem Status
Interrupt.

SCR

Table 10. uart_log_engine_wrap.SCR fields
BitsFieldAccessResetDescription
31:8Reserved--Reserved
7:0SCRRW0x0Scratch. Holds user data.

ECR

Table 11. uart_log_engine_wrap.ECR fields
BitsFieldAccessResetDescription
31:2Reserved--Reserved
1:0RCVR_TRIGGER_MS2BRW0x0Receiver FIFO Trigger Level Most Significant 2 Bits. To configure the least
significant 2 bits, use the `FCR.RCVR_TRIGGER` register field. The
configurations for the trigger levels are:
* `0x0` - 1 character
* `0x1` - 4 characters
* `0x2` - 8 characters
* `0x3` - 14 characters
* `0x4` - 32 characters
* `0x5` - 64 characters
* `0x6` - 128 characters
* `0x7` - 256 characters
* `0x8` - 512 characters
* `0x9` - 1024 characters
* `0xA` - 2048 characters
* `0xB` - 4096 characters

ITR

Table 12. uart_log_engine_wrap.ITR fields
BitsFieldAccessResetDescription
31:6Reserved--Reserved
5TRTIRW0x0Test Reception Timeout Interrupt. Writing a `1` forces the interrupt and
writing `0` releases it.
4TFEIRW0x0Test FIFO Error Interrupt. Writing `1` forces the interrupt and writing `0`
releases it.
3TDSSIRW0x0Test (Delta Status of) Modem Status Interrupt. Writing `1` forces the
interrupt and writing `0` releases it.
2TLSIRW0x0Test (Receiver) Line Status Interrupt. Writing `1` forces the interrupt and
writing `0` releases it.
1TTBEIRW0x0Test Transmitter Buffer Empty (Transmitter Holding Register Empty) Interrupt.
Writing `1` forces the interrupt and writing `0` releases it.
0TRBFIRW0x0Test Receiver Buffer Full (Received Data Ready) Interrupt. Writing `1` forces
the interrupt and writing `0` releases it.

log_engine.CTRL

Table 13. uart_log_engine_wrap.log_engine.CTRL fields
BitsFieldAccessResetDescription
31:1Reserved--Reserved
0ENRW0x0Log Engine Enable. When set, enables the Log Engine. When cleared, the engine
stops fetching and writing, discards buffered log data and resets transfer
progress. Configuration and pending LOG_LEN values are retained, so a pending
entry restarts from the start of its slot when the engine is enabled again.
Clearing does not wait for outstanding bus responses.

LOG_REGION_SIZE

Table 14. uart_log_engine_wrap.LOG_REGION_SIZE fields
BitsFieldAccessResetDescription
31:20Reserved--Reserved
19:0LOG_REGION_SIZERW0x0Log region size in bytes. Supported values are at most 512 KiB and aligned
to 128 bytes (16 slots times the 8-byte fetch beat). If software programs a
larger value, RTL clamps the effective region to 512 KiB. For a value that is
not 128-byte aligned, RTL divides the effective region among the 16 slots and
rounds each slot's transferable capacity down to complete 8-byte fetch beats.
A requested LOG_LEN above that capacity is clamped to the capacity.

LOG_REGION_ADDR

Table 15. uart_log_engine_wrap.LOG_REGION_ADDR fields
BitsFieldAccessResetDescription
63:56RESERVEDR0x0Reserved. Reads as zero; writes are ignored.
55:32LOG_REGION_ADDR_HIRW0x0Log Region Start Address High. Contains fabric address bits [55:32].
31:0LOG_REGION_ADDR_LORW0x0Log Region Start Address Low.

LOG_WRITE_ADDR

Table 16. uart_log_engine_wrap.LOG_WRITE_ADDR fields
BitsFieldAccessResetDescription
31:0LOG_WRITE_ADDRRW0x0Log Write Address. This is the address where the log data is written to.

INTR_STATUS

Table 17. uart_log_engine_wrap.INTR_STATUS fields
BitsFieldAccessResetDescription
31:5Reserved--Reserved
4LOG_WRITE_ERRRW1C0x0Log Write Error Interrupt. Asserted when the bus for writing log data returns
an error.
3:1Reserved--Reserved
0LOG_FETCH_ERRRW1C0x0Log Fetch Error Interrupt. Asserted when the bus for fetching log data returns
an error.

INTR_ENABLE

Table 18. uart_log_engine_wrap.INTR_ENABLE fields
BitsFieldAccessResetDescription
31:5Reserved--Reserved
4LOG_WRITE_ERRRW0x0Log Write Error Interrupt Enable.
3:1Reserved--Reserved
0LOG_FETCH_ERRRW0x0Log Fetch Error Interrupt Enable.

INTR_TEST

Table 19. uart_log_engine_wrap.INTR_TEST fields
BitsFieldAccessResetDescription
31:5Reserved--Reserved
4LOG_WRITE_ERRW 1P0x0Log Write Error Interrupt Test. Writing `1` forces the interrupt.
3:1Reserved--Reserved
0LOG_FETCH_ERRW 1P0x0Log Fetch Error Interrupt Test. Writing `1` forces the interrupt.

LOG_CTRL[16]

Table 20. uart_log_engine_wrap.LOG_CTRL[16] fields
BitsFieldAccessResetDescription
31:16Reserved--Reserved
15:0LOG_LENRW0x0Log Length. Writing a nonzero value representing the log length in bytes to this field
starts the log transfer process. The field holds the requested length until the
transfer completes, when hardware clears it to zero; it is not a remaining-byte
counter. There are 16 copies of this register, each representing
a log entry. The log entries go through round robin arbitration.

5. Registers — Write-Only and LCR.DLAB=1 Views

THR (write) shares +0x100 with RBR (read); FCR (write) shares +0x108 with IIR (read); DLL/DLM occupy +0x100/+0x104 when LCR.DLAB=1.

UART 16550 Main Write-Only Address Map

Contains the write-only registers. THR is accessible only when `LCR.DLAB = 0`;
FCR is writable for either `LCR.DLAB` value.

Register List:

Table 21. UART 16550 Main Write-Only Address Map register list
AddressNameAccessDescription
0x0THRWTransmitter Holding Register
0x8FCRWFIFO Control Register

Register Details:

THR

Table 22. uart_16550_main_wo.THR fields
BitsFieldAccessResetDescription
31:8Reserved--Reserved
7:0DATAW WMOD0x0Transmit Data. Holds a character to be transmitted. If FIFOs are enabled, this
field points to the top of the TX FIFO. Otherwise, this field points to a
single-byte Transmitter Holding Register.

FCR

Table 23. uart_16550_main_wo.FCR fields
BitsFieldAccessResetDescription
31:8Reserved--Reserved
7:6RCVR_TRIGGERW0x0Receiver FIFO Trigger Level (Least Significant 2 Bits). To configure the most
significant 2 bits, use the `ECR.RCVR_TRIGGER_MS2B` register field. The
configurations for the trigger levels are:
* `0x0` - 1 character
* `0x1` - 4 characters
* `0x2` - 8 characters
* `0x3` - 14 characters
* `0x4` - 32 characters
* `0x5` - 64 characters
* `0x6` - 128 characters
* `0x7` - 256 characters
* `0x8` - 512 characters
* `0x9` - 1024 characters
* `0xA` - 2048 characters
* `0xB` - 4096 characters
5:4Reserved--Reserved
3DMA_MODE_SELECTW0x0DMA mode select:
* `0` - DMA Mode 0
* `1` - DMA Mode 1
2XMIT_FIFO_RESETW 1P0x0Transmitter FIFO Reset. Writing `1` clears the TX FIFO.
1RCVR_FIFO_RESETW 1P0x0Receiver FIFO Reset. Writing `1` clears the RX FIFO.
0FIFO_ENABLEW0x0FIFO Enable. When set, enables the TX and RX FIFOs (FIFO Mode). When unset,
disables the FIFOs (Non-FIFO Mode).

UART 16550 Divisor Latch Address Map

Contains the registers accessible only when `LCR.DLAB = 1`.

Register List:

Table 24. UART 16550 Divisor Latch Address Map register list
AddressNameAccessDescription
0x0DLLRWDivisor Latch Least Significant Byte Register
0x4DLMRWDivisor Latch Most Significant Byte Register

Register Details:

DLL

Table 25. uart_16550_dl.DLL fields
BitsFieldAccessResetDescription
31:8Reserved--Reserved
7:0DLLRW0x0Divisor Latch Least Significant Byte. Baud rate is calculated as
`baud_rate = system_clock_frequency / (16 * (divisor + 1))`. When the divisor is set
to `0`, the transmitter and receiver logic are disabled.

DLM

Table 26. uart_16550_dl.DLM fields
BitsFieldAccessResetDescription
31:8Reserved--Reserved
7:0DLMRW0x0Divisor Latch Most Significant Byte. Baud rate is calculated as
`baud_rate = system_clock_frequency / (16 * (divisor + 1))`. When the divisor is set
to `0`, the transmitter and receiver logic are disabled.

7. Shared Transmit Holding Register

When the Log Engine is enabled (GEN_LOG_ENGINE=1, the default), the UART transmit holding register (THR, at wrapper offset 0x100) is written by two initiators: the CPU through the register interface, and the Log Engine through an internal 2:1 AXI4-Lite arbiter. The Log Engine’s write target is not fixed in hardware — it is taken from LOG_WRITE_ADDR (offset 0x210), which firmware must program to the THR address for log output to reach the UART.

The arbiter serialises the two initiators, but no hardware lock protects the shared register. The Log Engine configuration sequence in the Programmer’s Guide states the resulting firmware rules.