数字系统设计与硬件描述语言
期末考试作业
题目: 数字式竞赛抢答器设计 学院: 电子信息工程 专业: 电子信息工程 学号: 姓名:
一、 选题设计描述
1. 功能介绍
此设计用于竞赛的四人抢答,有如下的功能: (1) 具有多路抢答功能,台数设计为四;
(2) 具有抢答器开始后30秒倒计时,30秒后无人抢答显示超时,并报警; (3) 能显示超前抢答犯规,并警报;
(4) 能显示各组得分,大队加分,答错扣分;
当系统复位,主持人按下抢答开始按键,处于使能状态,抢答开始,某路抢答键按下时,该路信号将其他路信号锁存,同时抢答铃声响起,直至此路按键松开,显示该路组号。
2. 算法简介
本设计采用分层设计思想,分为:信号鉴别模块、计时模块、计分模块、BCD译码模块、分频器,还有顶层模块。
信号鉴别模块。此模块主要实现抢答器的抢答功能,并能够分辨是正常抢答还是提前抢答,选取最先按下的一路信号,锁存其余信号,实现信号选取功能.在此模块中,用到的信号为抢答信号a、b、c、d;抢答使能信号en;抢答结果信号states;警报时钟信号clk2;复位信号 rst;提前抢答信号fangui。
计时模块。此模块主要实现抢答过程中的计时功能,在抢答开始后进行30秒的倒计时,且在30秒后显示无人抢答报警信号。其中有抢答时钟信号clk;系统复位信号rst;抢答使能信号en;无人抢答警报信号warn;计时中止信号stop;计时十位个位信号tb,ta.
计分模块。此模块主要实现给四个抢答器计分的功能,初始条件下,为每个抢答器信号预制5分,当某组抢答且回答正确时加一分,答错减一分,未获答题机会时保持不变.其中设有时钟信号clk;复位信号rst;抢答使能信号en;抢答结果显示信号states;记分加减信号add(add=‘1’时为加,add=‘0’时为减);四个信号的得分显示信号a_out,b_out,c_out,d_out。
BCD译码模块.此模块主要实现将抢答结果信号显示在bcd七段译码器上。其中输入信号a;输出译码结果信号q。
分频器。此模块主要实现时钟分频功能。在开头对时钟信号进行一次千分频。其中时钟输入信号clkin,输出信号clk。
顶层模块.将前几个模块综合在一起,形成一个整体。分频器输出作为其他模块所需的时钟信号,使整个系统正常运转。
二、 程序源代码及说明
抢答信号鉴别模块的程序: library ieee;
use ieee.std_logic_1164.all; use ieee。std_logic_unsigned.all; entity qdjb is
port(clk2,en,rst:in std_logic;
a,b,c,d:in std_logic; fangui:out std_logic;
states:out std_logic_vector(3 downto 0)); end qdjb;
architecture one of qdjb is signal sinor,fanguif,tmp:std_logic; signal cnt:std_logic_vector(5 downto 0); begin
sinor<=a or b or c or d;
p1:process(a,rst,b,c,d,tmp) begin
if rst=’1’ then —-复位信号有效,系统复位。 tmp<=’1';states<=\"0000”; elsif tmp=’1' then
if a='1' then -—判断哪路信号变化,进行选取 states<=”0001\";tmp〈='0’; --对states进行置数 elsif b=’1’ then
states<=\"0010”;tmp〈=’0'; elsif c='1' then
states〈=\"0011”;tmp<=’0’; elsif d=’1' then
states<=”0100\";tmp〈=’0’; else tmp<='1’;states<=\"0000”; end if ; end if;
end process p1;
p2:process(clk2,en,rst,cnt) ——判断是否提前抢答并报警 begin
if rst=’1’ then
cnt<=\"000000”;fanguif<=’0'; ——初始化提前抢答犯规信号 elsif clk2'event and clk2='1’ then
if en=’0' and sinor='1’ then if cnt<”111111” then
fanguif〈=not fanguif;cnt<=cnt+1; else fanguif〈='0'; end if; end if; end if; end process p2; fangui〈=fanguif; end one; 计时模块的程序: library ieee;
use ieee.std_logic_1164。all; use ieee.std_logic_unsigned。all; entity js is
port(clk,rst,en,stop:in std_logic; warn:buffer std_logic;
ta,tb:buffer std_logic_vector(3 downto 0)); end js;
architecture one of js is signal co:std_logic; begin
p1:process(clk,rst,en,stop,ta) ——个位计时信号进行0到9循环计数 begin
if rst='1' or stop='1’ then ta〈=”0000\";
elsif clk'event and clk=’1' then co〈=’0'; if en='1’ then if ta=”0000” then ta<=\"1001\";co〈=’1’;
else ta<=ta-1; end if; end if; end if; end process p1;
p2:process(co,rst,en,stop,tb) ——十位计时信号0到3变化 begin
if rst=’1' or stop=’1’ then tb〈=”0011\";
elsif co'event and co=’1’ then if en=’1' then
if tb=\"0000\" then tb<=”0011\"; else tb<=tb-1; end if; end if; end if; end process p2;
p3:process(rst,ta,tb) --计时时间到达,报警 begin
if rst=’1' then warn〈='0’;
elsif ta=\"0000\" and tb=”0000” then warn〈=’1’; else warn<='0'; end if; end process p3; end one; 计分模块的程序: library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all;
entity jf is
port(clk,rst,en,add:in std_logic;
states:in std_logic_vector(3 downto 0);
a_out,b_out,c_out,d_out:buffer std_logic_vector(3 downto 0)); end jf;
architecture one of jf is begin
p1:process(clk,rst,add,states,a_out,b_out,c_out,d_out) begin
if (rst=’1') then
a_out<=”0101”;b_out<=”0101”;c_out〈=”0101\";d_out〈=”0101\"; --初始化置5分
elsif en='1'then
if clk'event and clk=’1' then case states is when \"0001\"=>
if add='1’ then --add信号为高时,加1分
if a_out=\"1111\" then -—最多15分 a_out<=”0000\"; else a_out〈=a_out+1; end if;
elsif add='0' then ——add信号为0,减1分
if a_out=\"0000\" then a_out〈=\"0000”; else a_out<=a_out-1; end if;
end if; when ”0010”=〉 if add='1' then
if b_out=\"1111” then b_out〈=”0000”; else b_out<=b_out+1;
end if;
elsif add='0' then
if b_out=\"0000\" then b_out〈=”0000”; else b_out〈=b_out—1; end if;
end if; when ”0011\"=〉 if add=’1' then
if c_out=”1111\" then c_out<=”0000\"; else c_out<=c_out+1; end if;
elsif add='0’ then
if c_out=”0000” then c_out〈=\"0000\"; else c_out<=c_out—1; end if;
end if; when \"0100\"=> if add='1’ then if d_out=\"1111” then d_out<=\"0000”; else d_out<=d_out+1; end if;
elsif add=’0’ then if d_out=”0000” then d_out<=”0000\"; else d_out〈=d_out-1; end if; end if;
when others=〉
a_out〈=a_out;b_out<=b_out;c_out<=c_out;d_out〈=d_out; end case; end if; end if;
end process p1; end one;
抢答器顶层模块程序: library ieee;
use ieee.std_logic_1164。all; use ieee。std_logic_unsigned.all; entity qiangda is
port(clkin,clk2,en,a,b,c,d,add,stop,rst:in std_logic; fangui,alarm:out std_logic;
ta,tb:buffer std_logic_vector(3 downto 0); states:buffer std_logic_vector(3 downto 0); statesout:out std_logic_vector(0 to 6);
a_out,b_out,c_out,d_out:buffer std_logic_vector(3 downto 0)); end qiangda;
architecture bhv of qiangda is component qdjb is
port(clk2,en,rst:in std_logic; a,b,c,d:in std_logic; fangui:out std_logic;
states:out std_logic_vector(3 downto 0)); end component; component js is
port(clk,rst,en,stop:in std_logic; warn:buffer std_logic;
ta,tb:buffer std_logic_vector(3 downto 0)); end component;
component jf is
port(clk,rst,en,add:in std_logic;
states:in std_logic_vector(3 downto 0);
a_out,b_out,c_out,d_out:buffer std_logic_vector(3 downto 0)); end component; component BCD7 is
port(a:in std_logic_vector(3 downto 0); q:out std_logic_vector(0 to 6)); end component BCD7; component divf is
port(clk: IN STD_LOGIC; q : OUT STD_LOGIC;
qn: OUT std_logic_vector(9 downto 0)); end component divf;
signal cnt:std_logic_vector(3 downto 0); signal clk: STD_LOGIC;
signal divqn: std_logic_vector(3 downto 0); begin
u1:qdjb port map(clk2,en,rst,a,b,c,d,fangui,states); u2:js port map(clk,rst,en,stop,alarm,ta,tb);
u3:jf port map(clk,rst,en,add,states,a_out,b_out,c_out,d_out); u4:BCD7 port map(states,statesout); u5:divf port map(clkin,clk,divqn); end bhv;
BCD7段译码器模块程序: LIBRARY IEEE;
USE IEEE。STD_LOGIC_1164。ALL; ENTITY BCD7 IS
PORT(a: IN STD_LOGIC_VECTOR(3 DOWNTO 0); -—数据输入
q : OUT STD_LOGIC_VECTOR(0 TO 6) ); -—7段输出 END BCD7;
ARCHITECTURE behav OF BCD7 IS BEGIN
PROCESS (a) BEGIN
case a(3 downto 0) is -— BCD 7段译码表
when ”0000\" =〉 q<=”1111110\";
when ”0001\" =〉 q<=”0110000”; when \"0010\" => q〈=\"1101101”;
when \"0011” =〉 q〈=”1111001”; when ”0100” =〉 q<=\"0110011\"; when ”0101” => q〈=\"1011011”; when ”0110” =〉 q〈=”1011111\";
when ”0111” =〉 q〈=”1110000\"; when \"1000” =〉 q〈=\"1111111\";
when ”1001” => q<=”1111011\"; when others => q〈=”0000000”; END case;
END PROCESS; END behav;
一千分频器模块程序: LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164。ALL; USE IEEE.STD_LOGIC_unsigned.ALL; ENTITY divf IS
PORT(clk: IN STD_LOGIC; q : OUT STD_LOGIC;
qn: OUT std_logic_vector(9 downto 0)); END divf;
ARCHITECTURE behav OF divf IS signal rst: std_logic;
signal qn1:std_logic_vector(9 downto 0); BEGIN
PROCESS (clk,rst) BEGIN
if rst='1’ then
qn1<= \"0000000000”; elsif clk’event and clk='1’ then qn1〈=qn1+1; end if; END PROCESS;
rst<='1’ when qn1=1000 else ’0’; qn<=qn1; ——计数
q〈=qn1(9); —-分频输出,1000分频 END behav;
三、 仿真结果及分析
系统总体框图:
对于各个模块的仿真测试所得结果,仿真波形分析如下:
1、 信号鉴别模块:
仿真结果:
本模块主要实现抢答功能。当rst信号为‘1’,en信号为‘1’时,抢答开始,当有一路正常获得抢答时,系统会自动封锁另外三路的抢答信号,只允许一人处于答题状态;当主持人没有允许抢答时,若有人超前抢答,警报会响起,同时只要有人抢答那么抢答显示台(states)会显示哪一个在抢答.如上图示,在系统第一个复位信号来临后,电路自动复位,在允许抢答信号来临之前(即en=‘0’),b台超前抢答,此时警报响起(即超前抢答警报信号fangui获得一个频率很高的脉冲,就会响起),之后主持人复位,并允许抢答,a台最先抢答,此时抢答显示台显示其台号1. 2、 计时模块:
仿真结果:
本模块主要实现计时功能.当rst信号为‘1'时,计时复位为30秒倒计时,主持人允许的en信号为‘1’时,开始进行倒计时,系统时钟每来一个上升沿,倒计时减1,当到30秒倒计时计玩仍然无人抢答时,警报指示灯亮(即warn=‘1'),若有人抢答主持人可以按下中止键(即stop=‘1’),这样倒计时就会回到30秒初始状态。图示的情况为在倒计时16秒时,主持人按下中止键,计时器变为初始值30,在下一轮抢答过程中,倒计时为0时仍然无人抢答,此时警报指示信号亮(即warn=‘1’)。 3、计分模块:
仿真结果:
本模块主要实现记分功能,其工作情况为:系统复位信号来临(即rst=‘1'),将每个选手的得分预置为5分,抢答显示台显示为0即无人抢答,当主持人允许抢答时,若有人抢答,答对(即add=‘1’,假设所有人都答对了)的加一分,答错(即add=‘0’)的减一分,没有抢答的保持不变。图示,开始后a台连续抢答5题,且都答对,a_out变成10了,之后c台连续抢答成功,且都答对加分,最高记到了15分数码管显示位F,此时获胜并把分数重新置为0. 4、BCD7段译码模块:
仿真结果:
本模块主要实现数据输入的7段输出.主要是0到9的数分别译出,10到15都译为“0000000”,
实现了设置的功能。 5、一千分频模块: 仿真结果:
本模块实现输入信号的一千分频。另外还可以取其中的其他位,实现其他分频。如上图,qn[0]实现两分频,qn[5]实现64分频,qn[6]实现128分频,等等. 6、顶层模块:
本模块为顶层文件,是综合抢答器鉴别模块、抢答器计时模块、抢答器记分模块、BCD7段译码模块和一千分频模块而成.在其仿真波形中描述的情况为:第一次系统复位后,主任人还没有宣布抢答开始,但a台超前抢答了,fangui信号脉冲波形出现了,主持人就知道a犯规了;接着第二轮系
统复位后,主持人宣布抢答开始,b台先抢答成功,抢答显示台号显示为3,单答题错误(add=‘0’),故减分,相应的数码管显示其总分情况.
四、 心得体会
这次实验,首先最难的就是模块的划分,必须先有一个总体的规划,然后细化去写每个模块的程序,我在写程序的过程中,参考了课程使用的课件,参考了网上资料,觉得vhdl程序结构特别严密,并且quartus ii软件能为我找出程序语法上的低级失误,低级错误,使我对于vhdl语法规则有了更加深刻的理解.此外,在仿真的过程中,开始时经常忘了将当前实体设置为顶层实体使得仿真过程中出现了多次错误,所以进过这次实验我大概有了一个仿真的固定步骤,一步一步来才不至于出现这种问题。总之,这次实验还是收获颇丰的,我知道了采用自顶向下的设计思想,那么顶层的设计就很重要,顶层设计好后,下面各部分写起来就比较清楚容易了。
因篇幅问题不能全部显示,请点此查看更多更全内容