HDLBits-Circuits学习小结(五)计数器(counters)

1 简单的计数器

1.1 二进制、十进制计数器

构建一个4位二进制计数器,其计数范围从0到15(包括0和15),周期为16。置位输入是同步的,应该将计数器重置为0。

count15
solution:

module top_module (
    input clk,
    input reset,      // Synchronous active-high reset
    output [3:0] q);
    
    
    always @(posedge clk) begin
        if (reset)
            q <= 4'b0000;
        else begin
            q <= q + 1'd1;
        end
    end
   
endmodule

构建一个十进制计数器,其计数范围从0到9(包括0和9),周期为10。置位输入是同步的,应该将计数器重置为0。
十进制计数器
solution:

module top_module (
    input clk,
    input reset,        // Synchronous active-high reset
    output [3:0] q);
    always @(posedge clk) begin
        if (reset)
            q <= 0;
        else begin
            if (q[3]==1 & q[2]==0 & q[1]==0 & q[0]==1)
                q <= 4'b0000;
            else
                q <= q + 1'b1;
        end
    end

endmodule

official 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

做一个十进制计数器,计数范围为1到10(含1和10)。复位输入是同步的,应将计数器复位为1。

count1to10
solution:

module top_module(
    input clk,
    input reset,
    output [3:0] q);
    
    always @(posedge clk) begin
        if (reset)
            q <= 4'b0001;
        else if (q == 4'b1010)
            q <= 4'b0001;
        else
            q <= q + 1'b1;
    end
    
endmodule

1.2 可以暂停的计数器

构建一个十进制计数器,其计数范围从0到9(包括0和9),周期为10。置位输入是同步的,应该将计数器重置为0。
我们希望能够暂停计数器,而不是总是每个时钟周期递增,因此slowena输入指出计数器应该何时递增。

slowena
错误的solution:

module top_module (
    input clk,
    input slowena,
    input reset,
    output [3:0] q);
    
    always @(posedge clk) begin
        if (reset || q ==9)
            q <= 0;
        else if (slowena)
            q <= q + 1;
        else
            q <= q;
    end

endmodule

原因在于这里的slowena是控制计数器递增的,即使是计数器是9,如果slowena没有发出递增的指令,那么计数器将保持是9。

正确的solution:

module top_module (
    input clk,
    input slowena,
    input reset,
    output [3:0] q);
    
    always @(posedge clk) begin
        if (reset)
            q <= 0;
        else if (slowena) begin
            if (q < 9)
            	q <= q + 1;
        	else
            	q <= 0;
        end
        else
            q <= q;
    end

endmodule

2 较为复杂的计数器

2.1 从1计数到12的计数器

设计一个从1计数到12的计数器,输入和输出如下:
Reset:同步高电平复位,强制计数器为1
Enable:高电平有效,以使计数器计数
Clk:时钟输入上升沿触发
Q[3:0]:计数器的输出
c_enable,c_load,c_d[3:0]将控制信号发送到提供的4位计数器,从而验证操作是否正确。

可以使用以下组件:

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

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 //复位
); //

    count4 the_counter (clk, c_enable, c_load, c_d , Q);
    assign c_enable = enable; 
    assign c_load = reset | (Q == 12 & enable ==1);
    assign c_d = 1'b1;
    
endmodule

2.2 从1000Hz时钟中导出1Hz的信号

🌟

从一个1000 Hz的时钟中,导出一个称为OneHertz的1 Hz信号,该信号可用于为一组小时/分钟/秒计数器驱动启用信号,以创建数字挂钟。由于我们希望时钟每秒计数一次,因此必须在每秒精确的一个周期内确定OneHertz信号。使用模数模块构建分频器。

使用modulo-10 (BCD)计数器和尽可能少的逻辑门来构建分频器。还输出使用的每个BCD计数器的enable信号(c_enable[0]表示最快的计数器,c_enable[2]表示最慢的计数器)。

给定下面的BCD计数器。使能端enable必须为高电平才能使计数器运行。复位是同步的,并设置为高电平时迫使计数器为零。电路中的所有计数器必须直接使用相同的1000Hz信号。

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

这是一道难题,思考过程参考的是这篇文章,这篇文章中提到:

如何设计这样一个电路呢?

通过例化一个10进制bcd码计数器,来实现1000分频的分频器。

也就是说时钟是1Khz的时钟,如何通过计数得到一个1Hz的信号,持续一个时钟就行。

那就计数到999给一个输出作为1Hz信号输出。

如何实现计数到999呢?

由于给的是一个模10计数器,所以先例化一个个位计数器,技术到9,给十位计数器一个使能,让其计数,同理,十位计数器计数到9给百位计数器一个使能,就可以得到这样的一个计数器。

从时间的角度上看,1khz就是0.001s,而1hz就是1s,那么这样就就可以解释通了。

solution:

module top_module (
    input clk,
    input reset,
    output OneHertz,
    output [2:0] c_enable
); //

    wire [3:0] q0,q1,q2; //一定要注明输出的长度,这里和bcdcount保持一致
    assign c_enable = {q1==4'd9 & q0==4'd9,q0==4'd9,1'b1};
    assign OneHertz = {q2==4'd9 & q1==4'd9 & q0==4'd9};
    
    bcdcount count0 (clk,reset,c_enable[0],q0);
    bcdcount count1 (clk,reset,c_enable[1],q1);
    bcdcount count2 (clk,reset,c_enable[2],q2);
    
endmodule

2.3 构建4位BCD计数器

构建一个4位BCD(二进制编码的十进制)计数器。每一位十进制数字都用4位编码:q[3:0]是个位,q[7:4]是十位,等等。对于数字位[3:1],还输出一个enable信号,指示高三位数字中的每一位何时应该递增。
您可能要实例化或修改一些一位十进制计数器。

BCD

module top_module (
    input clk,
    input reset,   // Synchronous active-high reset
    output [3:1] ena,
    output [15:0] q);
    
    wire enable;
    assign enable = 1'b1;
    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 bcd0 (clk,reset,enable,q[3:0]);
    bcd bcd1 (clk,reset,ena[1],q[7:4]);
    bcd bcd2 (clk,reset,ena[2],q[11:8]);
    bcd bcd3 (clk,reset,ena[3],q[15:12]);

endmodule

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

2.4 创建12小时时钟的计数器

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

重置将时钟重置为12:00 AM。 pm对于AM是0,对于PM是1。 hh,mm和ss是两个BCD(二进制-编码的十进制数字分别代表小时(01-12),分钟(00-59)和秒(00-59)。Reset的优先级比enable的优先级高。

以下时序图显示了从11:59:59 AM到12:00:00 PM的过渡行为以及同步复位和启用行为。

12小时
请注意,11:59:59 PM前进至12:00:00 AM,12:59:59 PM前进至01:00:00 PM。没有00:00:00。从图中知道,hh、mm、ss都是8位二进制数,且分为前四位和后四位,如果前四位满足了要求,后四位就加一个数;8位都满足了要求,就复位。

module top_module(
    input clk,
    input reset,
    input ena,
    output pm,
    output [7:0] hh,
    output [7:0] mm,
    output [7:0] ss); 
    
    wire [3:0] enable;
    assign enable[0] = ena;
    assign enable[1] = ena & (ss==8'h59);
    assign enable[2] = ena & (ss==8'h59) & (mm==8'h59);
    assign enable[3] = ena & (hh==8'h11) & (ss==8'h59) & (mm==8'h59);
    
    count60 second  (clk,reset,enable[0],ss);
    count60 minute  (clk,reset,enable[1],mm);
    count12 hour    (clk,reset,enable[2],hh);
    count2  halfday (clk,reset,enable[3],pm);
    
endmodule

module count12(
    input clk,
    input reset,
    input ena,
    output [7:0] q);
    
    always @(posedge clk) begin
        if (reset)
            q <= 8'h12;
        else if (ena) begin
            if (q == 8'h12)
                q <= 8'h1;
            else if (q[3:0] == 4'h9) begin
                q[3:0] <= 0;
                q[7:4] <= 1;
            end
            else
                q[3:0] <= q[3:0] + 1;
        end
        else
            q <= q;
    end
    
endmodule
    
module count60(
    input clk,
    input reset,
    input ena,
    output [7:0] q);
    
    always @(posedge clk) begin
        if (reset)
            q <= 0;
        else if (ena) begin
            if (q == 8'h59)
                q <= 0;
            else if (q[3:0] == 4'h9) begin
                q[3:0] <= 0;
                q[7:4] <= q[7:4] + 1;
            end
            else
                q[3:0] <= q[3:0] + 1;
        end
        else
            q <= q;
    end
    
endmodule

module count2(
    input clk,
    input reset,
    input ena,
    output q);
    
    always @(posedge clk) begin
        if (reset)
            q <= 0;
        else if (ena) begin
            if (q < 1'b1)
                q <= q + 1;
            else
                q <= 0;
        end
        else
            q <= q;
    end
    
endmodule
  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 尼尔森(Nilsson)是一个常见的瑞典姓氏,源自瑞典北部和南部地区。它起源于北欧文化中的尼尔家族,被认为是一个古老而充满历史的姓氏。 尼尔森这个姓氏在瑞典历史上非常常见,许多著名的瑞典人都拥有这个姓氏,如瑞典足球传奇运动员弗雷迪·尼尔森(Freddy Nilsson)和知名作曲家利特罗尔·尼尔森(Litorol Nilsson)。 尼尔森这个姓氏在其他国家也很常见,尤其是在瑞典人移民的国家,如美国、加拿大、澳大利亚等。在这些国家,许多姓氏为Nilsson的人注重传承瑞典文化和家族价值观,保持着对祖先的敬意。 总的来说,尼尔森是一个具有瑞典瑞典文化和历史背景的常见姓氏,代表着家族和传统的重要价值。尼尔森家族在各个领域都有杰出的人物,他们的成就为尼尔森这个姓氏增添了光彩,同时也让人们对这个姓氏有了更多的认识。 ### 回答2: 尼尔森(Nillson)是一个常见的瑞典姓氏,也可以是一个人名。作为一个姓氏,它在瑞典和其他北欧国家非常常见。像其他姓氏一样,尼尔森在使用中可能有不同的拼写和变体。 作为一个人名,尼尔森通常指的是一个男性,尤其是在北欧国家。 尼尔森可能是一个家族姓氏,也可能是给予某人的名字。尼尔森是一个非常常见的名字,特别在瑞典和丹麦。 尼尔森这个名字的起源可以追溯到瑞典和丹麦的传统和文化。 在瑞典,尼尔森很可能是尼尔的儿子或后代的意思。在丹麦,尼尔森可能是尼尔的儿子后代的意思。 虽然尼尔森可能是一个普通的名字,但它并没有特定的象征意义。 它只是一个家族姓氏或被给予的名字,没有传递特定的信息或意义,而是代表某个人或家族的身份。 就像其他姓氏和名字一样,尼尔森的使用是为了代码某个人或家族的身份和传统。 ### 回答3: 尼尔森(Nilsson),一般指的是瑞典流行巨星哈里·尼尔森(Harry Nilsson)。 哈里·尼尔森是20世纪60年代和70年代最富盛名的瑞典流行歌手之一。他以其独特的嗓音和多才多艺的音乐才能而闻名,他的音乐作品涵盖了多种风格,包括摇滚、流行、乡村和爵士等。他的代表作品包括《Without You》、《Everybody's Talkin'》和《Coconut》等。 尼尔森以其独特的音域和深情的演唱风格而受到广泛赞誉。他擅长创作动情的歌曲,并通过他的音乐传达了许多情感和体验。他的歌曲经常描绘人们在爱情、友谊和人生各个方面的复杂情感,深受听众喜爱。 尼尔森的音乐成就令人瞩目,他的专辑《Nilsson Schmilsson》获得了格莱美奖,并获得了多次金唱片认证。他的音乐影响了许多后来的音乐人,包括披头士乐队的成员以及其他许多著名艺人。 尼尔森在音乐创作方面的突出才能与他的问题生活和不幸的命运并存。他的生活中充满了酗酒、药物滥用和人际关系问题,这些困扰最终对他的音乐事业产生了重大影响。尽管他在这些问题上经历了艰难的时期,但他的音乐天赋和创造力使他成为一个不可忽视的艺人。 总的来说,哈里·尼尔森是一个备受尊敬的艺术家,他以他独特的音乐才能和感人的歌曲在乐坛中留下了难以磨灭的印记。尽管他的一生经历了许多挑战和困难,但他的音乐将继续让我们回忆和怀念。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值