Verilog Circuits-Sequential Logic-Counters

Problem 98:Four-bit binary counter

设计一个 4it 的计数器,从 0-15,共 16 个周期,reset 是同步复位且复位为 0

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

            if(reset)
                q<=0;
            else
                q<=q+1;
        end
  
endmodule

Problem 99 :Decade counter

将上题的 0-15 改为 0-9,同步复位,且复位为 0

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

Problem 100:Decade counter again

1-10 的计数器,不同的是同步复位为 1

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<=1;
            else
                q<=q+1;
        end
            
endmodule

Problem 101:Slow decade counter

设计 0-9 的计数器,共 1 0 个周期。该计数器采用同步复位且复位为 0。

我们希望该计数器不是随着 clk 的变化而递增,而是随着一个 slowena 使能信号来控制增加。时序图如图

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==1'b1)//当使能端赋值时,计数器才开始工作
                begin
                    if(q<=4'b1000)
                        q<=q+4'b1;
                    else
                        q<=4'b0;
                end
        end

endmodule

Problem 102:Counter 1-12

根据以下输入输出信号设计一个计算 1-12 的计数器

Reset :同步复位信号,高复位,将计数器复位为 1.

Enable :使能信号高有效

Clk :时钟上升沿触发计数器工作

Q[3:0] :计数器输出

c_enable, c_load, c_d[3:0] :题目中给我们提供了一个 4-bit 的计数器,这三个信号是用于该 4-bit 计数器的控制信号。

题目提供给我们 4-bit 计数器

  1. 有 enable 信号,带复位和置位的计数器,将该计数器例化至我们的代码中。
  2. 再用一些其他的逻辑门来完成本题
//题目提供的4-bit计数器代码
module count4(
    input clk,
    input enable,
    input load,
    input [3:0] d,
    output reg [3:0] Q
);
  • 本题相当于用 c_enale、c_load 和 c_d[3:0]三个控制信号来控制题目中给我们提供的 4-bit 计数器,使得该计数器的技术范围改变为 1~12
    .
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_d=4'b1;
    assign c_enable=enable;
    assign c_load=reset|(Q==4'd12&enable==1'b1);//读者觉得这里的load应该是置位端
    //count4 the_counter (clk, c_enable, c_load, c_d /*, ... */ );
    count4 the_count (.clk(clk)
                     ,.enable(c_enable)
                     ,.load(c_load)
                     ,.d(c_d)
                     ,.Q(Q)
                    );

endmodule

Problem 103:Counter 1000

从 1000Hz 中分离出 1Hz 的信号,叫做 OneHertz。一般用于驱动计数器的使能端去实现数字时钟。

如果我们想让时钟每秒计数一次,那么 OneHertz 信号必须每秒为一个周期

我们可以利用一个模 1 的 BCD 计数器和尽可能少的逻辑门来建立一个时钟分频器。同时输出每个 BCD 计数器的使能信号(C_enable[0]为高位,C_enable[2]为低位)

已给出 BCD 计数器,Enable 信号高有效。Reset 信号高有效且复位为 0

我们设计的电路中均要采用 1000Hz 的时钟

module bcdcount (
    input clk,
    input reset,
    input enable,
    output reg [3:0] Q
);
  • 假设三个定时器,每个都是模 10 的计数器,a 的输入时钟是 1000Hz,当 a 计到 10,给 b 一个使能,b 是 a 的十分之一,相当于 b 的时钟是 100Hz,同理,c 是 a 的百分之一,所以到 c 之后,也就是 999 就输出 1Hz 了
module top_module (
    input clk,
    input reset,
    output OneHertz,
    output [2:0] c_enable
); //
    wire [3:0]q0,q1,q2;
    assign c_enable={q0==4'd9&&q1==4'd9,q0==4'd9,1'b1};
    assign OneHertz={q0==4'd9&&q1==4'd9&&q2==4'd9};
  
    //bcdcount counter0 (clk, reset, c_enable[0]/*, ... */);
    //bcdcount counter1 (clk, reset, c_enable[1]/*, ... */);
    bcdcount counter0 (clk, reset, c_enable[0],q0);
    bcdcount counter1 (clk, reset, c_enable[1],q1);
    bcdcount counter2 (clk, reset, c_enable[2],q2);

  
endmodule

Problem 104:4-digit decimal counter

设计一个 4 位 BCD(二进制编码十进制)计数器。每个十进制数字用 4-bit 来表示:q[3:0]是个位,q[7:4]是十位等。

对于 ena[3:1],该信号用来表示个位、十位和百位的进位。时序图如下图所示:

module top_module (
    input clk,
    input reset,   // Synchronous active-high reset
    output [3:1] ena,
    output [15:0] q);
  
    wire [3:0]q0,q1,q2,q3;
    assign ena={q2==4'd9&&q1==4'd9&&q0==4'd9,q1==4'd9&&q0==4'd9,q0==4'd9};
    count10 add1(clk,reset,1'b1,q0);
    count10 add10(clk,reset,ena[1],q1);
    count10 add100(clk,reset,ena[2],q2);
    count10 add1000(clk,reset,ena[3],q3);  
    assign q={q3,q2,q1,q0};  
endmodule
    module count10(input clk,input reset,input enable,output reg[3:0]Q);
        always @(posedge clk)
            begin 
                if(reset)
                    Q<=0;
                else if(enable==1)
                    begin
                        if(Q<=4'b1000)
                   			 Q<=Q+1;
               			else
                    		Q<=0;
                    end
            end
    endmodule

Problem 105:12-hour clock

用计数器设计一个带 am/pm 的 12 小时时钟。该计数器通过一个 CLK 进行计时,用 ena 使能信号来驱动时钟的递增

reset 信号将时钟复位为 12:00AM。信号 pm 为 0 代表 AM,为 1 代表 PM。

hh、mm 和 ss 由两个 BCD 计数器构成 hours(01-12),minutes(00-59),second(00-59)。reset 信号比 enable 信号优先级高。

  • 需要注意的是从 11:59:59 PM 到 12:00:00 AM 和从 12:59:59 PM 到 01:00:00 PM 的变化。
module top_module(
    input clk,
    input reset,
    input ena,
    output pm,
    output [7:0] hh,
    output [7:0] mm,
    output [7:0] ss); 
    wire mcin,hcin,pmt;
    counter60 seconds(clk,reset,ena,ss,mcin);
    counter60 minutes(clk,reset,mcin,mm,hcin);
    counter12 hours(clk,reset,hcin&mcin,hh,pmt);
    always @(posedge clk)
        begin
            if(reset)
                pm<=1'b0;
            else if(pmt)
                pm<=~pm;
            else
                pm<=pm;
    
        end
endmodule  
    module counter60(input clk,input reset,input ena,output [7:0]tim,output cout);
        always @(posedge clk)
            begin
                if(reset)
                    tim<=8'd0;
                else if(ena)
                    begin
                        if(tim==8'b0101_1001)
                            tim<=8'd0;
                        else if(tim[3:0]==4'd9)
                            begin
                                tim[7:4]<=tim[7:4]+1;
                                tim[3:0]<=0;
                            end
                        else
                            tim[3:0]<=tim[3:0]+1;
                    end
            end
        assign cout=(tim==8'b0101_1001);
    endmodule
module counter12(input clk,input reset,input ena,output[7:0]tim,output cout);
    always @(posedge clk)
        begin
            if(reset)
                tim<=8'b0001_0010;
            else if(ena)
                begin
                    if(tim==8'b0001_0010)
                        tim<=8'b0000_0001;
                    else if(tim[3:0]==4'b1001)
                        begin
                        tim[3:0]<=0;
                            tim[7:4]<=tim[7:4]+1'b1;
                        end
                    else 
                        tim[3:0]<=tim[3:0]+1'b1;
                end
            
        end
    assign cout=(tim==8'b0001_0001)&&ena;
endmodule
posted @ 2021-12-14 22:18  heart-z  阅读(176)  评论(0)    收藏  举报