Language library

The Base Library

Core types, annotations, simulation utilities, strings, byte data, and common helpers used in everyday Livt code.

Livt ships a small foundation package and a set of official domain packages. Together they give projects common types, annotations, simulation helpers, byte/string utilities, reusable arithmetic, I/O building blocks, networking, crypto primitives, and fixed-size ML components.

This chapter is a guided overview, not a full API reference. It explains what users can depend on and how to choose the right package.

Two Levels: Livt.Base and Livt

Livt.Base is the core foundation. It contains language-adjacent helpers that are useful in almost every project:

  • primitive type support and annotations;
  • Simulation.Report and diagnostic helpers;
  • string and byte-data helpers;
  • bit, ASCII, conversion, format, and array utilities.

The umbrella Livt package is the easiest starting point when an application wants the official package family:

toml
[dependencies]
Livt = "0.3.0"

Use a direct package dependency when the project only needs one domain package:

toml
[dependencies]
Livt.IO = "0.2.0"

Core Types

Primitive keywords such as bool, byte, int, logic, string, clock, and reset are part of the base environment. In most code, use the keyword spelling:

livt
var valid: bool = true
var data: byte = 0x41
var signal: logic = 0b1

The keyword form keeps examples readable and avoids unnecessary namespace noise.

Annotations

Annotations add metadata to declarations. The most visible one is @Test:

livt
@Test
component PacketParserTest
{
    @Test
    fn ParsesHeader()
    {
        assert true == true
    }
}

@Test on a component marks a test suite. @Test on a function marks a test case. Other annotations configure contexts, warning suppression, and integration settings where the feature requires them.

Simulation Utilities

Simulation utilities are for tests and debugging:

livt
Simulation.Report("starting parser test")

Simulation.Report writes a message to simulator output. It is useful while developing tests, but it is not design behavior for the final hardware.

String Interpolation

Embed variable values directly in a report message using {variable} syntax:

livt
var result: int = this.component.Compute(input)
var expected: int = 42
Simulation.Report("result = {result} expected = {expected}")

The value is converted to a readable form automatically. Multiple variables in one string are supported.

To print an integer as bits, cast it to logic[N] first:

livt
var flags: int = 0b10110
var bits: logic[32] = flags as logic[32]
Simulation.Report("flags = {bits}")

Strings and Byte Data

Strings are useful for fixed text and simulation output:

livt
Simulation.Report("packet accepted")

When hardware needs byte data, encode the string:

livt
component HttpConstants
{
    public const OK: byte[] = "OK".Encode()

    public fn GetLength() int
    {
        return OK.Length()
    }
}

This pattern is useful for protocols that transmit text, such as UART messages or HTTP-style responses.

Context

Sequential processes use a component context for clock and reset:

livt
component Counter
{
    public count: int

    process Count()
    {
        this.count = this.count + 1
    }
}

A context also exposes timing metadata. Use this.context.TicksFor(...) when a reusable component needs a duration in clock ticks:

livt
component DelayTimer
{
    public fn TicksForTenMicroseconds() uint
    {
        return this.context.TicksFor(10us)
    }
}

The direct metadata fields are ticksPerSecond, periodNs, highTimeNs, and lowTimeNs. If a parent assigns a different context to a component, the timing values follow that assigned context.

Livt.Base Helpers

Livt.Base publishes a small set of foundational namespaces:

Namespace Contents
Livt.Bits Bit access, masks, extraction/insertion, population count, parity, rotation, zero/sign extension
Livt.Ascii ASCII constants, character classification, and upper/lower conversion
Livt.Convert Explicit integer conversions with named clamped, wrapping, and truncating behavior
Livt.Format Fixed-width text formatting for byte, int, and uint values
Livt.Array Fixed-size array helpers such as byte equality and search
Livt.String Byte-array string search helpers such as starts-with, ends-with, contains, and index-of
Livt.Diagnostics Assertion and reporting helpers for tests and simulation

Import the namespace you need with using:

livt
using Livt.Bits
using Livt.Ascii

Use these helpers for common operations instead of reimplementing them in every project.

Official Packages

The umbrella Livt package references the main official package family. Additional focused packages such as Livt.Bus can be added directly:

Package Purpose
Livt.Base Foundational helpers, annotations, diagnostics, strings, arrays, bits, ASCII, and conversions
Livt.IO RAM, UART, buffered UART, loopback UART, I2C pins, I2C master/slave, and I2C register targets
Livt.Math Square root, MAC, fixed-point helpers, complex Q15, trigonometric lookup, and pseudo-random generators
Livt.ML Fixed-size ML blocks: vector math, linear layers, activations, embeddings, attention, normalization, classifiers, and small models
Livt.Net Ethernet, ARP, IPv4, ICMP, TCP, HTTP, endpoint, web-server, and EthernetLite-style integration helpers
Livt.Crypto AES, SHA-2/SHA-3, HMAC, HKDF, CMAC, ChaCha20, Poly1305, AEAD, and deterministic random primitives
Livt.Utils Small general-purpose utilities such as CRC32
Livt.Bus Memory-mapped bus contracts and test components, including AXI4-Lite transaction helpers and Avalon/Wishbone signal interfaces

Livt.Bus is currently a direct dependency rather than part of the umbrella package:

toml
[dependencies]
Livt.Bus = "0.1.0"

It is the usual companion package for components that use Livt.HxS to expose memory-mapped fields and functions.

Livt.IO Example

livt
using Livt.IO

component SerialExample
{
    uart: Uart

    new(rx: in logic, tx: out logic)
    {
        this.uart = new Uart(rx, tx)
    }

    public fn SendByte(value: byte) bool
    {
        return this.uart.Transmit(value)
    }
}

Livt.Math Example

livt
using Livt.Math.FixedPoint

component FixedPointExample
{
    public fn Quarter() int
    {
        var half: int = 16384
        return Q15.MulValue(half, half)
    }
}

How to Choose a Package

  • Use Livt.Base for common helpers and simulation/test utilities.
  • Use Livt.IO for memory, serial I/O, and peripheral-style components.
  • Use Livt.Math for reusable arithmetic and fixed-point building blocks.
  • Use Livt.ML, Livt.Net, or Livt.Crypto for domain-specific components.
  • Use Livt.Utils for small general-purpose helpers that do not fit another domain.
  • Use Livt.Bus for memory-mapped bus boundaries and transaction-level tests.

Older standalone projects such as Ram, Queue, Stack, and BitSet are not part of the main official package table unless the umbrella Livt package references them.

Reading Base-Library Code

Do not treat the base library as magic. It is part of the Livt environment, and understanding its common pieces will make project and test behavior easier to reason about.

When a feature appears to come from nowhere, ask:

  • Is it a primitive keyword?
  • Is it an annotation?
  • Is it a simulation helper?
  • Is it a method on a base-library type?
  • Is it provided by one of the official packages?

That habit keeps the language model clear.

Worked Example

A static page store is a useful small example of base types in application code: encoded content is held in a fixed byte array, access is bounded by a length, and tests check the first, last, and out-of-range indices. Keep this extract independent from the complete web application so its data and boundary behavior remain easy to test.

Summary

Livt.Base provides the common foundation for Livt projects. The umbrella Livt package adds the official package family for I/O, math, ML, networking, crypto, and utilities. Start broad with Livt when exploring, and depend on a specific package when a project only needs one domain.