https://hdlbits.01xz.net/wiki/Sequential Logic/Counter 答案

1.Count15

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

因为q是4位的,所以到了4’hf加一会自动回到0的;
2.Count10

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

十进制是不能自己回到0的。
3.Count1to10

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

4.CountSlow

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

5.Count1to12

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 && Q == 4'b1100))? 1'b1 : 1'b0;
    assign c_d = 4'b1;
    count4 the_counter(clk, c_enable, c_load, c_d, Q);
endmodule

6.Counter

module top_module (
    input clk,
    input reset,
    output OneHertz,
    output [2:0] c_enable
); //bcdcount counter0 (clk, reset, c_enable[0]/*, ... */);bcdcount counter1 (clk, reset, c_enable[1]/*, ... */);
    
    wire[3:0] out0;
    wire[3:0] out1;
    wire[3:0] out2;    
    
    assign c_enable[0] = 1'b1;
    bcdcount conuter0(clk, reset, c_enable[0], out0);
    assign c_enable[1] = (out0[0]==1) && (out0[3]==1);
    bcdcount conuter1(clk, reset, c_enable[1], out1);
    assign c_enable[2] = (out1[0]==1) && (out1[3]==1) && c_enable[1];
    bcdcount conuter2(clk, reset, c_enable[2], out2);
    assign OneHertz = (out2[0]==1) && (out2[3]==1) && c_enable[1] && c_enable[2];
    
endmodule

对于第一次分析来说,这个题目是比较难的,必须搞清楚:十位进位是个位为9,百位进位是个位十位均为9,千位则是前三位都为9
7.countBCD

module top_module (
    input clk,
    input reset,   // Synchronous active-high reset
    output [3:1] ena,
    output [15:0] q);
    
    BCD_counter count0(clk, 1, reset, q[3:0]);
    assign ena[1] = q[0] && q[3];
    BCD_counter count1(clk, ena[1], reset, q[7:4]);
    assign ena[2] = ena[1] && (q[7] && q[4]);
    BCD_counter count2(clk, ena[2], reset, q[11:8]);
    assign ena[3] = ena[1] && ena[2] && (q[11] && q[8]);
    BCD_counter count3(clk, ena[3], reset, q[15:12]);
    
endmodule
module BCD_counter(
    input clk,
	input enable,
	input reset,
    output[3:0] q);
    
    always@(posedge clk)
        begin
            if(reset | (enable && q == 4'b1001))
                q <= 4'b0;
            else if(enable && q != 4'b1001)
                q <= q + 4'b1;
        end
endmodule

这一题算是上一题的巩固。
8.

module top_module(
    input clk,
    input reset,
    input ena,
    output pm,
    output [7:0] hh,
    output [7:0] mm,
    output [7:0] ss); 
    
    wire[3:1] enable;
    
    CLK_counter count1(clk, ena, reset, ss);
    assign enable[1] = (ss[6] && ss[4] && ss[3] && ss[0]);
    CLK_counter count2(clk, enable[1], reset, mm);
    assign enable[2] = (mm[6] && mm[4] && mm[3] && mm[0]) && enable[1];
    CLK_conuter_hh count3(clk, enable[2], reset, hh);
    assign enable[3] = (hh[4] && hh[0]) && enable[2] && enable[1];
    
    always@(posedge clk or posedge reset)
        begin
            if(reset)
                pm <= 1'b0;
            else if(enable[3])
                pm <= ~pm;          
        end   
endmodule
module CLK_counter(
    input clk,
	input enable,
	input reset,
    output[7:0] q);
    
    always@(posedge clk)
        begin
            if(reset)
                q <= 8'b0;
            else if(enable && q[3:0] == 4'b1001)
                begin
                    q[3:0] <= 4'b0;
                    if(q[7:4] == 4'b0101)
                        q[7:4] <= 4'b00;
                    else
                        q[7:4] <= q[7:4] + 4'b1;
                end
            else if(enable)
                q[3:0] <= q[3:0] + 4'b1;
        end
endmodule

module CLK_conuter_hh(
    input clk,
	input enable,
	input reset,
    output[7:0] q);
    
    always@(posedge clk)
        begin
            if(reset)
                q <= 8'b00010010;
            else if(enable && q[4] && q[1])
                q <= 8'b1;
            else if(enable && q[3:0] == 4'b1001)
                begin
                    q[3:0] <= 4'b0;
                    q[7:4] <= 1;
                end
            else if(enable)
                q[3:0] <= q[3:0] + 4'b1;                
        end
endmodule

这一题很有综合性,也很有难度(主要是某人debug小错误太多了)。
主要的问题在进制分析以及这个时钟的特点上。进制是分和秒是60进制,小时则是13进制,因为小时计数是从1到13,而每到12点就切换pm和am,搞清楚这个逻辑,题目就很清晰了。


如有错误欢迎讨论和指正。
练习网址

posted @ 2021-03-26 20:57  黑衣の甘铃儿  阅读(124)  评论(0)    收藏  举报