北邮数字电路与逻辑设计实验-实验报告(下)(共28页).docx
精选优质文档-倾情为你奉上北京邮电大学电路实验中心<数字电路与逻辑设计实验(下)>实验报告专心-专注-专业班级: xxx 学院: xxx 实 验 室: xxx 审阅教师: 姓名(班内序号): xxx学号: xxx 实验时间: xxx 评定成绩: 目录一、任务要求本电路可供甲乙二人进行猜拳游戏。通过不同的按键控制,选择多种出拳方式,显示猜 拳的结果,实现猜拳游戏,防止了作弊的可能。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总体框图启动开机动画、音效裁判准备双方出拳并确认裁判开判断胜负输出出拳结果和比分是否平局是否有人赢3局显示获胜方结束动画、音效结束图 2系统流程图中心模块分频器LED点阵数码管LCD液晶屏按键键盘图 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分频器模块分频比太大,不易仿真。24×4键盘输入模块图 5 4×4键盘输入模块仿真模块为时钟下降沿有效,resultout4为有按键按下的信号,resultout0.3为按下的按键。仿真中遍历了所有按键的情况,在resultout中对应有1631的所有情况(没有按顺序)。在中心模块编写时,考虑了防抖的问题,检测到按下多次按键与按下一次按键的效果相同,所以在此模块中没有必要加入防抖。3数码管显示模块图 6数码管显示模块仿真时钟clk为0时,DISP7点亮,显示甲的得分,时钟clk为1时,DISP6点亮,显示乙的得分。输入A、B遍历了甲、乙得分的所有结果,对应disp为数码管的显示,状态表示0分,0状态表示1分,m状态表示2分,y状态表示3分。48×8 LED点阵显示模块图 7 8×8 LED点阵显示模块仿真此模块状态太多,只仿真了部分状态。输入A、B的0-2状态分别代表石头、剪刀、布,3状态代表甲或乙获胜。输出colr为甲的出拳结果,colg为乙的出拳结果。5LCD液晶屏显示模块此模块使用50MHz信号,不易仿真。实现功能与数码管显示模块类似。6中心模块图 8中心模块仿真此模块状态太多,只仿真了部分状态。仿真中模拟按下了3个按键,第一个是裁判的“准备”键,按键抬起后结束开机动画,进入选手输入状态,LEDen和LEDstart都变为0。第二个是乙按下“剪刀”(甲默认出“布”),按键抬起后LEDB的信号发生变化。第一个是裁判的“开”键,按键抬起后结算双方出拳结果,给乙+1分(DISPB),同时显示双方出拳结果,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 issignal data:integer range 0 to 24999;signal Q:std_logic;beginprocess(clkin) begin if rising_edge(clkin) then -检测输入时钟上升沿 if(data=24999) then -此句为你想要的分频比,data=0,1,2,3,4.9的分频比为1,2,3,,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)BEGINIF (clk'event and clk='0') THENCASE 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)beginIF (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)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 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); beginCASE A IS -将甲得分变为数码管显示信号WHEN "00"=> dispA:=""-0 WHEN "01"=> dispA:=""-1 WHEN "10"=> dispA:=""-2 WHEN "11"=> dispA:=""-3 WHEN OTHERS=> dispA:=""END CASE; CASE B IS -将乙得分变为数码管显示信号WHEN "00"=> dispB:=""-0 WHEN "01"=> dispB:=""-1 WHEN "10"=> dispB:=""-2 WHEN "11"=> dispB:=""-3 WHEN OTHERS=> dispB:=""END CASE; CASE clk IS -时钟为0时显示甲,时钟为1时显示乙,相当于扫描WHEN '0'=> disp<=dispA; cat<=""WHEN '1'=> disp<=dispB; cat<=""WHEN OTHERS=> disp<="" cat<="" 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)BEGINif start='0' thenif A="00" then-甲出布A0<=""A1<=""A2<=""A3<=""A4<=""A5<=""A6<=""A7<=""elsif A="01" then-甲出剪刀A0<=""A1<=""A2<=""A3<=""A4<=""A5<=""A6<=""A7<=""elsif A="10" then-甲出石头A0<=""A1<=""A2<=""A3<=""A4<=""A5<=""A6<=""A7<=""elsecase temp1 is-甲获胜,显示动画when 0 =>-显示“甲”A0<=""A1<=""A2<=""A3<=""A4<=""A5<=""A6<=""A7<=""when 1 =>-显示“获”A0<=""A1<=""A2<=""A3<=""A4<=""A5<=""A6<=""A7<=""when 2 =>-显示“胜”A0<=""A1<=""A2<=""A3<=""A4<=""A5<=""A6<=""A7<=""when 3 =>-显示笑脸A0<=""A1<=""A2<=""A3<=""A4<=""A5<=""A6<=""A7<=""when 4 =>-显示笑脸A0<=""A1<=""A2<=""A3<=""A4<=""A5<=""A6<=""A7<=""when 5=>-显示空白A0<=""A1<=""A2<=""A3<=""A4<=""A5<=""A6<=""A7<=""when others=>NULL;end case;end if;if B="00" then-乙出布B0<=""B1<=""B2<=""B3<=""B4<=""B5<=""B6<=""B7<=""elsif B="01" then-乙出剪刀B0<=""B1<=""B2<=""B3<=""B4<=""B5<=""B6<=""B7<=""elsif B="10" then-乙出石头B0<=""B1<=""B2<=""B3<=""B4<=""B5<=""B6<=""B7<=""elsecase temp1 is-乙获胜,显示动画when 0 =>-显示“乙”B0<=""B1<=""B2<=""B3<=""B4<=""B5<=""B6<=""B7<=""when 1 =>-显示“获”B0<=""B1<=""B2<=""B3<=""B4<=""B5<=""B6<=""B7<=""when 2 =>显示“胜”B0<=""B1<=""B2<=""B3<=""B4<=""B5<=""B6<=""B7<=""when 3 =>-显示笑脸B0<=""B1<=""B2<=""B3<=""B4<=""B5<=""B6<=""B7<=""when 4 =>-显示笑脸B0<=""B1<=""B2<=""B3<=""B4<=""B5<=""B6<=""B7<=""when 5 =>-显示空白B0<=""B1<=""B2<=""B3<=""B4<=""B5<=""B6<=""B7<=""when others => NULL;end case;end if;if A="11" then-显示获胜动画时另一个颜色为空白B0<=""B1<=""B2<=""B3<=""B4<=""B5<=""B6<=""B7<=""elsif B="11" thenA0<=""A1<=""A2<=""A3<=""A4<=""A5<=""A6<=""A7<=""end if;else-显示开机动画B0<=""B1<=""B2<=""B3<=""B4<=""B5<=""B6<=""B7<=""case temp1 is-红色的“start”字样when 0 =>-显示sA0<=""A1<=""A2<=""A3<=""A4<=""A5<=""A6<=""A7<=""when 1 =>-显示tA0<=""A1<=""A2<=""A3<=""A4<=""A5<=""A6<=""A7<=""when 2 =>-显示aA0<=""A1<=""A2<=""A3<=""A4<=""A5<=""A6<=""A7<=""when 3 =>-显示rA0<=""A1<=""A2<=""A3<=""A4<=""A5<=""A6<=""A7<=""when 4 =>-显示tA0<=""A1<=""A2<=""A3<=""A4<=""A5<=""A6<=""A7<=""when others => NULL; -显示空白-A0<=""-A1<=""-A2<=""-A3<=""-A4<=""-A5<=""-A6<=""-A7<=""end case;end if;END PROCESS P1; P2:process(clk)beginif en='1' then IF (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) begin if 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; else data<=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 IS WHEN 0=> colr<=A0; colg<=B0; row<=""WHEN 1=> colr<=A1; colg<=B1; row<=""WHEN 2=> colr<=A2; colg<=B2; row<=""WHEN 3=> colr<=A3; colg<=B3; row<=""WHEN 4=> colr<=A4; colg<=B4; row<=""WHEN 5=> colr<=A5; colg<=B5; row<=""WHEN 6=> colr<=A6; colg<=B6; row<=""WHEN 7=> colr<=A7; colg<=B7; row<=""WHEN OTHERS=> colr<="" colg<="" row<="" 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"); -显示比分“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分频到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 <=rs