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)百分之一秒:

VHDL7段数码管秒表设计_第1张图片

(3)秒:

VHDL7段数码管秒表设计_第2张图片

(4)分钟:

VHDL7段数码管秒表设计_第3张图片

上图显示的时间为58:00:41

58分00秒41百分之一秒。

你可能感兴趣的:(VHDL7段数码管秒表设计)