VHDL7段數碼管秒錶設計

大三下學期的實驗,沒有錄製視頻,貼出代碼,僅供參考:

它具有計時功能。此秒錶有兩個按鍵(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百分之一秒。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章