HDLBits练习(六)计数器

1.4位计数器

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

2.如下

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

3.如下

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

    always@(posedge clk)begin
        if(reset)
            q <= 4'd1;
        else if(q < 4'd10)
            q <= q + 1'b1;
        else 
            q <= 4'd1;
    end
endmodule

4.如下

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

5.如下

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 | ((Q == 4'd12) && enable == 1'b1);//例化模块的计数复位信号
    assign c_d = c_load ? 4'd1 : 4'd0; //复位为1,c_d为初始值
 
    count4 u_counter (clk, c_enable, c_load, c_d, Q);
 
endmodule

6.如下

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 counter0 (clk, reset, c_enable[0], one);
    bcdcount counter1 (clk, reset, c_enable[1], ten);
    bcdcount counter2 (clk, reset, c_enable[2], hundred);
 
endmodule

7.如下

module top_module (
    input clk,
    input reset,   // Synchronous active-high reset
    output [3:1] ena,
    output [15:0] q);
    
    reg [3:0]	ones;
    reg [3:0]	tens;
    reg [3:0]	hundreds;
    reg [3:0]	thousands;
    
    always@(posedge clk)begin
        if(reset)begin
            ones <= 4'd0;
        end
        else if(ones == 4'd9)begin
            ones <= 4'd0;
        end
        else begin
            ones <= ones + 1'b1;
        end
    end
    
    always@(posedge clk)begin
        if(reset)begin
            tens <= 4'd0;
        end
        else if(tens == 4'd9 && ones == 4'd9)begin
            tens <= 4'd0;
        end
        else if(ones == 4'd9) begin
            tens <= tens + 1'b1;
        end
    end
    
    always@(posedge clk)begin
        if(reset)begin
            hundreds <= 4'd0;
        end
        else if(hundreds == 4'd9 && tens == 4'd9 && ones == 4'd9)begin
            hundreds <= 4'd0;
        end
        else if(tens == 4'd9 && ones == 4'd9) begin
            hundreds <= hundreds + 1'b1;
        end
    end
    
    always@(posedge clk)begin
        if(reset)begin
            thousands <= 4'd0;
        end
        else if(thousands == 4'd9 && hundreds == 4'd9 && tens == 4'd9 && ones == 4'd9)begin
            thousands <= 4'd0;
        end
        else if(hundreds == 4'd9 && tens == 4'd9 && ones == 4'd9) begin
            thousands <= thousands + 1'b1;
        end
    end
    
    assign q = {thousands, hundreds, tens, ones};
    assign ena[1] = (ones == 4'd9) ? 1'b1 : 1'b0;
    assign ena[2] = (tens == 4'd9 && ones == 4'd9) ? 1'b1 : 1'b0;
    assign ena[3] = (hundreds == 4'd9 && tens == 4'd9 && ones == 4'd9) ? 1'b1 : 1'b0;
 
endmodule

8.这个没想到把十位和个位分开来做,时序一直不对,如下:


module metastab_test(
    input clk,
    input reset,
    input ena,
    output pm,
    output [7:0] hh,
    output [7:0] mm,
    output [7:0] ss
); 
    
    
    reg 		pm_temp; //pm暂存器
    
    //个位与十位
    reg	[3:0]	ss_ones;
    reg [3:0]	ss_tens;
    reg	[3:0]	mm_ones;
    reg [3:0]	mm_tens;
    reg	[3:0]	hh_ones;
    reg [3:0]	hh_tens;
    
    wire		add_ss_ones;//秒钟个位累加信号
    wire		end_ss_ones;//秒钟个位结束信号
    wire		add_ss_tens;
    wire		end_ss_tens;
    wire		add_mm_ones;
    wire		end_mm_ones;
    wire		add_mm_tens;
    wire		end_mm_tens;
    wire		add_hh_ones;
    wire		end_hh_ones_0;
    wire		end_hh_ones_1;
    wire		add_hh_tens;
    wire		end_hh_tens_0;
    wire		end_hh_tens_1;
    
    wire		pm_ding;//pm翻转信号
   
  
 //秒钟个位累加 
    always@(posedge clk)begin
        if(reset)begin
            ss_ones <= 4'd0;
        end
        else if(add_ss_ones)begin
            if(end_ss_ones)begin
                ss_ones <= 4'd0;
            end
            else begin
                ss_ones <= ss_ones + 1'b1;
            end
        end
    end
    //使能信号作用域秒累加器,即可影响到其他累加器
    assign add_ss_ones = ena;
    assign end_ss_ones = add_ss_ones && ss_ones == 4'd9;
    
    //秒十位累加器
    always@(posedge clk)begin
        if(reset)begin
            ss_tens <= 4'd0;
        end
        else if(add_ss_tens)begin
            if(end_ss_tens)begin
                ss_tens <= 4'd0;
            end
            else begin
                ss_tens <= ss_tens + 1'b1;
            end
        end
    end
    
    assign add_ss_tens = end_ss_ones;
    assign end_ss_tens = add_ss_tens && ss_tens == 4'd5;
    
    //分钟个位累加器
    always@(posedge clk)begin
        if(reset)begin
            mm_ones <= 4'd0;
        end
        else if(add_mm_ones)begin
            if(end_mm_ones)begin
                mm_ones <= 4'd0;
            end
            else begin
                mm_ones <= mm_ones + 1'b1;
            end
        end
    end
    
    assign add_mm_ones = end_ss_tens;
    assign end_mm_ones = add_mm_ones && mm_ones == 4'd9;
    
    //分钟十位累加器
    always@(posedge clk)begin
        if(reset)begin
            mm_tens <= 4'd0;
        end
        else if(add_mm_tens)begin
            if(end_mm_tens)begin
                mm_tens <= 4'd0;
            end
            else begin
                mm_tens <= mm_tens + 1'b1;
            end
        end
    end
    
    assign add_mm_tens = end_mm_ones;
    assign end_mm_tens = add_mm_tens && mm_tens == 4'd5;
    
    //时位个位累加器
    always@(posedge clk)begin
        if(reset)begin
            hh_ones <= 4'd2;
        end
        else if(add_hh_ones)begin
            if(end_hh_ones_0)begin
                hh_ones <= 4'd0;
            end
            else if(end_hh_ones_1)begin
                hh_ones <= 4'd1;
            end
            else begin
                hh_ones <= hh_ones + 1'b1;
            end
        end
    end
    
    assign add_hh_ones = end_mm_tens;
    assign end_hh_ones_0 = add_hh_ones && hh_ones == 4'd9;
    assign end_hh_ones_1 = add_hh_ones && (hh_tens == 4'd1 && hh_ones == 4'd2); //1~12点
    
    //时位十位累加器
    always@(posedge clk)begin
        if(reset)begin
            hh_tens <= 4'd1;
        end
        else if(add_hh_tens)begin
            if(end_hh_tens_0)begin
                hh_tens <= 4'd0;
            end
            else if(end_hh_tens_1)begin
                hh_tens <= hh_tens + 1'b1;
            end
        end
    end
    
    assign add_hh_tens = end_mm_tens;
    assign end_hh_tens_0 = add_hh_tens && end_hh_ones_1;
    assign end_hh_tens_1 = add_hh_tens && end_hh_ones_0;
    
    //pm每隔12h取反
    always@(posedge clk)begin
        if(reset)begin
            pm_temp <= 1'b0;
        end
        else if(pm_ding)begin
            pm_temp <= ~pm_temp;
        end
    end
    
    assign pm_ding = hh_tens == 4'd1 && hh_ones == 4'd1 && end_mm_tens;
    
    assign ss = {ss_tens, ss_ones};
    assign mm = {mm_tens, mm_ones};
    assign hh = {hh_tens, hh_ones};
    assign pm = pm_temp;
 
endmodule

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值