Verilog HDLBits 第十二期:3.2.2 Counters

目录

前言

3.2.2.1 Four-bit binary counter(Count15)

Solution:

3.2.2.2 Decade counter(Count10)

Solution:

3.2.2.3 Decade counter again(Count1to10)

Solution:

3.2.2.4 Slow decade counter(Countslow)

Solution:

3.2.2.5 counter 1-12(Exams/ece241 2014 q7a)

Solution:

3.2.2.6 Counter 1000(Exams/ece241 2014 q7b)

Solution:

3.2.2.7 4-digit decimal counter(Countbcd)

Solution:

3.2.2.8 12-hour clock(Count clock)

Solution:


前言

HDLbits网站如下

Problem sets - HDLBits (01xz.net)

从本期开始我们继续HDLbits第三章Circuits的学习,本期的内容是3.2.2 Counters


3.2.2.1 Four-bit binary counter(Count15)

构建一个4位二进制计数器,从0到15(含)计数,周期为 16。复位输入是同步的,应将计数器复位为 0。

Solution:

module top_module (
    input clk,
    input reset,      // Synchronous active-high reset
    output [3:0] q);

    always@(posedge clk) begin
        if(reset||q==4'd15)
            q<=4'd0;
        else 
            q<=q+4'd1;
    end

endmodule

由于本题中q是4bit向量,所以if条件中不需要加 ”|q==4‘d15“,q会从15滚动到0


3.2.2.2 Decade counter(Count10)

构建一个十进制计数器,从0到9(含)计数,周期为 10。复位输入是同步的,应将计数器复位为 0。

Solution:

module top_module(
	input clk,
	input reset,
	output reg [3:0] q);
	
	always @(posedge clk)
		if (reset || q == 9)	// Count to 10 requires rolling over 9->0 instead of the more natural 15->0
			q <= 0;
		else
			q <= q+1;
	
endmodule

3.2.2.3 Decade counter again(Count1to10)

构建一个十进制计数器,从1到10(含)计数,周期为 10。复位输入是同步的,应将计数器复位为 1。

Solution:

module top_module(
	input clk,
	input reset,
	output reg [3:0] q);
	
	always @(posedge clk)
        if (reset || q == 10)	// Count to 10 requires rolling over 9->0 instead of the more natural 15->0
			q <= 1;
		else
			q <= q+1;
	
endmodule

3.2.2.4 Slow decade counter(Countslow)

构建一个从 0 到 9 计数的十进制计数器,周期为 10。复位输入是同步的,应该将计数器重置为 0。我们希望能够暂停计数器而不是每个时钟周期总是递增,所以slowena 输入指示计数器何时应该增加。

Hint:这是一个带有使能控制信号的常规十进制计数器

Solution:

module top_module (
    input clk,
    input slowena,
    input reset,
    output [3:0] q);
    always@(posedge clk)
        begin
            if(reset)
                q<=4'd0;
            else if(slowena)
                begin
                    if(q==4'd9)
                        q<=4'd0;
                    else
                		q<=q+4'd1;
                end          
        end

endmodule

3.2.2.5 counter 1-12(Exams/ece241 2014 q7a)

设计一个具有以下输入和输出的 1-12 计数器:

  • Reset 同步高电平有效复位,强制计数器为 1
  • Enable 为高时计数器运行
  • Clk 上升沿触发时钟输入
  • Q[3:0] 计数器的输出
  • c_enable, c_load, c_d[3:0] 控制信号发送到提供的 4 位计数器,因此可以验证正确的操作。

您可以使用以下组件:

  • 下面的四位二进制计数器(count4),具有使能和同步并行加载输入(加载的优先级高于使能)。为您提供了count4模块,在您的电路中实例化他。
  • 逻辑门
module count4(
	input clk,
	input enable,
	input load,
	input [3:0] d,
	output reg [3:0] Q
);

c_enable、c_load 和 c_d 输出是分别进入内部计数器的enable、load和 d 输入的信号。它们的目的是允许检查这些信号的正确性。

Solution:

module top_module (
    input clk,
    input reset,
    input enable,
    output [3:0] Q,
    output c_enable,
    output c_load,
    output [3:0] c_d
); //
    assign c_enable= enable;
    assign c_load=reset|(Q == 4'd12 & enable == 1'b1);
    assign c_d=4'b1;
    count4 the_counter (clk, c_enable, c_load, c_d ,Q);

endmodule

3.2.2.6 Counter 1000(Exams/ece241 2014 q7b)

从 1000 Hz 时钟导出一个 1 Hz 信号,称为 OneHertz,可用于驱动一组小时/分钟/秒计数器的启用信号以创建数字挂钟。由于我们希望时钟每秒计数一次,因此 OneHertz 信号必须每秒被断言恰好一个周期。使用模 10 (BCD) 计数器和尽可能少的其他门构建分频器。还从您使用的每个 BCD 计数器输出使能信号(c_enable[0] 表示最快的计数器,c_enable[2] 表示最慢的计数器)。

为您提供了以下 BCD 计数器。Enable始终为高计数器才能运行。Reset是同步的,并且为高电平时强制计数器归零。电路中的所有计数器必须直接使用相同的 1000 Hz 信号。

module bcdcount (
	input clk,
	input reset,
	input enable,
	output reg [3:0] Q
);

Solution:

module top_module (
    input clk,
    input reset,
    output OneHertz,
    output [2:0] c_enable
); //
    wire[3:0]	one, ten, hundred;
    
    assign c_enable = {one == 4'd9 && ten == 4'd9, one == 4'd9, 1'b1};
    assign OneHertz = (one == 4'd9 && ten == 4'd9 && hundred == 4'd9);
 
    bcdcount counter0 (clk, reset, c_enable[0], one);
    bcdcount counter1 (clk, reset, c_enable[1], ten);
    bcdcount counter2 (clk, reset, c_enable[2], hundred);
 
endmodule

3.2.2.7 4-digit decimal counter(Countbcd)

构建一个 4 位 BCD(二进制编码的十进制)计数器。每个十进制数字使用4位编码:q[3:0] 是个位,q[7:4] 是十位,以此类推。对于digits [3:1],还输出一个使能信号,指示何时应增加高三位数字中的每一个。

您可能想要实例化或修改一些一位数的十进制计数器。

Solution:

module top_module (
    input clk,
    input reset,   // Synchronous active-high reset
    output [3:1] ena,
    output [15:0] q);
    assign ena = {q[3:0]==4'd9&&q[7:4]==4'd9&&q[11:8]==4'd9,q[3:0]==4'd9&&q[7:4]==4'd9,q[3:0]==4'd9};
    bcd cnt0(
        .clk(clk),
        .reset(reset),
        .ena(1'b1),
        .q(q[3:0])    
    );
    bcd cnt1(
        .clk(clk),
        .reset(reset),
        .ena(ena[1]),
        .q(q[7:4])    
    );
    bcd cnt2(
        .clk(clk),
        .reset(reset),
        .ena(ena[2]),
        .q(q[11:8])    
    );
    bcd cnt3(
        .clk(clk),
        .reset(reset),
        .ena(ena[3]),
        .q(q[15:12])    
    );

endmodule
module bcd(
    input clk,
    input reset,
    input ena,
    output [3:0]q);
    
    always@(posedge clk)
        begin
            if(reset)
                q<=4'b0;
            else if(ena)
                begin
                    if(q==4'd9)
                        q<=4'd0;
                    else
                		q<=q+4'd1;
                end
        end
endmodule

3.2.2.8 12-hour clock(Count clock)

创建一组适合用作 12 小时制的计数器(带有 am/pm 指示器)。您的计数器由快速运行的 clk 计时,每当您的时钟应增加(即每秒一次)时,ena 上就会有一个脉冲。

reset将时钟复位到12:00AM。pm=0时表示AM,pm=1时表示PM。hh、mm、ss是两位BCD数,分别表示时(01-12),分(0-59),秒(0-59)。reset的优先级高于enable,即使enable=0也可能发生。

 Hint:请注意,11:59:59 PM 接着到 12:00:00 AM,12:59:59 PM 接着到 01:00:00 PM。没有 00:00:00。

Solution:

module top_module(
    input clk,
    input reset,
    input ena,
    output pm,
    output [7:0] hh,
    output [7:0] mm,
    output [7:0] ss); 
    //assign pm=1'd0;
    //assign hh=8'd1;
    sixty s(clk,reset,ena,ss);
    sixty m(clk,reset,ena&&(ss==8'h59),mm);
    twelve h(clk,reset,ena&&(ss==8'h59&&mm==8'h59),pm,hh);

endmodule
module sixty(
    input clk,
    input reset,
    input ena,
    output [7:0]nn);
    
    always@(posedge clk)
        begin
        	if(reset)
            	nn<=8'd0;
            else if(ena)
                if(nn==8'h59)
                    nn<=8'd0;
            	else if(nn[3:0]==4'd9)
                    begin
                    	nn[7:4]<=nn[7:4]+4'd1;
                        nn[3:0]<=4'd0;
                    end
                    else
                        nn<=nn+8'd1;                    
        end
endmodule  

module twelve(
    input clk,
    input reset,
    input ena,
    output pm,
    output [7:0]nn);
    //assign pm=8'd0;
    always@(posedge clk)
        begin
            if(reset)
                begin
                	nn<=8'h12;
                    pm<=1'd0;
                end
            else if(ena)
                if(nn==8'h11)
                    begin
	                    nn<=8'h12;
                        pm<=~pm;
                    end
           		else if(nn==8'h12)
                    nn<=8'h1;
                else if(nn[3:0]==4'd9)
                     begin
                         nn[7:4]<=nn[7:4]+4'd1;
                         nn[3:0]<=4'd0;
                     end
                     else
                         nn<=nn+8'd1;
        end
endmodule
            
            

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值