第1章:架构设计里程碑
架构设计,说白了就是给芯片画一张「总蓝图」。
我做了十几年ASIC项目,见过太多团队一上来就写代码,结果写到一半发现接口对不上、性能跑不满、模块之间打架。嗯,这时候再回头改架构,代价就大了去了。
1.1 顶层架构设计
顶层架构设计,是芯片的「骨架」。
我个人习惯,拿到需求后先画一张系统框图。这张图里要明确三件事:
- 数据流走向:数据从哪来,经过哪些处理,最终到哪去
- 控制流逻辑:谁控制谁,握手信号怎么走
- 时钟域划分:哪些模块跑高频,哪些可以降频
我在项目中遇到过最典型的坑:团队把两个不同时钟域的模块直接连在一起,没做同步处理。结果仿真没问题,上FPGA验证时数据时不时丢一拍。查了三天,最后发现是跨时钟域的问题。
核心原则:顶层架构设计阶段,至少要回答清楚三个问题——
- 芯片的输入输出是什么?
- 数据路径上有没有瓶颈?
- 功耗预算够不够分?
你想想看,如果顶层架构没想清楚,后面模块划分、接口定义全是白搭。
1.2 模块划分
模块划分,讲究「高内聚、低耦合」。
我见过有些架构师喜欢把功能拆得很碎,一个模块就几十行代码。结果呢?模块间通信的握手逻辑比功能逻辑还复杂。这其实没必要。
我个人建议,模块划分遵循这几个原则:
- 功能独立性:每个模块只做一件事,做好一件事
- 接口简洁性:模块间接口信号尽量少,能走总线就别拉专线
- 复用性:想想这个模块以后其他项目能不能直接用
举个例子,我曾经做一个视频处理芯片,有人把缩放模块和色彩空间转换模块合并了。理由是「反正都是处理像素」。结果后来需求变了,要换一种缩放算法,不得不把整个模块重写。如果当初分开,只需要改缩放那部分就行。
小技巧:模块划分时,可以先用Excel列一张「功能-模块映射表」。每个功能对应哪个模块,一目了然。我每次做架构评审前都会准备这张表,评审效率高很多。
1.3 接口定义
接口定义,是架构设计里最容易出问题的地方。
为什么?因为接口是模块之间的「契约」。契约没写好,后面联调就是灾难。
接口定义要包含这些内容:
| 接口要素 | 说明 | 常见问题 |
|---|---|---|
| 信号方向 | 输入/输出/双向 | 方向定义反了,仿真报错 |
| 位宽 | 数据总线宽度 | 位宽不够,数据被截断 |
| 时序要求 | 时钟沿、建立保持时间 | 跨时钟域没处理 |
| 协议类型 | AXI/APB/AHB/自定义 | 协议握手不匹配 |
我曾经犯过一个低级错误:两个模块之间用AXI总线通信,但一个模块用AXI3,另一个用AXI4。两者在写响应机制上不一样,联调时数据一直写不进去。查了两天才发现是协议版本不匹配。
避坑指南:接口定义一定要写成文档,并且做评审。不要口头约定。我曾经见过一个项目,架构师口头说「这个信号你拉一下就行」,结果两个工程师理解的不一样,最后流片回来功能对不上。
1.4 性能预算
性能预算,是架构设计的「体检报告」。
说白了,就是算清楚你的芯片能不能跑到目标性能。我习惯在架构阶段做三件事:
- 带宽预算:数据通路的最大吞吐量够不够
- 延迟预算:关键路径的延迟能不能满足
- 功耗预算:各模块分到的功耗够不够用
举个例子,一个4K视频处理芯片,要求60fps。算一下:每帧数据量大约12MB(以YUV420为例),60帧就是720MB/s。如果DDR带宽只有600MB/s,那肯定跑不满。这时候要么降分辨率,要么换更高带宽的DDR。
我在项目中遇到过最头疼的事:性能预算做得很漂亮,但实际实现时发现某个模块的时序收敛不了。为什么?因为预算时没考虑布线延迟。所以我现在做性能预算,都会留20%的余量。
关键点:性能预算不是一次性的。架构设计阶段做一次,模块设计阶段再细化一次,综合后还要再验证一次。动态调整,才能保证最终芯片能达标。
知识体系总览
下面这张图,是我自己总结的架构设计核心逻辑。每次做新项目,我都会对着这张图过一遍,确保没有遗漏。
这张图把架构设计的四个核心环节串起来了。顶层架构定方向,模块划分定边界,接口定义定契约,性能预算定指标。四者缺一不可。
嗯,架构设计阶段花的时间越多,后面实现阶段踩的坑就越少。我个人经验,架构设计至少要占整个项目周期的15%-20%。别急着写代码,先把架构想清楚。