FPGA课程设计报告简易电子琴的设计doc文档格式.docx
《FPGA课程设计报告简易电子琴的设计doc文档格式.docx》由会员分享,可在线阅读,更多相关《FPGA课程设计报告简易电子琴的设计doc文档格式.docx(27页珍藏版)》请在冰豆网上搜索。
Input
时钟频率50M
key(1~9)
键入以及选择曲目
num
Output
数码管显示
out_r
根据r选择不同模块
3、顶层划分:
主模块(key1.key2.key3.key4.key5.key6.key7.key8.key9)outclkbeep_r
4、主要模块:
主模块:
功能描述:
是四个子模块的核心,通过主模块分别调用四个不同的子模块。
管脚描述:
信号名称
输入/输出
源
功能描述
inclk
Input
Pin
系统时钟50MHz
Key(1~9)
按键选择,键入作用
outclk
Output
模块选择输出
按键模块:
通过按键key1~key7键入不同的7个音阶,频率不同则蜂鸣器发音就不同;
通过mm=(key8、key9)的值选择调用不同曲目模块。
Key(1~7)
按键键入7个不同音阶
Beep4
输出7个不同音阶
曲目模块:
功能描述:
不同的曲目模块输出不同的曲调,根据高低音对应的频率不同输出不同曲调的曲目。
在50MHZ的情况下对主时钟分频得到6MHZ的频率,得到在6MHZ下对应的音阶及其对应频率,以及分频数,通过计数分频数,来对不同频率的声音进行输出,实验箱原始时钟为50MHz,分频后变成不同的频率输出,通过蜂鸣器输出不同频率的声音。
音乐的节拍通过分频变为4Hz,作为1/4拍,即每个单位时长0.25s。
管脚描述:
Key(8~9)
选择曲目
Beep3
输出曲目
5、功能仿真:
1、综合:
2、总体电路图:
3、所有输入输出信号:
4、管脚分配:
输入信号:
一个时钟信号,9个按键;
输出信号:
一个数码管输出,一个蜂鸣器输出音调。
5、时序仿真:
仿真结果;
设置输入信号key1~key7为高电平,此时设置key8~key9=01,即mm=01,在数码管应该显示1,在仿真结束后,如图示数码管为11111001,即为1,outclk为蜂鸣器的输出,如图示也正确,所以本设计经过仿真证明正确可行。
6、硬件测试结果:
在时序验证后下载,通过硬件测试,实验达到预期效果,当mm(key8~key9)=00时,通过key1~key7这7个按键的键入蜂鸣器可以发出do~xi的七个音阶的音,即表示了电子琴的弹奏功能;
当mm=01时,播放了第一首歌;
mm=10时,播放了第二首歌;
mm=11时,播放第三首歌。
通过硬件的测试,所有的设计目标均实现。
7、对结果和结论的问题讨论:
实验过程中,蜂鸣器发音时好时坏,有时比较低沉,有时却比较尖锐,这可能是对主系统分频不精确导致的结果,当对主系统时钟不同分频时,结果都不同,最终在多次试验下,得到在6M时钟频率下效果最为理想。
8、音阶及其对应频率(时钟频率为50MHz分为6MHz)
音阶
频率/Hz
周期/us
半周期/us
分频数
中音
1
523
1912
956
11472
2
578
1684
842
10380
3
659
1518
759
9104
4
698
1432
716
8595
5
784
1276
638
7653
6
880
1136
568
6818
7
988
1012
506
6073
高音
H1
1046
478
5736
H2
1175
852
426
5106
五、心得体会:
在这次课程设计之前,其实做过了单片机关于蜂鸣器方面的实验,上手起来还是很快的,开始时,先按照老师的要求,写规范,确定实现方案,然后在逐一细化,一步一步按照要求去完成整个设计。
本次设计要用quartusII软件,由于之前对此软件不是太熟悉所以导致了一些错误和问题的发生,所以这次课程设计中认真学习了quartusII软件的具体使用步骤和操作流程,对所有可能出现的问题进行逐一攻破。
通过这次实验,我不但熟悉了quartusII软件,也了解了开发的最基本流程和方法,也进一步加深了对Verilog编程语言的理解,最重要的是锻炼了我独立思考和分析的逻辑能力,通过从顶向下的设计方法,一步步实现,然后将整个设计串套起来,是我对设计的流程以及编程有了很大的提高。
通过此次硬件课程设计,使我越来越认识到一点,编程对项目实现有着至关重要的作用,我们在硬件开发的过程中必须重视编程,将编程看作是完善开发的不可缺少的一部分。
在一次次的反复设计、论证和测试中,不仅提高了逻辑分析能力、全面分析问题的能力,还提升了发现问题、解决问题的能力。
虽然设计过程比较繁琐,大大小小也出现了许多问题,但这却磨练了我的意志。
通过各方面的学习,使我的知识面进一步拓宽了。
同时,通过本次课程设计,使我也发现了自己的不足,例如:
逻辑分析能力不突出,编程能力不足,解决问题的能力不足,使我认识到在以后的学习中在这些方面要多努力,加以改进,提升自我能力。
我相信通过这次课程设计的学习,对我以后有着十分重要的影响和作用。
附代码:
moduledianziqin(inclk,outclk,key1,key2,key3,key4,key5,key6,key7,key8,key9,num);
inputinclk;
inputkey1,key2,key3,key4,key5,key6,key7,key8,key9;
outputoutclk;
output[7:
0]num;
reg[7:
0]num;
regoutclk,clk_6M;
reg[3:
0]c;
wireout1,out2,out3,out4;
wire[8:
0]key;
reg[1:
0]mm;
assignkey={key1,key2,key3,key4,key5,key6,key7,key8,key9};
//由按键拼键为变量key
//调用子调块
digital_pianom1(
.inclk(inclk),
.key1(key1),
.key2(key2),
.key3(key3),
.key4(key4),
.key5(key5),
.key6(key6),
.key7(key7),
.beep4(out4)
);
bellm2(
.inclk(inclk),
.beep1(out1)
);
bell2m3(
.inclk(inclk),
.beep2(out2)
bell3m4(
.beep3(out3)
always@(posedgeinclk)
begin
if(c<
4'
d8)
c<
=c+4'
d1;
else
begin
c<
=4'
d0;
clk_6M<
=~clk_6M;
end
end
always@(posedgeclk_6M)//在时钟的上升沿检测是否有按键按下
begin
if(key==9'
b111111110)
mm<
=2'
b01;
elseif(key==9'
b111111101)
b10;
b111111100)
b11;
elsemm<
b00;
end
always@(mm)
case(mm)
2'
b01:
num<
=8'
b11111001;
b10:
b10100100;
b11:
b10110000;
default:
b11000000;
endcase
always@(mm)//按键响应
if(mm==2'
b01)
outclk<
=out1;
elseif(mm==2'
b10)
=out2;
b11)
=out3;
elseoutclk<
=out4;
endmodule
//digital_piano子模块
moduledigital_piano(inclk,key1,key2,key3,key4,key5,key6,key7,beep4);
inputinclk,key1,key2,key3,key4,key5,key6,key7;
outputbeep4;
wire[6:
0]key_code;
0]c;
regclk_6M;
regbeep_r;
reg[15:
0]count;
0]count_end;
parameterDo=7'
b1111110,
re=7'
b1111101,
mi=7'
b1111011,
fa=7'
b1110111,
so=7'
b1101111,
la=7'
b1011111,
si=7'
b0111111;
assignkey_code={key7,key6,key5,key4,key3,key2,key1};
assignbeep4=beep_r;
//输出音乐
always@(posedgeclk_6M)//分频模块,得出乐谱
count<
=count+16'
//计数器加1
if(count==count_end)
count<
=16'
//计数器清零
beep_r<
=!
beep_r;
always@(posedgeclk_6M)//状态机,根据按键状态,选择不同的音符输出
case(key_code)
Do:
count_end<
=16'
d11450;
re:
d10204;
mi:
d09090;
fa:
d08571;
so:
d07802;
la:
d06802;
si:
d06060;
default:
count_end<
//bell子模块《两只老虎》
modulebell(inclk,beep1);
//系统时钟
outputbeep1;
//蜂鸣器输出端
0]high,med,low;
0]origin;
regbeep_r;
//寄存器
0]state;
0]count;
assignbeep1=beep_r;
//输出音乐
//时钟频率6MHz
regclk_6MHz;
reg[2:
0]cnt1;
always@(posedgeinclk)
if(cnt1<
3'
cnt1<
=cnt1+3'
b1;
begin
=3'
b0;
clk_6MHz<
=~clk_6MHz;
end
//时钟频率4MHz
regclk_4Hz;
reg[24:
0]cnt2;
if(cnt2<
25'
d13000000)//
cnt2<
=cnt2+25'
cnt2<
=25'
clk_4Hz<
=~clk_4Hz;
always@(posedgeclk_6MHz)
=count+1'
//计数器加1
if(count==origin)
h0;
//输出取反
always@(posedgeclk_4Hz)
case({high,med,low})
12'
b000000010000:
origin=11466;
//mid1
b000000100000:
origin=10216;
//mid2
b000000110000:
origin=9101;
//mid3
b000001000000:
origin=8590;
//mid4
b000001010000:
origin=7653;
//mid5
b000001100000:
origin=6818;
//mid6
b000000000101:
origin=14447;
//low5
endcase
always@(posedgeclk_4Hz)//歌曲<
<
twotiger>
>
if(state==63)state=0;
//计时,以实现循环演奏
else
state=state+1;
case(state)
0,1:
{high,med,low}=12'
b000000010000;
2,3:
{high,med,low}=12'
b000000100000;
4,5:
b000000110000;
//mid3
6,7:
8,9:
10,11:
12,13:
14,15:
16,17:
18,19:
b000001000000;
//mid4
20,21,22,23:
b000001010000;
//mid5
24,25:
26,27:
28,29,30,31:
32:
33:
{high,med,low}=12'
b000001100000;
//mid6
34:
35:
36,37:
38,39:
40:
41:
42:
43:
44,45:
46,47:
48,49:
50,51:
b000000000101;
52,53,54,55:
{high,med,low}=12'
56,56:
57,58:
59,60,61,62,63:
default:
{high,med,low}=12'
bx;
//bell2子模块《康定情歌》
modulebell2(inclk,beep2);
outputbeep2;
assignbeep2=beep_r;
d8)//8
d1*******)//13000000
case({high,med,low})
'
b000000000001:
origin=22900;
//低1
'
b000000000010:
origin=20408;
//低2
b000000000011:
origin=18181;
//低3
b000000