大三下學期的實驗,沒有錄製視頻,貼出代碼,僅供參考:
它具有計時功能。此秒錶有兩個按鍵(reset, start)按下reset鍵後,秒錶清零,按下start鍵後,開始計時, 再次按下start鍵後, 停止計時, 用FPGA開發板上的兩個七段數碼管顯示時間(以秒爲單位),計時由0 到 59 循環。還有一個按鍵(select),用於輪流切換兩個七段數碼管分別顯示百分之一秒,秒,分鐘。
1、按鍵消抖模塊:
library IEEE;
USEIEEE.std_logic_1164.all;
ENTITY key_delayIS
port( clk_key_delay_in:instd_logic;
reset_key_delay_in: in std_logic;
start_key_delay_in: in std_logic;
select_key_delay_in: in std_logic;
start_key_delay_out: out std_logic;
select_key_delay_out:outstd_logic--最後一行不能加分號
);
END key_delay;
architectureb_key_delay of key_delay is
type state is (s0,s1,s2);--狀態機類型
type state1 is (s0,s1,s2);--狀態機類型
signal current:state;
signal current1:state;
begin
process(reset_key_delay_in,clk_key_delay_in,start_key_delay_in)
begin
if(reset_key_delay_in ='1') then
start_key_delay_out<='0';
current <= s0;
elsif(clk_key_delay_in'eventand clk_key_delay_in='1')then
case current is
when s0 =>
start_key_delay_out<='0';
if(start_key_delay_in='1')then
current<= s1;
else
current<= s0;
endif;
when s1 =>
start_key_delay_out<='0';
if(start_key_delay_in='1')then
current<= s2;
else
current<= s0;
endif;
when s2 =>
--start_key_delay_out<='1';此處輸出高電平
if(start_key_delay_in='1')then
current<= s2;
else
start_key_delay_out<='1';--此處輸出單脈衝
current<= s0;
endif;
when others=>
current<= s0;
start_key_delay_out<='0';
end case;
end if;
end process;
process(reset_key_delay_in,clk_key_delay_in,select_key_delay_in)
begin
if(reset_key_delay_in ='1') then
select_key_delay_out<='0';
current1 <= s0;
elsif(clk_key_delay_in'event and clk_key_delay_in='1')then
case current1 is
when s0 =>
select_key_delay_out<='0';
if(select_key_delay_in='1')then
current1<= s1;
else
current1<= s0;
endif;
when s1 =>
select_key_delay_out<='0';
if(select_key_delay_in='1')then
current1<= s2;
else
current1<= s0;
end if;
when s2 =>
select_key_delay_out<='1';
if(select_key_delay_in='1')then
current1<= s2;
else
current1<= s0;
endif;
when others=>
current1<= s0;
select_key_delay_out<='0';
end case;
end if;
end process;
end;
2、計時和數據選擇模塊:
library IEEE;
USEIEEE.std_logic_1164.all;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY count IS
port( clk_count_in :in std_logic;
reset_count_in :in std_logic;
start_count_in :in std_logic; --控制計時的開始
select_seg_in :in std_logic; --控制輸出的數據
count1ms_out :out std_logic; --1ms使能時鐘輸出,用於按鍵檢測
data1_out :out std_logic_vector(3 downto 0); --輸出的第1位
data2_out :out std_logic_vector(3 downto 0); --輸出的第2位
data3_out :out std_logic_vector(3 downto 0); --輸出的第3位
data4_out :out std_logic_vector(3 downto 0) --輸出的第4位
);
end count;
architectureb_count of count is
signal count_1ms :std_logic_vector(15 downto 0); --50_000
signal count_10ms :std_logic_vector(4 downto 0); --10
signal count_1s :INTEGER RANGE 99 downto 0 ; --100
signal count_1min :INTEGER RANGE 59 downto 0 ; --60
signal count_1h :INTEGER RANGE 59 downto 0 ; --60
signal count2_1s :std_logic_vector(3 downto 0);
signal count2_1min:std_logic_vector(3downto 0);
signal count2_1h :std_logic_vector(3 downto 0);
signal count3_1s :std_logic_vector(3 downto 0);
signal count3_1min:std_logic_vector(3downto 0);
signal count3_1h :std_logic_vector(3 downto 0);
signal signal_1ms :std_logic;
signal signal_10ms :std_logic;
signal signal_1s :std_logic;
signal signal_1min :std_logic;
signal signal_start :std_logic;
type state is (s0,s1,s2,s3);--狀態機類型
signal current:state;
begin
process(start_count_in,reset_count_in)
begin
if(reset_count_in='1')then
signal_start<= '0';
elsif(start_count_in'eventand start_count_in ='0')then--檢測到下降沿纔開始響應
if signal_start ='0' then
signal_start<='1';
else
signal_start<='0';
end if;
end if;
end process;
process (clk_count_in,reset_count_in)--1ms計時
begin
if(reset_count_in='1')then
count_1ms <= (others =>'0');
signal_1ms <='0';
elsif(clk_count_in'eventand clk_count_in='1')then
if count_1ms =49_999 then
signal_1ms <= '1';
count_1ms <= (others =>'0');
else
signal_1ms <= '0'; --signal_1ms的高電平持續了一個週期的clk_count_in
count_1ms <= count_1ms+1;
end if;
end if;
end process;
count1ms_out <= signal_1ms; --1ms使能輸出
process(signal_1ms,reset_count_in)--10ms計時
begin
if(reset_count_in='1')then
count_10ms <= (others =>'0');
signal_10ms <='0';
elsif(signal_1ms'event andsignal_1ms='1')then
if(signal_start= '0')then
if count_10ms= 9 then
signal_10ms <= '1';
count_10ms <= (others =>'0');
else
signal_10ms <= '0'; --signal_10ms的高電平持續了一個週期的signal_1ms,即持續了1ms
count_10ms <= count_10ms+1;
end if;
end if;
end if;
end process;
process(signal_10ms,reset_count_in)--1s計時,990ms
begin
if(reset_count_in='1')then
count_1s <= 0;
count2_1s <="0000";
count3_1s <="0000";
signal_1s <='0';
elsif(signal_10ms'event andsignal_10ms='1')then
if count_1s = 99then
signal_1s<='1';
count_1s <= 0;
else
signal_1s <= '0'; --signal_1s的高電平持續了一個週期的signal_10ms,即持續了10ms
count_1s <= count_1s+1;
end if;
if count2_1s ="1001" then --9
count2_1s<="0000";
if count3_1s= "1001" then --9
count3_1s<="0000";
else
count3_1s<= count3_1s+1;
end if;
else
count2_1s<= count2_1s+1;
end if;
end if;
end process;
process(signal_1s,reset_count_in)--1min計時 59s
begin
if(reset_count_in='1')then
count_1min <= 0;
count2_1min<="0000";
count3_1min<="0000";
signal_1min <='0';
elsif(signal_1s'event andsignal_1s='1')then
if count_1min = 59then
signal_1min <= '1';
count_1min <= 0;
else
signal_1min <= '0'; --signal_1min的高電平持續了一個週期的signal_1s,即持續了1s
count_1min <= count_1min+1;
end if;
if count2_1min ="1001" then --9
count2_1min<="0000";
ifcount3_1min = "0101" then --5
count3_1min<="0000";
else
count3_1min<= count3_1min+1;
end if;
else
count2_1min<= count2_1min+1;
end if;
end if;
end process;
process(signal_1min,reset_count_in)--1h計時
begin
if(reset_count_in='1')then
count_1h <= 0;
count2_1h<="1000";
count3_1h<="0101";
elsif(signal_1min'event andsignal_1min='1')then
if count_1h = 59then
count_1h <= 0;
else
count_1h <= count_1h+1;
end if;
if count2_1h ="1001" then --9
count2_1h<="0000";
if count3_1h= "0101" then --5
count3_1h<="0000";
else
count3_1h<= count3_1h+1;
end if;
else
count2_1h <= count2_1h+1;
end if;
end if;
end process;
process (select_seg_in)
begin
if(select_seg_in'event andselect_seg_in='0')then
case current is
when s0 =>
current<= s1;
when s1 =>
current<= s2;
when s2 =>
current<= s3;
when s3 =>
current<= s0;
when others=>
current<= s0;
end case;
end if;
end process;
process(clk_count_in,reset_count_in)--1min計時
begin
if(reset_count_in='1')then--按鍵按下爲高電平
data1_out <="1111";
data2_out <="1111";
data3_out <="1111";
data4_out <="1111";
elsif(clk_count_in'eventand clk_count_in='1')then
case current is
when s0 =>--此狀態4個數碼管都顯示,顯示秒和分
data1_out<=count2_1min; --0~9
data2_out<=count3_1min; --0~5
data3_out<=count2_1h; --0~9
data4_out<=count3_1h; --0~5
when s1=>--此狀態2個數碼管都顯示,顯示百分毫秒
data1_out<=count2_1s; --0~9
data2_out<=count3_1s; --0~9
data3_out<="1111";
data4_out<="1111";
when s2 => --此狀態2個數碼管都顯示,顯示秒
data1_out<=count2_1min; --0~9
data2_out<=count3_1min; --0~5
data3_out<="1111";
data4_out<="1111";
when s3 =>--此狀態2個數碼管都顯示,顯示分
data1_out<=count2_1h; --0~9
data2_out<=count3_1h; --0~5
data3_out<="1111";
data4_out<="1111";
when others=> --全滅
data1_out<="1111";
data2_out<="1111";
data3_out<="1111";
data4_out<="1111";
end case;
end if;
end process;
end;
3、數碼管驅動模塊:
library IEEE;
USEIEEE.std_logic_1164.all;
USEieee.std_logic_signed.all;
ENTITY seg IS
port( clk_seg_in :in std_logic;
reset_seg_in :in std_logic;
data1_in :in std_logic_vector(3 downto0);
data2_in :in std_logic_vector(3 downto0);
data3_in :in std_logic_vector(3 downto0);
data4_in :in std_logic_vector(3 downto0);
wei :out std_logic_vector(3downto 0); --位選
duan :outstd_logic_vector(7 downto 0) --段選
);
end seg;
architectureb_seg of seg is
signal CNT4:std_logic_vector(1 downto 0);
begin
process(clk_seg_in,reset_seg_in)--掃描顯示進程
begin
if(reset_seg_in='1')then --按鍵按下爲高電平
CNT4 <= (others =>'0');
elsif(clk_seg_in'event andclk_seg_in='1')then
if CNT4 ="11" THEN
CNT4 <="00";
else
CNT4 <=CNT4 + 1;
end if;
end if;
end process;
process(CNT4,reset_seg_in)
variable data:std_logic_vector(3downto 0);
begin
if(reset_seg_in='1')then --按鍵按下爲高電平
wei <= (others =>'1');
data := (others =>'1');
else
case CNT4 is
when"00" => data := data1_in; wei <= "1110";
when"01" => data := data2_in; wei <= "1101";
when"10" => data := data3_in; wei <= "1011";
when"11" => data := data4_in; wei <= "0111";
when others=> wei <= "1111";
end case;
end if;
case data is
when"0000" => duan <= "00000011"; --0
when"0001" => duan <= "10011111"; --1
when"0010" => duan <= "00100101"; --2
when"0011" => duan <= "00001101"; --3
when"0100" => duan <= "10011001"; --4
when"0101" => duan <= "01001001"; --5
when"0110" => duan <= "01000001"; --6
when"0111" => duan <= "00011111"; --7
when"1000" => duan <= "00000001"; --8
when"1001" => duan <= "00001001"; --9
WHEN OTHERS =>duan <= "11111111"; --熄滅
end case;
end process;
end;
5、頂層模塊:
library IEEE;
USEIEEE.std_logic_1164.all;
ENTITYMiaoBiao_top IS
PORT ( clk :instd_logic;
reset :in std_logic;
start :in std_logic;
selectt :in std_logic;
seg_wei :out std_logic_vector(3 downto 0);
seg_duan :out std_logic_vector(7 downto 0)
);
ENDMiaoBiao_top;
architecture aof MiaoBiao_top is
component key_delay --聲明消抖模塊
port( clk_key_delay_in :instd_logic;
reset_key_delay_in :in std_logic;
start_key_delay_in :in std_logic;
select_key_delay_in :in std_logic;
start_key_delay_out :out std_logic;
select_key_delay_out :out std_logic--最後一行不能加分號
);
end component;
component count --計數器
port( clk_count_in :in std_logic;
reset_count_in :in std_logic;
start_count_in :in std_logic; --控制計時的開始
select_seg_in :in std_logic; --控制輸出的數據
count1ms_out :out std_logic; --1ms使能時鐘輸出,用於按鍵檢測,和數碼管動態掃描
data1_out :out std_logic_vector(3 downto 0); --輸出的第1位
data2_out :out std_logic_vector(3 downto 0); --輸出的第2位
data3_out :out std_logic_vector(3 downto 0); --輸出的第3位
data4_out :out std_logic_vector(3 downto 0) --輸出的第4位
);
end component;
component seg --數碼管顯示
port( clk_seg_in :in std_logic;
reset_seg_in :in std_logic;
data1_in :in std_logic_vector(3 downto 0);
data2_in :in std_logic_vector(3 downto0);
data3_in :in std_logic_vector(3 downto0);
data4_in :in std_logic_vector(3 downto0);
wei: out std_logic_vector(3downto 0); --位選
duan: outstd_logic_vector(7 downto 0) --段選
);
end component;
signal start_signal :std_logic;
signal select_signal :std_logic;
signal count1ms_signal :std_logic;
signal data1_signal :std_logic_vector(3 downto 0);
signal data2_signal :std_logic_vector(3 downto 0);
signal data3_signal :std_logic_vector(3 downto 0);
signal data4_signal :std_logic_vector(3 downto 0);
begin
u1:key_delay port map ( count1ms_signal,
reset,
start,
selectt,
start_signal,
select_signal
);
u2:count port map ( clk,
reset,
start_signal,
select_signal,
count1ms_signal,
data1_signal,
data2_signal,
data3_signal,
data4_signal
);
u3:seg port map ( count1ms_signal,
reset,
data1_signal,
data2_signal,
data3_signal,
data4_signal,
seg_wei,
seg_duan
);
end;
FPGA開發板截圖:
(1)初始狀態
(2)百分之一秒:
(3)秒:
(4)分鐘:
上圖顯示的時間爲58:00:41
58分00秒41百分之一秒。