【FPGA】篮球计分计时系统

本设计是基于FPGA的篮球计时计分器,利用7段共阴LED作为显示器件。在此设计中共接入了1个四位一体7段共阴LED显示器,2个三位一体7段共阴LED显示器,前者用来记录赛程时间,其中2位用于显示分钟,2位用于显示秒钟,后者用于记录甲乙队的分数,每队3个LED显示器显示范围可达到0~999分。赛程计时采用倒计时方式,比赛开始时启动计时,直至计时到零为止。

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity basket is
    port(   clk     :in  std_logic;
            key     :in  std_logic_vector(7 downto 0);
            duan    :out std_logic_vector(6 downto 0);
            wei     :out std_logic_vector(9 downto 0)
        );
end entity;

architecture behavior of basket is
    
    signal clk_5k      :std_logic;
    signal firb        :integer range 0 to 9:=0;
    signal firs        :integer range 0 to 9:=0;
    signal firg        :integer range 0 to 9:=0;
    signal secb        :integer range 0 to 9:=0;
    signal secs        :integer range 0 to 9:=0;
    signal secg        :integer range 0 to 9:=0;
    signal fens        :integer range 0 to 9:=9;
    signal feng        :integer range 0 to 9:=9;
    signal mios        :integer range 0 to 9:=5;
    signal miog        :integer range 0 to 9:=9;
    signal we          :integer range 0 to 9:=0;
    signal state       :integer range 0 to 2:=0;
    signal run         :std_logic;
    
    begin
    
    process(clk)
        variable cnt1    :integer range 0 to 100 :=0;
        variable cnt2    :integer range 0 to 100 :=0;
        begin
            if clk'event and clk='1' then
                if cnt1=100 then
                    cnt1:=0;
                    if cnt2=100 then
                        cnt2:=0;
                        clk_5k<=not clk_5k;
                    else
                        cnt2:=cnt2+1;
                    end if;
                else
                    cnt1:=cnt1+1;
                end if;
            end if;
    end process;
    
   process(clk_5k,we,firb,firs,firg,secb,secs,
            secg,fens,feng,mios,miog)
        function dat_to_seg(datout:integer range 0 to 9)
            return std_logic_vector is
            variable seg :std_logic_vector(6 downto 0);
            begin
                case datout is
                    when 0=>
                        seg:="0111111";
                    when 1=>
                        seg:="0000110";
                    when 2=>
                        seg:="1011011";
                    when 3=>
                        seg:="1001111";
                    when 4=>
                        seg:="1100110";
                    when 5=>
                        seg:="1101101";
                    when 6=>
                        seg:="1111101";
                    when 7=>
                        seg:="0000111";
                    when 8=>
                        seg:="1111111";
                    when 9=>
                        seg:="1101111";
                end case;
                return seg;
            end dat_to_seg;
        begin
            if clk_5k'event and clk_5k='1' then
                if we=9 then
                    we<=0;
                else
                    we<=we+1;
                end if;
            end if;
            case we is
                when 0=>
                    wei<="0111111111";
                    duan<=dat_to_seg(firb);
                when 1=>
                    wei<="1011111111";
                    duan<=dat_to_seg(firs);
                when 2=>
                    wei<="1101111111";
                    duan<=dat_to_seg(firg);
                when 3=>
                    wei<="1110111111";
                    duan<=dat_to_seg(secb);
                when 4=>
                    wei<="1111011111";
                    duan<=dat_to_seg(secs);
                when 5=>
                    wei<="1111101111";
                    duan<=dat_to_seg(secg);
                when 6=>
                    wei<="1111110111";
                    duan<=dat_to_seg(fens);
                when 7=>
                    wei<="1111111011";
                    duan<=dat_to_seg(feng);
                when 8=>
                    wei<="1111111101";
                    duan<=dat_to_seg(mios);
                when 9=>
                    wei<="1111111110";
                    duan<=dat_to_seg(miog);
            end case;
    end process;
    
    process(clk_5k)
    variable cnt3 :integer range 0 to 2999;
    variable cnt4 :integer range 0 to 500;
        begin
            if clk_5k'event and clk_5k='1' then
                if run='1' and state=0 then
                    if miog=0 and mios=0 
                       and fens=0 and feng=0 then
                        run<='0';
                    end if;
                    if cnt3=2999 then
                        cnt3:=0;
                        if miog=0 then
                            if mios=0 then
                                if feng=0 then
                                    if fens=0 then
                                        fens<=9;
                                    else
                                        fens<=fens-1;
                                    end if;
                                    feng<=9;
                                else
                                    feng<=feng-1;
                                end if;
                                mios<=5;
                            else
                                mios<=mios-1;
                            end if;
                            miog<=9;
                        else
                            miog<=miog-1;
                        end if;
                    else
                        cnt3:=cnt3+1;
                    end if;
                end if;
                case key is
                    when "01111111" =>
                        if cnt4=500 then
                            cnt4:=0;
                            if firg=9 then
                                firg<=0;
                                if firs=9 then
                                    firs<=0;
                                    if firb=9 then
                                        firb<=0;
                                    else
                                        firb<=firb+1;
                                    end if;
                                else
                                    firs<=firs+1;
                                end if;
                            else
                                firg<=firg+1;
                            end if;
                        else
                            cnt4:=cnt4+1;
                        end if;
                    when "10111111"=>
                        if cnt4=500 then
                            cnt4:=0;
                            if firg=0 then
                                firg<=9;
                                if firs=0 then
                                    firs<=9;
                                    if firb=0 then
                                        firb<=9;
                                    else
                                        firb<=firb-1;
                                    end if;
                                else
                                    firs<=firs-1;
                                end if;
                            else
                                firg<=firg-1;
                            end if;
                        else
                            cnt4:=cnt4+1;
                        end if;
                    when "11011111"=>
                        if cnt4=500 then
                            cnt4:=0;
                            if secg=9 then
                                secg<=0;
                                if secs=9 then
                                    secs<=0;
                                    if secb=9 then
                                        secb<=0;
                                    else
                                        secb<=firb+1;
                                    end if;
                                else
                                    secs<=secs+1;
                                end if;
                            else
                                secg<=secg+1;
                            end if;
                        else
                            cnt4:=cnt4+1;
                        end if;
                    when "11101111"=>
                        if cnt4=500 then
                            cnt4:=0;
                            if secg=0 then
                                secg<=9;
                                if secs=0 then
                                    secs<=9;
                                    if secb=0 then
                                        secb<=9;
                                    else
                                        secb<=secb-1;
                                    end if;
                                else
                                    secs<=secs-1;
                                end if;
                            else
                                secg<=secg-1;
                            end if;
                        else
                            cnt4:=cnt4+1;
                        end if;
                    when "11110111"=>
                        if cnt4=500 then
                            cnt4:=0;
                            if state=2 then
                                state<=0;
                            else
                                state<=state+1;
                                run<='0';
                            end if;
                        else
                            cnt4:=cnt4+1;
                        end if;
                    when "11111011"=>
                        if cnt4=500 then
                            cnt4:=0;
                            case state is
                                when 0 =>
                                    NULL;
                                when 1 =>
                                    if run='0' then
                                        if feng=9 then
                                            feng<=0;
                                            if fens=9 then
                                                fens<=0;
                                            else
                                                fens<=fens+1;
                                            end if;
                                        else
                                            feng<=feng+1;
                                        end if;
                                    end if;
                                when 2 =>
                                    if run='0' then
                                        if miog=9 then
                                            miog<=0;
                                            if mios=5 then
                                                mios<=0;
                                            else
                                                mios<=mios+1;
                                            end if;
                                        else
                                            miog<=miog+1;
                                        end if;
                                    end if;
                            end case;
                        else
                            cnt4:=cnt4+1;
                        end if;
                    when "11111101"=>
                        if cnt4=500 then
                            cnt4:=0;
                            case state is
                                when 0 =>
                                    NULL;
                                when 1 =>
                                    if run='0' then
                                        if feng=0 then
                                            feng<=9;
                                            if fens=0 then
                                                fens<=9;
                                            else
                                                fens<=fens-1;
                                            end if;
                                        else
                                            feng<=feng-1;
                                        end if;
                                    end if;
                                when 2 =>
                                    if run='0' then
                                        if miog=0 then
                                            miog<=9;
                                            if mios=0 then
                                                mios<=5;
                                            else
                                                mios<=mios-1;
                                            end if;
                                        else
                                            miog<=miog-1;
                                        end if;
                                    end if;
                            end case;
                        else
                            cnt4:=cnt4+1;
                        end if;
                    when "11111110"=>
                        if cnt4=500 then
                            cnt4:=0;
                            run<=not run;
                            state<=0;
                        else
                            cnt4:=cnt4+1;
                        end if;
                    when others =>
                        NULL;
                end case;
            end if;
    end process;
    
end behavior;

《 “【FPGA】篮球计分计时系统” 》 有 4 条评论

  1. 移动商学院 的头像

    博主可以讲那个图片分享出来吗?

    1. cloud 的头像

      硬件原理图吗?
      这个系统的硬件图很简单的,几个按键,数码管也没有加驱动,段选连一起连在FPGA的IO口上,为选分别连在IO口上,然后自己通过引脚配置选择,实物拍的照可以共享出来.

  2. zhangfei 的头像
    zhangfei

    coding style 不错,呵呵,研究生阶段依然不同于常人

    1. cloud 的头像

      谢谢鼓励,呵呵
      希望毕业后不会落后你太远,嘿嘿…

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注