3、Flash架构:NAND Flash与NOR Flash的区别、内部阵列结构、Page/Block/Plane概念

好,咱们今天聊聊Flash架构。说实话,Flash这玩意儿在存储领域太常见了,但很多人对它的内部结构其实是一知半解的。我当年刚入行时,也踩过不少坑。比如有一次,我设计的嵌入式系统里用了NOR Flash做代码存储,结果发现擦写次数根本不够用,后来才意识到应该用NAND。嗯,这就是没搞清楚两者区别的代价。

3.1 NAND Flash与NOR Flash:到底差在哪?

先说说最核心的区别。你想想看,NOR Flash和NAND Flash,名字就差一个字,但内部逻辑完全不同。

NOR Flash,说白了就是“随机访问型”。它的存储单元是并联的,每个单元都能独立寻址。这意味着你可以像读内存一样,直接读任意地址的数据。我习惯用它来存代码,因为CPU可以直接在NOR上执行程序(XIP,eXecute In Place),不需要先拷贝到RAM里。

NAND Flash呢,是“串行访问型”。它的存储单元是串联的,读写必须按页(Page)进行。你不能直接读某个字节,得先把整页数据读出来。这听起来有点麻烦,但好处是——密度高、成本低、容量大。我建议做数据存储时优先考虑它,比如U盘、SSD、手机存储,全是NAND的天下。

我列个表,方便你对比:

特性 NOR Flash NAND Flash
访问方式 随机访问(字节级) 页访问(块级)
读速度 快(~100ns) 较慢(~25μs 首次)
写速度 慢(~10μs/字节) 快(~200μs/页)
擦除速度 慢(~1s/块) 快(~2ms/块)
密度 低(< 512Mb) 高(可达Tb级)
寿命 10万~100万次 1千~10万次
典型应用 代码存储、BIOS 数据存储、SSD

核心要点:NOR适合存代码,NAND适合存数据。别搞反了,否则你会后悔的。

3.2 内部阵列结构:NAND的“串”与NOR的“并”

咱们深入一点,看看芯片内部到底长什么样。

NOR Flash的阵列结构,每个存储单元都连接着位线(Bit Line)和字线(Word Line)。你可以把它想象成一张网格,每个交叉点就是一个存储单元。这种结构的好处是——读操作非常快,因为你可以直接选中某个单元。但坏处是——面积大,因为每个单元都需要独立的接触孔。我做过一个项目,用NOR Flash做128Mb的存储,结果芯片面积比同容量的NAND大了三倍多。

NAND Flash的阵列结构,就完全不同了。它的存储单元是串联成一串的,通常32个或64个单元串在一起,形成一个“NAND串”。这个串的一端接位线,另一端接源线。你想想看,这样设计的好处是什么?——单元之间共享接触孔,面积大大缩小。我建议你记住这个数字:NAND的单元面积可以做到NOR的1/4到1/8。这就是为什么NAND能轻松做到Tb级容量。

嗯,这里要注意:NAND的读操作是“串行”的。你要读某个单元,得先把整个串上的其他单元都打开,然后才能读到目标单元的数据。这就像排队,你得等前面的人走完,才能轮到你。

个人经验:我在设计NAND控制器时,发现一个常见误区——很多人以为NAND的读延迟是固定的。其实不是,它取决于你读的是哪个Page。如果Page在同一个Block里,读延迟会小很多。我曾经因为这个疏忽,导致系统响应时间不稳定,后来加了预取机制才解决。

3.3 Page、Block、Plane:NAND的三层结构

好,接下来是重点。NAND Flash有三个核心概念:Page、Block、Plane。我建议你把这几个概念刻在脑子里,因为所有NAND的操作都离不开它们。

3.3.1 Page(页)

Page是NAND读写的最小单位。什么意思?就是你没法只读一个字节,必须读一整页。常见的Page大小有2KB、4KB、8KB、16KB。我最近用的3D NAND,Page已经到16KB了。

每个Page又分为两个区域:

  • 主数据区(Main Area):存用户数据,比如你的照片、文档。
  • 备用区(Spare Area / OOB):存元数据,比如ECC校验码、坏块标记、逻辑地址映射。

举个例子,一个8KB的Page,通常主数据区是8KB,备用区是256字节。你写数据时,主数据区写满,备用区自动写入ECC。我习惯在设计驱动时,把备用区的前几个字节留给坏块标记,这样扫描坏块时效率高。

注意:Page的读写是原子的。如果你写了一半断电,那整个Page的数据都可能损坏。所以,我建议你在写Page之前,先确保电源稳定,或者加个电容做掉电保护。

3.3.2 Block(块)

Block是NAND擦除的最小单位。一个Block包含多个Page,常见的有64个、128个、256个Page。比如,一个Block有128个Page,每个Page 8KB,那这个Block就是1MB。

为什么擦除要以Block为单位?因为NAND的物理结构决定了——你不能只擦除一个Page,必须把整个Block都擦掉。这就像你没法只删除一本书的一页,必须把整章撕掉。

我遇到过一个问题:有一次,我需要更新一个文件中的几个字节,结果发现必须先把整个Block读出来,修改,然后擦除整个Block,再写回去。这个过程叫“读-改-写”,非常耗时。后来我用了日志结构(Log-Structured)的写入方式,才避免了频繁的擦除操作。

避坑指南:我曾经在一个项目里,因为频繁擦写同一个Block,导致那个Block提前报废。后来我加了磨损均衡(Wear Leveling)算法,才把寿命提上来。记住:NAND的擦写次数是有限的,别逮着一个Block猛薅。

3.3.3 Plane(平面)

Plane是NAND内部的一个并行单元。一个Die(芯片)通常包含多个Plane,比如2个、4个。每个Plane有自己的Page寄存器,可以独立执行读写操作。

Plane的作用是什么?——并行化。你想想看,如果只有一个Plane,那一次只能读一个Page。如果有4个Plane,那理论上可以同时读4个Page。这就是为什么高端SSD的读写速度那么快,因为它们内部有多个Plane在并行工作。

我建议你在设计NAND控制器时,尽量利用Plane的并行性。比如,把数据分散到不同的Plane上,这样读写速度能提升好几倍。我做过一个测试:单Plane读速度是200MB/s,4个Plane并行读,速度飙到了750MB/s。

嗯,这里有个细节:不同Plane之间的操作是独立的,但共享同一个I/O总线。所以,你不能同时往两个Plane里写数据,但可以一个在读,另一个在写。这叫“交错操作”(Interleaving)。

层级 最小操作单位 典型大小 操作类型
Page 读写 2KB ~ 16KB 读、写
Block 擦除 64 ~ 256 Pages 擦除
Plane 并行单元 多个Block 并行读写

3.4 总结一下

好,咱们把今天的内容串一下:

  • NOR vs NAND:NOR随机访问,适合存代码;NAND串行访问,适合存数据。
  • 内部阵列:NOR是并联结构,面积大;NAND是串联结构,密度高。
  • Page/Block/Plane:Page是读写单位,Block是擦除单位,Plane是并行单位。

我个人觉得,理解这三层结构是掌握NAND Flash的关键。你想想看,如果你连Page和Block都分不清,那后面学FTL(Flash Translation Layer)和垃圾回收时,肯定会一头雾水。

下次咱们聊NAND的读写时序和ECC校验,到时候我会分享一个我踩过的坑——因为ECC配置不对,导致数据静默损坏。嗯,那是个挺惨的教训。