学习 › 第 10 讲
计数器与移位寄存器:分步设计
阅读约 7 分钟 · bitGateLab 团队
计数器是一组触发器,每来一个时钟脉冲就按固定的顺序走过一系列状态;寄存器也是一组触发器,用来保存或移动一个二进制字。利用它们可以测量时间、分频、把数据从串行转换为并行,以及产生控制序列。学习本文之前,你需要熟悉 D、JK 和 T 触发器及其激励表,这些内容见锁存器与触发器一文。
异步(行波)计数器
最简单的计数方法是把若干 T = 1 的 T 触发器串接起来,让每个触发器都翻转,把频率除以 2。只有第一个触发器接系统时钟;后面的每个触发器都以前一个触发器的输出作为时钟。使用下降沿触发的触发器时,把一级的 Q 接到下一级的时钟,计数器就做加法计数(向上计数);使用上升沿触发的触发器时,要用 Q 才能做加法计数(用 Q 则做减法计数)。
它的缺点是延迟会累积:第 n 级要等前面所有级都变化之后才变化,就像一道波沿着链路传过去。在这段时间里,输出会经过一些错误的值。
例:4 位异步计数器,每个触发器的 tCQ = 12 ns。它从 0111 变到 1000。
- 12 ns 时 Q0 由 1 变为 0:输出读作 0110。
- 24 ns 时 Q1 变化:0100。
- 36 ns 时 Q2 变化:0000。
- 48 ns 时 Q3 变化:1000,即正确的值。
在这 48 ns 内,输出先后显示了 0110、0100 和 0000。如果有电路对这些值进行译码,就会看到虚假的脉冲。要想每次都读到稳定的值,时钟周期必须大于 48 ns,即 f < 20.8 MHz。
同步计数器
在同步计数器中,所有触发器接同一个时钟,由逻辑电路决定哪一位翻转。在二进制加法计数器中,当所有比它低的位都为 1 时,某一位才翻转:
T0 = 1, T1 = Q0, T2 = Q0·Q1, T3 = Q0·Q1·Q2
所有输出一起变化,都发生在时钟沿之后 tCQ 的时刻。最小周期不再因为触发器串成一条链而取决于位数,而是取决于 tCQ + AND 门的延迟 + tsu。
模 N 计数器
模 N 计数器走过 N 个状态后重新开始。它至少需要 ⌈log2 N⌉ 个触发器。实现方法有两种。
用异步复位:取一个二进制计数器,检测第一个不应出现的状态。对于模 10 计数器,这个状态是 1010;只需把 Q3 和 Q1 接到一个 NAND 门,再把它的输出接到低电平有效的清零端即可,因为这是 Q3 和 Q1 第一次同时为 1。这样做可行,但状态 1010 会出现几纳秒,并在输出上产生一个窄脉冲。
同步设计:写出状态表,再用激励表求出各输入。这样就没有过渡状态。
例:用 T 触发器设计同步模 6 计数器(0 到 5)。状态为 Q2 Q1 Q0;状态 110 和 111 不使用,按 X 处理。
| Q2 Q1 Q0 | 次态 | T2 | T1 | T0 |
|---|---|---|---|---|
| 000 | 001 | 0 | 0 | 1 |
| 001 | 010 | 0 | 1 | 1 |
| 010 | 011 | 0 | 0 | 1 |
| 011 | 100 | 1 | 1 | 1 |
| 100 | 101 | 0 | 0 | 1 |
| 101 | 000 | 1 | 0 | 1 |
当某一位要改变时,对应的 T 为 1。利用 X 化简:
- T0 = 1。
- T1 = Q2·Q0(覆盖 001 和 011;在 101 时为 0,因为 Q2 = 1)。
- T2 = Q1·Q0 + Q2·Q0 = Q0·(Q1 + Q2)。
检查未使用的状态:从 110 出发,T2 = 0,T1 = 0,T0 = 1,计数器进入 111;从 111 出发,T2 = 1,T1 = 0,T0 = 1,进入 010。两者都能回到计数序列:即使上电时处于无效状态,计数器也能自启动。
移位寄存器
移位寄存器就是串接起来的 D 触发器:每个触发器的输出接到下一个触发器的输入,每来一个时钟沿,所有的位都前进一个位置。按数据输入和输出的方式,可分为以下几类:
- SISO(串行输入,串行输出):把信号延迟 n 个时钟周期。
- SIPO(串行输入,并行输出):逐位接收数据,再一起输出。实现串行到并行的转换。
- PISO(并行输入,串行输出):一次装入一个完整的字,再逐位移出。每个触发器的输入端都有一个 2 选 1 MUX:
Di = LOAD·Pi + LOAD·Qi−1。 - PIPO(并行输入,并行输出):就是一个简单的存储寄存器。
例:4 位 SIPO 寄存器,初始为 0000,Q0 ← 输入,Q1 ← Q0,Q2 ← Q1,Q3 ← Q2。依次送入 1、0、1、1 这几位。
| 时钟沿 | 输入位 | Q0 Q1 Q2 Q3 |
|---|---|---|
| 1 | 1 | 1 0 0 0 |
| 2 | 0 | 0 1 0 0 |
| 3 | 1 | 1 0 1 0 |
| 4 | 1 | 1 1 0 1 |
4 个时钟沿之后,按 Q3 Q2 Q1 Q0 的顺序读,寄存器的内容是 1011:最先送入的那一位到了 Q3。
环形计数器和约翰逊计数器
如果把移位寄存器最后一个触发器的输出接到第一个触发器的输入,就得到环形计数器。初始化时只置入一个 1(例如 1000),这个 1 就循环移动:1000、0100、0010、0001、1000。n 个触发器有 n 个状态,而且每个状态本身就是译码好的,因为只有一个输出为 1。必须保证初始装入;如果它从 0000 启动,就会永远停在那里。
如果反馈回去的不是最后一个触发器的 Q 而是 Q,就得到约翰逊计数器(也叫扭环形计数器),它有 2n 个状态。对于 4 位(Q0 Q1 Q2 Q3,其中 Q0 ← Q3):
0000 → 1000 → 1100 → 1110 → 1111 → 0111 → 0011 → 0001 → 0000
每个状态只需一个两输入 AND 门就能区分出来,方法是看 1 和 0 的分界在哪里:例如 1100 是唯一满足 Q1 = 1 且 Q2 = 0 的状态,0000 是唯一满足 Q0 = 0 且 Q3 = 0 的状态。
常见错误
- 用组合逻辑对异步计数器的输出译码,却没有考虑过渡状态。
- 在上升沿触发的异步计数器中,级间接的是 Q 而不是 Q,结果得到一个减法计数器。
- 忘了检查模 N 计数器中未使用的状态会转到哪里。
- 启动环形计数器时没有装入初始的那个 1。
- 读 SIPO 寄存器时把位的顺序弄错:最先进入的那一位最终到达最远的一端。
在模拟器中试一试
在时序图上比较异步计数器和同步计数器,是观察行波效应的最好办法。
- 放置四个 T = 1 的 T 触发器,把时钟接到第一个,其余的串接成异步计数器。
- 把四个输出接到指示灯,并接到一个显示器或 LED 条。
- 在它旁边搭出同步计数器,令 T1 = Q0,T2 = Q0·Q1,T3 = Q0·Q1·Q2,全部使用同一个时钟。
- 打开时序图,让时钟运行,观察两者从 0111 到 1000 的跳变。
- 把四个 D 触发器串接成寄存器,在每个时钟沿之前改变串行输入,观察各位如何前进;然后把最后一级的 Q 反馈到第一级,验证约翰逊计数器的 8 个状态。
练习
- 模 12 计数器分别采用二进制计数器、环形计数器和约翰逊计数器时,各需要多少个触发器?
答案
二进制:4 个(24 = 16 ≥ 12)。环形:12 个。约翰逊:6 个(2 × 6 = 12)。
- 要用一个 4 位二进制计数器加低电平有效的异步复位做成模 12 计数器,应使用什么门、接哪些输出?
答案
12 = 1100。用一个 NAND 门接 Q3 和 Q2,其输出接到清零端,因为这是两者第一次同时为 1。
- 一个 8 位异步计数器使用 tCQ = 10 ns 的触发器。最坏情况下的稳定时间是多少?
答案
8 × 10 = 80 ns,例如从 01111111 变到 10000000 时。
- 用哪个两输入 AND 门可以译出 4 位约翰逊计数器的状态 0111?
答案
Q0·Q1:它是唯一满足 Q0 = 0 且 Q1 = 1 的状态。