职场文秘网

首页 > 领导讲话 > 组织讲话 / 正文

VerilogHDL乐曲演奏电路设计

2021-01-02 11:02:00

XX学院 Verilog HDL 乐曲演奏电路设计 专业:自动化 学号:
姓名:
设计目的与要求 1.课程设计目的:
1)加深对EDA技术的理解,掌握乐曲演奏电路的工作原理 2)了解怎样控制音调的高低变化和音长,从而完成乐曲的自动循环演奏。

3)培养自主学习、正确分析和解决问题的能力 2.课程设计要求:
1)使用Verilog HDL设计乐曲演奏电路,系统实现是用硬件描述语言Verilog HDL按分频控制的方式进行设计,然后进行编程、时序仿真、电路功能验证,奏出美妙的乐曲。

2) 通过控制输出到扬声器的激励信号频率的高低和持续的时间,从而使扬声器发出连续的乐曲声,且当乐曲演奏完成时,保证能自动从头开始演奏。

3.该方案可以实现的功能: 1)通过蜂鸣器播放音乐; 2)通过三位动态数码管输出相应的高中低音符; 3)通过一个开关实现两首乐曲的切换; 4)在音乐播放的同时,会有led流水灯的闪烁. 应用工具介绍 作为当今最流行的计算机软件系统,EDA技术是以计算机为工作平台,融合了应用电子技术、计算机技术、信息处理及智能化技术的最新成果,进行电子产品的自动设计。EDA可提供文本输入以及图形编辑的方法将设计者的意图用程序或者图形方式表达出来,而我们经常用到的VHDL语言便是用于编写源程序所需的最常见的硬件描述语言(HDL)之一。

2.1 EDA技术介绍 EDA是电子设计自动化(Electronic Design Automation)的缩写,在20世纪90年代初从计算机辅助设计(CAD)、计算机辅助制造(CAM)、计算机辅助测试(CAT)和计算机辅助工程(CAE)的概念发展而来。EDA技术是在电子CAD技术基础上发展起来的计算机软件系统,是指以计算机为工作平台,融合了应用电子技术、计算机技术、信息处理及智能化技术的最新成果,进行电子产品的自动设计[1]。

EDA技术就是以计算机为工具,设计者在EDA软件平台上,用硬件描述语言HDL完成设计文件,然后由计算机自动地完成逻辑编译、化简、分割、综合、优化、布局、布线和仿真,直至对于特定目标芯片的适配编译、逻辑映射和编程下载等工作。典型的EDA工具中必须包含两个特殊的软件包,即综合器和适配器。综合器的功能就是将设计者在EDA平台上完成的针对某个系统项目的HDL、原理图或状态图形描述,针对给定的硬件系统组件,进行编译、优化、转换和综合,最终获得我们欲实现功能的描述文件。综合器在工作前,必须给定所要实现的硬件结构参数,它的功能就是将软件描述与给定的硬件结构用一定的方式联系起来。也就是说,综合器是软件描述与硬件实现的一座桥梁。综合过程就是将电路的高级语言描述转换低级的、可与目标器件FPGA/CPLD相映射的网表文件。

在今天,EDA技术已经成为电子设计的普遍工具,无论设计芯片还是设计系统,没有EDA工具的支持,都是难以完成的。EDA工具已经成为设计师必不可少的武器,起着越来越重要的作用。从目前的EDA技术来看,其发展趋势是政府重视、使用普及、应用广泛、工具多样、软件功能强大。EDA技术发展迅猛,完全可以用日新月异来描述。EDA技术的应用广泛,现在已涉及到各行各业。EDA水平不断提高,设计工具趋于完美的地步。

2.2 Verilog HDL语言介绍 Verilog HDL是一种硬件描述语言,用于从算法级、门级到开关级的多种抽象设计层次的数字系统建模。被建模的数字系统对象的复杂性可以介于简单的门和完整的电子数字系统之间。数字系统能够按层次描述,并可在相同描述中显式地进行时序建模[2]。

作为一种通用化的硬件描述语言,Verilog HDL语言具有下述描述能力:设计的行为特性、设计的数据流特性、设计的结构组成以及包含响应监控和设计验证方面的时延和波形产生机制。所有这些都使用同一种建模语言。此外,Verilog HDL语言提供了编程语言接口,通过该接口可以在模拟、验证期间从设计外部访问设计,包括模拟的具体控制和运行[3]。

Verilog HDL语言不仅定义了语法,而且对每个语法结构都定义了清晰的模拟、仿真语义。因此,用这种语言编写的模型能够使用Verilog仿真器进行验证。语言从C编程语言中继承了多种操作符和结构。Verilog HDL提供了扩展的建模能力,其中许多扩展最初很难理解。但是,Verilog HDL语言的核心子集非常易于学习和使用,这对大多数建模应用来说已经足够。当然,完整的硬件描述语句足以对从最复杂的芯片到完整的电子系统进行描述。

Verilog HDL语言已经成为一种标准的硬件描述语言。它具有以下特点:
(1)作为一种多用途的硬件描述语言,它具有很好的易学性和易用性。

(2)Verilog HDL语言允许在同一个模块中进行不同抽象层次的描述。

(3)大多数逻辑综合工具都支持Verilog HDL,使得它成为设计人员的一个很好的选择。

(4)所有的制造厂商都提供了Verilog HDL的工艺库,用以支持仿真。

(5)Verilog HDL的程序语言接口拥有强大的功能,允许用户用C语言对内部数据结构进行描述[3]。

正是以上优点,使得Verilog HDL语言广泛流行。

下面是verilog的设计流程 Verilog的设计流程图 基本原理 乐曲演奏的原理是这样的:组成乐曲的每个音符的频率值(音调)及其持续的时间(音长)是乐曲能连续演奏所需的两个基本数据,因此只要控制输出到扬声器的激励信号频率的高低和持续的时间,就可以使扬声器发出连续的乐曲声[4]。

1、 音调的控制 频率的高低决定了音调的高低。音乐的十二平均率规定:每两个8度音(如简谱中的中音1与高音1)之间的频率相差一倍。在两个8度音之间,又可分为12个半音,每两个半音的频率比为12√2。 另外,音名A(简谱中的低音6)的频率为440Hz,音名B到C之间、E到F之间为半音,其余为全音[4]。由此可以计算出简谱中从低音1至高音1之间每个音名对应的频率,如表3.11所示:
表3.11 简谱中的音名与频率的关系 音名 频率/Hz 音名 频率/Hz 音名 频率/Hz 低音1 261.6 中音1 523.3 高音1 1046.5 低音2 293.7 中音2 587.3 高音2 1174.7 低音3 329.6 中音3 659.3 高音3 1318.5 低音4 349.2 中音4 698.5 高音4 1396.9 低音5 392 中音5 784 高音5 1568 低音6 440 中音6 880 高音6 1760 低音7 493.9 中音7 987.8 高音7 1975.5 所有不同频率的信号都是从同一个基准频率分频得到的。由于音阶频率多为非整数,而分频系数又不能为小数,故必须将计算得到的分频数四舍五入取整。若基准频率过低,则由于分频比太小,四舍五入取整后的误差较大;
若基准频率过高,虽然误差变小,但分频数将变大。实际的设计综合考虑这两方面的因素,在尽量减小频率误差的前提下取合适的基准频率[4]。本例中选取6MHz为基准频率。若无6MHz的基准频率,则可以先分频得到6MHz,或换一个新的基准频率。实际上,只要各个音名间的相对频率关系不变,演奏出的乐曲听起来都不会“走调“。

本例需要演奏的是梁祝乐曲,该乐曲各音阶频率及相应的分频比如表2所示。为了减小输出的偶次谐波分量,最后输出到扬声器的波形应为对称方波,因此在到达扬声器之前,有一个二分频的分频器。表2中的分频比就是从6MHz频率二分频得到的3MHz频率基础上计算得出的。由于最大的分频系数为9102,故采用14位二进制计数器分频可满足需要。在表2中,除给出了分频比以外,还给出了对应于各个音阶频率时计数器不同的预置数。对于不同的分频系数,只要加载不同的预置数即可。采用加载预置数实现分频的方法比采用反馈复零法节省资源,实现起来也容易一些,如表3.12所示:
表3.12 各音阶频率对应的分频比及预置数 音名 分频比 预置数 音名 分频比 预置数 低音3 9102 7281 中音2 5111 11272 低音5 7653 8730 中音3 4552 11831 低音6 6818 9565 中音5 3827 12556 低音7 6073 10310 中音6 3409 12974 中音1 5736 10647 高音1 2867 13516 此外,对于乐曲中的休止符,只要将分频系数设为0,即初始值为2141=16383即可,此时扬声器将不会发声。

2、 音长的控制 音符的持续时间必须根据乐曲的速度及每个音符的节拍数来确定。本例演奏的梁祝片段,最短的音符为4分音符,如果将全音符的持续时间设为1s的话,则只需要再提供一个4Hz的时钟频率即可产生4分音符的时长[4]。

如图3.2所示是乐曲演奏电路的原理框图,其中,乐谱产生电路用来控制音乐的音调和音长。控制音调通过设置计数器的预置数来实现,预置不同的数值可以使计数器产生不同频率的信号,从而产生不同的音调。控制音长是通过控制计数器预置数的停留时间来实现的,预置数停留的时间越长,则该音符演奏的时间越长。每个音符的演奏时间都是0.25s的整数倍,对于节拍较长的音符,如2分音符,在记谱时将该音名连续记录两次即可。

乐曲演奏电路的系统框图 音名显示电路用来显示乐曲演奏时对应的音符。可以用3个数码管,分别显示高、中、低音的音名,实现演奏的动态显示,十分直观。在本例中,high[3:0]、med[3:0]、low[3:0]等信号分别用于显示高音、中音、低音音符。为了使演奏能循环进行,需另外设置一个时长计数器,当乐曲演奏完成时,保证能自动从头开始演奏。

方案实现 由系统框图可以看到本方案分成8个模块。

1)48MHz分频成12MHz波形分频器,源代码和顶层模块如下 //48mhz分成12mhz的分频模块 module div_clk12mhz(clk_48mhz,clk_12mhz); input clk_48mhz; output clk_12mhz; reg clk_12mhz; reg [21:0] cnt; always @(posedge clk_48mhz) if(cnt<1) cnt=cnt+1; // (48mhz/12mhz=4,cnt<[4/2-1=1]) else begin cnt=0; clk_12mhz =!clk_12mhz; end endmodule 2)12MHz分频成6MHz波形分频器,源代码和顶层模块如下:
//12mhz分成6mhz的分频模块,提供给song模块 module div_clk6mhz(clk_12mhz,clk_6mhz); input clk_12mhz; output clk_6mhz; reg clk_6mhz; reg cnt; always @(posedge clk_12mhz) clk_6mhz=!clk_6mhz; endmodule 3)12MHz分频成4Hz波形分频器,源代码和顶层模块如下:
//12mhz分成4hz的分频模块,提供给song模块 module div_clk4hz(clk_12mhz,clk_4hz); input clk_12mhz; output clk_4hz; reg clk_4hz; reg [21:0] cnt; always @(posedge clk_12mhz) if(cnt<1499999) cnt=cnt+1; // (12mhz/4hz=3000000,cnt<[3000000/2-1=1499999]) else begin cnt=0; clk_4hz =! clk_4hz; end endmodule 4)12MHz分频成1mhz波形分频器,源代码和顶层模块如下:
//12mhz分成1mhz的分频模块,提供给quma模块 module div_clk1mhz(clk_12mhz,clk_1mhz); input clk_12mhz; output clk_1mhz; reg clk_1mhz; reg [21:0] cnt; always @(posedge clk_12mhz) if(cnt<5) cnt=cnt+1; // (12mhz/1mhz=12,cnt<[12/2-1=5]) else begin cnt=0; clk_1mhz =! clk_1mhz; end endmodule 5)12MHz分频成1khz波形分频器,源代码和顶层模块如下:
//12mhz分成1khz的分频模块,提供给quma模块 module div_clk1khz(clk_12mhz,clk_1khz); input clk_12mhz; output clk_1khz; reg clk_1khz; reg [21:0] cnt; always @(posedge clk_12mhz) if(cnt<5999) cnt=cnt+1; // (12mhz/1khz=12000,cnt<[12000/2-1=5999]) else begin cnt=0; clk_1khz =! clk_1khz; end endmodule 6) song模块源代码和顶层模块如下:
//音乐产生模块 module song(clk_6mhz,clk_4hz,speaker,high,med,low,k); //模块名为song(端口列表) input clk_6mhz,clk_4hz; input k; //定义两个输入端口 output speaker; //定义一个输出端口 output[3:0] high,med,low; reg[3:0] high,med,low; //定义了3个4位寄存器 reg[13:0] divider,origin; //定义了2个14位寄存器 reg[9:0] counter; //定义了1个10位寄存器 reg speaker; wire carry; assign carry=(divider==16383); //连续赋值语句 always @(posedge clk_6mhz) begin if(carry) divider<=origin; else divider<=divider+1; end always @(posedge carry) begin speaker<=~speaker;end //二分频产生方波信号 always @(posedge clk_4hz) begin case({high,med,low}) //分频比预置 'b000000000011:origin<=7281; //低音3 'b000000000101:origin<=8730; //低音5 'b000000000110:origin<=9565; //低音6 'b000000000111:origin<=10310; //低音7 'b000000010000:origin<=10647; //中音1 'b000000100000:origin<=11272; //中音2 'b000000110000:origin<=11831; //中音3 'b000001010000:origin<=12556; //中音5 'b000001100000:origin<=12974; //中音6 'b000001110000:origin<=13347; //中音7 'b000100000000:origin<=13516; //高音1 'b000000000000:origin<=16383; //休止符 endcase end always @(posedge clk_4hz) if (k==0) begin if(counter==149) counter<=0; //计时,以实现循环演奏 else counter<=counter+1; case(counter) //记谱 0: {high,med,low}<='b000000000011; //低音“3“ 1: {high,med,low}<='b000000000011; //持续4个时钟节拍 2: {high,med,low}<='b000000000011; 3: {high,med,low}<='b000000000011; 4: {high,med,low}<='b000000000101; //低音“5“ 5: {high,med,low}<='b000000000101; //发3个时钟节拍 6: {high,med,low}<='b000000000101; 7: {high,med,low}<='b000000000110; //低音“6“ 8: {high,med,low}<='b000000010000; //中音“1“ 9: {high,med,low}<='b000000010000; //发3个时钟节拍 10: {high,med,low}<='b000000010000; 11: {high,med,low}<='b000000100000; //中音“2“ 12: {high,med,low}<='b000000000110; //低音“6“ 13: {high,med,low}<='b000000010000; //中音“1“ 14: {high,med,low}<='b000000000101; //低音“5“ 15: {high,med,low}<='b000000000101; 16: {high,med,low}<='b000001010000; //中音“5“ 17: {high,med,low}<='b000001010000; //发3个时钟节拍 18: {high,med,low}<='b000001010000; 19: {high,med,low}<='b000100000000; //高音“1“ 20: {high,med,low}<='b000001100000; //中音“6“ 21: {high,med,low}<='b000001010000; //中音“5“ 22: {high,med,low}<='b000000110000; //中音“3“ 23: {high,med,low}<='b000001010000; //中音“5“ 24: {high,med,low}<='b000000100000; //中音“2“ 25: {high,med,low}<='b000000100000; //持续11个时钟节拍 26: {high,med,low}<='b000000100000; 27: {high,med,low}<='b000000100000; 28: {high,med,low}<='b000000100000; 29: {high,med,low}<='b000000100000; 30: {high,med,low}<='b000000100000; 31: {high,med,low}<='b000000100000; 32: {high,med,low}<='b000000100000; 33: {high,med,low}<='b000000100000; 34: {high,med,low}<='b000000100000; 35: {high,med,low}<='b000000110000; //中音“3“ 36: {high,med,low}<='b000000000111; //低音“7“ 37: {high,med,low}<='b000000000111; 38: {high,med,low}<='b000000000110; //低音“6“ 39: {high,med,low}<='b000000000110; 40: {high,med,low}<='b000000000101; //低音“5“ 41: {high,med,low}<='b000000000101; 42: {high,med,low}<='b000000000101; 43: {high,med,low}<='b000000000110; //低音“6“ 44: {high,med,low}<='b000000010000; //中音“1“ 45: {high,med,low}<='b000000010000; 46: {high,med,low}<='b000000100000; //中音“2“ 47: {high,med,low}<='b000000100000; 48: {high,med,low}<='b000000000011; //低音“3“ 49: {high,med,low}<='b000000000011; 50: {high,med,low}<='b000000010000; //中音“1“ 51: {high,med,low}<='b000000010000; 52: {high,med,low}<='b000000000110; //低音“6“ 53: {high,med,low}<='b000000000101; //低音“5“ 54: {high,med,low}<='b000000000110; //低音“6“ 55: {high,med,low}<='b000000010000; //中音“1“ 56: {high,med,low}<='b000000000101; //低音“5“ 57: {high,med,low}<='b000000000101; //持续8个时钟节拍 58: {high,med,low}<='b000000000101; 59: {high,med,low}<='b000000000101; 60: {high,med,low}<='b000000000101; 61: {high,med,low}<='b000000000101; 62: {high,med,low}<='b000000000101; 63: {high,med,low}<='b000000000101; 64: {high,med,low}<='b000000110000; //中音“3“ 65: {high,med,low}<='b000000110000; //发3个时钟节拍 66: {high,med,low}<='b000000110000; 67: {high,med,low}<='b000001010000; //中音“5“ 68: {high,med,low}<='b000000000111; //低音“7“ 69: {high,med,low}<='b000000000111; 70: {high,med,low}<='b000000100000; //中音“2“ 71: {high,med,low}<='b000000100000; 72: {high,med,low}<='b000000000110; //低音“6“ 73: {high,med,low}<='b000000010000; //中音“1“ 74: {high,med,low}<='b000000000101; //低音“5“ 75: {high,med,low}<='b000000000101; //持续4个时钟节拍 76: {high,med,low}<='b000000000101; 77: {high,med,low}<='b000000000101; 78: {high,med,low}<='b000000000000; //休止符 79: {high,med,low}<='b000000000000; 80: {high,med,low}<='b000000000011; //低音“3“ 81: {high,med,low}<='b000000000101; //低音“5“ 82: {high,med,low}<='b000000000101; 83: {high,med,low}<='b000000000011; //低音“3“ 84: {high,med,low}<='b000000000101; //低音“5“ 85: {high,med,low}<='b000000000110; //低音“6“ 86: {high,med,low}<='b000000000111; //低音“7“ 87: {high,med,low}<='b000000100000; //中音“2“ 88: {high,med,low}<='b000000000110; //低音“6“ 89: {high,med,low}<='b000000000110; //持续6个时钟节拍 90: {high,med,low}<='b000000000110; 91: {high,med,low}<='b000000000110; 92: {high,med,low}<='b000000000110; 93: {high,med,low}<='b000000000110; 94: {high,med,low}<='b000000000101; //低音“5“ 95: {high,med,low}<='b000000000110; //低音“6“ 96: {high,med,low}<='b000000010000; //中音“1“ 97: {high,med,low}<='b000000010000; //发3个时钟节拍 98: {high,med,low}<='b000000010000; 99: {high,med,low}<='b000000100000; //中音“2“ 100: {high,med,low}<='b000001010000; //中音“5“ 101: {high,med,low}<='b000001010000; 102: {high,med,low}<='b000000110000; //中音“3“ 103: {high,med,low}<='b000000110000; 104: {high,med,low}<='b000000100000; //中音“2“ 105: {high,med,low}<='b000000100000; 106: {high,med,low}<='b000000110000; //中音“3“ 107: {high,med,low}<='b000000100000; //中音“2“ 108: {high,med,low}<='b000000010000; //中音“1“ 109: {high,med,low}<='b000000010000; 110: {high,med,low}<='b000000000110; //低音“6“ 111: {high,med,low}<='b000000000101; //低音“5“ 112: {high,med,low}<='b000000000011; //低音“3“ 113: {high,med,low}<='b000000000011; //持续4个时钟节拍 114: {high,med,low}<='b000000000011; 115: {high,med,low}<='b000000000011; 116: {high,med,low}<='b000000010000; //中音“1“ 117: {high,med,low}<='b000000010000; //持续4个时钟节拍 118: {high,med,low}<='b000000010000; 119: {high,med,low}<='b000000010000; 120: {high,med,low}<='b000000000110; //低音“6“ 121: {high,med,low}<='b000000010000; //中音“1“ 122: {high,med,low}<='b000000000110; //低音“6“ 123: {high,med,low}<='b000000000101; //低音“5“ 124: {high,med,low}<='b000000000011; //低音“3“ 125: {high,med,low}<='b000000000101; //低音“5“ 126: {high,med,low}<='b000000000110; //低音“6“ 127: {high,med,low}<='b000000010000; //中音“1“ 128: {high,med,low}<='b000000000101; //低音“5“ 129: {high,med,low}<='b000000000101; //持续6个时钟节拍 130: {high,med,low}<='b000000000101; 131: {high,med,low}<='b000000000101; 132: {high,med,low}<='b000000000101; 133: {high,med,low}<='b000000000101; 134: {high,med,low}<='b000000110000; //中音“3“ 135: {high,med,low}<='b000001010000; //中音“5“ 136: {high,med,low}<='b000000100000; //中音“2“ 137: {high,med,low}<='b000000110000; //中音“3“ 138: {high,med,low}<='b000000100000; //中音“2“ 139: {high,med,low}<='b000000010000; //中音“1“ 140: {high,med,low}<='b000000000111; //低音“7“ 141: {high,med,low}<='b000000000111; 142: {high,med,low}<='b000000000110; //低音“6“ 143: {high,med,low}<='b000000000110; 144: {high,med,low}<='b000000000101; //低音“5“ 145: {high,med,low}<='b000000000101; //持续8个时钟节拍 146: {high,med,low}<='b000000000101; 147: {high,med,low}<='b000000000101; 148: {high,med,low}<='b000000000101; 149: {high,med,low}<='b000000000101; endcase end else if( k==1) begin if(counter==149) counter<=0; //计时,以实现循环演奏 else counter<=counter+1; case(counter) //记谱 0: {high,med,low}<='b000000110000; //中音“3“ 1: {high,med,low}<='b000000110000; //持续2个时钟节拍 2: {high,med,low}<='b000000100000; //中音2 3: {high,med,low}<='b000000100000; //持续2个时钟节拍 4: {high,med,low}<='b000000110000; //中音“3“ 5: {high,med,low}<='b000000110000; //发10个时钟节拍 6: {high,med,low}<='b000000110000; 7: {high,med,low}<='b000000110000; 8: {high,med,low}<='b000000110000; 9: {high,med,low}<='b000000110000; 10: {high,med,low}<='b000000110000; 11: {high,med,low}<='b000000110000; 12: {high,med,low}<='b000000110000; 13: {high,med,low}<='b000000110000; 14: {high,med,low}<='b000000100000; //中音2 15: {high,med,low}<='b000000100000; //持续2个时钟节拍 16: {high,med,low}<='b000000110000; //中音“3“ 17: {high,med,low}<='b000000110000; //发2个时钟节拍 18: {high,med,low}<='b000000100000; //中音2 19: {high,med,low}<='b000000100000; //中音2 20: {high,med,low}<='b000000010000; //中音“1“ 21: {high,med,low}<='b000000010000; 22: {high,med,low}<='b000000010000; 23: {high,med,low}<='b000000010000; 24: {high,med,low}<='b000000010000; 25: {high,med,low}<='b000000010000; 26: {high,med,low}<='b000000010000; 27: {high,med,low}<='b000000010000; 28: {high,med,low}<='b000000010000; 29: {high,med,low}<='b000000010000; 30: {high,med,low}<='b000000010000; 31: {high,med,low}<='b000000010000; 32: {high,med,low}<='b000000000110;//低6 33: {high,med,low}<='b000000000110; 34: {high,med,low}<='b000000010000; //中音“1“ 35: {high,med,low}<='b000000010000; 36: {high,med,low}<='b000000100000; //中2 有6个 37: {high,med,low}<='b000000100000; 38: {high,med,low}<='b000000100000; 39: {high,med,low}<='b000000100000; 40: {high,med,low}<='b000000100000; 41: {high,med,low}<='b000000100000; 42: {high,med,low}<='b000000110000; //中音3 43: {high,med,low}<='b000000110000; 44: {high,med,low}<='b000000100000; //中音“2“ 45: {high,med,low}<='b000000100000; 46: {high,med,low}<='b000000010000; //中音“1“ 47: {high,med,low}<='b000000010000; 48: {high,med,low}<='b000000000110; //低音“6“ 49: {high,med,low}<='b000000000110; 50: {high,med,low}<='b000000010000; //中音“1“ 51: {high,med,low}<='b000000010000; 52: {high,med,low}<='b000000000101; //低音“5“ 53: {high,med,low}<='b000000000101; //低音“5“ 54: {high,med,low}<='b000000000101; 55: {high,med,low}<='b000000000101; 56: {high,med,low}<='b000000000101; //低音“5“ 57: {high,med,low}<='b000000000101; 58: {high,med,low}<='b000000000101; 59: {high,med,low}<='b000000000101; 60: {high,med,low}<='b000000000101; 61: {high,med,low}<='b000000000101; 62: {high,med,low}<='b000000000101; 63: {high,med,low}<='b000000000101; 64: {high,med,low}<='b000000000101; 65: {high,med,low}<='b000000000101; 66: {high,med,low}<='b000000000101; 67: {high,med,low}<='b000000000101; 68: {high,med,low}<='b000000110000; //中音“3“ 69: {high,med,low}<='b000000110000; 70: {high,med,low}<='b000000100000; //中音“2“ 71: {high,med,low}<='b000000100000; 72: {high,med,low}<='b000000110000; //中音“3“ 73: {high,med,low}<='b000000110000; //中音“3“ 74: {high,med,low}<='b000000110000; //中音“3“ 75: {high,med,low}<='b000000110000; //中音“3“ 76: {high,med,low}<='b000000110000; //中音“3“ 77: {high,med,low}<='b000000110000; //中音“3“ 78: {high,med,low}<='b000000110000; //中音“3“ 79: {high,med,low}<='b000000110000; //中音“3“ 80: {high,med,low}<='b000000110000; //中音“3“ 81: {high,med,low}<='b000000110000; //中音“3“ 82: {high,med,low}<='b000000100000; //中音“2“ 83: {high,med,low}<='b000000100000; 84: {high,med,low}<='b000000110000; //中音“3“ 85: {high,med,low}<='b000000110000; //中音“3“ 86: {high,med,low}<='b000000100000; //中音“2“ 87: {high,med,low}<='b000000100000; //中音“2“ 88: {high,med,low}<='b000000010000; //中音“1“ 89: {high,med,low}<='b000000010000; //中音“1“ 90: {high,med,low}<='b000000010000; //中音“1“ 91: {high,med,low}<='b000000010000; //中音“1“ 92: {high,med,low}<='b000000010000; //中音“1“ 93: {high,med,low}<='b000000010000; //中音“1“ 94: {high,med,low}<='b000000010000; //中音“1“ 95: {high,med,low}<='b000000010000; //中音“1“ 96: {high,med,low}<='b000000010000; //中音“1“ 97: {high,med,low}<='b000000010000; //中音“1“ 98: {high,med,low}<='b000000010000; //中音“1“ 99: {high,med,low}<='b000000010000; //中音“1“ 100: {high,med,low}<='b000000010000; //中音“1“ 101: {high,med,low}<='b000000010000; //中音“1“ 102: {high,med,low}<='b000000010000; //中音“1“ 103: {high,med,low}<='b000000010000; //中音“1“ 104: {high,med,low}<='b000000010000; //中音“1“ 105: {high,med,low}<='b000000000110; //低音“6“ 106: {high,med,low}<='b000000000110; //低音“6“ 107: {high,med,low}<='b000000010000; //中音“1“ 108: {high,med,low}<='b000000010000; //中音“1“ 109: {high,med,low}<='b000000100000; //中音“2“ 110: {high,med,low}<='b000000100000; //中音“2“ 111: {high,med,low}<='b000000100000; //中音“2“ 112: {high,med,low}<='b000000100000; //中音“2“ 113: {high,med,low}<='b000000100000; //中音“2“ 114: {high,med,low}<='b000000100000; //中音“2“ 115: {high,med,low}<='b000000110000; //中音3 116: {high,med,low}<='b000000110000; 117: {high,med,low}<='b000000100000; //中音“2“ 118: {high,med,low}<='b000000100000; 119: {high,med,low}<='b000000010000; //中音“1“ 120: {high,med,low}<='b000000010000; 121: {high,med,low}<='b000000000110; //低音“6“ 122: {high,med,low}<='b000000000110; 123: {high,med,low}<='b000000010000; //中音“1“ 124: {high,med,low}<='b000000010000; 125: {high,med,low}<='b000000100000; //中音“2“ 126: {high,med,low}<='b000000100000; //中音“2“ 127: {high,med,low}<='b000000100000; //中音“2“ 128: {high,med,low}<='b000000100000; //中音“2“ 129: {high,med,low}<='b000000100000; //中音“2“ 130: {high,med,low}<='b000000100000; //中音“2“ 131: {high,med,low}<='b000000100000; //中音“2“ 132: {high,med,low}<='b000000100000; //中音“2“ 133: {high,med,low}<='b000000100000; //中音“2“ 134: {high,med,low}<='b000000100000; //中音“2“ 135: {high,med,low}<='b000000100000; //中音“2“ 136: {high,med,low}<='b000000100000; //中音“2“ 137: {high,med,low}<='b000000100000; //中音“2“ 138: {high,med,low}<='b000000100000; //中音“2“ 139: {high,med,low}<='b000000100000; //中音“2“ 140: {high,med,low}<='b000000100000; //中音“2“ 141: {high,med,low}<='b000000110000; //中音“3“ 142: {high,med,low}<='b000000110000; //持续2个时钟节拍 143: {high,med,low}<='b000000100000; //中音2 144: {high,med,low}<='b000000100000; //持续2个时钟节拍 145: {high,med,low}<='b000000110000; //中音“3“ 146: {high,med,low}<='b000000110000; //发10个时钟节拍 147: {high,med,low}<='b000000110000; 148: {high,med,low}<='b000000110000; 149: {high,med,low}<='b000000110000; endcase end endmodule //模块结束 7)取码模块源代码和顶层模块如下:
//取码模块,从song模块取得数码管显示部分的位码和段码 module quma(high,med,low,clk_1mhz,dig,duan); input [3:0] high,med,low; input clk_1mhz; reg[7:0] dig; output [7:0]dig;//定义输出八位位码 reg [7:0] duan; output [7:0] duan; //定义用于输出的段码的代码 always @(posedge clk_1mhz)//扫描high,med,low三个寄存器的值,取出位码和段码的代码 begin if (high!=0) //如果high的值不为0,则只输出high的值 begin dig<=8'b11111011; case (high) 1:duan<=8'b00000001; 2:duan<=8'b00000010; 3:duan<=8'b00000011; 4:duan<=8'b00000100; 5:duan<=8'b00000101; 6:duan<=8'b00000110; 7:duan<=8'b00000111; endcase end else if (med!=0) // 如果med的值不为0,则只输出med的值 begin dig<=8'b11111101; case (med ) 1:duan<=8'b00000001; 2:duan<=8'b00000010; 3:duan<=8'b00000011; 4:duan<=8'b00000100; 5:duan<=8'b00000101; 6:duan<=8'b00000110; 7:duan<=8'b00000111; endcase end else if (low!=0) //如果low的值不为0,则只输出low的值 begin dig<=8'b11111110; case (low ) 1:duan<=8'b00000001; 2:duan<=8'b00000010; 3:duan<=8'b00000011; 4:duan<=8'b00000100; 5:duan<=8'b00000101; 6:duan<=8'b00000110; 7:duan<=8'b00000111; endcase end end endmodule 8)disp:显示模块,每位输出转换为七段数码管显示。源代码和顶层模块如下:
//动态数码管显示模块 module disp(duan,clk_1khz,seg); input [7:0]duan; input clk_1khz; output [7:0]seg; reg [7:0]seg; always @(posedge clk_1khz) begin case(duan) 1:seg=8'b11111001; 2:seg=8'b10100100; 3:seg=8'b10110000; 4:seg=8'b10011001; 5:seg=8'b10010010; 6:seg=8'b10000010; 7:seg=8'b11111000; default: seg=8'b11111001; endcase end endmodule 方案测试 顶层图形文件建立后,对系统进行仿真,由于仿真时对输入输出信号的频率有要求,所以先对每个模块进行仿真。

1) 48MHz分频成12MHz波形模块,仿真波形如下:
2) 12MHz分频成6MHz波形模块,仿真波形如下:
3)12MHz分频成1MHz波形模块,仿真波形如下:
4)12MHz分频成4Hz波形模块,仿真波形如下:
5)12MHz分频成1khz波形模块,仿真波形如下:
6)音乐发生器模块,仿真波形如下:
7)取码模块,仿真波形如下:
8)显示模块,仿真波形如下:
引脚锁定:
待各个功能模块波形仿真通过后,画出原理图,仿真完毕,接下来开始引脚锁定:引脚锁定列表如下表所示:
端口名称 引脚位置 端口名称 引脚位置 clk_48mhz N2 Dig[7] M4 Speaker F18 Seg[0] J8 Dig[0] L6 Seg[1] M3 Dig[1] K5 Seg[2] K6 Dig[2] G3 Seg[3] J6 Dig[3] G4 Seg[4] U10 Dig[4] J3 Seg[5] N9 Dig[5] K4 Seg[6] L10 Dig[6] L3 Seg[7] L9 k L25 引脚锁定后下载程序:
安装usb-blaster驱动程序。配置JTAG文件,下载程序到试验箱FPGA芯片中进行调试,仿真和修改直到得到预期的仿真结果。

附录一:乐曲演奏电路设计原理图及其生成的顶层文件 由原理图生成文本文件,源程序和如下: // Copyright (C) 1991-2006 Altera Corporation // Your Use Of Altera Corporation's Design Tools, Logic Functions // And Other Software And Tools, And Its Ampp Partner Logic // Functions, And Any Output Files Any Of The Foregoing // (Including Device Programming Or Simulation Files), And Any // Associated Documentation Or Information Are Expressly Subject // To The Terms And Conditions Of The Altera Program License // Subscription Agreement, Altera Megacore Function License // Agreement, Or Other Applicable License Agreement, Including, // Without Limitation, That Your Use Is For The Sole Purpose Of // Programming Logic Devices Manufactured By Altera And Sold By // Altera Or Its Authorized Distributors. Please Refer To The // Applicable Agreement For Further Details. Module Block1( Clk_48mhz, Speaker, Dig, Seg ); Input Clk_48mhz; Output Speaker; Output [7:0] Dig; Output [7:0] Seg; Wire Synthesized_Wire_12; Wire Synthesized_Wire_4; Wire [6:0] Synthesized_Wire_5; Wire Synthesized_Wire_6; Wire Synthesized_Wire_7; Wire Synthesized_Wire_8; Wire [3:0] Synthesized_Wire_9; Wire [3:0] Synthesized_Wire_10; Wire [3:0] Synthesized_Wire_11; Div_Clk12mhz B2v_Inst(.Clk_48mhz(Clk_48mhz), .Clk_12mhz(Synthesized_Wire_12)); Div_Clk1khz B2v_Inst1(.Clk_12mhz(Synthesized_Wire_12), .Clk_1khz(Synthesized_Wire_4)); Div_Clk1mhz B2v_Inst2(.Clk_12mhz(Synthesized_Wire_12), .Clk_1mhz(Synthesized_Wire_8)); Div_Clk4hz B2v_Inst3(.Clk_12mhz(Synthesized_Wire_12), .Clk_4hz(Synthesized_Wire_7)); Div_Clk6mhz B2v_Inst4(.Clk_12mhz(Synthesized_Wire_12), .Clk_6mhz(Synthesized_Wire_6)); Disp B2v_Inst5(.Clk_1khz(Synthesized_Wire_4), .Duan(Synthesized_Wire_5),.Seg(Seg)); Song B2v_Inst6(.Clk_6mhz(Synthesized_Wire_6), .Clk_4hz(Synthesized_Wire_7),.Speaker(Speaker),.High(Synthesized_Wire_9),.Low(Synthesized_Wire_10),.Med(Synthesized_Wire_11)); Quma B2v_Inst9(.Clk_1mhz(Synthesized_Wire_8), .High(Synthesized_Wire_9),.Low(Synthesized_Wire_10),.Med(Synthesized_Wire_11),.Dig(Dig),.Duan(Synthesized_Wire_5)); Endmodule 实训心得 经过2个周的实训,我深刻体会到了自己知识的匮乏原来,我们学习的只是一个理论知识,通过这次实习。使我的理论知识上升到了一个实践的过程。同时在实践中也加深了我们对理论知识的理解。另外,这次实习不仅使我的verilog有一个很大的提高,而且还使我 学到了许多其他方面的知识,提高了我的动手能力。

在本次实训中,我们遇到了不少问题,其中就是由12mhz分频4hz的时候仿真波形不能仿真出来,经过一步一步的分析才发现,原来我们设置的endtime时间太长,本来想仿真出多个波形,便于观察设置了10s,结果仿真到百分之49然后就仿真不动了。经过调试设置了0.5秒,这样经过十几分钟的仿真,把仿真波形给调试出来了。其次,在编程的时候,程序综合也出现了好多错误,比如在song模块中阻塞非阻塞赋值同时出现在一个程序中,在显示模块中,开始编写的是七位二进制共阴数码管,结果在硬件测试的时候数码管显示不正常,才发现小数点没有赋值,而且数码管是共阳的,经过调试和修改程序,成功的使高中低音调和音节显示出来。再次,在想编译2首歌,用switch切换演唱不同歌曲时,经过我们小组成员共同研究歌谱和例子进行对比,经过一下午写出了两只蝴蝶的程序,经过修改song程序,成功的进行了仿真。最后,再用点阵显示歌名的时候,发现芯片点阵输出引脚只有3个,经过老师的分析讲解,让我们又学会了一个新的程序。an 通过这次实习,不仅使我们对所学过的知识有了一个新的认识。而且提高了我考虑问题,分析问题的全面性以及动手操作能力。培养了我的团队合作精神、学以致用的意识以及做事情要规范的认真态度。使我的综合能力有了一个很大的提高。总之,课程设计是一个学习新知识、巩固加深所学课本理论知识的过程,它培养了我们综合运用知识的能力,思考和解决问题的能力。它不仅加深了我对电子技术课程的理解,还让我感受到了设计电路的乐趣。不怕麻烦,反复设计、绘图与修改,就是希望能把这次课程设计做好。因此对我来说,这次课程设计是非常有意义的

Tags: 乐曲   演奏   电路设计  

搜索
网站分类
标签列表