Livt packages

Livt.IO

Version 1.8.1

Memory, UART, I2C, SPI, and Ethernet input/output components for Livt hardware designs.

Published files (126)

tests/i2c/I2cOpenDrainPinsTest.lvt

namespace Livt.IO.Tests

using Livt.IO

/**
 * Test bus adapter that exposes observed line levels and low-drive requests without
 * physical board pins.
 */
component OpenDrainProbe
{
	// Shared fixture instances, signals, and observation state.
	busAdapter: I2CBus
	scl_drive_low: logic
	sda_drive_low: logic

	/**
	 * Initializes fixture state and constructor bindings. Test cases share the fixture
	 * instance rather than constructing a fresh subject for each method.
	 */
	new(busAdapter: flip I2CBus)
	{
		this.busAdapter = busAdapter
		this.scl_drive_low = 0b0
		this.sda_drive_low = 0b0
	}

	/**
	 * Copies the requested low-drive flags to the borrowed bus attachment in the test clock
	 * context.
	 */
	process ApplyDrive()
	{
		state {
			this.busAdapter.scl_drive_low = this.scl_drive_low
			this.busAdapter.sda_drive_low = this.sda_drive_low
		}
	}

	/**
	 * Requests an open-drain low on SCL through the fixture drive process.
	 */
	public fn DriveSclLow()
	{
		this.scl_drive_low = 0b1
	}

	/**
	 * Releases the fixture SCL low-drive request.
	 */
	public fn ReleaseScl()
	{
		this.scl_drive_low = 0b0
	}

	/**
	 * Requests an open-drain low on SDA through the fixture drive process.
	 */
	public fn DriveSdaLow()
	{
		this.sda_drive_low = 0b1
	}

	/**
	 * Releases the fixture SDA low-drive request.
	 */
	public fn ReleaseSda()
	{
		this.sda_drive_low = 0b0
	}

	/**
	 * Returns the logical SCL level observed at the borrowed attachment.
	 */
	public fn ReadScl() logic
	{
		return this.busAdapter.scl
	}

	/**
	 * Returns the logical SDA level observed at the borrowed attachment.
	 */
	public fn ReadSda() logic
	{
		return this.busAdapter.sda
	}
}

/**
 * Exercises I2COpenDrainPins with a shared fixture instance. Each scenario establishes the
 * inputs and state it needs.
 */
@Test
component I2COpenDrainPinsTest
{
	// Shared fixture instances, signals, and observation state.
	pins: I2COpenDrainPins
	probe: OpenDrainProbe
	scl: logic
	sda: logic

	/**
	 * Creates the shared fixture instances (I2COpenDrainPins, OpenDrainProbe). Tests
	 * initialize the state required by their scenario.
	 */
	new()
	{
		this.scl = 0bZ
		this.sda = 0bZ
		this.pins = new I2COpenDrainPins(this.scl, this.sda)
		this.probe = new OpenDrainProbe(this.pins)
	}

	/**
	 * Checks the released lines read high case.
	 */
	@Test
	fn TestReleasedLinesReadHigh()
	{
		this.probe.ReleaseScl()
		this.probe.ReleaseSda()
		Simulation.Wait(80)

		assert this.probe.ReadScl() == 0b1
		assert this.probe.ReadSda() == 0b1
	}

	/**
	 * Checks the drive low and release case.
	 */
	@Test
	fn TestDriveLowAndRelease()
	{
		this.probe.DriveSclLow()
		this.probe.DriveSdaLow()
		Simulation.Wait(80)

		assert this.probe.ReadScl() == 0b0
		assert this.probe.ReadSda() == 0b0

		this.probe.ReleaseScl()
		this.probe.ReleaseSda()
		Simulation.Wait(80)

		assert this.probe.ReadScl() == 0b1
		assert this.probe.ReadSda() == 0b1
	}
}