第四章 芯片架构设计:系统架构设计方法、硬件加速器与CPU/DSP分工、总线架构选择(AXI/NoC)、存储架构设计(Cache/SRAM/DDR)
各位同学,欢迎来到第四章。这一章我们聊聊芯片架构设计。说实话,这是整个芯片设计流程中最「虚」也最「实」的一步。虚在它看不见摸不着,实在它直接决定了芯片能不能跑、能跑多快、功耗多少、面积多大。
我做了十几年通信芯片,见过太多「架构没想清楚就开干」的项目。结果呢?要么性能不达标,要么功耗爆炸,要么面积超标。最后只能推倒重来。嗯,咱们今天就把这些坑一个个填上。
4.1 系统架构设计方法:从需求到架构的映射
系统架构设计,说白了就是回答三个问题:做什么?怎么做?谁来做?
我个人的习惯是,拿到需求后先画一张「数据流图」。别急着想用什么总线、什么加速器。先把数据从哪来、到哪去、中间要经过哪些处理,画清楚。
核心原则:架构设计要遵循「自顶向下、逐层细化」的方法。先定大框架,再填细节。
举个例子。一个5G基带芯片,数据流大概是这样的:
- 天线接收 → 射频前端 → ADC → 数字基带
- 数字基带 → FFT → 信道估计 → 解调 → 译码
- 译码输出 → MAC层处理 → 应用层
你看,数据流画出来之后,每个模块做什么、需要多少算力、数据量多大,就一目了然了。
我的经验:画数据流图时,一定要标注每个节点的「数据吞吐率」和「延迟要求」。这两个参数决定了后续的总线选型和存储架构。
接下来是「算力分解」。把每个处理步骤需要的运算量算出来,单位是GOPS(Giga Operations Per Second)。比如:
| 处理模块 | 运算量(GOPS) | 延迟要求(us) | 建议实现方式 |
|---|---|---|---|
| FFT | 5 | 10 | 硬件加速器 |
| 信道估计 | 8 | 20 | 硬件加速器 |
| 解调 | 3 | 15 | DSP |
| 译码 | 20 | 50 | 专用硬件加速器 |
| MAC层处理 | 1 | 100 | CPU |
这张表一出来,架构就清晰了。算力高的、延迟敏感的,用硬件加速器。算力低的、逻辑复杂的,用CPU或DSP。
4.2 硬件加速器与CPU/DSP分工:谁该做什么?
这个问题我经常被问到:「老师,到底什么功能该用硬件加速器,什么该用软件跑?」
我的回答很简单:看三点——算力、灵活性、功耗。
- 算力需求高(比如>10 GOPS)且算法固定的,用硬件加速器。比如FFT、Viterbi译码、Turbo译码。
- 算力需求中等(1-10 GOPS)且需要灵活性的,用DSP。比如信道估计、均衡器。
- 算力需求低(<1 GOPS)且逻辑复杂的,用CPU。比如协议栈、控制面处理。
我曾经踩过的坑:有一个项目,我们把信道估计算法用硬件加速器实现了。结果算法迭代了三次,每次都要改RTL,改得我们欲哭无泪。后来我学乖了,凡是算法还在演进中的,先用DSP跑,等稳定了再考虑硬件化。
硬件加速器和CPU/DSP之间的通信,也是个大学问。我建议用寄存器接口做控制,用DMA做数据搬运。控制通路要轻量,数据通路要高效。
// 硬件加速器控制接口示例(C语言伪代码)
// 配置加速器参数
write_reg(ACCEL_CTRL, 0x01); // 启动加速器
write_reg(ACCEL_SRC_ADDR, src_buf); // 源数据地址
write_reg(ACCEL_DST_ADDR, dst_buf); // 目的数据地址
write_reg(ACCEL_LENGTH, data_len); // 数据长度
// 等待加速器完成
while(!(read_reg(ACCEL_STATUS) & 0x01));
// 读取结果
result = read_reg(ACCEL_RESULT);
你看,控制逻辑就这么简单。但数据搬运呢?我建议用DMA,别让CPU去搬数据。CPU的时间很宝贵,别浪费在搬砖上。
4.3 总线架构选择:AXI vs NoC
总线架构,说白了就是芯片内部的「高速公路」。选对了,数据畅通无阻。选错了,堵车堵到死。
目前主流的选择有两个:AXI总线和NoC(Network on Chip)。
| 特性 | AXI总线 | NoC |
|---|---|---|
| 拓扑结构 | 共享总线/交叉开关 | 网格/环形/树形 |
| 并发性 | 低(共享总线时) | 高(多路径并行) |
| 延迟 | 低(短距离) | 中(需路由) |
| 可扩展性 | 差(超过10个master就吃力) | 好(可扩展到上百节点) |
| 功耗 | 低 | 中 |
| 适用场景 | 中小规模SoC | 大规模多核/多加速器系统 |
我个人习惯是:10个master以下用AXI,10个以上用NoC。为什么?因为AXI的交叉开关面积和功耗随节点数呈O(n²)增长。你想想看,20个master的AXI交叉开关,面积比NoC还大,功耗也高,何必呢?
我的建议:如果选AXI,一定要用AXI4,支持outstanding transaction和burst传输。如果选NoC,推荐mesh拓扑,路由简单,延迟可预测。
还有一个细节:一致性协议。如果多个CPU共享数据,需要ACE(AXI Coherency Extensions)或CHI协议。NoC的话,一般需要自己实现一致性协议,或者用ARM的CMN互联。
4.4 存储架构设计:Cache/SRAM/DDR
存储架构,是芯片性能的「隐形杀手」。很多芯片性能上不去,不是算力不够,而是数据喂不饱。
存储架构设计要解决的核心问题是:数据在哪?怎么搬?多快能拿到?
4.4.1 Cache设计
Cache是CPU的「贴身保镖」。我见过很多芯片,CPU性能很强,但Cache太小,导致CPU经常stall。说白了就是「大炮打蚊子,弹药跟不上」。
Cache设计的关键参数:
- 大小:一般16KB-64KB per core(L1),256KB-2MB(L2)。通信芯片的L1建议32KB起步。
- 关联度:4-way或8-way。关联度越高,命中率越高,但延迟也越大。
- 行大小:64字节是标准。但通信芯片处理的数据包通常很小,32字节可能更合适。
- 替换策略:LRU(最近最少使用)是主流。但有些场景用伪LRU更省面积。
重要提醒:通信芯片的数据流通常是「流式」的,即数据进来处理完就出去,没有太多局部性。这种情况下,Cache的命中率可能很低。我建议关闭数据Cache,改用SRAM做显式管理。
4.4.2 SRAM设计
SRAM是芯片的「工作台」。数据从DDR搬上来,在SRAM里处理,处理完再搬回去。
SRAM设计的关键:
- 大小:根据数据流图算。每个处理步骤需要多大的buffer,加起来就是总SRAM需求。一般通信芯片的SRAM在1MB-8MB之间。
- 分区:把SRAM分成多个bank,每个bank独立访问。这样可以并行读写,提高带宽。
- 双端口 vs 单端口:双端口SRAM可以同时读写,但面积大。我建议只在关键路径上用双端口,其他地方用单端口。
// SRAM分区示例(硬件描述)
// 4个bank,每个bank 256KB,共1MB
// Bank0: 接收缓冲区
// Bank1: 发送缓冲区
// Bank2: 处理中间结果
// Bank3: 配置参数
// 访问控制
if (addr >= 0x0000 && addr < 0x4000) // Bank0
bank_sel = 0;
else if (addr >= 0x4000 && addr < 0x8000) // Bank1
bank_sel = 1;
else if (addr >= 0x8000 && addr < 0xC000) // Bank2
bank_sel = 2;
else // Bank3
bank_sel = 3;
4.4.3 DDR设计
DDR是芯片的「大仓库」。数据量大、访问频率低的数据,放在DDR里。
DDR设计的关键:
- 带宽:DDR带宽 = 频率 × 位宽 × 2(DDR双沿传输)。比如DDR4-3200,64位宽,带宽是3200×64/8 = 25.6GB/s。
- 延迟:DDR的延迟通常在50-100ns。如果对延迟敏感,建议用SRAM做缓存。
- 通道数:多通道可以提升带宽。但要注意,多通道需要地址交错,硬件设计更复杂。
我曾经踩过的坑:有一个项目,我们用了DDR4,但带宽利用率只有30%。后来发现是访问模式太随机,导致DDR的page miss率很高。解决办法是:把数据按访问顺序重新排列,或者用DDR burst方式连续读写。
最后,给大家一个存储架构设计的「黄金法则」:
- 热数据(频繁访问)→ SRAM
- 温数据(偶尔访问)→ Cache
- 冷数据(很少访问)→ DDR
嗯,这一章的内容就到这里。下一章我们聊聊「时钟与复位设计」,那是芯片的「心跳」和「起跑线」,同样重要。
课后思考:如果你的芯片需要处理4K视频流,数据吞吐率是12Gbps,你会怎么设计存储架构?Cache、SRAM、DDR各用多大?欢迎在群里讨论。
公众号:蓝海资料掘金营,微信deep3321