Livt packages
Livt.Net
Version 1.4.1
Ethernet, IPv4, TCP, UDP, ARP, TFTP, and Telnet networking components for Livt hardware.
Published files (163)
src/drivers/ethernetlite/EthernetLiteReceiver.lvt
namespace Livt.Net.Drivers.EthernetLite
using Livt.Net
using Livt.IO
enum EthernetLiteReceiveState
{
Empty
Capturing
Available
Acquired
}
/**
* Owns one RAM capture independently of the AXI transaction engine.
* Only the bound driver calls capture methods; one service owns acquisition.
* All borrowers and the driver must share coordinated reset.
*/
component EthernetLiteReceiver<CAPACITY: int = 128> : IFrameReceiver
{
static assert CAPACITY >= 60 && CAPACITY <= 1514, "RX capacity must be 60..1514"
const LENGTH_BITS: int = Bits.RequiredFor(CAPACITY)
// Storage is mutable only before publication or after release.
const ADDRESS_BITS: int = Bits.RequiredFor(CAPACITY - 1)
memory: SynchronousRam<byte, logic[ADDRESS_BITS], CAPACITY>
storage: IRam<byte>
phase: EthernetLiteReceiveState
written: logic[LENGTH_BITS]
length: logic[LENGTH_BITS]
failed: bool
/**
* Creates empty receive storage. Capture is supplied by the device driver.
*/
new()
{
this.memory = new SynchronousRam<byte, logic[ADDRESS_BITS], CAPACITY>()
this.storage = new RamAccess<byte, logic[ADDRESS_BITS], CAPACITY, SynchronousRam<byte, logic[ADDRESS_BITS], CAPACITY>>(this.memory)
}
/**
* Reports the allocated prefix capacity, not a wire-length claim.
*/
override fn GetReceiveCapacity() int
{
return CAPACITY
}
/**
* Reports a frame available to acquire or currently acquired.
*/
override fn HasReceiveFrame() bool
{
return this.phase == EthernetLiteReceiveState.Available || this.phase == EthernetLiteReceiveState.Acquired
}
/**
* Packet data is readable only by the current acquisition owner.
*/
override fn IsReady() bool
{
return this.phase == EthernetLiteReceiveState.Acquired
}
/**
* Returns the safe captured prefix only while acquired.
*/
override fn GetAvailableLength() int
{
if (!this.IsReady()) {
return 0
}
return (this.length as uint) as int
}
/**
* Reads an acquired byte; failure initializes the output to zero.
*/
override fn TryRead(index: int, value: out byte) PacketDataResult
{
value = 0x00
if (!this.IsReady()) {
return PacketDataResult.NotReady
}
if (index < 0 || index >= ((this.length as uint) as int)) {
return PacketDataResult.Invalid
}
var captured = this.storage.Read(index)
value = captured
return PacketDataResult.Success
}
/**
* Acquires one published prefix; repeated acquisition is Busy.
*/
override fn TryAcquire() FrameLinkResult
{
if (this.phase == EthernetLiteReceiveState.Acquired) {
return FrameLinkResult.Busy
}
if (this.failed) {
return FrameLinkResult.DeviceFailure
}
if (this.phase != EthernetLiteReceiveState.Available) {
return FrameLinkResult.NotReady
}
this.phase = EthernetLiteReceiveState.Acquired
return FrameLinkResult.Success
}
/**
* Releases storage after every dependent reader has finished.
*/
override fn TryRelease() FrameLinkResult
{
if (this.phase != EthernetLiteReceiveState.Acquired) {
return FrameLinkResult.Invalid
}
this.length = 0
this.written = 0
this.phase = EthernetLiteReceiveState.Empty
return FrameLinkResult.Success
}
/**
* EthernetLite does not supply exact wire length; CRC prefix scanning cannot prove it.
*/
override fn HasKnownWireLength() bool
{
return false
}
/**
* Unknown wire length has no usable numeric value.
*/
override fn GetWireLength() int
{
return 0
}
/**
* Reports a latched capture or device error.
*/
override fn HasReceiveError() bool
{
return this.failed
}
/**
* Acknowledges the error; device recovery is a separate driver operation.
*/
override fn TryAcknowledgeReceiveError() FrameLinkResult
{
if (!this.failed) {
return FrameLinkResult.NotReady
}
this.failed = false
return FrameLinkResult.Success
}
/**
* Driver-only admission: never overwrite published or acquired storage.
*/
public fn TryBeginCapture() bool
{
if (this.failed || this.phase != EthernetLiteReceiveState.Empty) {
return false
}
this.written = 0
this.length = 0
this.phase = EthernetLiteReceiveState.Capturing
return true
}
/**
* Driver-only append; rejects holes and overflow.
*/
public fn TryAppend(value: byte) bool
{
if (this.phase != EthernetLiteReceiveState.Capturing || ((this.written as uint) as int) >= CAPACITY) {
return false
}
this.storage.Write((this.written as uint) as int, value)
this.written++
return true
}
/**
* Publishes only a certified initialized prefix after device release succeeds.
*/
public fn TryPublish(length: int) bool
{
if (this.phase != EthernetLiteReceiveState.Capturing || length < 60 || length > ((this.written as uint) as int)) {
return false
}
this.length = length as logic[LENGTH_BITS]
this.phase = EthernetLiteReceiveState.Available
return true
}
/**
* Abandons incomplete capture and latches failure without revoking an acquired frame.
*/
public fn Fail()
{
if (this.phase == EthernetLiteReceiveState.Capturing) {
this.length = 0
this.written = 0
this.phase = EthernetLiteReceiveState.Empty
}
this.failed = true
}
/**
* Ends an empty poll without publishing or reporting failure.
*/
public fn AbandonCapture()
{
if (this.phase == EthernetLiteReceiveState.Capturing) {
this.written = 0
this.phase = EthernetLiteReceiveState.Empty
}
}
}