名称:篮球计分器设计VHDL代码Quartus DE2-115开发板(文末获取)
软件:Quartus
语言:VHDL
代码功能:
任务与要求:
1、具有24s(也可假定30s)计时、显示;
2、可对计时器清零、置数、启动和暂停
3、30秒倒计时;
4、两个数码管显示两队比分
5、超时报警并可解除报警。
本代码已在DE2-115开发板验证,DE2-115开发板如下,其他开发板可以修改管脚适配:
要求
第三部分 详细设计过程
整体设计分析:顶层电路包括输入端口有:clk_in(50MHz时钟输入端口),reset_p(复位信号),start(开始、继续信号),stop(暂停信号),score_1(1队分数),score_2(2队分数输入端口),其中reset_p高电平有效,start、stop端口均为低电平有效。
输出端口有:LED(闪烁报警),HEX0(显示秒个位)、HEX1(显示秒十位)、HEX2(显示1队分数)、HEX3(显示2队分数)。
图2 顶层模块
图形分析:顶层模块由分频模块,倒计时模块,数码管显示模块3个模块组成。其中,分频模块输入50MHz时钟,输出1Hz信号;倒计时模块在开始、暂停按键控制下输出秒倒计时信号和LED报警信号;数码管显示模块将两队分数和秒倒计时信号通过数码管显示。
3.1分频模块
3.1.1 模块功能描述
在这个模块中主要实现50MHz的时钟转换为1Hz的信号,DE2-115板子上的晶振为50MHz,而倒计时为一秒一次,即1Hz,故需要将50MHz的信号转换为1Hz的信号。50MHz对应周期为20ns,1Hz对应周期为1s,两者相差50000000倍。
为到达分频的目的,可以使用计数器来设计,即将50MHz的信号进行计数,一共计数5000000次后就是1s,计数到50000000后计数器清零,重新开始计数,这样循环往复就能的带周期性的1Hz信号。
3.1.2模块设计思想
设计分频模块时,我设计了1个进程,定义time_count为一个32位的计数器,使用50MHz的clk_in信号作为时钟,在时钟上升沿进行计数,当计数到“00000010111110101111000010000000”时清零,重新开始计数。“00000010111110101111000010000000”表示二进制的50000000。当计数到50000000时,控制clk_1Hz输出高电平,否则输出低电平。这样得到的clk_1Hz信号就是1秒钟输出一次脉冲的1Hz信号。
电路模块图如下所示:
图4 分频模块
图4所示为分频模块框图,clk_in为时钟信号输入,clk_1Hz为输出。
3.1.3设计关键知识点
在进程设计种使用了一个32位的计数器信号time_count,需要计数到“00000010111110101111000010000000”,该计数值是一个很大得
数,在进行模块仿真时会耗费大量时间,因此仿真时可以将改计数器改小,本设计改小为"00000000000000000000000000010000",即仿真时用这个小的计数器,用于仿真验证功能。实际需要上板调试时再改为大数。在该模块中调用ieee.std_logic_1164.all库和ieee.std_logic_unsigned.all库,并且确定输入输出信号的类型[4]。
实体部分如下:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
--分频模块,分频到1Hz
ENTITY fenping IS
PORT (
clk_in : IN STD_LOGIC;
clk_1Hz : OUT STD_LOGIC--输出1Hz
);
END fenping;
3.2倒计时模块
3.2.1模块功能描述
在这个模块中主要实现秒钟倒计时功能且倒计时结束后LED闪烁报警。当按下reset_p信号时,模块复位,按下start信号时开始倒计时,按下stop信号暂停,再次按下start信号时继续倒计时,直到倒计时为0后,LED闪烁报警。
该模块输入信号有系统时钟信号clk_in,倒计时时钟clk_1Hz,复位清零信号reset_p,启动、继续信号start,暂停信号stop。
输出有闪烁报警信号LED,秒信号second_time。
该模块使用状态机实现,一共分为s_idle,s_down_cnt,s_stop,s_end这4个状态。系统复位时处于s_idle状态,表示空闲。当按下start信号时,系统启动,进入s_down_cnt状态,该状态为倒计时状态,在这个状态下second信号按每秒一次递减,当second减为0时,进入s_end状态,表示结束。当second未减到0时,按下stop按键,则进入s_stop状态,表示暂停。在暂停状态下,按下start信号,进入s_down_cnt状态继续倒计时。状态机的状态转移图如下:
图5 倒计时模块状态机图
3.2.2模块设计思想
该模块用于倒计时控制及结束LED报警闪烁,模块输入信号有系统时钟信号clk_in,倒计时时钟clk_1Hz,复位清零信号reset_p,启动、继续信号start,暂停信号stop。输出有闪烁报警信号LED,秒信号second_time。输入信号start、stop控制倒计时的启动和暂停,reset_p控制计数器复位。通过状态机控制s_idle,s_down_cnt,s_stop,s_end这4个状态的切换。在s_down_cnt状态下,控制second信号倒计时。倒计时采用clk_1Hz为计时信号,每来一次clk_1Hz信号倒计时一次。在s_end状态时输出LED报警信号,LED闪烁频率为2Hz,也是采用分频思路,产生一个2Hz的信号。倒计时模块电路如下:
图6 倒计时模块
3.2.3设计关键知识点
本模块的关键在于状态机的设计,状态机在实现流程控制方面是首选的方法。倒计时控制信号包括启动。暂停按键以及倒计时的second信号。在这些信号控制下,状态机会进入不同的状态,然后在不同的状态下,我们可以控制信号倒计时以及LED闪烁。实体部分如下:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
--倒计时模块
ENTITY jishi IS
PORT (
clk_in : IN STD_LOGIC;
clk_1Hz : IN STD_LOGIC;--1Hz信号
reset_p : IN STD_LOGIC;--复位清零
start : IN STD_LOGIC;--启动、继续
stop : IN STD_LOGIC;--暂停
LED : OUT STD_LOGIC;--闪烁报警
second_time : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)--秒
);
END jishi;
3.3数码管显示模块
3.2.1模块功能描述
在这个模块中主要实现数码管的显示,本模块显示秒倒计时以及1队分数和2队分数。输入信号有clk时钟,second_time秒倒计时,score_1为1队分数,score_2为2队分数。输出为HEX0(显示秒个位)、HEX1(显示秒十位)、HEX2(显示1队分数)、HEX3(显示2队分数)。数码管显示实际上是实现译码器,数码管为8段数码管,即有8个段组成,如下图:
如要显示数字1,则上图中的1,2段点亮即可。若要显示数字2,则需要点亮0、1、6、4、3段,以此类推。本模块就是将十进制数字转换为数码管需要点亮的段。
3.2.2模块设计思想
该模块用于显示倒计时以及2队分数。倒计时为30s倒计时到0,因此需要2个数码管显示,一个显示十位,一个显示个位。因此需要将second_time信号转换为十位和个位,转换方法为将second_time除以10,得到的商即为十位数据,然后再将second_time减去商除以10,得到的就是个位。最后再通过一个case语句将十进制数据转换为对应数码管段的点亮信号。即实现数码管译码。
倒计时模块电路如下:
图6 显示模块
3.2.3设计关键知识点
本模块的关键在于计算倒计时的十位和个位,以及数码管译码器。将
second_time除以10,得到的商即为十位数据,然后再将second_time减去商除以10,得到的就是个位,译码器采用case语句实现。实体部分如下:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
USE ieee.std_logic_arith.all;
--数码管显示模块
ENTITY display IS
PORT (
clk : IN STD_LOGIC;
second_time : IN STD_LOGIC_VECTOR(7 DOWNTO 0);--秒钟
score_1 : IN STD_LOGIC_VECTOR(3 DOWNTO 0);--1队分数
score_2 : IN STD_LOGIC_VECTOR(3 DOWNTO 0);--2队分数
HEX0 : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
HEX1 : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
HEX2 : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
HEX3 : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END display;
第四部分 功能仿真
4.1分频模块仿真波形
上图为分频模块仿真图,图中clk_in为输入50MHz的时钟,输出clk_1Hz为1Hz的脉冲信号。程序种设计种使用了一个32位的计数器信号time_count,需要计数到“00000010111110101111000010000000”,该计数值是一个很大得数,在进行模块仿真时会耗费大量时间,因此仿真时将改计数器改小,本设计改小为"00000000000000000000000000010000"。可以看到clk_1Hz信号每个一段时间输出一个脉冲信号,因此功能仿真正确。
4.2倒计时模块仿真波形
图中输入为clk_in,clk_1Hz,reset_p,start,stop,输出为second_time和LED。复位后,按下start信号,开始倒计时,可以看到图上second_time从30开始减小,减小按clk_1Hz的频率变化。按下stop信号后,暂停倒计时,second_time信号保持9不。再次按下start信号后,继续倒计时,second_time继续减小直到0。此时LED开始闪烁,即高低电平变化。按下stop后,LED停止报警。
4.3数码管显示模块仿真波形
图中输入为clk,score_1,score_1,second_time,输出为HEX0~3.其中秒钟个位对应HEX0,秒
钟十位对应HEX1,1对分数对应HEX2,2队分数对应HEX3。可以看到图中1队分数为0001,即1分,对应的数码管译码值为11111001,2队分数为0010,即2分,对应的数码管译码值为10100100,数码管为共阴极,即低电平亮,故11111001对应显示为1,10100100对应显示为2。秒钟十位和个位的显示类似,对应HEX0和HEX1。
4.4整体仿真
仿真分析:
图中clk_in为输入50MHz的时钟,在start按下后,HEX0为1Hz变化一次,即按分频模块的1Hz信号的频率变化。 ---分频模块
图中复位后,按下start信号,开始倒计时,可以看到图上HEX1初始为10110000(对应数字3),HEX0初始为11000000(对应数字0),表示秒从30开始减小,减小按clk_1Hz的频率变化。按下stop信号后,暂停倒计时,HEX0和HEX1信号保持不变。再次按下start信号后,继续倒计时,继续减小直到11000000(对应数字0)。此时LED开始闪烁,即高低电平变化。按下stop后,LED停止报警。 ---倒计时模块
其中秒钟个位对应HEX0,秒钟十位对应HEX1,1对分数对应HEX2,2队分数对应HEX3。按共阴极的7段数码管方式译码,例如10110000(对应数字3),11000000(对应数字0)。最终1队分数显示1,2队分数显示2,倒计时数码管显示“00”。 ---显示模块
1. 工程文件
2. 程序文件
3. 程序编译
4. RTL图
状态图
5. 管脚图
6. 仿真图
整体仿真图
分频模块仿真图
倒计时模块仿真图
显示模块仿真图
部分代码展示:
LIBRARY ieee; USE ieee.std_logic_1164.all; --篮球计时器 ENTITY Basketball_clock IS PORT ( clk_in : IN STD_LOGIC; reset_p : IN STD_LOGIC;--复位清零 start : IN STD_LOGIC;--开始、继续 stop : IN STD_LOGIC;--暂停 score_1 : IN STD_LOGIC_VECTOR(3 DOWNTO 0);--1队分数 score_2 : IN STD_LOGIC_VECTOR(3 DOWNTO 0);--2队分数 LED : OUT STD_LOGIC;--闪烁报警 HEX0 : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);--数码管段选 HEX1 : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);--数码管段选 HEX2 : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);--数码管段选 HEX3 : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) --数码管段选 ); END Basketball_clock; ARCHITECTURE behave OF Basketball_clock IS --50M分频到1hz COMPONENT fenping IS PORT ( clk_in : IN STD_LOGIC; clk_1Hz : OUT STD_LOGIC ); END COMPONENT; --倒计时模块 COMPONENT jishi IS PORT ( clk_in : IN STD_LOGIC; clk_1Hz : IN STD_LOGIC; reset_p : IN STD_LOGIC; start : IN STD_LOGIC; stop : IN STD_LOGIC; LED : OUT STD_LOGIC; second_time : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) ); END COMPONENT; --数码管显示模块 COMPONENT display IS PORT ( clk : IN STD_LOGIC; second_time : IN STD_LOGIC_VECTOR(7 DOWNTO 0);--秒钟 score_1 : IN STD_LOGIC_VECTOR(3 DOWNTO 0);--1队分数 score_2 : IN STD_LOGIC_VECTOR(3 DOWNTO 0);--2队分数 HEX0 : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); HEX1 : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); HEX2 : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); HEX3 : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) ); END COMPONENT; SIGNAL clk_1Hz : STD_LOGIC; SIGNAL second_time : STD_LOGIC_VECTOR(7 DOWNTO 0); BEGIN --50M分频到1hz i_fenping : fenping PORT MAP ( clk_in => clk_in, clk_1Hz => clk_1Hz--1Hz ); --倒计时模块 i_jishi : jishi PORT MAP ( clk_in => clk_in, clk_1Hz => clk_1Hz, reset_p => reset_p,--复位 start => start,--开始 stop => stop,--暂停 LED => LED,--闪烁报警 second_time => second_time--秒 );
源代码
点击下方的公众号卡片获取