Toolchain integration

Vendor Integration

Generated VHDL, vendor project handoff, synthesis boundaries, wrappers, constraints, timing, and release artifacts.

Livt generates VHDL so that designs can enter existing FPGA and ASIC toolchains. The generated VHDL is not an afterthought. It is the handoff point between Livt and vendor tools, and it should remain inspectable.

Vendor integration is about keeping that handoff clean.

Generated VHDL

The normal flow is:

  1. Write Livt source.
  2. Build the project.
  3. Review or archive the generated VHDL when needed.
  4. Run simulation.
  5. Hand generated VHDL to the vendor flow for synthesis, implementation, or downstream integration.

Generated VHDL should map back to the Livt structure: components become VHDL entities and architectures, fields become signals or ports, and processes become VHDL process/state-machine logic.

Synthesis Boundaries

Keep synthesizable design code separate from test and simulation code. A source component should avoid simulation-only APIs unless it is explicitly not part of the synthesis path.

Good boundaries make vendor integration simpler:

  • src/ contains design code
  • tests/ contains test components and simulation scenarios
  • top-level constructors expose clear physical signals
  • interfaces group protocol signals
  • generated VHDL ports are easy to review

Top-Level Components

The top-level component is the bridge to the vendor project. Keep its constructor clear and hardware-facing:

livt
component Top
{
    app: AppCore

    new(clk: clock, rst: reset, rx: in logic, tx: out logic)
    {
        this.context.clk = clk
        this.context.rst = rst
        this.app = new AppCore(rx, tx)
    }
}

Avoid hiding board-level signals deep inside the design. A reviewer should be able to open the top-level component and understand the external contract.

Vendor Wrappers

Many designs need to connect Livt-generated VHDL to vendor-specific primitives: PLLs, block RAMs, transceivers, IO buffers, clocking resources, or generated IP.

The usual strategy is to wrap vendor-specific functionality behind a stable Livt interface:

livt
interface IUartPins
{
    rx: in logic
    tx: out logic
}

The Livt design depends on the interface. The vendor-specific wrapper handles the details of the target device.

Constraints and Timing

Livt source does not replace timing constraints. Vendor flows still need clock definitions, pin assignments, IO standards, generated clocks, false paths, and other constraints.

Keep constraints versioned with the project. When a Livt interface or top-level port changes, check whether constraints must change too.

Inspecting Generated Ports

Before integrating into a vendor project, inspect generated ports:

  • Are input and output directions correct?
  • Are clock and reset ports named and connected as expected?
  • Do interface fields expand into the expected VHDL records or ports?
  • Are public stored fields exposed intentionally?
  • Are test-only components excluded from synthesis?

This inspection catches boundary mistakes early.

Deployment Considerations

Deployment is project-specific, but the pattern is consistent:

  • build Livt
  • run tests
  • collect generated VHDL
  • run vendor synthesis and implementation
  • archive reports and bitstreams

As the design matures, automate these steps in CI so hardware integration is repeatable.

Summary

Livt should fit into existing hardware flows, not replace them all at once. Keep the generated VHDL visible, maintain clean top-level boundaries, wrap vendor-specific blocks behind interfaces, and treat constraints as part of the design.