Livt packages
Livt.IO
Version 1.8.1
Memory, UART, I2C, SPI, and Ethernet input/output components for Livt hardware designs.
Published files (126)
- BufferedUartApiTest.lvt
- BufferedUartPermissionTest.lvt
- BufferedUartTest.lvt
- ConcurrentUartTest.lvt
- LoopbackUartTest.lvt
- RtsCtsBufferedUartSmokeTest.lvt
- RtsCtsBufferedUartTest.lvt
- UartBaudConfigurationTest.lvt
- UartCapacityTest.lvt
- UartFrameConfigurationTest.lvt
- UartReceiverTest.lvt
- UartSynthesisConfigurationTest.lvt
- UartTest.lvt
- UartTransmitterTest.lvt
tests/uart/UartTransmitterTest.lvt
namespace Livt.IO.Tests
using Livt.IO
/**
* Exercises UartTransmitter with a shared fixture instance. Each scenario establishes the
* inputs and state it needs.
*/
@Test
@Context(ClockFrequency = 100MHz)
component UartTransmitterTest
{
// Independent reference timing for the default 100 MHz/115200-baud regression.
const DEFAULT_TICKS_PER_BIT: int = 868
// Shared fixture instances, signals, and observation state.
transmitter: UartTransmitter
// Shared fixture instances, signals, and observation state.
tx: logic
// Shared fixture instances, signals, and observation state.
tx_dv: logic
// Shared fixture instances, signals, and observation state.
tx_byte: byte
// Shared fixture instances, signals, and observation state.
tx_active: logic
// Shared fixture instances, signals, and observation state.
tx_done: logic
/**
* Creates the shared fixture instances (UartTransmitter). Tests initialize the state
* required by their scenario.
*/
new()
{
this.transmitter = new UartTransmitter(
this.tx,
this.tx_dv,
this.tx_byte,
this.tx_active,
this.tx_done
)
}
/**
* Checks the transmitter case.
*/
@Test
fn TestTransmitter()
{
this.tx_byte = 0xAA
this.tx_dv = 0b1
this.tx_dv = 0b0
Simulation.Wait(DEFAULT_TICKS_PER_BIT * 10)
assert this.tx == 0b1 // Idle state
// Wait for idle state
Simulation.Wait(10)
assert this.tx_active == 0b0
}
/**
* Checks the idle state case.
*/
@Test
fn TestIdleState()
{
// Verify TX line is high when idle
assert this.tx == 0b1
assert this.tx_active == 0b0
assert this.tx_done == 0b0
Simulation.Wait(100)
// Should remain idle
assert this.tx == 0b1
assert this.tx_active == 0b0
}
/**
* Checks the start bit case.
*/
@Test
fn TestStartBit()
{
this.tx_byte = 0xAA
this.tx_dv = 0b1
this.tx_dv = 0b0
// After triggering, should enter start bit state
Simulation.Wait(5)
assert this.tx_active == 0b1
assert this.tx == 0b0 // Start bit is low
// Should stay low for TICKS_PER_BIT cycles
Simulation.Wait(DEFAULT_TICKS_PER_BIT / 2)
assert this.tx == 0b0 // Still in start bit
// Wait for transmission to complete and return to idle
Simulation.Wait(DEFAULT_TICKS_PER_BIT * 10)
assert this.tx == 0b1
assert this.tx_active == 0b0
}
/**
* Checks the data bits transmission case.
*/
@Test
fn TestDataBitsTransmission()
{
// Test transmitting 0xAA (10101010 in binary)
this.tx_byte = 0xAA
this.tx_dv = 0b1
this.tx_dv = 0b0
// Skip start bit
Simulation.Wait(DEFAULT_TICKS_PER_BIT)
// Check each data bit (LSB first)
// 0xAA = 10101010, so LSB first: 0,1,0,1,0,1,0,1
Simulation.Wait(DEFAULT_TICKS_PER_BIT / 2)
assert this.tx == 0b0 // Bit 0
Simulation.Wait(DEFAULT_TICKS_PER_BIT)
assert this.tx == 0b1 // Bit 1
Simulation.Wait(DEFAULT_TICKS_PER_BIT)
assert this.tx == 0b0 // Bit 2
Simulation.Wait(DEFAULT_TICKS_PER_BIT)
assert this.tx == 0b1 // Bit 3
Simulation.Wait(DEFAULT_TICKS_PER_BIT)
assert this.tx == 0b0 // Bit 4
Simulation.Wait(DEFAULT_TICKS_PER_BIT)
assert this.tx == 0b1 // Bit 5
Simulation.Wait(DEFAULT_TICKS_PER_BIT)
assert this.tx == 0b0 // Bit 6
Simulation.Wait(DEFAULT_TICKS_PER_BIT)
assert this.tx == 0b1 // Bit 7
// Wait for stop bit and return to idle
Simulation.Wait(DEFAULT_TICKS_PER_BIT * 2)
assert this.tx == 0b1
assert this.tx_active == 0b0
}
/**
* Checks the stop bit case.
*/
@Test
fn TestStopBit()
{
this.tx_byte = 0x00
this.tx_dv = 0b1
this.tx_dv = 0b0
// Skip start bit + 8 data bits
Simulation.Wait(DEFAULT_TICKS_PER_BIT * 9)
// Should be in stop bit now
Simulation.Wait(DEFAULT_TICKS_PER_BIT / 2)
assert this.tx == 0b1 // Stop bit is high
assert this.tx_active == 0b1 // Still active during stop bit
// Wait for transmission to complete and return to idle
Simulation.Wait(DEFAULT_TICKS_PER_BIT)
assert this.tx == 0b1
assert this.tx_active == 0b0
}
/**
* Checks the tx done signal case.
*/
@Test
fn TestTxDoneSignal()
{
this.tx_byte = 0x55
this.tx_dv = 0b1
this.tx_dv = 0b0
// Before transmission completes
Simulation.Wait(DEFAULT_TICKS_PER_BIT * 5)
assert this.tx_done == 0b0
// Poll for tx_done signal in a window around expected completion
// Transmission takes: 1 start + 8 data + 1 stop = 10 bit periods
var done_seen = 0b0
state {
for (var i = 0; i < DEFAULT_TICKS_PER_BIT * 6; i = i++) {
if (this.tx_done == 0b1) {
done_seen = 0b1
}
}
}
// Verify we saw the tx_done pulse
assert done_seen == 0b1
// Verify tx_done returns to 0
assert this.tx_done == 0b0
// Ensure back to idle
assert this.tx == 0b1
assert this.tx_active == 0b0
}
/**
* Checks the tx active signal case.
*/
@Test
fn TestTxActiveSignal()
{
// Initially inactive
assert this.tx_active == 0b0
this.tx_byte = 0x42
this.tx_dv = 0b1
this.tx_dv = 0b0
// Should be active during transmission
Simulation.Wait(5)
assert this.tx_active == 0b1
// Should remain active throughout
Simulation.Wait(DEFAULT_TICKS_PER_BIT * 5)
assert this.tx_active == 0b1
// Complete transmission
Simulation.Wait(DEFAULT_TICKS_PER_BIT * 5)
// Should go inactive after cleanup
Simulation.Wait(5)
assert this.tx_active == 0b0
}
/**
* Checks the multiple bytes case.
*/
@Test
fn TestMultipleBytes()
{
// First byte
this.tx_byte = 0x12
this.tx_dv = 0b1
this.tx_dv = 0b0
// Wait for transmission to complete
Simulation.Wait(DEFAULT_TICKS_PER_BIT * 10 + 5)
assert this.tx == 0b1 // Back to idle
assert this.tx_active == 0b0
// Second byte
this.tx_byte = 0x34
this.tx_dv = 0b1
this.tx_dv = 0b0
// Should start transmitting again
Simulation.Wait(5)
assert this.tx_active == 0b1
assert this.tx == 0b0 // Start bit
// Wait for completion
Simulation.Wait(DEFAULT_TICKS_PER_BIT * 10)
assert this.tx == 0b1 // Back to idle
}
/**
* Checks the all zeros case.
*/
@Test
fn TestAllZeros()
{
this.tx_byte = 0x00
this.tx_dv = 0b1
this.tx_dv = 0b0
// Skip start bit
Simulation.Wait(DEFAULT_TICKS_PER_BIT)
// All data bits should be 0
for (var i = 0; i < 8; i = i + 1) {
Simulation.Wait(DEFAULT_TICKS_PER_BIT / 2)
assert this.tx == 0b0
Simulation.Wait(DEFAULT_TICKS_PER_BIT / 2)
}
// Stop bit should be 1
Simulation.Wait(DEFAULT_TICKS_PER_BIT / 2)
assert this.tx == 0b1
// Wait for return to idle
Simulation.Wait(DEFAULT_TICKS_PER_BIT)
assert this.tx == 0b1
assert this.tx_active == 0b0
}
/**
* Checks the all ones case.
*/
@Test
fn TestAllOnes()
{
this.tx_byte = 0xFF
this.tx_dv = 0b1
this.tx_dv = 0b0
// Skip start bit
Simulation.Wait(DEFAULT_TICKS_PER_BIT)
// All data bits should be 1
for (var i = 0; i < 8; i = i + 1) {
Simulation.Wait(DEFAULT_TICKS_PER_BIT / 2)
assert this.tx == 0b1
Simulation.Wait(DEFAULT_TICKS_PER_BIT / 2)
}
// Stop bit should be 1
Simulation.Wait(DEFAULT_TICKS_PER_BIT / 2)
assert this.tx == 0b1
// Wait for return to idle
Simulation.Wait(DEFAULT_TICKS_PER_BIT)
assert this.tx == 0b1
assert this.tx_active == 0b0
}
}