【HDLBits刷题笔记】10 Counters

Count15

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

Count10

题目给的答案把q清零和reset放在了一个if里if (reset || q == 9)。

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<9)?(q+1):0;
    end
endmodule

Count1to10

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

Countslow

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

Exams/ece241 2014 q7a

这道题感觉怪怪的,一开始我写的c_load = (Q==12)|reset;由于题目说了count4模块中的load优先级比enable高,所以enable为0时仍可以置数。

而题目貌似是希望load和enable不能冲突,enable为0时就不应该置数了,所以此时的load应该为0,所以我又把信号与上了一个enable。

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 , Q );
    assign c_d = 1;
    assign c_enable = enable;
    assign c_load = enable&(Q==12)|reset;
endmodule

Exams/ece241 2014 q7b

把三个BCD计数器级联在一起即可。一开始我写的c_enable[2]=(Q2==9);OneHertz=(Q3==9);而Q2、Q3都会持续多个周期,只有Q1是一个一直变的信号。

module top_module (
    input clk,
    input reset,
    output OneHertz,
    output [2:0] c_enable
); //
    wire [3:0]Q1;
    wire [3:0]Q2;
    wire [3:0]Q3;
    bcdcount counter0 (clk, reset, c_enable[0],Q1);
    bcdcount counter1 (clk, reset, c_enable[1],Q2);
    bcdcount counter2 (clk, reset, c_enable[2],Q3);
    assign c_enable[0]=1'b1;
    assign c_enable[1]=(Q1==9);
    assign c_enable[2]=(Q2==9)&&(Q1==9);
    assign OneHertz=(Q3==9)&&(Q2==9)&&(Q1==9);
endmodule

Countbcd

感觉写的稍微有点复杂,利用了verilog里写多个if优先下面的语句的特点,实际不会对一个数重复操作。

实际例化多个BCD计数器会简单很多。

module top_module (
    input clk,
    input reset,   // Synchronous active-high reset
    output [3:1] ena,
    output [15:0] q);
    always@(posedge clk)
    begin
        if(reset)
            q <= 'd0;
        else begin
            q[3:0] <= q[3:0] + 1;
            if(ena[1])begin
                q[3:0] <= 0;
                q[7:4] <= q[7:4]+1;
            end
            if(ena[2])begin
                q[3:0] <= 0;
                q[7:4] <= 0;
                q[11:8] <= q[11:8]+1;
            end
            if(ena[3])begin
                q[3:0] <= 0;
                q[7:4] <= 0;
                q[11:8] <= 0;
                q[15:12] <= (q[15:12]<9)?q[15:12] +1:0;
            end
        end
    end
    assign ena[1] = (q[3:0]==9);
    assign ena[2] = (q[7:4]==9)&&ena[1];
    assign ena[3] = (q[11:8]==9)&&ena[2];
endmodule

Count clock

这道题稍微有点复杂,难度也不算特别大,但是需要耐心debug,把情况全部考虑清楚。

我提交了五次才通过,可恶。

module top_module(
    input clk,
    input reset,
    input ena,
    output reg pm,
    output reg[7:0] hh,
    output reg[7:0] mm,
    output reg[7:0] ss); 
    
    always@(posedge clk)
    begin
        if(reset)begin
            pm <= 1'b0;
            hh <= {4'd1,4'd2};
            mm <= 0;
            ss <= 0;
        end
        else if(ena)begin
            ss[3:0] <= ss[3:0] +1'b1;
            if(ss[3:0] == 9)begin
                ss[3:0] <= 'd0;
                ss[7:4] <= (ss[7:4]==5)?0:(ss[7:4]+1);
            end
            if(ss[3:0] == 9&&ss[7:4] == 5)begin
                if(mm[3:0]<9)
                    mm[3:0] <= mm[3:0] + 1;
                else begin
                    mm[3:0] <= 'd0;
                    mm[7:4] <= (mm[7:4]==5)?0:(mm[7:4]+1);
                end
            end
            if(ss[3:0] == 9&&ss[7:4] == 5&&mm[3:0] == 9&&mm[7:4] == 5)begin
                if(hh[3:0]<9&&hh[7:4] == 0)
                    hh[3:0] <= hh[3:0] + 1;
                else if(hh[3:0]<2&&hh[7:4] == 1)
                    hh[3:0] <= hh[3:0] + 1;
                else begin
                    if(hh[7:4] == 1)
                        hh[3:0] <= 'd1;//注意这里是1
                    else
                        hh[3:0] <= 'd0;
                    hh[7:4] <= (hh[7:4]==1)?0:1;
                end                
            end
            if(ss[3:0] == 9&&ss[7:4] == 5&&mm[3:0] == 9&&mm[7:4] == 5&&hh[3:0]==1&&hh[7:4]==1)
                pm<=~pm;
        end
    end

endmodule

 

posted @ 2022-10-30 21:27  Magnolia666  阅读(387)  评论(0编辑  收藏  举报