关于 neosyn-fpga-mcp
neosyn-fpga-mcp 将 C⏚ 编译器工具链接入 MCP,让 AI Agent 编写并验证 FPGA 设计。它结合语言上下文资料与编译、仿真和综合检查,返回可供修正的诊断。
主要功能
- 01C⏚ 代码静态检查与诊断
- 02字节码或 Icarus Verilog 仿真
- 03生成 Verilog 或 VHDL
- 04使用 Yosys 检查综合结果
- 05提供脚手架、示例与语言文档
适用场景
- 01从空白文件搭建可编译的 C⏚ 设计
- 02定位仿真失败并迭代修复代码
- 03生成并检查 FPGA RTL
- 04确认综合结果未折叠或推断锁存器
MCP 相关
该 MCP 服务向支持 stdio 的 MCP 主机提供 C⏚ 检查、仿真、代码生成和综合等工具。模型可通过工具获取编译器诊断并逐步验证设计。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
13收录的工具列表 · 更新于 3 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| path | any | 否 | |
| source | string | 否 | |
| extra_files | any | 否 | |
| package_dir | any | 否 |
详细介绍
neosyn-fpga-mcp
一个将 C⏚ FPGA 工具链交到 AI Agent 手中的 MCP 服务。 模型编写硬件;服务使用真实编译器进行编译、仿真和综合检查,并返回模型可以据此采取行动的结构化诊断信息。
这才是值得关注的区别。让大模型编写 Verilog,它会自信地生成无法构建、无法综合或悄无声息地被折叠为空的代码。而在这里,每一步都由人类使用的同一款编译器进行判定。
两部分协同工作:
cg_context.md— 知识包。将其加载为系统提示词,模型就能编写可信的 C⏚ 代码:包括思维模型、类型、端口、结构体/枚举/泛型、标准库,以及那些会让初稿功亏一篑的易错之处。- MCP 服务 — 将编译器作为工具提供,让模型验证自己的输出,而不是依赖回忆。
知识能带来不错的初稿;将编译器纳入循环才能让结果正确。两者都与模型无关——任何 stdio-MCP 主机(Claude Desktop、Claude Code、Cursor、Cline)都能使用,知识包也适用于任何大模型。
为什么不微调? C⏚ 是一门小众语言,公开代码很少,而且每次发布都会增加功能。微调模型既昂贵又容易过时。上下文中的知识加上验证循环无需重新训练,能随着编译器的演进跟进语言变化,并通过运行代码而非回忆代码来逐步改进。
安装
pip install neosyn-fpga-mcp
然后将其指向 C⏚ 编译器 jar:
export CG_JAR=/path/to/cg-language-server.jar
获取该 jar 有两种方式:
- 开源 — 使用 cg-compiler releases 中预构建的 jar,或从源代码构建。
- 商业版 — 使用已安装的 Neosyn C⏚ 扩展中的 jar,该扩展提供高速字节码模拟器和 VHDL 输出。
需要提供许可证文件:将
NEOSYN_CG_LICENSE设置为该文件的路径,或将文件放在扩展使用的默认路径。没有许可证时,每个工具都会报告许可证问题,而不会运行。
cg_capabilities 会通过探测而非推断,报告你使用的是哪种版本以及它能做什么。
要求
- Python 3.10+
PATH中需要有 Java 17 或更高版本 — jar 的字节码面向 17。- 可选:
PATH中需要有yosys,供cg_synth使用(通过$YOSYS覆盖);iverilog供cg_simulate(simulator='iverilog')使用。cg_check、cg_generate_verilog或字节码模拟器均不需要它们。
无需 MCP 客户端即可对验证核心进行冒烟测试:
python3 - <<'EOF'
from neosyn_fpga_mcp import cg_mcp_server as cg
print(cg.simulate("package d;\ntask T { properties { test: { v:[1,2,3] } }\n"
" out push u8 v; u8 c; void setup(){c=0;}\n"
" void loop(){c=c+1; v.write(c);} }"))
EOF
将其连接到 MCP 主机
添加一条服务配置。请使用绝对路径。
{
"mcpServers": {
"cg": {
"command": "neosyn-fpga-mcp",
"args": [],
"env": {
"CG_JAR": "/abs/path/to/cg-language-server.jar"
}
}
}
}
同样的 command/args/env 格式适用于 Claude Desktop、Claude Code、Cursor、Cline 和其他 stdio-MCP 主机。
然后将 cg_context.md 加载为系统提示词(或将其粘贴到对话开头)。这样,模型既了解这门语言,也能验证代码。
服务提供的工具
共有 13 个工具。每个接收源码的工具都接受 source(C⏚ 字符串)和可选的 extra_files 映射({"Defs.cg": "..."}),用于导入代码包/任务。
这些就是全部的工具名称。服务会明确告知,而不是指望你读完下表:调用不存在的工具时,响应会列出所有工具,并给出最接近的真实名称(cg_compile →“你是不是想调用 cg_check?”);cg_capabilities 会提供该列表;会话中的首次调用也会提供一次该列表。列表由工具注册表生成,因此不会与下表脱节。
| 工具 | 参数(除 source / extra_files 外) | 返回值 | 适用场景 |
|---|---|---|---|
cg_check | — | {ok, diagnostics:[…], warnings:[…], summary} | 在 cg_lint 之后,对任何草稿运行此工具;在模拟前修复所有诊断信息。warnings 包含验证器发现的问题,编译器虽接受但会提出异议(bool == 1、给 const 赋值):ok 仍为 true,因为程序确实可以编译,summary 也会说明这一点,因为实际会据此采取行动的是 ok 字段。需要编译器版本 ≥ 2.10.0——较旧版本不会在此报告任何内容。 |
cg_simulate | timeout=60、simulator='bytecode' | {ok, simulator, timed_out, diagnostics, output} | 最可靠的正确性检查。output 包含端口值和 print() 行;properties { test: {...} } 块可执行自检。反复迭代,直到 ok 为 true。 |
cg_generate_verilog | target='verilog'、output_dir=None、top=None | {ok, file_count, files:{path:content}}(持久化时另含 {output_dir, written}) | 模拟通过后,用于交付 RTL。target 可以是 'verilog' 或 'vhdl'。传入 output_dir(相对于 $PROJECT_ROOT)可将文件写入磁盘并保留。传入 top(实体名称)可只生成该实体及其实例化的内容;需要高于 3.4.0 的编译器,较旧版本会拒绝运行,而不会生成全部内容。 |
cg_synth | top=None、timeout=180、flow='generic' | {ok, verdict, top, flow, cells, arith_ops, latches, warnings, stat, problems, output} | 最有力的正确性信号——使用 yosys 对 Verilog 进行综合。verdict ∈ REAL / FOLDED(常量折叠——输入未出现在端口上)/ SUSPECT(推断出锁存器)/ ERROR,因此不能捏造成功结果。warnings 会说明数据通路退化或推断出锁存器的情况。 |
cg_capabilities | — | {ok, jar, jar_present, bytecode_simulator:{available,reason,detail}, simulators:[…], tools:{…}, advice} | 此主机实际具备的能力,经过探测,而非假定。快速字节码模拟器随商业发行版提供,在开源编译器中不存在,因此对它做任何笼统断言,在两种环境中必有一种是错的——决定如何验证之前,请先调用此工具。 |
cg_scaffold | kind='task'、name、package、inputs、outputs、verify=True | {ok, kind, source, holes:[{line,text}], verified:{check,simulate}, message} | 从空白文件编写新的 C⏚ 时,请从这里开始。 返回完整、可编译、可自检的骨架,其中数据通路留有 >>> FILL IN 待填空位;交付前已验证通过,因此之后出现的任何失败都是由你的修改导致的。kind ∈ task(sync 任务,其 test: 块会逐周期检查每个输出值——这是默认选项,也是最严格的选项)/ fsm / stream / network / generic。inputs/outputs 是 "name:type" 字符串,对 task 和 stream 生效。与 cg_example 互为补充:编写新内容时用 scaffold,已有经过验证的内核实现时用 example。 |
cg_example | pattern=''、k=1 | 不传 pattern 时 → {ok, index:[{name,kind,use_when,tags}]};传入 pattern 时 → {ok, name, kind, source, …, runners_up:[…]} | 在经过验证的代码字典中进行按需评分查找(不是搜索)。按具体程度加权,因此 1/sqrt→RSqrt,而 sqrt→FixedSqrt;返回 1-2 个候选项,供自我纠正。k>1 时会返回更多来源,以便组合使用。 |
cg_lint | — | {ok, findings:[{rule,line,severity,message,fix}]} | 对编译器接受但仍有错误的代码进行静态检查。主要检查 test: 测试用例只驱动输入却不比较任何输出的情况——即使设计毫无作用,也会通过检查。无需 jar 或模拟器,因此请在每份草稿上先运行此工具,再运行 cg_check;在声称设计已验证之前,也要再次运行。 |
cg_suggest_for_error | message | {ok, recipe, hint, source} | 将编译器拒绝信息映射到包含修复模式的配方(除数/移位量为变量 → Recip;数据相关的循环上限 → SeqDiv)。当诊断信息匹配时,cg_check/cg_simulate/cg_generate_verilog 会自动将其附加为 suggestion。 |
cg_report | report_dir='fpga/build'、schematics=True | {ok, report, kernels, sim_ok, message} | 生成最终 FPGA 报告:渲染 <report_dir>/report.html(包含 REAL/FOLDED/SUSPECT 判定和单元计数的综合表、模拟 PASS/FAIL、生成的 Verilog 文件列表,以及尽力生成的数据通路 SVG 图)。不会执行综合——只有在 cg_synth 和 cg_simulate 中传入相同的 report_dir,相关行才会作为副产物逐渐累积。 |
cg_fsm | task=None | {ok, diagnostics, fsm} | 确认任务编译后的状态机具有预期的状态和转换。 |
cg_graph | network=None | {ok, diagnostics, graph} | 确认网络编译后的接线情况(实例、带位宽/接口的端口、连接)。 |
cg_docs | topic='' | 不传 topic 时 → {ok, topics:[{topic,description}]};传入 topic 时 → {ok, topic, description, content} | 按需获取 Markdown 知识文档。context = C⏚ 核心语言包;riscv = RV32I CPU 参考实现(可加载的单周期核心,以及适用于 CPU 类硬件的可复用模式:桶形移位器、有符号/无符号扩展、子字加载/存储、启动流程序加载、测试平台捕获)。构建处理器/解码器/数据通路/堆栈机时,请阅读 riscv。 |
选择后端
有两个工具接受后端选择器:
-
cg_simulate(source, simulator=…)— 选择运行设计的仿真器:'bytecode'(默认) — 编译器的快速字节码仿真器。无需 HDL 工具链;properties { test: {...} }代码块会执行自检。cg_simulate(src)或cg_simulate(src, simulator="bytecode")。'iverilog'— 生成 Verilog 和测试平台,并运行 Icarus Verilog (vvp),进行 Verilog 级交叉检查。仅当网络名称包含大写 T 的Test时才会生成测试平台(例如network TestFoo);小写的_test网络只会驱动字节码仿真器的test属性,不会驱动 iverilog。 需要在PATH中找到iverilog。cg_simulate(src, simulator="iverilog")。'verilator'— 为向前兼容而接受;除非安装了verilator二进制文件, 否则会报告为不可用。cg_simulate(src, simulator="verilator")。
-
cg_synth(source, flow=…)— 选择运行的 yosys 综合流程:'generic'(默认) — 可移植的可综合性检查(synth)。cg_synth(src)或cg_synth(src, flow="generic")。- 厂商 FPGA 系列 —
'ice40'、'ecp5'、'xilinx'、'gowin'、'intel'— 映射到对应芯片的原语(LUT/BRAM/DSP)。cg_synth(src, flow="ice40")。
top默认为第一个非测试平台任务/网络(可综合的 DUT);当文件中包含多个设计时, 请传入该参数。使用$YOSYS指定其他 yosys 二进制文件。
模型应如何使用
- 起草 C⏚(始终以
package开头)。 cg_lint→ 免费且即时;可捕获编译器会欣然接受的错误,尤其是没有检查任何内容的test:代码块。cg_check→ 修复所有诊断,并阅读warnings:这些是编译器对其仍会接受的代码提出的异议。cg_simulate→ 确认ok: true,且输出符合预期。- 仿真通过后运行
cg_generate_verilog,以交付 RTL。 cg_synth(可选)→ 确认 Verilog 能映射到实际硬件 (ok: true、合理的cells数量,且没有problems)。
第 2 步之所以存在,是因为设计即使什么都不做,第 3–4 步也可能都通过:没有输出向量的
测试夹具,即使 DUT 毫无作用,也会显示通过。只有 cg_lint 能捕获这一问题,而且运行它无需任何成本。
第 2–3 步的循环才是重点:模型编写,编译器评判,模型修复。cg_context.md 末尾也有相同的
流程,确保模型即使没有单独的指令也会遵循。
完整流程
from neosyn_fpga_mcp import cg_mcp_server as cg
src = '''package com.example.demo;
task Counter {
properties { test: { value: [1, 2, 3] } }
out push u8 value;
u8 count;
void setup() { count = 0; }
void loop() { count = count + 1; value.write(count); }
}'''
cg.check(src) # {'ok': True, 'diagnostics': [], ...}
cg.simulate(src) # {'ok': True, 'simulator': 'bytecode', ...}
cg.generate(src, output_dir="build/v") # {'ok': True, 'file_count': N, 'written': [...]}
cg.synth(src, flow="ice40") # {'ok': True, 'top': 'Counter', 'cells': ..., 'problems': []}
通过 MCP 工具执行相同的调用:cg_check → cg_simulate →
cg_generate_verilog → cg_synth。先起草,再依次检查列表中的步骤,并在每个关卡修复
诊断;cg_synth 是最后一道硬件关卡。
种子与适配:从经过验证的基础开始
知识加验证能让模型取得出乎意料的进展,但也有上限:
对于真正困难的定点数据通路(例如包含 1/r²·√r² 项的 n 体力核),让模型 从头开始 编写时,它会手足无措——无论是用 C⏚ 还是用 Verilog。可靠的做法是 种子与适配:给模型一个小型、经过验证的基础,让它只修改数据流,同时保留它无法自行构建的部分(Q16.16 乘累加、任务/网络/监控器结构)。
调用 cg_example(pattern) 获取一个。这里提供的是经过整理的已验证代码字典,支持按评分惰性访问(而不是自由形式搜索):不指定模式时返回索引;输入名称或意图("1/sqrt"、"distance"、"divide a by b" 等)时,返回最匹配的源码和 1–2 个备选项,让模型可以自行纠正。匹配会按具体程度加权,因此 "1/sqrt"→RSqrt,而单独的 "sqrt"→FixedSqrt。编译器拒绝某项内容时,cg_suggest_for_error(msg) 会指向包含可综合模式的配方。
examples/ 中存放经过验证的条目——每个条目都能通过仿真、生成 Verilog,并通过 yosys synth。kind 将可复用的基本组件(Recip、Divide、SeqDiv、FixedSqrt、RSqrt、SqrDist、DotProduct、Fir、Integ、Distance、Counter)与应用示例(Force、GalaxyForce——n 体组合)区分开来。完整表格(包含 use_when/标签/单元格数量)请见 examples/RECIPES.md。如果某个基本组件的演示使用常量输入(DotProduct、FixedSqrt、Distance),cg_synth 会报告 verdict: FOLDED——请通过 in push 端口驱动它(如 SqrDist 所示),以保留数据通路。
请查看仓库中的 cg_adapt_demo.py,了解种子与适配循环的端到端运行过程;EVAL.md 则介绍了如何在小型任务上测量 C⏚ 和 Verilog 的编写率,以及这项测量无法说明什么。
文档
- 安装设置和完整工具参考
- 安装 C⏚ — 扩展和命令行工具
- 许可
旧名称
该项目在 1.0.0 之前以 cg-agent-kit 名称发布;“cg”是我们对 C⏚ 的简称,对任何搜索 FPGA 工具的人来说都毫无意义。在 PyPI 上,该名称现在是一个用于安装此包的垫片;在包内,python -m cg_agent_kit.cg_mcp_server 和 cg-mcp-server 命令仍然都可用——因此,现有说明和主机配置继续有效。新安装应使用 neosyn-fpga-mcp。
许可证
MIT。版权所有 (c) 2026 Neosyn。
本软件按**“原样”提供,不附带任何形式的保证**,无论明示还是暗示,包括但不限于适销性、特定用途适用性和不侵权的保证。在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论该责任源于合同、侵权还是其他诉讼,也无论其是否因本软件或对本软件的使用或其他交易而产生或与之相关。完整文本随包附带,文件名为 LICENSE。
C⏚、Cg 和 Neosyn 是 Neosyn 的标志。C⏚ 编译器是依据其自身许可协议发布的独立作品——请参阅 neosyn.io/open。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。