第1章:架构设计里程碑

架构设计,说白了就是给芯片画一张「总蓝图」。

我做了十几年ASIC项目,见过太多团队一上来就写代码,结果写到一半发现接口对不上、性能跑不满、模块之间打架。嗯,这时候再回头改架构,代价就大了去了。

1.1 顶层架构设计

顶层架构设计,是芯片的「骨架」。

我个人习惯,拿到需求后先画一张系统框图。这张图里要明确三件事:

  • 数据流走向:数据从哪来,经过哪些处理,最终到哪去
  • 控制流逻辑:谁控制谁,握手信号怎么走
  • 时钟域划分:哪些模块跑高频,哪些可以降频

我在项目中遇到过最典型的坑:团队把两个不同时钟域的模块直接连在一起,没做同步处理。结果仿真没问题,上FPGA验证时数据时不时丢一拍。查了三天,最后发现是跨时钟域的问题。

核心原则:顶层架构设计阶段,至少要回答清楚三个问题——

  1. 芯片的输入输出是什么?
  2. 数据路径上有没有瓶颈?
  3. 功耗预算够不够分?

你想想看,如果顶层架构没想清楚,后面模块划分、接口定义全是白搭。

1.2 模块划分

模块划分,讲究「高内聚、低耦合」。

我见过有些架构师喜欢把功能拆得很碎,一个模块就几十行代码。结果呢?模块间通信的握手逻辑比功能逻辑还复杂。这其实没必要。

我个人建议,模块划分遵循这几个原则:

  • 功能独立性:每个模块只做一件事,做好一件事
  • 接口简洁性:模块间接口信号尽量少,能走总线就别拉专线
  • 复用性:想想这个模块以后其他项目能不能直接用

举个例子,我曾经做一个视频处理芯片,有人把缩放模块和色彩空间转换模块合并了。理由是「反正都是处理像素」。结果后来需求变了,要换一种缩放算法,不得不把整个模块重写。如果当初分开,只需要改缩放那部分就行。

小技巧:模块划分时,可以先用Excel列一张「功能-模块映射表」。每个功能对应哪个模块,一目了然。我每次做架构评审前都会准备这张表,评审效率高很多。

1.3 接口定义

接口定义,是架构设计里最容易出问题的地方。

为什么?因为接口是模块之间的「契约」。契约没写好,后面联调就是灾难。

接口定义要包含这些内容:

接口要素 说明 常见问题
信号方向 输入/输出/双向 方向定义反了,仿真报错
位宽 数据总线宽度 位宽不够,数据被截断
时序要求 时钟沿、建立保持时间 跨时钟域没处理
协议类型 AXI/APB/AHB/自定义 协议握手不匹配

我曾经犯过一个低级错误:两个模块之间用AXI总线通信,但一个模块用AXI3,另一个用AXI4。两者在写响应机制上不一样,联调时数据一直写不进去。查了两天才发现是协议版本不匹配。

避坑指南:接口定义一定要写成文档,并且做评审。不要口头约定。我曾经见过一个项目,架构师口头说「这个信号你拉一下就行」,结果两个工程师理解的不一样,最后流片回来功能对不上。

1.4 性能预算

性能预算,是架构设计的「体检报告」。

说白了,就是算清楚你的芯片能不能跑到目标性能。我习惯在架构阶段做三件事:

  1. 带宽预算:数据通路的最大吞吐量够不够
  2. 延迟预算:关键路径的延迟能不能满足
  3. 功耗预算:各模块分到的功耗够不够用

举个例子,一个4K视频处理芯片,要求60fps。算一下:每帧数据量大约12MB(以YUV420为例),60帧就是720MB/s。如果DDR带宽只有600MB/s,那肯定跑不满。这时候要么降分辨率,要么换更高带宽的DDR。

我在项目中遇到过最头疼的事:性能预算做得很漂亮,但实际实现时发现某个模块的时序收敛不了。为什么?因为预算时没考虑布线延迟。所以我现在做性能预算,都会留20%的余量。

关键点:性能预算不是一次性的。架构设计阶段做一次,模块设计阶段再细化一次,综合后还要再验证一次。动态调整,才能保证最终芯片能达标。

知识体系总览

下面这张图,是我自己总结的架构设计核心逻辑。每次做新项目,我都会对着这张图过一遍,确保没有遗漏。

架构设计里程碑 顶层架构设计 模块划分 接口定义 性能预算 数据流走向 控制流逻辑 时钟域划分 功能独立性 接口简洁性 复用性 信号方向/位宽 时序要求 协议类型 带宽/延迟/功耗

这张图把架构设计的四个核心环节串起来了。顶层架构定方向,模块划分定边界,接口定义定契约,性能预算定指标。四者缺一不可。

嗯,架构设计阶段花的时间越多,后面实现阶段踩的坑就越少。我个人经验,架构设计至少要占整个项目周期的15%-20%。别急着写代码,先把架构想清楚。


专注资料整理