4 位计数器:从 0 到 15 的高效二进制计数
4 位计数器从 4'b0000 递增至 4'h1111,然后回滚到 4'b0000。只要提供运行时钟且复位保持高电平,它将持续计数。
回滚发生在最终加法的最高有效位被丢弃时。当计数器达到最大值 4'b1111 并再收到一个计数请求时,计数器试图达到 5'b10000,但因只支持 4 位,最高位被丢弃,结果变为 0。
0000 0001 0010 ... 1110 1111 回滚 0000 0001 ...
设计包含两个输入:一个用于时钟,另一个用于低电平有效复位。低电平有效复位指复位引脚为 0 时复位生效。有一个 4 位输出 out 提供计数器值。
电子计数器设计
module counter (
input clk, // 时钟输入,允许计数器向上计数
input rstn, // 低电平有效复位输入,需要时将计数器复位为 0
output reg[3:0] out // 4位输出端口,输出计数器值
);
// 此 always 块在时钟上升沿(0->1)触发
// 进入块后,检查复位是否为 0,若是则将 out 置 0
// 若复位为 1,则允许向上计数,递增计数器
always @ (posedge clk) begin
if (! rstn) out <= 0;
else out <= out + 1;
end
endmodule
module counter 拥有时钟和低电平有效复位(用 n 表示)作为输入,计数器值作为 4 位输出。always 块在时钟从 0 变为 1 时 总是 执行,表示上升沿或正边沿。仅当复位保持高电平(1)时输出递增,由 if-else 块实现。若在时钟上升沿检测到复位为低,则输出复位为默认值 4'b0000。
测试平台
我们可以将设计实例化到测试平台模块中,验证计数器是否按预期计数。
测试平台模块命名为 tb_counter,作为仿真顶层模块无需端口。但需要内部变量生成、存储和驱动时钟与复位。为此声明两个 reg 类型变量用于时钟和复位。还需要 wire 类型网线连接设计输出,否则将默认为 1 位标量网线。
时钟通过 always 块生成,周期 10 个时间单位。initial 块用于设置内部变量初始值并驱动复位值给设计。设计在测试平台中 实例化 并连接到内部变量,以便从测试平台驱动值。测试平台中无 $display 语句,因此控制台无消息输出。
module tb_counter;
reg clk; // 声明内部 TB 变量 clk 驱动时钟给设计
reg rstn; // 声明内部 TB 变量 rstn 驱动低电平有效复位给设计
wire [3:0] out; // 声明 wire 连接设计输出
// 实例化计数器设计并连接测试平台变量
counter c0 (
.clk (clk),
.rstn (rstn),
.out (out)
);
// 生成驱动设计的时钟
// 此时钟每 5ns 翻转一次 -> 周期 = 10ns -> 频率 = 100 MHz
always #5 clk = ~clk;
// 此 initial 块构成测试平台激励
initial begin
// 1. 仿真开始时初始化测试平台变量为 0
clk <= 0;
rstn <= 0;
// 2. 驱动其余激励,中间复位置位
#20 rstn <= 1;
#80 rstn <= 0;
#50 rstn <= 1;
// 3. 200ns 后结束激励
#20 $finish;
end
endmodule
仿真日志
ncsim> run [0ns] clk=0 rstn=0 out=0xx [5ns] clk=1 rstn=0 out=0x0 [10ns] clk=0 rstn=0 out=0x0 [15ns] clk=1 rstn=0 out=0x0 [20ns] clk=0 rstn=1 out=0x0 [25ns] clk=1 rstn=1 out=0x1 [30ns] clk=0 rstn=1 out=0x1 [35ns] clk=1 rstn=1 out=0x2 [40ns] clk=0 rstn=1 out=0x2 [45ns] clk=1 rstn=1 out=0x3 [50ns] clk=0 rstn=1 out=0x3 [55ns] clk=1 rstn=1 out=0x4 [60ns] clk=0 rstn=1 out=0x4 [65ns] clk=1 rstn=1 out=0x5 [70ns] clk=0 rstn=1 out=0x5 [75ns] clk=1 rstn=1 out=0x6 [80ns] clk=0 rstn=1 out=0x6 [85ns] clk=1 rstn=1 out=0x7 [90ns] clk=0 rstn=1 out=0x7 [95ns] clk=1 rstn=1 out=0x8 [100ns] clk=0 rstn=0 out=0x8 [105ns] clk=1 rstn=0 out=0x0 [110ns] clk=0 rstn=0 out=0x0 [115ns] clk=1 rstn=0 out=0x0 [120ns] clk=0 rstn=0 out=0x0 [125ns] clk=1 rstn=0 out=0x0 [130ns] clk=0 rstn=0 out=0x0 [135ns] clk=1 rstn=0 out=0x0 [140ns] clk=0 rstn=0 out=0x0 [145ns] clk=1 rstn=0 out=0x0 [150ns] clk=0 rstn=1 out=0x0 [155ns] clk=1 rstn=1 out=0x1 [160ns] clk=0 rstn=1 out=0x1 [165ns] clk=1 rstn=1 out=0x2 Simulation complete via $finish(1) at time 170 NS + 0
注意:当低电平有效复位变为 0 时计数器复位为 0;当复位在约 150ns 释放时,计数器从下一个时钟上升沿开始计数。
硬件原理图
Verilog