Livt product updates

Livt Release Notes

Follow new Livt releases, important changes, and guidance for getting started.

Livt 1.1.0 Is Here

19.10.2026
Denis Vasilík

We are happy to announce Livt 1.1.0. This release makes reusable hardware easier to express, adds more ways to describe design intent, and improves the everyday experience of building and reviewing Livt projects.

The goal remains the same: start with readable behavior and make timing and hardware structure explicit where your design requires it. Higher-level abstractions should help you manage complexity without taking away control over state, clock cycles, and resource choices.

Build More Reusable Hardware

Generics now let components, interfaces, and functions work with different types without duplicating their implementation. Compile-time value parameters make settings such as buffer capacities part of a component's configuration, while interface constraints describe the capabilities a type must provide.

Static lambdas and callable parameters let reusable algorithms accept behavior that is bound at compile time. Together, these features support configurable queues, iterators, and processing components without introducing runtime type dispatch. The operations themselves still have the timing and resource costs of the hardware they describe.

Express Intent More Clearly

Default and named arguments make component construction and function calls easier to read. Function overloading allows related operations to share a name while remaining distinct through their parameter signatures.

Type-safe enums and exhaustive match statements help express finite choices clearly. Distinct types let you separate values that have the same underlying representation but different meanings. Immutable let bindings make it explicit when a local binding should not be reassigned, without making a referenced component or its contents immutable.

Make Hardware Configuration Explicit

Use static if to select an implementation at compile time and static assert to reject unsupported configurations before simulation. Hardware-width calculations and context-derived timing values help keep counters and storage dimensions aligned with the design's configuration. Clock-dependent dimensions can be resolved during HDL elaboration where appropriate.

Reset policies are configurable, with synchronous reset as the default. The generator emits the selected reset behavior directly, keeping the resulting VHDL easier to follow.

A Smoother Development Workflow

Compilation now reports preparation and analysis stages as well as HDL generation, so longer builds provide clearer feedback about what is happening. A two-line progress display gives filenames and paths more room alongside progress information.

The compiler reduces repeated analysis and reuses preparation work where it is safe to do so. Profiling helps identify where compilation time is spent. Editor improvements include transitive dependency discovery, more accurate diagnostics, and more reliable formatting of complex language constructs.

Cleaner HDL and Stronger Integration

Generated VHDL uses shorter, readable names and more consistent spacing and indentation. Improvements to component wiring, scheduled calls, array handling, and initialization make larger compositions more reliable, including corrections to patterns that could previously infer unintended latches.

Vivado and Gowin integration also receive improvements to wrapper generation, project paths, and build settings. Gowin templates use VHDL-2008 by default. When updating an existing project, regenerate its HDL and vendor integration files together, and review custom scripts or wrappers that refer to generated filenames or identifiers.

Get Started with Livt 1.1.0

The easiest way to get started is through the Livt extension for Visual Studio Code. See the installation guide, explore the Livt documentation, and discover public examples and libraries through the Eccelerators organization on GitHub.

Livt 1.0.0 Is Here

26.08.2026
Denis Vasilík

We are happy to announce Livt 1.0.0, the first stable release of our component-oriented programming language for digital hardware development.

Livt brings ideas such as clear interfaces, reusable packages, composition, and automated testing to FPGA development while keeping state, timing, clock domains, concurrency, and resource use explicit.

Get Started with Livt

To use Livt, create an Eccelerators account or sign in to your existing account. Send us a message after registering, and we will help you get started with a trial license.

The easiest way to install Livt is through the Livt extension for Visual Studio Code. The extension guides you through installation and provides the tools needed to create, validate, build, test, and explore Livt projects directly from VS Code.

Explore the Documentation and Examples

Visit the Livt documentation to learn about the language, components, interfaces, processes, contexts, testing, packages, HxS integration, and application development.

Do not forget to explore the open resources, examples, and libraries available through the Eccelerators organization on GitHub. They are a useful starting point for discovering Livt projects and reusable hardware components.

Ask the Livt Agent

You can also ask the Livt Agent included with the VS Code extension. The agent can help you understand Livt, explore an existing project, create components and tests, find reusable packages, and work through compiler diagnostics. It uses the Livt development workflow to validate and test its work, while you remain in control of the design and final result.

The Beginning of a Stable Livt Line

Livt 1.0.0 establishes the foundation for the language, compiler, HDL generation, testing workflow, package ecosystem, documentation, and development tools.

From here, we will continue expanding the Livt base libraries with reusable components for common hardware-development tasks. We will also continue developing AI-assisted workflows that help engineers move from an idea to a structured, tested, and reviewable hardware implementation.

For longer-form background, personal perspectives, and thoughts about Livt, digital hardware development, and AI-assisted engineering, follow Denis Vasilík on Substack.

Have questions, want to try Livt, or would you like to discuss how it could fit into your project? Get in touch with us—we would be happy to hear from you.

Livt Release 0.0.10

21.07.2026
Denis Vasilík

Livt 0.0.10 is a major quality and integration release that resolves 83 tracked issues. It makes larger applications easier to express and verify, with substantial improvements to HxS register interfaces, numeric conversions, arrays, reusable helper functions, and interface-based component composition.

The release also broadens the range of valid Livt programs that build and simulate predictably, while reporting unsupported or ambiguous source earlier and more clearly.

Complete HxS Register Interfaces

HxS integration is the headline capability in 0.0.10. A Livt component can describe a memory-mapped interface directly on its public fields and functions, connect that interface through Livt.Bus, and test it through the same bus contract used by the surrounding system.

Default layouts are deterministic, while explicit blocks, addresses, reserved bits, selected views, delegated windows, enum metadata, values, and reset information are available when a design needs more control. Functions can act as command triggers, accept register-supplied parameters, and return readable values. AXI4-Lite, Avalon, and Wishbone designs use the same annotation model.

livt
using Livt.HxS
using Livt.Bus.Axi4Lite

@Interface(BusType="AXI4Lite")
component DeviceControl
{
    public enabled: logic

    new(bus: flip IAxi4Lite32Master)
    {
        this.enabled = 0b0
    }

    @Register
    public fn Enable()
    {
        this.enabled = 0b1
    }
}

Read more in the Livt docs: HxS register interfaces.

Predictable Numeric Types and Conversions

Numeric intent is more consistent throughout expressions, comparisons, assignments, assertions, shifts, division, and modulo operations. Livt now applies one clear conversion model across bool, int, uint, byte, logic, and logic[N].

Safe widening remains concise, while conversions that can change meaning or lose information require an explicit as cast. High-bit unsigned values, fixed-width vectors, mixed numeric literals, and byte arithmetic now behave more consistently in both design code and tests.

livt
var data: byte = 0xFF
var widened: int = data as int
var bits: logic[8] = data as logic[8]
var lowNibble: logic[4] = bits as logic[4]
var sum: int = 10 + widened

Read more in the Livt docs: data types, casts, and operators.

Stronger Array Literals and Parameters

Array-heavy components are easier to write and reuse. Array literals support a trailing comma, whole-array assignments are checked consistently, and inferred arrays preserve their required dimensions and element values. Unconstrained array parameters also expose dependable length information, which is particularly useful for reusable helpers that work with several fixed array sizes.

livt
var header: byte[4] = [
    0x45,
    0x00,
    0x00,
    0x14,
]

assert header.Length() == 4

Read more in the Livt docs: arrays and dimensions.

More Dependable Reusable Helpers

Inline and context-free functions now cover more practical control-flow and mutation patterns. Helpers can use early returns, loops, shifts, compound assignments, output parameters, and array parameters more reliably. This makes it easier to keep small calculations and reusable data operations close to the components that use them.

livt
fn Fill[](value: out int)
{
    value = 42
}

public fn ReadFilledValue() int
{
    var result: int
    this.Fill(result)
    return result
}

Read more in the Livt docs: functions and component behavior.

Interface-Based Systems at Larger Scale

Interface-oriented applications are more robust across constructor injection, public interface fields, bus endpoints, scheduled calls, and nested component boundaries. Concrete components can be handed to consumers through their interface contract without exposing implementation-specific behavior, and fully qualified type names can be used where larger projects need explicit namespace clarity.

These improvements are especially valuable for processor cores, bus-connected peripherals, protocol adapters, and other systems assembled from several reusable components.

Read more in the Livt docs: interfaces and composition.

Broader Project Reliability

Livt 0.0.10 verifies many more combinations of literals, conversions, array operations, helper functions, interfaces, contexts, and component wiring. Projects with nested configuration files also fail gracefully when they contain unsupported settings instead of disrupting the development environment.

Together, these changes make the everyday workflow more predictable: valid projects build and simulate across a wider range of real application patterns, and mistakes are surfaced closer to the source that needs attention.

Livt 0.0.10 is available from the downloads section.

Livt Release 0.0.9

29.06.2026
Denis Vasilík

Livt 0.0.9 is a reliability release for larger, more connected Livt designs. It resolves 32 tracked compiler issues and focuses on the patterns that matter once a project grows beyond a single component: inherited interfaces, constructor-based wiring, bidirectional endpoints, context-aware timing, named states, inline helpers, arithmetic expressions, and vendor project generation.

The result is a cleaner foundation for building reusable components, protocol controllers, and simulation-backed libraries.

More Reliable Interfaces and Constructor Wiring

Interface-heavy designs are much more dependable in 0.0.9. Components that implement a derived interface can now be used through a parent-interface reference, which makes inheritance useful for real component boundaries. Constructor wiring was strengthened for direct component-to-interface bindings, nested endpoint pass-through, public interface endpoint fields, and bidirectional interface leaves.

This is especially helpful for reusable bus-style components. A component can expose a public endpoint, pass it through a wrapper, or hand a concrete implementation to a consumer that only depends on the interface contract.

livt
interface IBus
{
    observed: out logic
    drive: in logic
}

component BusProvider : IBus
{
}

component Consumer
{
    public ready: logic

    new(bus: flip IBus)
    {
        this.ready = bus.observed
        bus.drive = true
    }
}

Read more in the Livt docs: interfaces and composition.

Stronger State and Process Behavior

Named states and grouped state {} blocks received significant attention. Assignments before goto transitions are preserved, nested if / elif / else branches behave more predictably, local variables inside named states are initialized when their source line executes, and combinational process[] bodies can use local scratch variables without turning a simple process into an unintended multi-step behavior.

livt
public start: bool
public counter: int

process Main()
{
    state Idle
    {
        if (this.start)
        {
            this.counter = 0
            goto Count
        }
    }

    state Count
    {
        var step: int = 0
        step++
        this.counter += step
    }
}

Read more in the Livt docs: control flow and building blocks.

Context Timing as a First-Class Design Idiom

Livt 0.0.9 introduces a clearer timing idiom around component contexts. Components can use their assigned context for timing decisions instead of hard-coded clock constants. The context exposes timing metadata such as ticks per second and period, and the canonical TicksFor(...) helper converts a duration into clock ticks for the component's active context.

livt
component Timeout
{
    public fn TicksForOneMicrosecond() uint
    {
        return this.context.TicksFor(1us)
    }
}

This makes reusable components easier to configure: if a user assigns a different context, timing follows that context; if no context is assigned, the component uses its normal surrounding context.

Read more in the Livt docs: contexts, clock domains, and sync.

Better Arithmetic, Casts, and Helper Functions

Numeric behavior is more consistent across functions, assignments, and tests. Shifts on byte, int, and uint are covered in simple function bodies. Postfix increment and decrement work for supported parameters, variables, and fields. Scalar casts from int and uint to logic now use the low bit. Signed remainder follows signed arithmetic rules, and compound arithmetic assignments preserve the target width before storing the result.

livt
fn Mix(value: int, flags: uint) logic
{
    var next = value++
    var wrapped = next % 3
    return (flags as logic) ^ (wrapped as logic)
}

Inline and context-free helper functions were also hardened, including void helper calls, array field element writes, array-return helpers, and helper calls used inside assertions.

Read more in the Livt docs: data types and operators and namespaces.

Endpoint and Bus-Style Components

Public interface endpoints now behave better when multiple leaves are written in the same step, when endpoint values are held across process iterations, and when a wrapper forwards an endpoint into a nested component. This directly supports component library work such as open-drain buses, protocol adapters, and small reusable I/O building blocks.

livt
component BusCombiner
{
    public controller: IBus
    public target: IBus

    process Combine[]()
    {
        this.controller.observed = this.target.observed
        this.target.drive = this.controller.drive
    }
}

Read more in the Livt docs: interface composition.

Vendor Project Workflow

The vendor flow is more practical for Vivado-based projects. The generated wrapper now receives the full context information required by Livt components, and vendor templates can accept template-specific arguments. For Vivado templates, users can pass the target part directly on the command line and see a configuration overview before the vendor tool is launched.

bash
livt vendor vivado-ip xc7a100tcsg324-1

Read more in the Livt docs: vendor integration.

Verification-Driven Quality

Quality is central to how we work, which is why verification is built into every release. Each fix adds focused tests and simulation coverage, making the language more stable with each release: valid programs build and simulate more reliably, while invalid programs fail earlier with clearer messages.

Livt 0.0.9 is available from the downloads section.

Livt Release 0.0.8

23.06.2026
Denis Vasilík

Livt 0.0.8 is a major quality release that resolves 124 tracked improvements and defects. It makes Livt projects easier to write, easier to review, and easier to validate before they reach board-level integration. The release sharpens diagnostics, broadens language coverage, and expands the simulation suite so common combinations of literals, function parameters, arrays, structural references, and directed interfaces are exercised more consistently.

Language Expressiveness

The language continues to move toward a more compact, software-like style for hardware descriptions. Logic and byte arrays support Python-style slicing, including omitted bounds and negative indices. foreach loops work for arrays and iterator components, with multi-cycle sequencing in process contexts. class, static fn, and inline fn provide clean namespaces and reusable helper functions without forcing every helper into a component instance.

livt
var word: logic[8] = 0xA5
var upperNibble = word[4:8]
var lowerNibble = word[:4]

Read more in the Livt docs: data types, control flow, and namespaces.

Type Safety and Literals

Literal handling is now much stricter and more predictable. Decimal, binary, hexadecimal, boolean, string, time, and frequency literals are checked against their target types before a build continues. Out-of-range integer and unsigned values are rejected early, single-bit logic is distinguished from logic vectors, and state-bearing logic literals such as 0bZ, 0bU, and 0bX are preserved where they make sense. The same validation is applied consistently in variable initializers, constants, assignments, function calls, constructor calls, explicit casts, and array literals.

livt
var valid: logic = 0b1
var unknown: logic = 0bX
var mask: logic[8] = 0bZZZ0_0000
var marker: byte = 0xFF

Read more in the Livt docs: data types and literals.

Portable Numeric Semantics

Livt defines int and uint as 32-bit types, and this release makes numeric intent more predictable across projects. Signed and unsigned arithmetic, conversions, boundary checks, sign-bit behavior, casts, overflow-sensitive literals, and bitwise masks on logic vectors were tightened so designs behave consistently across common development flows.

livt
var signedCount: int = -1
var packetCount: uint = 0xffffffff
var value: logic[8] = 0xA5
var flags: logic[8] = value & 0x0F

Read more in the Livt docs: primitive types, casts, and operators.

Structural References and Interfaces

Component and interface values are now validated as structural references. A component-typed or interface-typed target must receive either a new Component(...) instance or an existing compatible reference. Livt intentionally has no built-in null value; absence or fallback behavior should be modeled with a real component that implements the required contract. Interface use is also clearer: constructors and processes are rejected in interfaces, process calls are rejected as expressions, override declarations must actually override something, and component construction must use new instead of function-call syntax.

livt
reader: IByteReader

new()
{
    this.reader = new RomByteReader()
}

Read more in the Livt docs: interfaces and composition.

Directed Fields and Constructors

Directed fields now respect the effective receiver orientation. This matters for interfaces that can be used from both sides of a connection, especially when an interface reference is passed through constructors with a flipped parameter view. Livt checks whether a field can be read or written from the current orientation and keeps pass-through connections deterministic. Function calls also check argument direction and assignability for out parameters, so invalid call sites are reported before simulation.

livt
interface IBus
{
    in valid: logic
    out ready: logic
}

slave: IBus

new(bus: flip IBus)
{
    this.slave = bus
}

Read more in the Livt docs: interfaces and building blocks.

Arrays and Vector Operations

Array behavior received another round of hardening. Unsupported arrays of complex types are rejected until their user-facing behavior is deliberately specified. Arithmetic on arrays is rejected with a direct diagnostic, scalar indexing gets a clear error, and Concat now requires known logic-vector widths. Livt can still infer concise declarations such as var a: logic[] = 0xAA and then compute the resulting width of a.Concat(b) when both operands are known.

livt
var a: logic[] = 0xAA
var b: logic[] = 0x55
var c = a.Concat(b)

assert c.Length() == 16

Read more in the Livt docs: arrays and vector types.

Diagnostics and Validation

Many former hard-to-read failures are now friendly validation messages. Livt reports keywords used as identifiers, local variables that shadow callable parameters, parent field redeclarations, constructor-name field ambiguities, unsupported process return syntax, unsupported division on logic operands, and invalid use of component or interface type names as values. Type-related diagnostics were improved as well, so users see Livt concepts instead of implementation details.

livt
fn Accumulate(value: int)
{
    // Invalid: the local variable shadows the parameter.
    var value = 0
}

Read more in the Livt docs: building blocks and control flow.

Project Quality and Verification

Everyday design workflows are more robust around loops, state blocks, component-local instantiation, array element assignment, subcomponent calls, byte-array parameters, boolean conditions, and same-name local component instances in independent functions. The verification suite now covers more function parameter combinations, literals, arrays, signed and unsigned arithmetic, structural calls, constructor wiring, and directed interface behavior. The result is a stronger workflow: more cases are checked early and exercised in simulation.

livt
@Test
fn AddsUnsignedValues()
{
    var result = this.alu.Add(1 as uint, 2 as uint)
    assert result == 3
}

Read more in the Livt docs: testing Livt code.

Tooling and Project Workflow

Tooling also received practical polish. Build and test commands report elapsed time, simulator paths can be configured, release profiles can strip simulation helpers, warnings can be controlled per profile, and Vivado project templates now refresh source and simulation file order during project creation. Dependency handling is more predictable too, including local paths, transitive dependencies, same-namespace resolution, name collisions, and reserved identifiers.

toml
[simulator]
path = "/opt/ghdl/bin/ghdl"

[build.release]
warnings = ["all", "no-variable-divisor"]

Read more in the Livt docs: vendor integration, packages and reuse, and the CLI reference.

Livt Release 0.0.7

05.05.2026
Denis Vasilík

Livt 0.0.7 improves the everyday reliability of Livt projects across language features, type checking, component composition, loops, interfaces, and project testing. The release resolves more than 88 tracked issues and focuses on making common design patterns easier to express and easier to validate.

Language Features

Compound assignment operators (+=, -=, *=, /=) are now supported in function and process bodies. Array literals can be used directly as field and variable initializers, including nested arrays. const arrays can be declared with bracket-list initializers, initialized from string .Encode() calls, queried with .Length(), and read from function bodies. Cast expressions, string escape sequences, and uppercase or lowercase hexadecimal literals are handled more consistently.

Type Checking

Type checking is stricter and more predictable. Bitwise masks on byte, helper functions with byte[] parameters, subcomponent call arguments, Length() on constant arrays, and narrowing conversions now produce clearer behavior and diagnostics. When a conversion would lose information, Livt reports the problem instead of allowing an unsafe result.

Component Behavior

Component behavior is more reliable around computed arguments, mixed boolean expressions, constructor-time calls, array field updates, process state transitions, public stored fields, and multi-step subcomponent operations. These improvements make process and function behavior easier to reason about in tests and in larger component hierarchies.

Interfaces and Inheritance

Interface and inheritance support is stronger. Interface-typed function parameters, inherited component functions, interface inheritance chains, interface constants, and automatically provided interface fields now behave more consistently. Components can rely on inherited contracts without repeating declarations that already belong to the interface.

Control Flow and Loops

Loop behavior is clearer. for loop variable initializers run on every iteration, var declarations are scoped to their block, and continue advances to the next iteration instead of restarting the surrounding behavior.

Tooling

Test execution and project feedback are more dependable. livt.toml defines the active test components, dependency test runs include the required package context, and parser diagnostics for missing newlines or semicolons point to the specific token that needs attention.