数字电路基础---计数器

目录

数字电路基础---计数器

1、计数器简介

2、实验任务

3、程序设计

3.1、模块设计

3.2、绘制波形图

3.3、编写代码

3.4、仿真验证

3.4.1、编写 TB 文件

3.4.2、仿真验证

4、本章总结

5、拓展训练


数字电路基础---计数器

       计数器是逻辑设计中非常常用的一个时序电路,计数器是由寄存器和加法器组成的,使用计数器可以实现使用计数器可以对脉冲的个数计数,以实现测量、计数、分频和控制的功能。

1、计数器简介

       计数是一种最简单基本的运算,计数器就是实现这种运算的逻辑电路。下面我们以一个 3 位计数器来学习下计数器的基本组成和相关知识,首先我们画出 3 位计数器的电路结构图。

       这个 3 位计数器的电路图相对之前我们学习的逻辑有点复杂,我们以 F1F2F3 代表 3 D 触发器,两个异或门 G1G2 1 个与门 G3 来进行说明计数器是如何工作的。一般触发器是有复位信号(图中没有画出),在上电复位之后,电路上电的 Q0 Q1 Q2 初始状态是 000,下面我们来看下这三个 D 触发器此时的输入信号是什么。

       我们先看 F1F1 的输入信号 D,是由 Q0 反馈回来的,我们已知此时的 Q 0,那么`Q 就是 1,这个 1 反馈给 F1 输入信号 D,此时 F1 的输入信号就是 1

      下面我们再来看 F2F2 的输入信号是 Q0 Q1 的值经过一个异或门之后得到的,我们已知此时的Q0 是 0Q1 也是 0,那么这两个 0 经过异或门逻辑处理(异或门两个输入信号值相同输出 0,不同输出1)后就是 0 了,因此 F2 的输入信号也是 0

      再看 F3F3 的输入信号是由 Q0 Q1 经过一个与门之后的输出值,与 Q2 的值相异或得到的,我们来看,Q0 Q1 都是 0,两个 0 相与,输出肯定还是 0,这个输出的 0,再与 Q2 的值相异或,根据异或门的规律,两个输入现在都是 0,那么异或门的输出也是 0F3 的输入此时就是 0

       到这里,我们已经分析出了 F1F2 F3 这三个触发器此时的输入值了,下面我们就可以根据 D触发器的逻辑规律知道下一刻电路的输出值了,现在我们给 CLK 端口一个上升沿,也就是 CLK 0 变为 1了,那么 3 个边沿 D 触发器将会同时触发,当 CLK 这个时钟信号的上升沿到来时,D 触发器的输入值将会被锁存,根据逻辑规律,下一刻 3 D 触发器的输出值就分别为 100。这里如果我们把 Q2 的值当做二进制数的最高位,把 Q0 的值当做二进制数的最低位,那么现在计数器所输出的值,就是二进制数 001,也就是十进制的 1。计数器接收到第一个时钟信号的上升沿后,计数器就输出二进制数 001,依次类推,如果第二个时钟信号的上升沿到来时,这个时候计数器将会输出二进制数 010,也就是十进制数 2,每当电路多到来一个时钟上升沿,计数器就会作加 1 运算。当电路计到第 8 个脉冲时,电路状态将由 111 又变为 000,完成一个循环周期,所以该电路也称为模 8 同步加法计数器。所谓同步就是指该电路中的四个边沿型 D 触发器共用一个时钟脉冲 CLK,当时钟上升沿到来时,它们能够同时触发。

       讲到这里,大家应该已经了解了计数器的工作原理了,下面我们根据上面的分析,画出 3 位加法计数器的特性表,如下图所示。

       由计数器真值表可以看出,每个时钟上升沿之后,计数器的值就加 1,当经过 8 个时钟周期之后,计数器计数从 111 溢出到 000,然后依次循环往复的计数。

2、实验任务

本节的实验任务是使用 Verilog 语言设计一个 3bit 的计数器电路。

3、程序设计

3.1、模块设计

       本次实验是设计一个 3bit 的计数器,所以我们将模块名命名为 counter。因为是时序逻辑电路,所以输入肯定有时钟和复位,输出为一个 3bit 的计数器,模块框图如下图所示:

 模块端口与功能描述如下表所示:

3.2、绘制波形图

       根据计数器的电路图、真值表以及模块框图,我们可以知道每当一个周期的到来时,寄存器就会累加 1。由此绘制出计数器模块的波形图如下图所示:

由上图可知,cnt循环从0计数到7,每当计数器计数到最大值时,就会从零开始重新累加。

3.3、编写代码

根据上一小节的波形图,可以使用 Verilog 编写一个计数器(counter.v)代码,代码如下:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/06/19 15:53:23
// Design Name: 
// Module Name: counter
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//
//实验任务
//使用 Verilog 语言设计一个 3bit 的计数器电路。

module counter(
    input               sys_clk,
    input               sys_rst_n,
    
    output reg [2:0]    cnt
    );

always@(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)
        cnt <= 3'd0;
    else
        cnt <= cnt + 3'd1;
end

endmodule

       程序中第 28 行定义了一个 3bit cnt,当 cnt 计数到 3bit 的最大值之后进行清零,然后进行循环的累加操作。

3.4、仿真验证

3.4.1、编写 TB 文件

       计数器模块的输入端口只有时钟和复位,因此计数器 TB 模块(tb_counter.v)只需要对时钟以及复位信号进行激励即可,仿真代码编写如下:

`timescale 1ns / 1ps          //仿真单位/仿真精度
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/06/19 16:00:22
// Design Name: 
// Module Name: tb_counter
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module tb_counter();

//parameter define
parameter T = 20;   //50MHz系统时钟(一个周期是20ns:1/50MHz=0.02us=20ns)
//parameter T = 5;   //黑金FPGA-xc7a5tfgg484-2-时钟周期为5ns 
//200MHz系统时钟(一个周期是5ns:1/200MHz=0.005us=5ns)

reg           sys_clk;
reg           sys_rst_n;

wire  [2:0]   cnt;

initial begin
    sys_clk = 1'b1;
    sys_rst_n <= 1'b0;
    #201
    sys_rst_n <= 1'b1;
end

always #(T/2) sys_clk <= ~sys_clk;

counter counter_inst(
    .sys_clk       (sys_clk    ),
    .sys_rst_n     (sys_rst_n  ),
  
    .cnt           (cnt        )
);

endmodule

3.4.2、仿真验证

接下来打开 Modelsim 软件对代码进行仿真,在运行仿真 10us 后,仿真的波形如下图所示:

       由上图可以看出,仿真波形与我们绘制的波形图是一致的,说明我们本次设计的3bit计数器代码是没有问题的。

4、本章总结

       本章主要讲解了在后续学习和设计中最常使用的计数器,通过本章的例子,我们掌握了计数器的设计方法,希望大家能够通过后面章节的训练熟练掌握计数器的使用。

5、拓展训练

       对现有例程稍作修改,设计一个 1 秒钟的计数器。这里提醒一下,我们板载的晶振是 50Mhz。我们计数的时钟就是 50MHz,换算成时间为[1/(50*10^6)Hz]s = 0.000_000_02s,也就是说 50MHz 频率的时钟一个周期的时间为 0.000_000_02s,那么 1 秒钟需要 50_000_000(1/0.000_000_02s)个脉冲周期,所以我们的计数器需要在 50MHz 的时钟下计 50_000_000 次。

(见: Vivado 下 LED 流水灯实验_OliverH-yishuihan的博客-CSDN博客 中 “3.2、程序设计” )

  • 8
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
自1.6版以后,增加了表达式计算的功能,从此可以进行复杂的公式计算,如输入以下公式“2+(18-10)/7^2+sin(1)+sqrt(sqrt(5),3)*2”,按下计算按钮或回车会自动得出最终结果。另外增加了一个“单步求解”的选项,可以一步一步显示出公式的计算过程。支持各种三角函数,运算的结果可选择弧度或角度值,这取决于计算器的角度|弧度按钮选择。打开表达式计算的功能步骤是:鼠标右键单击液晶屏幕,在弹出的菜单中选择“* 表达式(公式)计算 *”一项,即可打开该功能。(注:表达式功能不能在小窗口状态下使用),另外,v1.6版还改进了许多以前版本中不方便或有BUG的地方,使用更加方便!增加了十几种三角函数运算(包括各种双曲正弦、余弦、正割、余割等等以及相关反函数),加入了角度与弧度计算,加入了位移指令,增加了各种常用常数表,使用户在计算一些常用公式时,不必再去翻书查找。加入了各种单位换算,单位换算与屏幕计算结果实时换算,并可实时改变换算单位。并修改了数据转换为"人民币中文大写形式、人民币数字形式(例如:1435.75、人民币壹仟肆佰叁拾伍圆柒角伍分、¥1435.75)的一些BUG,大大方便了财务、票据等方面的工作,输入的任何数据和计算结果可自动输入在其它程序窗口当前光标位置,就像和其它程序融为一体一样。如果用户经常在应用软件中做计算输入工作(例如各种文字处理、制表、工程计算、股票等等一切需要输入计算数据和结果的地方。),那么这个功能将使工作变得非常方便!(如果不需要这项功能,鼠标右键单击液晶屏幕,在弹出的菜单中取消“数据自动输入其它窗口”一项即可!)。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值