Livt packages
Livt.IO
Version 1.8.1
Memory, UART, I2C, SPI, and Ethernet input/output components for Livt hardware designs.
Published files (126)
src/uart/RtsCtsBufferedUart.lvt
namespace Livt.IO
/**
* Active-low RTS/CTS UART with compile-time receive and transmit capacities.
* Scheduled methods report transaction results; they are not single-cycle ports.
*/
component RtsCtsBufferedUart<RX_CAPACITY: int = 64,
TX_CAPACITY: int = 64,
DATA_BITS: UartDataBits = UartDataBits.Eight,
PARITY: UartParity = UartParity.None,
STOP_BITS: UartStopBits = UartStopBits.One,
BAUD: Frequency = 115200Hz> : IBufferedUart by buffered
{
// Reserve at least one receive slot; small FIFOs require prompt peer response.
const RTS_HEADROOM: int = (RX_CAPACITY + 7) / 8
const RTS_STOP_LEVEL: int = RX_CAPACITY - RTS_HEADROOM
const RTS_RESUME_LEVEL: int = RTS_STOP_LEVEL - RTS_HEADROOM
static assert RX_CAPACITY >= 2, "RTS/CTS receive capacity must be at least two"
// Scheduled UART implementation delegated through the common contract.
buffered: BufferedUart<RX_CAPACITY, TX_CAPACITY, DATA_BITS, PARITY, STOP_BITS, BAUD>
// Asynchronous CTS input and its two-stage synchronized representation.
ctsN: logic
ctsMeta: logic
ctsSync: logic
permission: bool
// Registered RTS output and the receive occupancy used by its hysteresis.
rtsN: logic
receiveCount: int
/**
* Inherits clock/reset from the selected context and specializes the baud rate.
*/
new(rx: in logic, tx: out logic, ctsN: in logic, rtsN: out logic)
{
this.ctsN = ctsN
this.ctsMeta = 0b1
this.ctsSync = 0b1
rtsN = this.rtsN
this.buffered = new BufferedUart<RX_CAPACITY, TX_CAPACITY, DATA_BITS, PARITY, STOP_BITS, BAUD>(
rx, tx, launchPermission = permission)
}
/**
* Two clocked stages synchronize active-low CTS before launch permission.
*/
process SynchronizeCts()
{
state Tick {
ctsSync = ctsMeta
ctsMeta = ctsN
goto Tick
}
}
/**
* Read the FIFO occupancy without a scheduled status call.
*/
process Status[]()
{
permission = ctsSync == 0b0
receiveCount = this.buffered.receiveCount
}
/**
* Stop with reserved headroom and resume only below the lower watermark.
*/
process UpdateRts()
{
state Tick {
if (receiveCount >= RTS_STOP_LEVEL) {
rtsN = 0b1
} elif (receiveCount <= RTS_RESUME_LEVEL) {
rtsN = 0b0
}
goto Tick
}
}
}