数字电路实验报告

时间:2024.5.15

北京邮电大学 

数字电路与逻辑设计实验 

实验报告 

实验名称:足球比赛游戏机

         班级:

学号:

姓名

20##年11月8号

一、实验目的

(1)进一步掌握VHDL和Quartus II软件的使用;

(2)理解状态机的工作原理和设计方法;

(3)掌握利用EDA工具进行自顶向下的电子系统设计方法。

二、实验所用仪器及元器件

(1)计算机;

(2)EDA开发板及相应元器件。

三、实验内容

(1)基本内容

1、按下开始键后,点阵显示球场初始状态,黄色点表示球,红、绿点表示甲、乙双方的球员,上下各有四个点表示双方的球门。

2、甲、乙双方各有一组上下左右按键来控制自己的球员,当球员位于足球的上下左右四个点时,按下方向键可带球向对应的方向移动,如果移动方向正前方有对方球员,则球不能移动。

3、在没有球员踢球的时候,足球每秒随机向四个方向移动一格。

4、足球到四周边界线(点阵最外一圈的点)时,再继续向外踢球时,可以球不移动,等待球随机移动;也可以自己设定相关的出界规则。

5、足球进入球门,则胜方自动加 1 分,每方的分数用2 位数码管显示。

6、每场比赛时间为 90 秒,用数码管倒计时显示时间。计时到0 后,比赛停止,点阵显示胜利方(甲、乙或者平),直到再次按下比赛开始键后重新开始。

(2)提高要求

1、进球和比赛结束后点阵显示动画或者蜂鸣器播放音乐庆祝。

2、自拟其它功能。

四、系统设计

本次试验我把电路分为中心逻辑模块(center)和外围硬件驱动模块(按键keyboard,点阵显示screen,数码管显示digit,倒计时countdown,分频器clkgen)。

各部分把信号送给center,center对信号做出反应。

五.程序设计

(1)    点阵模块

点阵分成了两个小块,一部分负责扫描,即通过扫描显示输入图形,一部分负责图像的输入,这样做能简化程序结构,让程序思路更清晰。

扫描模块在1kHz的上升沿,列移位输出

由中心部件传过来的信号shenfu(胜负)为000时未分胜负,则显示甲乙球的对应坐标,否则根据胜负显示结果。

library ieee;

use ieee.std_logic_1164.all;

use ieee.numeric_std.all;

entity screen is

    port (

        row: out std_logic_vector(7 downto 0);

        rcol: out std_logic_vector(7 downto 0);

        gcol: out std_logic_vector(7 downto 0);

       

        p0_pos_row: in std_logic_vector(7 downto 0);

        p0_pos_col: in std_logic_vector(7 downto 0);

       

        p1_pos_row: in std_logic_vector(7 downto 0);

        p1_pos_col: in std_logic_vector(7 downto 0);

       

        p2_pos_row: in std_logic_vector(7 downto 0);

        p2_pos_col: in std_logic_vector(7 downto 0);

       

        shenfu: in std_logic_vector(2 downto 0);

       

        clock: in std_logic

         );

end entity screen;

architecture v of screen is

signal r: std_logic_vector(7 downto 0):="00000001";

signal rc: std_logic_vector(7 downto 0);

signal gc: std_logic_vector(7 downto 0);

begin

       led_SCAN: process (clock)

       begin

              if rising_edge(clock) then

                     if (r = "10000000") then

                            r <= "00000001";

                     else

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

                            r(0)<='0';

                     end if;       

              end if;

       end process led_SCAN;

      

       led_out: process (r,shenfu,p0_pos_row, p0_pos_col,p1_pos_row, p1_pos_col,p2_pos_row, p2_pos_col)

       begin

              case shenfu is

                     when "000"=>

                            if (r="00000001") then

                                   rc<="00111100";

                                   gc<="00000000";

                            elsif (r="10000000") then

                                   gc<="00111100";

                                   rc<="00000000";

                            else

                                   if (r=p2_pos_row and r=p1_pos_row and r=p0_pos_row) then

                                          rc<=p1_pos_col or p0_pos_col;

                                          gc<=p2_pos_col or p0_pos_col;

                                   elsif (r=p2_pos_row and r=p0_pos_row) then

                                          gc<=p2_pos_col or p0_pos_col;

                                          rc<="00000000";

                                   elsif (r=p1_pos_row and r=p0_pos_row) then

                                          rc<=p1_pos_col or p0_pos_col;

                                          gc<="00000000";

                                   elsif (r=p1_pos_row and r=p2_pos_row) then

                                          gc<=p2_pos_col;

                                          rc<=p1_pos_col;

                                   elsif (r=p1_pos_row) then

                                          gc<="00000000";

                                          rc<=p1_pos_col;

                                   elsif (r=p2_pos_row) then

                                          rc<="00000000";

                                          gc<=p2_pos_col;

                                   elsif (r=p0_pos_row) then

                                          gc<=p0_pos_col;

                                          rc<=p0_pos_col;

                                   else

                                          gc<="00000000";

                                          rc<="00000000";

                                   end if;

                            end if;

                     when "100"=>

                            gc<=p0_pos_col;

                            case r is

                                   when "00000001"=> rc<="00010000";

                                   when "00000010"=> rc<="00010000";

                                   when "00000100"=> rc<="00010000";

                                   when "00001000"=> rc<="11111110";

                                   when "00010000"=> rc<="10010010";

                                   when "00100000"=> rc<="11111110";

                                   when "01000000"=> rc<="10010010";

                                   when "10000000"=> rc<="11111110";

                                   when others => rc<="00000000";

                            end case;

                     when "010"=>

                            gc<=p0_pos_col;

                            case r is

                                   when "00000001"=> rc<="11111111";

                                   when "00000010"=> rc<="01000000";

                                   when "00000100"=> rc<="00100000";

                                   when "00001000"=> rc<="00010000";

                                   when "00010000"=> rc<="0000100";

                                   when "00100000"=> rc<="00000100";

                                   when "01000000"=> rc<="00000010";

                                   when "10000000"=> rc<="11111111";

                                   when others => rc<="00000000";

                            end case;

                     when "001"=>

                            gc<=p0_pos_col;

                            case r is

                                   when "00000001"=> rc<="00010000";

                                   when "00000010"=> rc<="00010000";

                                   when "00000100"=> rc<="00010000";

                                   when "00001000"=> rc<="11111111";

                                   when "00010000"=> rc<="00111000";

                                   when "00100000"=> rc<="01010100";

                                   when "01000000"=> rc<="00111000";

                                   when "10000000"=> rc<="01111100";

                                   when others => rc<="00000000";

                            end case;

                     when others => null;

                     end case;

       end process led_out;

      

       row<=not r;  

       rcol<=rc;

       gcol<=gc; 

        

end architecture v;

(2)    数码管模块

         数码管模块根据输入的数字经过译码显示出来,只和输入的num有关,不会影响程序。

         使用digit_translate进行译码,得到的结果在扫描到对应的时间输出

         digit_translate由于多次使用,作为component调用,是一个4-7译码器。

library ieee;

use ieee.std_logic_1164.all;

use ieee.numeric_std.all;

entity digit is

    port (

        cat: out std_logic_vector(5 downto 0);

        outdata: out std_logic_vector(6 downto 0);

       

        num5: in std_logic_vector(3 downto 0);

        num4: in std_logic_vector(3 downto 0);

        num3: in std_logic_vector(3 downto 0);

        num2: in std_logic_vector(3 downto 0);

        num1: in std_logic_vector(3 downto 0);

        num0: in std_logic_vector(3 downto 0);

        clock: in std_logic;

        reset: in std_logic

         );

end entity digit;

architecture digit_scan of digit is

         COMPONENT digit_translate

                   PORT

                   (

                            num          :        IN STD_LOGIC_VECTOR(3 DOWNTO 0);

                            decode              :        OUT STD_LOGIC_VECTOR(6 DOWNTO 0)

                   );

         END COMPONENT;

        

         signal temp_cat: std_logic_vector(5 downto 0);

        

         signal num0_decode: std_logic_vector(6 downto 0);

         signal num1_decode: std_logic_vector(6 downto 0);

         signal num2_decode: std_logic_vector(6 downto 0);

         signal num3_decode: std_logic_vector(6 downto 0);

         signal num4_decode: std_logic_vector(6 downto 0);

         signal num5_decode: std_logic_vector(6 downto 0);

         signal outdata_temp: std_logic_vector(6 downto 0);

begin

         m0:digit_translate port map(num0,num0_decode);

         m1:digit_translate port map(num1,num1_decode);

         m2:digit_translate port map(num2,num2_decode);

         m3:digit_translate port map(num3,num3_decode);

         m4:digit_translate port map(num4,num4_decode);

         m5:digit_translate port map(num5,num5_decode);

        

         process (clock, reset) is

         begin

                   if (reset = '1') then

                            temp_cat<="000001";

                   elsif rising_edge(clock) then

                            if (temp_cat="100000") then

                                     temp_cat<="000001";

                            else

                                     temp_cat(5 downto 1)<=temp_cat(4 downto 0);

                                     temp_cat(0)<='0';

                            end if;      

                           

                   end if;

         end process;

        

         process(temp_cat,num0_decode,num1_decode,num2_decode,num3_decode,num4_decode,num5_decode) is

         begin

                   if (temp_cat="000001") then

                            outdata_temp<=num0_decode;

                   elsif (temp_cat="000010") then

                            outdata_temp<=num1_decode;

                   elsif (temp_cat="000100") then

                            outdata_temp<=num2_decode;

                   elsif (temp_cat="001000") then

                            outdata_temp<=num3_decode;

                   elsif (temp_cat="010000") then

                            outdata_temp<=num4_decode;

                   else

                            outdata_temp<=num5_decode;

                   end if;

         end process;

        

         cat<=not temp_cat;

         outdata<=outdata_temp;

        

end architecture digit_scan;

(3)    倒计时模块

输入1Hz的时钟,start为高时开始倒计时,reset为高时倒计时归为80,时间到0时time_out输出为高

输出分为十位count_10和个位count输出。

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

entity count_down is

    port (

        clock: in std_logic;

        reset: in std_logic;

        start: in std_logic;

        time_out: out std_logic;

        count_10: out std_logic_vector(3 downto 0);

        count: out std_logic_vector(3 downto 0)

         );

end entity count_down;

architecture my of count_down is

signal count_10_temp: std_logic_vector(3 downto 0);

signal count_temp: std_logic_vector(3 downto 0);

begin

process (clock,reset) is

begin

    if (reset = '1') then

        count_10_temp<="1001";

        count_temp<="0000";

        time_out<='0';

    elsif rising_edge(clock) and start='1' then

            if (count_temp="0000" and count_10_temp="0000") then

                     time_out<='1';

            elsif (count_temp="0000") then

                     count_temp<="1001";

                     count_10_temp<=count_10_temp-1;

                     time_out<='0';

            else

                     count_temp<=count_temp-1;

                     time_out<='0';

            end if;

    end if;

end process;

count_10<=count_10_temp;

count<=count_temp;

end architecture my;

(4)    键盘模块

         键盘输出行扫描,输入列信号,

之后防抖、转码输出,屏蔽了多余的接口

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

entity keyboard is

         port (

                   col       : out std_logic_vector(3 downto 0);

                   row     : in std_logic_vector(3 downto 0);

                   debug_key : out std_logic_vector(7 downto 0); --used for debug

                   p1_key: out std_logic_vector(3 downto 0);--player 1 (up,left,down,right)

        p2_key: out std_logic_vector(3 downto 0);--player 2 (up,left,down,right)

       

        reset: in std_logic;

                   clock: in std_logic); --1kHz

end entity;

architecture keyboard_main of keyboard is

signal temp_col: std_logic_vector(3 downto 0):="0001"; --col=not temp_col

signal keys:std_logic_vector(7 downto 0);

signal catch_row0: std_logic_vector(3 downto 0);

signal catch_row1: std_logic_vector(3 downto 0);

signal catch_row2: std_logic_vector(3 downto 0);

signal catch_row3: std_logic_vector(3 downto 0);

signal t0: integer range 0 to 99:=0;

signal t1: integer range 0 to 99:=0;

signal t2: integer range 0 to 99:=0;

signal t3: integer range 0 to 99:=0;

signal p1_key_out:  std_logic_vector(3 downto 0);

signal p2_key_out:  std_logic_vector(3 downto 0);

--signal step: std_logic_vector(1 downto 0);

begin

         scan:process (clock) is

         begin

                   if rising_edge(clock) then

                            if (temp_col="1000") then

                                     temp_col<="0001";

                            else

                                     temp_col(3 downto 1)<=temp_col(2 downto 0);

                                     temp_col(0)<='0';

                            end if;      

                   end if;

         end process;

        

         col<=not temp_col;

         keys(7 downto 4)<=temp_col;

        

         anti_shake:process (row,temp_col,clock) is

         begin

                   if rising_edge(clock) then

                            if temp_col="0001" then --row0

                                     if (row="1111") then --if any key was not pressed

                                               t0<=0;

                                               keys(3 downto 0)<="0000";

                                     else

                                               if t0=0 then

                                                        catch_row0<=row;

                                                        keys(3 downto 0)<="0000";

                                                        t0<=t0+1;

                                               elsif catch_row0=row then

                                                        if t0=24 then --0.1s delay

                                                                 t0<=0;

                                                                 keys(3 downto 0)<=not catch_row0;

                                                        else

                                                                 t0<=t0+1;

                                                                 keys(3 downto 0)<="0000";

                                                        end if;

                                               else

                                                        catch_row0<=row;

                                                        t0<=0;

                                                        keys(3 downto 0)<="0000";

                                               end if;

                                     end if;

                            elsif temp_col="0010" then --row1

                                     if (row="1111") then

                                               t1<=0;

                                               keys(3 downto 0)<=not row;

                                     else

                                               if t1=0 then

                                                        catch_row1<=row;

                                                        keys(3 downto 0)<="0000";

                                                        t1<=t1+1;

                                               elsif catch_row1=row then

                                                        if t1=24 then

                                                                 t1<=0;

                                                                 keys(3 downto 0)<=not row;

                                                        else

                                                                 t1<=t1+1;

                                                                 keys(3 downto 0)<="0000";

                                                        end if;

                                               else

                                                        catch_row1<=row;

                                                        t1<=0;

                                               end if;

                                     end if;

                            elsif temp_col="0100" then --row2

                                     if (row="1111") then

                                               t2<=0;

                                               keys(3 downto 0)<=not row;

                                     else

                                               if t2=0 then

                                                        catch_row2<=row;

                                                        keys(3 downto 0)<="0000";

                                                        t2<=t2+1;

                                               elsif catch_row2=row then

                                                        if t2=24 then

                                                                 t2<=0;

                                                                 keys(3 downto 0)<=not row;

                                                        else

                                                                 t2<=t2+1;

                                                                 keys(3 downto 0)<="0000";

                                                        end if;

                                               else

                                                        catch_row2<=row;

                                                        t2<=0;

                                               end if;

                                     end if;

                            else --row3

                                     if (row="1111") then

                                               t3<=0;

                                               keys(3 downto 0)<=not row;

                                     else

                                               if t3=0 then

                                                        catch_row3<=row;

                                                        keys(3 downto 0)<="0000";

                                                        t3<=t3+1;

                                               elsif catch_row3=row then

                                                        if t3=24 then

                                                                 t3<=0;

                                                                 keys(3 downto 0)<=not row;

                                                        else

                                                                 t3<=t3+1;

                                                                 keys(3 downto 0)<="0000";

                                                        end if;

                                               else

                                                        catch_row3<=row;

                                                        t3<=0;

                                               end if;

                                     end if;

                            end if;

                   end if;

         end process;

        

         translate:process (clock,keys,reset) is --keys=col & row  

         begin

                   if rising_edge(clock) then

                            if reset='1' then

                                     p1_key_out<="0000";

                                     p2_key_out<="0000";

                            elsif (keys="01000010") then

                                     p1_key_out<="1000"; --player 1 press up

                                     p2_key_out<="0000";

                                     ---step<="01";

                            elsif (keys="10000001") then

                                     p1_key_out<="0100"; --player 1 press left

                                     p2_key_out<="0000";

                                     ---step<="01";

                            elsif (keys="01000001") then

                                     p1_key_out<="0010"; --player 1 press down

                                     p2_key_out<="0000";

                                     ---step<="01";

                            elsif (keys="00100001") then

                                     p1_key_out<="0001"; --player 1 press right

                                     p2_key_out<="0000";

                                     ---step<="01";

                            elsif (keys="01000100") then

                                     p2_key_out<="1000";

                                     p1_key_out<="0000";

                                     ---step<="01";

                            elsif (keys="10001000") then

                                     p2_key_out<="0100";

                                     p1_key_out<="0000";

                                     ---step<="01";

                            elsif (keys="01001000") then

                                     p2_key_out<="0010";

                                     p1_key_out<="0000";

                                     ---step<="01";

                            elsif (keys="00101000") then

                                     p2_key_out<="0001";

                                     p1_key_out<="0000";

                                     ---step<="01";

                            else

                                     p1_key_out<="0000";

                                     p2_key_out<="0000";

--                                   p2_key_out<=p2_key_out;

--                                   p1_key_out<=p1_key_out;

                                     --p2_key_out<="0000";

                                     ---step<="00";

                            end if;

                   end if;

         end process;

        

         p1_key<=p1_key_out;

         p2_key<=p2_key_out;

         debug_key<=keys;

         --debug_key(7 downto 4)<=p1_key_out;

         --debug_key(3 downto 0)<=p2_key_out;

end keyboard_main;

(5)    中心逻辑模块

输入甲乙(p1、p2)的按键、时钟、开始信号、时间到信号,输出甲乙小球的位置,甲乙的得分,胜负状态等。

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

entity center is

    PORT

         (

                   p1_key:    in STD_LOGIC_VECTOR(3 DOWNTO 0);

                   p2_key:    in STD_LOGIC_VECTOR(3 DOWNTO 0);

                   p0_pos_row: out std_logic_vector(7 downto 0);

        p0_pos_col: out std_logic_vector(7 downto 0);

        

        p1_pos_row: out std_logic_vector(7 downto 0);

        p1_pos_col: out std_logic_vector(7 downto 0);

       

        p2_pos_row: out std_logic_vector(7 downto 0);

        p2_pos_col: out std_logic_vector(7 downto 0);

       

        shenfu: out std_logic_vector(2 downto 0); --who win? p1"100" p2"010" eq"001"

       

        p1_score_10: out std_logic_vector(3 downto 0);

        p1_score: out std_logic_vector(3 downto 0);

        p2_score_10: out std_logic_vector(3 downto 0);

        p2_score: out std_logic_vector(3 downto 0);

       

        clock: in std_logic;

        reset: in std_logic;

        start: in std_logic;

        timeout: in std_logic;

        start_out: out std_logic;

       

        state_debug : out std_logic_vector(3 downto 0)

        );

end entity center;

architecture m of center is

signal state: std_logic_vector(3 downto 0):="0001";

signal empty: std_logic_vector(9 downto 0);

signal random: std_logic_vector(3 downto 0):="0001";

signal p0_y:  std_logic_vector(7 downto 0);

signal p0_x:  std_logic_vector(7 downto 0);

signal p1_y:  std_logic_vector(7 downto 0);

signal p1_x:  std_logic_vector(7 downto 0);

signal p2_y:  std_logic_vector(7 downto 0);

signal p2_x:  std_logic_vector(7 downto 0);

signal p1_score_10_temp: std_logic_vector(3 downto 0);

signal p1_score_temp: std_logic_vector(3 downto 0);

signal p2_score_10_temp: std_logic_vector(3 downto 0);

signal p2_score_temp: std_logic_vector(3 downto 0);

signal jinqiu: std_logic:='0';

signal anjian: std_logic:='0';

signal p1_key_old: std_logic_vector(3 downto 0);

signal p2_key_old: std_logic_vector(3 downto 0);

begin       

process (clock,p1_score_temp,p2_score_temp,empty) is

begin

    if rising_edge(clock) then

                   if state="0001" then --reset

                            if start='1' then

                                     state<="0010";

                                     start_out<='1';

                            else

                                     state<="0001";

                                     start_out<='0';

                            end if;

                   elsif state="0010" then --game

                            if reset='1' then

                                     state<="0001";

                            elsif timeout='1' then

                                     state<="0100";

                            elsif jinqiu='1' then

                                     state<="1000"; --jingqiu

                            elsif empty="1111101000" then

                                     state<="0011"; --p0 random move

                            elsif anjian='1' then

                                     state<="1111";

                            else

                                     state<="0010";

                            end if;

                   elsif state="0100" then --time over

                            if reset='1' then

                                     state<="0001";

                            else

                                     state<="0100";

                            end if;

                   elsif state="1000" then --jingqiu

                            state<="0010";

                   elsif state="1111" then --wait for other input

                            if anjian='0' then

                                     state<="0010";

                            else

                                     state<="1111";

                            end if;

                   else

                            state<="0010";

                   end if;

    end if;

end process;

process (p1_key,p2_key,state,clock) is

begin

if rising_edge(clock) then

         if state="0001" then

                            p0_y<="00010000";

                            p0_x<="00010000";

                            p1_y<="00000010";

                            p1_x<="00001000";

                            p2_y<="01000000";

                            p2_x<="00001000";

                           

                            jinqiu<='0';

                            p1_score_10_temp<="0000";

                            p1_score_temp<="0000";

                            p2_score_10_temp<="0000";

                            p2_score_temp<="0000";

                            random<="0010";

                            shenfu<="000";

                           

         elsif state="0010" then

                  

                   empty<="0000000000";

                   if p1_key_old=p1_key and p2_key_old=p2_key then

                            anjian<='1';

                   else

                            anjian<='0';

                            p1_key_old<=p1_key;p2_key_old<=p2_key;

                            if p1_key="1000" then --p1 press up

                                    

                                     if (p0_x=p1_x and p1_y(6 downto 0)=p0_y(7 downto 1)) then

                                               if (not ((p0_x=p2_x) and p2_y(6 downto 0)=p0_y(7 downto 1)))and p0_y(7)='0' then

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

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

                                               end if;

                                     elsif (not (p2_x=p1_x and p1_y(6 downto 0)=p2_y(7 downto 1))) and p1_y(7)='0' then

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

                                     end if;

                                    

                            elsif p1_key="0010" then

        

                                     if (p0_x=p1_x and p1_y(7 downto 1)=p0_y(6 downto 0) ) then

                                               if (not (p0_x=p2_x and p2_y(7 downto 1)=p0_y(6 downto 0)))and p0_y(0)='0' then

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

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

                                               end if;

                                     elsif (not (p2_x=p1_x and p1_y(7 downto 1)=p2_y(6 downto 0)))and p1_y(0)='0' then

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

                                     end if;

                                    

                            elsif p1_key="0100" then

        

                                     if (p0_y=p1_y and p1_x(6 downto 0)=p0_x(7 downto 1)) then

                                               if (not (p0_x=p2_x and p2_y(6 downto 0)=p0_y(7 downto 1)))and p0_x(7)='0' then

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

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

                                                        p1_x(0)<='0';

                                               end if;

                                     elsif (not (p2_y=p1_y and p1_x(6 downto 0)=p2_x(7 downto 1)))and p1_x(7)='0' then

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

                                               p1_x(0)<='0';

                                     end if;

        

                            elsif p1_key="0001" then

                                    

                                     if (p0_y=p1_y and p1_x(7 downto 1)=p0_x(6 downto 0)) then

                                               if (not (p0_x=p2_x and p2_y(7 downto 1)=p0_y(6 downto 0)))and p0_x(0)='0' then

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

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

                                                        p1_x(7)<='0';

                                               end if;

                                     elsif (not (p2_y=p1_y and p1_x(7 downto 1)=p2_x(6 downto 0)))and p1_x(0)='0' then

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

                                               p1_x(7)<='0';

                                     end if;

                                    

                            elsif p2_key="1000" then

                                    

                                     if (p0_x=p2_x and p2_y(7 downto 1)=p0_y(6 downto 0)) then

                                               if (not (p0_x=p1_x and p1_y(7 downto 1)=p0_y(6 downto 0)))and p0_y(0)='0' then

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

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

                                               end if;

                                     elsif (not (p1_x=p2_x and p2_y(7 downto 1)=p1_y(6 downto 0)))and p2_y(0)='0' then

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

                                     end if;

                                    

                            elsif p2_key="0010" then

                           

                                     if (p0_x=p2_x and p2_y(6 downto 0)=p0_y(7 downto 1)) then

                                               if (not (p0_x=p1_x and p1_y(6 downto 0)=p0_y(7 downto 1)))and p0_y(7)='0' then

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

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

                                               end if;

                                     elsif (not (p1_x=p2_x and p2_y(6 downto 0)=p1_y(7 downto 1))) and p2_y(7)='0' then

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

                                     end if;

                                    

                            elsif p2_key="0100" then

                           

                                     if (p0_y=p2_y and p2_x(6 downto 0)=p0_x(7 downto 1)) then

                                               if (not (p0_x=p1_x and p1_y(6 downto 0)=p0_y(7 downto 1)))and p0_x(7)='0' then

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

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

                                                        p2_x(0)<='0';

                                               end if;

                                     elsif (not (p1_y=p2_y and p2_x(6 downto 0)=p1_x(7 downto 1)))and p2_x(7)='0' then

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

                                               p2_x(0)<='0';

                                     end if;

                                    

                            elsif p2_key="0001" then

                           

                                     if (p0_y=p2_y and p2_x(7 downto 1)=p0_x(6 downto 0)) then

                                               if (not (p0_x=p1_x and p1_y(7 downto 1)=p0_y(6 downto 0)))and p0_x(0)='0' then

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

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

                                                        p2_x(7)<='0';

                                               end if;

                                     elsif (not (p1_y=p2_y and p2_x(7 downto 1)=p1_x(6 downto 0)))and p2_x(0)='0' then

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

                                               p2_x(7)<='0';

                                     end if;

                                    

                            end if;

                   end if;

                  

                   if (p0_y="10000000") then

                            if (p0_x>="00000100" and p0_x<="00100000") then

                                     jinqiu<='1';

                                     if (p1_score_temp="1001") then

                                               p1_score_temp<="0000";

                                               p1_score_10_temp<=p1_score_10_temp+1;

                                     else

                                               p1_score_temp<=p1_score_temp+1;

                                     end if;

                            end if;

                   elsif (p0_y="00000001") then

                            if (p0_x>="00000100" and p0_x<="00100000") then

                                     jinqiu<='1';

                                     if (p2_score_temp="1001") then

                                               p2_score_temp<="0000";

                                               p2_score_10_temp<=p2_score_10_temp+1;

                                     else

                                               p2_score_temp<=p2_score_temp+1;

                                     end if;

                            end if;

                   end if;

                  

         elsif state="0100" then --time over

                            if p1_score_10_temp<p2_score_10_temp then

                                     shenfu<="010"; --p2 win

                            elsif p1_score_10_temp>p2_score_10_temp then

                                     shenfu<="100"; --p1_win

                            elsif p1_score_10_temp=p2_score_10_temp then

                                     if p1_score_temp<p2_score_temp then

                                               shenfu<="010"; --p2 win

                                     elsif p1_score_temp>p2_score_temp then

                                               shenfu<="100"; --p1 win

                                     elsif p1_score_temp=p2_score_temp then

                                               shenfu<="001"; --eq

                                     end if;

                            end if;

         elsif state="1000" then --jingqiu

                            p0_y<="00010000";

                            p0_x<="00010000";

                            p1_y<="00000010";

                            p1_x<="00001000";

                            p2_y<="01000000";

                            p2_x<="00001000";

                            shenfu<="000";

                            jinqiu<='0';

                                    

         elsif state="0011" then --random move

                   empty<="0000000000";

                   if random(1 downto 0)="00" then

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

                   elsif random(1 downto 0)="01" then

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

                   elsif random(1 downto 0)="01" then

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

                   else

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

                   end if;

         elsif state="1111" then

                   empty<=empty+1;

                   random<=random xor empty(3 downto 0);

                   if p1_key="0000" and p2_key="0000" then

                            anjian<='0';

                   else

                            anjian<='1';

                   end if;

    end if;

end if;

end process;

p0_pos_row<=p0_y;

p0_pos_col<=p0_x;

p1_pos_row<=p1_y;

p1_pos_col<=p1_x;

p2_pos_row<=p2_y;

p2_pos_col<=p2_x;

p1_score_10<=p1_score_10_temp;

p1_score<=p1_score_temp;

p2_score_10<=p2_score_10_temp;

p2_score<=p2_score_temp;

state_debug<=state;

end architecture m;

(6)    分频器模块

输入25MHz,输出1MHz、1kHz、1Hz

library ieee;

use ieee.std_logic_1164.all;

use ieee.numeric_std.all;

entity clk_gen is

    port (

        clk_25MHz: in std_logic;

        clk_1MHz: out std_logic;

        clk_1kHz: out std_logic;

        clk_1Hz : out std_logic);

end entity clk_gen;

architecture my of clk_gen is

signal count_25: integer range 0 to 24;

signal count_10: integer range 0 to 4;

signal count_100: integer range 0 to 49;

signal count_1000: integer range 0 to 499;

signal clk_temp_1MHz:  std_logic;

signal clk_temp_1kHz:  std_logic;

signal clk_temp_10Hz:  std_logic;

signal clk_temp_1Hz:  std_logic;

begin

process (clk_25MHz) is

begin

    if rising_edge(clk_25MHz) then

            if (count_25=12) then

                     count_25<=count_25+1;

                     clk_temp_1MHz<= not clk_temp_1MHz;

            elsif (count_25=24) then

                     count_25<=0;

                     clk_temp_1MHz<= not clk_temp_1MHz;

            else

                     count_25<=count_25+1;

            end if;      

    end if;

end process;

process (clk_temp_1MHz) is

begin

    if rising_edge(clk_temp_1MHz) then

            if (count_1000=499) then

                     count_1000<=0;

                     clk_temp_1kHz<= not clk_temp_1kHz;

            else

                     count_1000<=count_1000+1;

            end if;      

    end if;

end process;

process (clk_temp_1kHz) is

begin

    if rising_edge(clk_temp_1kHz) then

            if (count_100=49) then

                     count_100<=0;

                     clk_temp_10Hz<= not clk_temp_10Hz;

            else

                     count_100<=count_100+1;

            end if;      

    end if;

end process;

process (clk_temp_10Hz) is

begin

    if rising_edge(clk_temp_10Hz) then

            if (count_10=4) then

                     count_10<=0;

                     clk_temp_1Hz<= not clk_temp_1Hz;

            else

                     count_10<=count_10+1;

            end if;      

    end if;

end process;

clk_1MHz<=clk_temp_1MHz;

clk_1kHz<=clk_temp_1kHz;

clk_1Hz<=clk_temp_1Hz;

end architecture my;

六、仿真波形及分析(由于时间原因未能完成仿真)

七、功能说明及资源利用情况

八、故障及问题分析

1.未设计球员的出界情况导致球员“丢失”。

2.不能在两个地方给同一个信号赋值。

3防抖电路设计不良导致按键不灵敏。

4状态的转移会在下一个时钟沿体现。

5仍然存在很多bug例如进一个球加2分,球员和足球同列时颜色会改变等。

6未能完成随机数的实现。

九、总结和结论

    vhdl语言可以说是比较难以掌握的语言之一,它确实和其他语言不同,比如时钟的触犯,时序电路和逻辑电路,状态的转移等都非常有硬件编程的特色。对于本来就不精通于这类实验的我来说无疑是一次巨大的考验。说实话,上学期的数字电路实验课上所学的知识已经几乎忘光,我不得不重新开始对于vhdl语言的学习,经过几次预约的实验,与同学一起的学习与讨论,我还是克服了这道难关。我非常感谢唯一和我做同样实验的我的同学,它给予了我非常大的帮助,如果没有他,我可能真的无法完成此次实验。虽然最后的程序还是有不少bug,仿真也未能完成,“如果移动方向正前方有对方球员,则球不能移动”也未能实现,随机数还是无法正常使用,由于时间紧张,实验较难,而且我的水平也有限,无法在验收完前完成了。可是我相信我能够做到,实验虽然完结,学习的路却没有完结,我会更加努力,更好地掌握vhdl语言。

更多相关推荐:
数字电路实验报告模板

组合逻辑电路的设计与调试一、实验目的1、掌握用门电路设计组合逻辑电路的方法。2、掌握组合逻辑电路的调试方法。二、实验器材数字电路实验箱一台、74LS00若干三、实验内容1、用与非门实现散人多数表决器电路(1)真…

数电实验报告1

实验一门电路逻辑功能及测试一实验目的1熟悉门电路逻辑功能2熟悉数字电路学习机及示波器使用方法二实验仪器及材料1双踪示波器2器件74LS00二输入端四与非门2片74LS20四输入端双与非门1片74LS86二输入端...

数字电路实验报告

数字电路技术实验报告学号130704002130704010姓名曹兴运丁玉祥组号B8日期20xx1012一实验目的1掌握中规模集成译码器的逻辑功能和使用方法2掌握中规模集成编码器的逻辑功能和使用方法3熟悉掌握集...

数字电路实验报告3

暨南大学本科实验报告专用纸课程名称数字逻辑电路实验成绩评定实验项目名称三态门特性研究和典型应用指导教师实验项目编号0806003803实验项目类型验证型实验地点B406学生姓名学号学院电气信息学院系专业电子信息...

数字电路实验报告4

暨南大学本科实验报告专用纸课程名称数字逻辑电路实验成绩评定实验项目名称中规模集成电路功能测试及应用指导教师实验项目编号0806003804实验项目类型验证型实验地点学生姓名学号学院电气信息学院系专业实验时间20...

数字电路与数字逻辑大型实验报告

数字电路与数字逻辑大型实验报告1一实验内容一QuartusII操作练习1用原理图输入法设计一个3线8线译码器二数字频率计设计三倒计时秒表设计二数字频率计的设计1工作原理脉冲信号的频率就是在单位时间内所产生的脉冲...

数电实验课程设计总结报告(电子表)

数字电路课程设计数字定时器课程设计任务书1集成数字定时器2技术指标1设计一个数字定时器要求它具有数字钟的功能又可以按预定时刻发出控制信号对被控对象实施开关控制2时钟功能具有24小时计时方式显示时分秒计时范围要求...

数电实验报告模板

计算机科学学院数字电路班级20xx级1班组成员指导老师日期1实验指导书有的内容全部弄下来2实验过程及实验图实验报告3实验数据4实验总结实验4时序电路一实验目的1掌握常用时序电路分析设计及测试方法2训练独立进行实...

数字电路课设实验报告

福州大学至诚学院数字电路课程设计报告专业电子科学与技术姓名宋伟强吴恩典学号210891218210891220指导老师蔡超20xx年10月10日1目录1简述32设计任务和要求33设计原理431电源电路432脉冲...

数字电路数字时钟课程实验报告

数字时钟设计实验报告一设计要求设计一个24小时制的数字时钟要求计时显示精度到秒有校时功能采用中小规模集成电路设计发挥增加闹钟功能二设计方案由秒时钟信号发生器计时电路和校时电路构成电路秒时钟信号发生器可由振荡器和...

数电实验报告

1中频自动增益数字电路研究报告目录一设计要求31基本要求32发挥部分3二实验设计321实验一用加法器实现二位乘法电路3211实验分析3212电路仿真结果5213实验研究与思考522实验二中频自动增益数字电路62...

哈工大 数字逻辑电路与系统实验报告

HarbinInstituteofTechnology数字逻辑电路与系统课程名称院系班级姓名学号教师哈尔滨工业大学20xx年12月实验二时序逻辑电路的设计与仿真32同步计数器实验321实验目的1练习使用计数器设...

数字电路实验报告(24篇)