HDLbits练习记录(十一)全程更新

Circuits>Sequential Logic>Counters

1.Four-bit binary counter

功能:

四位二进制计数器,一个周期是16个,同步清零。

收获:

代码:

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

2.Decade counter

功能:

0-9十年计数器,同步清零。

收获:

代码:

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

3.Decade counter again

功能:

计数1-10,同步清零。

收获:

代码:

module top_module (
    input clk,
    input reset,
    output [3:0] q);
//
    reg [3:0]count;
//
    always@(posedge clk)
        begin
            if(reset|(count==4'd10))
                count <= 4'd1;
            else
                count <= count + 4'd1;
        end
    assign q = count;
endmodule

4.Countslow

功能:

0-9计数,同步清零,带有停止计数开关。

收获:

对于这些功能,应该存在优先级问题,对于本题,应首先对优先级进行分级,再使用if进行排序,首先优先级最高的为清零信号,再次其应该是暂停信号,然后才是计数器到上限信号,最后是计数器正常计数。

代码:

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

5.Counter 1-12

功能:

一个1-12计数器,同步清零,高使能运行,需要实例化模块。

收获:

教训:刚开始采用的always和case,结果如下图所示,与应该产生的结果延迟了一个周期,思考了一下,这是因为always模块和实例化模块是并行的,而always模块里进行判决,就相当于延迟了一个时钟周期。时钟周期一般没办法提前,但是可以延后,通过加寄存器的方式可以延后时序,也可以通过使用#来延时。

代码:

差一个周期时序的代码:(失败

module top_module (
    input clk,
    input reset,
    input enable,
    output [3:0] Q,
    output c_enable,
    output c_load,
    output [3:0] c_d
); 
    //
    reg ena=1'b1;
    reg load=1'b0;
    reg co;
    reg [3:0]d;
    reg [3:0]counter;
    //
    assign c_enable = ena;
    assign   c_load = load;
    assign      c_d = d;
    assign  counter = Q;
    //
    always@(posedge clk)
        begin
            case({reset,enable})
                2'b10: 
                    begin//复位  
                           d <= 4'b0001;
                        load <= 1'b1; 
                        ena  <= 1'b0;
                    end
                2'b11://复位
                    begin  
                           d <= 4'b0001;
                        load <= 1'b1; 
                        ena  <= 1'b1;
                    end
                2'b00://暂停状态
                    begin  
                           d <= 4'b0000;//没用到
                        load <= 1'b0; 
                        ena  <= 1'b0;
                    end
                2'b01://正常计数状态
                    begin  
                        if(~co)
                            begin
                           d <= 4'b0000;//没用到
                        load <= 1'b0; 
                        ena  <= 1'b1;
                            end
                        else
                            begin
                                d <= 4'b0001;
                             load <= 1'b1;
                              ena <= 1'b0;
                            end
                    end
                default: 
                    begin
                           d <= 4'b0000;
                        load <= 1'b0; 
                        ena  <= 1'b0;
                    end
            endcase
            if(counter==4'd10)
                co <= 1'd1;
            else
                co <= 1'b0;
        end
    count4 count4_inst0(
        .clk(clk),
        .enable(ena),
        .load(load),
        .d(d),
        .Q(Q)//out
    );
endmodule

成功代码:

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;
    
    count4 the_counter (
        .clk(clk),
        .enable(c_enable),
        .load(c_load),
        .d(c_d),
        .Q(Q)
    );

endmodule

6.Counter 1000

功能:

输入1000Hz的时钟信号,使用三个十计数器,从而达到1s产生一个信号的功能。

收获:

对于这几次代码使用的输出output给一些模块赋值是可以使用的,相当于把输出线又分叉了一根当作了反馈进行输入了。

代码:

module top_module (
    input clk,
    input reset,
    output OneHertz,//1HZ 100次
    output [2:0] c_enable
); 
    //
    reg [3:0]q2,q1,q0;
    //
    assign    OneHertz = ((q2==4'd9)&(q1==4'd9)&(q0==4'd9))?1'b1:1'b0;
    assign c_enable[2] = ((q1==4'd9)&(q0==4'd9))?1'b1:1'b0;
    assign c_enable[1] = (q0==4'd9)?1'b1:1'b0; 
    assign c_enable[0] = ~reset;
    bcdcount bcdcount_inst2(
        .clk(clk),
        .reset(reset),
        .enable(c_enable[2]),
        .Q(q2)
    );
    bcdcount bcdcount_inst1(
        .clk(clk),
        .reset(reset),
        .enable(c_enable[1]),
        .Q(q1)
    );
    bcdcount bcdcount_inst0(
        .clk(clk),
        .reset(reset),
        .enable(c_enable[0]),
        .Q(q0)
    );

endmodule

7.4-digit decimal counter

功能:

首先写一个二进制十计数器,带enable和reset,然后实例化,实现10000计数器,每四位表示一位,分别是个十百千位

收获:

代码:

module top_module (
    input clk,
    input reset,   // Synchronous active-high reset
    output [3:1] ena,
    output [15:0] q);
    //
    assign ena[1] = (q[3:0]==4'd9)?1'b1:1'b0;
    assign ena[2] = ((q[7:4]==4'd9)&(q[3:0]==4'd9))?1'b1:1'b0;
    assign ena[3] = ((q[11:8]==4'd9)&(q[7:4]==4'd9)&(q[3:0]==4'd9))?1'b1:1'b0;
    //
    counter counter_inst0(
        .clk(clk),
        .reset(reset),
        .enable(~reset),
        .Q(q[3:0])
    );
     counter counter_inst1(
        .clk(clk),
        .reset(reset),
        .enable(ena[1]),
        .Q(q[7:4])
    );
     counter counter_inst2(
        .clk(clk),
        .reset(reset),
        .enable(ena[2]),
        .Q(q[11:8])
    );
     counter counter_inst3(
        .clk(clk),
        .reset(reset),
        .enable(ena[3]),
        .Q(q[15:12])
    );
endmodule

module counter(input clk,input reset,input enable,output [3:0]Q);
    //
    reg [3:0]count;
    //
    assign Q = count;
    always@(posedge clk)
        begin
            if(reset)
                count <= 4'b0000;
            else if(~enable)
                count <= count + 4'd0;
            else if(count==4'd9)
                count <= 4'd0;
            else
                count <= count + 4'd1;
        end
endmodule

8.12 hour clock

功能:

收获:

代码:

暂时未调试成功(

# ** Error (suppressible): (vsim-3601) Iteration limit 5000 reached at time 38255 ps.

module top_module(
    input clk,
    input reset,
    input ena,
    output pm,
    output [7:0] hh,
    output [7:0] mm,
    output [7:0] ss); 
    //
    wire [1:0]link;
    //
    assign link[0] = ((ss[3:0]==4'd9)&(ss[7:4]==4'd5)&ena)?1'b1:1'b0;
    assign link[1] = ((mm[3:0]==4'd9)&(mm[7:4]==4'd5)&(ss[3:0]==4'd9)&(ss[7:4]==4'd5)&link[0])?1'b1:1'b0;
    assign      pm = reset?1'b0:(((ss[3:0]==4'd9)&(ss[7:4]==4'd5)&ena&(mm[3:0]==4'd9)&
                                  (mm[7:4]==4'd5)&(hh[7:4]==4'd1)&(hh[3:0]==4'd2))?(~pm):pm);
    counter12 hour(
        .clk(clk),
        .reset(reset),
        .enable(link[1]),
        .Q(hh)
    );
    counter60 minute(
        .clk(clk),
        .reset(reset),
        .enable(link[0]),
        .Q(mm)
    );
    counter60 second(
        .clk(clk),
        .reset(reset),
        .enable(ena),
        .Q(ss)
    );
endmodule
module counter12(input clk,input reset,input enable,output [7:0]Q);//十二计数器
    //
    wire ena;
    //
    assign ena = ((Q[3:0]==4'd9)&enable)?1'b1:1'b0;
   // assign clean = ((Q[3:0]==4'd2)&(Q[7:4]==4'd1)&enable)?1'b1:1'b0;
    counter10_12_0 counter_inst0(
        .clk(clk),
        .reset(reset),
        .clean((Q[3:0]==4'd2)&(Q[7:4]==4'd1)&enable),
        .enable(enable),
        .Q(Q[3:0])
    );
    counter10_12_1 counter_inst1(
        .clk(clk),
        .reset(reset),
        .clean((Q[3:0]==4'd2)&(Q[7:4]==4'd1)&enable),
        .enable(ena),
        .Q(Q[7:4])
    );
endmodule
module counter60(input clk,input reset,input enable,output [7:0]Q);//六十计数器

    //
    wire ena;
    //
    assign ena = ((Q[3:0]==4'd9)&enable)?1'b1:1'b0;
    //assign clean = ((Q[3:0]==4'd9)&(Q[7:4]==4'd5)&enable)?1'b1:1'b0;
    counter10 counter_inst0(
        .clk(clk),
        .reset(reset|((Q[3:0]==4'd9)&(Q[7:4]==4'd5)&enable)),
        .enable(enable),
        .Q(Q[3:0])
    );
    counter10 counter_inst1(
        .clk(clk),
        .reset(reset|((Q[3:0]==4'd9)&(Q[7:4]==4'd5)&enable)),
        .enable(ena),
        .Q(Q[7:4])
    );
endmodule
module counter10(input clk,input reset,input enable,output [3:0]Q);//0-9 十计数器
    //
    reg [3:0]count;
    //
    assign Q = count;
    always@(posedge clk)
        begin
            if(reset|((count==4'd9)&enable))
                count <= 4'd0;
            else if(~enable)
                count <= count + 4'd0;
            else
                count <= count + 4'd1;
        end
endmodule
module counter10_12_0(input clk,input reset,input clean,input enable,output [3:0]Q);//0-9 十计数器 加clean清1
    //
    reg [3:0]count;
    //
    assign Q = count;
    always@(posedge clk)
        begin
            if(reset)
                count <= 4'd2;
            else if(clean)
                count <= 4'd1;
            else if(~enable)
                count <= count + 4'd0;
            else if((count==4'd9)&enable)
                count <= 4'd0;
            else
                count <= count + 4'd1;
        end
endmodule
module counter10_12_1(input clk,input reset,input clean,input enable,output [3:0]Q);//0-9 十计数器 加clean清1
    //
    reg [3:0]count;
    //
    assign Q = count;
    always@(posedge clk)
        begin
            if(reset)
                count <= 4'd1;
            else if(clean)
                count <= 4'd0;
            else if(~enable)
                count <= count + 4'd0;
            else
                count <= count + 4'd1;
        end
endmodule

换了一种方式,还是出现了这个问题。

module top_module(
    input clk,
    input reset,
    input ena,
    output pm,
    output [7:0] hh,
    output [7:0] mm,
    output [7:0] ss); 
    //
    wire [1:0]link;
    //
    assign link[0] = ((ss[3:0]==4'd9)&(ss[7:4]==4'd5)&ena)?1'b1:1'b0;
    assign link[1] = ((mm[3:0]==4'd9)&(mm[7:4]==4'd5)&link[0])?1'b1:1'b0;
    assign      pm = reset?1'b0:(((ss[3:0]==4'd9)&(ss[7:4]==4'd5)&ena&(mm[3:0]==4'd9)&
                                  (mm[7:4]==4'd5)&(hh[7:4]==4'd1)&(hh[3:0]==4'd2))?(~pm):pm);
    counter12 hour(
        .clk(clk),
        .reset(reset),
        .enable(link[1]),
        .Q(hh)
    );
    counter60 minute(
        .clk(clk),
        .reset(reset),
        .enable(link[0]),
        .Q(mm)
    );
    counter60 second(
        .clk(clk),
        .reset(reset),
        .enable(ena),
        .Q(ss)
    );
endmodule
module counter12(input clk,input reset,input enable,output [7:0]Q);//十二计数器
    //
    wire ena,clean;
    //
    assign ena = ((Q[3:0]==4'd9)&enable)?1'b1:1'b0;
    assign clean = ((Q[3:0]==4'd2)&(Q[7:4]==4'd1)&enable)?1'b1:1'b0;
    counter10_12_0 counter_inst0(
        .clk(clk),
        .reset(reset),
        .clean(clean),
        .enable(enable),
        .Q(Q[3:0])
    );
    counter10_12_1 counter_inst1(
        .clk(clk),
        .reset(reset),
        .clean(clean),
        .enable(ena),
        .Q(Q[7:4])
    );
endmodule
module counter60(input clk,input reset,input enable,output [7:0]Q);//六十计数器
    //
    /*wire ena,clean;
    //
    assign ena = ((Q[3:0]==4'd9)&enable)?1'b1:1'b0;
    assign clean = ((Q[3:0]==4'd9)&(Q[7:4]==4'd5)&enable)?1'b1:1'b0;//59不行 58可以
    counter10 counter_inst0(
        .clk(clk),
        .reset(reset|clean),
        .enable(enable),
        .Q(Q[3:0])
    );
    counter10 counter_inst1(
        .clk(clk),
        .reset(reset|clean),
        .enable(ena),
        .Q(Q[7:4])
    );*/
    reg [7:0]count;
    assign Q = count;
    always@(posedge clk)
        begin
            if(reset)
                count[7:0] <= 8'd0;
            else if(~enable)
                count[3:0] <= count[3:0] +4'd0;
            else if((count[7:4]==5)&(count[3:0]==9)&enable)
                begin
                    count[7:4] <= 4'd0;
                    count[3:0] <= 4'd0;
                end
            else if(enable&(count[3:0]==4'd9))
                begin
                    count[3:0] <= 4'd0;
                    count[7:4] <= count[7:4] + 4'd1;
                end
            else
                count[3:0] <= count[3:0] + 4'd1;
        end
endmodule
module counter10(input clk,input reset,input enable,output [3:0]Q);//0-9 十计数器
    //
    reg [3:0]count;
    //
    assign Q = count;
    always@(posedge clk)
        begin
            if(reset|((count==4'd9)&enable))
                count <= 4'd0;
            else if(~enable)
                count <= count + 4'd0;
            else
                count <= count + 4'd1;
        end
endmodule

module counter10_12_0(input clk,input reset,input clean,input enable,output [3:0]Q);//0-9 十计数器 加clean清1
    //
    reg [3:0]count;
    //
    assign Q = count;
    always@(posedge clk)
        begin
            if(reset)
                count <= 4'd2;
            else if(clean)
                count <= 4'd1;
            else if(~enable)
                count <= count + 4'd0;
            else if((count==4'd9)&enable)
                count <= 4'd0;
            else
                count <= count + 4'd1;
        end
endmodule

module counter10_12_1(input clk,input reset,input clean,input enable,output [3:0]Q);//0-9 十计数器 加clean清1
    //
    reg [3:0]count;
    //
    assign Q = count;
    always@(posedge clk)
        begin
            if(reset)
                count <= 4'd1;
            else if(clean)
                count <= 4'd0;
            else if(~enable)
                count <= count + 4'd0;
            else
                count <= count + 4'd1;
        end
endmodule

又换了一种方法,问题解决了,终于解决了,但是之前的问题还没有找到,之后找一下大佬请教一下吧。

module top_module(
    input clk,
    input reset,
    input ena,
    output pm,
    output [7:0] hh,
    output [7:0] mm,
    output [7:0] ss);
    //
    reg p;
    //
    assign pm = p;
    counter60 counter60_second(
        .clk(clk),
        .reset(reset),
        .enable(ena),
        .q(ss)
    );
    counter60 counter60_minute(
        .clk(clk),
        .reset(reset),
        .enable(ena&(ss==8'h59)),
        .q(mm)
    );
    counter12 counter60_hour(
        .clk(clk),
        .reset(reset),
        .enable(ena&(ss==8'h59)&(mm==8'h59)),
        .q(hh)
    );
    always@(posedge clk)
        begin
            if(reset)
                p <= 1'b0;
            else if((hh==8'h11)&(mm==8'h59)&(ss==8'h59))
                p <= ~p;
            else;
        end
endmodule
module counter60(input clk,input reset,input enable,output [7:0]q);
    always@(posedge clk)
        begin
            if(reset)
                q <= 8'h00;
            else if(enable)
                begin
                    if(q==8'h59)
                        begin
                        q <= 8'h00;
                        end
                    else if(q[3:0]==4'h9)
                        begin
                            q[3:0] <= 4'h0;
                            q[7:4] <= q[7:4] + 4'h1;
                        end
                    else
                        begin
                            q[3:0] <= q[3:0] + 4'h1;
                        end
                end
        end
endmodule
module counter12(input clk,input reset,input enable,output [7:0]q);
    always@(posedge clk)
        begin
            if(reset)
                q <= 8'h12;
            else if(enable)
                begin
                    if(q==8'h12)
                        begin
                        q <= 8'h01;
                        end
                    else if(q[3:0]==4'h9)
                        begin
                            q[3:0] <= 4'h0;
                            q[7:4] <= q[7:4] + 4'h1;
                        end
                    else
                        begin
                            q[3:0] <= q[3:0] + 4'h1;
                        end
                end
        end
endmodule

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值