篮球计分板系统睿智CPLD开发板VHDL QuartusII
项目信息
名称: 篮球计分板系统VHDL QuartusII
软件: QuartusII
语言: VHDL
代码功能
本项目实现了一个基于FPGA的双队篮球计分板系统。系统支持两支队伍(A队和B队)的分数管理,每队分数范围为0-999分。通过按键可以实现加1分、加2分、减1分、减2分的操作,并通过8位七段数码管动态显示两队分数。系统具有按键消抖功能,确保操作的准确性和稳定性。整个系统采用模块化设计,结构清晰,便于维护和扩展。
本代码已在睿智CPLD开发板验证
演示视频
代码实现思路
系统采用分层模块化设计思想,将复杂的计分板功能分解为多个独立的功能模块。顶层模块负责整体协调,计分控制模块处理分数逻辑,显示模块负责数码管驱动,按键处理模块确保输入稳定性。
核心设计思路:
1.分层架构设计:采用自顶向下的设计方法,将系统分为顶层控制、计分逻辑、显示驱动、信号处理等层次
2.状态机控制:使用有限状态机管理按键消抖和数据转换过程,确保系统稳定运行
3.动态扫描显示:采用时分复用技术,通过快速扫描8个数码管实现同时显示效果
4.数据格式转换:实现二进制到BCD码的转换,便于数码管显示十进制数字
5.边界保护机制:在计分逻辑中加入上下限保护,防止分数溢出或下溢
主要模块说明
·top_scoreboard.vhd:顶层模块,负责整个系统的信号连接和模块实例化
·score_ctrl.vhd:计分控制模块,实现双队分数的加减运算和边界保护逻辑
·sevenseg_scan6.vhd:七段数码管扫描显示模块,负责8位数码管的动态扫描和数字显示
·key_jitter.vhd:按键消抖模块,消除按键机械抖动,输出稳定的按键信号
·b_to_bcd.vhd:二进制转BCD码模块,将二进制数据转换为便于数码管显示的BCD格式
·edge_fall.vhd:边沿检测模块,检测信号的下降沿触发事件
信号流程
1.输入处理:按键信号经过消抖处理,产生稳定的控制信号
2.逻辑运算:计分控制模块根据队伍选择和操作类型更新对应队伍分数
3.数据转换:二进制分数转换为BCD码格式
4.显示输出:通过动态扫描方式驱动8位七段数码管显示两队分数
1、工程文件
2、程序文件
3、程序编译
4、RTL图
5、管脚分配
部分代码展示:
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; -- 双队伍分数控制器,范围饱和在 0..999 -- team_sel = '0' 操作A队,'1' 操作B队 entity score_ctrl is port ( clk : in std_logic; rst_n : in std_logic; -- 低有效复位 team_sel : in std_logic; add2_p : in std_logic; add1_p : in std_logic; sub2_p : in std_logic; sub1_p : in std_logic; score_a : out unsigned(9 downto 0); -- 0..999 可用10位表示 score_b : out unsigned(9 downto 0) ); end entity; architecture rtl of score_ctrl is signal sa, sb : unsigned(9 downto 0) := (others => '0'); begin process(clk) begin if rising_edge(clk) then if rst_n = '0' then sa <= (others => '0'); sb <= (others => '0'); else -- 默认保持原值,仅在对应按键脉冲时修改 if team_sel = '0' then if add2_p = '1' then -- 加2分,带上限裁剪(不超过999) if to_integer(sa) + 2 > 999 then sa <= to_unsigned(999, sa'length); else sa <= to_unsigned(to_integer(sa) + 2, sa'length); end if; end if; if add1_p = '1' then -- 加1分,带上限裁剪(不超过999) if to_integer(sa) + 1 > 999 then sa <= to_unsigned(999, sa'length); else sa <= to_unsigned(to_integer(sa) + 1, sa'length); end if; end if; if sub2_p = '1' then -- 减2分,带下限裁剪(不小于0) if to_integer(sa) - 2 < 0 then sa <= (others => '0'); else sa <= to_unsigned(to_integer(sa) - 2, sa'length); end if; end if; if sub1_p = '1' then -- 减1分,带下限裁剪(不小于0) if to_integer(sa) - 1 < 0 then sa <= (others => '0'); else sa <= to_unsigned(to_integer(sa) - 1, sa'length); end if; end if; else if add2_p = '1' then -- 加2分,带上限裁剪(不超过999) if to_integer(sb) + 2 > 999 then sb <= to_unsigned(999, sb'length); else sb <= to_unsigned(to_integer(sb) + 2, sb'length); end if; end if; if add1_p = '1' then -- 加1分,带上限裁剪(不超过999) if to_integer(sb) + 1 > 999 then sb <= to_unsigned(999, sb'length); else sb <= to_unsigned(to_integer(sb) + 1, sb'length); end if; end if; if sub2_p = '1' then -- 减2分,带下限裁剪(不小于0) if to_integer(sb) - 2 < 0 then sb <= (others => '0'); else sb <= to_unsigned(to_integer(sb) - 2, sb'length); end if; end if; if sub1_p = '1' then -- 减1分,带下限裁剪(不小于0) if to_integer(sb) - 1 < 0 then sb <= (others => '0'); else sb <= to_unsigned(to_integer(sb) - 1, sb'length); end if; end if; end if; end if; end if; end process; score_a <= sa; score_b <= sb; end architecture;
代码下载(付费可见):
79