北邮数字电路与逻辑设计实验-实验报告(下)

发布时间:2018-08-01 13:26:30   来源:文档文库   
字号:

邮电学电

<数字电路与逻辑设计实验>



  级: xxx

  院: xxx

室: xxx

审阅教师:        

姓名(班内序号): xxx

  号: xxx

实验时间: xxx

评定成绩:



目录

一、任务要求 2

1.基本要求 2

2.提高要求 2

二、系统 2

1.设 2

2.总 4

3.分块设 5

1)分频器模块 5

24×4键盘输入模块 5

3)数码管显示模块 6

48×8 LED点阵显示模块 6

5LCD液晶屏显示模块 6

6)中心模块 6

三、仿真分析 6

1.分频器模块 6

24×4键盘输入模块 7

3.数码管显示模块 7

48×8 LED点阵显示模块 8

5LCD液晶屏显示模块 8

6.中心模块 8

四、源程序 9

1.分频器模块 9

24×4键盘输入模块 9

3.数码管显示模块 11

48×8 LED点阵显示模块 12

5LCD液晶屏显示模块 19

6.中心模块 23

五、功能情况 26

六、故障分析 27

七、总结结论 27



任务要求

本电路可供甲乙二人进行猜拳游戏。通过不同的按键控制,选择多种出拳方式,显示猜 拳的结果,实现猜拳游戏,防止了作弊的可能。

1基本要求

1、甲乙双方各用 4×4 键盘中的三个按键模拟“石头”、“剪刀”、“布”,一个按键为“确 认”。4×4 键盘第一行为甲,第二行为乙;

2、裁判用 4×4 键盘第三行的一个按键模拟“开”,一个按键为“准备”,一个按键为“复 位”;

3、裁判宣布“准备”后,甲乙双方分别选择出拳方式并确认;

4、裁判“开”以后,用点阵的左右三列同时显示甲乙双方的猜拳选择(如下图所示), 并用两个数码管显示甲乙的猜拳比分;

1甲“布”,乙“剪刀”;甲“剪刀”,乙“石头”

5、猜拳游戏为五局三胜制。若甲乙双方出拳一致,则比分保持不变,双方重新出拳;

6、比赛结束后,用 8×8 点阵显示甲乙获胜方;

7、复位后游戏重新开始。

2提高要求

1、点阵显示增加游戏开机动画、结束动画;

2、为游戏增加音效;

3、在 LCD1602 液晶屏上显示甲乙双方的猜拳比分;

4、自拟其他功能。

、系统

1

本电路分为6个模块,分别是中心模块(包含状态机)、8×8 LED点阵显示模块数码管显示模块LCD液晶屏显示模块、4×4键盘输入模块、分频器模块,各模块使用VHDL语言设计,顶层连接使Quartus II原理图设计

分频器模块负责将50MHz时钟分成低频信号,供其他模块使用。中心模块负责读取4×4键盘输入模块输入,并控制状态机和其他模块的输出显示。8×8 LED点阵显示模块负责接收中心模块的信号,显示相应的图案数码管显示模块LCD液晶屏显示模块负责接收中心模块的信号,显示比分4×4键盘输入模块负责读取键盘输入,并将其输出到中心模块。

2

2系统流程图

3逻辑框图

4 BDF原理图

3分块设

1分频器模块

输入clkin50MHz时钟,输出clkout1KHz时钟,作为中心模块、8×8 LED点阵显示模块数码管显示模块、4×4键盘输入模块时钟信号。

24×4键盘输入模块

4×4键盘输入模块负责读取键盘输入,并将其输出到中心模块。KBcol4二进制信号,是键盘遍历扫描信号。输入KBrow4二进制信号,是键盘的检测信号。输出resultout5二进制信号,是4×4键盘输入模块检测出的所按按键其中第一位代表键盘按下后四位二进制数表示所按的按键

3数码管显示模块

数码管显示模块负责接收中心模块的信号,显示比分输入AB分别2二进制信号,代表乙的得分输出cat8二进制信号,控制8个数码管使能端。输出disp7二进制信号,控制数码管所显示的图案。

48×8 LED点阵显示模块

8×8 LED点阵显示模块负责接收中心模块的信号,显示相应的图案输入AB分别2二进制信号,代表乙的出拳结果,其中“11”表示甲或乙获胜显示结束动画。输入en为点阵的使能端start为开机动画控制信号。输出row8二进制信号,点阵的扫描信号。输出colr8二进制信号,是红色点阵的数据信号。输出colg8二进制信号,是绿色点阵的数据信号

5LCD液晶屏显示模块

LCD液晶屏显示模块负责接收中心模块的信号,显示比分时钟clk直接使用50MHz信号。输入rstLCD液晶屏模块的复位信号,输入AB分别2二进制信号,代表乙的得分。输出rsenrwdata_outLCD液晶屏的控制和数据信号

6中心模块

中心模块负责读取4×4键盘输入模块输入,并控制状态机和其他模块的输出显示。输入KB5二进制信号,是4×4键盘输入模块检测出的所按按键。输出LEDen控制LED点阵模块的使能端LEDstartLED点阵模块的开机动画控制信号。输出LEDALEDB分别2二进制信号,代表乙的出拳结果,其中“11”表示甲或乙获胜显示结束动画。输出DISPADISPB分别2二进制信号,代表乙的得分

、仿真分析

1分频器模块

分频比太大,不易仿真。

24×4键盘输入模块

5 4×4键盘输入模块仿真

模块为时钟下降沿有效,resultout[4]为有按键按下信号,resultout[0..3]为按下的按键仿真遍历了所有按键的情况,在resultout对应16~31所有情况没有按顺序)中心模块编写时,考虑了防抖的问题,检测到按下多次按键与按下一次按键的效果相同,所以在此模块中没有必要加入防抖

3数码管显示模块

6数码管显示模块仿真

时钟clk‘0’DISP7点亮显示甲的得分,时钟clk‘1’DISP6点亮,显示乙的得分。输入AB遍历了甲、乙得分的所有结果,对应disp数码管的显示,‘~’状态表示0分,‘0’状态表示1分,‘m’状态表示2分,‘y’状态表示3分。

48×8 LED点阵显示模块

7 8×8 LED点阵显示模块仿真

模块状态太多,只仿真了部分状态。输入AB‘0’-‘2’状态分别代表石头、剪刀、布,‘3’状态代表甲或获胜。输出colr为甲的出拳结果,colg为乙的出拳结果。

5LCD液晶屏显示模块

模块使用50MHz信号,不易仿真。实现功能与数码管显示模块类似

6中心模块

8中心模块仿真

模块状态太多,只仿真了部分状态。仿真中模拟3按键第一个是裁判的准备键,按键抬起后结束开机动画,进入选手输入状态LEDenLEDstart都变为‘0’。第二个乙按下“剪刀”(甲默认出“布”),按键抬起后LEDB的信号发生变化。第一个是裁判的“开”键,按键抬起后结算双方出拳结果,给乙+1DISPB),同时显示双方出拳结果,LEDen变为‘1’

、源程序

1分频器模块

library ieee;

use ieee.std_logic_1164.all;

entity fenpinqi12 is

port( clkin:in std_logic; --时钟信号输入

clkout:out std_logic); --时钟信号输出

end fenpinqi12;

architecture aroneMHZ of fenpinqi12 is

signal data:integer range 0 to 24999;

signal Q:std_logic;

begin

process(clkin)

begin

if rising_edge(clkin) then --检测输入时钟上升沿

if(data=24999) then --此句为你想要的分频比,data=0,1,2,3,4.......9的分频比为1,23,,,10

data<=0;

Q<=not Q;

else

data<=data+1;

end if;

end if;

clkout<=Q;

end process;

end aroneMHZ;

24×4键盘输入模块

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY KBcontroller IS

PORT(

clk:IN STD_LOGIC; --时钟

KBcol:OUT STD_LOGIC_VECTOR(0 TO 3); --扫描信号

KBrow:IN STD_LOGIC_VECTOR(0 TO 3); --检测信号

resultout:OUT STD_LOGIC_VECTOR(4 DOWNTO 0) --检测结果

);

END KBcontroller;

ARCHITECTURE behavioral OF KBcontroller IS

signal temp:INTEGER RANGE 0 TO 3;

signal result:STD_LOGIC_VECTOR(4 DOWNTO 0);

BEGIN

P1:PROCESS(temp)

BEGIN

IF (clk'event and clk='0') THEN

CASE temp IS --检测键盘输入结果

WHEN 0=>

CASE KBrow IS

WHEN "0111"=> result<="11111";

WHEN "1011"=> result<="11110";

WHEN "1101"=> result<="11101";

WHEN "1110"=> result<="11100";

WHEN OTHERS=> result<="00000";

END CASE;

WHEN 1=>

CASE KBrow IS

WHEN "0111"=> result<="11011";

WHEN "1011"=> result<="11010";

WHEN "1101"=> result<="11001";

WHEN "1110"=> result<="11000";

WHEN OTHERS=> result<="00000";

END CASE;

WHEN 2=>

CASE KBrow IS

WHEN "0111"=> result<="10111";

WHEN "1011"=> result<="10110";

WHEN "1101"=> result<="10101";

WHEN "1110"=> result<="10100";

WHEN OTHERS=> result<="00000";

END CASE;

WHEN 3=>

CASE KBrow IS

WHEN "0111"=> result<="10011";

WHEN "1011"=> result<="10010";

WHEN "1101"=> result<="10001";

WHEN "1110"=> result<="10000";

WHEN OTHERS=> result<="00000";

END CASE;

WHEN OTHERS=> NULL;

END CASE;

END IF;

resultout<=result;

END PROCESS P1;

P2:process(clk)

begin

IF (clk'event and clk='1') THEN --4计数器,对应键盘4

IF temp=3 THEN

temp<=0;

ELSE

temp<=temp+1;

END IF;

END IF;

END PROCESS P2;

P3:process(temp)

begin

CASE temp IS --键盘扫描输出

WHEN 0=> KBcol<="1110";

WHEN 1=> KBcol<="1101";

WHEN 2=> KBcol<="1011";

WHEN 3=> KBcol<="0111";

WHEN OTHERS=> KBcol<="1111";

END CASE;

END PROCESS P3;

END behavioral;

3数码管显示模块

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY DISPshow IS

PORT(

clk:IN STD_LOGIC; --时钟

A:IN STD_LOGIC_VECTOR(1 DOWNTO 0); --的得分

B:IN STD_LOGIC_VECTOR(1 DOWNTO 0); --得分

disp:OUT STD_LOGIC_VECTOR(0 To 6); --显示内容

cat:OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); --数码管使能

END DISPshow;

ARCHITECTURE behavioral OF DISPshow IS

BEGIN

P3:process(clk,A,B)

variable dispA:STD_LOGIC_VECTOR(0 To 6);

variable dispB:STD_LOGIC_VECTOR(0 To 6);

begin

CASE A IS --得分变为数码管显示信号

WHEN "00"=> dispA:="1111110";--0

WHEN "01"=> dispA:="0110000";--1

WHEN "10"=> dispA:="1101101";--2

WHEN "11"=> dispA:="1111001";--3

WHEN OTHERS=> dispA:="0000000";

END CASE;

CASE B IS --将乙得分变为数码管显示信号

WHEN "00"=> dispB:="1111110";--0

WHEN "01"=> dispB:="0110000";--1

WHEN "10"=> dispB:="1101101";--2

WHEN "11"=> dispB:="1111001";--3

WHEN OTHERS=> dispB:="0000000";

END CASE;

CASE clk IS --时钟为‘0’时显示甲,时钟为‘1’时显示相当于扫描

WHEN '0'=> disp<=dispA; cat<="01111111";

WHEN '1'=> disp<=dispB; cat<="10111111";

WHEN OTHERS=> disp<="0000000"; cat<="11111111";

END CASE;

END PROCESS P3;

END behavioral;

48×8 LED点阵显示模块

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY LEDshow IS

PORT(

clk:IN STD_LOGIC;--时钟

en:IN STD_LOGIC;--使能端

A:IN STD_LOGIC_VECTOR(1 DOWNTO 0); --甲的出拳

B:IN STD_LOGIC_VECTOR(1 DOWNTO 0); --乙的出拳

start:IN STD_LOGIC;--开始动画控制

colr:OUT STD_LOGIC_VECTOR(7 DOWNTO 0); --红色数据信号

colg:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);--绿色数据信号

row:OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); --扫描信号

END LEDshow;

ARCHITECTURE behavioral OF LEDshow IS

signal temp:INTEGER RANGE 0 TO 8;

signal temp1:INTEGER RANGE 0 TO 5;

signal data:integer range 0 to 249;

signal clk_2Hz,Q:STD_LOGIC;

signal A0:STD_LOGIC_VECTOR(0 to 7);

signal A1:STD_LOGIC_VECTOR(0 to 7);

signal A2:STD_LOGIC_VECTOR(0 to 7);

signal A3:STD_LOGIC_VECTOR(0 to 7);

signal A4:STD_LOGIC_VECTOR(0 to 7);

signal A5:STD_LOGIC_VECTOR(0 to 7);

signal A6:STD_LOGIC_VECTOR(0 to 7);

signal A7:STD_LOGIC_VECTOR(0 to 7);

signal B0:STD_LOGIC_VECTOR(7 DOWNTO 0);

signal B1:STD_LOGIC_VECTOR(7 DOWNTO 0);

signal B2:STD_LOGIC_VECTOR(7 DOWNTO 0);

signal B3:STD_LOGIC_VECTOR(7 DOWNTO 0);

signal B4:STD_LOGIC_VECTOR(7 DOWNTO 0);

signal B5:STD_LOGIC_VECTOR(7 DOWNTO 0);

signal B6:STD_LOGIC_VECTOR(7 DOWNTO 0);

signal B7:STD_LOGIC_VECTOR(7 DOWNTO 0);

BEGIN

P1:PROCESS(clk_2Hz)

BEGIN

if start='0' then

if A="00" then--甲出布

A0<="00000000"; A1<="00000000"; A2<="11100000"; A3<="11100000";

A4<="11100000"; A5<="11100000"; A6<="00000000"; A7<="00000000";

elsif A="01" then--甲出剪刀

A0<="00000000"; A1<="00000000"; A2<="00100000"; A3<="11000000";

A4<="11000000"; A5<="00100000"; A6<="00000000"; A7<="00000000";

elsif A="10" then--甲出石头

A0<="00000000"; A1<="00000000"; A2<="01000000"; A3<="11100000";

A4<="11100000"; A5<="01000000"; A6<="00000000"; A7<="00000000";

else

case temp1 is--甲获胜,显示动画

when 0 =>--显示“甲”

A0<="11111110";

A1<="10010010";

A2<="11111110";

A3<="10010010";

A4<="11111110";

A5<="00010000";

A6<="00010000";

A7<="00010000";

when 1 =>--显示“获”

A0<="00101000";

A1<="11111110";

A2<="10101000";

A3<="01001010";

A4<="10111110";

A5<="01101000";

A6<="10101100";

A7<="01110010";

when 2 =>--显示“胜”

A0<="11100100";

A1<="10110100";

A2<="11111111";

A3<="10100100";

A4<="11111111";

A5<="10100100";

A6<="10100100";

A7<="10111111";

when 3 =>--显示笑脸

A0<="00111100";

A1<="01000010";

A2<="10000001";

A3<="10100101";

A4<="10000001";

A5<="10100101";

A6<="01011010";

A7<="00111100";

when 4 =>--显示笑脸

A0<="00111100";

A1<="01000010";

A2<="10000001";

A3<="10100101";

A4<="10000001";

A5<="10100101";

A6<="01011010";

A7<="00111100";

when 5=>--显示空白

A0<="00000000"; A1<="00000000"; A2<="00000000"; A3<="00000000";

A4<="00000000"; A5<="00000000"; A6<="00000000"; A7<="00000000";

when others=>NULL;

end case;

end if;

if B="00" then--乙出布

B0<="00000000"; B1<="00000000"; B2<="00000111"; B3<="00000111";

B4<="00000111"; B5<="00000111"; B6<="00000000"; B7<="00000000";

elsif B="01" then--乙出剪刀

B0<="00000000"; B1<="00000000"; B2<="00000100"; B3<="00000011";

B4<="00000011"; B5<="00000100"; B6<="00000000"; B7<="00000000";

elsif B="10" then--乙出石头

B0<="00000000"; B1<="00000000"; B2<="00000010"; B3<="00000111";

B4<="00000111"; B5<="00000010"; B6<="00000000"; B7<="00000000";

else

case temp1 is--乙获胜,显示动画

when 0 =>--显示

B0<="11111100";

B1<="00000100";

B2<="00001000";

B3<="00010000";

B4<="00100000";

B5<="01000001";

B6<="10000001";

B7<="11111111";

when 1 =>--显示

B0<="00101000";

B1<="11111110";

B2<="10101000";

B3<="01001010";

B4<="10111110";

B5<="01101000";

B6<="10101100";

B7<="01110010";

when 2 =>显示“

B0<="11100100";

B1<="10110100";

B2<="11111111";

B3<="10100100";

B4<="11111111";

B5<="10100100";

B6<="10100100";

B7<="10111111";

when 3 =>--显示笑脸

B0<="00111100";

B1<="01000010";

B2<="10000001";

B3<="10100101";

B4<="10000001";

B5<="10100101";

B6<="01011010";

B7<="00111100";

when 4 =>--显示笑脸

B0<="00111100";

B1<="01000010";

B2<="10000001";

B3<="10100101";

B4<="10000001";

B5<="10100101";

B6<="01011010";

B7<="00111100";

when 5 =>--显示空白

B0<="00000000"; B1<="00000000"; B2<="00000000"; B3<="00000000";

B4<="00000000"; B5<="00000000"; B6<="00000000"; B7<="00000000";

when others => NULL;

end case;

end if;

if A="11" then--显示获胜动画时另一个颜色为空白

B0<="00000000"; B1<="00000000"; B2<="00000000"; B3<="00000000";

B4<="00000000"; B5<="00000000"; B6<="00000000"; B7<="00000000";

elsif B="11" then

A0<="00000000"; A1<="00000000"; A2<="00000000"; A3<="00000000";

A4<="00000000"; A5<="00000000"; A6<="00000000"; A7<="00000000";

end if;

else--显示开机动画

B0<="00000000"; B1<="00000000"; B2<="00000000"; B3<="00000000";

B4<="00000000"; B5<="00000000"; B6<="00000000"; B7<="00000000";

case temp1 is--红色的“start”字样

when 0 =>--显示‘s’

A0<="00000000";

A1<="00111000";

A2<="01000100";

A3<="01000000";

A4<="00111000";

A5<="00000100";

A6<="01000100";

A7<="00111000";

when 1 =>--显示‘t’

A0<="00000000";

A1<="01111100";

A2<="00010000";

A3<="00010000";

A4<="00010000";

A5<="00010000";

A6<="00010000";

A7<="00010000";

when 2 =>--显示‘a’

A0<="00000000";

A1<="00010000";

A2<="00101000";

A3<="01000100";

A4<="01000100";

A5<="01111100";

A6<="01000100";

A7<="01000100";

when 3 =>--显示‘r’

A0<="00000000";

A1<="01111000";

A2<="01000100";

A3<="01000100";

A4<="01111000";

A5<="01010000";

A6<="01001000";

A7<="01000100";

when 4 =>--显示‘t’

A0<="00000000";

A1<="01111100";

A2<="00010000";

A3<="00010000";

A4<="00010000";

A5<="00010000";

A6<="00010000";

A7<="00010000";

when others => NULL; --显示空白

-- A0<="00000000";

-- A1<="00000000";

-- A2<="00000000";

-- A3<="00000000";

-- A4<="00000000";

-- A5<="00000000";

-- A6<="00000000";

-- A7<="00000000";

end case;

end if;

END PROCESS P1;

P2:process(clk)

begin

if en='1' then

IF (clk'event and clk='1') THEN--8计数器,用于扫描点阵

IF temp>=7 THEN

temp<=0;

ELSE

temp<=temp+1;

END IF;

END IF;

else

temp<=8;--使能端为0则不扫描

end if;

END PROCESS P2;

P4:process(clk)

begin

if rising_edge(clk) then--分频器,分出2Hz的信号,用于动画显示

if(data=249) then --此句为你想要的分频比,data=0,1,2,3,4.......9的分频比为1,23,,,10

data<=0;

Q<=not Q;

else

data<=data+1;

end if;

end if;

clk_2Hz<=Q;

end process P4;

P5:process(clk_2Hz)

begin

IF (clk_2Hz'event and clk_2Hz='1') THEN--6计数器,用于动画显示

IF temp1>=5 THEN

temp1<=0;

ELSE

temp1<=temp1+1;

END IF;

END IF;

END PROCESS P5;

P3:process(temp)

begin--点阵扫描显示进程

CASE temp IS

WHEN 0=> colr<=A0; colg<=B0; row<="01111111";

WHEN 1=> colr<=A1; colg<=B1; row<="10111111";

WHEN 2=> colr<=A2; colg<=B2; row<="11011111";

WHEN 3=> colr<=A3; colg<=B3; row<="11101111";

WHEN 4=> colr<=A4; colg<=B4; row<="11110111";

WHEN 5=> colr<=A5; colg<=B5; row<="11111011";

WHEN 6=> colr<=A6; colg<=B6; row<="11111101";

WHEN 7=> colr<=A7; colg<=B7; row<="11111110";

WHEN OTHERS=> colr<="00000000"; colg<="00000000"; row<="11111111";

END CASE;

END PROCESS P3;

END behavioral;

5LCD液晶屏显示模块

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_ARITH.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY show IS PORT

(rst,clk: IN STD_LOGIC; --复位时钟

A:IN STD_LOGIC_VECTOR(1 DOWNTO 0); --甲的得分

B:IN STD_LOGIC_VECTOR(1 DOWNTO 0); --乙的得分

rs, en, rst_out, sec_out: OUT STD_LOGIC;

rw: OUT STD_LOGIC;

data_out: OUT STD_LOGIC_VECTOR(7 DOWNTO 0));

END show;

ARCHITECTURE fwm OF show IS

TYPE states IS (pause,hold, func_set, dis_on,mode_set,set_ddram1,write_ddram1,set_ddram2,write_char1,write_char2,write_char3,

write_char4,write_char5, write_char6,write_char7,write_char8,write_char9,write_char10,write_char11,write_char12,

write_char13,write_char14,write_char15,return_home,toggle_e,rst1,rst2,rst3,dis_off,dis_clr);

SIGNAL state, n_state: states; --

--SIGNAL data_out: STD_LOGIC_VECTOR(7 DOWNTO 0);

SIGNAL s0,s1,m0,m1,h0,h1,t0,t1 : STD_LOGIC_VECTOR(3 DOWNTO 0);

SIGNAL clk_400Hz, clk_100Hz : STD_LOGIC;

SIGNAL temp:STD_LOGIC;

TYPE ram IS ARRAY (0 TO 15)OF STD_LOGIC_VECTOR(7 DOWNTO 0);

SIGNAL ram1:ram:=(X"20",X"20",X"20",X"20",X"41",X"3A",X"30",X"20",X"20",X"42",X"3A",X"30",X"20",X"20",X"20",X"20"); --显示比分“A0 B0

signal stop_out:std_logic;

BEGIN rst_out <= NOT rst; sec_out <= s0(0); --

--data_out <= data_out WHEN rw = '0' ELSE "ZZZZZZZZ"; -- 设置LCD的数据线为三态数据线

PROCESS(clk,rst) --50MHz分频到400Hz

VARIABLE cnt1: INTEGER RANGE 0 TO 62500;

BEGIN

IF rst='0' THEN cnt1:=0;

clk_400Hz<='0';

ELSIF clk'EVENT AND clk = '1' THEN

IF cnt1 < 62500 THEN cnt1 := cnt1 + 1;

ELSE cnt1 := 0;

clk_400Hz <= NOT clk_400Hz;

END IF; END IF;

END PROCESS;

PROCESS(clk_400Hz) --50MHz分频到400Hz

BEGIN

case A is--修改甲的得分显示

when "00"=> ram1(6)<=X"30";

when "01"=> ram1(6)<=X"31";

when "10"=> ram1(6)<=X"32";

when "11"=> ram1(6)<=X"33";

when others=> NULL;

end case;

case B is--修改的得分显示

when "00"=> ram1(11)<=X"30";

when "01"=> ram1(11)<=X"31";

when "10"=> ram1(11)<=X"32";

when "11"=> ram1(11)<=X"33";

when others=> NULL;

end case;

END PROCESS;

PROCESS (clk_400Hz, rst)

VARIABLE cnt : INTEGER RANGE 0 TO 16;

VARIABLE cnt2 :INTEGER RANGE 0 TO 199;

BEGIN

IF rst = '0' THEN state <=rst1;

data_out <= X"38";

n_state <= rst2;

en <= '1';

rs <= '0';

rw <= '0';

ELSIF clk_400Hz'EVENT AND clk_400Hz = '1' THEN --产生秒脉冲100Hz信号,调试时采用100Hz

--IF stop ='1' THEN state<=pause;

--END IF;

CASE state IS --LCD控制

WHEN rst1 => en <= '1';

rs <= '0';rw <= '0';

data_out <= X"38";

state <= toggle_e;

n_state <= rst2;--设置功能:8,两行,5×7

WHEN rst2 => en <= '1';

rs <= '0';rw <= '0';

data_out <= X"38";

state <= toggle_e;

n_state <= rst3;--设置功能:8,两行,5×7

WHEN rst3 => en <= '1';

rs <= '0';rw <= '0';

data_out <= X"38";--001 1000

state <= toggle_e;

n_state <= func_set;--设置功能:8,两行,5×7,可靠复位

WHEN func_set => en <= '1';

rs <= '0';

rw <= '0';

data_out <= X"38";

state <= toggle_e;

n_state <= dis_off;

WHEN dis_off => en <= '1';

rs <= '0';rw <= '0';

data_out <= X"08";

state <= toggle_e;

n_state <= dis_clr; --显示控制:显示关,光标关

WHEN dis_clr => en <= '1';

rs <= '0';

rw <= '0';

data_out <= X"01";

state <= toggle_e;

n_state <= dis_on;--清屏

WHEN dis_on => en <= '1';

rs <= '0';

rw <= '0';

data_out <= X"0C";

state <= toggle_e;

n_state <= mode_set;--显示控制:显示开,光标关

WHEN mode_set => en <= '1';

rs <= '0';rw <= '0';

data_out <= X"06";

state <= toggle_e;

n_state <= set_ddram1;--显示模式:自动增地址,光标右移

WHEN set_ddram1 => en <='1';

rs<='0';

rw<='0';

data_out<=X"80";

state <= toggle_e;

n_state<=write_ddram1;

WHEN write_ddram1=>en<='1';

rs<='1';

rw<='0';

data_out<=ram1(cnt)(7 DOWNTO 0);

state <= toggle_e;

cnt:=cnt+1; --ram115byte写入ADDRAM

IF cnt=16

THEN n_state<=return_home;

END IF;

WHEN return_home => en <= '1';

rs <= '0';

rw <= '0';

data_out <= "11000000";

state <= toggle_e;

n_state <= set_ddram1;--返回写地址到第一行第一列位置

WHEN toggle_e => en <= '0';

state <= hold;--en下降沿

WHEN hold => state <= n_state; --保持

WHEN pause=>en<='0';

state <= toggle_e;

when others=>NULL;

END CASE;

END IF;

END PROCESS;

END fwm;

6中心模块

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY main IS

PORT(

clk:IN STD_LOGIC;--时钟

LEDen:OUT STD_LOGIC;--LED点阵使能端

KB:IN STD_LOGIC_VECTOR(4 DOWNTO 0);--键盘

LEDA:OUT STD_LOGIC_VECTOR(1 DOWNTO 0):="00"; --甲的出拳

LEDB:OUT STD_LOGIC_VECTOR(1 DOWNTO 0):="00";--乙的出拳

DISPA:OUT STD_LOGIC_VECTOR(1 DOWNTO 0):="00"; --甲的得分

DISPB:OUT STD_LOGIC_VECTOR(1 DOWNTO 0):="00";--乙的得分

LEDstart:OUT STD_LOGIC--开机动画控制

);

END main;

ARCHITECTURE behavioral OF main IS

type state_type is(S0,S1,S2,S3);

signal temp:state_type:=s0;

signal finish:STD_LOGIC:='0';

signal change:STD_LOGIC:='0';

signal goalA:INTEGER RANGE 0 TO 3:=0;

signal goalB:INTEGER RANGE 0 TO 3:=0;

signal answerA:INTEGER RANGE 0 TO 3:=0;

signal answerB:INTEGER RANGE 0 TO 3:=0;

signal confirmA:STD_LOGIC:='0';

signal confirmB:STD_LOGIC:='0';

BEGIN

P1:process(clk)--状态机进程

begin

IF (clk'event and clk='1') THEN

case temp is

--reset

when s0 =>if (KB="10010") then temp<=s1;--change<='0';--按下准备进入ready状态

end if;

--ready

when s1 =>if (KB="10110") then temp<=s2;--change<='1'; --按下进入show状态

elsif (KB="11110") then temp<=s0;--change<='0'; --按下复位进入reset状态

end if;

--show

when s2 =>if (finish='0' and KB="10010") then temp<=s1;--change<='0'; --按下准备进入ready状态

elsif finish='1' then temp<=s3;--change<='0'; --游戏结束,进入end状态

elsif (KB="11110") then temp<=s0;--change<='0'; --按下复位进入reset状态

end if;

--end

when s3 =>if (KB="11110") then temp<=s0;--change<='0'; --按下复位进入reset状态

end if;

when others => temp<=s0;--change<='0';

end case;

end if;

END PROCESS P1;

P2:process(clk,goalA,goalB)--输出控制进程

begin

IF (clk'event and clk='1') THEN

case temp is

when s0 =>--reset状态显示开始动画

answerA<=0;

answerB<=0;

confirmA<='0';

confirmB<='0';

finish<='0';

LEDen<='1';

LEDstart<='1';

change<='0';

when s1 =>--ready状态

change<='0';

LEDstart<='0';

LEDen<='0';

case KB is--检测甲乙的出拳

when "10000" =>if confirmA='0' then answerA<=0;end if;--

when "10100" =>if confirmA='0' then answerA<=1;end if;--剪刀

when "11000" =>if confirmA='0' then answerA<=2;end if;--石头

when "11100" =>confirmA<='1';--按下确认

when "10001" =>if confirmB='0' then answerB<=0;end if;

when "10101" =>if confirmB='0' then answerB<=1;end if;

when "11001" =>if confirmB='0' then answerB<=2;end if;

when "11101" =>confirmB<='1'; --按下确认

when others => NULL;

end case;

when s2 =>--show状态显示出拳结果

change<='1';

LEDen<='1';

LEDstart<='0';

if (goalA>=3 or goalB>=3) then--赢三局游戏结束

finish<='1';

end if;

confirmA<='0';

confirmB<='0';

when s3 =>--end状态

change<='0';

LEDen<='1';

LEDstart<='0';

if KB="11010" then--按下结果键,显示获胜方的获胜动画

if goalA>=3 then

answerA<=3;

else answerB<=3;

end if;

end if;

when others => NULL;

end case;

case goalA is--显示得分

when 0 => DISPA<="00";

when 1 => DISPA<="01";

when 2 => DISPA<="10";

when 3 => DISPA<="11";

when others => NULL;

end case;

case goalB is--显示得分

when 0 => DISPB<="00";

when 1 => DISPB<="01";

when 2 => DISPB<="10";

when 3 => DISPB<="11";

when others => NULL;

end case;

case answerA is--显示出拳

when 0 => LEDA<="00";

when 1 => LEDA<="01";

when 2 => LEDA<="10";

when 3 => LEDA<="11";

when others => NULL;

end case;

case answerB is--显示出拳

when 0 => LEDB<="00";

when 1 => LEDB<="01";

when 2 => LEDB<="10";

when 3 => LEDB<="11";

when others => NULL;

end case;

end if;

END PROCESS P2;

P3:process(temp,change)--计算得分的进程

begin

if (temp=s0) then--reset状态清零

goalA<=0;

goalB<=0;

elsif (change'event and change='1') then

if(temp=s2) then

case answerB is--判断获胜方并加分

when 0 =>

if answerA=2 then goalB<=goalB+1;end if;

if answerA=1 then goalA<=goalA+1;end if;

when 1 =>

if answerA=0 then goalB<=goalB+1;end if;

if answerA=2 then goalA<=goalA+1;end if;

when 2 =>

if answerA=1 then goalB<=goalB+1;end if;

if answerA=0 then goalA<=goalA+1;end if;

when others => NULL;

end case;

end if;

end if;

END PROCESS P3;

END behavioral;

、功能情况

工程实现了全部基本要求、提高要求的13动画和LCD显示)。验收包含提高要求的程序出现了一点问题现在已经解决),因此只验收了基本要求。

情况如下

9资源利用情况

验收时,只包含基本要求,资情况如下

10资源利用情况2

、故障分析

1增加动画和LCD显示模块时,出现问题,只有甲获胜会加分,乙获胜不加分。经过仿真发现问题是电路需要反应时间导致时钟沿不匹配解决方法修改了时钟沿。

2设计4×4键盘输入模块,发现检测不到按键信号。后来发现是扫描与检测的端口接反了。

总结结论

经过逻辑分析,编写VHDL代码,然后调试,进行波形仿真,最后下载到实验板实现,一系列工序之后,成功实现了本实验。我认识到进行数字电路实验,理论分析是十分重要的一环,只有逻辑分析透彻无误,才能用语言进行描述,进而用硬件实现。这次实验让我对VHDL这样一门硬件描述语言有了更加深刻的认识。编写硬件描述代码必须使用与编写软件完全不同的思想。编写硬件描述代码,不仅要符合基本编程语言的规范,更应该时时刻刻联系实现功能的硬件,理解时序和组合的关系,理解同步和异步的差异,理解进程和信号的流程等等,这样才能使写出的代码效率更高。这学期数字电路实验,我在实验操作能力有所提升的同时也更深的理解了数字电路与逻辑设计的理论知识,也体会到了数字电路的强大功能。

本文来源:https://www.2haoxitong.net/k/doc/50fc7bc3fc0a79563c1ec5da50e2524de518d0e9.html

《北邮数字电路与逻辑设计实验-实验报告(下).doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档

文档为doc格式