This package provides a layered UART implementation in Livt, from low-level RX/TX blocks up to a buffered controller and a simple convenience wrapper for application code.
For background on the design approach and why this repository is structured as a stack
from signal-level components up to application-facing APIs, see DESIGN_NOTE.md.
The current package is organized around these main components:
UartReceiverreceives bytes from a serial RX line.UartTransmittersends bytes on a serial TX line.UartBasecombines the receiver and transmitter into one component with explicit control signals.BufferedUartadds 16-byte transmit and receive FIFOs on top ofUartBase.UartwrapsBufferedUartwith a small application-friendly API, including an all-or-nothingSend(data: byte[])helper.LoopbackUartconnects TX back to RX internally for testing and verification.
The UART framing is currently fixed to:
- 8 data bits
- 1 start bit
- 1 stop bit
- no parity
Both the receiver and transmitter default to TICKS_PER_BIT = 868, which corresponds to 115200 baud
on a 100 MHz clock.
.
├── src/
│ ├── UartReceiver.lvt
│ ├── UartTransmitter.lvt
│ ├── UartBase.lvt
│ ├── BufferedUart.lvt
│ ├── Uart.lvt
│ └── LoopbackUart.lvt
├── tests/
│ ├── UartReceiverTest.lvt
│ ├── UartTransmitterTest.lvt
│ ├── UartBaseTest.lvt
│ ├── BufferedUartTest.lvt
│ ├── UartTest.lvt
│ └── LoopbackUartTest.lvt
└── livt.toml
Build the package with:
livt buildThe package configuration is defined in livt.toml. The current project
name there is Uart.
Run the full test suite with:
livt testConfigured test components:
UartReceiverTestUartTransmitterTestUartBaseTestBufferedUartTestUartTestLoopbackUartTest
Low-level UART receiver.
- Input:
rx - Outputs:
rx_dv,rx_byte,rx_frame_error - Helpers:
IsDataValid(),GetData(),IsFrameError()
The receiver double-registers the input line before sampling, pulses rx_dv for one cycle when a byte is complete, and pulses rx_frame_error when a frame is rejected because of an invalid stop bit.
Low-level UART transmitter.
- Inputs:
tx_dv,tx_byte - Outputs:
tx,tx_active,tx_done
Pulse tx_dv high to begin transmitting tx_byte. tx_active stays high while transmission is in progress, and tx_done pulses for one cycle at completion.
Thin composition layer that instantiates UartReceiver and UartTransmitter together.
Use this component when you want direct control over the UART handshake and status signals.
Higher-level controller built on top of UartBase.
Features:
- 16-byte transmit FIFO
- 16-byte receive FIFO
- queued transmit API with backpressure
- receive polling API
- buffer management helpers
Public methods:
Transmit(data: logic[8]) boolReceive() logic[8]IsDataAvailable() boolIsBusy() boolGetAvailableBytes() intGetTransmitSpace() intHasFrameError() boolGetFrameErrorCount() intClearReceiveBuffer()ClearTransmitBuffer()ClearFrameErrors()
Transmit() returns false when the transmit FIFO is full. Incoming received bytes are dropped if the receive FIFO is full.
Small convenience wrapper around BufferedUart in the Livt.IO namespace.
Public methods:
IsDataAvailable() boolReceive() logic[8]Transmit(data: logic[8]) boolGetTransmitSpace() intHasFrameError() boolGetFrameErrorCount() intClearFrameErrors()Send(data: byte[]) bool
Send() is all-or-nothing: it returns false without queueing any bytes if there is not enough transmit space for the full message.
Test-oriented wrapper around BufferedUart that internally connects TX back to RX.
Public methods:
Transmit(data: logic[8]) boolReceive() logic[8]IsDataAvailable() boolGetAvailableBytes() intGetTransmitSpace() intIsBusy() boolHasFrameError() boolGetFrameErrorCount() intClearReceiveBuffer()ClearTransmitBuffer()ClearFrameErrors()
LoopbackUart is intended for simulation, verification, and self-test scenarios where transmitted bytes should immediately flow back through the receive path.
using Livt.IO
component MyComponent
{
uart: Uart
new(rx: in logic, tx: out logic)
{
this.uart = new Uart(rx, tx)
}
public fn SendHello()
{
var helloWorld = "Hello, World!".Encode()
this.uart.Send(helloWorld)
}
}
To target a different clock or baud rate, update TICKS_PER_BIT in both:
Formula:
TICKS_PER_BIT = Clock Frequency / Baud Rate
For example, at 100 MHz and 115200 baud:
100000000 / 115200 = 868
LoopbackUartis intended for simulation and verification, not for external serial IO.- The top-level
Uartcomponent currently delegates toBufferedUart, so transmit operations are queue-based rather than single-cycle direct sends. - This package no longer includes the older AXI4-Lite, Avalon, or Wishbone wrapper components described in the previous README.
Contributions are welcome. Areas that would be natural extensions for this package include:
- parity bit support
- configurable stop bits
- configurable buffer sizes
- overflow reporting for dropped received bytes
- configurable baud-rate settings without editing source constants
This project is licensed under the MIT License.