2021年4月25日 星期日

HBLbits_Verilog Basic_Count clock

 HBLbits_Verilog Basic_Count clock

Create a set of counters suitable for use as a 12-hour clock (with am/pm indicator). Your counters are clocked by a fast-running clk, with a pulse on ena whenever your clock should increment (i.e., once per second).

reset resets the clock to 12:00 AM. pm is 0 for AM and 1 for PMhhmm, and ss are two BCD (Binary-Coded Decimal) digits each for hours (01-12), minutes (00-59), and seconds (00-59). Reset has higher priority than enable, and can occur even when not enabled.

The following timing diagram shows the rollover behaviour from 11:59:59 AM to 12:00:00 PM and the synchronous reset and enable behaviour.




module top_module(

    input clk,
    input reset,
    input ena,
    output pm,
    output [7:0] hh,
    output [7:0] mm,
    output [7:0] ss); 
    
    always@(posedge clk) begin
        if (reset) begin
            hh <= 8'h12;
        mm <= 0;
        ss <= 0;
        pm <= 0;
        end
        else begin
            if (ena) begin
                pm <= (hh == 8'h11 && mm == 8'h59 && ss == 8'h59)? ~pm : pm;
                if (ss == 8'h59) begin // ss = 59
                    ss <= 0;
                    
                    if (mm == 8'h59) begin // mm = 59
                        mm <= 0;
                        
                        if (hh == 8'h12) begin
                            hh <= 8'h01;
                        end
                        
                        else begin
                            if (hh[3:0] == 4'd9) begin
                                hh[3:0] <= 0;
                                hh[7:4] <= hh[7:4] + 4'd1;
                            end
                            else 
                                hh[3:0] <= hh[3:0] + 4'd1;  
                        end
         
                    end
                    else begin
                        if (mm[3:0] == 4'd9) begin
                            mm[3:0] <= 0;
                            mm[7:4] <= mm[7:4] + 4'd1;
                        end
                        else 
                            mm[3:0] <= mm[3:0] + 4'd1; 
                    end
                    
                    
                end
                else begin
                    if (ss[3:0] == 4'd9) begin
                        ss[3:0] <= 0;
                        ss[7:4] <= ss[7:4] + 4'd1;
                    end
                    else 
                        ss[3:0] <= ss[3:0] + 4'd1;
                end
            end   
        end
      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 ssl_2_ssh,ssh_2_mml;   //地位向高位进位
    cnt cnt_ssl(.clk(clk),.reset(reset),.count_start(ena),.count_end(4'd9),.end_cnt(ssl_2_ssh),.count(ss[3:0]));
    cnt cnt_ssh(.clk(clk),.reset(reset),.count_start(ssl_2_ssh),.count_end(4'd5),.end_cnt(ssh_2_mml),.count(ss[7:4]));
   
    //例化计数器表示分钟
    wire mml_2_mmh, mmh_2_hh;
    cnt cnt_mml(.clk(clk),.reset(reset),.count_start(ssh_2_mml),.count_end(4'd9),.end_cnt(mml_2_mmh),.count(mm[3:0]));
    cnt cnt_mmh(.clk(clk),.reset(reset),.count_start(mml_2_mmh),.count_end(4'd5),.end_cnt(mmh_2_hh),.count(mm[7:4]));
    
    //小时计数
    reg a_2_p;
    always @(posedge clk)begin
        if(reset)begin
            a_2_p <= 0;
            hh <= 8'h12;        // 初始条件 12:00:00 AM
        end
        else if(mmh_2_hh)begin
            if(hh == 8'h12)
                hh <= 8'h01;
            else begin
                hh <= hh + 1'b1;
                if(hh == 8'h09)
                    hh <= 8'h10;
                if(hh == 8'h11)
                    a_2_p <= ~ a_2_p;
            end
        end
    end
    assign pm = a_2_p;
endmodule
//计数器子模块,可以设置开始和结束条件
module cnt(
    input clk,
    input reset,
    input count_start,     //开始计数输入
    input [3:0] count_end, //计数到多少停止计数
    output end_cnt,        //一次计数完成标志
    output [3:0] count);
 
    wire add_cnt;
    always @(posedge clk)begin
        if(reset)begin
           count <= 4'd0; 
        end
        else if(add_cnt)begin
            if(end_cnt)
                count <= 4'd0;
            else
                count <= count + 1'b1;
        end
    end
    assign add_cnt = count_start;   //计数开始条件,当满足了开始计数
    assign end_cnt = add_cnt && count == count_end;    //计数结束产生一个标志
endmodule


沒有留言:

張貼留言

2024_09 作業3 以Node-Red 為主

 2024_09 作業3  (以Node-Red 為主  Arduino 可能需要配合修改 ) Arduino 可能需要修改的部分 1)mqtt broker  2) 主題Topic (發行 接收) 3) WIFI ssid , password const char br...