FPGA刷题——计数器(简易秒表、可置位计数器、加减计数器)

继续牛客网刷题,这篇是计数器部分:

目录

简易秒表

可置位计数器

加减计数器


计数器是非常基本的使用,没有计数器就无法处理时序。

简易秒表

 这一题实现了秒和分的计数器,当秒计数器从1-60,分计数器+1,当分计数器=60,清零分计数器。用一段always就可以实现,代码如下:

module count_module(
	input clk,
	input rst_n,

    output reg [5:0]second,
    output reg [5:0]minute
	);
	


always@(posedge clk or negedge rst_n)begin
   if(rst_n == 1'b0)begin
       second <= 6'd0;
       minute <= 6'd0;
   end
   else begin
       if(minute==6'd59)begin
           minute <= 6'd60;
       end
       else if(second == 6'd60)begin
           second <= 6'd1;
           minute <= minute + 1'b1;
       end
       else begin
               second <= second + 1'b1;
               minute <= minute;
       end
   end
end

	
endmodule

这里需要注意的是计数器的初值,比如计数器60次一清零,如果清零时为计数器赋0,那么清零的条件应该写60-1(0~59是60个数)如果清零时为计数器赋1,那么清零的条件应该写60

可置位计数器

题目要求编写一个十六进制计数器,即输出数值number每次变化1,在0-15之间循环。输出set信号的值为一时,将输出数值num置为set_num。

module count_module(
	input clk,
	input rst_n,
	input set,
	input [3:0] set_num,
	output reg [3:0]number,
	output reg zero
	);
    reg [3:0]num;
    always @(posedge clk or negedge rst_n)
        if (!rst_n)
            begin 
                zero <= 1'd0;
            end
        else if (num == 4'd0)
            begin
                zero <= 1'b1;
            end
        else 
            begin  
                zero <= 1'b0;
            end
         
    always @(posedge clk or negedge rst_n)
        if (!rst_n)
            begin 
                num <= 4'b0;
            end
        else if(set)
            begin
                num <= set_num;
            end
        else 
            begin
                num <= num + 1'd1;
            end
 
    always @(posedge clk or negedge rst_n)
        if (!rst_n)
            begin 
                number <= 1'd0;
            end
        else 
            begin
                number <= num;
            end        
 
endmodule

加减计数器

题目要求编写一个十进制计数器,即输出数值number每次变化1,在0-9之间循环。根据mode信号的值,更改输出数值number的变化方向。当mode=1,计数器递增。当mode=0,计数器递减。可以将mode作为判断条件,使用if-else语句实现不同的变化方向。

注意,这一题的zero信号是用时序逻辑来赋值,利用number的过程值num进行判断;

  1. 题目的testbench要求输出都延后一个时钟,因此增加一个寄存器tmp来暂存计数。
  2. 根据mode来判断计数何时跳变;zero输出时刻在tmp为0的下一周期,因此用tmp==0来判断。
module count_module(
	input clk,
	input rst_n,
	input mode,
	output reg [3:0]number,
	output reg zero
	);
    
      reg [3:0]num;
    always @(posedge clk or negedge rst_n)
        if (!rst_n)
            begin 
                zero <= 1'd0;
            end
        else if (num == 4'd0)
            begin
                zero <= 1'b1;
            end
        else 
            begin  
                zero <= 1'b0;
            end
         
    always @(posedge clk or negedge rst_n)
        if (!rst_n)
            begin 
                num <= 4'b0;
            end
        else if(mode)
            begin
                if(num == 9)
                    num <= 0;
                else
                    num <= num + 1'd1;
            end
        else if(!mode)
            begin
                if(num == 0)
                    num <= 9;
                else
                    num <= num - 1'd1;
            end
        else num <= num;
         
    always @(posedge clk or negedge rst_n)
        if (!rst_n)
            begin 
                number <= 4'd0;
            end
        else 
            begin  
                number <= num;
            end
    
    
endmodule

从上面三道题可以看出,计数器基本都使用 if-else 语句进行实现,使用if-else语句时,要注意代码是从上到下执行,如果if里面的语句可以实现,就不会跳转到else,因此,应该把条件判断的部分(不容易实现的部分)写在最前面,以此类推。

  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值