数字电路与逻辑设计实验报告.docx

上传人:b****4 文档编号:24179457 上传时间:2023-05-25 格式:DOCX 页数:28 大小:419.79KB
下载 相关 举报
数字电路与逻辑设计实验报告.docx_第1页
第1页 / 共28页
数字电路与逻辑设计实验报告.docx_第2页
第2页 / 共28页
数字电路与逻辑设计实验报告.docx_第3页
第3页 / 共28页
数字电路与逻辑设计实验报告.docx_第4页
第4页 / 共28页
数字电路与逻辑设计实验报告.docx_第5页
第5页 / 共28页
点击查看更多>>
下载资源
资源描述

数字电路与逻辑设计实验报告.docx

《数字电路与逻辑设计实验报告.docx》由会员分享,可在线阅读,更多相关《数字电路与逻辑设计实验报告.docx(28页珍藏版)》请在冰豆网上搜索。

数字电路与逻辑设计实验报告.docx

数字电路与逻辑设计实验报告

北京邮电大学

数字电路与逻辑设计

实验报告

课题名称:

简易钢琴游戏

姓名:

学号:

班级:

学院:

实验指导教师:

一.课题要求

设计制作一个简易钢琴游戏机。

1.原理概述:

根据声乐知识,产生音乐的两个因素是音乐频率的持续时间,音乐的十二平均率规定,每两个八音度之间的频率相差一倍,在两个八音度之间,又可分为12个半音。

每两个半音的频率比为4。

另外,音名A(乐谱中的低音6)的频率为440HZ,音名B到C之间,E到F之间为半音,其余为全音。

由此可以计算出乐谱中从低音1到高音1之间每个音名的频率如表1所示。

2.基本要求:

1、用8×8点阵进行游戏显示。

2、BTN1~BTN7七个按键模拟钢琴演奏时的“1234567”七个音符。

点阵的第一列对应音符“1”,第二列对应音符“2”,依此类推,低中高音自定。

3、光点在点阵第一行随机出现,逐点下落,下落速度为0.2秒/行,如图1所示。

4、在光点下落到点阵最后一行之前的过程中,如果按下与该列点阵相应的音符键,该光点消失,蜂鸣器演奏相应的音符声音,计分器加1。

如果在光点下落到最后一行依然没有进行相应的按键操作,该光点消失,计分器不加分。

计分器由数码管显示。

5、每隔1秒在点阵的不同列的第一行出现一个光点,如图2所示。

6、游戏时间为30秒,数码管倒计时显示。

3.提高要求:

1、光点在点阵某行随机出现,然后逐点下落。

2、下落速度随机变化。

3、光点按照存储的乐曲顺序和速度的出现。

4、自拟其它功能。

二.系统设计

1.设计思路

将整个系统分为几个模块,分别设计各个模块,最后把模块连接成系统。

这种分模块设计容易实现,易于纠错,对一个模块的修改不影响其他模块,设计思路清晰明了,整个系统规整有序。

将不同的模块在quartus中制作成器件,在顶层框图中用连线进行相应的连接,加上输入与输出,便完成了整个系统的设计。

2.系统框图

3.分块设计

(1)分频器模块:

把50MHz的时钟频率分别分成1kHz、5HZ和1HZ,分别用于数码管与点阵扫描、光点下落频率、随机数生成与倒计时;

(2)防抖模块:

用于按键的防抖;

(3)随机数生成模块:

每隔一秒产生一个随机数,并判断按键的正确与否;

(4)倒计时模块:

从30开始计时;

(5)数码显示模块:

记录分数,同时将分数与倒计时输出到数码管,用于显示;

(6)点阵模块:

根据分频得到的频率与随机数发生器产生的随机数生成两个扫描频率,分别为行扫描与列扫描,输出到相应管脚;

(7)蜂鸣器模块:

根据按键btn1-btn7七个按钮,结合拨码开关状态(低中高),将50MHz原始时钟进行21中不同的分频,分频系数M=50M/f。

将得到分频信号输出到beep管脚就能够发出相应的音符。

三.仿真波形与波形分析

我是分模块进行仿真的,对每个模块我都新建了一个工程进行仿真。

由于50MHz时钟在Quartus中不好仿真,因此包括分频的模块如分频模块、防抖模块与蜂鸣器模块就没有做仿真了。

1随机数发生器

Clear是清零复位端。

memorize与random是产生的两个随机数,图中的随机数是循环加一的。

Clk_out3是时钟输入。

BTN是按键输入,若按键输入与随机数对应,则匹配值match等于1.

2点阵模块

Memorize与random为两个随机数,clk_out1是扫描频率,clk_out2为光点的下落频率,a为行扫描row,b为列扫描col。

由于时钟频率的关系,仿真图不容易观察,并且由于程序还存在一些问题,可以看出行扫描与列扫描存在不匹配。

3倒计时

Clear是清零端,复位值为30。

clk_out3是时钟输入,time1是个位,time2是十位,从30开始减一,直到均为零。

4计分器与数码管显示

Clear用于清零,clk_out1作为时钟输入。

Cat0是计分的个位,cat1是计分的十位,match是匹配判断值,当match在上升沿等于1时,cat0加1,若cat0等于9,则向cat1进位。

四.代码源程序

①防抖模块

LIBRARYIEEE;

USEIEEE.STD_LOGIC_1164.ALL;

ENTITYfangdouIS

PORT(clk_out2:

INSTD_LOGIC;

btn_in:

instd_logic_vector(6downto0);

btn:

outstd_logic_vector(6downto0)

);

ENDfangdou;

ARCHITECTUREbehaveOFfangdouIS

signalbtntmp1,btntmp2:

std_logic_vector(6downto0);

BEGIN

PROCESS(clk_out2)--防抖

BEGIN

IF(clk_out2'EVENTANDclk_out2='0')THEN

btntmp2<=btntmp1;

btntmp1<=btn_in;

ENDIF;

ENDPROCESS;

btn(0)<=clk_out2andbtntmp1(0)and(notbtntmp2(0));

btn

(1)<=clk_out2andbtntmp1

(1)and(notbtntmp2

(1));

btn

(2)<=clk_out2andbtntmp1

(2)and(notbtntmp2

(2));

btn(3)<=clk_out2andbtntmp1(3)and(notbtntmp2(3));

btn(4)<=clk_out2andbtntmp1(4)and(notbtntmp2(4));

btn(5)<=clk_out2andbtntmp1(5)and(notbtntmp2(5));

btn(6)<=clk_out2andbtntmp1(6)and(notbtntmp2(6));

endbehave;

用于BTN0-BTN7按键的防抖,按键的持续时间为0.2S。

②分频模块

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_unsigned.all;

entityfenpinis

port(clk:

instd_logic;

clk_out1,clk_out2,clk_out3:

outstd_logic

);

endfenpin;

architecturebehaveoffenpinis

signaltemp1,temp2,temp3:

integerrange0to50000000;

signalclk_out_1,clk_out_2:

std_logic;

begin

p1:

PROCESS(clk)

BEGIN

--ifclear<='1'then

--temp1<=0;

IFclk'EVENTANDclk='1'THEN

IFtemp1=2THEN

temp1<=0;clk_out_1<=notclk_out_1;

ELSE

temp1<=temp1+1;

ENDIF;

ENDIF;

ENDPROCESSp1;

clk_out1<=clk_out_1;

p4:

PROCESS(clk_out_1)

BEGIN

--ifclear<='1'then

--temp2<=0;

IFclk_out_1'EVENTANDclk_out_1='1'THEN

IFtemp2=2THEN

temp2<=0;clk_out_2<=notclk_out_2;

ELSE

temp2<=temp2+1;

ENDIF;

ENDIF;

ENDPROCESSp4;

clk_out2<=clk_out_2;

p6:

PROCESS(clk_out_2)

BEGIN

--ifclear<='1'then

--temp1<=0;

IFclk_out_2'EVENTANDclk_out_2='1'THEN

IFtemp3=5THEN

temp3<=0;

ELSE

temp3<=temp3+1;

ENDIF;

ENDIF;

ENDPROCESSp6;

p7:

PROCESS(temp3)

BEGIN

--IFclk'EVENTANDclk='1'THEN

IFtemp3<3THEN

clk_out3<='0';

ELSE

clk_out3<='1';

ENDIF;

--endif;

ENDPROCESSp7;

endbehave;

用50MHz原始时钟进行分频,分频输出频率分别为1kHz、5Hz、1Hz,占空比为50%。

③随机数发生器

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_unsigned.all;

entityrandomeris

port(clk_out3:

instd_logic;

clear:

instd_logic;

match:

outstd_logic;

random,memorize:

outintegerrange0to9;

btn:

instd_logic_vector(6downto0)

);

endrandomer;

architecturebehaveofrandomeris

signalrandom1,memorize1:

integerrange0to9;

begin

p3:

process(clk_out3,clear)--随机数发生器

begin

ifclear='1'then

memorize1<=0;

random1<=1;

elsIFclk_out3'eventandclk_out3='1'THEN

ifrandom1=6then

random1<=0;

else

memorize1<=random1;

random1<=random1+1;

endif;

endif;

endprocessp3;

p4:

process(random1,btn,memorize1)

begin

match<='0';

casebtnis

when"1000000"=>ifrandom1=0ormemorize1=0thenmatch<='1';endif;

when"0100000"=>ifrandom1=1ormemorize1=1thenmatch<='1';endif;

when"0010000"=>ifrandom1=2ormemorize1=2thenmatch<='1';endif;

when"0001000"=>ifrandom1=3ormemorize1=3thenmatch<='1';endif;

when"0000100"=>ifrandom1=3ormemorize1=4thenmatch<='1';endif;

when"0000010"=>ifrandom1=5ormemorize1=5thenmatch<='1';endif;

when"0000001"=>ifrandom1=6ormemorize1=6thenmatch<='1';endif;

whenothers=>null;

endcase;

endprocessp4;

random<=random1;

memorize<=memorize1;

endbehave;

随机数模块我没有做完,不知道怎么做,没有头绪,用M序列做的话感觉转化比较麻烦。

我只以循环加一的的方式生成了两个数。

另外,当有BTN键输入的时候,判断是否与生成的随机数匹配,若匹配,则match等于1,否则等于0。

④点阵模块

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_unsigned.all;

entitydianzhenis

port(clk_out1,clk_out2:

instd_logic;

a,b:

outstd_logic_vector(7downto0);

random,memorize:

inintegerrange0to9);

enddianzhen;

architecturebehaveofdianzhenis

signaltmp:

integerrange0to4;

begin

p8:

process(clk_out2)

begin

IFclk_out2'EVENTANDclk_out2='1'THEN

iftmp=4then

tmp<=0;

else

tmp<=tmp+1;

endif;

endif;

endprocessp8;

p9:

PROCESS(clk_out1,tmp,random,memorize)--点阵扫描

BEGIN

CASEclk_out1is

when'0'=>

casetmpis

WHEN0=>

caserandomis

when0=>a<="01111111";b<="10000000";

when1=>a<="01111111";b<="01000000";

when2=>a<="01111111";b<="00100000";

when3=>a<="01111111";b<="00010000";

when4=>a<="01111111";b<="00001000";

when5=>a<="01111111";b<="00000100";

when6=>a<="01111111";b<="00000010";

whenothers=>a<="01111111";b<="00000000";

endcase;

WHEN1=>

caserandomis

when0=>a<="10111111";b<="10000000";

when1=>a<="10111111";b<="01000000";

when2=>a<="10111111";b<="00100000";

when3=>a<="10111111";b<="00010000";

when4=>a<="10111111";b<="00001000";

when5=>a<="10111111";b<="00000100";

when6=>a<="10111111";b<="00000010";

whenothers=>a<="11111111";b<="00000000";

endcase;

WHEN2=>

caserandomis

when0=>a<="11011111";b<="10000000";

when1=>a<="11011111";b<="01000000";

when2=>a<="11011111";b<="00100000";

when3=>a<="11011111";b<="00010000";

when4=>a<="11011111";b<="00001000";

when5=>a<="11011111";b<="00000100";

when6=>a<="11011111";b<="00000010";

whenothers=>a<="11011111";b<="00000000";

endcase;

WHEN3=>

caserandomis

when0=>a<="11101111";b<="10000000";

when1=>a<="11101111";b<="01000000";

when2=>a<="11101111";b<="00100000";

when3=>a<="11101111";b<="00010000";

when4=>a<="11101111";b<="00001000";

when5=>a<="11101111";b<="00000100";

when6=>a<="11101111";b<="00000010";

whenothers=>a<="11111111";b<="00000000";

endcase;

WHEN4=>

caserandomis

when0=>a<="11110111";b<="10000000";

when1=>a<="11110111";b<="01000000";

when2=>a<="11110111";b<="00100000";

when3=>a<="11110111";b<="00010000";

when4=>a<="11110111";b<="00001000";

when5=>a<="11110111";b<="00000100";

when6=>a<="11110111";b<="00000010";

whenothers=>a<="11111111";b<="00000000";

endcase;

endcase;

when'1'=>

casetmpis

WHEN0=>

casememorizeis

when0=>a<="11111011";b<="10000000";

when1=>a<="11111011";b<="01000000";

when2=>a<="11111011";b<="00100000";

when3=>a<="11111011";b<="00010000";

when4=>a<="11111011";b<="00001000";

when5=>a<="11111011";b<="00000100";

when6=>a<="11111011";b<="00000010";

whenothers=>a<="11111011";b<="00000000";

endcase;

WHEN1=>

casememorizeis

when0=>a<="11111101";b<="10000000";

when1=>a<="11111101";b<="01000000";

when2=>a<="11111101";b<="00100000";

when3=>a<="11111101";b<="00010000";

when4=>a<="11111101";b<="00001000";

when5=>a<="11111101";b<="00000100";

when6=>a<="11111101";b<="00000010";

whenothers=>a<="11111101";b<="00000000";

endcase;

WHEN2=>

casememorizeis

when0=>a<="11111110";b<="10000000";

when1=>a<="11111110";b<="01000000";

when2=>a<="11111110";b<="00100000";

when3=>a<="11111110";b<="00010000";

when4=>a<="11111110";b<="00001000";

when5=>a<="11111110";b<="00000100";

when6=>a<="11111110";b<="00000010";

whenothers=>a<="11111110";b<="00000000";

endcase;

whenothers=>null;

endcase;

endcase;

endprocessp9;

endbehave;

我使用了两个频率,一个为1kHz,用于行扫描(a)与列扫描(b),另一个为5Hz,用于光点的下落。

根据随机数的值使相应的点发光。

⑤倒计时

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_unsigned.all;

entitytimingis

port(clk_out3:

instd_logic;

clear:

instd_logic;

time1,time2:

outintegerrange0to9

);

endtiming;

architecturebehaveoftimingis

signaltime3,time4:

integerrange0to9;

begin--倒计时

p20:

PROCESS(clk_out3,clear)

BEGIN

ifclear='1'then

time3<=0;

time4<=3;

--endif;

elsifclk_out3'EVENTANDclk_out3='1'THEN

iftime3=0then

iftime4/=0then

time3<=9;

time4<=time4-1;

endif;

elsetime3<=time3-1;

endif;

endif;

time1<=time3;time2<=time4;

ENDPROCESSp20;

endbehave;

倒计时模块相对比较简单,用clear作为清零端,初值为30,每隔一秒个位减一,若个位不够向十位借一,直到个位与十位均为零。

⑥计分与数码管显示

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_unsigned.all;

entitycounteris

port(clk_out1:

instd_logic;

btn:

instd_logic_vector(6downto0);

count:

outstd_logic_vector(5downto0);

coutout:

outstd_logic_vector(6downto0);

random,memorize:

inintegerrange0to9;

time1,time2:

inintegerrange0to9;

match:

instd_logic;

clear:

instd_logic

);

endcounter;

architecturebehaveofcounteris

signalcnt:

integerrange0TO3;

signalcat0,cat1:

integerrange0to9;

begin

p1:

process(btn,random,memorize,clear)--计分器

begin

ifclear='1'then

cat0<=0;

cat1<=0;

elsifmatch'eventandmatch='1'then

ifcat0=9then

cat0<=0;

cat1<=cat1+1;

else

cat0<=cat0+1;

endif;

endif;

endprocessp1;

p15:

PROCESS(clk_out1)

BEGIN

IF(clk_out1'EVENTANDclk_out1='1')THEN

IFcnt=3THEN

cnt<=0;

ELSE

cnt<=cnt+1;

ENDIF;

ENDIF;

ENDPROCESSp15;

p16:

process(cnt,cat0,cat1,time1,time2)

begin

CASEcntIS

WHEN0=>count<="011111";

casecat0is

when0=>coutout<="1111110";

when1=>coutout<="0110000";

when2=>couto

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 表格模板 > 书信模板

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1