顶层文件设计:
1、抢答器:锁存抢答者信号,并控制相应的LED灯点亮
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
--抢答器,确定抢答选手编号,并控制相应的LED灯点亮
ENTITY QAI IS
PORT(CLR:IN STD_LOGIC;--开始键
A,B:IN STD_LOGIC;
A1,B1:BUFFER STD_LOGIC;
G:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
RST:IN STD_LOGIC);
END QAI;
--CLR 开始\停止按键;RST 复位键
A、B抢答者按键
ARCHITECTURE BEHAV OF QAI IS
BEGIN
PROCESS(CLR,A,B)
BEGIN
IF (CLR='0' OR RST='0') THEN
A1<='0';B1<='0';G<="0000";
ELSIF (A1='1'OR B1='1') THEN NULL;--锁存抢答者编号
ELSIF(A='0' AND B='1') THEN
A1<='1';B1<='0';G<="0001";
ELSIF(A='1' AND B='0') THEN
A1<='0';B1<='1';G<="0010";
END IF;
END PROCESS;
END BEHAV;
2、数据处理器:
①抢答犯规或者倒计时五秒时蜂鸣器以一秒响一次的频率报警
②按下按键,蜂鸣器响应
③1秒时钟分频
④30秒倒计时+倒计时5秒报警(这部分为队友负责)
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
--抢答30s倒计时
ENTITY RAT IS
PORT(RST,CLR:IN STD_LOGIC;
CLK,A,B:IN STD_LOGIC;
QA:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--个位
QB:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--十位
BEEP:OUT STD_LOGIC);
END RAT;
ARCHITECTURE BEHAV OF RAT IS
SIGNAL clk1:std_logic;
SIGNAL flag:std_logic:= '0';
SIGNAL flag1:std_logic:= '1';
SIGNAL TMPA:STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL TMPB:STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
PROCESS(CLK)--时钟分频--1s
VARIABLE num1:INTEGER RANGE 1 TO 25000000;
BEGIN
IF rising_edge(CLK)then
IF num1 = 25000000
THEN num1:= 1;clk1<= not clk1;
ELSE num1:= num1+1;
END if;
END if;
END PROCESS;
PROCESS(CLK, RST)
BEGIN
IF RST = '0' THEN
flag <= '0';停止抢答状态
flag1 <= '1';
ELSIF rising_edge(CLK) THEN
IF CLR= '0' THEN
flag <= not flag;
flag1 <= '1';
END IF;
IF flag='0'THEN
IF( A= '0' OR B= '0' )THEN
flag1 <= '0';--提前抢答,不启动倒计时
END IF;
ELSE
IF( A= '0' OR B= '0' )THEN
flag1 <= '1';--正确抢答,启动倒计时
END IF;
END IF;
END IF;
END PROCESS;
PROCESS(clk1)
BEGIN
IF (RST='0' OR flag='0' OR A= '0' OR B= '0') THEN
TMPA<="0000";TMPB<="0011";--重新开始
ELSIF rising_edge(clk1) THEN--开始计时
IF (flag='1'OR flag1='1') THEN
IF TMPA="0000" THEN --30s倒计时
IF TMPB="0000" THEN
TMPB<="0000";
ELSE
TMPB<=TMPB-1;
TMPA<="1001";
END IF;
ELSE TMPA<=TMPA-1;
END IF;
END IF;
END IF;
QA<=TMPA;QB<=TMPB;
END PROCESS;
PROCESS (CLR,A,B)
BEGIN--抢答犯规\倒计时五秒--启动报警
IF (flag1 = '0' OR (TMPA<="0101" AND TMPA>="0001" AND TMPB="0000")) THEN
IF clk1='1' THEN
BEEP<='1';
ELSE
BEEP<='0';
END IF;
ELSIF (CLR='0' OR A='0' OR B='0')THEN--按键控制蜂鸣器响应
BEEP<='1';
ELSE
BEEP<='0';
END IF;
END PROCESS;
END BEHAV;
3、计分功能:按下计分按钮能实现对应组别的加分操作
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
--增加的计分功能
ENTITY SCORE IS
PORT(RST:IN STD_LOGIC;
ADD:IN STD_LOGIC;
CHOOSE:IN STD_LOGIC_VECTOR(3 DOWNTO 0);
OUT1:OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END SCORE;
ARCHITECTURE BEHAV OF SCORE IS
BEGIN
PROCESS(RST,ADD,CHOOSE)
VARIABLE POINT_A:STD_LOGIC_VECTOR(3 DOWNTO 0);
VARIABLE POINT_B:STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
IF RST='0' THEN--初始化分数
POINT_A:="0000";
POINT_B:="0000";
ELSIF RISING_EDGE(ADD) THEN
IF CHOOSE="0001" THEN--A组得分
IF POINT_A="1001" THEN--最高计分为9分
POINT_A:="0000";
ELSE
POINT_A:=POINT_A+1;
END IF;
ELSIF CHOOSE="0010" THEN--B组得分
IF POINT_B="1001" THEN
POINT_B:="0000";
ELSE
POINT_B:=POINT_B+1;
END IF;
END IF;
END IF;
IF CHOOSE="0001" THEN--抢答者1
OUT1<=POINT_A;
ELSIF CHOOSE="0010" THEN--抢答者2
OUT1<=POINT_B;
ELSIF CHOOSE="0000" THEN--无人抢答
OUT1<="0000";
END IF;
END PROCESS;
END BEHAV;
4、数码管译码:数码管段选
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
--译码器
ENTITY DECODER IS
PORT(AIN4:IN STD_LOGIC_VECTOR(3 DOWNTO 0);
DOUT8:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END DECODER;
ARCHITECTURE BEHAV OF DECODER IS
BEGIN
PROCESS(AIN4)
BEGIN
CASE AIN4 IS
WHEN "0000"=>DOUT8<="11000000";--0--对应数码管段选hgfedcba,0为点亮,1为熄灭
WHEN "0001"=>DOUT8<="11111001";--1
WHEN "0010"=>DOUT8<="10100100";--2
WHEN "0011"=>DOUT8<="10110000";--3
WHEN "0100"=>DOUT8<="10011001";--4
WHEN "0101"=>DOUT8<="10010010";--5
WHEN "0110"=>DOUT8<="10000010";--6
WHEN "0111"=>DOUT8<="11011000";--7
WHEN "1000"=>DOUT8<="10000000";--8
WHEN "1001"=>DOUT8<="10010000";--9
WHEN OTHERS=>DOUT8<="11111111";--全灭
END CASE;
END PROCESS;
END BEHAV;
5、数码管动态扫描:数码管位选
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
--数码管的动态扫描
ENTITY CHOSE_4 is
PORT(RST,CLK:IN STD_LOGIC;
qal,score,tmpa,tmpb:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
BT: OUT STD_LOGIC_VECTOR(5 DOWNTO 0); --数码管选择输出引脚
SEG:OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); --数码管段输出引脚;
END CHOSE_4;
ARCHITECTURE BEHAV OF CHOSE_4 IS
SIGNAL scan_LED:integer range 0 to 5;--扫描数码管的个数
SIGNAL clk2:std_logic;
BEGIN
PROCESS(CLK)--时钟分频--1000Hz扫描数码管
variable num2:integer range 1 to 25000;
BEGIN
if rising_edge(CLK)then
if num2 = 25000
then num2 := 1;clk2<= not clk2;
else num2 := num2+1;
END if;
END IF;
if rising_edge(clk2)then
if(scan_LED=5)then
scan_LED<=0;
else
scan_LED<=scan_LED+1;
end if;
end if;
END PROCESS;
PROCESS(scan_LED)
BEGIN
IF RST='1' THEN
CASE scan_LED IS
WHEN 0=>BT<="111110";SEG<=qal;--数码管6
WHEN 1=>BT<="111101";SEG<="10111111";--数码管5
WHEN 2=>BT<="111011";SEG<=score;--数码管4
WHEN 3=>BT<="110111";SEG<="10111111";--数码管3
WHEN 4=>BT<="101111";SEG<=tmpa;--数码管2
WHEN 5=>BT<="011111";SEG<=tmpb;--数码管1
when OTHERS => Null;
END CASE;
ELSE
BT<="111000";SEG<="10001110";--按下复位键RST,输出FFF
END IF;
END PROCESS;
END BEHAV;
6、按键消抖(这部分为队友负责)
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY XD IS
PORT(CLK:IN STD_LOGIC;
CLR_IN,A_IN,B_IN,RST_IN,ADD_IN:IN STD_LOGIC;
CLR,A,B,RST,ADD:OUT STD_LOGIC);
END XD;
ARCHITECTURE BEHAV OF XD IS
BEGIN
PROCESS(CLK,RST_IN)
VARIABLE COUNT1:INTEGER RANGE 0 TO 1000000;--20ms计数
BEGIN
IF RST_IN='0' THEN--按下按键进行20ms检测判断
IF RISING_EDGE(CLK) THEN
IF COUNT1<1000000 THEN--计数器计数
COUNT1:=COUNT1+1;
ELSE COUNT1:=COUNT1;--此时计数器值为1000000
END IF;
IF COUNT1=1000000 THEN RST<='0';--确认按键按下,输出低电平
ELSE RST<='1';--确认按键未按下,输出高电平
END IF;
END IF;
ELSE
COUNT1:=0;--计数器清零
RST<='1';--按键未按下或者按键按下后松开即为高电平
END IF;
END PROCESS;
PROCESS(CLK,CLR_IN)
VARIABLE COUNT2:INTEGER RANGE 0 TO 1000000;
BEGIN
IF CLR_IN='0' THEN
IF RISING_EDGE(CLK) THEN
IF COUNT2<1000000 THEN
COUNT2:=COUNT2+1;
ELSE COUNT2:=COUNT2;
END IF;
IF COUNT2=1000000 THEN CLR<='0';
ELSE CLR<='1';
END IF;
END IF;
ELSE
COUNT2:=0;
CLR<='1';
END IF;
END PROCESS;
PROCESS(CLK,ADD_IN)
VARIABLE COUNT3:INTEGER RANGE 0 TO 1000000;
BEGIN
IF ADD_IN='0' THEN
IF RISING_EDGE(CLK) THEN
IF COUNT3<1000000 THEN
COUNT3:=COUNT3+1;
ELSE COUNT3:=COUNT3;
END IF;
IF COUNT3=1000000 THEN ADD<='0';
ELSE ADD<='1';
END IF;
END IF;
ELSE
COUNT3:=0;
ADD<='1';
END IF;
END PROCESS;
PROCESS(CLK,A_IN)
VARIABLE COUNT4:INTEGER RANGE 0 TO 1000000;
BEGIN
IF A_IN='0' THEN
IF RISING_EDGE(CLK) THEN
IF COUNT4<1000000 THEN
COUNT4:=COUNT4+1;
ELSE COUNT4:=COUNT4;
END IF;
IF COUNT4=1000000 THEN A<='0';
ELSE A<='1';
END IF;
END IF;
ELSE
COUNT4:=0;
A<='1';
END IF;
END PROCESS;
PROCESS(CLK,A_IN)
VARIABLE COUNT5:INTEGER RANGE 0 TO 1000000;
BEGIN
IF B_IN='0' THEN
IF RISING_EDGE(CLK) THEN
IF COUNT5<1000000 THEN
COUNT5:=COUNT5+1;
ELSE COUNT5:=COUNT5;
END IF;
IF COUNT5=1000000 THEN B<='0';
ELSE B<='1';
END IF;
END IF;
ELSE
COUNT5:=0;
B<='1';
END IF;
END PROCESS;
END BEHAV;
7、编译仿真结果
8、引脚分配