本文為大家介紹電子計時器的VHDL設(shè)計方法。
設(shè)計要求
設(shè)計一個電子計時器,給定時鐘信號為512HZ,要求系統(tǒng)達到以下功能:
(1)用6個數(shù)碼管分別顯示時、分、秒,計時范圍為00:00:00~23:59:59。
(2)計時精度是1s。
(3)具有啟/ 停開關(guān), 復(fù)位開關(guān)。
總體方框圖
內(nèi)部各功能模塊
本系統(tǒng)由六十進制計數(shù)器模塊、二十四進制計數(shù)器模塊、分頻模塊執(zhí)行計時功能, 輸入信號是512Hz,通過分頻后為1Hz,時鐘信號是1Hz作為計時器的秒輸入,秒為60進制計數(shù)器,分也為60進制計數(shù)器,小時采用二十四進制計數(shù)器, 各級進位作為高位的使能控制。
六十進制計數(shù)器模塊
設(shè)計一個八位的六十進制計數(shù)器模塊,輸入信號為en、reset、clk,分別為使能、復(fù)位和時鐘信號,輸出信號為qa[3?0]、qb[3?0]、rco,分別為低4位輸出、高4位輸出和進位位。
六十進制計數(shù)器
示波形分析
秒計數(shù)器的仿真波形圖
利用60進制計數(shù)器完成00到59的循環(huán)計數(shù)功能,當(dāng)秒計數(shù)至59時,再來一個時鐘脈沖則產(chǎn)生進位輸出,即enmin=1;reset作為復(fù)位信號低電平有效,即高電平時正常循環(huán)計數(shù),低電平清零。因為這種60進制的VHDL語言是很好寫的,它并不復(fù)雜,再說我們必須要學(xué)會這些基本的硬件語言的描寫。
分鐘計數(shù)器的仿真波形圖
VHDL源程序
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.ALL;
ENTITY count60 IS
PORT( en,Reset,clk: in STD_LOGIC;
qa: out STD_LOGIC_VECTOR(3 DOWNTO 0);
qb: out STD_LOGIC_VECTOR(3 DOWNTO 0);
rco: OUT STD_LOGIC); END count60;
ARCHITECTURE a OF count60 IS
BEGIN
process(clk)
variable tma: STD_LOGIC_VECTOR(3 DOWNTO 0);
variable tmb: STD_LOGIC_VECTOR(3 DOWNTO 0); begin
If Reset =‘0’then tma:=“0000”;
tmb:=“0000”;
elsif clk‘event and clk=’1‘ then
if en=’1‘ then
rco<=tmb(2)and tmb(0)and tma(3)and tma(0);
if tma=“1001” then
tma:=“0000”;
if tmb=“0101” then
tmb:=“0000”;
else tmb:=tmb+1;
end if;
else tma:=tma+1;
end if;
end if;
end if;
qa<=tma;qb<=tmb; end process; END a;
二十四進制計數(shù)器模塊
設(shè)計一個八位的二十四進制計數(shù)器模塊,輸入信號為en、reset、clk,分別為使能、復(fù)位和時鐘信號,輸出信號為qa[3?0]、qb[3?0],分別為低4位輸出、高4位輸出。
二十四進制計數(shù)器示意圖
波形分析
小時計數(shù)器的仿真波形圖
VHDL源程序
小時計數(shù)模塊利用24進制計數(shù)器,通過分鐘的進位信號的輸入可實現(xiàn)從00到23的循環(huán)計數(shù)。
該模塊部分VHDL 源程序如下:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.ALL;
ENTITY count24 IS
PORT( en,Reset,clk: in STD_LOGIC;
qa: out STD_LOGIC_VECTOR(3 DOWNTO 0);
qb: out STD_LOGIC_VECTOR(3 DOWNTO 0));
END count24;
ARCHITECTURE a1 OF count24 IS
BEGIN
process(clk)
variable tma: STD_LOGIC_VECTOR(3 DOWNTO 0);
variable tmb: STD_LOGIC_VECTOR(3 DOWNTO 0);
begin
If Reset = ‘0’then tma:=“0000”;
tmb:=“0000”; else
if clk‘event and clk=’1‘ then
if en=’1‘ then
if tma=“1001” then
tma:=“0000”;
tmb:=tmb+1;
elsif tmb=“0010” and tma=“0011” then
tma:=“0000”;
tmb:=“0000”;
else tma:=tma+1;
end if;
end if;
end if;
end if;
qa<=tma;
qb<=tmb;
end process;
END a1;
分頻器模塊
設(shè)計一個分頻器,要求將輸入512HZ的時鐘信號分頻為1HZ的時鐘信號作為計時器的秒輸入。輸入信號為clk和rst,分別為時鐘信號和復(fù)位信號,輸出信號為clk_out,為分頻器1HZ的時鐘信號輸出。
分頻器示意圖
VHDL 源程序
該模塊部分VHDL 源程序如下:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY fenpinqi IS
PORT (CLK,RST:in std_logic;
CLK_OUT:out std_logic);
END fenpinqi;
ARCHITECTURE behav OF fenpinqi IS
signal clk_data:std_logic;
SIGNAL CNT6 :
INTEGER := 0;
BEGIN
PROCESS(CLK)
BEGIN
IF RST = ‘0’ THEN CNT6<=0
ELSIF CLK‘EVENT AND CLK=’1‘ THEN
IF CNT6=255 THEN
clk_data<=NOT clk_data;
CNT6<=0;
ELSE CNT6<=CNT6+1;
END IF;
END IF;
CLK_OUT<=clk_data;
END PROCESS;
END behav;
LED顯示模塊
LED有著顯示亮度高,響應(yīng)速度快的特點,最常用的是七段式LED顯示器,又稱數(shù)碼管。七段LED顯示器內(nèi)部由七個條形發(fā)光二極管和一個小圓點發(fā)光二極管組成,根據(jù)各管的亮暗組合成字符。
LED數(shù)碼管的g~a七個發(fā)光二極管因加正電壓而發(fā)亮,因加零電壓而不能發(fā)亮,不同亮暗的組合就能形成不同的字形,這種組合稱之為字形碼(段碼),如顯示”0”,字形碼為3fh。
LED數(shù)碼管結(jié)構(gòu)圖
數(shù)碼管的接口有靜態(tài)接口和動態(tài)接口。動態(tài)接口采用各數(shù)碼管循環(huán)輪流顯示的方法,當(dāng)循環(huán)顯示頻率較高時,利用人眼的暫留特性,看不出閃爍顯示現(xiàn)象,這種顯示需要一個接口完成字形碼的輸出(字形選擇),另一接口完成各數(shù)碼管的輪流點亮(數(shù)位選擇)。
將二十四進制計數(shù)器和2個六十進制計數(shù)器的輸出作為LED顯示模塊的輸入,在時鐘信號的控制下通過此模塊完成6個LED數(shù)碼管的顯示,輸出信號為WEI[2…0]和LED[6…0],分別為位選信號和段碼輸出。
LED顯示示意圖
VHDL 源程序
該模塊部分VHDL 源程序如下:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY clock1 IS
PORT(CLK: IN STD_LOGIC;
S1, S2, S3, S4, S5, S6: IN STD_LOGIC_VECTOR(3 DOWNTO 0);
WEI: OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
LED: OUT STD_LOGIC_VECTOR(6 DOWNTO 0));
END ENTITY;
ARCHITECTURE behave OF clock1 IS
SIGNAL CNT6 : INTEGER RANGE 0 TO 5 := 0;
SIGNAL SHUJU: STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
PRO1:PROCESS(CLK)
BEGIN
IF CLK‘EVENT AND CLK = ’1‘ THEN
CNT6 <= CNT6 + 1;
CASE CNT6 IS
WHEN 0 => WEI <= “000”; SHUJU <= S1;
WHEN 1 => WEI <= “001”; SHUJU <= S2;
WHEN 2 => WEI <= “010”; SHUJU <= S3;
WHEN 3 => WEI <= “011”; SHUJU <= S4;
WHEN 4 => WEI <= “100”; SHUJU <= S5;
WHEN 5 => WEI <= “101”; SHUJU <= S6;
CNT6<=0;
WHEN OTHERS => NULL;
END CASE;
END IF;
END PROCESS;
PRO2: PROCESS(SHUJU)
BEGIN
CASE SHUJU IS
WHEN “0000” => LED<= “1111110”
WHEN “0001” => LED<= “0110000”
WHEN “0010” => LED<= “1101101”
WHEN “0011” => LED<= “1111001”
WHEN “0100” => LED<= “0110011”
WHEN “0101” => LED<= “1011011”
WHEN “0110” => LED<= “1011111”
WHEN “0111” => LED<= “1110000”
WHEN “1000” => LED<= “1111111”
WHEN “1001” => LED<= “1111011”
WHEN others=> LED<= “0000000”
END CASE;
END PROCESS;
END
頂層系統(tǒng)聯(lián)調(diào)
通過上面的分頻器,兩個60進制的計數(shù)器,一個12/24進制的計數(shù)器,6選1掃描器,7段數(shù)碼顯示器,設(shè)計如圖所示的頂層。規(guī)定每一模塊的功能和各模塊之間的接口。同時整個計數(shù)器有清零。 設(shè)計思想,利用脈沖時鐘產(chǎn)生一個1Hz的信號來實現(xiàn)一秒鐘的控制,要產(chǎn)生1Hz的信號就要用到分頻器,實驗中用512分頻器把512Hz的信號變成1Hz。然后信號進入控制秒的計數(shù)器,當(dāng)?shù)?0個脈沖時鐘到來時,產(chǎn)生一個進位信號, 送到控制分的計數(shù)器,同理,當(dāng)?shù)?0個脈沖時鐘到來時,產(chǎn)生一個進位信號,送到控制小時的計數(shù)器。當(dāng)小時計數(shù)器計數(shù)到12/24時,完成一個周期,跳轉(zhuǎn)到零。輸出是由動態(tài)掃描器來完成的。掃描器時鐘取至前面分頻未結(jié)束時的一個512Hz的信號。這樣就能夠在7段數(shù)碼顯示管上,以512Hz的頻率掃描顯示出時鐘的數(shù)字變化。
通過元件例化將各個模塊連接起來,組成一個整體。
元件例化就是將預(yù)先設(shè)計好的設(shè)計實體定義為一個元件,然后利用特定的語句將此元件與當(dāng)前的設(shè)計實體中的指定端口相連接,從而為當(dāng)前設(shè)計實體引入一個新的低一級的設(shè)計層次。所定義的例化元件相當(dāng)于一個要插在這個電路系統(tǒng)板上的芯片,而當(dāng)前設(shè)計實體中指定的端口則相當(dāng)于這塊電路板上準(zhǔn)備接受此芯片的一個插座。
VHDL 源程序
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_signed.all;
use ieee.std_logic_arith.all;
entity dzjsq is
port(en,clk,reset:in std_logic;
wei:out std_logic_vector(2 downto 0);
led:out std_logic_vector(7 downto 0));
end entity dzjsq;
architecture abc of dzjsq is
component count60
PORT( en,Reset,clk: in STD_LOGIC;
qa: out STD_LOGIC_VECTOR(3 DOWNTO 0);
qb: out STD_LOGIC_VECTOR(3 DOWNTO 0);
rco: OUT STD_LOGIC);
end component;
component count24
PORT( en,Reset,clk: in STD_LOGIC;
qa: out STD_LOGIC_VECTOR(3 DOWNTO 0);
qb: out STD_LOGIC_VECTOR(3 DOWNTO 0));
end component; component fenpinqi
PORT (CLK,RST:in std_logic; CLK_OUT:out std_logic);
end component; component clock1
PORT(CLK: IN STD_LOGIC;
S1, S2, S3, S4, S5, S6: IN STD_LOGIC_VECTOR(3 DOWNTO 0);
WEI: OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
LED: OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
end component;
signal a1,a2,a3,a4,a5,a6:std_logic_vector(3 downto 0);
signal b1,b2,b3: std_logic; begin
u1: fenpinqi port map(clk,reset,b1);
u2:count60 port map(en,reset,b1,a1,a2,b2);
u3:count60 port map(en,reset,b2,a3,a4,b3);
u4:count24 port map(en,reset,b3,a5,a6);
u5:clock1 port map(clk,a1,a2,a3,a4,a5,a6,wei,led);
end architecture abc;
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.ALL;
ENTITY count60 IS
PORT( en,Reset,clk: in STD_LOGIC;
qa: out STD_LOGIC_VECTOR(3 DOWNTO 0);
qb: out STD_LOGIC_VECTOR(3 DOWNTO 0);
rco: OUT STD_LOGIC);
END count60;
ARCHITECTURE a OF count60 IS
BEGIN
process(clk)
variable tma: STD_LOGIC_VECTOR(3 DOWNTO 0);
variable tmb: STD_LOGIC_VECTOR(3 DOWNTO 0);
begin
If Reset =‘0’then tma:=“0000”;
tmb:=“0000”;
elsif clk‘event and clk=’1‘ then
if en=’1‘ then
rco<=tmb(2)and tmb(0)and tma(3)and tma(0);
if tma=“1001” then
tma:=“0000”;
if tmb=“0101” then
tmb:=“0000”;
else tmb:=tmb+1;
end if;
else tma:=tma+1;
end if;
end if;
end if;
qa<=tma;
qb<=tmb;
end process;
END a;
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.ALL;
ENTITY count24 IS
PORT( en,Reset,clk: in STD_LOGIC;
qa: out STD_LOGIC_VECTOR(3 DOWNTO 0);
qb: out STD_LOGIC_VECTOR(3 DOWNTO 0));
END count24;
ARCHITECTURE a1 OF count24 IS
BEGIN
process(clk)
variable tma: STD_LOGIC_VECTOR(3 DOWNTO 0);
variable tmb: STD_LOGIC_VECTOR(3 DOWNTO 0);
begin
If Reset = ‘0’then tma:=“0000”;
tmb:=“0000”;
else if clk‘event and clk=’1‘ then
if en=’1‘ then
if tma=“1001” then
tma:=“0000”;
tmb:=tmb+1;
elsif tmb=“0010” and tma=“0011” then
tma:=“0000”;
tmb:=“0000”;
else tma:=tma+1;
end if;
end if;
end if;
end if;
qa<=tma;
qb<=tmb;
end process;
END a1; LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY fenpinqi IS
PORT (CLK,RST:in std_logic;
CLK_OUT:out std_logic);
END fenpinqi;
ARCHITECTURE behav OF fenpinqi IS signal clk_data:std_logic;
SIGNAL CNT6 : INTEGER := 0;
BEGIN
PROCESS(CLK) BEGIN
IF RST = ‘0’ THEN
CNT6<=0
ELSIF CLK‘EVENT AND CLK=’1‘ THEN
IF CNT6=512 THEN
clk_data<=NOT clk_data;
CNT6<=0;
ELSE CNT6<=CNT6+1;
END IF;
END IF;
CLK_OUT<=clk_data;
END PROCESS;
END behav;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY clock1 IS
PORT(CLK: IN STD_LOGIC;
S1, S2, S3, S4, S5, S6: IN STD_LOGIC_VECTOR(3 DOWNTO 0); WEI: OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
LED: OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END ENTITY;
ARCHITECTURE behave OF clock1 IS SIGNAL CNT6 : INTEGER RANGE 0 TO 5 := 0;
SIGNAL SHUJU: STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN PRO1:PROCESS(CLK)
BEGIN
IF CLK‘EVENT AND CLK = ’1‘ THEN
CNT6 <= CNT6 + 1;
CASE CNT6 IS
WHEN 0 => WEI <= “000”;
SHUJU <= S1; WHEN 1 => WEI <= “001”;
SHUJU <= S2; WHEN 2 => WEI <= “010”;
SHUJU <= S3; WHEN 3 => WEI <= “011”;
SHUJU <= S4; WHEN 4 => WEI <= “100”;
SHUJU <= S5;
WHEN 5 => WEI <= “101”;
SHUJU <= S6;
CNT6<=0;
WHEN OTHERS => NULL;
END CASE;
END IF;
END PROCESS;
PRO2: PROCESS(SHUJU)
BEGIN CASE SHUJU IS WHEN “0000” => LED<= x“3f”
WHEN “0001” => LED<= x“06”
WHEN “0010” => LED<= x“5b”
WHEN “0011” => LED<= x“4f”
WHEN “0100” => LED<= x“66”
WHEN “0101” => LED<= x“6d”
WHEN “0110” => LED<= x“7d”
WHEN “0111” => LED<= x“07”
WHEN “1000” => LED<= x“7f”
WHEN “1001” => LED<= x“6f”
WHEN others=> LED<= x“00”
END CASE;
END PROCESS;
END
電子計時器的功能仿真結(jié)果
-
vhdl
+關(guān)注
關(guān)注
30文章
817瀏覽量
128134 -
VHDL代碼
+關(guān)注
關(guān)注
2文章
13瀏覽量
20844 -
電子計時器
+關(guān)注
關(guān)注
0文章
4瀏覽量
3158
發(fā)布評論請先 登錄
相關(guān)推薦
評論