m基於FPGA的電子鐘verilog實現,可設定鬧鐘,包含testbench測試檔案

我爱C编程發表於2024-03-21

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

  

相關文章