简易电子琴设计及FPGA功能验证 FPGA毕业课程设计 - 图文

更新时间:2024-05-22 00:03:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

西安邮电大学

FPGA课程设计报告

题 目: 简易电子琴设计及FPGA功能验证

院 系: 电子工程学院 专业班级: 微电子0901 导师姓名: 黄海生

2012年 6 月 29 日

目录

1.任务.. .......................................................................................................................... 2 2.目的 ............................................................................................................................ 2 3.使用环境 .................................................................................................................... 2 4.FPGA课程设计详细内容 ........................................................................................ 2

4.1 技术规范 ......................................................................................................... 2

4.1.1 总体描述 ............................................................................................... 2 4.1.2 结构框图 ............................................................................................... 2 4.1.3 引脚描述 ............................................................................................... 3 4.1.3 应用范围................................................................................................5 4.2 设计方案 ......................................................................................................... 5

4.2.1 顶层方案设计 ....................................................................................... 5 4.2.2 顶层模块程序 ....................................................................................... 7 4.3 功能验证方案及源程序 ................................................................................. 7 4.3.1按键输入控制模块方案设计及源程序.................................................7 4.3.2控制模块方案设计及源程序.................................................................8 4.3.3LCD驱动模块方案设计及源程序.......................................................11

4.4 电路设计及功能仿真报告 ........................................................................... 19 4.5 综合及布局布线报告和引脚分布报告 ....................................................... 21 4.6 硬件测试结果报告 ....................................................................................... 21 5.课程设计的心得体会 .............................................................................................. 22 6.参考资料 .................................................................................................................. 22

1. 任务:

a、设计一个简单电子琴。(内置2~4首简单音调曲)

b、用FPGA开发板的按键可选择演奏内置曲调,用数码管显示当前演奏的哪个演奏曲目或停止。

c、要求电子琴具有自主选择,自动播放所选曲目或停止曲目。

2. 目的:

a、在掌握计算机组成原理理论相关的基础上,了解 EDA技术,掌握

Verilog HDL 硬件描述语言的设计方法和思想,通过学习的 Verilog HDL 语言结合电子电路的设计知识理论联系实际,掌握所学的课程知识;

b、深入学习Verilog HDL、FPGA,了解其编程环境; c、学会运用Modelsim和Quartus II等编程仿真软件;

d、将硬件语言编程与硬件实物功能演示相结合,加深理解Verilog HDL、

FPGA的学习;

3. 使用环境 (软件硬件环境,设备等)

软硬件环境:

软件:Quartus II 7.2, Modelsim6.1; 硬件环境:DEII开发板;

设备:PC一台,USB下载线,FPGA开发板及电源。

在 EDA 软件平台上,根据硬件描述语言Verilog 完成的设计文件,自动的完成逻辑编译、化简、分割、综合及优化、布局布线、仿真、目标芯片的适配编译、逻辑映射和编程下载等工作。

Verilog HDL语言,用Modelsim进行前仿真,以及代码的生成,验证程序验证,也可进行综合。用Quartus II进行后仿真。

4. FPGA课程设计详细内容

4.1 技术规范 4.1.1 原理

简易电子琴的设计通过软硬件结合实现,硬件系统包括主控制器芯片、LED、蜂鸣器等,软件资源包括编写Verilog HDL程序的应用软件Modelsim和仿真软件Quartus II。电子琴有自动播放功能。

播放功能中有三首曲子。程序共有六个模块,分别为主模块、数码管显示模块、分频模块、计数器模块、存储器模块、音频输出模块。硬件实现是用一个数码管显示当前播放的曲目,另外四个按键key1、key2用来选择曲目。通过主模块调用各模块实现电子琴的功能。 乐曲演奏的原理:

乐曲演奏的原理:组成乐曲的每个音符的频率值(音调)以及持续时间(音长)是乐曲能持续演奏所需的两个基本数据,因此只要控制输出到扬声器的激励信号的频率的高低和持续的时间,就可以使扬声器发出持续的乐曲声。 ? 音调的控制

频率的高低决定了音调的高低。音乐的十二平均率规定:每两个八度音(如简谱中的中音1与高音1)之间的频率相差一倍。在两个八度音之间,又可分为十二个半音,每半个音的频率比为。另外,音名A(简谱中的低音6)的频率为440HZ,音名B到C之间,E到F之间为半音,其余为全音。由此可以计算出简谱中从低音1至高音1之间的每个音名对应的频率如图所示: 音名 低音1 低音2 低音3 低音4 低音5 低音6 低音7 频率(HZ) 261.6 293.7 329.6 349.2 392 440 音名 中音1 中音2 中音3 中音4 中音5 中音6 频率(HZ) 523.3 587.3 659.3 698.5 784 880 音名 高音1 高音2 高音3 高音4 高音5 高音6 频率(HZ) 1046.5 1174.7 1318.5 1396.9 1568 1760 中音7 高音7 493.9 987.8 1975.5 所有不同频率均从同一基准频率分频得到。将分频数四舍五入进行取整,并尽量减小误差。在本设计中选取5MHZ作为基准频率。从下表中可以看出最大分频系数为11468,采用14位二进制计数器分频可满足要求。此外还应给出预置数,对应不同的预置数,只需加载不同的预置数即可。采用加载预置数实现分频的方法比采用反馈复零法节省资源,实现起来更加容易。 分频比 预置数 6826 7871 8798 9224 音名 分频比 中音1 4777 中音2 4257 中音3 3792 中音4 3579 预置数 音名 分频比 预置数 13994 14255 14487 14593 14789 14963 15117 音名 低音1 9557 低音2 8512 低音3 7585 低音4 7159 低音5 6378 低音6 5682 低音7 5062 ? 音长的控制 11606 高音1 2389 12126 高音2 2128 12591 高音3 1896 12804 高音4 1790 13194 高音5 1594 13524 高音6 1420 13852 高音7 1266 10005 中音5 3189 10701 中音6 2841 11321 中音7 2531 音符的持续时间须根据音乐的速度及每个音符的节拍数来确定。如果设定全音符的持续时间为1S的话,假设产生4分音符,则产生四分频即可实现四分音符的时长,并提供4HZ分频器。如图为乐曲演奏的原理图,其中,乐谱产生电路用来控制音乐的音调和时长。控制音调通过设置计数器的预置数来实现,预置不同的数值会可以使计数器产生不同频率的信号,从而产生不同的音调。控制音长是通过控制计数器预置数的停留时间来实现的,预置数的停留时间越长,则该音符的演奏时间越长,如2分音符,在记谱时将该音符记录两次即可。

4.1.2总体方案

本次设计课程的目的是让我们在学习verilogHDL的基础上更加深入的了解硬件设计语言的

功能、作用及其特征,并且将我们的动手能力与创新能力结合起来。 本次试验的总体框图为:

设计框图说明

4.1.3引脚描述

信号名 输入输出 目标源 功能描述 CLK Input Pin 主时钟频率,5MHZ,占空比为1:1 DIR Input Pin 使能端,控制时钟产生,以及读写同步 OUT Output Pin 输出乐曲信号(方波形式) SCREEN Output Pin 数码管显示信号 4.1.4 顶层划分

顶层模块说明:

1. D触发器:实现信号读取,产生内部使能端,控制分频器;

2. 分频器: 实现与基准时钟同步操作,读取存储器数据进行分频操作,实现音调与音长的改变与输出;

3. 节拍发生器: 根据使能端,产生对应的频率产生对应音符时长; 4. 存储器:实现将预置数传送给分频器,实现曲目的不停音调和音长; 5. 2分频器:将产生的信号再次进行2分频;

注: 音名显示控制

音名显示电路用来显示演奏乐曲时对应的音乐曲曲目名。可以用三个数码管,

加以显示,本设计中使用HIGH[3:0],MED[3;0],LOW[3;0]等信号加以显示,为了能使其循环显示,需要一时长计数器,等音乐演奏完成后,保证自动从头开始演奏。

4.1.5子模块描述

<1> 按键接收器 D触发器 1、功能描述

运用D触发器和数据锁存器实现数据线输出的使能端。 2、管脚描述 信号名称 输入输出 源 目标 输入 DIR Pin 输出 DR Pin 3、实现说明:

功能描述 按键输入信号 使能端 ? 在按键信号产生后,进行信号的锁存和产生使能信号。

4、验证方案

? 正常的信号锁存,和信号转换; ? 是否实现正确使能输出; <2>节拍发生器 分频器 1、功能描述

根据信号的输入,对应产生对应曲目的节拍频率时钟用来读取存储器音调音长数据,产生不同的预置数 2、管脚描述 信号名称 DIR CLK CK 输入 输出 输入 输入 输出 源 PIN PIN PIN 目标 功能描述 按键输入 基准时钟频率 1位节拍频率时钟 3、实现说明

在CLK的上升沿,将锁存后的DIR信号输入到内部,并根据对应时钟节拍分频,产生对应节拍频率。 4、测试

略; <3> 分频器

1、功能描述

将基准时钟按照预置数的信息进行分频,且与时钟同步,并当使能端低电平时,停止输出,也可实现循环播放。

2、管脚描述 信号名称 输入输出 源 目标 功能描述 输入 使能端 DIR PIN 输入 基准频率 CK PIN 输入 预置数 VOICE PIN 输出 乐曲输出 SPEAK PIN ; 3、实现说明

通过计数器、存储器、D触发器,实现分频。当计数从预置数到初始值

时Speaker翻转一次,即为分频。

4、测试

用modelsim仿真,观察波形是否为所需方波; <4>存储器

1、功能描述

按照使能端的数据,选择对应的预置数据进行读操作,并且于时钟同步。

2、管脚描述 信号名称 输入输出 源 目标 功能描述 输入 使能端 DR PIN 输入 基准频率 CLK PIN 输出 读取的预置数 VOICE PIN 输出 数码管信号输SCREEN PIN 出 ; 3、实现说明

通过选择,在时钟的上升沿进行数据的读取,并将读出的数据同时传至数码管,与分频器。

4、测试

用modelsim仿真,观察预置数的值是否为对应曲目;

4.1.6 验证方案:

正常情况下,输入一个DIR的值,查看波形输出是否正常。改变DIR的值,再次查看波形输出是否正常,并且其频率是否满足上述的公式计算出的值。

4.1.7 应用范围:

简易电子琴可以应用于简单的设计中,亦可应用于娱乐方面。 4.2 设计方案

4.2.1顶层方案设计

顶层主要是对各个子模块进行调用与连接,顶层主要调用以下模块: (1)按键驱动模块

该模块用于选择所要播放曲目。 (2)控制模块:

该模块用于处理比较所选择的功能。 (3)数码管显示模块:

该模块用于显示用户是否登陆成功,即LCD驱动。 4.2.2顶层模块程序 信号定义与说明

CLK_4HZ: 用于控制音长(节拍)的时钟频率 clk_6MHZ:用于产生各种音阶频率的基准频率

speak:用于激励扬声器的输出信号,本例中为方波信号 low=0;

assign dir={key1,key0};

clock5mhz mhz(.clk(clk),.dir(dir),.clk_5MHZ(clk_5MHZ)); clock4hz

m(.dr(dr),.clk_5MHZ(clk_5MHZ),.clk_4HZ(clk_4HZ),.voice(voice),.speak(speak));

decode dec(.dir(dir),.decodeout(decodeout)); endmodule

信号定义与说明

CLK_4HZ: 用于控制音长(节拍)的时钟频率 clk_6MHZ:用于产生各种音阶频率的基准频率

speak:用于激励扬声器的输出信号,本例中为方波信号 voice={

if(counter==63) counter<=0; else counter<=counter+1; case(counter) 0: {

if(counter==195) counter<=0; else counter<=counter+1;

case(counter) 0: {

if(counter==103) counter<=0;

else counter<=counter+1; case(counter) 0: { if(dir==2'b00) clk_5MHZ<=0;

else if(cnt<4'b1010) cnt<=cnt+4'b0001; else begin

cnt<=4'b0000;

clk_5MHZ<=~clk_5MHZ; end end

endmodule

module clock4hz(clk_5MHZ,dir,ck,clk_4HZ);

时钟频率4Hz(基于clock6mhz分频后的时钟再次分频) input clk_5MHZ; input [1:0] dir; output clk_4HZ;

output ck;

wire clk_5MHZ,ck; wire [1:0] dir; reg clk_4HZ; reg [19:0] cnt;

assign ck=clk_4HZ;

always@(posedge clk_5MHZ) begin if(dir==2'b00) clk_4HZ<=0; else begin

cnt<=20'b0; clk_4HZ<=~clk_4HZ; end end

endmodule 触发器模块:

module D(dir,dr); input [1:0] dir; output dr; wire dr;

wire [1:0] dir;

assign dr=dir[0]|dir[1];

endmodule 数码管显示:

module decode(dir,decodeout); input[1:0] dir;

output[6:0] decodeout; reg [6:0] decodeout; wire [1:0] dir; always @(dir) begin

case(dir) endcase end

endmodule

分频器模块:

module main(dr,clk_5MHZ,clk_4HZ,voice,speak); input dr;

input clk_5MHZ;

input [11:0] voice; input clk_4HZ; output speak; wire dr;

wire clk_5MHZ,clk_4HZ; wire [11:0] voice; reg speak;

reg [13:0] divider,origin; wire carry;

assign carry=(divider==16383); always @(posedge clk_5MHZ) begin

if(carry) divider<=origin;

else divider=divider+1; end

always @(posedge carry) begin

speak<=~speak; end

always @(posedge clk_4HZ) begin

if(dr==1'b0) origin<=16383; case(voice)

default: origin<=16383; endcase end endmodule 激励

module epiano_tb;

reg clk50m,clk27m,rst,key1,key2; wire spk_out;

wire [6:0] key_display; e_piano

a(.clk50m(clk),.clk27m(clk27m),.spk_out(speak),.rst(rst),.key1(key1),.key2(key2),.key_display(key_display));

always #10 clk50m=~clk50m; always #20 clk27m=~clk27m; initial begin

clk50m=0;clk27m=0; #50 rst=0; #50 rst=1;

#1500 key1=0;key2=1; #2000 key1=1;key2=1; end endmodule

4.3 功能验证方案及源程序

①计数器模块

module counter(fenpin8,cout,rst,key1,key2); input fenpin8,rst,key1,key2; output [10:0]cout; reg [10:0] cout;

always @(posedge fenpin8 or negedge rst or negedge key1 or negedge key2)

begin

if(!rst)

cout<=11'd0; else

begin

if(!key1) begin

cout<=11'd0; end

else if(!key2) begin

cout<=11'd512; end

else if(!key3) begin

cout<=11'd1024; end

else if(!key4) begin

cout<=11'd1536; end else cout<=cout+1; end end

endmodule ②分频模块

module fenpin8(clk27m,rst,clk_8hz); input clk27m,rst; output clk_8hz; reg clk_8hz; reg [31:0] cnt;

always @(posedge clk27m or negedge rst) begin

if(!rst) begin cnt<=0;

clk_8hz<=0; end

else begin

if(cnt==N2)

begin cnt<=0; clk_8hz<=!clk_8hz; end

else

cnt<=cnt+1; end end

endmodule 激励

module fenpin8_tb; reg clk27m,rst; wire clk_8hz;

fenpin8 fenpin8_tb(.clk27m(clk27m),.clk_8hz(clk_8hz),.rst(rst));

always #50 clk27m=~clk27m; initial begin

clk27m=0; #20 rst=0; #80 rst=1; end

endmodule

module fenpin5m(clk50m,rst,clk_5m); input clk50m,rst; output clk_5m; reg clk_5m; reg [3:0] cnt; parameter N=10;

always @(posedge clk50m or negedge rst) begin

if(!rst) begin cnt<=0; clk_5m<=0; end

else begin

if(cnt==N2) begin cnt<=0;

clk_5m<=!clk_5m; end end end

endmodule 激励

module fenpin5m_tb; reg clk50m,rst; wire clk_5m;

fenpin5m fenpin5m_tb(.clk50m(clk50m),.clk_5m(clk_5m),.rst(rst));

always #50 clk50m=~clk50m; initial begin

clk50m=0; #20 rst=0; #80 rst=1; end

endmodule ③存数器模块

module music_rom ( address, clock, q);

input [10:0] address; input clock; output [7:0] q;

wire [7:0] sub_wire0;

wire [7:0] q = sub_wire0[7:0]; altsyncram altsyncram_component ( .clock0 (clock),

.address_a (address), .q_a (sub_wire0), .aclr0 (1'b0), .aclr1 (1'b0),

.address_b (1'b1),

.addressstall_a (1'b0), .addressstall_b (1'b0), .byteena_a (1'b1), .byteena_b (1'b1), .clock1 (1'b1),

.clocken0 (1'b1), .clocken1 (1'b1), .clocken2 (1'b1), .clocken3 (1'b1), .data_a ({8{1'b1}}), .data_b (1'b1), .eccstatus (), .q_b (),

.rden_a (1'b1), .rden_b (1'b1), .wren_a (1'b0), .wren_b (1'b0)); defparam

altsyncram_component.clock_enable_input_a = \ altsyncram_component.clock_enable_output_a = \ altsyncram_component.init_file = \

altsyncram_component.intended_device_family = \ altsyncram_component.lpm__mode = \

altsyncram_component.outdata_aclr_a = \ altsyncram_component.outdata_reg_a = \ altsyncram_component.widthad_a = 11, altsyncram_component.width_a = 8,

altsyncram_component.width_byteena_a = 1; endmodule 激励

module music_rom_tb; reg [8:0]address; reg clk;

wire [7:0]q;

music_rom music_rom_tb(.address(address),.clock(clk),.q(q)); always #50 clk=~clk; initial begin

clk=0;

#100 address=3; #100 address=12; #40 address=10; end

endmodule ④音频输出模块

module SPK_OUT(data,spk_out,clk_5m,clk_8hz); input [7:0]data;

input clk_5m,clk_8hz; output spk_out;

reg spk_out=0;

reg [13:0]reg_temp; reg [13:0] count=0;

always @(posedge clk_8hz) begin

case(data)

7'd0: reg_temp=16383; 7'd1: reg_temp=9557; 7'd2: reg_temp=8513; 7'd3: reg_temp=7584; 7'd4: reg_temp=7159; 7'd5: reg_temp=6378; 7'd6: reg_temp=5682; 7'd7: reg_temp=5061; 7'd8: reg_temp=4778; 7'd9: reg_temp=4257; 7'd10: reg_temp=3584; 7'd11: reg_temp=3579; 7'd12: reg_temp=3189; 7'd13: reg_temp=2841; 7'd14: reg_temp=2531; 7'd15: reg_temp=2389; 7'd16: reg_temp=2128; 7'd17: reg_temp=1810; 7'd18: reg_temp=1790; 7'd19: reg_temp=1594; 7'd20: reg_temp=1420; 7'd21: reg_temp=1265; default: reg_temp=16383; endcase end

always @(posedge clk_5m) begin

if(count>reg_temp) begin

count<=0;

spk_out<=~spk_out; end else

count<=count+1; end

endmodule 激励

module SPK_OUT_tb;

reg clk_5m,clk_8hz; reg [5:0]data; wire spk_out; SPK_OUT

uaa(.data(data),.clk_5m(clk_5m),.clk_8hz(clk_8hz),.spk_out(spk_out));

always #25 clk_5m=~clk_5m;

always #3000 clk_8hz=~clk_8hz; initial begin

clk_5m=0;clk_8hz=0; #3000 data=5; #6000 data=7; end

endmodule ⑤数码管显示模块

module shumaguan(key1,key2,key_display,rst); input key1,key2,rst;

output [6:0] key_display; reg [6:0] key_display;

always @(negedge rst or negedge key1 or negedge key2 ) begin

if(!rst) else begin

if(!key1)

else if(!key2) else if(!key3) else if(!key4) else end end

endmodule 激励

module shumaguan_tb; reg key1,key2,rst;

wire [6:0] key_display;

shumaguan

uaa(.key1(key1),.key2(key2),.rst(rst),.key_display(key_display));

initial begin

#20 key1=0;key2=1; #80 key1=1;key2=1; #450 key1=1;key2=1; #650 key1=1;key2=1; end endmodule

4.4 电路设计及功能仿真报告 主模块仿真结果:

输出模块仿真结果:

数码管模块仿真结果:

4.5 综合及布局布线报告和引脚分布报告 总体模块RTL View:

引脚分布报告:

4.6 硬件测试结果报告

硬件测试结果与预期结果一样,可实现简易电子琴的操作。

5.课程设计的心得体会

通过对测试结果的分析,我们发现采用FPGA所设计的电子琴系统设计趋于简单、开发时间短;外围器件少,体积小,抗干扰能力强,可靠性高;系统维护起来更方便、快捷.尤其对于设计者来说,不需要考虑太多的硬件设计,只需要有自己的设计思路,编程实现再用烧到FPGA器件中进行测试就可以了。电子琴作为一种乐器,成本不是很高,因此有一定的生产价值。

通过几个星期的繁忙工作,终于完成了简易电子琴的设计,这个课程设计使我受益匪浅,它使我了解了硬件设计的整个流程,并且加深了我对计算机组成原理这门的课内容的理解,通过这个课程设计,不仅使我了解了组成原理的脊髓,而且使我对VERILOG_HDL理解更加深刻,扩充的我的知识面。 这个课程设计同时培养了我的耐心和毅力,一个小小的错误就会导致结果出不来的情况,而对与错误的检查是需要有足够的耐心,由于这个课程设计也使我积累了一定的经验,相信这些经验在我以后的学习和工作中会有很大的作用。此课程设计也使我了解了VERILOG_HDL设计的方便和灵活性,这的确是我们

跨入计算机硬件行业很好的一次锻炼机会。

在本次课程设计的整个过程中,得到了黄海生老师的大力支持,在此感谢黄老师的细心讲解和耐心的指点。

6.参考资料等

①王金平,数字系统设计与verilog,电子工业出版社2008.

②夏宇闻,verilog数字系统设计教程,北京航空航天出版社,2008. ③杜慧敏,基于verilog的FPGA设计基础,西安电子科技大学,2005.

西安邮电大学 电子工程学院系FPGA课程设计过程考核表

学生姓名 进行时间 袁东明 班级学号 微电子090126 2012年 6 月 18 日 — 2012 年 6 月 29 日 与教学任务计划结合程度(10分) 学习内容(20分) 与专业培养结合程度(6分) 其它(4分) 接受单位评价 实践能力(10分) 学习态度(6分) 学习纪律(4分) 报告内容与实践过程紧密结合(15分) 报告鉴定 报告内容与教学计划内容紧密结合(15分) (60分) 报告质量(主题、结构、观点、逻辑、资料、字数 30分) 成绩鉴定 (20分) 评阅教师姓名 职称 成绩

本文来源:https://www.bwwdw.com/article/ld27.html

Top