存储子系统可分为内(主)存和外(辅)存两类。内存是直接受处理器控制与管理,并只能暂存信息的存储器;外存则是可以永久性保存信息的存储器,外存中的程序必须调入内存才能运行。
存储子系统设计的总原则是满足处理器存取需求和芯片应用需求,主要关注存储结构、存储器件、存储器映射与重映射。
SoC的存储结构是分层次的,离处理器越近的存储器,速度越快,容量越小,如图1.4所示。
图1.4 SoC的存储结构
各级存储延迟如图1.5所示。
图1.5 各级存储延迟
在通常情况下,处理器通过缓存和便笺存储器(ScratchPad Memory,SPM)访问内存,如图1.6所示。
图1.6 处理器数据缓存结构示意图
缓存速度在一定程度上影响着系统性能。为了进一步提升系统性能,引入了多级缓存,即L1缓存、L2缓存、L3缓存。在图1.7中,L1缓存为CPU专有,L2缓存为多个CPU共享,L3缓存则位于L2缓存与内存之间。缓存机制无法确保处理器所需数据一定位于缓存之中,一旦没有,就需要访问内存。
图1.7 多级缓存
缓存行(Cache Line)是缓存与内存之间数据传输的最小单位。在缓存缺失(Cache Miss)的情况下,即使处理器试图加载1B数据,缓存也会从内存中一次性地加载整块内存数据到缓存行中。例如,缓存行的大小是8B,即使处理器只读取1B,当出现缓存缺失时,缓存也会从内存中加载8B的数据块来填充整个缓存行。
有些微控制器本身并不含有缓存机制,如果需要,可以设置外挂缓存,如图1.8所示。
便笺存储器(SPM)与内存统一编址,处理器可以直接对其进行访问,不会出现访问缓存时的缓存缺失现象。有些处理器提供专门的SPM接口,通过外部总线接口可以直接访问内部SPM。指令SPM和数据SPM可以分开。
图1.8 外挂缓存
SPM由SRAM存储部件、地址译码部件和数据输出电路三个部分构成,使用总线与处理器连接。由于SPM不需要标记存储器(Tag RAM)就可以直接对其进行访问,其硬件构造相对比较简单,同一制造工艺下的面积一般仅为缓存的65%,因此功耗低、速度快。
在理想情况下,如果处理器当前需要读写的数据已在SPM中,则可以实现快速存取数据、缓存命中的高效数据处理方式。如果待处理数据量很大,片上存储资源又十分紧张,无法将全部数据搬运至SPM中,则可以使用DMA(Direct Memory Access,直接存储器访问)机制来实现SPM与内存的数据交互,即通过DMA将内存中的待处理数据提前送入SPM,待处理完成后将其移出,并更新下一次待处理数据,如图1.9所示。
图1.9 使用DMA机制传输数据
SPM与缓存的最大差别在于使用场景不同。缓存主要针对的是用最小的面积代价解决大部分连续访问的效率问题,只要缓存命中,就不用去远处的内存中读取数据,从而使处理器性能得到保证,但是由于存在不命中的可能,因此数据存取的延迟存在不确定性,不太适用于一些对计算延迟敏感的场景。SPM则主要针对实时计算的应用,常见于DSP(Digital Signal Processor,数字信号处理器)及类似ARM处理器的M系列、R系列的小处理器,如果处理器内核附近集成了SPM,则读写延迟固定,计算时间相对可控,因此SPM适用于高精度工业控制、航空航天、汽车制动控制等实时性要求高的场景。
有些多核DSP在使用时,为了快速实现不同DSP内核之间的数据交换,使用了一些特殊设计,举例如下。
·将需要共享的数据通过专用的接口写到其他DSP内核的内部RAM中。
·将需要共享的数据写到外部的数据交换存储器(FIFO)中,其他的DSP内核可从该数据交换存储器中读取,如图1.10所示。其中,XLMI(Xtensa Local Memory Interface)是DSP本地存储器接口。
图1.10 DSP内核之间的数据交换
缓存、SPM、内存都是按照应用场景来区分的,如果按照存储器件的类型分类,则可以分为静态随机访问存储器(Static Random Access Memory,SRAM)、动态随机访问存储器(Dynamic Random Access Memory,DRAM)、Flash、一次性可编程(One Time Programmable,OTP)存储器。
SRAM中的“S”(静态)是指只要不掉电,SRAM中存储的数据就不会丢失,不需要刷新;“R”(随机)是指SRAM中的内容可以按任何顺序访问,与前一次访问的位置无关。
DRAM中的“D”(动态)是指即使在通电情况下,也只能使数据保持很短的时间,需要通过不断刷新来保证数据不丢失。
同步动态随机存取存储器(Synchronous Dynamic Random Access Memory,SDRAM)中的“同步”是指具有一个与CPU同步的时钟,内部的指令发送与数据传输都以其为基准。DDR SDRAM(双倍速率SDRAM)是目前使用较多的存储器件,其可以在一个周期内读写两次数据,从而使数据传输速度加倍。
Flash是一种长寿命的非易失性存储器,在断电情况下仍能保持所存储的数据信息。Nand Flash和Nor Flash是两种主流的非易失性存储器。
Nand Flash的容量较大,改写速度快,比较廉价,但用户不能直接运行存储于其上的代码。Nor Flash可以通过处理器总线随机访问,其读取类似SDRAM,但不支持随机写操作;提供XIP模式,应用程序可以直接运行于其上;成本较高,只有小容量Nor Flash获得的收益比较大。
OTP存储器是芯片中的特殊存储器件,只允许一次性写入数据,一旦写入便不能修改,但其读取操作没有限制。OTP存储器擦写和读取的速度都比较慢,其优势是数据一旦被写入,就不会再被改写,常用于存储芯片的标识符(ID)、批次(Lot)、版本、安全Boot密钥等不允许被改写的特定内容。OTP存储器的内容一般在自动测试阶段通过机台写入,并于芯片启动后读取使用。
SoC存储系统用于程序和数据的存储。
各种RAM(SRAM、DRAM、SDRAM)都支持随机读和随机写,而ROM和Nor Flash仅支持随机读,不支持随机写。程序可以存储于所有支持掉电保存数据的存储器(ROM、Nand Flash、Nor Flash)中,当需要被执行时加载其到相应的存储器中,所以需要安排RAM存储空间以执行ROM和Nor Flash上的程序。较大的程序可以运行在动态存储器中,如在多阶段启动中,会首先将操作系统从启动源闪存复制到DRAM中,然后启动DRAM中的操作系统。
通常芯片功能操作中的数据可以存储在片上RAM中,供快速读写。大批量的数据则存储在DRAM或Nand Flash中。
SoC上集成了多种类型的存储器,通常会为每一个存储器分配一个数值连续、以十六进制表示的自然数作为其地址编码。这种自然数与存储器的对应关系称为存储器映射(Memory Map),又称为内存映射、地址映射(Address Map)。存储器映射是一个逻辑概念,在芯片上电复位后才建立起来。完成存储器映射后,用户就可以按照存储器地址访问对应的存储器。指令代码和数据都位于同一内存地址空间,但可以将它们限制在不同的特定地址范围;一部分内存地址空间开放,供系统外设使用,另一部分内存地址空间保留,供处理器内部使用。内存地址空间可分为可缓存区和非缓存区。需要维护可缓存区与处理器缓存之间的数据一致性,在不同工作场景下,同一内存地址空间可以在可缓存区与非缓存区之间转换。
存储器重映射是对此前已确立的存储器映射的再次修改,二者都是将地址编码资源分配给存储器,只是产生时间不同。存储器重映射发生在系统启动及运行过程中,并且与处理器异常(中断)处理机制紧密相关。芯片系统必须具备异常(中断)处理能力,当异常(中断)产生时,处理器在硬件驱动机制下跳转到预先设定的存储器,取出相应的异常(中断)处理程序的入口地址,并根据该地址进入异常(中断)处理程序。