EDA课程设计报告

EDA技术课程设计任务书

系(部):电子与通信工程系     专业:电气工程及其自动化       指导教师:谢明华

长沙学院课程设计鉴定表

目录

摘要.................................................................................................................................................. 5

一、 课程设计内容............................................................................................................................ 6

二、系统总体设计............................................................................................................................. 6

三、系统软件设计与实现................................................................................................................... 7

1. 各模块程序说明..................................................................................................................... 7

2.各模块输入输出端口说明:................................................................................................... 18

2.引脚分配及下载过程:.......................................................................................................... 20

四、系统测试与结果分析:.............................................................................................................. 20

1. 源程序仿真波形结果............................................................................................................. 20

2. 采样编码模块仿真波形结果.................................................................................................. 21

3. 分频模块仿真波形结果......................................................................................................... 21

4. 时钟选择模块仿真波形结果.................................................................................................. 21

5. 随机数产生模块仿真波形结果............................................................................................... 22

6. 匹配模块仿真波形结果......................................................................................................... 22

五、心得体会................................................................................................................................... 24

参考文献.......................................................................................................................................... 25

摘要

本次按键游戏课程设计我们主要是应用VHDL语言程序设计,游戏参与者根据系统中的亮灯提示控制相应按键。对按键控制准确,说明参与者的身体越灵活,反应越快。整个系统划分为:编码模块,分频模块,时钟选择模块(即速度控制模块),随机数产生模块,比较匹配模块(即得分模块)等模块,所有算法由软件结合硬件电路来实现,利用描述语言VHDL,并通过XilinxFPGA 芯片实现。

一、课程设计内容

用8个灯作目标,与之对应有8个按键进行控制。每一次8个灯中随机出现一个灯处于“亮”的状态,在灯亮的时间内要求按到对应的按键,若按到则加1分,且灯熄灭;否则失败扣1分。 游戏分1-4四个难度级别,每个级别灯闪亮的速度不同,级别越高,速度越快,灯亮的时间越短。设定初始等级为1,连续成功按键5次加1等级,分数不清0,连续失败5次减1等级, 等级为0时游戏结束。设有暂停/继续和开始/停止功能。

二、系统总体设计

系统框图与说明

各框图说明:

①分频模块是将输入的FPGA 的50MHz 的时钟分频为各种需要的时钟。

②时钟选择模块根据按键匹配的结果,选择对应难度的时钟,即选择A,B,C,D 其中的一个,

然后控制其他的模块。

③随机数产生模块使用的是m 序列,是基于线性反馈移位寄存器的原理实现的。本实验中

使用的是8 级m 序列发生器,产生一个长度为255 个时钟脉冲周期的二进制伪随机序列。

其逻辑框图如下:

取其中的三位(如后三位)通过3-8 译码器来点亮LED 灯。

④采样编码模块,将8 个输入按键进行采样,编码成3 位数。

⑤匹配模块,是把用户的按键输入值与对应于亮灯的随机数进行比较,如果相同则增加分数

值,不同则减少分数值。

三、系统软件设计与实现

1.各模块程序说明

 1)顶层模块

entity game is

port(clk50m:in std_logic;

       k1,k2,k3,k4,k5,k6,k7,k8:in std_logic;

       start:in std_logic;

       clear:in std_logic;

       en:in STD_LOGIC;

       win,lose:out std_logic;

       led:out std_logic_vector(2 downto 0);

       Sel_selout:out std_logic;

       Sel7s:out std_logic_vector(6 downto 0);

       sound:out std_logic;

       LCD_RS : out STD_LOGIC;

       LCD_RW : out STD_LOGIC;

       LCD_EN : out STD_LOGIC;

       data : out STD_LOGIC_VECTOR (3 downto 0));

end game;

architecture Behavioral of game is

signal A,B,C,D,clk,clkout,clk4,clk500,clk6m:std_logic;

signal key:STD_LOGIC_VECTOR (2 downto 0);

signal mwin,mlose:std_logic;

signal en_A,en_B,en_C,en_D: std_logic;

signal mled:std_logic_vector(2 downto 0);

signal score,highscore:STD_LOGIC_VECTOR(11 downto 0);

signal life:STD_LOGIC_VECTOR (7 downto 0);

--采样编码模块声明

component code

port(clk50m:in std_logic;

       clk:in std_logic;

       start:in std_logic;

       k1,k2,k3,k4,k5,k6,k7,k8:in std_logic;

       key:out std_logic_vector(2 downto 0));

end component;

--分频模块声明

component divider

   Port ( clk50m : in STD_LOGIC;

               start:in STD_LOGIC;

            A : out STD_LOGIC;

            B : out STD_LOGIC;

            C: out STD_LOGIC;

            D : out STD_LOGIC;

            clk500:out STD_LOGIC;

            clk4:out std_logic;

            clk6m:out std_logic);

end component;

--时钟选择模块声明

component clk_sel

   port(clk50m:in std_logic;

          start:in std_logic;

          A,B,C,D:in std_logic;

          en_A,en_B,en_C,en_D:in std_logic;

          leda,ledb,ledc,ledd:out std_logic;

          clkout:out std_logic);

end component;

--随机数产生模块声明

component random

   Port ( clk : in STD_LOGIC;

           start:in STD_LOGIC;

           en:in STD_LOGIC;

           led : out STD_LOGIC_VECTOR (2 downto 0));

end component;

--匹配模块声明

component compare

port( start:in std_logic;

      clear:in std_logic;

      en:in std_logic;

      clk : in STD_LOGIC;

      key : in STD_LOGIC_VECTOR (2 downto 0);

      led : in STD_LOGIC_VECTOR (2 downto 0);

      win,lose:out STD_LOGIC;

      en_A : out STD_LOGIC;

      en_B : out STD_LOGIC;

      en_C : out STD_LOGIC;

      en_D : out STD_LOGIC;

      highscore_out:out STD_LOGIC_VECTOR(11 downto 0);

      score_out : out STD_LOGIC_VECTOR (11 downto 0);

      life_out : out STD_LOGIC_VECTOR (7 downto 0));

end component;

begin

   win<=mwin;

   lose<=mlose;

   led<=mled;

   u0:code port map(clk50m,clkout,start,k1,k2,k3,k4,k5,k6,k7,k8,key);

   u1:divider port map(clk50m,start,A,B,C,D,clk500,clk4,clk6m);

   u2:clk_sel port map(clk50m,start,A,B,C,D,en_A,en_B,en_C,en_D,leda,ledb,ledc,ledd,clkout);

   u3:random port map(clkout,start,en,mled);

   u4:compare port

   map(start,clear,en,clkout,key,mled,mwin,mlose,en_A,en_B,en_C,en_D,highscore,score,life);

   u5:music port map(clk6m,clk4,en_A,en_B,en_C,en_D,sound);

   u6:lcd port

   map(clk500,start,mwin,mlose,highscore,score,life,LCD_RS,LCD_RW,LCD_EN,data);

end Behavioral;

2)采样编码模块

 (采样编码模块,将8 个输入按键进行采样,编码成3 位数。)

library ieee;

use ieee.std_logic_1164.all;

entity code is

  port(clk50m:in std_logic; --50MHz 的输入时钟

      clk:in std_logic; --时钟选择后得到的时钟,即不同难度对应的时钟

      start:in std_logic; --开始信号,高电平有效

      k1,k2,k3,k4,k5,k6,k7,k8:in std_logic; --8 个输入按键

      key:out std_logic_vector(2 downto 0)); --按键编码后得到的编码

end code;

architecture Behavioral of code is

signal flag:std_logic; --标志位

begin

process(clk50m,clk,start)

begin

if start='0' then --初始时令flag=0

   flag<='0';

elsif clk50m='1' then--用50MHz 的时钟进行采样编码,且在一个难度时钟内只采样编码一次

    if flag='0' then

        if k8='1' then

            key<="111";

            flag<='1'; --flag=1 时表明已经采样编码完毕

        elsif k7='1' then

              key<="110";

              flag<='1';

        elsif k6='1' then

              key<="101";

              flag<='1';

        elsif k5='1' then

              key<="100";

              flag<='1';

        elsif k4='1' then

              key<="011";

              flag<='1';

        elsif k3='1' then

              key<="010";

              flag<='1';

        elsif k2='1' then

              key<="001";

              flag<='1';

        elsif k1='1' then

              key<="000";

              flag<='1';

        end if;

    end if;

elsif rising_edge(clk) then --在难度时钟的上升沿将flag 置0,表明可进行采样编码

    if flag='1' then

        flag<='0';

    end if;

end if;

end process;

end Behavioral;

3)分频模块

  (分频模块是将输入的FPGA 的50MHz 的时钟分频为各种需要的时钟。)

    library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

entity game is

    Port ( clk50m : in STD_LOGIC; --50MHz 的输入时钟

             start:in STD_LOGIC; --开始信号,高电平有效

          A : out STD_LOGIC; --难度A 的周期为2.5 秒

          B : out STD_LOGIC; --难度B 的周期为2.0 秒

          C : out STD_LOGIC; --难度C 的周期为1.5 秒

          D : out STD_LOGIC; --难度D 的周期为1.0 秒

             clk500:out STD_LOGIC; --clk500=500Hz

             clk4:out std_logic; --clk=4Hz

             clk6m:out std_logic); --clk6m=6.25MHz

end game;

architecture Behavioral of game is

signal ma,mb,mc,md,m4,m500,m6m:std_logic:='0';

signal cnt1:integer range 1 to 50000;

signal cnt2:integer range 1 to 6250000;

signal cnt3:integer range 1 to 2;

signal cnt4:integer range 1 to 5;

signal cnt5:integer range 1 to 3;

begin

    A<=ma;

    B<=mb;

    C<=mc;

    D<=md;

    clk500<=m500;

    clk6m<=m6m;

    clk4<=m4;

process(clk50m)

   variable n:integer range 1 to 5:=1;

begin

    if rising_edge(clk50m) then --50MHz8 分频后得到6.25MHz 的信号clk6m

        n:=n+1;

        if n=5 then

            m6m<=not m6m;

            n:=1;

        end if;

        if cnt1=50000 then --50MHz100000 分频后得到500Hz 的信号clk500

           m500<=not m500;

           cnt1<=1;

        else

           cnt1<=cnt1+1;

        end if;

        if cnt2=6250000 then ----50MHz12500000 分频后得到4Hz 的信号clk4

           m4<=not m4;

           cnt2<=1;

        else

           cnt2<=cnt2+1;

        end if;

    end if;

end process;

process(start,m4,md)

begin

    if start='0' then --start=0 时初始化

         ma<='0';

         mb<='0';

         mc<='0';

         md<='0';

         cnt3<=1;

         cnt5<=1;

    else

         if rising_edge(m4) then --4Hz 时钟4 分频后得到1Hz

             if cnt3=2 then

               cnt3<=1;

               md<=not md;

            else

               cnt3<=cnt3+1;

            end if;

            if cnt4=5 then --4Hz 时钟10 分频后得到0.4Hz 时

              ma<=not ma;

              cnt4<=1;

           else

              cnt4<=cnt4+1;

           end if;

           if cnt5=3 then --4Hz 时钟6 分频后得到0.67Hz 时

              mc<=not mc;

              cnt5<=1;

           else

              cnt5<=cnt5+1;

           end if;

       end if;

       if rising_edge(md) then --1Hz 时钟2 分频后得到0.5Hz 的时

           mb<=not mb;

       end if;

   end if;

end process;

end Behavioral;

4)时钟选择模块

  (时钟选择模块根据按键匹配的结果,选择对应难度的时钟,即选择A,B,C,D 其 中的一个,然后控    制  其他的模块。)

  library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

entity clk_sel is

port(clk50m:in std_logic; --50MHz 的输入时钟

     start:in std_logic; --开始信号,高电平有效

     A,B,C,D:in std_logic; --A,B,C,D 分别对应难度A,B,C,D 的时钟

     en_A,en_B,en_C,en_D:in std_logic;--en_A,en_B,en_C,en_D 分别为A,B,C,D 的使能信号

     led_selout:out std_logic;

     led7s:out std_logic_vector(6 downto 0);--不同的难度用不同的LED 来指示

     clkout:out std_logic); --不同的难度输出对应的难度时钟

end clk_sel;

architecture Behavioral of clk_sel is

signal m:std_logic_vector(3 downto 0);

signal clk:std_logic:='0';

Begin

    led_selout<='1';

    m<=en_A&en_B&en_C&en_D;

    clkout<=clk;

process(clk50m)

begin

if start='0' then

     clk<='0';

elsif rising_edge(clk50m) then

    if m=8 then --当en_A='1'时,时钟对应为难度A 的时钟,且指示难度A 的LED亮

       clk<=A;

      led7s<="1111001";

   elsif m=4 then --当en_B='1'时,时钟对应为难度B 的时钟,且指示难度B 的LED 亮

       clk<=B;

      led7s<="0100100";

   elsif m=2 then --当en_C='1'时,时钟对应为难度C 的时钟,且指示难度C 的LED 亮

       clk<=C;

     led7s<="0110000";

   elsif m=1 then --当en_D='1'时,时钟对应为难度D 的时钟,且指示难度D 的LED 亮

       clk<=D;

      led7s<="0011001";

    else

       clk<='0';

    end if;

end if;

end process;

end Behavioral;

5)随机数产生模块

(随机数产生模块使用的是m 序列,是基于线性反馈移位寄存器的原理实现的。本实验中使用的是8 级  m 序列发生器,产生一个长度为255 个时钟脉冲周期的二进制伪随机序列。)

entity random is

   Port ( clk : in STD_LOGIC; --难度时钟

            start:in STD_LOGIC; --开始信号,高电平有效

            en:in STD_LOGIC; --暂停信号,en=0 时暂停

        led : out STD_LOGIC_VECTOR (2 downto 0)); --产生的三位随机数

end random;

architecture Behavioral of random is

signal m:std_logic_vector(7 downto 0):="10000000";

begin

led<=m(2 downto 0);

process(clk,en,start)

begin

    if start='0' then

        m<="11000011";

    elsif en='0' then

        m<=m;

    elsif rising_edge(clk) then

        m(7 downto 1)<=m(6 downto 0);

        m(0)<=m(7) xor m(3) xor m(2) xor m(1);

    end if;

end process;

end Behavioral;

6)匹配模块

   (匹配模块,是把用户的按键输入值与对应于亮灯的随机数进行比较,如果相同则增加分数值,不同则   减少分数值。)

    library ieee;

use ieee.std_logic_1164.all;

entity compare is

port( start:in std_logic; --开始信号,高电平有效

     clear:in std_logic; --最高分清零信号,clear=1 时清除最高分纪录

     en:in std_logic; --暂停信号,en=0 时暂停

     clk : in STD_LOGIC; --clk50m 为50MHz 的输入时钟,clk 为难度时钟

     key : in STD_LOGIC_VECTOR (2 downto 0); --key 为编码后得到的编码值

     led : in STD_LOGIC_VECTOR (2 downto 0);--led 为产生的三位随机数

     win,lose:out STD_LOGIC; --win=1 表明游戏胜利,lose=1 表明游戏失败

     en_A : out STD_LOGIC; --难度A 的使能信号

     en_B : out STD_LOGIC; --难度B 的使能信号

     en_C : out STD_LOGIC; --难度C 的使能信号

     en_D : out STD_LOGIC; --难度D 的使能信号

     highscore_out:out STD_LOGIC_VECTOR(11 downto 0); --最高分

     score_out : out STD_LOGIC_VECTOR (11 downto 0); --当前分数

end compare;

architecture Behavioral of compare is

signal mscore,mhighscore:integer range 0 to 999;

signal result,mwin,mlose:std_logic;

signal cnt1:integer range 0 to 4;

signal cnt2:integer range 0 to 1;

type state is(na,nb,nc,nd);

signal nandu:state;

begin

result<=mwin or mlose; --当result=1 时游戏结束,LCD 上会显示输或赢

win<=mwin;--得5 分加一条命,失误一次扣一分,失误达到2 次扣一条命,当分数为0 时,失误一次不减分,但扣一条命

  process(clk,start,en,clear)

  begin

    if mscore>mhighscore then

        mhighscore<=mscore;

    else

        mhighscore<=mhighscore;

    end if;

    if start='0' then

       mscore<=0; --初始分数为0

       cnt1<=0;

       mhighscore<=mhighscore;

       cnt2<=0;

       mwin<='0';

       mlose<='0';

       nandu<=na;

       en_A<='1';

       en_B<='0';

       en_C<='0';

       en_D<='0';

   elsif clear='1' then

       mhighscore<=0;

   elsif en='0' then

       mscore<=mscore;

       mhighscore<=mhighscore;

   elsif rising_edge(clk) then

         if result='0' then

         if led=key then

           elsif mscore=999 then

                      mwin<='1';

               elsif mscore<999 then

         mscore<=mscore+1;

           end if;

        else

           if mscore=0 and mlife=0 then

              mscore<=0;

              mlose<='1';

           elsif mlife=0 then

              mscore<=mscore;

              mlose<='1';

           elsif mscore=0 then

              mscore<=0;

           else

              mscore<=mscore-1;

           end if;

          end if;

      end if;

      end if;

      case nandu is

      when na=> --当分数小于5 分时,难度为A

             en_A<='1';

             en_B<='0';

             en_C<='0';

             en_D<='0';

             if mscore>=5 and mscore<10 then

              nandu<=nb;

          else

              nandu<=na;

          end if;

      when nb=> --当分数在5-10 之间时,难度为B

             en_A<='0';

             en_B<='1';

             en_C<='0';

             en_D<='0';

             if mscore>=10 and mscore<15 then

              nandu<=nc;

          else

              nandu<=nb;

          end if;

      when nc=> --当分数在10-15 之间时,难度为C

             en_A<='0';

             en_B<='0';

             en_C<='1';

             en_D<='0';

             if mscore>=15 and mscore<20 then

              nandu<=nd;

          else

              nandu<=nc;

          end if;

      when nd=> --当分数在15 以上时,难度为D

             en_A<='0';

             en_B<='0';

             en_C<='0';

             en_D<='1';

             nandu<=nd;

      when others=>

                 en_A<='1';

                 en_B<='0';

                 en_C<='0';

                 en_D<='0';

                 nandu<=na;

      end case;

  end if;

end process;

process(clk)

begin

    if falling_edge(clk) then

        if mscore>=900 then

        score_out(11 downto 8)<=x"9";

        if (mscore-900)>=90 then

            score_out(7 downto 4)<=x"9";

            score_out(3 downto 0)<=conv_std_logic_vector((mscore-990),4);

        elsif (mscore-900)>=80 then

               score_out(7 downto 4)<=x"8";

               score_out(3 downto 0)<=conv_std_logic_vector((mscore-980),4);

        elsif (mscore-900)>=70 then

               score_out(7 downto 4)<=x"7";

               score_out(3 downto 0)<=conv_std_logic_vector((mscore-970),4);

        elsif (mscore-900)>=60 then

               score_out(7 downto 4)<=x"6";

               score_out(3 downto 0)<=conv_std_logic_vector((mscore-960),4);

        elsif (mscore-900)>=50 then

               score_out(7 downto 4)<=x"5";

               score_out(3 downto 0)<=conv_std_logic_vector((mscore-950),4);

        elsif (mscore-900)>=40 then

               score_out(7 downto 4)<=x"4";

               score_out(3 downto 0)<=conv_std_logic_vector((mscore-940),4);

        elsif (mscore-900)>=30 then

               score_out(7 downto 4)<=x"3";

               score_out(3 downto 0)<=conv_std_logic_vector((mscore-930),4);

        elsif (mscore-900)>=20 then

               score_out(7 downto 4)<=x"2";

               score_out(3 downto 0)<=conv_std_logic_vector((mscore-920),4);

        elsif (mscore-900)>=10 then

               score_out(7 downto 4)<=x"1";

               score_out(3 downto 0)<=conv_std_logic_vector((mscore-910),4);

        else

               score_out(7 downto 4)<=x"0";

               score_out(3 downto 0)<=conv_std_logic_vector((mscore-900),4);

        end if;

   if mhighscore>=900 then

        highscore_out(11 downto 8)<=x"9";

        if (mhighscore-900)>=90 then

             highscore_out(7 downto 4)<=x"9";

             highscore_out(3 downto 0)<=conv_std_logic_vector((mhighscore-990),4);

        elsif (mhighscore-900)>=80 then

              highscore_out(7 downto 4)<=x"8";

              highscore_out(3 downto 0)<=conv_std_logic_vector((mhighscore-980),4);

        elsif (mhighscore-900)>=70 then

              highscore_out(7 downto 4)<=x"7";

              highscore_out(3 downto 0)<=conv_std_logic_vector((mhighscore-970),4);

        elsif (mhighscore-900)>=60 then

              highscore_out(7 downto 4)<=x"6";

              highscore_out(3 downto 0)<=conv_std_logic_vector((mhighscore-960),4);

        elsif (mhighscore-900)>=50 then

              highscore_out(7 downto 4)<=x"5";

              highscore_out(3 downto 0)<=conv_std_logic_vector((mhighscore-950),4);

        elsif (mhighscore-900)>=40 then

              highscore_out(7 downto 4)<=x"4";

              highscore_out(3 downto 0)<=conv_std_logic_vector((mhighscore-940),4);

        elsif (mhighscore-900)>=30 then

              highscore_out(7 downto 4)<=x"3";

              highscore_out(3 downto 0)<=conv_std_logic_vector((mhighscore-930),4);

        elsif (mhighscore-900)>=20 then

              highscore_out(7 downto 4)<=x"2";

              highscore_out(3 downto 0)<=conv_std_logic_vector((mhighscore-920),4);

        elsif (mhighscore-900)>=10 then

              highscore_out(7 downto 4)<=x"1";

              highscore_out(3 downto 0)<=conv_std_logic_vector((mhighscore-910),4);

        else

              highscore_out(7 downto 4)<=x"0";

              highscore_out(3 downto 0)<=conv_std_logic_vector((mhighscore-900),4);

        end if;

end process;

end Behavioral;

2.各模块输入输出端口说明:

  1)顶层模块game

  输入信号IN:

  clk50m:in std_logic; --50MHz 的输入时钟

  k1,k2,k3,k4,k5,k6,k7,k8:in std_logic; --8 个输入按键

  start:in std_logic; --开始信号,高电平有效

  clear:in std_logic; --最高分清零信号,clear=1 时清除最高分纪录

  en:in STD_LOGIC; --暂停信号,en=0 时暂停

  输出信号OUT:

  win,lose:out std_logic; --win=1 表明游戏胜利,lose=1 表明游戏失败

  led:out std_logic_vector(2 downto 0); --产生的三位随机数,送到74LS138进行译码,从而点亮一个LED

  leda,ledb,ledc,ledd:out std_logic; --不同的难度分别用不同的LED 灯来指示

  sound:out std_logic; --为输出的喇叭信号

  LCD_RS : out STD_LOGIC;

  LCD_RW : out STD_LOGIC;

  LCD_EN : out STD_LOGIC;

  data : out STD_LOGIC_VECTOR (3 downto 0)); --数据信号输出

2)采样编码模块code

(输入为50MHz 的时钟信号clk50m,选择的难度信号clk,

   开始信号start,以及八个按键;输出为编码值key。)

输入信号IN:

clk50m:in std_logic;

clk:in std_logic;

start:in std_logic;

k1,k2,k3,k4,k5,k6,k7,k8:in std_logic;

输出信号OUT:

key:out std_logic_vector(2 downto 0)

3)分频模块divider 

(输入为50MHz 的时钟信号,开始信号start;

  输出为A,B,C,D 四种难度的时钟。)

  输入信号IN:

clk50m : in STD_LOGIC;

start:in STD_LOGIC;

  输出信号OUT:

A : out STD_LOGIC;

B : out STD_LOGIC;

C: out STD_LOGIC;

D : out STD_LOGIC;

clk500:out STD_LOGIC;

clk4:out std_logic;

clk6m:out std_logic

4 )时钟选择模块clk_sel

(输入为A,B,C,D 四种难度的时钟,50MHz 的时钟clk50m,开始信号start,

 en_A,en_B,en_C,en_D 四种时钟的选择信号;

 输出为leda,ledb,ledc,ledd 四个对应不同难度的LED,选择的A,B,C,D 难度中的一个时钟。)

输入信号IN:

clk50m:in std_logic;

start:in std_logic;

A,B,C,D:in std_logic;

en_A,en_B,en_C,en_D:in std_logic;

输出信号OUT:

leda,ledb,ledc,ledd:out std_logic;

clkout:out std_logic

5)随机数产生模块random

(输入为选择的难度时钟clk,暂停信号en,开始信号start;

  输出为产生的三位随机数。)

输入信号IN:

clk : in STD_LOGIC;

start:in STD_LOGIC;

en:in STD_LOGIC;

输出信号OUT:

led : out STD_LOGIC_VECTOR (2 downto 0)

6)匹配模块compare

(输入选择的难度时钟clk,最高分清零信号clear,暂停信号en,开始信号start,编码key,

  随机数led;

  输出为最高分highscore_out,当前分数score_out,不同难度的选择信号                           en_A,en_B,en_C,en_D,输信号lose,赢信号win。)

输入信号IN:

start:in std_logic;

clear:in std_logic;

en:in std_logic;

clk : in STD_LOGIC;

key : in STD_LOGIC_VECTOR (2 downto 0);

led : in STD_LOGIC_VECTOR (2 downto 0);

输出信号OUT:

win,lose:out STD_LOGIC;

en_A : out STD_LOGIC;

en_B : out STD_LOGIC;

en_C : out STD_LOGIC;

en_D : out STD_LOGIC;

highscore_out:out STD_LOGIC_VECTOR(11 downto 0);

score_out : out STD_LOGIC_VECTOR (11 downto 0);

life_out : out STD_LOGIC_VECTOR (7 downto 0));

2.引脚分配及下载过程:

引脚分频图如下:

四、系统测试与结果分析:

1.源程序仿真波形结果

2.采样编码模块仿真波形结果

由仿真图可知,在一个clk 周期内虽然有多次按键输入,但只有第一次的按键有效,即在一

个clk 周期内只采样编码一次。

3.分频模块仿真波形结果

由于A,B,C,D 的频率较小,得不到仿真结果,所以将代码烧录到板子上通过LED 灯的亮灭来

观察a,b,c,d 的频率,观察结果与预期相符。

4.时钟选择模块仿真波形结果

5.随机数产生模块仿真波形结果

由仿真图可知,产生的led 可认为是随机数。

6.匹配模块仿真波形结果

由以上波形可看出,匹配时,分数增加一分,连续分数增加5分,难度增加一级,分数在5

以下时难度为A,在5-10 之间时难度为B,在10-15 之间时难度为C,在15 以上时难度为D,

不匹配时,分数减一分,连续分数减5次减1等级,等级为0时游戏结束。最高分只升不降。

最高分比当前分数滞后一个周期。当等级为0 时游戏结束。

五、心得体会

    这次课程设计对于没学号EDA技术的同学来说是困难的。在设计程序的初期阶段我对于整个VHDL程序设计流程的方向性的把握不是很准确,刚开始在模块的设计就出现了很大的问题,对于各个模块功能实现的具体代码把握也不是很明确,在这些模块中,比较有难度的是分数与按键匹配的判定,以及判定之后的加分升级,还有一个是LED的显示,在查了资料后才终于得出了结论。 

在这里,我想要指出的是匹配模块,最先是用难度时钟进行匹配加减分,但是仿真得不到正确结果,于是就改用50MHz 的频率进行匹配加减分,需要设置标志位,保证在一个难度时钟内只匹配一次,另外需要将编码延时一个难度周期,只有在前后两次按键不一样时才进行匹配,这样的好处就是分数更新很快,几乎没有延时,但缺点就是如果前后两次按键一样时就不进行匹配,既不加分也不减分,不满足要求。最后我们采用的办法是用难度时钟的上升沿进行匹配,在难度时钟的下降沿进行加减分,这样能满足要求,不过加减分仍有一定的延迟。

参考文献

潘松、黄继业著《EDA技术实用教材》——VHDL版(第四版)  科学出版社

               

相关推荐