免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

diagram-design:硬件与嵌入式图形化设计工具的架构与实践

diagram-design:硬件与嵌入式图形化设计工具的架构与实践 diagram-design说白了就是一个画图工具但又不是简简单单画个框图。这名字是我给自己一个内部工具起的主要用在硬件设计和嵌入式开发流程里把脑子里那套模块划分、信号连接、时序约束变成一张张能看懂、能检查、能自动生成代码和网表的图表。做硬件、做FPGA、做嵌入式底层的人应该都有这种感觉一个复杂系统躺在代码里是一堆抽象逻辑但一旦有人问你“这个模块和那个模块到底怎么连的”光靠嘴说或者翻代码效率极低。这个工具要解决的就是这么一个问题图形化设计不只是为了画得好看而是让设计意图从一开头就以一种可追踪、可复用、可自动化的方式固化下来。无论你是画原理图、做FPGA顶层连线还是给嵌入式软件画模块依赖图diagram-design都能把“画图”这件事从手工劳动变成工程设计的一部分。这篇文章我不会泛泛地讲“设计很重要”这种废话而是把我在实际搭建和使用这套流程时踩过的坑、验证过的方案、调整过的参数习惯全部摊开讲希望能给正在纠结到底该自己搭一套图形化设计工具、还是硬着头皮继续用命令行和手写网表的同行一点参考。1. 内容整体设计与思路拆解1.1 为什么单独做一个“diagram-design”而不是直接用现成工具先说一个很多人会问的问题画图工具那么多Visio、draw.io、甚至PowerPoint都能画框图为什么还要自己搞一个我的答案是现成工具解决的是“画得好看”的问题而设计场景里真正需要的是“画得有用”。所谓“画得有用”至少要满足三个条件。第一图中的每一个图元都对应到真实的模块、端口、信号或约束而不是一个矩形加一行文字的空壳。第二图与代码、网表、配置文件之间能互相转换甚至可以反向同步改图就改设计改设计也能回刷图。第三图本身要能参与自动化流程比如检查连接合法性、生成顶层例化代码、导出清单文档。这三个条件通用绘图工具一个都做不到。所以我从最开始就把diagram-design定位成一个“半代码半图形”的中间层图形是给人看的接口底层数据是结构化的、可以被脚本和编译器消费的。这样设计的好处是它既能作为设计入口Design Entry供人直观地搭建系统结构又能作为设计交付物输出到下游工具链避免“画一套图、写一套代码、各说各话”的经典混乱。1.2 设计思路图形、模型、代码三层分离这套工具的核心结构我拆成了三层这也是整个项目里最值得分享的架构决策。最上层是“图形层”也就是你眼睛看到的模块框、引脚符号、连接线、总线标注。这一层只管表达不管逻辑。第二层是“模型层”这是所有图的真相来源。每一个图元背后都有一个对象实例模块有名称、类型、实例名、参数列表端口有方向、位宽、协议类型连接线有信号名、驱动源、负载列表。第三层是“生成层”根据模型层的数据按不同模板输出VHDL、Verilog、SystemVerilog、布局文件、依赖清单等。一开始我也想过把图形和模型直接绑定在一起画一个框就建一个对象但后来发现这样耦合太紧一旦图需要调整布局或者把某些细节折叠模型就跟着乱。分层之后图形层只是模型层的一个“视图”你甚至可以同时打开两张不同的图来看同一个模块的不同细节模型不会冲突。这就像看同一份代码既可以看类图也可以看时序图但底层都是同一套源码。1.3 图表设计的边界别想一口吃成胖子做这类工具最容易犯的毛病是什么都想画什么都要自动化。我的建议是先把边界划清楚。在diagram-design里我明确不管三个东西不管PCB布线细节、不管代码语法级调试、不管多人实时协作文档编辑。这些都是成熟工具的地盘硬要自己搞就是重造轮子。边界划清楚之后整个项目就聚焦了它只负责把“系统结构”和“模块连接关系”这件事做到极致。就连热词里面提到的“printed circuit board design techniques for emc compliance”这类EMC设计规范我的处理方式也不是在diagram-design里画PCB而是通过导出带约束的连线信息供PCB工具在布局布线阶段参考。工具做窄了反而更好用也好维护。2. 核心细节解析与实操要点2.1 图元库设计引脚、端口、总线这些基础元素该怎么建模图元库是diagram-design的基石方案选型的时候这一步花了我很长时间。一个图元落到模型层至少要有几类属性外观属性、电气属性、语义属性。外观属性包括形状、颜色、引脚位置电气属性包括引脚方向input/output/inout、电平标准、位宽语义属性包括关联的HDL类型、参数默认值、可复用性标记。比如引脚我的模型里每个引脚有唯一的full_name格式类似“模块名.引脚名”这样在跨图引用时才不会重名混乱。位宽方面我不允许出现裸的“data”而是强制写成“data[7:0]”这种完整形式哪怕只有1位也要写成“bit0”。一开始觉得麻烦后来发现这一步省了无数后来查线的功夫。总线在图形上我画成粗线在模型层它其实是一个信号组。比如一个AXI总线在图上可以画成一组线但在模型里它会展开成AW、W、B、AR、R五组通道每个通道再展开成具体的信号和位宽。这个展开逻辑是自动的所以在图上看到的是“AXI总线段”在生成的代码里却是完整的总线信号定义。这种“图画简笔、代码写实”的思路是整个工具体验提升的关键。2.2 连接规则与合法性检查改图不能改出隐性错误画图这件事最怕的不是画得慢而是画完了谁也不知道图里的连接是不是逻辑正确的。所以diagram-design里内置了一套连接规则引擎每次保存图或者导出之前都会跑一遍检查。规则分成几档。第一档是致命错误例如输出引脚连输出引脚、位宽不匹配、信号名重复定义这类必须报错并阻止导出。第二档是警告例如悬空输入引脚、未连接的总线成员、缺少上拉配置的电平敏感信号这类允许导出但会打高亮标记。第三档是提示比如一个信号只有一个驱动源但名字以“n”开头暗示低有效这类只记录不打扰。这套规则的实现并不复杂本质就是遍历模型层的连接关系逐个对照端口定义和类型信息。但做得好的地方是报错信息非常具体不是笼统地说“net error”而是类似“信号wr_en[4]位索引4由u_uart_tx驱动却连接到u_dma_rx的输入引脚req[3]位宽和索引均不匹配”。修过复杂连接错误的人都知道越具体的报错越能救命。2.3 层次化设计大图拆小图、小图成组件单张图画个二三十个模块就到极限了再往上挤就是一团乱麻。diagram-design支持层次化设计顶层图引用的一个模块可以对应到底层的一张子图对上层来说它是一个黑盒对下层来说它是一张完整的连接图。实现层次化的关键是处理好“端口映射”。在模型层顶层图的模块实例有一组外部端口它们必须与子图的边界端口一一对应。我的做法是让子图自动生成一组“边界端口”图元用户只需要把内部信号连到边界端口上导出的时候工具会自动匹配名称和位宽如果对不上就报错。这种做法的好处是多人协作时可以各自维护自己的子图互不干扰。我曾经在项目里把一张接近两百个模块的顶层图拆成八张子图每个子图一个人维护最后在顶层只要关心子图之间的连接整个复杂度一下就降下来了。如果你在设计里还没接触过层次化我强烈建议尽早培养这个习惯哪怕小项目也按层次画后期扩展会省很多事。2.4 设计与仿真、综合工具链的衔接含Design Compiler、Pango Design Suite图终究要变成能跑的东西。diagram-design的出口之一是HDL代码生成生成的时候要考虑目标工具链的不同习惯。这里我结合几个常见的工具链说下差异。首先是Synopsys Design Compiler这类逻辑综合工具它对代码风格的要求比较严格顶层模块最好只有时钟、复位和IO端口内部逻辑尽量采用结构化描述。面对这类工具diagram-design生成的代码会倾向于输出结构化的模块例化风格即每个子模块都单独例化显式列出所有端口连接避免在顶层写复杂assign语句。其次是Pango Design Suite这类国产FPGA工具链它本身自带原理图设计入口但你也可以把外部生成的HDL文件直接作为工程源文件导入。用diagram-design生成的文件我一般会按照“模块名.v”或“模块名.vhd”的命名规则导出一个模块一个文件并且文件头部写清楚生成时间和对应的图文件名。这样即便工具链换成Quartus或者Vivado文件组织方式也不需要变化。最后是仿真环境。很多工程师在仿真的第一步就栽跟头典型的就是一开始提到的“cannot find the design mem_1r1w_1c in the library work”这类错误。这个问题我单独在后面的常见问题部分展开讲这里只提前说一句库的编译顺序和引用映射是仿真环境配置里最容易踩坑的地方diagram-design在生成仿真脚本时会把依赖顺序整理好减少这类异常。3. 实操过程与核心环节实现3.1 5分钟快速上手建立你的第一个Diagram工程如果你要试这套思路建议直接从“画一个最简单的小系统”开始不要贪大。我以最近一个典型场景为例一个MCU子系统包含CPU核心、UART、GPIO、Timer和内部RAMRAM用一个单端口1R1W的存储器。第一步新建工程设置顶层模块名比如叫做“mcu_subsystem”。第二步添加图元模块从库中拖出“CPU_Core”“UART_IP”“GPIO_IP”“Timer_IP”“mem_1r1w_1c”五个组件每个组件填好实例名和参数值。这里要特别注意实例名不能跟模块名一样比如模块叫“UART_IP”实例名就命名为“u_uart0”。第三步连线。把CPU的总线接口连到UART、GPIO、Timer的从接口上把RAM的读端口和写端口分别连到CPU对应的总线上再补上时钟和复位网络。第四步保存并运行合法性检查。如果全是绿标就可以直接点击“生成Verilog”工具会在输出目录里生成顶层文件和各个子模块文件。整个流程熟练之后大概五分钟。第一次上手的时候最需要留意的是端口方向画线的时候拖拽方向一定要从驱动端连到接收端如果方向反了检查器立刻会报“输出引脚连接到输出引脚请检查驱动关系”的提示。不要试图绕过检查直接导出真到了仿真阶段再回头查Line的连接关系成本高得多。3.2 一个例子从图形到Verilog的实现细节为了让上面的流程更具体我直接把生成代码的关键片段展示一下这里去掉复杂的逻辑只保留结构部分。顶层模块例化UART子模块的代码大概是这样的module mcu_subsystem ( input wire clk, input wire rst_n, input wire uart_rxd, output wire uart_txd, output wire [ 3:0] gpio_out, input wire [ 3:0] gpio_in, output wire timer_irq ); wire cpu_clk; wire cpu_rst_n; wire [31:0] cpu_ahb_addr; wire [31:0] cpu_ahb_wdata; wire [31:0] cpu_ahb_rdata; wire cpu_ahb_write; wire [ 1:0] cpu_ahb_size; wire [ 2:0] cpu_ahb_burst; wire cpu_ahb_ready; wire cpu_ahb_valid; UART_IP u_uart0 ( .clk (clk), .rst_n (rst_n), .ahb_addr (cpu_ahb_addr[15:0]), .ahb_wdata (cpu_ahb_wdata[31:0]), .ahb_rdata (cpu_ahb_rdata[31:0]), .ahb_write (cpu_ahb_write), .ahb_size (cpu_ahb_size), .ahb_ready (cpu_ahb_ready), .ahb_valid (cpu_ahb_valid), .uart_rxd (uart_rxd), .uart_txd (uart_txd) ); // 其他模块类似... endmodule注意例化里地址信号做了位截取这是diagram-design根据连接时指定的“连接子集”自动生成的。比如你在画图时把CPU总线的低16位连到UART的地址端口工具就会自动生成[15:0]这样的截取逻辑不需要手工改代码。这个功能是我最常用的因为手写这种接口适配代码不仅慢而且极易写错位宽。3.3 从图中导出网表与设计文档除了HDL代码diagram-design还能根据模型层导出EDIF网表和Markdown格式的设计文档。EDIF网表主要用于对接一些成熟的综合流程或者第三方工具虽然现在的综合工具都倾向于直接吃HDL但有些公司内部流程仍然需要网表。这个功能我建议做成“按需导出”不需要每次都用但一旦遇到系统集成或者文档审核能省下大量手工整理的时间。设计文档的导出我反而用得更多。diagram-design会生成一份“模块连接关系清单”包括每个模块的实例名、模块名、参数、所有端口连接的对端信号、以及未连接端口提示。这份清单可以直接评审用。我最常用的是把它转成Excel给硬件团队核对FPGA引脚分配比对着原理图数引脚快得多。3.4 与HDL代码编辑器的协同工作流有了diagram-design并不意味着扔掉代码编辑器。实际项目里图和代码需要频繁互相参考。我的做法是把生成的HDL文件加入版本管理同时图形文件也加入版本管理。每次从diagram-design导出代码后提交信息里写清楚“图版本”例如“export from mcu_subsystem.dgm rev 42”。这样任何人看到某一行代码的git记录都能回头找到对应的图形版本。另外diagram-design还支持把手写的HDL文件“反向导入”成图。这个功能的实现原理是解析模块声明和例化语句自动生成模块框和连线。它肯定不如手工画图那么优雅但对于从老项目接手的情况反向导入可以在半小时内让一个人对几十个模块的顶层结构有直观认识。这也是我强烈推荐你尝试的功能尤其是面对别人留下来的无文档代码时这比一行行看代码高效太多了。4. 常见问题与排查技巧实录4.1 仿真库报错cannot find the design “mem_1r1w_1c” in the library “work”这个报错太典型了几乎所有用ModelSim、Questa、Vivado XSim的工程师都会撞上。报错的意思是仿真器在当前库默认是work库里找不到名为mem_1r1w_1c的设计单元。原因通常有三个其中八成是因为你还没有编译这个模块就急着跑了仿真。解决办法是明确编译顺序。比如mem_1r1w_1c是一个存储器模型如果它被顶层mcu_subsystem例化仿真器在编译顶层之前必须先把mem_1r1w_1c对应的源文件编译进仿真库。很多初学者只compile了testbench没有把设计目录里所有源文件按依赖顺序compile一遍自然就会报找不到设计。第二个常见原因是库名混了。比如你编译的时候指定了“-work mem_lib”但仿真的时候只把mem_lib加入了库映射而顶层模块仍然指向work库这就会造成“我在mem_lib里明明编译了你还是说找不到”的假象。我的建议很简单不论是编译还是仿真都使用同一套库映射脚本。diagram-design生成仿真脚本的时候会自动把每个模块编译到work库并保证先编译底层再编译顶层就是为了一次性避开这些坑。第三个不太常见但很坑的原因是模块名写错。mem_1r1w_1c这个名称我在热词里看到过实际项目中也很常见——这种“前缀越长越容易拼错”的命名风格实验室里特别多。检查方法很简单打开编译后的library面板看里面列的unit名字和报错名字是不是完全一致注意大小写和下划线。Verilog对大小写敏感VHDL则不敏感跨语言协作时尤其容易出这种问题。4.2 连接检查总报错位宽与方向到底该怎么处理在diagram-design里我设计了一个规则端口位宽一律以“MSB:LSB”的完整定义形式为准端口连接时不允许直接连一个没有位索引的信号。例如一个8位输出端口如果你想接其中一位必须在信号名前加“bit_sel”标记或者使用“[3]”这种索引方式。一开始团队成员觉得麻烦但跑了几次仿真后大家就认可了这个约束因为位宽不匹配造成的仿真错误实在太多了。方向问题也一样。我的工具里每个端口必须声明in、out、inout不能缺省。如果发现一个信号同时连接了两个输出端口检查器会报“multiple driver”错误。这在FPGA设计里尤其需要重视因为多驱动意味着三态逻辑或者总线冲突严重点会造成上板后器件发热甚至损坏。任何检查器报出的多驱动问题都要当成最高优先级去处理不要抱着“先跑跑看”的想法。4.3 层次化设计导出后找不到子模块在层次化设计中还有一个非常常见的问题顶层图导出的代码里例化了子模块但综合或仿真时报“Module not found”。这个问题的根源通常不是代码逻辑错而是文件组织问题。diagram-design默认会导出所有子模块文件到同一个目录然后推荐你在工程里统一添加所有.v文件。如果你的综合工具只添加了顶层文件没有把子模块源文件一起加入工程就会报找不到。解决思路是两条。第一养成“导出后立即检查文件列表”的习惯确认所有子模块文件都在输出目录里。第二在使用命令行的流程里写一个自动收集文件列表的脚本把目录下所有v文件按名称加入编译列表。很多开源工具链都支持通配符比如vlog *.v但也有些工具不支持需要你手动展开文件列表。千万别嫌麻烦这一步出错率极高。4.4 编译环境与库版本导致的奇怪错误仿真和综合工具对语言标准的支持有细微差别有时同一套代码在不同版本工具里结果不一样。遇到过最典型的场景是某段代码在ModelSim里跑得好好的换到Vivado XSim就报语法错误。原因通常是代码里用了SystemVerilog的写法但文件名却是.vVivado把它当Verilog-2001来编译自然不认。diagram-design在生成代码时默认采用Verilog-2001标准所有接口也只使用该标准支持的语法。如果你确实需要SystemVerilog特性比如interface、struct可以在工具的工程配置里切换生成模板。但如果对目标工具链没有十足的把握我建议保守一点代码生成用旧标准复杂数据结构在模块内部自己处理不要依赖跨工具都未必兼容的interface特性。4.5 “保存出错”与意外退出不能让一张图成为唯一副本工具使用久了就会遇到程序意外退出。diagram-design的自动备份策略是每5分钟把当前图上所有对象的JSON快照存一份到backup目录同时保留最近10个备份。我有一次画到一半直接断电重启后从备份里恢复了15分钟前的内容丢失不算多。这里也提醒一句任何设计工具都不是你数据的保险箱图文件一定要纳入git或公司内部的版本管理并保持日常提交否则一个损坏的配置文件就可能让你几天的工作白费。在git管理模型文件时我还有一个小技巧把导出的HDL文件不加入.gitignore而是跟图文件一起提交但提交信息里明确标注“generated, do not hand-edit”。这样做的好处是diff的时候能清晰看到图形变化对代码的影响。代价是偶尔会出现手工改过代码、图与代码不相同步的情况所以每次重新从diagram-design导出后一定要用diff工具确认没有覆盖手改内容。4.6 高程设计的EMC约束和PCB衔接热词里有一条“printed circuit board design techniques for emc compliance”虽然这看起来和diagram-design关系很远但在实际项目里图形化设计的连接信息对后续PCB设计有直接影响。diagram-design允许在信号级别打上约束标签例如“clock_50m”、“high_speed_diff”、“analog_sensitive”导出文档时这些标签会作为特殊属性被PCB工具读入。这些标签可以帮助布局工程师快速识别高速信号和敏感模拟信号在布线阶段做阻抗控制和屏蔽处理。虽然它绝对不能替代专业的EMC仿真软件但能在设计早期就避免不少EMC隐患。从整个研发流程看diagram-design做的是“把约束前置”这件事——在设计入口就标记好的关键信号不会等到PCB布局时再去原理图里一个脚一个脚地找。5. 从Diagram Design到代码生成模板的进阶玩法5.1 为什么需要定制代码模板diagram-design的代码生成模板决定了同一张图在不同项目中产出的代码风格。刚搭建这套工具时我用的是内置默认模板。后来到第二个项目发现团队要求所有模块文件头必须包含作者、时间、版本和修改记录默认模板没有这些。第三个项目又要输出指定风格的复位同步逻辑。如果每次都靠导出后手工改这工具就失去了意义。所以diagram-design把模板做成了可配置的文本模块。你可以理解为像Jinja2或者FreeMarker那种模板引擎虽然实现上没那么花哨但核心思路是一致的代码结构固定不变变化的部分用变量占位由模型层数据填充。比如模块注释、端口定义、例化格式、always块风格这些全部都能通过模板控制。5.2 “design patterns for embedded systems in C”对模板设计的启发热词里有一条关于嵌入式系统C语言设计模式的书这让我想到一个很重要的点设计模式不应该只在代码层面关注它在图形化设计入口同样有价值。diagram-design的模板系统支持“设计模式”级别的组合。比如有一种模式叫“寄存器桥接”它会自动生成一组寄存器读写的接口代码另一种模式叫“中断汇聚”会把多个中断源合并成一个中断向量。你不需要每次画一条总线然后把所有信号都展开连一遍只需要把对应的组合模式拖到图上填好参数底层代码就自动生成了。有了这个能力图表不再是仅仅反映结构还直接影响最终代码行为。这就好像写代码时你选择了某个架构模式图的表达和代码实现一起变了两者始终一致。5.3 从“画图”到“设计系统”的演化如果你只把diagram-design当画图工具那它也就只能帮你画个漂亮图。但真正用起来之后它会慢慢演化成一个“设计系统”。你可以把常用的模块预置在库中把团队的连接规范固化在检查规则里把代码风格固化在模板里。新成员加入团队后只需要按照图把模块拖出来、连上线、导出代码不需要再纠结代码风格和端口定义弯路会少走很多。这种“设计系统”的思维其实和前端界提到的Ant Design Vue、或者移动端的组件库概念很像。我在热词列表里看到“ant design vue”“wot design uni”的时候就想到现在前端已经非常成熟地用组件库和设计令牌来保持多项目一致性而硬件设计领域还大量依赖个人经验和代码复制。diagram-design算是我自己做的一次尝试把前端那套“设计系统”思路移植到硬件和嵌入式设计里虽然还不如前端生态那样成熟但已经能感受到它在一致性方面带来的巨大价值。6. 工具选型、扩展性与生态对接心得6.1 自己造轮子之前先想清楚这四个问题如果你看完上面这些也想自己搞一套类似的工具先别急着写代码问自己四个问题。第一你的核心痛点真的是画图吗如果只是缺文档那直接用Markdown加代码块就够了。第二你有人力维护吗这种工具一旦用起来就会不断有同事提需求“能不能加个UART模板”“能不能导出带颜色的PDF”每一个都要人去实现。第三你能保证长期跟进吗工具链升级、OS升级、HDL标准升级都会让工具出问题。第四你公司的流程允许你引入自研工具吗有些公司对EDA和设计工具有严格的审批限制自研工具不一定能进入生产流程。如果四个问题都答得上、能解决那自研路线绝对值得。如果有一条跟不上我更推荐用已有的开源工具或者脚本在现成的流程里做增量改进。工具本身不是重点重点是让设计流程更顺畅。6.2 图形数据格式的选择与版本兼容diagram-design内部图形数据用的是JSON格式存储。之所以选JSON是因为它简单、可读、容易写脚本处理Git里diff也比较直观。每次保存图时工具会写入一个schema版本号外加模型层所有对象的完整内容。Schema版本号非常重要因为工具一旦升级旧版本打开新文件时能自动提示需要迁移避免静默出错。在做版本迁移时我走过一次弯路一开始没有保留旧的schema导致升级后所有旧图直接打不开。现在我的做法是每次修改schema都写一个migration脚本让工具启动时自动检测并转换。总结成一句话就是用户看到的是一张图工具底层是一个需要长期维护的数据模型别把两者混为一谈。6.3 对接版本管理工具和CI流程diagram-design在生成代码的同时会自动生成一份“源文件清单”文件罗列了所有输出文件的路径和依赖关系。这份清单可以直接供CI流程使用。比如每天晚上定时跑一次“从最新图文件导出HDL、编译、跑冒烟测试”如果图形有改动导致代码生成失败CI能在第二天一早告诉你而不是等你下午自己手动导出时才暴露。在对接git时还有一个非常实用的小功能diagram-design支持在导出代码时自动写入当前git commit hash作为注释。这样生成的HDL文件自带“指纹”如果现场出问题可以快速定位到对应版本的图模型和代码。这个功能在调试老旧项目时尤其管用能省下大量翻git历史的时间。6.4 开源化、模块化插件与团队共享虽然这套工具是给我自己手头项目做的但它的架构并没有绑死在某一个具体公司或者流程上。所有解析器、生成器、规则检查器都是独立的模块通过配置文件组合在一起。比如你可以把“Verilog生成器”替换成“VHDL生成器”也可以把“默认检查规则”换成团队的“安全编码规范规则”不需要改核心代码。如果你所在团队有脚本能力强的成员我建议在diagram-design基础上再做一层公司内部插件库把项目里常见的模块模板沉淀进去。这有点像“设计资产库”每个项目都从库里拖模块而不是从头画。坚持一段时间后团队内部的模块风格会越来越统一即使不同人负责不同模块最后组合在一起也不会出现接口对不上的情况。7. 一些实际的使用体会和扩展建议做了这一版diagram-design我的总体感受是图形化设计从来都不是个“画图”问题而是一个“工程表达”问题。同一张系统架构图在不同阶段应该有不同的表达粒度——评审时看模块骨架详细设计时看信号连接编码时看接口定义。以前这些粒度靠不同文档硬凑现在依靠一套模型层数据不同的视图只是同一数据的投影而已。实际项目里我还会用diagram-design做一些“画完之后能自动生成代码”的事比如生成顶层例化文件、生成testbench框架、生成寄存器地址映射头文件。这些都属于重复劳动但只要数据模型建得好自动化起来比预想中容易得多。其实这一点也解释了为什么我一直强调模型层的重要性图形只是皮肤数据才是血肉和骨骼。最后分享一个我在实践中的小技巧画图之前先花十分钟定义好端口命名规范。比如“模块名动词信号名”这种方式像“cpu_wr_data”“uart_rx_valid”。一旦定了规则后续检查规则和代码模板都可以依赖于这批命名省掉到处加注释和文档的时间。很多项目图的连接关系混乱根源不是画得不好而是命名从一开始就没有体系。diagram-design的规则引擎里我会配置一些命名模式检查不符合规范就直接标黄逼着大家在画图阶段就把这件事做对。如果你正准备给自己或者团队引入类似的图表设计流程建议从小范围试起挑一个中小规模的模块从画图、导出代码、跑仿真到写文档完整走通一遍再决定要不要全量铺开。工具永远是为了让设计更清晰、更高效服务的别为了用工具而用工具也别一上来就追求大而全的功能。先把纵向流程打通再慢慢增加横向扩展这条路走下来会比一开始就堆功能稳妥得多。
返回列表