Project 01 · VHDL

VHDL templates that follow
your house style

A snippet engine fills blanks. It cannot decide whether a reset exists, or whether a FIFO crosses clock domains. Each template here is a small Lua program that renders VHDL, so a handful of answers change the structure of the code, not just its names.

FOUR KEYSTROKES two answers, one AXI4-Lite slave

Problem

A tabstop cannot decide
whether a reset exists

Every team writes the same handful of blocks its own way. A snippet stores one answer and leaves the rest to editing afterwards. The question is structural: an asynchronous reset is a different sensitivity list and a different if, not a different word.

process, rendered twice same template, same label
-- reset = { style = "async" }
p_main : process (clk, rst_n) is
begin
  if rst_n = '0' then
    -- reset state
  elsif rising_edge(clk) then
    -- clocked logic
  end if;
end process p_main;

-- reset = { style = "sync" }
p_main : process (clk) is
begin
  if rising_edge(clk) then
    if rst_n = '0' then
      -- reset state
    else
      -- clocked logic
    end if;
  end if;
end process p_main;
SAME TEMPLATE one line of configuration apart

Approach

Templates are Lua
that renders VHDL

A template declares its parameters and returns the lines to insert. Because it is a function rather than a string, a parameter can add a synchroniser stage, drop a generic, or split a process in two. Twenty-one ship with the plugin: skeletons, RTL blocks, clock-domain crossings, FIFOs and a dual-port RAM, five bus slaves, three testbench styles.

Completion comes from an in-process LSP server, so they appear in the normal menu without an external binary. An inserted block stays live: change a parameter and it re-renders where it sits.

RE-RENDERS as the parameters change, no snippet engine

Correctness

Generated code that does not analyse
is worse than none

So none of it is taken on trust. Every template is rendered into fixtures, and every fixture is compiled and style-checked before it can be merged.

Beyond templates

Reading what is already written

Most of an FPGA day is spent wiring up entities that already exist. The plugin can instantiate entities and create testbenches from what is in the project: it parses an entity and writes the instance, its component declaration and the signals to connect it, named throughout.

Clocks and resets are found by the shape of the declaration rather than by name, so two clocks and an active-low reset come out driven correctly even when nothing is called clk.

BOTH CLOCKS DRIVEN found by shape, neither called clk

Scope

What it does not do

No SystemVerilog, and no synthesis or simulation from inside the editor — those belong to tools that already do them well. MIT-licensed, and the VHDL it generates is explicitly public domain: code out of a generator should not carry the generator's licence.