C⏚ v2.0.0Updated 2026-05-12·Guides

Integrate with an FPGA toolchain

The C⏚ compiler emits plain Verilog-2001 (or VHDL-93) - no SystemVerilog, no vendor extensions, no proprietary primitives. The output is intended to slot into standard synthesis flows without an extra translation step. Exact tool acceptance still depends on the generated design, target family, and the constraints you supply. This guide walks through the handoff from cg-language-server.jar generate to a working bitstream.

You should already have the runtime and command setup from Install, plus a working .cg design. See CLI reference if you want the command flags without the narrative around them. The vendor toolchain (Vivado, Quartus, Yosys + nextpnr, etc.) is whatever you would use for hand-written HDL.

Step 1 - Generate the HDL

Invoke the generate subcommand on either a single file or a directory:

java -jar cg-language-server.jar generate src/MyDesign.cg

Default target is Verilog. To get VHDL instead:

java -jar cg-language-server.jar generate src/MyDesign.cg --target vhdl

To pick a specific output directory:

java -jar cg-language-server.jar generate src/ --output build/hdl

Without --output, Verilog lands in verilog-gen/ and VHDL in vhdl-gen/, both at the project root (next to src/).

Step 2 - Inspect what you got

Each top-level entity becomes one HDL file, preserving the C⏚ package path on disk:

verilog-gen/
  com/
    example/
      Counter.v
      Counter_test.v
      MyTopNetwork.v

Module names are the unqualified entity name (Counter, MyTopNetwork). Every generated module exposes:

  • clock - one input per clock declared in the entity's properties { clocks: [...] }. The default name is just clock.
  • reset_n - active-low asynchronous reset, by default. The reset polarity and synchronicity are configurable per entity via properties { reset: ... }.
  • The user-defined ports, one Verilog port per in or out declaration. push ports add a _valid flag; stream ports add _valid and _ready.

External tasks (implementation: { type: "external", file: ... }) are not regenerated. Their file and dependencies paths must be added to your toolchain project alongside the generated files.

Step 3 - Add the files to your toolchain project

The procedure depends on your vendor flow. Generated files are plain HDL, so you add them much as you would hand-written source.

AMD/Xilinx Vivado. Create a project, then Add Sources → Add Files and select everything under verilog-gen/. Set the top module to the network you want synthesized (right-click the module, Set as Top).

Intel Quartus. Project → Add/Remove Files in Project and add the .v files. Set the top-level entity under Assignments → Settings → General.

Yosys + nextpnr. Pass every .v file to yosys -p:

yosys -p "read_verilog verilog-gen/com/example/*.v; \
         synth_ice40 -top MyTopNetwork -json out.json"

For VHDL via GHDL plus Yosys (the ghdl-yosys-plugin flow):

yosys -m ghdl -p "ghdl --std=93 vhdl-gen/com/example/*.vhd -e MyTopNetwork; \
                  synth_ecp5 -json out.json"

Icarus Verilog (simulation). For an HDL-level cross-check against the bytecode simulator, see the Cross-check guide.

Step 4 - Constrain the clocks

Generated modules do not embed timing constraints. You write the SDC, XDC, or LPF file by hand, naming the same clock port the generated module exposes. A single-clock design needs one create_clock (or vendor equivalent); a multi-clock design needs one per domain plus appropriate clock-group rules. Consult your toolchain's timing-constraint documentation for the syntax.

Step 5 - Synthesize

Run the vendor flow as usual. There is no C⏚-specific step. The generated HDL is regular RTL - synthesis tools see ordinary register transfers, multiplexers, and arithmetic; no black boxes, no opaque primitives.

Toolchain compatibility

The generated HDL is designed for the following categories of flow. This list describes intended compatibility, not an exhaustive test matrix for every release and device family.

ToolHDLNotes
AMD/Xilinx VivadoVerilog, VHDLVerilog-2001 and VHDL-93 supported out of the box
Intel Quartus PrimeVerilog, VHDLSame; no language-version flags needed
Lattice DiamondVerilog, VHDLSame
Microchip LiberoVerilog, VHDLSame
Yosys / nextpnrVerilogOpen flow for iCE40, ECP5, Gowin
GHDL + ghdl-yosys-pluginVHDLOpen flow for VHDL designs
Icarus VerilogVerilogSimulation only
VerilatorVerilogSimulation only; some tasks may need --no-timing

What the compiler avoids on purpose:

  • SystemVerilog-only constructs (logic, always_ff, packed structs). Output stays in Verilog-2001 so it passes Quartus and Vivado in their strictest modes.
  • Vendor primitives (BUFG, IOBUF, DSP/BRAM blocks). Inference is left to the synthesis tool, which keeps the output portable.
  • VHDL-2008 features in the VHDL backend. Output stays VHDL-93 for the same portability reason.

Verify

After synthesis, the place-and-route report should show resource usage similar to a hand-written equivalent. If you see surprising mismatches (e.g. RAM inferred as registers, or vice versa), open the generated HDL - it is readable and inspecting the actual register/RAM declarations usually points at the cause.

Where next

  • Cross-check against HDL - run the same testbench through the bytecode sim and Icarus Verilog or GHDL.
  • Properties - implementation for wrapping pre-existing HDL with type: "external".
  • Bytecode simulator - Neosyn: Generate HDL is on the same status-bar / editor-title / right-click / palette surfaces as Fast Sim, for one-click generation from VS Code.