1.演算法模擬效果
本系統進行Vivado2019.2平臺的開發,測試結果如下所示:
2.演算法涉及理論知識概要
電子鐘是現代生活中常見的計時工具,其準確性和功能性不斷提高。基於FPGA的電子鐘設計不僅具有靈活的可定製性,還能透過整合其他功能(如鬧鐘)來增強實用性。Verilog作為一種廣泛使用的硬體描述語言,為FPGA設計提供了強大的描述和模擬能力。FPGA是一種可透過程式設計配置實現特定功能的積體電路。它由可配置邏輯塊(CLB)、輸入輸出塊(IOB)和可程式設計互連資源組成。Verilog則是一種用於描述數字系統和模擬其行為的硬體描述語言。
2.1 電子鐘的計時原理
電子鐘的核心是一個計時器,通常由振盪器、分頻器和計數器組成。振盪器產生穩定的頻率訊號,分頻器將頻率降低到合適的水平以供計數器使用。計數器則根據分頻後的訊號進行累加,實現時間的計量。
在電子鐘設計中,通常需要多個計數器來分別計量小時、分鐘和秒。這些計數器之間的關係可以透過模運算來描述。例如,秒計數器每累計到60就歸零,並觸發分鐘計數器加1。
2.2 時間顯示方式
電子鐘的時間顯示通常採用2個十進位制格式。
2.3 鬧鐘設定與觸發機制
鬧鐘功能的實現需要額外的儲存器和比較器。儲存器用於儲存使用者設定的鬧鐘時間,比較器則不斷比較當前時間和鬧鐘時間。當兩者相等時,觸發鬧鐘訊號。
數學上,鬧鐘觸發可以表示為一個條件判斷:
(A = B)
其中,(A) 是當前時間,(B) 是設定的鬧鐘時間。當等式成立時,輸出鬧鐘訊號。
在實際設計中,由於時間訊號是連續變化的,而鬧鐘設定是靜態的,因此需要使用邊緣觸發或定時檢查的方式來檢測時間匹配條件。
3.Verilog核心程式
`timescale 1ns / 1ps module TEST(); reg i_clk; // 輸入時鐘 reg i_rst; // 非同步復位訊號 reg i_time_set; // 時間設定使能訊號 reg [3:0] i_set_miao01; // 設定的秒的個位 reg [3:0] i_set_miao10; // 設定的秒的十位 reg [3:0] i_set_fen01; // 設定的分的個位 reg [3:0] i_set_fen10; // 設定的分的十位 reg [3:0] i_set_shi01; // 設定的時的個位 reg [3:0] i_set_shi10; // 設定的時的十位 reg i_set_clock; // 鬧鐘設定使能訊號 reg [3:0] i_clock_fen01; // 鬧鐘設定的分的個位 reg [3:0] i_clock_fen10; // 鬧鐘設定的分的十位 reg [3:0] i_clock_shi01; // 鬧鐘設定的時的個位 reg [3:0] i_clock_shi10; // 鬧鐘設定的時的十位 wire o_clock_flager; // 鬧鐘標誌輸出,當時間匹配時為高電平 wire [3:0] o_miao01; // 輸出的秒的個位 wire [3:0] o_miao10; // 輸出的秒的十位 wire [3:0] o_fen01; // 輸出的分的個位 wire [3:0] o_fen10; // 輸出的分的十位 wire [3:0] o_shi01; // 輸出的時的個位 wire [3:0] o_shi10; // 輸出的時的十位 tops tops_u( .i_clk (i_clk), // 輸入時鐘 .i_rst (i_rst), // 非同步復位訊號 .i_time_set (i_time_set), // 時間設定使能訊號 .i_set_miao01 (i_set_miao01), // 設定的秒的個位 .i_set_miao10 (i_set_miao10), // 設定的秒的十位 .i_set_fen01 (i_set_fen01), // 設定的分的個位 .i_set_fen10 (i_set_fen10), // 設定的分的十位 .i_set_shi01 (i_set_shi01), // 設定的時的個位 .i_set_shi10 (i_set_shi10), // 設定的時的十位 .i_set_clock (i_set_clock), // 鬧鐘設定使能訊號 .i_clock_fen01 (i_clock_fen01), // 鬧鐘設定的分的個位 .i_clock_fen10 (i_clock_fen10), // 鬧鐘設定的分的十位 .i_clock_shi01 (i_clock_shi01), // 鬧鐘設定的時的個位 .i_clock_shi10 (i_clock_shi10), // 鬧鐘設定的時的十位 .o_clock_flager (o_clock_flager), // 鬧鐘標誌輸出,當時間匹配時為高電平 .o_miao01 (o_miao01), // 輸出的秒的個位 .o_miao10 (o_miao10), // 輸出的秒的十位 .o_fen01 (o_fen01), // 輸出的分的個位 .o_fen10 (o_fen10), // 輸出的分的十位 .o_shi01 (o_shi01), // 輸出的時的個位 .o_shi10 (o_shi10) // 輸出的時的十位 ); always #5 i_clk = !i_clk; initial begin i_clk = 1'b1; i_rst = 1'b1; #1000 i_rst = 1'b0; end initial begin i_time_set = 1'b0; i_set_miao01 = 4'd0; i_set_miao10 = 4'd0; i_set_fen01 = 4'd0; i_set_fen10 = 4'd0; i_set_shi01 = 4'd0; i_set_shi10 = 4'd0; end initial begin i_set_clock = 1'b0; i_clock_fen01 = 4'd0; i_clock_fen10 = 4'd0; i_clock_shi01 = 4'd0; i_clock_shi10 = 4'd0; #1000 i_set_clock = 1'b1;//鬧鐘設定為15點40分 i_clock_fen01 = 4'd0; i_clock_fen10 = 4'd4; i_clock_shi01 = 4'd5; i_clock_shi10 = 4'd1; end endmodule