我是靠谱客的博主 害怕草莓,最近开发中收集的这篇文章主要介绍HDLbits 刷题Day18(Counters),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

3.2.2.1 Four-bit binary counter
问题陈述:

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

Verilog代码:

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

3.2.2.2 Decade counter
问题陈述:

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

Verilog代码:

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

3.2.2.3 Decade counter again
问题陈述:

制作一个从 1 到 10 的十年计数器,包括 1 到 10。复位输入是同步的,应将计数器复位为 1。请添加图片描述

Verilog代码:

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

3.2.2.4 Slow decade counter
问题陈述:

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

Verilog代码:

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

3.2.2.5 Counter 1-12
问题陈述:

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

Reset同步高电平有效复位,强制计数器为 1
Enable设置高以使计数器运行
Clk正边沿触发时钟输入
Q[3:0]计数器的输出
c_enable, c_load, **c_d[3:0]**控制信号进入提供的 4 位计数器,因此可以验证正确的操作。
您有以下可用组件:
下面的 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输入的信号。它们的目的是允许检查这些信号的正确性。

Verilog代码:

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=((Q>=4'd12)&&(enable==1'b1))|reset;
    assign c_d=c_load?4'b1:4'b0;
    count4 the_counter (clk, c_enable, c_load, c_d ,Q);

endmodule

3.2.2.6 Counter100
问题陈述:

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

为您提供以下 BCD计数器。Enable必须为高电平才能使计数器运行。复位是同步的并设置为高以强制计数器为零。电路中的所有计数器必须直接使用相同的 1000
Hz 信号。
module bcdcount (
input clk,
input reset,
input enable,
output reg [3:0] Q
);

Verilog代码:

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 u1(clk,reset,c_enable[0],one);
    bcdcount u2(clk,reset,c_enable[1],ten);
    bcdcount u3(clk,reset,c_enable[2],hundred);

endmodule

3.2.2.7 4-digit decimal counter
问题陈述:

构建一个 4 位 BCD(二进制编码的十进制)计数器。每个十进制数字使用 4 位编码:q[3:0] 是个位,q[7:4] 是十位等。对于数字 [3:1],还输出一个使能信号,指示每个前三位应递增。

您可能想要实例化或修改一些一位十进制计数器。
请添加图片描述

Verilog代码:

module top_module (
    input clk,
    input reset,   // Synchronous active-high reset
    output [3:1] ena,
    output [15:0] q);
 	reg ena0;
    always@(posedge clk)begin
        if(reset)
            ena0<=1'b1;
    end
    assign ena[1]=q[3:0]==4'd9;
    assign ena[2]=q[3:0]==4'd9&&q[7:4]==4'd9;
    assign ena[3]=q[3:0]==4'd9&&q[7:4]==4'd9&&q[11:8]==4'd9;
    bcdcount u1(clk,reset,ena0,q[3:0]);
    bcdcount u2(clk,reset,ena[1],q[7:4]);
    bcdcount u3(clk,reset,ena[2],q[11:8]);
    bcdcount u4(clk,reset,ena[3],q[15:12]);

endmodule
module bcdcount(
    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'b0;
            else
        q<=q+1'b1;
        end
    end
endmodule

3.2.2.8 12-hour clock
问题陈述:

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

reset将时钟重置为 12:00 AM。pm对于 AM 为 0,对于 PM 为
1。hh、mm和ss是两个BCD(二进制编码的十进制)数字,分别表示小时 (01-12)、分钟 (00-59) 和秒
(00-59)。重置的优先级高于启用,即使未启用也可能发生。

以下时序图显示了从上午 11:59:59到下午 12:00:00的翻转行为以及同步复位和启用行为。
请添加图片描述

Verilog代码:

module top_module(
    input clk,
    input reset,
    input ena,
    output pm,
    output [7:0] hh,
    output [7:0] mm,
    output [7:0] ss); 
    reg [3:0] s1,s2;
    reg [3:0] m1,m2;
    reg [3:0] h1;
    reg [3:0]h2;
    wire pm_zh;
    always@(posedge clk)
        begin
            if(reset)
                s1<=4'b0;
            else if(ena)
                begin
                    if(s1==4'd9)
                        s1<=4'd0;
                    else
                        s1<=s1+4'd1;
                end
        end
    always@(posedge clk)
        begin
            if(reset)
                s2<=4'b0;
            else if(ena&&s1==4'd9)
                begin
                    if(s2==4'd5)
                        s2<=4'd0;
                    else
                        s2<=s2+4'd1;
                end
        end
    always@(posedge clk) begin
        if(reset)
            m1<=4'b0;
        else if(ena&&s1==4'd9&&s2==4'd5)
            begin
                if(m1==4'd9)
                    m1<=4'd0;
                else
                    m1<=m1+4'd1;
            end
    end
    always @(posedge clk)
        begin
            if(reset)
                m2<=4'b0;
            else if(ena&&m1==4'd9&&s1==4'd9&&s2==4'd5)
                begin
                    if(m2==4'd5)
                        m2<=4'd0;
                    else
                        m2<=m2+4'd1;
                end
        end
    always@(posedge clk)
        begin
            if(reset)
                h1<=4'd2;
            else if(ena&&m1==4'd9&&m2==4'd5&&s1==4'd9&&s2==4'd5)
                begin
                    if(h1==4'd9)
                        h1<=4'd0;
                    else if(h1==4'd2&&h2==4'd1)
                        h1<=4'd1;
                    else
                        h1<=h1+4'd1;
                end
        end
    always@(posedge clk)
        begin
            if(reset)
                h2<=4'd1;
            else if (ena&&m1==4'd9&&m2==4'd5&&s1==4'd9&&s2==4'd5)
                begin
                    if(h2==4'd1&&h1==4'd2)
                        h2<=4'd0;
                    else if(h1==4'd9)
                        h2<=h2+4'd1;
                end
        end
    always@(posedge clk)
        begin
            if(reset)
                pm<=1'b0;
            else if(pm_zh)
                begin
                    pm<=~pm;
                end
        end
    assign pm_zh=(h2==4'd1&&h1==4'd1&&ena&&m1==4'd9&&m2==4'd5&&s1==4'd9&&s2==4'd5);
    assign ss={s2,s1};
    assign mm={m2,m1};
    assign hh={h2,h1}             
endmodule

最后

以上就是害怕草莓为你收集整理的HDLbits 刷题Day18(Counters)的全部内容,希望文章能够帮你解决HDLbits 刷题Day18(Counters)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部