第四章:SRAM架构设计——行译码器、列译码器、灵敏放大器、写驱动器

各位同学,今天我们来聊聊SRAM内部最核心的几个模块。说实话,很多新手觉得SRAM就是一堆存储单元排在一起,地址送进去数据就出来。哪有那么简单!你想想看,一个64Kb的SRAM,如果不用译码器,难道要拉几万条地址线?

我个人习惯把SRAM比作一个大型图书馆。行译码器就是找书架号,列译码器是找书的具体位置,灵敏放大器是那个帮你快速识别书名的管理员,写驱动器则是负责把新书放回去的搬运工。好,我们一个一个来看。

4.1 行译码器:选通字线

行译码器的作用,说白了就是把地址信号翻译成某一条字线的选通信号。比如你有10位地址,那就要译出1024条字线。每条字线对应一行存储单元。

设计要点:

  • 译码结构:常用两级译码。先预译码,再全局译码。这样可以减少门扇入,提高速度。
  • 驱动能力:字线很长,负载很大。我建议在字线末端加 repeater,不然信号爬坡太慢。
  • 时序匹配:字线开启时间不能太短,否则存储单元读不出来;也不能太长,否则会写干扰。
⚠️ 我曾经在一个项目中,因为字线脉冲宽度设得太窄,导致读操作时存储单元里的数据还没完全传到位线上就被关闭了。结果整个芯片读出来的数据全是乱的。排查了整整两天才找到问题。

行译码器的基本电路就是NAND+INV的组合。对于n位地址,用2^n个NAND门,每个门接不同的地址组合。然后加一级驱动buffer。

// 以3-8译码器为例
// 输入:A[2:0]
// 输出:WL[7:0]
// 每个WL对应一个地址组合

assign WL[0] = ~A[2] & ~A[1] & ~A[0];
assign WL[1] = ~A[2] & ~A[1] &  A[0];
// ... 以此类推

4.2 列译码器:选通位线

行译码器选通一行后,这一行所有存储单元都会把数据放到各自的位线上。但一次我们只需要读一个或几个bit。列译码器就是干这个的——从多列中选出目标列。

设计要点:

  • 列选择信号:通常用传输门或三态门实现。列选通时,把该列的位线连接到全局数据线上。
  • 位线负载:每根位线上挂了很多存储单元,寄生电容很大。列译码器要尽量减小对位线的额外负载。
  • 多路选择:如果数据宽度是8位,那列译码器要同时选通8列。这时候要注意各列之间的匹配。

嗯,这里要注意:列译码器的速度通常不是瓶颈,因为位线已经由灵敏放大器放大了。但它的面积和功耗需要关注。

4.3 灵敏放大器:读出数据的核心

这是SRAM里最精妙的部分。为什么需要它?因为存储单元读出的信号非常微弱。一个6T单元,读操作时位线上的电压摆幅可能只有100-200mV。你直接用逻辑门去判断,根本识别不了。

灵敏放大器就是一个高增益、低失调的差分放大器。它把位线上的微小电压差放大到满摆幅的CMOS电平。

设计要点:

  • 差分输入:位线BL和BLB是一对差分信号。灵敏放大器比较这两个信号的差值。
  • 使能信号:SAE(Sense Amplifier Enable)控制灵敏放大器的工作时机。必须在位线电压差建立到足够大之后再开启。
  • 锁存型结构:现代SRAM多用锁存型灵敏放大器。它既有放大功能,又有锁存功能,可以节省一级寄存器。
💡 我个人的经验:灵敏放大器的失调电压一定要小。如果失调太大,可能把0误判成1。在工艺角仿真时,一定要跑蒙特卡洛分析,看看失调分布是否在可接受范围内。

一个典型的锁存型灵敏放大器电路如下:

// 简化模型
// BL, BLB: 位线差分输入
// SAE: 使能信号
// Q, QB: 输出

always @(posedge SAE or negedge SAE) begin
    if (SAE) begin
        // 放大阶段
        Q  <= (BL > BLB) ? 1 : 0;
        QB <= (BL > BLB) ? 0 : 1;
    end else begin
        // 预充电阶段
        Q  <= 0;
        QB <= 0;
    end
end

4.4 写驱动器:写入数据的保障

写操作和读操作完全不同。读操作是存储单元把数据推到位线上,写操作是外部数据强行写入存储单元。写驱动器就是负责这个「强行写入」的模块。

设计要点:

  • 驱动强度:写驱动器必须能克服存储单元中交叉耦合反相器的反馈。说白了,你要有足够大的电流把存储节点拉到目标电平。
  • 写掩码:有些设计支持按字节写入,这时候写驱动器要能独立控制每一列的写入使能。
  • 写辅助电路:在先进工艺下,写操作越来越困难。常用写辅助技术包括:降低位线电压、提高字线电压、或者用负压技术。
⚠️ 我曾经遇到过一个案例:写驱动器的尺寸设计得太小,导致写入时无法翻转存储单元的状态。特别是在低电压下,这个问题更严重。后来我们把写驱动器的W/L增加了30%,问题才解决。

写驱动器的基本结构就是一对互补的驱动管,分别连接BL和BLB。写入时,一个拉高,一个拉低,形成差分驱动。

// 写驱动器控制逻辑
// Data: 要写入的数据
// WE: 写使能
// BL, BLB: 位线

assign BL  = WE ?  Data : 1'bz;
assign BLB = WE ? ~Data : 1'bz;

4.5 整体架构与设计权衡

这四个模块不是孤立的。它们之间有很多交互和权衡。

关键权衡点:

  • 速度 vs 面积:行译码器用更复杂的预译码可以提高速度,但面积会增大。
  • 功耗 vs 性能:灵敏放大器开启时间越长,读可靠性越高,但功耗也越大。
  • 写能力 vs 读稳定性:存储单元的尺寸设计需要在写入能力和读稳定性之间平衡。写驱动器太强可能影响读操作。

下面这张图展示了SRAM读操作时各模块的时序配合:

SRAM读操作时序图 CLK Addr 有效地址 有效地址 WL 字线选通 字线选通 BL/BLB 电压差建立 电压差建立 SAE 放大 放大 Q 数据有效 地址建立 译码延迟 单元读出 SA开启 时钟高电平 地址有效 字线选通 灵敏放大

从时序图可以看出,整个读操作是流水线式的。地址先建立,然后行译码器选通字线,存储单元把数据放到位线上,位线电压差建立后,灵敏放大器使能,最后数据输出。

写操作类似,只是把灵敏放大器换成了写驱动器。写驱动器在字线选通的同时,把数据强行写入存储单元。

💡 我建议你在设计SRAM时,先把这四个模块的时序约束搞清楚。用Spice跑一下关键路径的延迟,看看有没有时序违规。特别是读操作,从地址变化到数据输出,这个延迟决定了SRAM的最高工作频率。

好了,关于SRAM架构设计的核心模块就讲到这里。这四个模块看似简单,但每个都有很多设计细节和坑。希望今天的分享能帮你少走一些弯路。


专注资料整理