第一章 绪论
1.1 EDA简介
EDA 技术就是依赖功能强大的计算机,在EDA工具软件平台上,对以硬件描述语言HDL为系统逻辑描述手段完成的设计文件,自动地完成逻辑编译、化简、分割、综合、布局布线以及逻辑优化和仿真测试,直至实现既定的电子线路系统功能。EDA技术使得设计者的工作仅限于利用软件的方式,即利用硬件描述语言和EDA软件来完成对系统硬件功能的实现,这是电子设计技术的一个巨大进步。EDA技术在进入21世纪后,得到了更大的发展。嵌入式处理器软核的成熟,使得SOPC步入大规模应用阶段。电子技术领域全方位融入EDA技术,除了日益成熟的数字技术外,传统的电路系统设计建模理念发生了重大的变化。同时,EDA使得电子领域各学科的界限更加模糊,更加互为包容。这些都利于设计人员利用EDA技术进行电子系统设计,如全定制或半定制ASIC设计,FPGA/CPLD开发应用和印制电路板。从EDA技术的特点不难看出,相比于传统的数字电子系统或IC设计,EDA技术拥有独特的优势。在传统的数字电子系统或IC设计中,手工设计占了较大的比例。因此,也存在很多缺点。例如:复杂电路的设计、调试十分困难;由于无法进行硬件系统仿真,如果某一过程存在错误,查找和修改十分不便;设计过程中产生大量文档,不易管理;可移植性差等。相比之下,EDA技术有很大不同。它运用HDL对数字系统进行抽象的行为与功能描述到具体的内部线路结构描述,从而可以在电子设计的各个阶段、各个层次进行计算机模拟验证,保证设计过程的正确性,可以大大降低设计成本,缩短设计周期。由于有各类库的支持,能够完成各种自动设计过程。它极大地简化了设计文档的管理,逻辑设计仿真测试技术也日益强大。VHDL在现在的EDA设计中使用最多,也拥有几乎所有主流EDA工具的支持。
EDA技术在硬件实现方面融合了大规模集成电路制造技术,IC版图设计,ASIC测试和封装以及FPGA/CPLD编程下载和自动测试等技术;在计算机辅助工程方面融合了计算机辅助设计(CAD),计算机辅助制造(CAM),计算机辅助测试(CAT),计算机辅助工程(CAE)技术以及多种计算机语言的设计概念;
1.2芯片介绍
主流产品:ALTERA公司 、FLEX公司
产品类型:CPLD:EPROM类型,掉电后程序不丢失。
FPGA:SRAM类型,掉电后程序丢失,必须重新编程。
工作电压:5V/3.3V/2.5V/1.8V/1.5V
目前主要产品
MAX7000S/AE,MAX3000A系列、FLEX10KE/ACEX1K系列
APEX20K/20KE系列、APEXII系列、Stratix系列
Cyclone(飓风) 系列、Excalibur系列
1.3 Cyclone(飓风)系列介绍
Altera最新一代SRAM工艺中等规模FPGA:
与Stratix结构类似,是一种低成本FPGA系列:
是目前主流产品,其配置芯片业改用新的产品
可支持多种扩展模块
摄像头模块
VGA模块
2.4寸彩屏
3.2寸彩屏
7寸高清大屏
以太网模块
网口模块
USB模块
高速AD DA
第二章 模块介绍
2.1设计分析根据设计要求,由于乐曲自动演奏机和硬件电子琴的设计已经存在,我们对已有的设计进行修改,形成两个不同功能的模块,然后采用元件例化,拼接两个模块,同时附加一个选择功能模块,以实现乐曲自动演机和硬件电子琴两个功能。 2.2硬件电子琴分析对于硬件电子琴,参考了实验时使用的程序,已经达到的要求有: (1)按下key1~key7 分别表示中音的DO、 RE 、 ME、 FA、 SOL、 LA、 S; (2)按下相应的键有对应LED灯指示。 2.3 乐曲自动演奏机分析对于乐曲自动演奏机,参考了实验时使用的程序,已经达到的要求有: (1)可以在电路上能自动演奏乐曲,在这里我们采用的是贝多芬的《欢乐颂》 (2)有相应的LED灯指示高低音。 而对于其他要求: (1)晶振为12 MHz. (2)采用CPLD 器件为ALTERA 的EPM7064SL-44。 我们在实验箱验证时,先按照实验箱芯片和晶振进行就修改,在实验箱上确认实验相应功能之后,我们在对应模块的频率数值进行修改,并在对管脚重新锁定即可 2.4整体设计分析整体设计要求:用key8实现两个功能切换。添加一个选择器,以实现两个功能切换。当key8键没有按下时,电路实现硬件电子琴功能,当key8键按下之后,电路实现乐曲自动演奏机。由于不存在现成可以借鉴的,于是,课程设计任务重心就放在了选择器模块的编写以及整体电路的合成上。 顶层模块输入输出: 图2-1 顶层文件图形 管脚说明:输入:时钟信号——clk ,按键——[6:0]key ,功能切换键——key7 输出:LED灯——[6:0]led ,蜂鸣器——beep; Key0: DO key1: RE key2: ME key3:FA key4: SOL key5: LA key6: SI key7:功能切换键 2.5 设计流程
第三章 功能划分与模块划分3.1自动演奏模块自动演奏模块功能:在按下key7键后,实现可以自动播放乐曲的功能。 3.2 自动演奏设计方案(1)根据乐曲自动演奏的基本原理设计出适合EDA多功能试验箱的源程序,通过分频模块得到12MHZ的晶振;源程序编写完成,编译调试后,在实验箱上验证其功能; (2)验证模块是否能完成实践要求的所有功能;然后去掉分频模块,将功能模块做适当的修改,编译调试成功后,将其下载到CPLD实验板上。 方案设计步骤: (1)在Quartus Ⅱ中建立一个工程项目文件song.qpf,并在该项目下新建Verilog HDL源程序文件song.v输入程序代码并保存。完整的Verilog HDL程序参考程序清单。 (2)然后在该工程选择目标器件并对相应的引脚进行锁定,在这里所选择器件为Alter公司的EPM7064SL-44芯片。 (3)对该工程文件进行全程编译处理,若在编译中发现错误,则找出错误并更正,直到编译成功。 (4)最后拿出下载电缆,将此电缆的两端分别接到PC机的打印机并口和核心板上的JTAG 接口上,打开电源执行下载命令,把程序下载到CPLD器件中。此时可以得到《欢乐颂》乐曲的演奏以及LED灯的明灭指示其高低音。 3.3硬件电子琴模块硬件电子琴模块功能:在按下功能切换键key7后,可以实现电子琴功能,即按下key1 到key7的过程中发出相应的高低音。 3.3.1硬件电子琴设计方案(1)根据硬件电子琴演奏的基本原理设计出适合EDA多功能试验箱的源程序,通过分频模块得到12MHZ的晶振;源程序编写完成,编译调试后,在实验箱上验证其功能; (2)验证模块是否能完成实践要求的所有功能;然后去掉分频模块,将功能模块做适当的修改后,编译调试成功后,将其下载到CPLD实验板上。 3.3.2设计步骤(1)在Quarters II中建立一个工程项目文件beep1.qpf。并在该项目下新建Verilog HDL源程序文件beep1.v,输入程序代码并保存,进行综合编译,若在编译中发现错误,则找出并更正错误,直至编译成功为止。 (2)选择目标器件并进行引脚锁定。将未使用的管脚设置为三态输入。 (3)对该工程文件进行全程编译处理。若在编译过程中发现错误,则找出并更正错误,直到编译成功为止。 (4)将产生的beep1.sof输出对FPGA进行配置。按下按键KEY1~KEY8就可以开始使用电子琴来演奏音乐了。
第四章 课程设计原理4.1硬件电子琴设计原理乐曲演奏的原理是:由于组成乐曲的每个音符的频率值(音调)及其持续时间(音长)是乐曲演奏的2个基本数据,因此需要控制输出到扬声器的激励信号的频率高低和该频率信号持续的时间。频率的高低决定了音调的高低,而乐曲的简谱与各音名的频率对应关系在后面将给出。所有不同频率的信号都是从一基准频率分频而得来的,由于音阶频率多为非整数,而分频系数有不能为小数,故必须将计算得到的分频数进行向下取整,基准频率和分频系数应综合考虑加以选择,从而保证音乐不会走调。如在48MHz 时钟下,中音1(对应的频率值是523.3Hz)的分频系数应该为:48000000/(2*523.3)=45863,这样只需对系统时钟进行45863次分频即可得到所要的中音M1(分频系数计算公式为D=F/2K,由于F/2K之后,会使分频系数D变小,所以功能模块中语句:beep_r<=!beep_r,使得输出取反,K=F/2count_end,消除了前面除以2K的影响) 。 4.2乐曲自动演奏设计原理硬件电路和自动演奏的原理同硬件电子琴实验原理类似。至于其他音符,同样可由一式求出对应的分频系数。在程序中设置一个状态机,每250ms改变一个状态(即一个节拍),组成乐曲的每个音符的频率值(音调)相对应于状态机的每一个状态。只要让状态机的状态按顺序转换,就可以自动演奏播放音乐了。 《欢乐颂》乐曲的简谱如图所示: 图4-1《欢乐颂》简谱图 4.3各模块的实现方法4.3.1选择器模块实现方法我们可以对输出进行控制。即让两个模块都工作,但是输出的部分添加选择器,有选择输出信号。当KEY8没有按下时,硬件电子琴的模块输出接到蜂鸣器和LED灯;当KEY8按下时,乐曲自动演奏模块输出接到蜂鸣器和LED灯。从输出进行控制,通过将蜂鸣和LED灯的输入和两个模块的输出有选择的匹配进行切换。通过编译下载到实验箱验证可以实现功能,而且在两种状态的切换时,不会出现无法控制的状况。 4.3.2自动演奏模块实现方法通过参照实验课本,我们根据相关实验对试验程序进行了简单修改,得到了本次自动演奏模块的歌曲《欢乐颂》,实现其自动演奏功能。 对于自动演奏模块而言,要实现其功能,只需要在顶层模块中添加触发自动演奏模块的触发点,在本程序中,即按下key8按键,屏蔽掉硬件电子琴的时钟信号,而使自动演奏模块的电子时钟信号作为使能信号。 在自动演奏模块中,首先计算出各个音符所对应的参数,对参数进行定义和设计。通过对晶振的控制实现每个音响应时间的长短并且可以修改相关参数实现音长的改变。演奏过程中,设置循环体,即每次演奏结束,可以再从头开始演奏,从而实现自动演奏的自动功能。程序中可以设置每次循环时间,也可以设置循环中断。每个音符都需要驱动蜂鸣器实现其功能。 最后,自动演奏模块中,需要有LED灯的指示,对于这样的要求,我们在程序最后添加了assign赋值语句。实现了每个音符响时对应的LED灯点亮。对于在实验中没有出现的音符所对应的LED灯则设置为高阻态,从而屏蔽LED灯点亮。 在程序中,通过控制TIME从而得到每个音阶所响应的时间,不同晶振所对应的的时间为1s,对应的时间可以控制振荡次数实现控制时间的长短。 if(state == 8'd125) state = 8'd0;语句实现的是自动演奏循环和实现歌曲演奏长短。通过系应该参数从而使歌曲唱到想要唱到的部分。 4.3.3硬件电子琴模块实现方法在原理部分我们已经知道了硬件电子琴和自动演奏乐曲的原理是相同的,因此在知道了如何实现乐曲演奏模块的方法后,对于硬件电子琴只需要实现同样的方法,就可以实现其模块功能,只不过在硬件电子琴模块中,需要的是利用按键实现其功能。对于每一个按键,在程序中设置各按键所对应的参数即可实现硬件电子琴的功能。 硬件电子琴的功能实现主要靠蜂鸣器和系数得到实现。在试验程序的基础上进行修改系数而得到。控制程序的循环体部分实现了计数和完成清零的操作。通过assign赋值语句实现LED灯的操作,在这里,我们添加了数码管的功能,从而实现了再按下按键的同时,实现数码管显示相对应的音阶大小。
第五章 实验箱设计
5.1硬件电子琴模块程序图5-1 硬件电子琴模块图 module beep1(clk,key,beep,led); //模块名称beep input clk; //系统时钟48MHz input[6:0]key; //按键输入 output beep; //蜂鸣器输出端 output[6:0]led; //LED输出 reg beep_r; //寄存器 reg[15:0]count,count_end; reg[6:0]key_r; reg [13:0]a; //消抖寄存器 always@(posedge clk) begin count <= count + 1'b1; //计数器加1 if((count == count_end)&(!(count_end == 16'hffff))) begin count <= 16'h0; //计数器清零 beep_r <= !beep_r; //取反输出信号 end end always @(key) begin a=2000; //消抖等待时间 key_r = key; //取键值 case(key_r) 7'b1111110:begin while(a>0) begin a=a-1; end count_end = 16'hb327; while(a>0) begin a=a-1; end end 7'b1111101:begin while(a>0)begin a=a-1 ;end count_end = 16'h9fa0;while(a>0)begin a=a-1; end end //中音2的分频系数值 7'b1111011:begin while(a>0)begin a=a-1 ;end count_end = 16'h8e32;while(a>0)begin a=a-1; end end //中音3的分频系数值 7'b1110111:begin while(a>0)begin a=a-1 ;end count_end16'h8637;while(a>0)begin a=a-1; end end//中音4的分频系数值 7'b1101111:begin while(a>0)begin a=a-1 ;end count_end = 16'h7794;while(a>0)begin a=a-1; end end //中音5的分频系数值 7'b1011111:begin while(a>0)begin a=a-1 ;end count_end = 16'h6a88;while(a>0)begin a=a-1; end end //中音6的分频系数值 7'b0111111:begin while(a>0)begin a=a-1 ;end count_end = 16'h5ee8;while(a>0)begin a=a-1; end end //中音7的分频系数值 default: begin while(a>0)begin a=a-1 ;end count_end = 16'hffff;while(a>0)begin a=a-1; end end endcase end assign beep =beep_r; //输出音乐 assign led =key_r; //输出按键状态 endmodule 5.2乐曲自动演奏机程序图5-2 乐曲自动演奏模块图 module song(clk,beep,led); //模块名称 input clk; //系统时钟48Mhz output beep; //蜂鸣器输出端 output[7:0] led; reg beep_r; //寄存器 reg[7:0] state; //乐谱状态机 reg[15:0]count,count_end; reg[23:0]count1; //乐谱参数:D=F/2K (D:参数,F:时钟频率,K:音高频率) //以下是12MHZ晶振状态下的各音高对应的参数 /*parameter L_5 = 16'h3bca, //低音5 M_1 = 16'h2cc9, //中音1 M_2 = 16'h27f8, //中音2 M_3 = 16'h238c, //中音3 M_4 = 16'h218d, //中音4 M_5 = 16'h1de5, //中音5 M_6 = 16'h1aa2; //中音6 parameter TIME = 3000000; //控制每一个音的长短(250ms)*/ //乐谱参数:D=F/2K (D:参数,F:时钟频率,K:音高频率) parameter L_5 = 16'd61224, //低音5 M_1 = 16'd45863, //中音1 M_2 = 16'd40864, //中音2 M_3 = 16'd36402, //中音3 M_4 = 16'd34359, //中音4 M_5 = 16'd30612; //中音5 parameter TIME = 12000000; //控制每一个音的长短(250ms) assign beep = beep_r; //输出音乐 ,蜂鸣器 always@(posedge clk) begin count <= count + 1'b1; //计数器加1 if(count == count_end) begin count <= 16'h0; //计数器清零 beep_r <= !beep_r; //输出取反 end end always @(posedge clk) begin if(count1 < TIME) //一个节拍250mS count1 = count1 + 1'b1; else begin count1 = 24'd0; if(state == 8'd125) //控制歌曲循环播放时间 state = 8'd0; //循环从头开始 else state = state + 1'b1; //循环结构体 begin case(state) 8'd0,8'd1: count_end = M_3;//中音"3",持续2个节拍 8'd2,8'd3: count_end = M_3;//中音"3",持续2个节拍 8'd4,8'd5: count_end = M_4;//中音"4",持续2个节拍 8'd6,8'd7: count_end = M_5; 8'd8,8'd9: count_end = M_5; 8'd10,8'd11: count_end = M_4; 8'd12,8'd13: count_end = M_3; 8'd14,8'd15: count_end = M_2; 8'd16,8'd17: count_end = M_1; 8'd18,8'd19: count_end = M_1; 8'd20,8'd21: count_end = M_2; 8'd22,8'd23: count_end = M_3; 8'd24,8'd25,8'd26: count_end = M_3; 8'd27: count_end = M_2; 8'd28,8'd29,8'd30,8'd31: count_end = M_2; 8'd32,8'd33: count_end = M_3; 8'd34,8'd35: count_end = M_3; 8'd36,8'd37: count_end = M_4; 8'd38,8'd39: count_end = M_5; 8'd40,8'd41: count_end = M_5; 8'd42,8'd43: count_end = M_4; 8'd44,8'd45: count_end = M_3; 8'd46,8'd47: count_end = M_2; 8'd48,8'd49: count_end = M_1; 8'd50,8'd51: count_end = M_1; 8'd52,8'd53: count_end = M_2; 8'd54,8'd55: count_end = M_3; 8'd56,8'd57,8'd58: count_end = M_2; 8'd59: count_end = M_1; 8'd60,8'd61,8'd62,8'd63: count_end = M_1; 8'd64,8'd65: count_end = M_2; 8'd66,8'd67: count_end = M_2; 8'd68,8'd69: count_end = M_3; 8'd70,8'd71: count_end = M_1; 8'd72,8'd73: count_end = M_2; 8'd74: count_end = M_3; 8'd75: count_end = M_4; 8'd76,8'd77: count_end = M_3; 8'd78,8'd79: count_end = M_1; 8'd80,8'd81: count_end = M_2; 8'd82: count_end = M_3; 8'd83: count_end = M_4; 8'd84,8'd85: count_end = M_3; 8'd86,8'd87: count_end = M_2; 8'd88,8'd89: count_end = M_1; 8'd90,8'd91: count_end = M_2; //8'd92,8'd93: count_end = L_5; 8'd92,8'd93,8'd94,8'd95: count_end = L_5; //8'd94,8'd95: count_end = M_3; 8'd96,8'd97: count_end = M_3; 8'd98,8'd99: count_end = M_3; 8'd100,8'd101: count_end = M_4; 8'd102,8'd103: count_end = M_5; 8'd104,8'd105: count_end = M_5; 8'd106,8'd107: count_end = M_4; 8'd108: count_end = M_3; 8'd109: count_end = M_2; 8'd110,8'd111: count_end = M_1; 8'd112,8'd113: count_end = M_1; 8'd114,8'd115: count_end = M_2; 8'd116,8'd117: count_end = M_3; 8'd118,8'd119,8'd120: count_end = M_2; 8'd121: count_end = M_1; 8'd122,8'd123,8'd124,8'd125: count_end = M_1; default:count_end = 16'hffff; endcase end end end assign led[0]=(count_end == M_1)?0:1; //控制LED灯的语言 assign led[1]=(count_end == M_2)?0:1; assign led[2]=(count_end == M_3)?0:1; assign led[3]=(count_end == M_4)?0:1; assign led[4]=(count_end == M_5)?0:1; assign led[5]=(count_end == L_5)?0:1; assign led[6]=1; assign led[7]=1; endmodule
5.3 选择模块程序 图5-3选择模块图
module select(key,beep1,beep2,led1,led2,beep,led); input key,beep1,beep2; input [6:0]led1; input [6:0]led2; output beep; output [6:0]led; reg key_r; always @(negedge key) begin key_r = ~key_r; //将琴键开关转换为乒乓开关 end assign beep=(key_r)?beep2:beep1; assign led=(key_r)?led2:led1; endmodule 5.4顶层文件程序
图5-4顶层文件图 module dzq(key,key7,beep,led,clk); input key7; input [6:0]key; input clk; output [6:0]led; output beep; reg dout1; reg dout2; reg dout3; reg led; reg key_r; wire a,b,key_l; wire [6:0]c; wire [6:0]d; assign key_l = (dout1 | dout2 | dout3); //按键消抖输出 always @(posedge clk) begin dout1 <= key7; dout2 <= dout1; dout3 <= dout2; end song (.clk(clk),.beep(b),.led(c)); beep1 (.clk(clk),.key(key),.beep(a),.led(d)); select (.key(key_l),.beep1(a),.beep2(b),.beep(beep),.led(led),.led1(d),.led2(c)); endmodule 第六章 实验图形文件6.1管脚锁定图引脚锁定:选择Assignments-pin planer
图6-1管脚锁定图 RTL图:选择Tools—netlist viewers—RTL viewers 图6-2 RTL图 6.2DXP原理图及封装DXP原理图的设计: - 执行“文件”—“创建”—“项目”—“PCB项目”命令
- 在projects面板上新建一个项目文件,默认名为PCB_Projects.PrjPCB.
- 执行“文件”—“保存项目”命令
- 利用libiaries元件库进行原理图绘制
图6-3 dxp原理图 DXP封装设计: - 执行“文件”—“创建”—“PCB文件”命令,新建PCB设计文件并保存
- 设置工作层:选择机械层设置物理边界,在禁止布线层设置电气边界。
- 加载网络表:执行“设计”—Import Changes From DESIGN.PRJPCB命令,单击“使变化生效”—“执行变化”
- 元件自动布局:执行“工具”—“放置元件”—“自动布局”命令
- 元件自动布线:执行“自动布线”—“设定”—“全部对象”命令,选择默认设置,确认布线即可
图6-4封装图 6.3任务完成情况说明 | | | | 按下KEY1—KEY7 分别表示中音的DO、 RE 、 ME、 FA、 SOL、 LA、 SI; | | | | | | 可以在电路上能自动演奏乐曲。在这里我们采用的是贝多芬的《欢乐颂》,且有相应的LED灯指示高低音; | | | | |
表6-5 任务完成情况表:
6.4硬件连接图
图6-6按键电路图 图6-6 LED灯电路图 图6-7 2X5下载插座 图6-8 蜂鸣器电路图 图6-9 晶振电路图 图6-10 电源电路图
总结
本次EDA课程设计进一步加深了我们对实验课的认识和对EDA的了解,对于Verilog HDL语言的运用更加的熟练。同时对于课程设计过程中要进行的调试和编写程序有了一定的认识。
电子琴使用按键的冲突,不得不消除原有模块的高音阶部分,而将其改造出现在的模块和形式,对于硬件电子琴的改造,看似是对原功能块的简单的改进,而实际上是需要重新构造电路的,因为在演奏的过程中会有LED灯的使用冲突,如何调试和调用,才是本课程设计的重点,因为顶层文件的需要,我们需要对各自的程序进行调整和修改。目的是为了能够在最后的开发平台上得到我们想要的结果。
在这次的课程设计过程中,我们采取的分工合作的方式来进行课程设计是一件很好的事情。大家各有侧重点但是同时都为课程设计做出应该做的努力,分工协作有时候不仅有利用于课程设计的快速进行,而且也有利于个人和小组的交流和促进,在分工的时候,每个人都各尽所长,实现了又快又好的完成课程任务的目标。最后,特别感谢本次课程设计给予我们指导的老师,在老师的知道和启发下,我们才能正确的完成课程设计。
附录:项目实物图 |