Livt is a programming language for FPGA and ASIC development. It lets you model hardware as components with fields, constructors, processes, functions, and interfaces, then generates VHDL that can be inspected, simulated, and handed to existing vendor tools.
The goal is not to hide hardware. Good FPGA work still requires clear thinking about timing, state, signals, reset behavior, and resource usage. Livt raises the level at which you express that hardware, so more of your attention can go into the design itself instead of repeated HDL boilerplate.
Why Livt Exists
Traditional HDLs such as VHDL and Verilog are precise and proven, but they make many common development tasks more verbose than they need to be. Software teams have long relied on package managers, test frameworks, CI, rich language tooling, and reusable abstractions. Hardware projects need the same discipline, but with semantics that still respect synthesizable digital design.
Livt brings those ideas into the FPGA and ASIC domain:
- Components make hardware boundaries explicit.
- Constructors describe how components are wired together.
- Processes describe ongoing behavior.
- Functions encapsulate reusable calculations or operations.
- Interfaces define contracts for signal bundles and behavior.
- Tests are written in Livt alongside the design.
- Generated VHDL remains part of the workflow rather than a black box.
The result is a language that feels familiar to software developers without discarding the mental model hardware engineers rely on.
Who This Guide Is For
This guide is for developers who want a practical introduction to Livt:
- FPGA and ASIC engineers who want more structure, reuse, and automated testing without giving up control over the generated hardware.
- Embedded and software developers who understand programming but need a clearer path into hardware design.
- Teams that want hardware code to be easier to review, test, package, and evolve.
You do not need to be a VHDL expert to start reading, but hardware concepts will appear quickly. When timing, reset, simulation, or synthesis matters, the guide will name it directly.
A First Livt Project
A Livt project has source files, test files, and a project configuration file. A minimal project looks like this:
HelloWorld/
|-- livt.toml
|-- src/
| `-- HelloWorld.lvt
`-- tests/
`-- HelloWorldTest.lvt
Source files usually live in src/. Test components live in tests/.
A Small Component
The following component prints a message during simulation:
namespace Livt.App
component HelloWorld
{
public fn SayHello()
{
Simulation.Report("Hello, Livt!")
}
}
This is intentionally small, but it already shows the shape of Livt code:
component HelloWorlddeclares a component.public fn SayHello()exposes behavior that other components or tests can call.Simulation.Report(...)writes a message to the simulator output.
Simulation.Report is a simulation-only API. It is useful in tests, examples, and debugging, but it does not describe synthesizable hardware. That boundary is important in Livt: some code describes hardware, while other code exists only to verify or observe the design during simulation.
A Built-In Test
Tests are written as Livt components marked with @Test. A test component can instantiate the design under test and assert its behavior:
namespace Livt.App.Tests
using Livt.App
@Test
component HelloWorldTest
{
helloWorld: HelloWorld
new()
{
this.helloWorld = new HelloWorld()
}
@Test
fn PrintsGreeting()
{
this.helloWorld.SayHello()
}
}
Annotations start with @ and apply to the declaration that follows them. @Test on a component marks a test suite. @Test on a function marks an individual test case.
The constructor creates the component under test. The test function then calls the public function, which prints the message during simulation.
This example is deliberately about visibility, not hardware behavior. It teaches how to run code in the simulator and see output. Later examples will use assertions to check behavior.
Building
Run the build command from the project directory:
livt build
The compiler reads the Livt source, checks the project, and generates VHDL output. The generated files are meant to be readable. They are the bridge between the Livt source and the existing FPGA toolchain.
Typical build output lists the base library files, project source files, and test files that were compiled:
Compiling Livt.Lang.lvt
Compiling Livt.Simulation.lvt
Compiling HelloWorld.lvt
Compiling HelloWorldTest.lvt
Exact paths and file names can vary by project and compiler version. What matters is the workflow: write Livt, build, inspect generated VHDL when needed, and feed that VHDL into the next tool.
Running Tests
Run the test command from the same project directory:
livt test
The test runner builds what is needed, analyzes the generated VHDL with the configured simulator, elaborates the test component, and runs the test cases. For this example, the important output is the report from SayHello and the final simulation completion message:
Nothing to compile - all components are up to date.
analyze .../out/debug/lib/Livt.Lang.TestContextProvider.Package.vhd
analyze .../out/debug/lib/Livt.Lang.IContext.Package.vhd
analyze .../out/debug/main/Livt.App.HelloWorld.Package.vhd
analyze .../out/debug/tests/Livt.App.Tests.HelloWorldTest.Package.vhd
analyze .../out/debug/lib/Livt.Lang.TestContextProvider.vhd
analyze .../out/debug/main/Livt.App.HelloWorld.vhd
analyze .../out/debug/tests/Livt.App.Tests.HelloWorldTest.vhd
elaborate helloworldtest
.../Livt.App.HelloWorld.vhd:58:41:@165ns:(report note): Hello, Livt!
.../Livt.App.Tests.HelloWorldTest.vhd:198:41:@275ns:(report note): Simulation finished
Even this small example shows an important part of Livt's workflow: tests are not an afterthought. They are written in the same language as the design and can be run early, before the design is integrated into a larger vendor project.
The next step after printing is checking. In real tests, you will normally use assert to verify expected behavior and reserve Simulation.Report for progress messages or debugging.
What Livt Code Describes
Livt code usually falls into four categories:
- Structure: components, constructors, fields, interfaces, and namespaces.
- Behavior: processes, functions, assignments, conditions, loops, and states.
- Data: primitive types, fixed-size arrays, constants, strings, and literals.
- Verification: test components, assertions, simulation reports, and waits.
The language is designed so these categories work together. A component can store state, expose a public signal, implement an interface, instantiate subcomponents, and be tested through a Livt testbench.
How to Use These Docs
The next pages build up Livt in layers.
Page 2 introduces the core building blocks: namespaces, components, fields, constants, constructors, processes, functions, and interfaces.
Page 3 explains the type system and operators. This is where logic, byte, int, arrays, string data, and casts become precise.
Page 4 covers control flow, including loops, assertions, process-level continue, and explicit FSM-style sequencing with state and goto.
After that, the guide moves from syntax into design practice: organizing code, composing systems with interfaces, using the base library, writing tests, and integrating Livt into larger hardware workflows.
The purpose of this guide is not only to list syntax. It should help you develop a professional Livt style: clear components, explicit hardware boundaries, readable tests, and designs that can grow without becoming fragile.