diagram-design,直译过来就是“图表设计”。听起来像设计岗的活儿,但在我这种既画硬件原理图、又写嵌入式 C 代码、偶尔还要折腾前端可视化图表的人眼里,diagram 从来不是简单“画个图”,而是一整套把复杂系统装进一张图的思维方法。
这些年我先后用 Pango Design Suite 画过 FPGA 的顶层原理图,用 Cadence 的 Design Entry HDL 做过板级原理图输入,也在 Web 端用 Ant Design Vue 搭过数据监控面板。越做越发现一件事:不管是电路原理图、软件状态机图,还是前端图表,底层的设计逻辑惊人地一致。模块化、层次化、接口清晰、可追溯——这些原则在不同领域里换着名字出现,本质却是同一套。
这篇文章就想把这些零散经验串起来,聊一聊我理解的 diagram-design。既是分享,也是给自己做个阶段性的技术沉淀。无论你是硬件工程师、嵌入式开发者,还是前端设计者,只要工作里离不开“画图表达系统”这件事,我相信都能从中找到点能直接用的东西。
1. 从“画图”到“diagram-design”:核心思路拆解
1.1 一张图承载的是整个系统的信息流
我最早接触 diagram 这个词是在电路设计里。学校里画一个简单的放大电路,图里无非是几个电阻电容和三极管。但到了工程实际,一张原理图承载的信息量远超初学者想象:器件型号、封装信息、电源网络、信号流向、阻抗匹配、时序关系,全都要在图纸上表达清楚。设计图不再是“示意图”,而是系统的正式技术文档。
后来我写嵌入式代码,发现软件架构图、状态机转移图、模块调用关系图,本质上和硬件原理图承担同一种角色——把系统的静态结构和动态行为可视化。硬件里叫 netlist,软件里叫调用图,前端里叫组件树。叫法不同,但都是同一个东西:用图来表达组件之间的关系。
这就是 diagram-design 的第一层内涵:设计图是系统信息的结构化表达。它把散布在文档、代码、表格里的信息抽出来,统一放到一个大家都能看的“共同视图”里。评审的时候不看代码、不看网表,所有人盯着一张图讨论,效率比翻文档高一个数量级。
1.2 硬件与软件领域的设计图思维共性
做 diagram-design 久了,我总结出几个跨领域通用的设计原则:
层次化。复杂的系统必须拆成层次。硬件上有系统框图、单板框图、电路原理图、PCB 布局图;软件上有系统架构图、模块图、函数调用图。每一层只关注本层的细节,层与层之间通过标准接口衔接。
模块化。每个功能块应该能够独立理解。硬件里是一个功能电路,软件里是一个模块文件。图和图之间通过命名、编号、端口建立起对应关系。
可追溯性。这是最容易被新手忽略的一点。设计图不是画完就完了,它要能支撑设计审查、故障排查和版本迭代。原理图里的网络名、位号,代码里的注释、命名,都是图的一部分。
我见过太多人把设计图当成“一次性产物”,画完扔在角落里,后面谁都不看。真正会做设计的人,会把图当成活的文档,跟着项目持续迭代。这也是为什么我后来写代码时,会把状态机图画在代码注释里,把模块依赖图画在 README 里——不是为了给别人看,是为了让三个月后的自己还能看懂。
2. 硬件原理图设计:Design Entry HDL 与 Concept HDL 实战要点
2.1 Design Entry HDL 的工作流程与核心概念
如果你用过 Proteus、Multisim 这类教学软件,你会对 Cadence 的 Design Entry HDL 有心理落差。它是典型的工业级 EDA 工具,界面谈不上漂亮,但功能非常扎实。我最初用它画原理图的时候,被它的“库”和“视图”概念绕了很久。
Design Entry HDL 的工作流大致是这样的:
- 新建工程(Project),指定工程目录。
- 创建或指定元件库,通过
cds.lib文件管理库路径。 - 在库里新建 Cellview(通常是
schematic视图),开始画原理图。 - 编辑元器件属性,连接网络,添加上下页连接符。
- 运行 DRC(设计规则检查),消除电气和连接错误。
- 生成网表,交付给 PCB Layout 工具。
这里最核心的概念是“库”。在 Design Entry HDL 的世界里,元器件都存在库里,而库的路径统一由cds.lib文件来定义。每新建一个工程,你需要让工具找到正确的库文件,否则就什么都调不出来。
2.2 库文件配置:cds.lib 的坑与解决方法
我踩过的第一个大坑就是cds.lib配置。当时从同事那边拷了一个工程,打开后满屏红色报错,提示找不到这个库那个库。查了半天才发现,同事机器上的库路径是绝对路径,换到我的机器上全得改。
cds.lib里常见的定义有两种写法:
INCLUDE $PROJECT_DIR/libs/local_lib/cds.lib DEFINE basic $HOME/cadence_libs/basicDEFINE语句把库名映射到具体目录路径,INCLUDE用来把子目录里的cds.lib文件合并进来。这里有一个实用技巧:不要写死绝对路径,尽量用环境变量。项目里统一用一个环境变量指代库根目录,换机器、换工位都能直接用。
注释掉不用的库也是一个好习惯。有些库是历史遗留项目用的,加载进来除了拖慢启动速度、制造一堆无用的错误提示,没有任何好处。我后来养成一个习惯:每个项目只保留最小化的库集合,宁可后面需要再补,也不一次性全引进来。
2.3 “cannot find the design in the library 'work'” 错误排查
这个报错大概是 Design Entry HDL 用户最熟悉的一条了:
WARNING: Cannot find the design 'mem_1r1w_1c' in the library 'work'. (LB-...)我当时第一次遇到一脸懵,明明是同一个工程,怎么找不到?排查下来发现,问题出在视图名和实际保存的视图不一致上。Design Entry HDL 里每个 cell 可以有多个视图,比如schematic、symbol、verilog。如果网表生成器在找schematic视图,但你的 cell 里只有一个叫layout的视图,就会报这个错。
另一个常见原因是库没有正确编译或者缓存过期。Design Entry HDL 在加载库的时候会生成缓存文件,一旦某个源文件被外部修改过,缓存没刷新,就会找不到对应的 design。这时候可以尝试把库重新导入,或者清理工程目录下的临时文件。
实用经验总结:
- 检查 cell 的视图名是否与配置一致;
- 检查
cds.lib的库路径是否指向正确目录; - 检查库缓存,必要时重建;
- 如果以上都不行,把工程目录下
*.cds.*的临时文件删掉重开。
3. PCB 与 EMC:图表化设计在板级层面的落地
3.1 从原理图到 PCB:netlist 的桥梁作用
原理图画完,工作只完成了一半。在 diagram-design 的视角里,原理图到 PCB 布局图之间存在一座桥,那就是 netlist。netlist 把原理图里的元件符号、引脚、网络关系翻译成布局布线软件能理解的数据结构。
常有人问我,原理图画得规范与否,对后续 PCB 设计影响真的那么大吗?答案是影响非常大。如果原理图里网络命名混乱、缺少电源符号,生成的 netlist 在 PCB 工具里就很难管理。我在工程实践中逐渐形成了一套命名规范:
- 电源网络统一用
+3V3、+5V、VCC_IO这样的格式,大写开头; - 地网络统一叫
GND、AGND、PGND,区分模拟地和功率地; - 差分信号对用
_P和_N后缀区分极性; - 关键信号(时钟、复位、高速数据线)在原理图里就加网络标签,不使用跨页连接符时也要保证命名一致。
这样做的目的只有一个:到了 PCB 阶段,你能一眼从飞线图里看出哪些网络是关键的、哪些是普通的。
3.2 EMC 合规设计的七条实践经验
市面上关于 EMC 的书很多,其中《Printed Circuit Board Design Techniques for EMC Compliance》是经典之作。这本书从电磁兼容的基本理论讲到 PCB 设计具体技术,我翻了不下三遍。结合自己的项目经验,我总结了七条对收音机工程师最有用的实践经验:
第一,叠层结构先行。四层板比双层板改善 EMC 的效果是数量级的,因为有了完整的地平面。预算允许的条件下,优先选四层以上。
第二,地平面完整率是生命线。信号换层时,回流路径必须紧邻地平面。凡是看到不完整地平面下方有高速信号,就等于看到天线。
第三,电源去耦要靠近引脚。去耦电容不是摆上就行,而是要放在负载引脚旁边,回流路径越短越好。常见误区是电容摆得远远的只求栅格对齐,效果大打折扣。
第四,时钟信号优先处理。时钟线尽量走内层、走短直线,不要跨分割区,不要用锐角拐弯。过孔换层时要成对布放,保证回流路径连续。
第五,接口滤波要放在连接器处。I/O 线上如果需要串联电阻或磁珠,必须挨着连接器摆,让干扰在入口就被挡掉。
第六,分区布局。模拟电路、数字电路、功率电路要分区布局,电源地和模拟地在单一条件下连接,避免数字噪声耦合进模拟区。
第七,遵守布线间距规则。高速线之间的 3W 原则(线间距至少为线宽的 3 倍)、时钟线与其他信号线的间距,这些不是教条,而是经过验证的经验值。不要因为布线拥挤就妥协,EMC 测试不过的代价远大于布线时多绕一点线。
这些细节在原理图和板图上都表现为“图形语言”。一个资深 Layout 工程师一眼扫过去,就知道这板子能不能过 EMC。这也是 diagram-design 在物理层面的体现——图本身的质量直接决定了产品能否量产。
4. FPGA 设计中的图表化流程:Pango Design Suite 实战
4.1 Pango Design Suite 环境搭建
近几年国产 FPGA 工具链越来越成熟了,高云的 Pango Design Suite 就是一个典型代表。之前拿到一块高云 FPGA 开发板,需要快速搭一个验证环境,我花了一个下午把工具链整个过了一遍,流程跟国外主流工具已经很接近了。
Pango Design Suite 支持两种设计输入方式:HDL 代码(Verilog/VHDL)和原理图输入。虽然大部分工程习惯了写 Verilog,但某些接口定义、顶层例化的场景,用原理图反而更直观。某些同事尤其喜欢用原理图做模块间互联的顶层,一来能直接看到信号方向,二来不容易犯书写笔误。
安装时有几个注意点:
- 安装路径不要有中文或空格,否则综合时容易出莫名其妙的问题;
- 许可证(License)环境变量要配置好,很多启动报错其实是环境变量没配;
- 尽量安装完整版本,旧的绿色版工具在器件支持上明显跟不上。
4.2 原理图输入与 IP 核链接设计
用 Pango Design Suite 做原理图输入,核心操作和 Cadence 类似:从库中拖出 IP 核或门级符号,连线,设置属性。
这里说说热词里提到的 “design linking IP”。在 FPGA 设计里,IP 核通常以图形化模块的形式提供,你可以在原理图编辑器里直接例化它,然后在配置窗口里设置参数,比如 PLL 的输入频率、输出频率,RAM 的位宽和深度。原理图上会生成一个带端口符号的 IP 模块,连线调用即可。
我个人的习惯是:顶层用原理图,底层用 HDL。也就是说,系统级互联(各模块之间、IP 核之间)用图形化方式表达,容易审查;单个功能模块内部用代码实现,便于复用和参数化。这样兼顾了可读性和灵活性。
在 Pango 里做原理图输入,有个容易踩坑的地方是信号命名冲突。原理图工具会自动生成网络名,如果你手工修改时不小心把两个网络改成同名但本应隔离的信号,DRC 通常能查出来,但也要自己留意。DRC 过了也不代表逻辑一定对,这只是电气一致性检查。
4.3 仿真验证:把图变成可运行的验证模型
设计图画完,不能一烧了之。FPGA 流程里一定要做功能仿真。Pango Design Suite 自带仿真流程,也可以导出网表到 ModelSim 之类的第三方工具。
仿真和原理图阶段的关系容易被低估。我在验证mem_1r1w_1c这类单口 RAM 的时候,就遇到过仿真模型和实际硬件不一致的情况。后来学乖了:凡是涉及 IP 核的设计,仿真模型一定要打开初始化文件,检查默认值。很多 IP 在代码生成时会有默认参数,如果你没有显式初始化,仿真结果可能和实际运行差之毫厘谬之千里。
仿真测试平台,建议按信号类型分组:时钟和复位放在一起,数据和控制信号放在一起,分别打波形、看时序。我习惯在测试代码里加$display打印关键状态,这样跑完就一目了然。
5. 嵌入式 C 语言中的“设计图”:设计模式落地
5.1 从架构图到状态机:让代码保持可读
硬件和 FPGA 聊完了,回到软件。嵌入式开发者常常忽视设计模式,总觉得那是桌面软件的事。其实嵌入式的状态复杂度和资源约束,恰恰更需要模式化的设计。Bruce 的《Design Patterns for Embedded Systems in C》这本书我看过,里面讲的不是花哨的面向对象技巧,而是怎么在 C 语言里用结构体、函数指针、状态表,把状态机写清楚。
我自己的一个习惯是:在写代码之前,先画状态转移图。不是用专门的 UML 工具,就是白板或者纸上画个圆圈和箭头。把每个状态、每个触发条件列清楚,才开始写代码。
状态机的 C 语言实现,最直观的就是查表法:
typedef struct { uint8_t state; uint8_t event; void (*action)(void); uint8_t next_state; } transition_t; static const transition_t state_table[] = { {STATE_IDLE, EVENT_START, action_start, STATE_RUNNING}, {STATE_RUNNING, EVENT_STOP, action_stop, STATE_IDLE}, // ... }; uint8_t state_machine(uint8_t current_state, uint8_t event) { for (int i = 0; i < sizeof(state_table)/sizeof(state_table[0]); i++) { if (state_table[i].state == current_state && state_table[i].event == event) { state_table[i].action(); return state_table[i].next_state; } } return current_state; }这段代码的可读性远远好过于十几个嵌套的if-else。别人拿到代码,只需要查看状态表,就能理解整个流程图。
5.2 模块化与接口设计:像管原理图一样管代码
写代码和画原理图,最后都逃不开模块化的问题。硬件工程师会为每个功能块画方框、标接口,软件工程师也应该这样抽象模块。
我通常把每个功能模块做成一个.c加一个.h的组合,.h就是模块的“接口符号”,只暴露必要的函数原型和数据类型,内部实现细节全部static隐藏。这样模块之间依赖关系一目了然,每一个模块都可以单独拿来测试,就像硬件里可以单独测一个功能电路一样。
这里我强烈推荐用 Doxygen 风格注释把接口文档写在头文件里。前几年我参与的一个项目,硬件设计和软件设计是同步进行的,接口定义好之后,两边各画各的图、各写各的代码。到最后联调时,几乎没有接口层面的返工。这依靠的不是个人默契,而是把接口写清楚的工程纪律。
6. 图表设计工具选型:Ant Design Vue 与 Qt Design Studio
6.1 前端数据可视化:Ant Design Vue 中的图表实践
聊到 diagram-design,不能只说硬件的 diagram,还要说软件界面的 diagram——数据可视化图表。做物联网后台和中间件管理界面时,我常用 Vue 3 和 Ant Design Vue。它是蚂蚁 Ant Design 设计体系的 Vue 实现,表格、表单、日期选择器这些组件非常成熟。
但很多人不知道,Ant Design Vue 本身并不直接提供图表组件。它是偏“中后台交互”的组件库,真正的图表渲染要靠 ECharts 或者 G2Plot,Ant Design Vue 负责搭建图表的容器、交互、样式体系。我的常规做法是:
- 用 Ant Design Vue 的 Card、Table、Descriptions 搭建页面骨架;
- 图表部分独立封装成组件,内部用 ECharts 渲染;
- 定义统一的数据格式和主题色,保证不同图表风格一致。
比如做一个设备温度监控图表,我会先封装一个ChartCard组件,接收数据源和图表类型选项,内部再转发给 ECharts 初始化。这样做的好处是,后续增加新的图表类型,只需要在配置里增加一个 type,不用重新搭页面。
6.2 Qt Design Studio 与轻量级设计工具
如果你做的是桌面端应用或 HMI 界面,Qt Design Studio 也是绕不开的工具链。它允许设计师在接近真实的运行环境下设计界面,然后导出 QML 代码直接交付给开发。
有人说 Qt Design Studio 是收费软件,不好搞。其实 Qt 有开源授权路径,只是你自己得注意组件版本合规问题。个人学习和内部验证,我一般用社区版,配合 Qt Creator 也够用。曾经试着找“开源下载”的渠道,最后发现还是官方渠道最靠谱,第三方整合包容易缺组件、带广告插件。
Qt Design Studio 的核心价值在于“所见即所得”。它把设计图和代码之间的翻译成本降到了最低。设计师在工具里调整控件位置、颜色、间距,导出的 QML 就是开发手里的准最终版。这比传统的前后端“拼图”模式效率高太多了。
6.3 图表设计中的数据表达原则
不管用哪个框架,数据可视化的核心还是“把数据变成可读的图”。我有几条实操经验:
先明确读者再选图表。给管理层看,要结论,用仪表盘和摘要卡片;给工程师看,要细节,用趋势图和日志列表。同一套数据,设计的呈现方式应该完全不同。
颜色有语义,不要乱用。告警用红色、正常用绿色、运行中用蓝色。一套颜色体系定下来,不要一会儿用深红一会儿用粉红。
坐标轴和标签要清晰。图表标注单位、时间格式、坐标范围,这些细节决定可读性。很多图表做得花哨却看不懂,问题就出在坐标轴没标清楚。
交互和静态并存。大屏展示要简洁,后台系统要能下钻。用 Ant Design Vue 做筛选器和交互,用 ECharts 做图表渲染,能比较好地平衡“美观”和“信息密度”。
7. 常见问题与排查技巧实录
7.1 工具崩溃与工程设计恢复
工业级 EDA 工具偶尔会抽风。热词里有条信息很有意思:“Program has encountered a problem and must exit. The design will be saved as ...”,这几乎是所有用大型设计软件的人都碰到过的话。
遇到这种情况,我建议的做法是:
- 不要慌,先找自动备份文件。多数 EDA 工具每隔几分钟会生成
.bak文件,位置通常在工程目录或者临时目录; - 检查项目目录下的
local或backup文件夹; - 找到最近的
.bak文件,复制出来,改名覆盖原文件; - 重新打开工程,确认设计完整度;
- 关键设计环节(比如大规模改动前)手动另存为一个新版本文件,这是个好习惯。
有一次我做一个 FPGA 工程的顶层连线,画了快两个小时,软件突然闪退。找到自动备份文件后发现,最近的一个备份只落后大概两分钟的工作量,心里的石头才落地。所以我的经验是:自动保存间隔要设短,重要节点手动存版本。
7.2 库与版本兼容问题速查
设计工具之间最让人头疼的就是版本和库兼容问题。分享一个我整理的排查清单:
| 症状 | 可能原因 | 解决思路 |
|---|---|---|
| 启动报错找不到库文件 | 环境变量未配置或库路径错误 | 检查环境变量和 cds.lib 配置 |
| 原理图导出网表失败 | 部分元器件缺封装属性 | 在元件属性中补充 PCB Footprint |
| 仿真模型和实际行为不符 | IP 核参数配置错误 | 重新核对 IP 配置向导中的参数 |
| 界面错乱、控件缺失 | 工具版本与项目文件版本不匹配 | 升级或回退工具版本,保持统一 |
还有一个小技巧:很多设计工具的工程文件是文本格式的(或压缩包格式的),出问题时可以先看看文件头,确认是不是版本兼容问题。实在解决不了,搜报错信息比翻工具的官方文档效率高得多。
7.3 安装与环境搭建的坑
很巧的是,热词里同时出现了 “pango design suite 使用教程” 和 “advanced design system 安装”,说明不少人卡在了环境搭建环节。
无论是高云的 Pango Design Suite,还是射频领域常用的 Keysight ADS,安装失败大多数集中在几类问题:
许可证文件路径。License 文件没有放在正确目录、环境变量没有指向 license 文件,都会导致启动失败。这个问题的排查方法很简单:打开终端,手动执行启动命令,看报错信息里 license 相关字样。
依赖库缺失。Linux 版本的设计工具往往依赖特定版本的图形库、USB 库。如果缺依赖,通常会给出明确的提示,apt install或yum install补上即可。Windows 版本则要注意 Visual C++ 运行库是否安装齐全。
磁盘空间和权限。设计工具安装包动辄几个 GB,安装时磁盘空间不足或目录无写权限,也会出现各种匪夷所思的报错。安装前检查空间是最基本的操作,但很多人会忽略。
杀毒软件干预。国内环境尤其常见,杀毒软件把设计工具的破解补丁或调试工具误删,导致运行时提示找不到模块。把工作目录加入白名单,是省心省力的做法。
8. 写在最后:让 diagram 成为你的思考载体
从 Cadence 的原理图,到 Pango 的 FPGA 顶层图,再到前端 ECharts 的折线图,我在这些工具之间反复横跳。最后发现,真正拉开差距的不是工具熟练度,而是你能不能把一个复杂系统用清晰的图表达出来。
我现在的习惯是:接到一个设计任务,不管硬件还是软件,先画图。系统框图、状态转移图、接口关系图、数据流图,至少画一遍。画的过程其实就是思考的过程,很多逻辑漏洞在动手画图的时候自己就暴露出来了。
如果你也想从“会用工具”进阶到“会做设计”,我建议从今天开始,把你手头的设计都当成 diagram-design 来做。别急着打开工具写代码、画电路,先在纸上或者白板上把系统的“图”勾出来,把模块边界画清楚,再回到工具里落地。这样看起来多花了半小时,实际省下的返工时间可能是好几倍。
工具会过时,设计语言会演进,但“用图思考、按图实施、以图沟通”这套方法论,在可见的未来不会过时。