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.cgDefault target is Verilog. To get VHDL instead:
java -jar cg-language-server.jar generate src/MyDesign.cg --target vhdlTo pick a specific output directory:
java -jar cg-language-server.jar generate src/ --output build/hdlWithout --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.vModule names are the unqualified entity name (Counter,
MyTopNetwork). Every generated module exposes:
clock- one input per clock declared in the entity'sproperties { clocks: [...] }. The default name is justclock.reset_n- active-low asynchronous reset, by default. The reset polarity and synchronicity are configurable per entity viaproperties { reset: ... }.- The user-defined ports, one Verilog port per
inoroutdeclaration.pushports add a_validflag;streamports add_validand_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.
| Tool | HDL | Notes |
|---|---|---|
| AMD/Xilinx Vivado | Verilog, VHDL | Verilog-2001 and VHDL-93 supported out of the box |
| Intel Quartus Prime | Verilog, VHDL | Same; no language-version flags needed |
| Lattice Diamond | Verilog, VHDL | Same |
| Microchip Libero | Verilog, VHDL | Same |
| Yosys / nextpnr | Verilog | Open flow for iCE40, ECP5, Gowin |
| GHDL + ghdl-yosys-plugin | VHDL | Open flow for VHDL designs |
| Icarus Verilog | Verilog | Simulation only |
| Verilator | Verilog | Simulation 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.