Livt packages
Livt.Net
Version 1.4.1
Ethernet, IPv4, TCP, UDP, ARP, TFTP, and Telnet networking components for Livt hardware.
Published files (163)
- ethernet
- services
- tftp
- ArpCompositionChecks.lvt
- ArpPacketParserTest.lvt
- ArpResponderTest.lvt
- ChecksumApiTest.lvt
- ChecksumWordSumTest.lvt
- CompactPacketFieldsTest.lvt
- CountingPacketData.lvt
- EthernetFrameBuilderTest.lvt
- EthernetFrameParserTest.lvt
- EthernetLiteDeviceFixture.lvt
- EthernetLiteDriverTest.lvt
- EthernetLiteReceiveWindowTest.lvt
- EthernetLiteResetScenario.lvt
- EthernetLiteResetTest.lvt
- FaultingFrameData.lvt
- FaultingPacketData.lvt
- FrameCapacityTest.lvt
- FrameCompositionTest.lvt
- FrameForwarder.lvt
- FrameLinkTest.lvt
- FrameMii10Link.lvt
- FrameMiiLink.lvt
- FrameMiiPins.lvt
- GenericPacketTest.lvt
- IcmpCapacityChecks.lvt
- IcmpEchoResponderTest.lvt
- IcmpStorageBackendTest.lvt
- InternetChecksumTest.lvt
- Ipv4HeaderBuilderTest.lvt
- Ipv4HeaderChecksumTest.lvt
- Ipv4PacketFieldsTest.lvt
- Ipv4PacketParserTest.lvt
- MiiFrame10Test.lvt
- MiiFrameTest.lvt
- PacketConvenienceTest.lvt
- PacketDataTest.lvt
- PacketMetadataStub.lvt
- PacketMetadataTest.lvt
- PacketParserFailureTest.lvt
- PacketStorageParityTest.lvt
- RamIpv4PacketParserTest.lvt
- ReceiveContractChecks.lvt
- ScheduledWordSumTest.lvt
- SynAckCompositionChecks.lvt
- TcpChecksumTest.lvt
- TcpConnectionRecognizerTest.lvt
- TcpHeaderParserTest.lvt
- TcpMultiSessionArrayStorageTest.lvt
- TcpMultiSessionAutoStorageTest.lvt
- TcpMultiSessionDistributedStorageTest.lvt
- TcpMultiSessionMixedStorageTest.lvt
- TcpMultiSessionStorageChecks.lvt
- TcpMultiSessionTest.lvt
- TcpRamPacketTest.lvt
- TcpRetryTimerTest.lvt
- TcpSegmentBuilderTest.lvt
- TcpSegmentTest.lvt
- TcpStreamServerArrayStorageTest.lvt
- TcpStreamServerAutoStorageTest.lvt
- TcpStreamServerDistributedStorageTest.lvt
- TcpStreamServerMixedStorageTest.lvt
- TcpStreamServerStorageChecks.lvt
- TcpStreamServerTest.lvt
- TelnetSessionTest.lvt
- TransmitContractChecks.lvt
- UdpPacketTest.lvt
tests/EthernetLiteDeviceFixture.lvt
namespace Livt.Net.Tests
using Livt.Net.Drivers.EthernetLite
/**
* Livt-only register model with independently stalled AXI channels.
* RX memory deliberately retains bytes after shorter frames. The fixture accepts
* externally computed FCS values rather than sharing the driver's CRC algorithm.
*/
component EthernetLiteDeviceFixture
{
public awready: out logic
public wready: out logic
public bresp: out logic[2]
public bvalid: out logic
public arready: out logic
public rdata: out logic[32]
public rresp: out logic[2]
public rvalid: out logic
public awaddr: in logic[13]
public awvalid: in logic
public wdata: in logic[32]
public wstrb: in logic[4]
public wvalid: in logic
public bready: in logic
public araddr: in logic[13]
public arvalid: in logic
public rready: in logic
// Borrowed bus and model-visible slave outputs.
m_axi_arvalid: logic
m_axi_araddr: logic[13]
m_axi_rready: logic
m_axi_awvalid: logic
m_axi_awaddr: logic[13]
m_axi_wvalid: logic
m_axi_wdata: logic[32]
m_axi_wstrb: logic[4]
m_axi_bready: logic
driveArready: logic
driveRdata: logic[32]
driveRresp: logic[2]
driveRvalid: logic
driveAwready: logic
driveWready: logic
driveBresp: logic[2]
driveBvalid: logic
// Register model, error injection and immutable completed write trace.
memory: byte[256]
ping: bool
pong: bool
reads: int
writes: int
addresses: int[512]
values: logic[512, 32]
readError: int
writeError: int
addressFirst: bool
holdResponses: bool
holdWriteResponses: bool
programming: int
/**
* Starts idle with no errors; choose write-channel order before transactions.
*/
new()
{
this.readError = -1
this.writeError = -1
}
/**
* Drives and samples live pins in the same clock domain as the transaction core.
*/
process Pins[]()
{
this.awready = this.driveAwready
this.wready = this.driveWready
this.bresp = this.driveBresp
this.bvalid = this.driveBvalid
this.arready = this.driveArready
this.rdata = this.driveRdata
this.rresp = this.driveRresp
this.rvalid = this.driveRvalid
this.m_axi_awaddr = this.awaddr
this.m_axi_awvalid = this.awvalid
this.m_axi_wdata = this.wdata
this.m_axi_wstrb = this.wstrb
this.m_axi_wvalid = this.wvalid
this.m_axi_bready = this.bready
this.m_axi_araddr = this.araddr
this.m_axi_arvalid = this.arvalid
this.m_axi_rready = this.rready
}
/**
* Returns a register value in the fixture, not a protocol parser result.
*/
fn ReadWord(address: int) logic[32]
{
if (address == 0x07FC) {
if (this.programming > 0) {
this.programming = this.programming - 1
return 0x00000003
}
return 0x00000000
}
if (address == 0x17FC) {
if (this.ping) {
return 0x00000001
}
return 0x00000000
}
if (address == 0x1FFC) {
if (this.pong) {
return 0x00000001
}
return 0x00000000
}
var offset = address - 0x1000
if (address >= 0x1800) {
offset = address - 0x1800
}
assert offset >= 0 && offset + 3 < 256
var word: logic[32] = 0x00000000
for (var lane = 0; lane < 4; lane++) {
var octet = this.memory[offset + lane] as logic[8]
for (var bit = 0; bit < 8; bit++) {
word[lane * 8 + bit] = octet[bit]
}
}
return word
}
/**
* Delays AR and R independently and holds response fields until acceptance.
*/
process ReadChannel()
{
var address = 0
var delay = 0
state Idle {
if (this.m_axi_arvalid == 0b1) {
delay = 3
address = (this.m_axi_araddr as uint) as int
goto DelayAddress
} else { goto Idle }
}
state DelayAddress {
assert this.m_axi_arvalid == 0b1
assert this.m_axi_araddr == (address as logic[13])
delay = delay - 1
if (delay == 0) {
this.driveArready = 0b1;
goto AcceptAddress
}
else {
goto DelayAddress
}
}
state AcceptAddress {
this.driveArready = 0b0
this.reads = this.reads + 1
goto PrepareResponse
}
state PrepareResponse {
this.driveRdata = this.ReadWord(address)
this.driveRresp = 0b00
if (address == this.readError) {
this.driveRresp = 0b10
}
delay = 4
goto DelayResponse
}
state DelayResponse {
if (this.holdResponses) {
goto DelayResponse
}
else {
delay = delay - 1
if (delay == 0) {
this.driveRvalid = 0b1;
goto Response
}
else {
goto DelayResponse
}
}
}
state Response {
if (this.m_axi_rready == 0b1) {
this.driveRvalid = 0b0;
goto Idle
}
else {
goto Response
}
}
}
/**
* Accepts AW/W in either order, delays B and checks stability during stalls.
*/
process WriteChannels()
{
var address = 0
var word: logic[32] = 0x00000000
var delay = 0
state Idle {
if (this.m_axi_awvalid == 0b1 && this.m_axi_wvalid == 0b1) {
address = (this.m_axi_awaddr as uint) as int
word = this.m_axi_wdata
delay = 3
goto DelayFirst
} else { goto Idle }
}
state DelayFirst {
assert this.m_axi_awaddr == (address as logic[13])
assert this.m_axi_wdata == word
assert this.m_axi_awvalid == 0b1 && this.m_axi_wvalid == 0b1
assert this.m_axi_wstrb == 0b1111
delay = delay - 1
if (delay == 0) {
if (this.addressFirst) {
this.driveAwready = 0b1
}
else {
this.driveWready = 0b1
}
goto AcceptFirst
} else { goto DelayFirst }
}
state AcceptFirst {
this.driveAwready = 0b0
this.driveWready = 0b0
delay = 5
goto DelaySecond
}
state DelaySecond {
if (this.addressFirst) {
assert this.m_axi_awvalid == 0b0
assert this.m_axi_wvalid == 0b1
assert this.m_axi_wdata == word
} else {
assert this.m_axi_wvalid == 0b0
assert this.m_axi_awvalid == 0b1
assert this.m_axi_awaddr == (address as logic[13])
}
delay = delay - 1
if (delay == 0) {
if (this.addressFirst) {
this.driveWready = 0b1
}
else {
this.driveAwready = 0b1
}
goto AcceptSecond
} else { goto DelaySecond }
}
state AcceptSecond {
this.driveAwready = 0b0
this.driveWready = 0b0
assert this.writes < 512
this.addresses[this.writes] = address
this.values[this.writes] = word
this.writes = this.writes + 1
this.driveBresp = 0b00
if (address == this.writeError) {
this.driveBresp = 0b11
}
else {
if (address == 0x17FC) {
this.ping = false
}
if (address == 0x1FFC) {
this.pong = false
}
if (address == 0x07FC && word == 0x00000003) {
this.programming = 2
}
}
delay = 7
goto DelayResponse
}
state DelayResponse {
if (this.holdResponses || this.holdWriteResponses) {
goto DelayResponse
}
else {
delay = delay - 1
if (delay == 0) {
this.driveBvalid = 0b1;
goto Response
}
else {
goto DelayResponse
}
}
}
state Response {
if (this.m_axi_bready == 0b1) {
this.driveBvalid = 0b0;
goto Idle
}
else {
goto Response
}
}
}
/**
* Selects the independent write-channel acceptance order.
*/
public fn SetAddressFirst(value: bool)
{
this.addressFirst = value
}
/**
* Holds future responses while addresses/data may already have been accepted.
*/
public fn HoldResponses(value: bool)
{
this.holdResponses = value
}
/**
* Holds B responses independently so a submitted frame can enter the write path.
*/
public fn HoldWriteResponses(value: bool)
{
this.holdWriteResponses = value
}
/**
* Injects SLVERR at a read address; -1 disables injection.
*/
public fn SetReadError(address: int)
{
this.readError = address
}
/**
* Injects DECERR at a write address; -1 disables injection.
*/
public fn SetWriteError(address: int)
{
this.writeError = address
}
/**
* Reports accepted write count, including injected failures.
*/
public fn GetWriteCount() int
{
return this.writes
}
/**
* Reads a completed trace address.
*/
public fn GetWriteAddress(index: int) int
{
return this.addresses[index]
}
/**
* Reads a completed trace value.
*/
public fn GetWriteValue(index: int) logic[32]
{
return this.values[index]
}
/**
* Prepares increasing octets plus an independent precomputed FCS; retains tail RAM.
*/
public fn QueueFrame(length: int, fcs: byte[4], pong: bool)
{
assert !this.ping && !this.pong
for (var i = 0; i < length; i++) {
this.memory[i] = i as byte
}
for (var i = 0; i < 4; i++) {
this.memory[length + i] = fcs[i]
}
if (pong) {
this.pong = true
}
else {
this.ping = true
}
}
}