内存子系统设计:L1/L2/L3缓存架构,系统缓存(SLC)的作用,以及DRAM控制器与总线(AXI/CHI)的设计要点

各位同学,今天我们来聊聊手机SoC里最烧脑、也最见功力的部分——内存子系统。

说实话,我入行那会儿,做第一颗SoC时,觉得CPU核够强就行。结果一跑分,数据从DDR搬进搬出,CPU干等着,性能直接腰斩。从那以后,我彻底明白了:没有好的内存子系统,再强的CPU也是白搭

这一章,我们就把缓存架构、系统缓存、DRAM控制器和总线协议这四块,掰开揉碎了讲清楚。

1. L1/L2/L3缓存架构:为什么需要三级缓存?

你想想看,CPU主频跑到3GHz,一个时钟周期才0.33纳秒。而DDR5的访问延迟,再怎么优化也要50-100纳秒。这中间的鸿沟,全靠缓存来填。

L1缓存:每个CPU核独享,分指令缓存和数据缓存。我习惯把L1设计成32KB+32KB,指令和数据分开。为什么?因为指令流和数据流有完全不同的访问模式,混在一起反而容易冲突。

L2缓存:也是每个核独享,但容量大一些,通常是256KB到512KB。L2的作用是过滤掉大部分L1 miss的请求。我在项目中遇到过,L2命中率如果低于80%,整个系统的性能就会明显下滑。

L3缓存:所有CPU核共享。容量从2MB到8MB不等。L3是最后一道防线,如果L3也miss,那就只能去访问DDR了。

核心要点:三级缓存的根本目的,就是让数据尽可能靠近CPU。每多一级缓存,延迟就翻几倍,但容量也大一个数量级。

这里有个设计上的取舍:L3缓存做大了,延迟会上升;做小了,命中率不够。我个人建议,对于手机SoC,L3容量控制在4MB左右比较平衡。太小了,游戏场景下频繁miss;太大了,芯片面积和功耗都扛不住。

2. 系统缓存(SLC):被很多人忽略的关键角色

系统缓存,英文叫System Level Cache,简称SLC。它和L3有什么不同?

L3是CPU专用的。而SLC是整个SoC共享的。GPU、NPU、ISP、视频编解码器,这些IP核都能访问SLC。

为什么要搞一个SLC?

  • 减少对DDR的访问:多个IP核共享数据时,SLC可以缓存中间结果。比如GPU渲染一帧画面,NPU做AI处理,ISP处理图像,这些数据在SLC里流转,根本不用去DDR。
  • 降低系统功耗:访问一次DDR的功耗,是访问SLC的5-10倍。SLC命中率每提高10%,系统功耗就能降不少。
  • 提高带宽利用率:DDR带宽是有限的。SLC把频繁访问的数据留在片内,DDR带宽就能留给那些真正需要大吞吐量的场景。

避坑指南:我曾经在一个项目中,SLC设计得太大(8MB),结果芯片面积超标,成本压不下来。后来我学乖了,SLC容量一般控制在2-4MB,配合智能的预取策略,效果反而更好。

SLC的替换策略也很关键。我习惯用伪LRU算法,硬件实现简单,性能接近真LRU。别小看这个选择,真LRU的硬件开销太大,在手机SoC这种面积敏感的场景下,不划算。

3. DRAM控制器:与DDR打交道的“翻译官”

DRAM控制器,说白了就是CPU和DDR内存之间的桥梁。它负责把CPU的请求,翻译成DDR芯片能理解的命令序列。

设计DRAM控制器时,有几个关键点:

  • 命令调度:DDR芯片有行激活、列读写、预充电等操作。控制器要合理安排这些命令,最大化带宽利用率。我常用的调度策略是FR-FCFS(先就绪先服务),优先处理那些行已经激活的请求。
  • 地址映射:物理地址如何映射到DDR的bank、row、column?这个映射关系直接影响性能。我建议把连续的地址映射到不同的bank,这样可以利用bank级并行,提高吞吐量。
  • 刷新管理:DDR需要定期刷新,否则数据会丢失。刷新期间,DDR无法响应读写请求。所以刷新时机要选好,最好在系统空闲时做。

注意:DRAM控制器的设计,一定要和DDR的时序参数(tRCD、tCL、tRP等)紧密配合。这些参数在DDR的JEDEC标准里有明确规定,不能随意改。我曾经见过一个团队,把tRCD设得太小,结果DDR芯片工作不稳定,数据出错。

另外,现在的手机SoC普遍支持LPDDR5LPDDR5X。这些新标准引入了WCK(写时钟)和DQ训练等新特性。设计控制器时,要确保支持这些特性,否则性能发挥不出来。

4. 总线协议:AXI与CHI

总线是连接CPU、缓存、DRAM控制器的“高速公路”。手机SoC里,最常用的总线协议是ARM的AXI和CHI。

AXI(Advanced eXtensible Interface)是AMBA协议家族的一员。它支持独立地址/数据通道、乱序传输、突发传输等特性。我刚开始做SoC时,用的就是AXI。它简单、成熟,但有个缺点:不支持一致性

什么叫一致性?就是多个CPU核或IP核,看到的数据是同一个版本。如果没有一致性,CPU核A修改了数据,CPU核B读到的还是旧数据,那就乱套了。

CHI(Coherent Hub Interface)是ARM新一代的总线协议。它专门解决一致性问题。CHI引入了Snoop Filter(监听过滤器)和Home Node(归属节点)的概念,可以高效地维护多核之间的数据一致性。

我建议,对于手机SoC,如果CPU核数超过4个,或者有多个高性能IP核(GPU、NPU)需要共享数据,一定要用CHI。AXI虽然简单,但在多核场景下,一致性维护的开销太大。

经验之谈:我在一个8核CPU的项目中,最初用了AXI总线。结果发现,CPU核之间频繁的缓存一致性操作,占用了大量总线带宽。后来换成CHI,性能提升了15%,功耗还降了10%。

CHI的另一个好处是支持QoS(服务质量)。你可以给不同的IP核设置不同的优先级。比如,GPU的请求优先级高,ISP的请求优先级低。这样,在带宽紧张时,系统能保证关键任务的性能。

5. 知识体系总览

下面这张图,是我自己总结的内存子系统架构图。你可以看到,L1/L2/L3缓存、SLC、DRAM控制器、总线协议,它们是如何协同工作的。

CPU核0 CPU核1 CPU核2 CPU核3 L1 I/D L1 I/D L1 I/D L1 I/D L2 L2 L2 L2 L3 共享缓存 SLC 系统缓存 GPU/NPU/ISP共享 CHI/AXI 总线 DRAM控制器 LPDDR5/DDR5 GPU NPU ISP 图例 CPU核 L1缓存 L2缓存 L3缓存 SLC 总线 DRAM控制器

从这张图可以清楚看到:CPU核通过L1、L2、L3逐级访问数据,SLC作为系统级缓存,服务于所有IP核。CHI/CHI总线负责维护一致性,DRAM控制器最终把请求发送到DDR。

6. 设计要点总结

好了,这一章的内容就到这里。我最后给你总结几个设计要点:

  1. 缓存层级要合理:L1要快,L2要够,L3要平衡。SLC不要贪大,2-4MB足够。
  2. 一致性是关键:多核场景下,一定要用CHI总线。AXI只适合简单场景。
  3. DRAM控制器要精细调优:命令调度、地址映射、刷新管理,每个环节都不能马虎。
  4. 带宽和延迟要权衡:缓存可以降低延迟,但会增加面积和功耗。DDR带宽高,但延迟大。设计时,要根据应用场景做取舍。

个人心得:我做了十几年SoC,最大的体会是——内存子系统没有银弹。每个项目都要根据目标应用、功耗预算、成本限制,反复迭代优化。别指望一套方案打天下。

嗯,这一章就讲到这里。下一章,我们会深入讨论缓存一致性的具体实现,包括MESI协议、Snoop Filter的设计,以及CHI总线的详细报文格式。到时候见。


公众号:蓝海资料掘金营,微信deep3321