Livt packages

Livt.Net

Version 1.4.1

Ethernet, IPv4, TCP, UDP, ARP, TFTP, and Telnet networking components for Livt hardware.

Published files (163)

tests/EthernetLiteResetScenario.lvt

namespace Livt.Net.Tests

using Livt.Net
using Livt.Net.Drivers.EthernetLite

/**
 * Device lifecycle exercised entirely in Livt, including real AXI handshake stalls.
 */
component EthernetLiteResetScenario
{
	transactions: EthernetLiteTransactions
	device: EthernetLiteDeviceFixture
	source: ArrayPacketData<1600>
	receiver: EthernetLiteReceiver<128>
	provider: FaultingPacketData<ArrayPacketData<1600>>
	transmitter: EthernetLiteTransmitter<FaultingPacketData<ArrayPacketData<1600>>>
	driver: EthernetLiteDriver<EthernetLiteTransactions, FaultingPacketData<ArrayPacketData<1600>>>

	/**
	 * Creates the independent storage/capability graph and hardware boundary.
	 */
	new(clk: in clock, resetLine: in logic)
	{
		this.context.clk = clk
		this.context.rst = resetLine
		this.transactions = new EthernetLiteTransactions()
		this.device = new EthernetLiteDeviceFixture()
		this.source = new ArrayPacketData<1600>()
		this.receiver = new EthernetLiteReceiver<128>()
		this.provider = new FaultingPacketData<ArrayPacketData<1600>>(this.source)
		this.transmitter = new EthernetLiteTransmitter<FaultingPacketData<ArrayPacketData<1600>>>(this.provider)
		var mac: byte[6] = [0x00, 0x00, 0x5E, 0x00, 0xFA, 0xCE]
		this.driver = new EthernetLiteDriver<EthernetLiteTransactions, FaultingPacketData<ArrayPacketData<1600>>>(this.transactions, this.receiver, this.transmitter, mac)
	}

	/**
	 * Wires the real transaction engine to the Livt slave fixture at signal level.
	 */
	process Pins[]()
	{
		this.transactions.awready = this.device.awready
		this.transactions.wready = this.device.wready
		this.transactions.bresp = this.device.bresp
		this.transactions.bvalid = this.device.bvalid
		this.transactions.arready = this.device.arready
		this.transactions.rdata = this.device.rdata
		this.transactions.rresp = this.device.rresp
		this.transactions.rvalid = this.device.rvalid
		this.device.awaddr = this.transactions.awaddr
		this.device.awvalid = this.transactions.awvalid
		this.device.wdata = this.transactions.wdata
		this.device.wstrb = this.transactions.wstrb
		this.device.wvalid = this.transactions.wvalid
		this.device.bready = this.transactions.bready
		this.device.araddr = this.transactions.araddr
		this.device.arvalid = this.transactions.arvalid
		this.device.rready = this.transactions.rready
	}

	/**
	 * Waits with a finite test deadline for the MAC programming completion poll.
	 */
	fn WaitInitialized()
	{
		var ready = false

		for (var i = 0; i < 5000; i++) {
			ready = this.driver.IsInitialized()

			if (ready) {
				break
			}
		}

		assert ready
	}

	/**
	 * Prepares deterministic bytes; callers must have ended the preceding borrow.
	 */
	fn Prepare(length: int)
	{
		if (this.source.IsReady()) {
			this.source.TryRelease()
		}
		else {
			this.source.TryClear()
		}

		for (var i = 0; i < length; i++) {
			assert this.source.TryWrite(i, (i + 128) as byte) == PacketDataResult.Success
		}

		assert this.source.TryPublish() == PacketDataResult.Success
	}

	/**
	 * Checks a stable terminal result and the end of source ownership.
	 */
	fn WaitCompletion(expected: FrameTransmitOutcome)
	{
		var outcome = FrameTransmitOutcome.Cancelled
		var result = FrameLinkResult.NotReady

		for (var i = 0; i < 10000; i++) {
			result = this.transmitter.TryGetCompletion(outcome)

			if (result == FrameLinkResult.Success) {
				break
			}
		}

		assert result == FrameLinkResult.Success
		assert outcome == expected
		assert !this.transmitter.IsSourceBorrowed()
		assert this.transmitter.TryGetCompletion(outcome) == FrameLinkResult.Success
		assert outcome == expected
		assert this.transmitter.TrySubmit() == FrameLinkResult.Busy
		assert this.transmitter.TryAcknowledgeCompletion() == FrameLinkResult.Success
	}

	/**
	 * Validates unknown wire length, exact safe prefix, bounds and acquisition lifetime.
	 */
	fn CheckCapture(length: int)
	{
		var acquired = FrameLinkResult.NotReady

		for (var i = 0; i < 10000; i++) {
			acquired = this.receiver.TryAcquire()

			if (acquired == FrameLinkResult.Success) {
				break
			}
		}

		assert acquired == FrameLinkResult.Success
		assert this.receiver.TryAcquire() == FrameLinkResult.Busy
		assert this.receiver.GetAvailableLength() == length
		assert !this.receiver.HasKnownWireLength()
		assert this.receiver.GetWireLength() == 0
		var value: byte = 0x00

		for (var i = 0; i < length; i++) {
			assert this.receiver.TryRead(i, value) == PacketDataResult.Success
			assert value == (i as byte)
		}

		assert this.receiver.TryRead(length, value) == PacketDataResult.Invalid
		assert value == 0x00
		assert this.receiver.TryRead(-1, value) == PacketDataResult.Invalid
	}

	/**
	 * Holds an acquired RX prefix while TX stalls after AW and W acceptance.
	 */
	public fn StartStalledTransfer()
	{
		this.WaitInitialized()
		var fcs: byte[4] = [0xEE, 0x7F, 0xEC, 0xB0]
		this.device.QueueFrame(60, fcs, false)
		this.CheckCapture(60)
		this.Prepare(60)
		this.device.HoldWriteResponses(true)
		assert this.transmitter.TrySubmit() == FrameLinkResult.Accepted
		var writes = 0

		for (var i = 0; i < 10000; i++) {
			writes = this.device.GetWriteCount()

			if (writes >= 4) {
				break
			}
		}

		assert writes == 4
		assert this.transmitter.IsSourceBorrowed()
		var outcome = FrameTransmitOutcome.Delivered
		assert this.transmitter.TryGetCompletion(outcome) == FrameLinkResult.NotReady
		assert this.receiver.IsReady()
	}

	/**
	 * Checks revoked metadata after reset and proves fresh TX/RX can complete.
	 */
	public fn CheckResetAndReuse()
	{
		assert !this.receiver.HasReceiveFrame()
		assert !this.receiver.IsReady()
		assert this.receiver.GetAvailableLength() == 0
		assert !this.transmitter.IsSourceBorrowed()
		var outcome = FrameTransmitOutcome.Delivered
		assert this.transmitter.TryGetCompletion(outcome) == FrameLinkResult.NotReady
		assert !this.source.IsReady()
		assert this.source.GetWrittenLength() == 0
		this.WaitInitialized()
		assert this.device.GetWriteCount() == 3
		this.Prepare(61)
		assert this.transmitter.TrySubmit() == FrameLinkResult.Accepted
		this.WaitCompletion(FrameTransmitOutcome.Delivered)
		assert this.device.GetWriteCount() == 21
		assert this.device.GetWriteValue(18) == 0x000000BC
		var fcs: byte[4] = [0xEE, 0x7F, 0xEC, 0xB0]
		this.device.QueueFrame(60, fcs, false)
		this.CheckCapture(60)
		assert this.receiver.TryRelease() == FrameLinkResult.Success
	}
}