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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
@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.
[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.