名稱:基于VHDL的倒計時控制器設計Basys3開發(fā)板驗證(代碼在文末下載)
軟件:VIVADO
語言:VHDL
代碼功能:
倒計時控制器:
1、可以通過按鍵切換倒計時狀態(tài)、設置狀態(tài)。
2、在設置狀態(tài)下設計倒計時的時間,通過上下兩個按鍵控制時間加減。
3、時間設置好后,通過按鍵切換到倒計時狀態(tài),從設置的時間開始倒計時。
FPGA代碼Verilog/VHDL代碼資源下載:www.hdlcode.com
本代碼已在Basys3開發(fā)板驗證,開發(fā)板如下,其他開發(fā)板可以修改管腳適配:
演示視頻:
設計文檔:
1. 工程文件
2. 程序文件
3. 程序編譯
4. 仿真圖
4.1 main1_one_digit模塊仿真
Testbench
仿真圖
4.2 main2_four_digits模塊仿真
Testbench
仿真圖
4.3 整體仿真
Testbench
仿真圖
部分代碼展示:
LIBRARY?ieee; ???USE?ieee.std_logic_1164.all; ???USE?ieee.std_logic_unsigned.all; --計時模塊 ENTITY?downcnt_time?IS ???PORT?( ??????clk????????:?IN?STD_LOGIC;--100MHz ??????clk_5KHz???:?OUT?STD_LOGIC;--輸出5KHz,用于控制數(shù)碼管切換 ??????btnU???????:?IN?STD_LOGIC;--按鍵 ??????btnD???????:?IN?STD_LOGIC;--按鍵 ??????btnC???????:?IN?STD_LOGIC;--按鍵 ??????d3?????????:?OUT?STD_LOGIC_VECTOR(3?DOWNTO?0);--分鐘十位 ??????d2?????????:?OUT?STD_LOGIC_VECTOR(3?DOWNTO?0);--分鐘個位 ??????d1?????????:?OUT?STD_LOGIC_VECTOR(3?DOWNTO?0);--秒鐘十位 ??????d0?????????:?OUT?STD_LOGIC_VECTOR(3?DOWNTO?0)--秒鐘十位 ???); END?downcnt_time; ARCHITECTURE?Behavioral?OF?downcnt_time?IS --定義信號 ???TYPE?State_type?IS?(s_timing,?s_set,?s_setting,?s_time);??--?定義狀態(tài) ???SIGNAL?state?:?State_Type;????--?創(chuàng)建信號 ???SIGNAL?clk_1Hz????:?STD_LOGIC;--1hz,用于計時 ???SIGNAL?clk_5K?????:?STD_LOGIC?:=?'0'; ???SIGNAL?count_1Hz??????:?integer?:=?0; ???SIGNAL?count_5KHz?????:?integer?:=?0;?? ???SIGNAL?btnU_dff1??:?STD_LOGIC; ???SIGNAL?btnU_dff2??:?STD_LOGIC; ???SIGNAL?btnD_dff1??:?STD_LOGIC; ???SIGNAL?btnD_dff2??:?STD_LOGIC; ???SIGNAL?btnU_push????:?STD_LOGIC; ???SIGNAL?btnD_push????:?STD_LOGIC; ???SIGNAL?Min_10?:?STD_LOGIC_VECTOR(3?DOWNTO?0)?:=?"0000";--分鐘十位 ???SIGNAL?Min_1?:?STD_LOGIC_VECTOR(3?DOWNTO?0)?:=?"0000";--分鐘個位 ???SIGNAL?Sec_10?:?STD_LOGIC_VECTOR(3?DOWNTO?0)?:=?"0000";--秒鐘十位 ???SIGNAL?Sec_1?:?STD_LOGIC_VECTOR(3?DOWNTO?0)?:=?"0000";--秒鐘十位 BEGIN ???PROCESS?(clk) ???BEGIN ??????IF?(clk'EVENT?AND?clk?=?'1')?THEN ?????????IF?(count_5KHz?>=?100)?THEN--100MHz計數(shù)10000后翻轉(zhuǎn)得到5KHz的信號,仿真時將10000改小為100 ????????????count_5KHz?<=?0; ????????????clk_5K?<=?NOT(clk_5K);--翻轉(zhuǎn),得到5Khz ?????????ELSE ????????????count_5KHz?<=?count_5KHz?+?1;--計數(shù) ?????????END?IF; ??????END?IF; ???END?PROCESS; ??? ???clk_5KHz?<=?clk_5K;--輸出5KHz ??? ???PROCESS?(clk) ???BEGIN ??????IF?(clk'EVENT?AND?clk?=?'1')?THEN ?????????IF?(count_1Hz?>=?1000)?THEN--100MHz分頻到1Hz,計數(shù)100000000,仿真時減小為1000 ????????????count_1Hz?<=?0; clk_1Hz?<=?'1';--得到1Hz信號脈沖 ?????????ELSE ????????????count_1Hz?<=?count_1Hz?+?1;--計數(shù) clk_1Hz?<=?'0'; ?????????END?IF; ??????END?IF; ???END?PROCESS; ??? ???--狀態(tài)控制 ???PROCESS?(clk) ???BEGIN ??????IF?(clk'EVENT?AND?clk?=?'1')?THEN ?????????CASE?state?IS ????????????WHEN?s_timing?=>--計時狀態(tài) ???????????????IF?(btnC?=?'1')?THEN--btnC按下 ??????????????????state?<=?s_set; ???????????????ELSE ??????????????????state?<=?s_timing; ???????????????END?IF; ????????????WHEN?s_set?=>--btnC按鍵按下 ???????????????IF?(btnC?=?'0')?THEN--btnC按鍵松開 ??????????????????state?<=?s_setting;--進入設置狀態(tài) ???????????????ELSE ??????????????????state?<=?s_set; ???????????????END?IF; ????????????WHEN?s_setting?=>--設置狀態(tài) ???????????????IF?(btnC?=?'1')?THEN--btnC按下 ??????????????????state?<=?s_time; ???????????????ELSE ??????????????????state?<=?s_setting; ???????????????END?IF; ????????????WHEN?s_time?=>--btnC按下 ???????????????IF?(btnC?=?'0')?THEN--btnC按鍵松開 ??????????????????state?<=?s_timing;--進入計時狀態(tài) ???????????????ELSE ??????????????????state?<=?s_time; ???????????????END?IF; ????????????WHEN?OTHERS?=> ?????????END?CASE; ??????END?IF; ???END?PROCESS; ??? ???--使用D觸發(fā)器將btnU和btnD緩存 ???PROCESS?(clk) ???BEGIN ??????IF?(clk'EVENT?AND?clk?=?'1')?THEN ?????????btnU_dff1?<=?btnU; ?????????btnU_dff2?<=?btnU_dff1; ?????????btnD_dff1?<=?btnD; ?????????btnD_dff2?<=?btnD_dff1; ??????END?IF; ???END?PROCESS; ??? ???--得到btnU和btnD的按鍵上升沿,只保持一個時鐘周期的高電平 ???btnU_push?<=?btnU_dff1?AND?NOT(btnU_dff2); ???btnD_push?<=?btnD_dff1?AND?NOT(btnD_dff2); ??? ???PROCESS?(clk) ???BEGIN ??????IF?(clk'EVENT?AND?clk?=?'1')?THEN ?????????IF?(state?=?s_setting)?THEN--設置時間狀態(tài) ????????????IF?(btnU_push?=?'1')?THEN--btnU按鍵按下,控制分鐘時間加 ???????????????IF?(Min_10?=?"1001"?AND?Min_1?=?"1001")?THEN--分鐘為99時,不再增加 ??????????????????Min_10?<=?"1001"; ??????????????????Min_1?<=?"1001"; ???????????????ELSIF?(Min_1?=?"1001")?THEN--分鐘個位是9 ??????????????????Min_10?<=?Min_10?+?"0001";--十位加1 ??????????????????Min_1?<=?"0000"; ???????????????ELSE ??????????????????Min_10?<=?Min_10; ??????????????????Min_1?<=?Min_1?+?"0001";--個位加1 ???????????????END?IF; ????????????ELSIF?(btnD_push?=?'1')?THEN--btnU按鍵按下,控制分鐘時間減 ???????????????IF?(Min_10?=?"0000"?AND?Min_1?=?"0000")?THEN--時間減到0,不再減 ??????????????????Min_10?<=?"0000"; ??????????????????Min_1?<=?"0000"; ???????????????ELSIF?(Min_1?=?"0000")?THEN--個位為0 ??????????????????Min_10?<=?Min_10?-?"0001";--十位減1 ??????????????????Min_1?<=?"1001"; ???????????????ELSE ??????????????????Min_10?<=?Min_10; ??????????????????Min_1?<=?Min_1?-?"0001";--個位減1 ???????????????END?IF; ????????????END?IF; ?????????ELSIF?(state?=?s_timing)?THEN--倒計時狀態(tài) ????????????IF?(clk_1Hz?=?'1')?THEN ???????????????IF?(Min_10?=?"0000"?AND?Min_1?=?"0000"?AND?Sec_10?=?"0000"?AND?Sec_1?=?"0000")?THEN--減到0,倒計時結(jié)束 ??????????????????Min_10?<=?"0000"; ??????????????????Min_1?<=?"0000"; ???????????????ELSIF?(Min_1?=?"0000"?AND?Sec_10?=?"0000"?AND?Sec_1?=?"0000")?THEN-- ??????????????????Min_10?<=?Min_10?-?"0001";--分鐘十位減1 ??????????????????Min_1?<=?"1001"; ???????????????ELSIF?(Sec_10?=?"0000"?AND?Sec_1?=?"0000")?THEN ??????????????????Min_10?<=?Min_10; ??????????????????Min_1?<=?Min_1?-?"0001";--分鐘個位減1 ???????????????ELSE ??????????????????Min_10?<=?Min_10; ??????????????????Min_1?<=?Min_1; ???????????????END?IF; ????????????END?IF; ?????????END?IF; ??????END?IF; ???END?PROCESS;
點擊鏈接獲取代碼文件:http://www.hdlcode.com/index.php?m=home&c=View&a=index&aid=295
閱讀全文