姓名:*** 学号: ***
地点: 主楼402 时间: 5月9日
一、实验目的:
进一步练习VHDL语言设计工程的建立与仿真的步骤和方法、熟悉VHDL语言基本设计实体的编写方法。
二、实验环境:
PC个人计算机、Windows XP操作系统、Quartus II集成开发环境软件。
三、设计要求:
设计一个四人抢答的抢答器的逻辑模块,模块功能如下描述:
(1)上一轮抢答结束后,主持人按下清零按钮,系统初始化,此时除了禁止抢答灯外,所有灯灭,而禁止抢答灯亮。
(2)主持人按下允许抢答按钮,允许抢答灯亮,模块开始计时;当达到设定的允许抢答的时间时,允许抢答灯灭,禁止抢答灯亮。
(3)参赛选手在允许抢答的时间内按下自己的抢答按钮,谁第一个按下,他的抢答成功灯亮,其他选手在抢答无效。
(4)选手在禁止抢答的时间段按下抢答的按钮,他的犯规灯亮,多个选手犯规,他们的犯规灯都亮。
由上述功能可确定模块的引脚:每个按钮对应一个输入信号,按钮按下输入为高电平;每个灯对应一个输出信号,输出高电平灯亮。为了计时,还有一个时钟信号输入,允许抢答的时间为16个时钟周期。
四、设计思想:
抢答器主要由两个模块来实现功能:
(一)抢答鉴别及锁存模块
根据设计要求,首先要有清零按钮clr,主持人控制按钮en,四人抢答按钮a、b、c、d,并由dsp显示抢答成功的选手号码,用wrg_lgt表示犯规灯,用fbd_lgt表示禁止抢答灯,用alw_lgt表示允许抢答灯。为了实现当有选手抢答后锁存电路使其他选手无法抢答的功能,设置两个锁存信号temp1、temp2。按下清零开关(clr=1),tmp1、tmp2=0,若主持人未按下允许抢答按钮(en=0),即禁止抢答灯亮(alw_lgt=1)时,有人抢答,则tmp2=1,关闭抢答电路,犯规选手的犯规灯亮;若主持人按下允许抢答开关(en=1)后,即允许抢答灯亮(alw_lgt=1)时,有人抢答,则tmp1=1,关闭抢答电路,抢答成功选手的抢答成功灯亮。
(二)倒计时模块
用4位二进制矢量count表示抢答倒计时,从“1111”到“0000”表示16个时钟周期,由给定的时钟信号clk触发。主持人按下允许抢答按钮(en=1)后,开始倒计时。
为实现有人抢答则暂停计时及16个时钟周期后停止计时的功能,设置暂停锁存信号tmp3,按下清零开关(clr=1)后,tmp3=0,主持人按下允许抢答按钮(en=1)后,开始倒计时,若有人抢答,则tmp3=1,暂停倒计时;若一直无人抢答,当16个时钟周期结束(count=“0000”)时,则tmp3=1,停止倒计时。
五、电路图
仿真电路图如下:
六、仿真波形
(一)有人抢答时仿真波形
图1
由图1可知,clr=1,系统进入初始状态,即count="1111",dsp="0000",fbd_lgt=1,alw_lgt=0,wrg_lgt="0000";en=1时,count开始16个时钟周期的倒计时,在15个时钟周期时,有人抢答(a=1),倒计时暂停,抢答成功的选手的抢答成功灯亮。
(二)无人抢答时仿真波形
图2
由图2可知,en=1,16个时钟周期的时间(count="0000")到而无人抢答,则按下清零按钮,重新开始倒计时。
七、程序代码
library ieee;
use ieee.std_logic_11.all;
use ieee.std_logic_unsigned.all;
entity qa is
port
( clr :in std_logic;--清零按钮
clk :in std_logic;--时钟信号
en :in std_logic;--主持人控制按钮
a,b,c,d :in std_logic; --四个人的抢答按钮
fbd_lgt :out std_logic;--禁止抢答灯
alw_lgt :out std_logic;--允许抢答灯
wrg_lgt :out std_logic_vector(3 downto 0);--犯规灯
dsp :out std_logic_vector(3 downto 0);--抢答结果显示
count:out std_logic_vector(3 downto 0)--计时信号
);
end qa;
architecture rtl of qa is
signal dsp1 :std_logic_vector(3 downto 0);--四人抢答成功显示
signal count1:std_logic_vector(3 downto 0);--计时信号
signal tmp1,tmp2,tmp3:std_logic;--锁存
signal wrg_lgt1 :std_logic_vector(3 downto 0);--犯规灯
signal fbd_lgt1 :std_logic;--禁止抢答灯
signal alw_lgt1 :std_logic;--允许抢答灯
begin
process(clr,en,tmp1,tmp2,a,b,c,d)
begin
if clr='1' then
tmp1<='0';
tmp2<='0';
fbd_lgt1<='1';
alw_lgt1<='0';
dsp1<="0000";
wrg_lgt1<="0000";
elsif en='1' then
alw_lgt1<='1';
fbd_lgt1<='0';
if tmp1='0' then
if a='1' then
tmp1<='1';
dsp1<="0001";
end if;
if b='1' then
tmp1<='1';
dsp1<="0010";
end if;
if c='1' then
tmp1<='1';
dsp1<="0011";
end if;
if d='1' then
tmp1<='1';
dsp1<="0100";
end if;
end if;
elsif en='0' then
alw_lgt1<='0';
fbd_lgt1<='1';
if tmp2='0' then
if a='1' then
tmp2<='1';
wrg_lgt1<="0001";
end if;
if b='1' then
tmp2<='1';
wrg_lgt1<="0010";
end if;
if c='1' then
tmp2<='1';
wrg_lgt1<="0011";
end if;
if d='1' then
tmp2<='1';
wrg_lgt1<="0100";
end if;
end if;
end if;
end process;
process(clr,clk,tmp1,tmp3)
begin
if (clk'event and clk='1') then
if clr='1' then
count1<="1111";
tmp3<='0';
elsif en='1' and tmp1='0' and tmp3='0' then
if count1="0000" then
tmp3<='1';
else
count1<=count1-'1';
end if;
end if;
end if;
end process;
count<=count1;
alw_lgt<=alw_lgt1;
dsp<=dsp1;
wrg_lgt<=wrg_lgt1;
fbd_lgt<=fbd_lgt1;
end rtl;