verilog 学习笔记 —— 时序逻辑 Sequential Logics (counters 计数器)

1. Four-bit binary counter  4位二进制计数器

 

module top_module(
	input clk,
	input reset,
	output reg [3:0] q);
	
	always @(posedge clk)
		if (reset)
			q <= 0;
		else
			q <= q+1;		// Because q is 4 bits, it rolls over from 15 -> 0.
		// If you want a counter that counts a range different from 0 to (2^n)-1, 
		// then you need to add another rule to reset q to 0 when roll-over should occur.
	    // 4位,满了后溢出自然会成为0000
endmodule

2. Decade counter   十进制计数器

module top_module (
    input clk,
    input reset,        // Synchronous active-high reset
    output [3:0] q);
    always@(posedge clk)
        begin
            if(reset || q>=4'd9)  //  4'd   4表示占的比特位,d表示后面数字的表示形式,二者之间没有绝对关系
                q<=1'b0;          //  4位比特位,可以表示到15,所以要将超过10的部分复位掉
            else
                q<=q+1'b1;
        end

endmodule

 3.Decade counter again

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

endmodule

4. Slow decade counter

module top_module (
    input clk,
    input slowena,
    input reset,
    output [3:0] q);
    always@(posedge clk)
        begin
            if(reset)      //复位的优先级最高
                q<=1'b0;
            else if (slowena)
                begin
                    if(q>=4'd9)
                        q<=4'd0;
                    else
                        q<=1'b1+q;
                end
            else
                q<=q;
        end
          
endmodule

 5. Counter 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
); //

   //count4 the_counter (clk, c_enable, c_load, c_d /*, ... */ );
    assign c_enable = enable ;
    assign c_load = reset | ((enable == 1'b1)&&(Q>=12));   //注意一下计数到多大
    assign c_d = c_load ? (4'b1) : (4'b0) ;
    count4 the_counter(clk, c_enable,c_load,c_d,Q);

endmodule

6. Counter100

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

7. 4-digit decimal counter

 

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;   //个位计数到10,开启十位使能信号
    assign ena[2]=   q[3:0]==4'd9 && q[7:4]==4'd9;//个位计数到10,且十位计数到10,开启百位使能信号
    assign ena[3]=   q[3:0]==4'd9 && q[7:4]==4'd9  &&  q[11:8]==4'd9 ;//个位计数到10,且十位计数到10,且百位计数到十,开启千位使能信号
    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

8. 12-hour clock

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,h2;
    wire pm_zh;
    
    
    
    //秒:s1为秒的个位,十进一,s2为秒的十位,六进一
    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
    //秒:s1为秒的个位,十进一,s2为秒的十位,六进一
    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'b1;
                end
        end
    
    
    
    
    //分:m1为分的个位,十进一,m2为分的十位,六进一
    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
    //分:m1为分的个位,十进一,m2为分的十位,六进一
    always@(posedge clk)
        begin
            if(reset)
                m2<=4'b0;
            else if(ena && m1==4'd9 && s2==4'd5 && s1==4'd9)
                begin
                    if(m2==4'd5)
                        m2<=4'd0;
                    else
                        m2<=m2+4'b1;
                end
        end
    
    
    
    
    
     //时:h1为时的个位,十进一,h2为时的十位,六进一
    always@(posedge clk)
        begin
            if(reset)
                h1<=4'd2;
            else if(ena && m2==4'd5 && m1==4'd9 && s2==4'd5 && s1==4'd9 )
                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
    //时:h1为时的个位,十进一,h2为时的十位,六进一
    always@(posedge clk)
        begin
            if(reset)
                h2<=4'd1;
            else if(ena && m2==4'd5 && m1==4'd9 && s2==4'd5 && s1==4'd9)
                begin
                    if(h2==4'd1&&h1==4'd2)
                        h2<=4'd0;
                    else if(h1==4'd9)
                        h2<=h2+4'd1;
                end
        end   
    
    
    // pm标志位
    always@(posedge clk)
        begin
            if(reset)
                pm<=1'b0;
            else if(pm_zh)
                begin
                    pm<=~pm;
                end
        end
    
    //时间到达 11:59:59  时, pm_zhen 给个标志位
    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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值