Forge
Hardware Engineering: Using Forge to Write Verilog and VHDL Securely
RTL is source code with its own gravity — architecturally distinct from software, and just as exposed when written against a cloud model. What it takes for a coding appliance to be genuinely useful for hardware description languages.
· 9 min read
Register-transfer level design has spent the last several years watching the software world adopt AI-assisted coding at a pace hardware teams could only envy from a distance. The reasons for the gap are not mysterious. Verilog and VHDL are text, and an LLM that has seen enough of them can produce plausible-looking modules, but a hardware team's source tree is frequently the single most sensitive artifact the organization holds. An RTL repository for a defense radar front end, a custom accelerator, or a secure element does not just describe a program's behavior; it describes a physical thing that will be fabricated, and in regulated programs it can carry export-control and classification weight that ordinary application source code does not. Sending that tree to a cloud coding assistant, even one with a strong data-handling policy, is a different category of exposure than sending it a snippet of a web backend. For teams under ITAR, EAR, or classification constraints, it has often been a non-starter entirely, which has left hardware engineers writing RTL the way software engineers wrote code fifteen years ago: alone, in an editor, without a collaborator that has read the rest of the codebase.
Forge's premise is that a repository-aware coding assistant should not have to disqualify itself from HDL work just because HDL work happens to be sensitive. The appliance is sealed and air-gapped by design, so the constraint that keeps RTL off cloud assistants, the source can't leave the boundary, is exactly the constraint Forge was built to satisfy from the start. But satisfying the confidentiality requirement is necessary, not sufficient. Making that same appliance genuinely useful for hardware description languages, rather than merely tolerant of them, means treating Verilog and VHDL as their own domain with their own structure, not as software source code that happens to use unfamiliar keywords.
RTL is not software, and pretending otherwise breaks retrieval
The single biggest mistake in applying a general-purpose coding assistant to hardware description languages is treating a module the way you'd treat a function. A Verilog always block or a VHDL process is not a sequence of imperative statements executed top to bottom. It's a description of hardware that will exist concurrently and permanently, evaluated on every clock edge, sensitive to a signal list that has to be exactly right or the synthesized behavior silently diverges from simulation. A retrieval system built around the assumptions of sequential software (this line runs, then that line runs, then the function returns) will misread that structure in ways that matter. It will fail to flag a missing signal in a sensitivity list as the correctness problem it is, because "control flow" in the software sense doesn't map cleanly onto what that sensitivity list is actually declaring.
Forge's indexing has to represent an HDL codebase on its own terms: module and entity boundaries, port lists, signal-level connectivity between instantiated components, clock and reset domains, and the generate-block and parameter structures that let a single module description expand into many different physical instances depending on how it's elaborated. A question like "what else is on this clock domain" or "trace this signal from the top level down to the leaf instance" is a graph traversal over exactly the kind of structure Forge already builds for software call graphs, but the graph's edges mean something different in RTL, and an assistant that doesn't model that difference will retrieve confidently and answer wrong.
Verilog and VHDL are not one language wearing two hats
A second failure mode is treating the two dominant HDLs as interchangeable dialects of the same underlying idea. They share a job, describing synchronous digital hardware, but their type disciplines, their simulation semantics, and the idioms experienced engineers reach for are different enough that an assistant trained mostly on one and lightly exposed to the other tends to produce code that looks right and simulates wrong. VHDL's strict typing catches classes of mistakes at compile time that Verilog's looser typing will happily let through to simulation, where they show up as a subtly wrong waveform instead of a build error. A coding assistant that generates VHDL with Verilog's permissiveness in mind, or Verilog with VHDL's type strictness assumed, produces code that a hardware engineer then has to debug at exactly the layer where the assistant was supposed to save time.
Being useful here means treating each language as a first-class citizen of its own idioms rather than as a translation of the other: recognizing SystemVerilog's interface and assertion constructs as tools with their own correct usage, not as syntactic variations on plain Verilog, and respecting VHDL's package and library structure as the mechanism experienced teams actually use to manage large designs, rather than flattening everything into a single file because that's easier for a model to reason about in isolation.
Simulation semantics: the gap between "compiles" and "correct"
Software has a relatively forgiving feedback loop: code that compiles and passes a test suite is usually doing approximately what was intended. RTL's feedback loop is stricter and later. A module can elaborate cleanly, pass a simple testbench, and still contain a race condition between blocking and non-blocking assignments that only shows up under specific timing, or a latch inferred by an incomplete conditional that synthesis will happily turn into physical hardware nobody intended to build. The gap between "this simulates" and "this is what the engineer meant" is where a large fraction of real RTL bugs live, and it's a gap that a coding assistant without hardware-specific grounding will not reliably see, because the code in question is syntactically fine.
A hardware-aware assistant is useful in proportion to how well it reasons about that gap rather than about syntax alone: flagging a sensitivity list that omits a signal the block actually reads, noticing an incomplete case statement that will infer a latch instead of the intended combinational logic, recognizing where a signal crosses between clock domains without the synchronization the crossing requires. These are the review comments a strong senior RTL engineer gives, not the comments a linter gives, and they're the bar an assistant has to clear to be worth having in the loop on a design that will eventually be taped out or loaded onto a device that can't be patched after the fact the way software can.
Repository scale means something different for a hardware tree
A software monorepo's scale problem is mostly about breadth: many services, many files, many indirect dependencies to trace. A hardware repository's scale problem is often about depth: a design hierarchy that descends through many levels of instantiation, where a signal at the top level has to be traced through a dozen intermediate modules before it reaches the leaf where its actual behavior is defined, and where the same lower-level module might be instantiated dozens of times with different parameters producing meaningfully different physical behavior at each site. Answering "what happens to this signal" honestly requires walking that hierarchy correctly, not just finding textual matches for the signal's name, a name that may be locally rebound or renamed at a port map with every level of instantiation.
This is the same underlying discipline Forge applies to software repository context: index the real structure once, retrieve the load-bearing slice of it for a given question rather than everything that might be relevant, applied against a graph whose shape is hierarchical instantiation and physical connectivity instead of function calls and imports. Getting it right matters more here, not less, because a wrong answer about software behavior gets caught in code review or a failing test; a wrong answer about hardware behavior can survive all the way to a fabricated part.
Why this has to happen inside the boundary
None of the above is optional polish on top of a working assistant. It's what "working" means for this domain. But it only matters if the underlying constraint that brought a hardware team to a sealed appliance in the first place is actually honored: that the RTL, the design hierarchy, the module names that might telegraph what a program is building, none of it ever needs to leave the enclave to get a useful answer. A hardware-aware coding assistant that requires shipping fragments of the design out for indexing or inference has solved the easier half of the problem and left the harder half, the reason the team couldn't use a cloud tool in the first place, exactly where it started.
That is the case for treating hardware description languages as a real target for a sealed coding appliance rather than an edge case tolerated by a general-purpose one: the engineering discipline required to be genuinely useful on RTL and the confidentiality requirement that keeps RTL off the cloud are not competing priorities to trade off against each other. They point at the same appliance: one that understands the hierarchy, the timing, and the semantics of the hardware being described, entirely inside the boundary the design could never leave.