Livt packages
Livt.Collections
Version 1.4.2
Fixed-capacity FIFOs, queues, stacks, circular buffers, lists, and bit sets for Livt hardware.
Published files (62)
src/queue/Queue.lvt
namespace Livt.Collections
/**
* Application-level FIFO access through scheduled transactions over one Fifo.
* Arbitration and completion add control state and latency; use Fifo directly
* for cycle-level datapaths. Clear has priority; pending enqueue and dequeue
* alternate. Each operation retains its own result.
*/
component Queue<T, CAPACITY: int = 64> : IQueue<T>
{
// Signal-level storage core shared by all scheduled operations.
fifo: Fifo<T, CAPACITY>
// Per-operation request/completion toggles used by scheduled callers.
enqueueRequest: bool
enqueueCompleted: bool
dequeueRequest: bool
dequeueCompleted: bool
clearRequest: bool
clearCompleted: bool
// Payloads and captured results retained until the matching call completes.
payload: T
enqueueAccepted: bool
dequeueAccepted: bool
response: T
// Fairness state and combinational requests presented to the FIFO owner.
lastWasEnqueue: bool
fifoClear: bool
fifoPush: bool
fifoPop: bool
// FIFO acceptance, payload, occupancy, and free-space observations.
fifoPushAccepted: bool
fifoPopAccepted: bool
fifoData: T
fifoCount: int
fifoSpace: int
/**
* Creates storage in the inherited single-clock context.
*/
new()
{
this.fifo = new Fifo<T, CAPACITY>(
this.fifoClear, this.fifoPush, this.payload, this.fifoPop,
this.fifoPushAccepted, this.fifoPopAccepted, this.fifoData,
this.fifoCount, this.fifoSpace)
}
/**
* Appends a value if space exists at its arbitrated transaction edge.
*/
override fn TryEnqueue(value: T) bool
{
payload = value
enqueueRequest = !enqueueRequest
while (enqueueCompleted != enqueueRequest) {
state {
}
}
return enqueueAccepted
}
/**
* Removes the oldest value; assigns zero and returns false when empty.
*/
override fn TryDequeue(value: out T) bool
{
dequeueRequest = !dequeueRequest
while (dequeueCompleted != dequeueRequest) {
state {
}
}
value = response
return dequeueAccepted
}
/**
* Discards the contents at one edge, ahead of pending transfers.
*/
override fn Clear()
{
clearRequest = !clearRequest
while (clearCompleted != clearRequest) {
state {
}
}
}
/**
* Returns an occupancy snapshot, not a reservation.
*/
override fn GetCount() int
{
return fifoCount
}
/**
* Returns a free-space snapshot, not a reservation.
*/
override fn GetSpace() int
{
return fifoSpace
}
/**
* Chooses exactly one pending operation without a scheduled helper call.
*/
process Drive[]()
{
fifoClear = clearRequest != clearCompleted
fifoPush = !fifoClear &&
enqueueRequest != enqueueCompleted &&
(dequeueRequest == dequeueCompleted ||
!lastWasEnqueue)
fifoPop = !fifoClear && dequeueRequest != dequeueCompleted && !fifoPush
}
/**
* Captures each result on the FIFO edge; other callers cannot overwrite it.
*/
process Complete()
{
state Tick {
if (fifoClear) {
clearCompleted = clearRequest
} elif (fifoPush) {
enqueueAccepted = fifoPushAccepted
enqueueCompleted = enqueueRequest
lastWasEnqueue = true
} elif (fifoPop) {
dequeueAccepted = fifoPopAccepted
response = fifoData
dequeueCompleted = dequeueRequest
lastWasEnqueue = false
}
goto Tick
}
}
}