计数器设计
什么是计数器
计数器顾名思义就是用来计数的电路。它能够记录输入脉冲(通常是时钟脉冲)的数量,并将计数值以二进制或其他编码形式(如BCD码)存储起来。当计数值达到某个预设的最大值时,计数器会回到初始状态(通常是0),并继续计数。
计数器的主要功能
-
事件计数: 最直接的功能,用来计算发生了多少个特定事件(如,某个按钮被按下了多少次,或者数据包通过了多少个时钟周期)。
-
分频: 可以将高频时钟信号分频为较低频率的信号,例如,一个每计数到 N 就翻转一次输出的计数器,可以实现 N 分频。
-
定时: 通过计数固定频率的时钟脉冲,可以实现精确的延时或定时功能。
-
序列发生器: 可以按照特定的顺序产生一系列二进制值,用于控制其他电路的动作。
-
地址生成器: 在存储器控制器中,计数器常用来生成连续的存储器地址。
-
状态机: 虽然不是计数器本身,但计数器经常作为状态机内部的辅助逻辑,例如用于控制某个状态的持续时间。
计数器的分类
-
按计数方式分类:
- 加法计数器:每次计数器加1
- 减法计数器:每次计数器减1
- 可逆计数器:每次计数器加1或减1
- 环形计数器:每次计数器加1或减1,当计数器达到最大值时,再从最小值开始计数
-
根据时钟同步方式:
- 同步计数器(Synchronous Counter): 所有的触发器(FF)都使用同一个时钟信号的同一个边沿(例如上升沿)进行触发,因此所有位的状态同时改变。这是FPGA设计中推荐和常用的类型,因为它具有更好的时序特性,不易产生毛刺。
- 异步计数器(Asynchronous Counter / Ripple Counter): 计数器中的低位触发器的输出作为高位触发器的时钟输入。这种设计简单,但由于存在传播延时,不同位的状态改变不是严格同步的,可能产生毛刺,不适用于高速和复杂的时序电路。
-
根据计数进制:
- 二进制计数器: 以二进制形式计数,例如4位二进制计数器可以从0000计数到1111(即0到15)。
- BCD计数器(十进制计数器): 以十进制形式计数,每4位二进制表示一个十进制数字,从0000到1001(即0到9),然后进位。
计数器的结构
计数器即为加法器、比较器、寄存器以及选择器构成,如下图所示:

计数器的设计实现
计数器设计10步法:
- 计数器考虑三要素:初值、加 1 条件和结束值
- 计数器初值必须为 0
- 使用某一个计数值,必须同时满足加 1 条件
- 结束条件必须满足加 1 条件,且结束值是 N - 1(N 是计数器的计数最大值)
- 取某个数时,assign 的形式是:
(加1条件)&& (计数器值N - 1) - 计数结束后必须清零
- 如果要限定范围,推荐使用
>= 和 < - 设计步骤是先写计数器的 always 段,条件用名字代替,然后用 assign 写加 1 条件,最后用 assign 写结束条件
- 加 1 条件必须和计数器严格对齐,其他信号一律和计数器对齐
- 命名必须符合规范,加 1 条件前缀为“cnt_add”,结束条件前缀为“cnt_end”