当前位置:文档之家› 北邮数字电路与逻辑设计实验-实验报告(下)

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

北京邮电大学电路实验中心<数字电路与逻辑设计实验(下)>实验报告班级: xxx 学院: xxx实验室: xxx 审阅教师:姓名(班内序号): xxx 学号: xxx实验时间: xxx评定成绩:目录一、任务要求 (2)1.基本要求 (2)2.提高要求 (2)二、系统设计 (2)1.设计思路 (2)2.总体框图 (4)3.分块设计 (5)(1)分频器模块 (5)(2)4×4键盘输入模块 (5)(3)数码管显示模块 (6)(4)8×8 LED点阵显示模块 (6)(5)LCD液晶屏显示模块 (6)(6)中心模块 (6)三、仿真波形及波形分析 (6)1.分频器模块 (6)2.4×4键盘输入模块 (7)3.数码管显示模块 (7)4.8×8 LED点阵显示模块 (8)5.LCD液晶屏显示模块 (8)6.中心模块 (8)四、源程序 (9)1.分频器模块 (9)2.4×4键盘输入模块 (9)3.数码管显示模块 (11)4.8×8 LED点阵显示模块 (12)5.LCD液晶屏显示模块 (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)分频器模块输入clkin为50MHz时钟,输出clkout为1KHz时钟,作为中心模块、8×8 LED点阵显示模块、数码管显示模块、4×4键盘输入模块的时钟信号。

(2)4×4键盘输入模块4×4键盘输入模块负责读取键盘输入,并将其输出到中心模块。

输出KBcol为4位二进制信号,是键盘的遍历扫描信号。

输入KBrow为4位二进制信号,是键盘的检测信号。

输出resultout为5位二进制信号,是4×4键盘输入模块所检测出的所按的按键,其中第一位代表键盘按下,后四位用二进制数表示所按的按键。

(3)数码管显示模块数码管显示模块负责接收中心模块的信号,显示比分。

输入A、B分别为2位二进制信号,代表甲、乙的得分。

输出cat为8位二进制信号,控制8个数码管的使能端。

输出disp为7位二进制信号,控制数码管所显示的图案。

(4)8×8 LED点阵显示模块8×8 LED点阵显示模块负责接收中心模块的信号,显示相应的图案。

输入A、B分别为2位二进制信号,代表甲、乙的出拳结果,其中“11”表示甲或乙获胜,显示结束动画。

输入en为点阵的使能端,start为开机动画控制信号。

输出row为8位二进制信号,是点阵的扫描信号。

输出colr为8位二进制信号,是红色点阵的数据信号。

输出colg为8位二进制信号,是绿色点阵的数据信号。

(5)LCD液晶屏显示模块LCD液晶屏显示模块负责接收中心模块的信号,显示比分。

时钟clk直接使用50MHz信号。

输入rst为LCD液晶屏模块的复位信号,输入A、B分别为2位二进制信号,代表甲、乙的得分。

输出rs、en、rw、data_out为LCD液晶屏的控制和数据信号。

(6)中心模块中心模块负责读取4×4键盘输入模块的输入,并控制状态机和其他模块的输出显示。

输入KB为5位二进制信号,是4×4键盘输入模块所检测出的所按的按键。

输出LEDen控制LED点阵模块的使能端,LEDstart为LED点阵模块的开机动画控制信号。

输出LEDA、LEDB分别为2位二进制信号,代表甲、乙的出拳结果,其中“11”表示甲或乙获胜,显示结束动画。

输出DISPA、DISPB分别为2位二进制信号,代表甲、乙的得分。

三、仿真波形及波形分析1.分频器模块分频比太大,不易仿真。

2.4×4键盘输入模块图 5 4×4键盘输入模块仿真模块为时钟下降沿有效,resultout[4]为有按键按下的信号,resultout[0..3]为按下的按键。

仿真中遍历了所有按键的情况,在resultout中对应有16~31的所有情况(没有按顺序)。

在中心模块编写时,考虑了防抖的问题,检测到按下多次按键与按下一次按键的效果相同,所以在此模块中没有必要加入防抖。

3.数码管显示模块图6数码管显示模块仿真时钟clk为‘0’时,DISP7点亮,显示甲的得分,时钟clk为‘1’时,DISP6点亮,显示乙的得分。

输入A、B遍历了甲、乙得分的所有结果,对应disp为数码管的显示,‘~’状态表示0分,‘0’状态表示1分,‘m’状态表示2分,‘y’状态表示3分。

4.8×8 LED点阵显示模块图7 8×8 LED点阵显示模块仿真此模块状态太多,只仿真了部分状态。

输入A、B的‘0’-‘2’状态分别代表石头、剪刀、布,‘3’状态代表甲或乙获胜。

输出colr为甲的出拳结果,colg为乙的出拳结果。

5.LCD液晶屏显示模块此模块使用50MHz信号,不易仿真。

实现功能与数码管显示模块类似。

6.中心模块图8中心模块仿真此模块状态太多,只仿真了部分状态。

仿真中模拟按下了3个按键,第一个是裁判的“准备”键,按键抬起后结束开机动画,进入选手输入状态,LEDen和LEDstart都变为‘0’。

第二个是乙按下“剪刀”(甲默认出“布”),按键抬起后LEDB的信号发生变化。

第一个是裁判的“开”键,按键抬起后结算双方出拳结果,给乙+1分(DISPB),同时显示双方出拳结果,LEDen变为‘1’。

四、源程序1.分频器模块library ieee;use ieee.std_logic_1164.all;entity fenpinqi12 isport( clkin:in std_logic; --时钟信号输入clkout:out std_logic); --时钟信号输出end fenpinqi12;architecture aroneMHZ of fenpinqi12 issignal data:integer range 0 to 24999;signal Q:std_logic;beginprocess(clkin)beginif rising_edge(clkin) then --检测输入时钟上升沿if(data=24999) then --此句为你想要的分频比,data=0,1,2,3,4.......9的分频比为1,2,3,,,10 data<=0;Q<=not Q;elsedata<=data+1;end if;end if;clkout<=Q;end process;end aroneMHZ;2.4×4键盘输入模块LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY KBcontroller ISPORT(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 ISsignal temp:INTEGER RANGE 0 TO 3;signal result:STD_LOGIC_VECTOR(4 DOWNTO 0);BEGINP1:PROCESS(temp)BEGINIF (clk'event and clk='0') THENCASE temp IS --检测键盘输入结果WHEN 0=>CASE KBrow ISWHEN "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 ISWHEN "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 ISWHEN "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 ISWHEN "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)beginIF (clk'event and clk='1') THEN --模4计数器,对应键盘的4列IF temp=3 THENtemp<=0;ELSEtemp<=temp+1;END IF;END IF;END PROCESS P2;P3:process(temp)beginCASE 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 ISPORT(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 ISBEGINP3:process(clk,A,B)variable dispA:STD_LOGIC_VECTOR(0 To 6);variable dispB:STD_LOGIC_VECTOR(0 To 6);beginCASE A IS --将甲得分变为数码管显示信号WHEN "00"=> dispA:="1111110";--0WHEN "01"=> dispA:="0110000";--1WHEN "10"=> dispA:="1101101";--2WHEN "11"=> dispA:="1111001";--3WHEN OTHERS=> dispA:="0000000";END CASE;CASE B IS --将乙得分变为数码管显示信号WHEN "00"=> dispB:="1111110";--0WHEN "01"=> dispB:="0110000";--1WHEN "10"=> dispB:="1101101";--2WHEN "11"=> dispB:="1111001";--3WHEN 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;4.8×8 LED点阵显示模块LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY LEDshow ISPORT(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 ISsignal 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);BEGINP1:PROCESS(clk_2Hz)BEGINif start='0' thenif 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";elsecase 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"; elsecase 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" thenA0<="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)beginif en='1' thenIF (clk'event and clk='1') THEN--模8计数器,用于扫描点阵IF temp>=7 THENtemp<=0;ELSEtemp<=temp+1;END IF;END IF;elsetemp<=8;--使能端为0,则不扫描end if;END PROCESS P2;P4:process(clk)beginif rising_edge(clk) then--分频器,分出2Hz的信号,用于动画显示if(data=249) then --此句为你想要的分频比,data=0,1,2,3,4.......9的分频比为1,2,3,,,10 data<=0;Q<=not Q;elsedata<=data+1;end if;end if;clk_2Hz<=Q;end process P4;P5:process(clk_2Hz)beginIF (clk_2Hz'event and clk_2Hz='1') THEN--模6计数器,用于动画显示IF temp1>=5 THENtemp1<=0;ELSEtemp1<=temp1+1;END IF;END IF;END PROCESS P5;P3:process(temp)begin--点阵扫描显示进程CASE temp ISWHEN 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;5.LCD液晶屏显示模块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 ISTYPE 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);SIGNALram1: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"); --显示比分“A:0 B:0”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分频到400HzVARIABLE cnt1: INTEGER RANGE 0 TO 62500;BEGINIF rst='0' THEN cnt1:=0;clk_400Hz<='0';ELSIF clk'EVENT AND clk = '1' THENIF cnt1 < 62500 THEN cnt1 := cnt1 + 1;ELSE cnt1 := 0;clk_400Hz <= NOT clk_400Hz;END IF; END IF;END PROCESS;PROCESS(clk_400Hz) --50MHz分频到400HzBEGINcase 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;BEGINIF 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×7WHEN rst2 => en <= '1';rs <= '0';rw <= '0';data_out <= X"38";state <= toggle_e;n_state <= rst3;--设置功能:8位,两行,5×7WHEN rst3 => en <= '1';rs <= '0';rw <= '0';data_out <= X"38";--001 1000state <= 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; --将ram1的15个byte写入ADDRAMIF cnt=16THEN 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 ISPORT(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 IStype 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';BEGINP1:process(clk)--状态机进程beginIF (clk'event and clk='1') THENcase temp is--resetwhen s0 =>if (KB="10010") then temp<=s1;--change<='0';--按下“准备”进入ready状态end if;--readywhen s1 =>if (KB="10110") then temp<=s2;--change<='1'; --按下“开”进入show状态elsif (KB="11110") then temp<=s0;--change<='0'; --按下“复位”进入reset状态end if;--showwhen 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;--endwhen 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)--输出控制进程beginIF (clk'event and clk='1') THENcase temp iswhen 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 thenanswerA<=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";。

相关主题