hooku

Please enjoy some eccentric technologies.

NAND学习笔记

NAND

本文的NAND均指RAWNAND。

SLC,MLC,TLC

NAND类型 理论可擦写次数 每单元存储bit数
SLC 100,000 1
MLC 10,000 2
TLC 3000~5000 3

NAND标准

NAND标准主要分为ONFi和JEDC标准。 ONFi标准的NAND通常支持Async,NVDDR,NVDDR2,NVDDR3模式,主要NAND厂商是Micron, Hynix, Intel, SanDisk。
JEDC标准的NAND通常支持Async,Toggle模式,主要NAND厂商是Samsung, Toshiba。

标准 发布时间 Async NV-DDR NV-DDR2 NV-DDR3 Toggle 1.0 Toggle 2.0
ONFI 1.0 2006 50MT/s
ONFI 2.0 2008 50MT/s 133MT/s
ONFI 2.1 2009 50MT/s 200MT/s
ONFI 3.0 2011 50MT/s 200MT/s 400MT/s
JESD230 2012 50MT/s 200MT/s 400MT/s 133MT/s
ONFI 3.2 2013 50MT/s 200MT/s 533MT/s
JESD230B 2014 50MT/s 200MT/s 533MT/s 133MT/s 400MT/s
ONFI 4.0 2014 50MT/s 200MT/s 667MT/s 800MT/s
JESD230C 2016 50MT/s 200MT/s 667MT/s 133MT/s 400MT/s
ONFI 4.1 2017 50MT/s 200MT/s 667MT/s 1200MT/s

NV-DDR模式在ONFi2.3之前又作Sync模式。

Toggle模式

Toggle模式采用了一根双向的DQS信号, 不需要一根单独的时钟信号。
当Host向NAND发送数据时,DQS信号由Host端控制;Host接收数据时,DQS信号由NAND控制。
Sync模式下,时钟信号是连续发送的,而Toggle模式只在读写时传输DQS信号;因此Toggle模式比Sync模式省电。

NAND层次

LU0 LU1 .. LUn
Block 0 Block 0 ..
Page 0
Page 1
...
Page x
Block 1 Block 1 ..
Page 0
...
Page x
Block 2 Block 2 ..
...
Page Reg0 Page Reg1 ..
  • LUN(Logical Unit Number):指闪存能够执行命令、获取状态的最小单元。例如,可以在LUN0进行写入时,对LUN1进行读取。
  • Block是最小的擦除单位。如果每个Block包含的Page个数不是2的幂,地址应与大于他的最近的2的幂对齐。
  • Page是最小的读写单位。(某些闪存支持Partial Page,比如可以设置Column地址,来指定从Page的某个Offset开始,直到整个Page读完)
  • Page Reg用来缓存即将存入Page,或刚从Page取出的数据。

NAND地址分为

  1. Column Address(行地址):表示数据在Page中的偏移量。在Row Address之前发送,但是如Block Erase之类的指令无需发送该地址。
  2. Row Address(列地址):LUN+Block+Page的地址。

坏块标记(Bad Block Marker)

在NAND出厂时,当某个Block有缺陷时,该Block的第一个Page的OOB处(通常会在当前Block的最前面3个Page,以及最后面3个Page)标记坏块信息(BBM)。
没有缺陷的Block此处应为0xFF,有缺陷则标记为0x0。其他不等于0xFF的值也将被认为是坏块。
在初次使用NAND闪存时,厂商通常会提供一个NAND烧写工具,该工具会遍历NAND上所有的BBM,并在NAND上创建一个表,称作BBT(Bad Block Table)。 这个表会把所有的坏块记录下来,方便后续访问NAND(有了BBT,就不需要每次读取一个新的Block之前再访问这个Block的BBM了)。

常用引脚

引脚 I/O 全称 说明
CE# I Chip Enable 当R/B#信号为低电平时(如正进行读写、擦除操作),CE#可以上拉,选择另一个NAND芯片进行操作。
R/B# O Ready/Busy Output 低电平时表示LUN正忙
CLE I Command Latch Enable 指令锁存使能,用于区分当前I/O口传的是命令还是地址。
ALE I Address Latch Enable 地址锁存使能
WE# I Write Enable 写使能
RE# I Read Enable 读使能
IO0-7,8-15 I/O I/O Port NAND总线宽度可以是8位,或者16位的,但是所有的地址传输只用低8位总线(高8位填0)
DQS I Data Strobe
WP# I Write Protect 拉底后,对闪存的写入、擦除命令失效

对NAND检测及初始化

  1. Controller拉底CE#,选中NAND。
  2. Controller向NAND发送Reset命令。
  3. Controller向NAND发送Read ID命令,若NAND回应了正确的ID,则可初步判断Controller与NAND的连接配置正确。

大部分ONFi、Toggle NAND初始的时候是Async模式,通过发送Set Feature命令后,可以切入ONFi Sync,或者Toggle模式。

Legacy NAND(Async模式)

NVDDR 模式

包括6种速度(Mode 0~5)

频率 NVDDR模式 NVDDR2模式
20MHz NVDDR Mode 0
33MHz NVDDR Mode 1 NVDDR2 Mode 0
40MHz NVDDR2 Mode 1
50MHz NVDDR Mode 2
66MHz NVDDR Mode 3 NVDDR2 Mode 2
83MHz NVDDR Mode 4 NVDDR2 Mode 3
100MHz NVDDR Mode5 NVDDR2 Mode 4
133MHz NVDDR2 Mode 5
166MHz NVDDR2 Mode 6
200MHz NVDDR2 Mode 7
267MHz NVDDR2 Mode 8

NAND 模式的切换

通过发送 SET FEATURE 命令

NVDDR2 模式

包括9种速度(Mode 0~8) 高速情况下,通常使用DQS RE_B差分

Toggle 模式

Toggle 模式多了一根DQS(Data Strobe)线,在DQS的上升 & 下降沿,对 通常,Toggle NAND能够兼容Legacy NAND的操作,

NAND空闲区

OOB(Out-of-Band)/Spare region

NAND Read Retry技术

NAND在一定的擦写次数后,其读取的电平阈值会发生漂移。因此,可以通过更改参考电压的方式延长闪存使用寿命。

Meta D0 BCH D1 BCH D2 BCH D3 BCH D4 BCH D5 BCH D6 BCH D7 BCH
32B 128B ? 128B ? 128B ? 128B ? 128B ? 128B ? 128B ? 128B ?

i.MX6 的NAND控制器

i.MX6内建了GPMI(General Purpose Media Interface) NAND控制器,以及BCH硬件ECC加速模块进行NAND纠错。
GPMI模块兼容ONFi 2.2以及Toggle NAND协议。
此外,i.MX6的BCH模块最多能纠错62位数据(数据长度<1900字节)。

BCH控制器

BCH的主要功能是对NAND的数据进行纠错处理。

NAND BCH Layout

|                          P                            |
|<----------------------------------------------------->|
|                                                       |
|                                        (Block Mark)   |
|                      P'                      |      | |     |
|<-------------------------------------------->|  D   | |  O' |
|                                              |<---->| |<--->|
V                                              V      V V     V
+---+----------+-+----------+-+----------+-+----------+-+-----+
| M |   data   |E|   data   |E|   data   |E|   data   |E|     |
+---+----------+-+----------+-+----------+-+----------+-+-----+
                                               ^              ^
                                               |      O       |
                                               |<------------>|
                                               |              |
简写 说明
G gf_len Galois Field长度
E ecc_strength ECC纠错强度(可纠错的数据bit数?)
M metadata_size metadata长度(Byte)
C ecc_chunk_size 被校验的数据块长度(Byte),例如512B。第一块数据块包含了metadata因此第一块的长度比该数值稍大些
N ecc_chunk_count 被校验的数据块个数(包括第一个?)
P' data_page_size datapage大小
P 实际使用的page大小(Byte)
O oob长度(Byte)
O' 空闲的oob
D BBM与ecc_chunk(data)位置结尾的差值

ECC纠错能力计算

计算公式:

NAND纠错满足如下关系
    (E*G*N)/8 <= (O - M)
不等式整理得:
    E <= (O - M)*8/(G*N)

GF13(BCH40)的生成多项式是:x^9+1
可以对<=900 Bytes数据纠错(所以,C=512B时采用GF13)

GF14(BCH20)的生成多项式是:x^10 + x
可以对<=1900 Bytes数据纠错(所以,C=1024B时采用GF14)

BCH 默认参数的计算

ecc_chunk_size=1 << `ECC Codeword size`
if (ecc_chunk_size == 512)
    gf_len = 13
if (ecc_chunk_size == 1024)
    gf_len = 14
ecc_strength = roundup(`ECC Codeword size`, 2)
metadata_size=10
ecc_chunk_count = `data_page_size`/ecc_chunk_size
P = 'data_page_size` + metadata_size + (gf_len*ecc_strength*ecc_chunk_count)/8

交换BBM的位置计算

在BCH向GPMI写入NAND数据之前,需要将写入BBM位置处的Byte复制到Metadata头部,并且在BBM位置仍然保留原来的BBM;这样就不会破坏原本该block上的坏块标记信息。
同时,需要保证BBM的位置落在data里,而不是ECC里(因为data里存放的数据是raw的,这样在decode完一个page的NAND数据后,BBM位置的数据就可以被Metadata头部的数据替换回来。 NAND驱动仍应对BBM在BCH Layout上的位置进行检查,防止其落入ECC的位置。

计算公式:

D = (gf_len*ecc_strength*(ecc_chunk_count-1))/8 + metadata_size

Async模式下,读取数据的波形

{signal: [
  {name: 'CE#', wave: '1.0..............1.'},
  {name: 'R/B#', wave: 'x.0..........10..x.'},
  {name: 'CLE', wave: 'x.010......10....x.'},
  {name: 'ALE', wave: 'x.0...1..0.......x.'},
  {name: 'RE#', wave: '1.............n.|h.'},
  {name: 'WE#', wave: '1..nh.n.|nh........', phase: 0.5},
  {name: 'IO0-7', wave: 'x..3x|4.|x|3x|=.|x.', data: ['00', 'ADDR', '30', 'DATA']},
]}

Sync模式下,读取数据的波形

{signal: [
  {name: 'CE#', wave: '1.0................1.'},
  {name: 'R/B#', wave: 'x.0..........10....x.'},
  {name: 'CLE', wave: 'x.010......10.1....x.'},
  {name: 'ALE', wave: 'x.0...1..0....1....x.'},
  {name: 'CLK(RE#)', wave: 'n....|..|.......n.|..'},
  {name: 'WR#(WE#)', wave: 'x..1x.1..x.1xx0....x.'},
  {name: 'IO0-7', wave: 'x..3x|4.|x|3x|====|x.', data: ['00', 'ADDR', '30', 'D0', 'D1', 'D2']},
  {name: 'DQS', wave: 'x.............0P....x', phase: 0.5},
]}

Toggle模式下,读取数据的波形

{signal: [
  {name: 'CE#', wave: '1.0................1.'},
  {name: 'R/B#', wave: 'x.0..........10....x.'},
  {name: 'CLE', wave: 'x.010......10......x.'},
  {name: 'ALE', wave: 'x.0...1..0.........x.'},
  {name: 'RE#', wave: '1.............01010|1', phase: 0.5},
  {name: 'WE#', wave: '1..nh.n.|h.nh........'},
  {name: 'IO0-7', wave: 'x..3x|4.|x|3x|====|x.', data: ['00', 'ADDR', '30', 'D0', 'D1', 'D2']},
  {name: 'DQS', wave: 'z.............0101|z.'},
]}

部分i.MX芯片的ECC纠错能力

芯片 BCH ECC能力
imx23 20
imx28 20
imx6q 40
imx6sx 62

测试常用 NAND 列表

Env NAND pagesize(Byte) blockcount pageperblk manufacturer devicecode iddata MB
RTL hy27ss16121a 256+8 4096 32 0xAD 0x46 32
RTL k9f5616q0c 256+8 2048 32 0xEC 0x45 16
RTL tc58dvm82f1ft00 256+8 2048 32 0x98 0x75 0x20 16
RTL hy27ss08121a 512+16 4096 32 0xAD 0x36 64
RTL k9f5608q0c 512+16 2048 32 0xEC 0x35 32
RTL nand512w3a2 512+16 4096 32 0x20 0x76 0x00, 0x00 64
RTL tc58dvg02a1fti0 512+16 8192 32 0x98 0x79 0x20 128
RTL hy27uf162g2m 1K+32 2048 64 0xAD 0xCA 0x00, 0x55 128
RTL k9f1g16u0m 1K+32 1024 64 0xEC 0xC1 0x00, 0x55 64
RTL mt29f2g16aab 1K+32 2048 64 0x2C 0xCA 0x00, 0x55 128
RTL tc58nyg0d9bxgj5 1K+32 512 128 0x98 0xB1 0x00, 0x61 64
RTL hy27uf082g2m 2K+64 2048 64 0xAD 0xDA 0x00, 0x15 256
RTL k9f1g08u0m 2K+64 1024 64 0xEC 0xF1 0x00, 0x15 128
RTL k9k8g08u0m 2K+64 8192 64 0xEC 0xD3 0x51, 0x95, 0x58 1024
RTL mt29f2g08aab 2K+64 2048 64 0x2C 0xDA 0x15, 0x15 256
RTL nand02gw3b 2K+64 2048 64 0x20 0xDA 0x00, 0x15 256
RTL nand04gw3b 2K+64 4096 64 0x20 0xDC 0x00, 0x15 512
RTL tc58nvg0s3aft05 2K+64 1024 64 0x98 0xF1 0x80, 0x95, 0x40 128
RTL k9gag08u0m 4K+128 4096 128 0xEC 0xD5 0x14, 0xB6, 0x74 2048
RTL tc58nvg4d1dtg00 4K+218 4096 128 0x98 0xD5 0x00, 0x3A, 0x00 2048
RTL k9kbgd8x1m 8K+512 4152 64 0xEC 0xD5 0x10, 0x66, 0x34, 0xC2 2076
RTL k9gbg08u0m 8K+436 4152 128 0xEC 0xD7 0x94, 0x72, 0x54, 0x42 4152
RTL k9gbgd8u0m 8K+512 4152 128 0xEC 0xD7 0x14, 0x76, 0x54, 0xC2 4152
RTL k9fagd8u0m 8K+640 4152 64 0xEC 0xD5 0x10, 0x66, 0x34, 0xC2 2076
RTL toggle20_k9gcgy8s0a 8K+640 8192 128 0xEC 0xAE 0xE5, 0x7E, 0x7C, 0xC4 8192
RTL sdtnqgama_008ga 16K+1280 2132 256 0x45 0xDE 0x94, 0x93, 0x76, 0xD7 8528
RTL sdtnrgama_008gp 16K+1280 2132 256 0x45 0xDE 0x94, 0x93, 0x76, 0x50 8528
RTL sdtnrgama_008g 16K+1280 2132 256 0x45 0xDE 0x94, 0x93, 0x76, 0x50 8528
MX8QXPLPD4 MT29F128G08CBCCBH6 16K+1872 512 0x2C 0x84 0x64 0x54 0xa9

参考

ONFi Specification
Raw NAND ECC
How Micron FortisFlash Technology Improves Performance and Endurance
gpmi-nand.c