自学内容网 自学内容网

SSD | (三)NAND闪存(上)

文章目录

  • 📚闪存基本原理
    • 🐇存储单元及相关操作
    • 🐇闪存类型
    • 🐇闪存组织结构
    • 🐇擦、写、读操作
    • 🐇阈值电压分布图

📚闪存基本原理

🐇存储单元及相关操作

  • 闪存是一种非易失性存储器,也就是说,即使掉电,存储在闪存中的数据也不会丢失。这是闪存能作为SSD存储介质的根本原因之一。

  • ⭐️闪存擦写原理

    • 传统2D闪存的基本存储单元是一种类NMOS的浮栅晶体管。
      • 浮栅晶体管由源极(Source)、漏极(Drain)和浮栅极(Floating Gate)组成。
      • 浮栅极位于源极和漏极之间,由导体材料制成,上下被绝缘层包围。
      • 存储在浮栅极的电子不会因为掉电而消失,保证了数据的非易失性。
        在这里插入图片描述
    • 把浮栅极里没有电子的状态用“1”来表示存储一定量电子的状态用“0”表示:初始清空浮栅极里面的电子(通过擦除操作),当需要写“1”的时候,无须进行任何操作;当需要写“0”的时候,则往浮栅极里面注入一定量的电子(也就是进行写操作)。
    • 擦除操作
      • 目的是移除浮栅极上的电子,将数据从“0”变为“1”。
      • 通过在衬底加正电压,建立一个反向的强电场,利用F-N隧道效应将电子从浮栅极中“吸”出来。
    • 写入操作
      • 目的是在浮栅极上注入电子,将数据从“1”变为“0”。
      • 通过在控制极施加一个大的正电压,在控制极和衬底之间建立一个强电场,使电子通过隧道氧化层进入浮栅极。
        在这里插入图片描述
  • ⭐️闪存的耐久性

    • 随着擦写次数的增加,隔离浮栅极电子的隧道氧化层的绝缘效果会逐渐变差。
    • 这可能导致电子更容易进出浮栅极,从而引起数据的非预期变化,如“0”变成“1”或“1”变成“0”。
    • 闪存的寿命通常用擦写次数(Program/Erase Cycle,PEC)来衡量,超过一定次数后,闪存可能就不可用了。
  • ⭐️读取操作

    • 具体来说,往浮栅极注入的电子越多,晶体管的导通电压越大。
      在这里插入图片描述

    • 读取操作是通过在控制极上施加一个介于“0”和“1”状态导通电压之间的参考电压来完成。如果在施加参考电压后晶体管导通,则表示存储的数据是“1”;如果不导通,则表示存储的数据是“0”。

    • 假设浮栅极里面没有电子或者只有少许电子(即“1”)时的导通电压为0.1V,而往浮栅极里面注入一定量电子(即“0”)时的导通电压为0.5V,我们在控制极上施加一个介于两者之间的电压,比如0.3V,那么:如果管子导通,说明该晶体管存储的数据是“1”;反之,则说明该晶体管存储的数据是“0”

    • 读取操作不会对浮栅极的电子状态产生影响,因此不会影响闪存的寿命。


  • ⭐️Q&A小结
    • 为什么闪存可以存储数据?
      • 首先,闪存是非易失性存储介质。存储在浮栅极里面的电子上下层都被绝缘层包用即使掉电,里面的电子也很难跑掉。
      • 其次,闪存可以通过浮栅极里面有无电子或者电子的多少来表示“0”和“1”,能表示“0”和“1”,就具备了存储数据的基础。
    • 为什么闪存有寿命?
      • 擦写操作需要在存储单元的控制极和衬底建立强电场以从浮栅极中清空或者注入电子。
      • 这会对隧道氧化层造成物理损伤,日积月累,当擦写次数过多时,隧道氧化层这道“屏障就失去隔离电子的作用,闪存就存储不了数据了。
    • 闪存为什么要写前擦除?
      • 假设某存储单元之前写入的是“0”,即浮栅极里面有电子,现在我们要把该位从“0”改成“1”,是不能通过往里面注入更多电子达到这个目的的,只能通过擦除操作完成从“0”到“1”的更改。
      • 这就好比一块白板,如果上面之前写了很多字,你不能在上面直接写新的字,否则很难分辨,只有擦了重写才能看清楚。
    • 为什么闪存有数据保持性问题?
      • 存储在浮栅极里面的电子,随着时间的流逝,会慢慢通过隧道氧化层溜出(正所谓“天下没有不透风的墙”),今天溜走一个电子,明天再溜走一个,日积月累,量变引起质变,就会导致里面存储“0”的数据变成“1”。
      • 这就产生了闪存数据保持问题(Data Retention)。隧道氧化层经历擦写次数越多,这道“墙”透风越厉害,数据保持能力也就越差。

🐇闪存类型

  • SLC (Single Level Cell)

    • 每个存储单元存储1位数据。电压阈值有两个状态,对应于“0”和“1”。
    • 读取速度20-25微秒,写入速度50-100微秒。擦除时间2-5毫秒,擦写次数约100,000次。
    • 比特成本高。可靠性最高,因为只有两种状态,对电子数量的变化不敏感。
    • 应用场景:对成本不敏感且对可靠性要求极高的场合,如服务器和高端企业级存储。
  • MLC (Multiple Level Cell)

    • 每个存储单元存储2位数据。电压阈值有四种状态,每个状态对应2位数据。
    • 读取速度55-110微秒,写入速度400-1500微秒。擦除时间5-10毫秒,擦写次数约15,000次。
    • 比特成本较低,因为存储密度是SLC的两倍。可靠性低于SLC,因为状态更多,对电子数量的变化更敏感。
    • 应用场景:中端市场,平衡成本和性能。
  • TLC (Triple Level Cell)

    • 每个存储单元存储3位数据。电压阈值有八种状态
    • 读取速度75-170微秒,写入速度800-2000微秒。擦除时间10-15毫秒,擦写次数3,000~5,000次。
    • 比特成本更低,因为存储密度是MLC的1.5倍。可靠性低于MLC,状态更多,对电子数量的变化更敏感。
    • 应用场景:主流消费级SSD市场,成本效益高。
  • QLC (Quad Level Cell)

    • 每个存储单元存储4位数据。电压阈值有十六种状态
    • 读取速度120-200微秒,写入速度2000-3000微秒。擦除时间15-20毫秒,擦写次数800-1500次。
    • 比特成本最低,因为存储密度是TLC的1.33倍。可靠性最低,状态最多,对电子数量的变化极其敏感。
    • 应用场景:消费级市场和读密集型企业级应用,如视频存储。
      在这里插入图片描述在这里插入图片描述
      在这里插入图片描述
  • ⭐️存储单元的读取原理

    • 对于SLC(单层单元):

      • 读取操作:在控制极加 V R E A D V_{READ} VREAD电压。
      • 判断逻辑:晶体管导通表示数据为“1”,不导通表示数据为“0”。
    • 对于MLC(多层单元):

      • MLC存储2位数据,分为低位数据(LowerPage, LP)和高位数据(UpperPage, UP)。
        在这里插入图片描述

      • 读取LowerPage(LP):在存储单元的控制极加上一个特定的电压 V B V_{B} VB。如果晶体管导通(即电流可以通过),说明存储单元的低位数据是“1”。如果晶体管不导通(即电流不能通过),说明存储单元的低位数据是“0”。这里的关键点是,无论存储单元的状态是“11”还是“01”,它们的低位都是“1”,所以只要晶体管导通,就可以确定LP的数据是“1”。同理,如果晶体管不导通,那么无论状态是“00”还是“10”,LP的数据都是“0”。

      • 读取UpperPage(UP):读取UP比LP复杂,需要分两步施加不同的电压(切两刀)。

        • 第一步:在控制极上加上电压 V A V_{A} VA。如果晶体管导通,说明存储单元处于“11”状态,因此UP的数据是“1”。如果晶体管不导通,说明存储单元处于“01”、“00”或“10”状态之一,此时无法直接确定UP的数据是“0”还是“1”。
        • 第二步:如果第一步中晶体管不导通,再在控制极上加上另一个电压 V C V_{C} VC。如果此时晶体管导通,说明存储单元处于“00”或“01”状态,因此UP的数据是“0”。如果晶体管仍然不导通,说明存储单元处于“10”状态,因此UP的数据是“1”。
    • TLC和QLC的读取思路和MLC相同,一刀不行就切多刀。

  • ⭐️提升闪存密度虽然可以增加存储容量,但同时也带来了读取速度的降低、写入性能的下降、寿命的缩短和可靠性的降低等问题

    • 读取速度:在读取不同类型的物理页时,速度不同。一些页只需要施加一次电压(切一刀)就能读取数据,而其他页可能需要施加多次电压(切几刀)。需要多次电压施加的页读取速度更慢,因为每次电压施加都需要额外的时间。
    • 写入性能:提升闪存密度会导致写入性能变差。随着存储单元存储的位数增加,需要编程的状态也增多,每个状态更精细,对注入电子的控制要求更精确。控制不精确可能导致状态间的跳变,影响数据的正确写入。
    • 寿命和可靠性
      • 存储单元的状态越多,这些状态之间的阈值电压分布就越接近,对电子数量的微小变化更敏感。
      • 电子的流失或增加可能导致状态错误,如SLC的“0”状态可能因电子流失而保持不变,但MLC的“00”状态可能因相同数量的电子流失而跳变到“01”状态,导致数据错误。
      • 电子流失与浮栅晶体管的隧道氧化层的隔绝效果有关。隔绝效果越好,电子越不容易丢失。
      • SLC对电子流失不太敏感,可以接受较高的擦写次数。而MLC对电子流失更敏感,需要限制擦写次数以保证数据可靠性
      • 随着存储单元存储位数的增加,擦写次数减少,闪存的寿命也随之缩短。

🔥目前 SSD的主流存储介质是3DTLC,业界已经很少使用SLC和MLC(因为成本太高),只将其应用在一些对成本不敏感且对可靠性要求很高的场合,比如航天航空。QLC由于寿命有限,一般仅应用在消费级或者读密集型的企业级应用(如视频网站)上,但随着闪存技术的发展,相信QLC会应用在越来越多的场合,最后可能取代TLC成为主流。

🐇闪存组织结构

  • ⭐️闪存块的组织结构(注意:以下没有考虑奇/偶位线,如果考虑,则在此基础上一个字线上闪存页要翻倍)
    在这里插入图片描述

    • 其中,横向是m条字线(Word Line,WL),纵向是n条位线(BitLine,BL)。
    • 1个字线包含若干个闪存页:对SLC来说,1个字线包含1个闪存页;对于MLC来说,1个字线包含2个闪存页,这2个闪存页是1对——LP和UP;对于TLC来说,1个字线包含3个闪存页——LP、MP和UP(不同闪存厂商叫法可能不一样)。假设一个SLC闪存块由1024个闪存页组成,则图中m=1024,即有1024条字线。
    • 一个闪存页有多少位,那么就有多少条位线,比如对16KB的闪存页来说,n=16x1024x8。
    • 一个闪存块中的所有存储单元都是共用一个衬底的,当往衬底加高电压进行擦除操作时,该闪存块中的所有存储单元电子都会被“吸”出来,因此擦除操作的基本单元是闪存块
  • ⭐️闪存的宏观组成
    在这里插入图片描述

    • 一个闪存内部存储组织结构如上所示:
      • 一个闪存芯片有若干个Die(或者叫LUN),每个Die有若于个Plane,每个Plane有若干个,每个块有若干个,每个页对应着一条字线且由成千上万个存储单元构成。
      • 闪存 Die/LUN 是接收和执行命令的基本单元。如上所示的LUN0 和 LUN1 可以同时接收和执行不同的命令(有一定的限制,不同厂家的多 Die操作的限制可能不同)。在一个LUN中,一次只能独立执行一个命令,即你不能在对其中某个闪存页进行写的同时,对其他闪存页进行读。
      • 一个 Die 又分为若于个Plane。早期闪存每个Die一般包括2个Plane,现在的主流闪存是每个Die包括4个Plane,已经有每个Die包括6个Plane 的闪存了。每个Plane 都有自己独立的缓存(Cache Register 和 Page Register 即闪存缓存和页缓存),每个页缓存的大小等于一个闪存页的大小,它们是闪存内部的RAM,用于缓存要写入闪存阵列(Array)或者从闪存陈列中读取的数据
      • 在写某个闪存页的时候,主控先把数据从主控端传输到与该闪存页所对应的Plane的闪存缓存当中,然后把闪存缓存中的数据写到闪存介质;读的时候与之相反,闪存先把用户所需的闪存页数据从闪存阵列读取到闪存缓存,然后再按需传到主控端。
  • 上图中每个 Plane 只画了一个页缓存。事实上,为支持一次性编程(one-pass programming)现在的闪存内部都不只配备一个页缓存。
  • 所谓的“一次性编程”,是指一次性把一个存储单元的状态编程到目标状态。例如TLC,一个存储单元涉及LP、MP和UP的数据,一次性编程需要把3个闪存页的数据都准备好,然后一起编程到闪存存储单元阵列。这就需要至少3个页缓存,分别缓存主机写入的3个闪存页的数据,等3个闪存页的数据都齐后,闪存根据3个页的数据把每个存储单元编程到期望的状态。

🐇擦、写、读操作

  • ⭐️
    在这里插入图片描述

    • 前面提到,擦除一个存储单元,是在控制极上加0V电压,然后在衬底加高电压,建立一个强电场把电子从浮栅极里面“拉”出来。
    • 闪存擦除的最小单元是闪存块,擦除闪存块时,要在所有字线的控制极上加0V电压,在衬底加高电压,然后这个闪存块上的所有存储单元在隧道效应的作用下,把在浮栅极里面的电子“拉”出来,达到清空所有存储单元电子的目的。
    • 怎么确保所有(或者绝大多数)存储单元的浮栅极电子被清空呢?闪存内部存在一个验证过程,即读取这些存储单元,看它们是否都处于擦除状态:如果不是,就继续擦除(加大衬底电压,使电场变强);否则,就结束擦除操作。
    • 擦除操作允许一些存储单元始终擦除不干净,毕竟一个闪存块有数百万个存储单元难免有些存储单元存在质量问题。至于允许多少个存储单元擦除不干净,取决于闪存厂商的参数。
    • 如果在允许的擦除时间内,闪存块中擦除不干净的存储单元个数始终超过闪存厂商设置的阈值,则擦除失败。从用户角度看,这些闪存块需要被标为坏块,后续不再使用。
  • ⭐️
    在这里插入图片描述

    • 如上图所示,假设要写某个闪存页,落在字线1(WL1)。在与要编程的闪存页对应的控制极上加一个高电压 V P R O G V_{PROG} VPROG,在其他不编程的闪存页(或者字线)的控制极上加个稍微大点的电压 V P A S S V_{PASS} VPASS,从而保证不管当前存储单元处于什么状态,这些晶体管都是导通的。可以把这些导通的晶体管看作一根根导线。

    • 闪存页的写入(编程)过程可以总结如下

      • 编程准备:闪存页由 16 × 1024 × 8 16 \times 1024 \times 8 16×1024×8个存储单元组成,每个存储单元在擦除后默认处于“1”状态。写入操作需要将某些存储单元编程为“0”,这需要向这些存储单元的浮栅极注入电子。
      • 抑制不需要编程的存储单元:对于不需要编程为“0”(即保持为“1”)的存储单元,它们的控制极上被统一施加高电压 V P R O G V_{PROG} VPROG,为了抑制这些存储单元被注入电子,对应的位线上加一个高电压 V INH V_{\text{INH}} VINH,从而削弱控制极和衬底间的电场,阻止电子进入浮栅极。(如上图存储单元0,2,3)
      • 编程需要写“0”的存储单元:对于需要编程为“0”的存储单元,保持位线电压为0V,使得控制极和衬底之间建立的电场足以将电子注入浮栅极。(如上图存储单元1)
    • 分步编程过程

      • 编程过程是迭代的,首先在编程字线控制极上施加一个大电压,然后读取数据进行验证。
      • 如果大多数存储单元已达到目标状态,则结束编程;否则,进一步增加电压并继续编程,直到大多数存储单元达到目标状态。
      • 电压步进增加的原因:使用逐渐增加的电压步进进行编程是为了避免过度编程。如果一开始就使用大电压,可能会导致存储单元进入非目标状态,而由于编程是增加电子的过程,无法将状态调回。因此,应先使用小电压编程到状态“1”,在验证未达到目标状态时,再逐步增加电压,以实现精确编程。
        在这里插入图片描述
    • 跟擦除操作一样,写入操作允许一些存储单元始终编程不到目标状态,闪存厂商会提供个相关参数设置。如果在允许的写入时间内,闪存页中编程不到位的存储单元个数始终超过闪存厂商设置的阈值,则写入失败。从用户角度看,这些闪存块需要被标为坏块,后续不再使用。写入操作同样会对闪存存储单元有物理损伤。

  • ⭐️
    在这里插入图片描述

    • 如上图所示,假设要读的闪存页在字线1(WL1)上。
    • 首先,在不读取的其他字线控制极上施加 V P A S S V_{PASS} VPASS电压,确保这些晶体管无论当前处于何种状态都是导通的;然后给每个位线(BL0~BLn-1)充电;接着根据所读闪存页的类型(LP、MP还是UP),在WL1上施加不同的读参考电压:
      • 如果某个位线放电了,说明该位线上所读的那个存储单元是导通的;如果位线保持之前的充电状态,说明该位线上所读的那个存储单元是截止的。
      • 通过一次或者多次施加不同的参考电压,最终能确定所有晶体管所处的状态,从而获得存储在里面的数据。
    • 由于读的时候在控制极上加的电压不大,建立的电场不足以损伤隧道氧化层,所以读操作不会影响闪存的寿命。
    • 但我们在读一个闪存页的时候,需要在别的字线上施加一个较大的 V P A S S V_{PASS} VPASS电压,这可能导致这些没有读取的闪存页有轻微的“写入”操作,即会有电子进入。
    • 如果一个闪存块上读的次数过多,就可能因量变引起质变,导致存储单元数据从“1”变成“0”,发生位翻转。如果不采取措施,这种情况最终可能导致数据丢失。这就是读干扰,后面会对这个问题进行深入分析。

🐇阈值电压分布图

  • 每个存储单元都对应一个阈值电压(在控制极施加大于该阈值电压的电压,晶体管导通,否则品体管截止),如果对一个闪存页或者一个字线上所有存储单元的阈值电压的分布做一个统计,即统计不同阈值电压下存储单元的个数,然后绘成一张图,就是阈值电压分布图
  • 以MLC内存页的阈值电压分布图为例,横坐标是阈值电压,纵坐标是每个阈值电压对应的存储单元个数。包含不同电子数的存储单元对应不同的阈值电压,只要落在同一个范围内,它们就属于同一个状态。
    在这里插入图片描述
    在这里插入图片描述
  • V R 1 V_{R1} VR1 V R 2 V_{R2} VR2 V R 3 V_{R3} VR3:默认读参考电压,即读不同闪存页的时候,在要读的闪存页控制极上施加的电压。比如读LP的时候,需要施加电压 V R 2 V_{R2} VR2;读UP的时候,需要先后施加 V R 1 V_{R1} VR1 V R 3 V_{R3} VR3
  • V P V 1 V_{PV1} VPV1 V P V 2 V_{PV2} VPV2 V P V 3 V_{PV3} VPV3Program-Verify(编程-验证)电压。比如我们要把存储单元从擦除状态S0编程到状态S1,在编程一段时间后,我们要做读取验证,即在控制极施加电压 V P V 1 V_{PV1} VPV1,然后通过存储单元的导通状态来判断编程是否到位。
    • 如果存储单元导通(阈值电压小于 V P V 1 V_{PV1} VPV1),说明还没有编程到位;否则,就表示这些单元已经编程到状态 S1(后续在编程的时候,这些存储单元将会被禁止继续编程)。
  • V P A S S V_{PASS} VPASS:前面在讲读闪存页的时候,提到在未选中的闪存页的控制极上施加 V P A S S V_{PASS} VPASS,这是一个比所有编程状态下阈值电压都要高的电压,这样才能确保不管当前存储单元处于何种状态,施加 V P A S S V_{PASS} VPASS总能确保晶体管是导通的。
  • 相邻两个状态中间有个读参考电压,它用于区分相邻两种状态参考电压与左侧状态的距离,比如图中的E0、E2、E4,为左边状态允许的最大阈值电压的增加值;参考电压与右侧状态的距离,比如图中的E1、E3、E5,为右边状态允许的最大值电压的减少值。
    • 这些距离越宽越好,因为越宽表示允许更多电子的意外流失或者意外注入,闪存容错性越好。
    • 但随着闪存每个存储单元存储的位数变多,状态也在增多,每个状态之间的间隔越来越小,状态发生很小偏移,就可能导致状态和读参考电压发生重叠,所以闪存容错率变低,这意味着可靠性变差。

  • 为了正确读取数据,我们希望各个状态下的阈值电压不要和读参考电压发生重叠,否则用默认参考电压去读会发生误判。
  • 如下图所示,如果状态S2向左偏移(浅色到深色),此时阈值电压和读取参考电压 V R 2 V_{R2} VR2有部分重叠,这个时候如果还是用 V R 2 V_{R2} VR2电压去辨别是否导通,那么处于状态S2中的一些存储单元(参考电压左边S2部分)会被判为S1,因此可能导致数据读取错误。
    在这里插入图片描述

  • 阈值电压分布图的作用
    • 可以用它以具体、形象的方式阐述和分析与闪存相关的问题
    • 可以用它来调试闪存出错问题。平时我们读闪存的时候,会碰到一些闪存页数据出错的问题,如果想知道是什么原因导致数据出错,就可以绘制该闪存页的值电压分布图,观察这些阀值电压的分布。
      • 如果阈值电压整体左移,说明数据丢失是电子流失导致的;
      • 如果阈值电压右移,说明是意外注入电子导致的;
      • 如果观察到各个“山峰”大小高低不一,则很有可能是double program(同一个闪存页被多次编程)问题;
      • 如果发现有些“山峰”(尤其是最右边的)缺失,则有可能是异常掉电导致的。

  • 参考书籍:《深入浅出SSD:固态存储核心技术、原理与实战》(第2版)

原文地址:https://blog.csdn.net/m0_63398413/article/details/142864054

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!