HDLBits练习(十二)Circuits_Sequential Logic_Counters

Count15

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

弄清楚计数器的清零和计数条件就很容易。

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

    reg [3:0] q_reg;

    always@(posedge clk)
        if(reset == 1'b1)
            q_reg <= 4'd0;
        else if(q_reg == 4'hf)
            q_reg <= 4'd0;
        else
            q_reg <= q_reg + 1'b1;

    assign q = q_reg;

endmodule

Count10

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

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

    always@(posedge clk)
        if(reset == 1'b1)
            q_reg <= 4'd0;
        else if(q_reg == 4'd9)
            q_reg <= 4'd0;
        else
            q_reg <= q_reg + 1'b1;

    assign q = q_reg;

endmodule

Count1to10

要求:制作一个从 1 到 10 的十年计数器,包括 1 到 10。复位输入是同步的,应将计数器复位为 1。

module top_module (
    input clk,
    input reset,
    output [3:0] q);
    
    reg [3:0] q_reg;

    always@(posedge clk)
        if(reset == 1'b1)
            q_reg <= 4'd1;
        else if(q_reg == 4'd10)
            q_reg <= 4'd1;
        else
            q_reg <= q_reg + 1'b1;

    assign q = q_reg;

endmodule

Countslow

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

module top_module (
    input clk,
    input slowena,
    input reset,
    output [3:0] q);

    reg [3:0] q_reg;
    
    always@(posedge clk)
        if(reset == 1'b1)
            q_reg <= 4'd0;
        else if((q_reg == 4'd9) && (slowena == 1'b1))
            q_reg <= 4'd0;
        else if(slowena == 1'b1)
            q_reg <= q_reg + 1'b1;
        else
            q_reg <= q_reg;
    
    assign q = q_reg;

endmodule

Counter 1 to 12(Exams/ece241 2014 q7a)

要求:设计一个具有以下输入和输出的 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
);
//1-12计数,计数到12时给count4输出置1,reset高电平置1

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

endmodule

Counter 1000(Exams/ece241 2014 q7b)

要求:从 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
);
module top_module (
    input clk,
    input reset,
    output OneHertz,
    output [2:0] c_enable
); //
    wire [3:0] unit,ten,hun;
    
    assign c_enable[0] = ~reset;
    assign c_enable[1] = ~reset && (unit == 4'd9);
    assign c_enable[2] = ~reset && (ten == 4'd9) && (unit == 4'd9);
    assign OneHertz = (unit == 4'd9) && (ten == 4'd9) && (hun == 4'd9);
    
    bcdcount counter0 (clk, reset, c_enable[0],unit);
    bcdcount counter1 (clk, reset, c_enable[1],ten);
    bcdcount counter2 (clk, reset, c_enable[2],hun);

endmodule

Countbcd

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

 

module top_module (
    input clk,
    input reset,   // Synchronous active-high reset
    output [3:1] ena,
    output [15:0] q);
    
    reg [3:1] ena_reg;
    reg [15:0] q_reg;
    
    
    always@(posedge clk)
        if(reset == 1'b1)
            q_reg[3:0] <= 4'd0;
        else if(q_reg[3:0] == 4'd9)
            q_reg[3:0] <= 4'd0;
        else
            q_reg[3:0] <= q_reg[3:0] + 1'b1;
    
    always@(posedge clk)
        if(reset == 1'b1)
            ena_reg[1] <= 1'b0;
        else if(q_reg[3:0] == 4'd8)
            ena_reg[1] <= 1'b1;
        else
            ena_reg[1] <= 1'b0;
            
    always@(posedge clk)
        if(reset == 1'b1)
            q_reg[7:4] <= 4'd0;
        else if((q_reg[7:4] == 4'd9) && ena_reg[1])
            q_reg[7:4] <= 4'd0;
        else if(ena_reg[1])
            q_reg[7:4] <= q_reg[7:4] + 1'b1;
        else
            q_reg[7:4] <= q_reg[7:4];

    always@(posedge clk)
        if(reset == 1'b1)
            ena_reg[2] <= 1'b0;
        else if((q_reg[7:4] == 4'd9) && (q_reg[3:0] == 4'd8))
            ena_reg[2] <= 1'b1;
        else
            ena_reg[2] <= 1'b0;            

    always@(posedge clk)
        if(reset == 1'b1)
            q_reg[11:8] <= 4'd0;
        else if((q_reg[11:8] == 4'd9) && ena_reg[2])
            q_reg[11:8] <= 4'd0;
        else if(ena_reg[2])
            q_reg[11:8] <= q_reg[11:8] + 1'b1; 
        else
            q_reg[11:8] <= q_reg[11:8];

    always@(posedge clk)
        if(reset == 1'b1)
            ena_reg[3] <= 1'b0;
        else if((q_reg[11:8] == 4'd9) && (q_reg[7:4] == 4'd9) && (q_reg[3:0] == 4'd8))
            ena_reg[3] <= 1'b1;
        else
            ena_reg[3] <= 1'b0;

    always@(posedge clk)
        if(reset == 1'b1)
            q_reg[15:12] <= 4'd0;
        else if((q_reg[15:12] == 4'd9) && ena_reg[3])
            q_reg[15:12] <= 4'd0;
        else if(ena_reg[3])
            q_reg[15:12] <= q_reg[15:12] + 1'b1; 
        else
            q_reg[15:12] <= q_reg[15:12];  

    assign q = q_reg;
    assign ena = ena_reg;

endmodule

Count 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的翻转行为以及同步复位和启用行为。

 这里是比较综合的计数器应用,注意每个计数器清零条件和计数条件。

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] ss_unit;
    reg [3:0] ss_ten;
    reg [3:0] mm_unit;
    reg [3:0] mm_ten;
    reg [3:0] hh_unit;
    reg [3:0] hh_ten;
    reg pm_reg;  
    
    always@(posedge clk)
        if(reset == 1'b1)
            pm_reg <= 1'b0;
        else if((hh == 8'h11) && (mm == 8'h59) && (ss == 8'h59) && (ena == 1'b1))
            pm_reg <= ~pm_reg;
        else
            pm_reg <= pm_reg;

    always@(posedge clk)
        if(reset == 1'b1)
            ss_unit <= 4'd0;
        else if((ss_unit == 4'd9) && (ena == 1'b1))
            ss_unit <= 4'd0;          
        else if(ena == 1'b1)   
                ss_unit <= ss_unit + 1'b1;
        else
            ss_unit <= ss_unit;
            
    always@(posedge clk)
        if(reset == 1'b1)
            ss_ten <= 4'd0;
        else if((ss_ten == 4'd5) && (ss_unit == 4'd9) 
                && (ena == 1'b1))
            ss_ten <= 4'd0;          
        else if((ss_unit == 4'd9) && (ena == 1'b1))  
            ss_ten <= ss_ten + 1'b1;
        else
            ss_ten <= ss_ten;
            
    always@(posedge clk)
        if(reset == 1'b1)
            mm_unit <= 4'd0;
        else if((mm_unit == 4'd9) && (ss_ten == 4'd5) 
                && (ss_unit == 4'd9) && (ena == 1'b1))
            mm_unit <= 4'd0;  
        else if((ena == 1'b1) && (ss_ten == 4'd5) && (ss_unit == 4'd9))
            mm_unit <= mm_unit + 1'b1;
        else
            mm_unit <= mm_unit; 
            
    always@(posedge clk)
        if(reset == 1'b1)
            mm_ten <= 4'd0;
        else if((mm_ten == 4'd5) && (mm_unit == 4'd9)
                && (ss_ten == 4'd5) && (ss_unit == 4'd9) 
                && (ena == 1'b1))
            mm_ten <= 4'd0;          
        else if((mm_unit == 4'd9) && (ss_ten == 4'd5) 
                && (ss_unit == 4'd9) && (ena == 1'b1))  
            mm_ten <= mm_ten + 1'b1;
        else
            mm_ten <= mm_ten;
            
    always@(posedge clk)
        if(reset == 1'b1)
            hh_unit <= 4'd2;
        else if((hh_unit == 4'd9) 
                && (mm_ten == 4'd5) && (mm_unit == 4'd9) 
                && (ss_ten == 4'd5) && (ss_unit == 4'd9) 
                && (ena == 1'b1))
            hh_unit <= 4'd0;
        else if((hh_ten == 4'd1) && (hh_unit == 4'd2) 
                && (mm_ten == 4'd5) && (mm_unit == 4'd9) 
                && (ss_ten == 4'd5) && (ss_unit == 4'd9) 
                && (ena == 1'b1))
            hh_unit <= 4'd1;
        else if((ena == 1'b1) && (mm_ten == 4'd5) 
                && (mm_unit == 4'd9) && (ss_ten == 4'd5) 
                && (ss_unit == 4'd9))
            hh_unit <= hh_unit + 1'b1;
        else
            hh_unit <= hh_unit; 
            
    always@(posedge clk)
        if(reset == 1'b1)
            hh_ten <= 4'd1;
        else if((hh_ten == 4'd1) && (hh_unit == 4'd2)
                &&(mm_ten == 4'd5) && (mm_unit == 4'd9)
                && (ss_ten == 4'd5) && (ss_unit == 4'd9) 
                && (ena == 1'b1))
            hh_ten <= 4'd0;          
        else if((hh_unit == 4'd9) && (mm_ten == 4'd5) 
                && (mm_unit == 4'd9) && (ss_ten == 4'd5) 
                && (ss_unit == 4'd9) && (ena == 1'b1))  
            hh_ten <= hh_ten + 1'b1;
        else
            hh_ten <= hh_ten;

    assign pm = pm_reg;
    assign ss = {ss_ten,ss_unit};
    assign mm = {mm_ten,mm_unit};
    assign hh = {hh_ten,hh_unit};
    
endmodule
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值