一、时序逻辑基础

大家好,我是你们的讲师。今天咱们聊聊时序逻辑的基础。说实话,这是整个数字芯片设计的根基。你想想看,如果连组合逻辑和时序逻辑都分不清,那后面的设计基本就是空中楼阁。

什么是时序逻辑

时序逻辑,说白了就是带记忆功能的电路。它的输出不仅取决于当前输入,还取决于电路之前的状态。我刚开始学的时候,老师打了个比方:组合逻辑就像自动售货机,你投币它就出货,不投就不出;时序逻辑呢,更像一个计数器,你按一次按钮它加1,再按一次再加1——它记住了你按过几次。

从数学角度讲,时序逻辑的状态方程可以写成:

Q_next = f(Q_current, inputs)

这里的 Q_current 就是当前状态,Q_next 是下一个状态。这个「状态」的概念,是时序逻辑的核心。

核心要点:时序逻辑 = 组合逻辑 + 存储单元(触发器/锁存器)

组合逻辑 vs 时序逻辑

我整理了一个表格,方便大家对比:

对比项 组合逻辑 时序逻辑
输出依赖 仅当前输入 当前输入 + 历史状态
存储能力 有(触发器/锁存器)
时钟依赖 不依赖 通常依赖时钟
典型电路 加法器、多路选择器 计数器、状态机、寄存器
延迟特性 纯门延迟 时钟周期延迟

嗯,这里有个坑。我在项目中遇到过有人把组合逻辑的毛刺直接接到触发器的时钟端,结果芯片跑起来各种随机错误。后来查了三天才定位到问题——组合逻辑的输出不能直接当时钟用,除非你做了特殊处理。

同步电路与异步电路

这是另一个容易混淆的点。同步电路,所有触发器共享同一个时钟。异步电路呢,各个触发器的时钟可能来自不同源。

我个人习惯,能同步就同步。为什么?因为同步电路好分析、好验证、好综合。异步电路虽然在某些场景下能省功耗,但跨时钟域处理不好就是灾难。

避坑指南:我曾经在一个项目中,为了省一个PLL,把两个不同频率的时钟直接驱动到同一个模块里。结果仿真没问题,上板子就挂。后来发现是异步路径的时序约束没做对。从那以后,我只要看到异步设计,第一反应就是「你确定要这么做?」

同步电路的特点:

  • 所有触发器在时钟上升沿(或下降沿)同时更新
  • 时序分析相对简单,STA(静态时序分析)可以全覆盖
  • 综合工具优化效果好

异步电路的特点:

  • 不同时钟域之间需要同步器
  • 可能存在亚稳态问题
  • 调试难度大,我一般只在低功耗场景下才考虑

时钟信号与复位信号

时钟信号,是时序逻辑的「心跳」。没有时钟,触发器就不知道什么时候该干活。复位信号呢,是让电路回到一个已知的初始状态。

时钟的几个关键参数:

  • 频率:决定了电路能跑多快
  • 占空比:通常50%,但有些特殊场景需要非50%
  • 抖动(Jitter):时钟边沿的不确定性,我见过因为PLL抖动太大导致高速接口误码的案例
  • 偏斜(Skew):时钟到达不同触发器的延迟差异

复位信号分两种:

  1. 同步复位:只在时钟边沿生效
  2. 异步复位:立即生效,不依赖时钟

代码示例,同步复位 vs 异步复位:

// 同步复位
always @(posedge clk) begin
  if (rst_n)
    q <= 1'b0;
  else
    q <= d;
end

// 异步复位
always @(posedge clk or negedge rst_n) begin
  if (!rst_n)
    q <= 1'b0;
  else
    q <= d;
end

小技巧:我个人推荐使用异步复位、同步释放的方式。这样既能保证复位立即生效,又能避免复位撤销时的亚稳态问题。具体实现方法,后面章节会详细讲。

本章知识体系

下面我用一张图来总结本章的核心内容:

时序逻辑基础 - 知识体系 时序逻辑 组合 vs 时序 同步 vs 异步 时钟与复位 组合逻辑 输出仅依赖当前输入 无记忆能力 典型:加法器、MUX 时序逻辑 输出依赖历史状态 典型:计数器、状态机 同步电路 共享同一时钟 易分析、易验证 STA全覆盖 异步电路 多时钟域 需同步器处理 时钟信号 频率、占空比、抖动 偏斜(Skew) 时序逻辑的「心跳」 复位信号 同步复位 / 异步复位 异步复位同步释放

这张图把本章的知识点串起来了。你从上往下看,时序逻辑往下分三个方向,每个方向又有更细的内容。我建议你把这图存下来,后面学完所有章节再回来看,会有更深的理解。

本章小结:时序逻辑的核心是「记忆」。组合逻辑没有记忆,时序逻辑有。同步电路好做,异步电路要小心。时钟是心跳,复位是保险。这些概念搞清楚了,后面的内容就好办了。


公众号:蓝海资料掘金营,微信deep3321