Livt packages
Livt.ML
Version 1.6.1
Fixed-size quantized inference, tensor storage, attention, and transformer building blocks for Livt.
Published files (132)
src/embedding/Embedding64Stream.lvt
namespace Livt.ML.Embedding
/**
* Streams one 64-value embedding row from an external scalar memory service.
*
* The component converts a valid entry index into 64 consecutive flat memory
* addresses and forwards returned values with toggle handshakes. It stores no
* embedding table and is therefore suitable for ROM, Livt.IO RAM, or an
* external-memory controller.
*/
component Embedding64Stream
{
// Compile-time dimensions, bounds, and numeric constants.
public const VECTOR_SIZE: int = 64
// Entry-selection handshake and invalid-index status.
entryRequest: logic
entryIndex: int
entryAcknowledge: logic
// Borrowed scalar-memory request/response handshake.
memoryRequest: logic
memoryAddress: int
memoryData: int
memoryAcknowledge: logic
// Output payload and toggle acknowledgment; payload stays stable while pending.
outputRequest: logic
outputData: int
outputLast: logic
outputAcknowledge: logic
// Entry-selection handshake and invalid-index status.
invalidEntry: logic
// Transfer progress and retained request/acknowledgment state.
entrySeen: logic
// Current position and bounds within the configured frame.
elementIndex: int
currentEntry: int
entryCount: int
// Transfer progress and retained request/acknowledgment state.
waitingMemory: bool
pendingOutput: bool
active: bool
/**
* Binds the borrowed scalar memory service and entry/output handshakes. entryCount defines
* valid row indices; memory addresses count scalar elements. Hold request payloads until
* acknowledged.
*/
new(
entryCount: int,
entryRequest: in logic, entryIndex: in int, entryAcknowledge: out logic,
memoryRequest: out logic, memoryAddress: out int, memoryData: in int,
memoryAcknowledge: in logic, outputRequest: out logic,
outputData: out int, outputLast: out logic, outputAcknowledge: in logic,
invalidEntry: out logic)
{
this.entryCount = entryCount
this.entryRequest = entryRequest
this.entryIndex = entryIndex
entryAcknowledge = this.entryAcknowledge
memoryRequest = this.memoryRequest
memoryAddress = this.memoryAddress
this.memoryData = memoryData
this.memoryAcknowledge = memoryAcknowledge
outputRequest = this.outputRequest
outputData = this.outputData
outputLast = this.outputLast
this.outputAcknowledge = outputAcknowledge
invalidEntry = this.invalidEntry
}
/**
* Accepts one entry request, reads its 64 scalar values, and holds each output until
* acknowledged. An invalid entry is acknowledged with invalidEntry and produces no row.
*/
process Main()
{
entryAcknowledge = entrySeen
if (pendingOutput) {
if (outputAcknowledge == outputRequest) {
pendingOutput = false
if (elementIndex == 63) {
elementIndex = 0
active = false
} else {
elementIndex++
memoryAddress = currentEntry * VECTOR_SIZE + elementIndex
memoryRequest = !memoryRequest
waitingMemory = true
}
}
} else {
if (waitingMemory) {
if (memoryAcknowledge == memoryRequest) {
outputData = memoryData
outputLast = 0b0
if (elementIndex == 63) {
outputLast = 0b1
}
outputRequest = !outputRequest
waitingMemory = false
pendingOutput = true
}
} else {
if (!active && entryRequest != entrySeen) {
entrySeen = entryRequest
invalidEntry = 0b0
if (entryIndex < 0 || entryIndex >= entryCount) {
invalidEntry = 0b1
} else {
currentEntry = entryIndex
elementIndex = 0
memoryAddress = entryIndex * VECTOR_SIZE
memoryRequest = !memoryRequest
waitingMemory = true
active = true
}
}
}
}
}
}