计数器简介以及FPGA实现

在时序逻辑电路中,最基本的单元是寄存器,本篇将会介绍如何利用寄存器,实现一个具有计数器功能的电路。在FPGA开发中,一切与时间有关的设计都会用到计数器,所以学会设计计数器至关重要。

一、计数器介绍

计数是一种最简单基本的运算,计数器就是实现这种运算的逻辑电路,计数器在数字系统中主要是对脉冲的个数进行计数,以实现测量、计数和控制的功能,同时兼有分频功能。

计数器在数字系统中应用广泛,如电子计算机的控制器中对指令地址进行计数,以便顺序取出下一条指令,在运算器中作乘法、除法运算时记下加法、减法次数,又如在数字仪器中对脉冲的计数等等。

二、绘制计数器时序图

在代码编写之前,我们先利用visio把时序图绘制出来,编写代码时思路会更清晰

初次使用visio绘制时序图,需要事先下载三个形状,分别是FPGA_DESIGN、状态机形状和逻辑图形状。

 下载好形状开始波形图绘制,如下图所示:

 实际上,我们只需要计数器技术范围是0到M/2-1即可,因为我们可以控制LED灯在计数器一个计数周期结束时电平进行翻转。这样做也能够节省1bit的硬件资源,改进后的时序图如下:

tips:分享几个使用visio绘图的快捷键

ctrl+滚轮:放大或缩小界面

shift+移动箭头:微量移动

ctrl+分别选中:合并选中

ctrl+拖动选中的内容:快速复制选中的内容到指定位置

三、ISE仿真实现(附verilog代码)

module counter
#(
	parameter	CNT_MAX = 25'd24_999_999
)
(
	input	wire	sys_clk		,
	input	wire	sys_rst_n	,

	output	reg		led_out
 );

reg		[24:0]		cnt;
always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n == 1'b0)
		cnt <= 25'd0;
	else	if(cnt == CNT_MAX)
		cnt <= 25'd0;
	else
		cnt <= cnt + 25'd1;
		
always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n == 1'b0)
		led_out <= 1'b0;
	else if (cnt == CNT_MAX)
		led_out <= ~led_out;
	else
		led_out <= led_out;
		
endmodule

仿真代码:1、定义输入输出信号 2、初始化输入信号。模拟复位信号、时钟信号,使用initial语句对其进行赋值 3、实例化

`timescale 1ns / 1ns
module tb_counter();
	// Inputs
	reg sys_clk;
	reg sys_rst_n;

	// Outputs
	wire led_out;

	initial 
		begin
			sys_clk = 1'b1;
			sys_rst_n <= 1'b0;
			#20;
			sys_rst_n <= 1'b1;
		end
		
	always #10 sys_clk = ~sys_clk;
		
	counter 
	#(
		.CNT_MAX(25'd24)
	)
	uut //实例化名称要写在端口前边
	(
		.sys_clk(sys_clk), 
		.sys_rst_n(sys_rst_n), 
		.led_out(led_out)
	);
      
endmodule

四、仿真结果

 分析:

1、时钟频率是50MHZ   

2、每过一个时钟周期,计数器加1,计数器周期是24   

3、计数器达到最大值24时,输出信号进行翻转

满足设计要求

 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值