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:
| Address | Name | Access | Description |
|---|---|---|---|
| 0x0 | uart_log_engine_ctrl.CTRL | RW | Control Register |
| 0x100 | RBR | R | Receiver Buffer Register |
| 0x104 | IER | RW | Interrupt Enable Register |
| 0x108 | IIR | R | Interrupt Identification Register |
| 0x10C | LCR | RW | Line Control Register |
| 0x110 | MCR | RW | Modem Control Register |
| 0x114 | LSR | R | Line Status Register |
| 0x118 | MSR | R | Modem Status Register |
| 0x11C | SCR | RW | Scratch Register |
| 0x120 | ECR | RW | Extended Control Register |
| 0x124 | ITR | RW | Interrupt Test Register |
| 0x200 | log_engine.CTRL | RW | Control Register |
| 0x204 | LOG_REGION_SIZE | RW | Log Region Size Register |
| 0x208 | LOG_REGION_ADDR | RW | Log Region Address Register |
| 0x210 | LOG_WRITE_ADDR | RW | Log Write Address Register |
| 0x214 | INTR_STATUS | RW | Interrupt Status Register |
| 0x218 | INTR_ENABLE | RW | Interrupt Enable Register |
| 0x21C | INTR_TEST | W | Interrupt Test Register |
| 0x240 - 0x27C | LOG_CTRL[16] | RW | Log Control Register |
Register Details:
uart_log_engine_ctrl.CTRL
| Bits | Field | Access | Reset | Description |
|---|---|---|---|---|
| 31:1 | Reserved | - | - | Reserved |
| 0 | UART_EN | RW | 0x0 | UART Enable. When set, the pad-mux downstream will be forced to accept UART traffic. |
RBR
| Bits | Field | Access | Reset | Description |
|---|---|---|---|---|
| 31:8 | Reserved | - | - | Reserved |
| 7:0 | DATA | R RMOD | 0x0 | Received 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
| Bits | Field | Access | Reset | Description |
|---|---|---|---|---|
| 31:5 | Reserved | - | - | Reserved |
| 4 | EFEI | RW | 0x0 | Enable FIFO Error Interrupt. |
| 3 | EDSSI | RW | 0x0 | Enable (Delta Status of) Modem Status Interrupt. |
| 2 | ELSI | RW | 0x0 | Enable (Receiver) Line Status Interrupt. |
| 1 | ETBEI | RW | 0x0 | Enable Transmitter Buffer Empty (Transmitter Holding Register Empty) Interrupt. |
| 0 | ERBFI | RW | 0x0 | Enable Receiver Buffer Full (Received Data Ready) Interrupt. |
IIR
| Bits | Field | Access | Reset | Description |
|---|---|---|---|---|
| 31:8 | Reserved | - | - | Reserved |
| 7:6 | FIFOS_ENABLED | R | 0x0 | FIFOs Enabled: * `0x0` - FIFOs are disabled * `0x3` - FIFOs are enabled |
| 5:4 | Reserved | - | - | Reserved |
| 3:1 | INTERRUPT_ID | R | 0x0 | Interrupt 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) |
| 0 | INTERRUPT_PENDING | R | 0x1 | Interrupt Pending. Active-low. |
LCR
| Bits | Field | Access | Reset | Description |
|---|---|---|---|---|
| 31:8 | Reserved | - | - | Reserved |
| 7 | DLAB | RW | 0x0 | Divisor 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. |
| 6 | SET_BREAK | RW | 0x0 | Set Break. If set, forces the `tx_o` output to `0` to cause a break condition on the receiving UART. |
| 5 | STICK_PARITY | RW | 0x0 | Stick 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. |
| 4 | EPS | RW | 0x0 | Even Parity Select: * `1` - even parity * `0` - odd parity |
| 3 | PEN | RW | 0x0 | Parity Enable. |
| 2 | STB | RW | 0x0 | Stop Bits: * `0` - 1 stop bit. * `1` - 2 stop bits (or 1.5 stop bits if word length is set to 5 bits) |
| 1:0 | WLS | RW | 0x0 | Word Length Select: * `0x0` - 5 bits per character * `0x1` - 6 bits per character * `0x2` - 7 bits per character * `0x3` - 8 bits per character |
MCR
| Bits | Field | Access | Reset | Description |
|---|---|---|---|---|
| 31:6 | Reserved | - | - | Reserved |
| 5 | LINE_LOOPBACK | RW | 0x0 | Line Loopback. If set, the `rx_i` input is internally connected to the `tx_o` output. |
| 4 | LOOP | RW | 0x0 | System Loopback. If set, the transmitter is internally connected to the receiver. The `tx_o` output is set to `1`. |
| 3 | OUT2 | RW | 0x0 | User Output 2. Writing to this bit drives the `out2_no` in the opposite polarity. |
| 2 | OUT1 | RW | 0x0 | User Output 1. Writing to this bit drives the `out1_no` in the opposite polarity. |
| 1 | RTS | RW | 0x0 | Request to Send. Writing to this bit drives the `rts_no` output in the opposite polarity. |
| 0 | DTR | RW | 0x0 | Data Terminal Ready. Writing to this bit drives the `dtr_no` output in the opposite polarity. |
LSR
| Bits | Field | Access | Reset | Description |
|---|---|---|---|---|
| 31:8 | Reserved | - | - | Reserved |
| 7 | ERROR_IN_RCVR_FIFO | R | 0x0 | Error 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. |
| 6 | TEMT | R | 0x1 | Transmitter Empty. When set, indicates that the transmitter shift register and the transmitter FIFO (or THR in non-FIFO mode) are empty. |
| 5 | THRE | R | 0x1 | Transmitter 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. |
| 4 | BI | R RC | 0x0 | Break 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. |
| 3 | FE | R RC | 0x0 | Framing 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. |
| 2 | PE | R RC | 0x0 | Parity 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. |
| 1 | OE | R RC | 0x0 | Overrun 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. |
| 0 | DR | R | 0x0 | Data Ready. When set, indicates that the RX FIFO (or RBR in non-FIFO mode) contains data. |
MSR
| Bits | Field | Access | Reset | Description |
|---|---|---|---|---|
| 31:8 | Reserved | - | - | Reserved |
| 7 | DCD | R | 0x0 | Data Carrier Detect. This bit reflects the `dcd_ni` input in the opposite polarity, so it reads `1` while a carrier is detected. |
| 6 | RI | R | 0x0 | Ring Indicator. This bit reflects the `ri_ni` input in the opposite polarity, so it reads `1` while the remote modem signals an incoming call. |
| 5 | DSR | R | 0x0 | Data 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. |
| 4 | CTS | R | 0x0 | Clear 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. |
| 3 | DDCD | R RC | 0x0 | Delta 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. |
| 2 | TERI | R RC | 0x0 | Trailing 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. |
| 1 | DDSR | R RC | 0x0 | Delta 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. |
| 0 | DCTS | R RC | 0x0 | Delta 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
| Bits | Field | Access | Reset | Description |
|---|---|---|---|---|
| 31:8 | Reserved | - | - | Reserved |
| 7:0 | SCR | RW | 0x0 | Scratch. Holds user data. |
ECR
| Bits | Field | Access | Reset | Description |
|---|---|---|---|---|
| 31:2 | Reserved | - | - | Reserved |
| 1:0 | RCVR_TRIGGER_MS2B | RW | 0x0 | Receiver 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
| Bits | Field | Access | Reset | Description |
|---|---|---|---|---|
| 31:6 | Reserved | - | - | Reserved |
| 5 | TRTI | RW | 0x0 | Test Reception Timeout Interrupt. Writing a `1` forces the interrupt and writing `0` releases it. |
| 4 | TFEI | RW | 0x0 | Test FIFO Error Interrupt. Writing `1` forces the interrupt and writing `0` releases it. |
| 3 | TDSSI | RW | 0x0 | Test (Delta Status of) Modem Status Interrupt. Writing `1` forces the interrupt and writing `0` releases it. |
| 2 | TLSI | RW | 0x0 | Test (Receiver) Line Status Interrupt. Writing `1` forces the interrupt and writing `0` releases it. |
| 1 | TTBEI | RW | 0x0 | Test Transmitter Buffer Empty (Transmitter Holding Register Empty) Interrupt. Writing `1` forces the interrupt and writing `0` releases it. |
| 0 | TRBFI | RW | 0x0 | Test Receiver Buffer Full (Received Data Ready) Interrupt. Writing `1` forces the interrupt and writing `0` releases it. |
log_engine.CTRL
| Bits | Field | Access | Reset | Description |
|---|---|---|---|---|
| 31:1 | Reserved | - | - | Reserved |
| 0 | EN | RW | 0x0 | Log 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
| Bits | Field | Access | Reset | Description |
|---|---|---|---|---|
| 31:20 | Reserved | - | - | Reserved |
| 19:0 | LOG_REGION_SIZE | RW | 0x0 | Log 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
| Bits | Field | Access | Reset | Description |
|---|---|---|---|---|
| 63:56 | RESERVED | R | 0x0 | Reserved. Reads as zero; writes are ignored. |
| 55:32 | LOG_REGION_ADDR_HI | RW | 0x0 | Log Region Start Address High. Contains fabric address bits [55:32]. |
| 31:0 | LOG_REGION_ADDR_LO | RW | 0x0 | Log Region Start Address Low. |
LOG_WRITE_ADDR
| Bits | Field | Access | Reset | Description |
|---|---|---|---|---|
| 31:0 | LOG_WRITE_ADDR | RW | 0x0 | Log Write Address. This is the address where the log data is written to. |
INTR_STATUS
| Bits | Field | Access | Reset | Description |
|---|---|---|---|---|
| 31:5 | Reserved | - | - | Reserved |
| 4 | LOG_WRITE_ERR | RW1C | 0x0 | Log Write Error Interrupt. Asserted when the bus for writing log data returns an error. |
| 3:1 | Reserved | - | - | Reserved |
| 0 | LOG_FETCH_ERR | RW1C | 0x0 | Log Fetch Error Interrupt. Asserted when the bus for fetching log data returns an error. |
INTR_ENABLE
| Bits | Field | Access | Reset | Description |
|---|---|---|---|---|
| 31:5 | Reserved | - | - | Reserved |
| 4 | LOG_WRITE_ERR | RW | 0x0 | Log Write Error Interrupt Enable. |
| 3:1 | Reserved | - | - | Reserved |
| 0 | LOG_FETCH_ERR | RW | 0x0 | Log Fetch Error Interrupt Enable. |
INTR_TEST
| Bits | Field | Access | Reset | Description |
|---|---|---|---|---|
| 31:5 | Reserved | - | - | Reserved |
| 4 | LOG_WRITE_ERR | W 1P | 0x0 | Log Write Error Interrupt Test. Writing `1` forces the interrupt. |
| 3:1 | Reserved | - | - | Reserved |
| 0 | LOG_FETCH_ERR | W 1P | 0x0 | Log Fetch Error Interrupt Test. Writing `1` forces the interrupt. |
LOG_CTRL[16]
| Bits | Field | Access | Reset | Description |
|---|---|---|---|---|
| 31:16 | Reserved | - | - | Reserved |
| 15:0 | LOG_LEN | RW | 0x0 | Log 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:
| Address | Name | Access | Description |
|---|---|---|---|
| 0x0 | THR | W | Transmitter Holding Register |
| 0x8 | FCR | W | FIFO Control Register |
Register Details:
THR
| Bits | Field | Access | Reset | Description |
|---|---|---|---|---|
| 31:8 | Reserved | - | - | Reserved |
| 7:0 | DATA | W WMOD | 0x0 | Transmit 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
| Bits | Field | Access | Reset | Description |
|---|---|---|---|---|
| 31:8 | Reserved | - | - | Reserved |
| 7:6 | RCVR_TRIGGER | W | 0x0 | Receiver 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:4 | Reserved | - | - | Reserved |
| 3 | DMA_MODE_SELECT | W | 0x0 | DMA mode select: * `0` - DMA Mode 0 * `1` - DMA Mode 1 |
| 2 | XMIT_FIFO_RESET | W 1P | 0x0 | Transmitter FIFO Reset. Writing `1` clears the TX FIFO. |
| 1 | RCVR_FIFO_RESET | W 1P | 0x0 | Receiver FIFO Reset. Writing `1` clears the RX FIFO. |
| 0 | FIFO_ENABLE | W | 0x0 | FIFO 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:
| Address | Name | Access | Description |
|---|---|---|---|
| 0x0 | DLL | RW | Divisor Latch Least Significant Byte Register |
| 0x4 | DLM | RW | Divisor Latch Most Significant Byte Register |
Register Details:
DLL
| Bits | Field | Access | Reset | Description |
|---|---|---|---|---|
| 31:8 | Reserved | - | - | Reserved |
| 7:0 | DLL | RW | 0x0 | Divisor 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
| Bits | Field | Access | Reset | Description |
|---|---|---|---|---|
| 31:8 | Reserved | - | - | Reserved |
| 7:0 | DLM | RW | 0x0 | Divisor 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. |
6. Interrupts
TODO
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.