1、介绍
计数器是数字电路中的一种基本元件,用于按特定顺序对事件进行计数。它通常由触发器(如 D 触发器或 JK 触发器)构成,能够在时钟信号的作用下,将输入的脉冲转换为二进制数值。计数器可以是向上计数(递增)或向下计数(递减),也可以是可逆计数(既可以递增也可以递减)。广泛应用于时钟分频、事件计数、频率计等各种数字系统中。根据设计需求,计数器还可以是同步或异步的,具备不同的计数范围和特性。
学过 51 或者其他单片机的小伙伴应该知道定时器的基本原理就是计数器,比如我一个周期需要 20ns,而我需要定时 1ms,那么我可以通过计算所需的计数次数(50,000次)来设置定时器。计数器在实际应该中是最常用的电路之一。
2、实战任务
设计一个 2bit 的计数器电路,模拟定时器的工作原理。
3、系统框图
根据实战任务要求来设计一个 2bit 的计数器。输入为 CLK 时钟(来模拟计数的脉冲,在上升沿的时候开始计数),输出为一个count(2bit) 的计数器,模块框图如下图所示:
4、波形图
根据计数器的工作原理和实战要求,我们知道每当时钟的上升沿的到来时,寄存器(count)就会累加一。则计数器的波形图如下所示:
由上图可知,计数器从 0 开始循环计数到 3。当计数器达到最大值后,它会自动从零重新开始累加。这种自动清零的机制源于我们将 count 的位宽设置为 2,因为 2^2 的最大值为 4,而计数是从 0 开始的。当计数器计数到 3 后,下一次计数会是 4,其二进制表示为 100。由于 count 的位宽为 2,只会保留最后两位,因此 100 的最后两位是 00,这使得 count 的值重置为 0。
5、程序编写
module count (
input clk, // 输入时钟信号
output reg [1:0] counter // 2 位输出计数器
);
always @(posedge clk) begin
counter <= counter + 2'd1; // 计数器加 1,每次时钟上升沿增加 1
end
endmodule
2
3
4
5
6
7
8
9
10
11
程序注释:
第 1 - 5 行:根据计数器的功能定义,输入信号,脉冲 clk ,输出信号分别为两位宽的信号 counter ,用于计数器计数。
第 7 - 9 行:每来一个脉冲,计数器的值加一
6、仿真编写
`timescale 1ns/1ns // 设置仿真时间单位和时间精度为 1 纳秒
module count_mod();
//reg define
reg clk;
always #10 clk = ~clk;
//初始化输入信号
initial begin
clk = 1'd0; //初始化时钟信号
#200;
end
count u_count (
.clk (clk ) // 输入时钟信号
);
endmodule
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
程序注释:
第 5 行:功能定义,重新定义使用的信号。
第 7 行:这里是产生一个计数脉冲。
第 10 - 15 行:这里主要是将 计数脉冲 进行初始了。
第 17 - 19 行:进行I/O绑定,例化。
由于仿真时信号需要具体化,否则仿真出来的信号会出现高阻(Hiz),为了防止这种情况出现,我们需要将 count.v 进行修改:
module count (
input clk // 输入时钟信号
);
reg [1:0] counter = 2'd0;// 2 位输出计数器
always @(posedge clk) begin
counter <= counter + 2'd1; // 计数器加 1,每次时钟上升沿增加 1
end
endmodule
2
3
4
5
6
7
8
9
10
11
7、工程创建
开始使用 Gowin 创建项目工程了,接着在 Gowin 的 Design 窗口空白地方右键点击选择 Add Files... 添加文件,分别创建所需的文件 count.v 和 count_mod.v ,如下图所示:
添加完对应程序后,然后开始仿真,新建工程将 Project_Name 和 Default Library Name 都改成 count 名称,如下图所示:
分别添加我们仿真所需的文件 count.v和 count_mod.v,如下图所示:
接下来选择 Compile->Compile All ,编译没有问题后,在 Add Simulation Configuration 配置好对应的文件,如下图所示:
仿真结果如下:
由上面的仿真图,可以看出与我们的波形图的结果是一致的,证明我们的程序没有问题。
8、RTL 原理图
接下来在过程管理窗口 Process > Place & Route > Run,来对代码布局布线进行综合(如果前面没有执行 Synthesize 编译,直接执行这个,编译器会自动执行前面的内容),如下图所示:
再点击 tools -> Shematic Viewer -> RTL Design Viewer 然后查看 RTL 电路图,如下图所示:
然后查看 RTL 电路图,在软件里 半加器 是怎样的,如下图所示: