Language library

The Base Library

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

The Livt base library provides the common types, annotations, and utilities that make everyday code concise. You have already seen several of them: primitive types, @Test, Simulation.Report, string encoding, and component context.

This page is not a complete API reference. It explains how to think about the base library and where it fits into normal Livt code.

Core Types

Primitive keywords such as bool, byte, int, logic, string, clock, and reset map to base-library concepts. 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.

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 synthesizable design behavior.

Simulation code should stay mostly in tests. If a source component uses simulation-only helpers, make that choice obvious and keep it out of the synthesis path.

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 simple UART messages or HTTP-style responses.

Context

Sequential processes use a component context for clock and reset:

livt
component Counter
{
    public count: int

    new(clk: clock, rst: reset)
    {
        this.context.clk = clk
        this.context.rst = rst
    }

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

You usually do not create the context yourself. You bind its clock and reset signals when a component needs an explicit timing source.

Hardware-Oriented Helpers

The base library should be used for common, well-defined operations instead of recreating them in every project. Examples include:

  • simulation reporting
  • test annotations and test context
  • string-to-byte encoding
  • common primitive type support
  • shared interfaces used by the compiler and generated VHDL

As the ecosystem grows, more protocol helpers and reusable components may live in packages rather than the base library. Use the base library for universal building blocks; use packages for domain-specific functionality.

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 generated code 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 an interface required by the compiler or test runner?

That habit keeps the language model clear.

Summary

The base library provides the common foundation for Livt projects. Use keyword types for everyday declarations, keep simulation helpers in tests, encode strings when hardware needs byte data, and rely on context for clocked behavior.