羽毛球计分器Basys3开发板VHDL代码带设计报告

名称:羽毛球计分器Basys3开发板verilog代码带设计报告

软件:VIVADO

语言:VHDL

代码功能:

羽毛球计分器

1、计分器可以同时显示2位选手的分数,每个选手的分数通过1bit的输入按键信号控制,按一次加一分,一共2个按键对应2个不同的分数。/

2、分数最高为21分,谁先达到21分则获胜,比赛结束,同时通过LED显示获胜的选手。

3、分数通过7段数码管显示,一共4个数码管,其中2个显示选手1的分数,另外2个显示选手2的分数,

4、分数达到21分后显示持续5秒后自动清零,或者有复位信号也会清零

FPGA代码Verilog/VHDL代码资源下载:www.hdlcode.com

本代码已在Basys3开发板验证,开发板如下,其他开发板可以修改管脚适配:

basys3开发板.png

代码下载:羽毛球计分器Basys3开发板verilog代码带设计报告名称:羽毛球计分器Basys3开发板verilog代码带设计报告(代码在文末下载)软件:VIVADO语言:VHDL代码功能:羽毛球计分器1、计分器可以同时显示2位选手的分数,每个选手的分数通过1bit的输入按键信号控制,按一次加一分,一共2个按键对应2个不同的分数。/2、分数最高为21分,谁先达到21分则获胜,比赛结束,同时通过LED显示获胜的选手。3、分数通过7段数码管显示,一共4个数码管,其中icon-default.png?t=N7T8http://www.hdlcode.com/index.php?m=home&c=View&a=index&aid=287

羽毛球计分器设计报告(节选)

一、摘要

本题目要求设计使用VHDL语言设计一个羽毛球计分器,计分器可以同时显示2位选手的分数,每个选手的分数通过1bit的输入按键信号控制,按一次加一分,一共2个按键对应2个不同的分数。分数最高为21分,谁先达到21分则获胜,比赛结束,同时通过LED显示获胜的选手。分数通过7段数码管显示,一共4个数码管,其中2个显示选手1的分数,另外2个显示选手2的分数,分数达到21分后显示持续5秒后自动清零,或者有复位信号也会清零。通过这个计分器可以用来在羽毛球比赛中计分。

二、概述

本报告设计的是一个羽毛球计分器,可记录并显示2个选手分数,每个选手的分数通过1bit的输入按键信号控制,按一次加一分,一共2个按键对应2个不同的分数。分数最高为21分,谁先达到21分则获胜,比赛结束,同时通过LED显示获胜的选手。分数通过7段数码管显示,一共4个数码管,其中2个显示选手1的分数,另外2个显示选手2的分数,分数达到21分后显示持续5秒后自动清零,或者有复位信号也会清零。

本工程代码一共可以分为3个模块,分别为顶层模块badminton_scoreboard、计分模块badminton_score和显示模块display。其中计分模块根据按键控制对应选手的分数,按一次加1分,加到21分获胜并不再增加,并且需要控制获胜后的led指示灯和获胜后持续5秒后返回初始状态。显示模块用于将计分模块的二进制分数转换为便于数码管显示的BCD码分数,然后控制数码管的位选信号和段选信号分别显示AB两组选手的分数(分为个位和十位显示)。顶层模块调用计分模块和显示模块,将计分模块的分数输入到显示模块,其他信号连接到外部IO接口。

三、顶层模块

顶层模块badminton_scoreboard的实体定义如下:

entity badminton_scoreboard is

   Port ( clk : in STD_LOGIC;

          bit_sel : out STD_LOGIC_VECTOR (3 downto 0);

          seg_sel : out STD_LOGIC_VECTOR (7 downto 0);

          reset : in STD_LOGIC;

          player_A_point : in STD_LOGIC;

          player_B_point : in STD_LOGIC;

          win_A_led : out STD_LOGIC;

          win_B_led : out STD_LOGIC);

end badminton_scoreboard;

顶层模块输入包括时钟clk信号,复位reset信号,2个按键player_A_point和player_B_point。输出为2个led灯win_A_led和win_B_led,2个数码管控制信号bit_sel和seg_sel ,其中bit_sel为4bit,控制当前显示哪个数码管,seg_sel为8bit信号,控制当前点亮的数码管的显示值,通过bit_sel信号的时分复用可以使4个数码管同时显示不同的值。顶层模块调用计分模块和显示模块,用于将两个模块连接,代码如下:

--call Scoring module

U_badminton_score: badminton_score

  PORT MAP(

     clk             =>clk,

     reset           =>reset,--reset

     player_A_point  =>player_A_point,--player_A_point key

     player_B_point  =>player_B_point,--player_B_point key

     score_A         =>score_A,----A score

     score_B         =>score_B,----B score

     win_A_led       =>win_A_led,--A win LED

     win_B_led       =>win_B_led--B win LED

  );

--call Display module

U_display: display

  PORT MAP(

     clk         =>clk,

     score_A     =>score_A,--A score

     score_B     =>score_B,--B score

     bit_sel     =>bit_sel,--Digital tube position selection

     seg_sel     =>seg_sel--Digital tube section selection

  );

首先调用Scoreboard模块,可以得到2个选手的分数,即score_1信号和score_2信号,再调用数码管显示模块segment_display,将score_1信号和score_2信号输入到segment_display模块中,最终通过7segment_display的bit_select和lednum_select信号进行显示。

四、计分模块

计分模块的输入包括时钟clk信号,复位reset信号,2个按键player_A_point和player_B_point。输出为2个led灯LED_1和LED_2,和2个分数信号score_1和score_2。

实体定义如下:

--Scoring module

ENTITY badminton_score IS

  PORT (

     clk             : IN STD_LOGIC;

     reset           : IN STD_LOGIC;--reset

     player_A_point  : IN STD_LOGIC;--player_A_point key

     player_B_point  : IN STD_LOGIC;--player_B_point key

     score_A         : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);----A score

     score_B         : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);----B score

     win_A_led       : OUT STD_LOGIC;--A win LED

     win_B_led       : OUT STD_LOGIC--B win LED

  );

END badminton_score;

为了控制按键按下后加一分,可以通过一个process进程,判断按键是否按下然后控制分数加1,但是由于按键信号相对于时钟信号是一个持续时间很长的信号,所以需要将按键信号缩短为只持续一个时钟周期的信号,可以通过检测按键上升沿实现。实现方法如下:

Basys3板子上一个有4个数码管,四个数码管有4个位选信号控制当前点亮哪个数码管,然后4个数码管共用8位段选信号。因此需要通过时分复用的方式依次点亮4个数码管才能同时显示4个数字。Basys3板子上的数码管位选为低电平选中,即低电平时显示,高电平时不显示。段选信号也是低电平点亮,高电平熄灭。如下图所示,图中可以看到,若要显示数字0,需要将ABCDF全部点亮,G和DP不点亮,因此,按DP,G,F,E,D,C,B,A的顺序就是11000000。即十六进制的C0。

设计代码如下:

  PROCESS (clk)

  BEGIN

   

五、Testbench

Testebnch用于产生仿真测试激励,即模拟顶层模块的输入时钟、复位、按键A、按键B

等信号,观察输出的信号是否正确。由于testbench是一个模拟输入,所以实体可以是空的,如下:

entity test is

--  Port ( );

end test;

然后调用顶层模块

u_badminton_scoreboard:badminton_scoreboard

   Port MAP(

          clk =>clk,

          bit_sel =>bit_sel,

          seg_sel =>seg_sel,

          reset =>reset,

          player_A_point =>player_A_point,

          player_B_point =>player_B_point,

          win_A_led =>win_A_led,

          win_B_led =>win_B_led

          );

根据要求,模拟的时钟信号为1KHz,如下,500us高电平和500us低电平:

  PROCESS

  BEGIN

     clk <= '0';

     WAIT FOR 500 us;

     clk <= '1';

     WAIT FOR 500 us;

  END PROCESS;

根据计分器的实际功能,设计激励信号为:先复位,使代码初始化,然后重复按下10次player_A_point按键,模块A选手赢得10分,然后重复按下10次player_B_point按键,模块B选手赢得10分,最后再重复按下12次player_A_point按键,模块A选手赢得12分。使A分数可以达到21,以观察得到21分后的信号变化,对应的testebnch代码如下:

  

六、仿真图结果

使用上述testbench仿真,分别看计分模块和数码管显示模块。

1.计分模块仿真

下图为计分模块的仿真图

上图中,reset信号为高电平后,score_A和score_B均为0,表示复位,分数清零。

随后player_A_point信号和player_B_point分别交替产生10个个高电平脉冲,AB对应的分数也由0依次变为10。然后只有player_A_point信号继续再来12个高电平脉冲。A的分数继续增长达到21后,在来高电平脉冲分数不再增加。并且在A分数为21后,win_LED_A拉高,表示A获胜。并且一直持续了5秒后自动清零。从上面两个仿真图可以看到计分模块实现了模块对应功能,仿真正确。

2. 数码管显示模块仿真

下图中score_A、score_B是输入的8位二进制分数,d2表示分数A的十位,d2表示分数B的个位,c2表示分数score_B的十位,c1表示score_B的个位。图中当score_A为19时,对应d2=1,d1=9,十位和个位均正确。

下图中bit_sel依次产生低电平信号,选通对应数码管。当数码管显示0时段选信号seg_sel等于十六进制的C0。显示1时为十六进制F9。图中当score_A等于1、score_B等于0时,数码管应该显示01,00,故对应的编码值为,C0,F9,C0,C0,与仿真图一致。故数码管显示模块仿真正确。

七、综合即实现结果

对代码进行综合实现,结果如下图所示

资源消耗LUT为113,FF为104,IO为18,BUFG为1.

八、结论

本设计使用VHDL设计了羽毛球计分器,系统分为3个部分,分别为顶层模块、计分模块、显示模块。顶层模块调用计分模块和显示模块,用于将两个模块连接,使其组合到一起。经过testbench仿真,计分模块完成了根据按键控制对应选手的分数,并且需要控制获胜后的led指示灯和获胜后持续5秒后返回初始状态。显示模块完成了将计分模块的分数转换为数码管显示的内容。最终仿真结果表明程序实现了网球计分器的全部功能。

部分代码展示:

LIBRARY ieee;
   USE ieee.std_logic_1164.all;
   USE ieee.std_logic_unsigned.all;
--Scoring module
ENTITY badminton_score IS
   PORT (
      clk             : IN STD_LOGIC;
      reset           : IN STD_LOGIC;--reset 
      player_A_point  : IN STD_LOGIC;--player_A_point key
      player_B_point  : IN STD_LOGIC;--player_B_point key
      score_A         : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);----A score
      score_B         : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);----B score
      win_A_led       : OUT STD_LOGIC;--A win LED
      win_B_led       : OUT STD_LOGIC--B win LED
   );
END badminton_score;
ARCHITECTURE behave OF badminton_score IS
   
   SIGNAL player_A_point_temp1 : STD_LOGIC := '0';
   SIGNAL player_A_point_temp2 : STD_LOGIC := '0';
   
   SIGNAL player_B_point_temp1 : STD_LOGIC := '0';
   SIGNAL player_B_point_temp2 : STD_LOGIC := '0';
   
   SIGNAL A_point_add          : STD_LOGIC;
   SIGNAL B_point_add          : STD_LOGIC;
   
   SIGNAL count                : STD_LOGIC_VECTOR(15 DOWNTO 0) := "0000000000000000";
   
   SIGNAL score_A_temp        : STD_LOGIC_VECTOR(7 DOWNTO 0);
   SIGNAL score_B_temp        : STD_LOGIC_VECTOR(7 DOWNTO 0);
   
   SIGNAL A_win_flag          : STD_LOGIC:='0';
   SIGNAL B_win_flag          : STD_LOGIC:='0';
BEGIN
   score_A <= score_A_temp;--Output score A
   score_B <= score_B_temp;--Output score B
   
   --D trigger to synchronization of player_A_point
   PROCESS (clk)
   BEGIN
      IF (clk'EVENT AND clk = '1') THEN
         player_A_point_temp1 <= player_A_point;
         player_A_point_temp2 <= player_A_point_temp1;
      END IF;
   END PROCESS;
   
   --D trigger to synchronization of player_B_point
   PROCESS (clk)
   BEGIN
      IF (clk'EVENT AND clk = '1') THEN
         player_B_point_temp1 <= player_B_point;
         player_B_point_temp2 <= player_B_point_temp1;
      END IF;
   END PROCESS;
   
   A_point_add <= player_A_point_temp1 AND (NOT(player_A_point_temp2));--Rising edge of key A
   B_point_add <= player_B_point_temp1 AND (NOT(player_B_point_temp2));--Rising edge of key B
  
   --Time 5 seconds
   PROCESS (clk)
   BEGIN
      IF (clk'EVENT AND clk = '1') THEN
         IF (reset = '1') THEN--reset
            count <= "0000000000000000";
         ELSIF (A_win_flag = '1' OR B_win_flag = '1') THEN--win flag for A or B
            count <= count + "0000000000000001";--count to 5 seconds
         ELSE
            count <= "0000000000000000";
         END IF;
      END IF;
   END PROCESS;
   
   --Control A's score
   PROCESS (clk)
   BEGIN
      IF (clk'EVENT AND clk = '1') THEN
         IF (reset = '1') THEN
            score_A_temp <= "00000000";
            A_win_flag<='0';--clera A flag
         ELSIF (count = "0001001110001000") THEN--if count=5000,clk =1KHz count for 5000 means 5seconds
            score_A_temp <= "00000000";--reset scoreA
            A_win_flag<='0';--clera A flag
         ELSIF (score_A_temp >= "00010101"  and (score_A_temp-score_B_temp)>="00000010" and (score_A_temp>score_B_temp)) THEN--when score is more then 21 and bigger then 2
               score_A_temp <= score_A_temp;--21
               A_win_flag<='1';--A win flag
         ELSIF (A_point_add = '1') THEN--add key
--            IF (score_A_temp >= "00010101"  and (score_A_temp-score_B_temp)>="00000010" and (score_A_temp>score_B_temp)) THEN--when score is more then 21 and bigger then 2
--               score_A_temp <= score_A_temp;--21
--               A_win_flag<='1';--A win flag
--            ELSE
               score_A_temp <= score_A_temp + "00000001";--increase one 
--            END IF;
         ELSE
            score_A_temp <= score_A_temp;--keep
         END IF;
      END IF;
   END PROCESS;
   
   --Control B's score
   PROCESS (clk)
   BEGIN
      IF (clk'EVENT AND clk = '1') THEN
         IF (reset = '1') THEN
            score_B_temp <= "00000000";
             B_win_flag<='0';--clera B flag
         ELSIF (count = "0001001110001000") THEN--if count=5000,clk =1KHz count for 5000 means 5seconds
            score_B_temp <= "00000000";--reset score B
             B_win_flag<='0';--clera B flag        
         ELSIF (score_B_temp >= "00010101"  and (score_B_temp-score_A_temp)>="00000010" and (score_B_temp>score_A_temp)) THEN--when score is more then 21 and bigger then 2
                score_B_temp <= score_B_temp;--when 21 keep 21
                B_win_flag<='1';--B win flag
         ELSIF (B_point_add = '1') THEN--add key
--            IF (score_B_temp >= "00010101"  and (score_B_temp-score_A_temp)>="00000010" and (score_B_temp>score_A_temp)) THEN--when score is more then 21 and bigger then 2
--               score_B_temp <= score_B_temp;--when 21 keep 21
--               B_win_flag<='1';--B win flag
--            ELSE
               score_B_temp <= score_B_temp + "00000001";--increase one 
--            END IF;
         ELSE
            score_B_temp <= score_B_temp;--keep
         END IF;
      END IF;
   END PROCESS;

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值