Livt packages
Livt.Bus
Version 2.0.1
Configurable Avalon, AXI4-Lite, and Wishbone memory-mapped masters, interfaces, bridges, and test components.
Published files (67)
src/axi4lite/testing/Axi4LiteTestSlave32.lvt
namespace Livt.Bus.Axi4Lite.Testing
using Livt.Bus.Axi4Lite
/**
* Configurable AXI4-Lite slave used to verify the public test master.
*/
component Axi4LiteTestSlave32
{
bus: IAxi4Lite32Master
registers: uint[16]
awDelay: uint
wDelay: uint
bDelay: uint
arDelay: uint
rDelay: uint
configuredWriteResponse: Logic[2]
configuredReadResponse: Logic[2]
new(bus: flip IAxi4Lite32Master)
{
this.bus = bus
this.bus.awready = 0b0
this.bus.wready = 0b0
this.bus.bvalid = 0b0
this.bus.bresp = 0b00
this.bus.arready = 0b0
this.bus.rvalid = 0b0
this.bus.rdata = 0x00000000
this.bus.rresp = 0b00
this.awDelay = 0
this.wDelay = 0
this.bDelay = 0
this.arDelay = 0
this.rDelay = 0
this.configuredWriteResponse = 0b00
this.configuredReadResponse = 0b00
}
/**
* Configures clock-tick delays for write address, write data, write response,
* read address, and read data handshakes respectively.
*/
public fn ConfigureDelays(awDelay: uint, wDelay: uint, bDelay: uint, arDelay: uint, rDelay: uint)
{
state Apply {
this.awDelay = awDelay
this.wDelay = wDelay
this.bDelay = bDelay
this.arDelay = arDelay
this.rDelay = rDelay
}
}
/**
* Configures the two-bit AXI response returned by subsequent writes and reads.
*/
public fn ConfigureResponses(writeResponse: Logic[2], readResponse: Logic[2])
{
state Apply {
this.configuredWriteResponse = writeResponse
this.configuredReadResponse = readResponse
}
}
/**
* Clears all sixteen 32-bit words in the target model.
*/
public fn Clear()
{
var index: int = 0
while (index < 16) {
registers[index] = 0
index = index + 1
}
}
process Run()
{
var awTicks: uint = 0
var wTicks: uint = 0
var bTicks: uint = 0
var arTicks: uint = 0
var rTicks: uint = 0
var addressAccepted: bool = false
var dataAccepted: bool = false
var capturedWriteAddress: uint = 0
var capturedWriteData: uint = 0
var capturedWriteStrobe: Logic[4] = 0b0000
var capturedReadAddress: uint = 0
var registerIndex: int = 0
var nextValue: uint = 0
state Idle {
this.bus.awready = 0b0
this.bus.wready = 0b0
this.bus.bvalid = 0b0
this.bus.arready = 0b0
this.bus.rvalid = 0b0
addressAccepted = false
dataAccepted = false
awTicks = 0
wTicks = 0
bTicks = 0
arTicks = 0
rTicks = 0
if (this.bus.awvalid == 0b1 || this.bus.wvalid == 0b1) {
goto WriteTransfer
} elif (this.bus.arvalid == 0b1) {
goto ReadAddress
} else {
goto Idle
}
}
state WriteTransfer {
if (addressAccepted == false) {
if (awTicks >= awDelay) {
if (this.bus.awready == 0b1 && this.bus.awvalid == 0b1) {
capturedWriteAddress = this.bus.awaddr as uint
addressAccepted = true
this.bus.awready = 0b0
} else {
this.bus.awready = 0b1
}
} else {
awTicks = awTicks + 1
}
}
if (dataAccepted == false) {
if (wTicks >= wDelay) {
if (this.bus.wready == 0b1 && this.bus.wvalid == 0b1) {
capturedWriteData = this.bus.wdata as uint
capturedWriteStrobe = this.bus.wstrb
dataAccepted = true
this.bus.wready = 0b0
} else {
this.bus.wready = 0b1
}
} else {
wTicks = wTicks + 1
}
}
if (addressAccepted && dataAccepted) {
goto WriteApply
} else {
goto WriteTransfer
}
}
state WriteApply {
this.bus.awready = 0b0
this.bus.wready = 0b0
registerIndex = (capturedWriteAddress >> 2) as int
if (registerIndex >= 0 && registerIndex < 16) {
nextValue = registers[registerIndex]
if (capturedWriteStrobe[0] == 0b1) {
nextValue = (nextValue & (0xFFFFFF00 as uint)) | (capturedWriteData & (0x000000FF as uint))
}
if (capturedWriteStrobe[1] == 0b1) {
nextValue = (nextValue & (0xFFFF00FF as uint)) | (capturedWriteData & (0x0000FF00 as uint))
}
if (capturedWriteStrobe[2] == 0b1) {
nextValue = (nextValue & (0xFF00FFFF as uint)) | (capturedWriteData & (0x00FF0000 as uint))
}
if (capturedWriteStrobe[3] == 0b1) {
nextValue = (nextValue & (0x00FFFFFF as uint)) | (capturedWriteData & (0xFF000000 as uint))
}
registers[registerIndex] = nextValue
}
bTicks = 0
goto WriteResponseDelay
}
state WriteResponseDelay {
if (bTicks >= bDelay) {
this.bus.bresp = configuredWriteResponse
this.bus.bvalid = 0b1
goto WriteResponse
} else {
bTicks = bTicks + 1
goto WriteResponseDelay
}
}
state WriteResponse {
if (this.bus.bready == 0b1) {
this.bus.bvalid = 0b0
goto Idle
} else {
goto WriteResponse
}
}
state ReadAddress {
if (arTicks >= arDelay) {
this.bus.arready = 0b1
if (this.bus.arvalid == 0b1) {
capturedReadAddress = this.bus.araddr as uint
rTicks = 0
goto ReadDataDelay
} else {
goto ReadAddress
}
} else {
arTicks = arTicks + 1
goto ReadAddress
}
}
state ReadDataDelay {
this.bus.arready = 0b0
if (rTicks >= rDelay) {
registerIndex = (capturedReadAddress >> 2) as int
if (registerIndex >= 0 && registerIndex < 16) {
this.bus.rdata = registers[registerIndex] as Logic[32]
} else {
this.bus.rdata = 0x00000000
}
this.bus.rresp = configuredReadResponse
this.bus.rvalid = 0b1
goto ReadData
} else {
rTicks = rTicks + 1
goto ReadDataDelay
}
}
state ReadData {
if (this.bus.rready == 0b1) {
this.bus.rvalid = 0b0
goto Idle
} else {
goto ReadData
}
}
}
}