数字系统设计大作业报告A6
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数字系统设计大作业报告——基于FPGA的带指示功能的简易电子琴
学院电子与信息学院
专业
学生姓名
一、题目要求
(一)制作一个有16个琴键的简易电子琴。
(二)音符从低音fa到高音suo。
(三)由开关控制用LED指示演示一首歌曲的弹奏方法。如《一闪一闪亮晶晶》其简谱如下图所示:
(一)模块关系图
(二)底层模块介绍
1.键盘编码模块
输入:键盘信号。
输出:分频比,为受控分频模块提供的复位信号。
设计思路:该模块为纯组合逻辑,将键盘输入信号编码为受控分频模块的分频比和复位信号。在没有键按下或无法编码的按键情况时,输出有效的复位信号(高电平);按下某个键时,输出相应的分频比,同时清除复位信号(低电平)。
2.受控分频模块
输入:分频比、系统时钟、复位信号。
输出:音频信号。
设计思路:该模块为受控分频器,用来输出相应的音频波。分频输出的频率受输入分频比的控制。分频器用计数器实现,计数器复位,用键盘编码模块产生的复位信号,溢出判断量是键盘编码模块输出的分频比。该模块输出为占空比50%的方波,以此来驱动功放或扬声器发声。
3.固定分频模块
输入:系统时钟、复位信号
输出:5Hz时钟信号。
设计思路:该模块为固定频率的分频器,用来输出约5Hz的信号,为LED驱动波形产生模块提供基准频率。分频器用计数器实现,计数器时钟和复位信号由外部提供,固定溢出量,产生占空比50%的方波以此为LED驱动波形产生模块提供基准频率。
4.LED驱动波形产生模块
输入:5Hz时钟信号、音乐指示开关信号。
输出:LED驱动信号。
功能:产生驱动乐曲指示灯的信号。
设计思路:该模块为一个进位计数器,最小计数变量在停止标记无效(高电平)的情况下在低频时钟上升沿计数,每计数5次进位一次。对应一个音符中4次LED流水和一次停顿。最小音符单元在最小计数变量进位时自增一次,该演示曲每句6个时值为1的音,一个时值为2的音,因此最小音符单元计数满8时进位一次。最小音符单元用来指示这是每句中的第几个音。句子变量在最小音符单元进位时自增一次,该演示曲共六句,计数满后所有变量恢复初始状态,停止标记变为有效(低电平),使演示只进行一遍。同时流水灯‚行‛驱动波形产生进程中在每句前6个时值为1的每个音符弹奏时间内产生较短的4次LED流水信号,在每句后1个时值为2的每个音符弹奏时间内产生较长的4次LED流水信号。流水灯‚列‛驱动波形产生进程中根据句子变量和最小音符单元的值,产生音符选择信号(流水灯‚列‛驱动信号)。
(三)模块连接图
1.键盘与发音部分
KBD为键盘编码模块
ccd为受控分频模块
2.弹奏指示部分
LC2为固定分频模块
LC1为LED驱动波形产生模块
3.顶层设计
TDisp为弹奏指示部分
tomp为键盘与发音部分
(四)关键代码
1.琴键编码器
……
if(KB(15)='0') then
rst_ag<='0'; ds_ag<=x"117A8";--_4----0
elsif(KB(14)='0') then
rst_ag<='0'; ds_ag<=x"0F920";--_5----1
elsif(KB(13)='0') then
rst_ag<='0'; ds_ag<=x"0DDF2";--_6----2
elsif(KB(12)='0') then
rst_ag<='0'; ds_ag<=x"0C5BA";--_7----3--低音
……
elsif(KB(0)='0') then
rst_ag<='0'; ds_ag<=x"03E48";--5.----15--高音
else
rst_ag<='1'; --------------------未按键
end if;
……
这部分代码采用if-elsif-else 语句,构成16路优先编码器,将按键情况编码为分频比。
2.受控分频器
……
elsif(rising_edge(clk)) then
if(cnt < ds_i) then--分频计数器计数
cnt <= cnt + x"00001";
else---------分频计数溢出
div_in <= not div_in;
cnt<=x"00001";
end if;
……
这部分代码用if 语句构成计数器,用来生成方波,由于计数器溢出值为变量,该变量受键盘编码器控制,因此产生的方波频率受到键盘控制,以便产生不同音调的琴声。
3.固定分频器
……
if(rst_i='0') then
cnt<=0;
div_in<='0';
elsif(rising_edge(clk)) then
if(cnt < 4999900) then--4个9
cnt <= cnt + 1;
else
div_in <= not div_in;
cnt<=0;
end if;
end if;
……
这部分代码是用if语句构成的计数器,计数溢出值固定,用以生成驱动LED 的基本低频时钟信号。
4.LED驱动器
……
if(rst_i='0') then--计数复位
micnt<=0;
minu<=1;
stns<=1;
stp<='1';
elsif(rising_edge(clk5) and stp='1') then
if(micnt /= 5) then--正常计数
micnt <= micnt + 1;
elsif(minu /= 8) then--最小计数变量溢出
micnt<=1;
minu <= minu + 1;--最小音符单元加‘1’
elsif(stns /= 6) then--最小音符单元溢出
micnt<=1;
minu<=1;
stns <= stns + 1;--句子加‘1’
else--所有句子完毕
stns<=1;
minu<=1;
micnt<=0;
stp<='0';--停止计数,只计数一次
end if;
end if;
……
这部分代码为三个计数器,micnt给minu进位,minu给stns进位,通过判断这三个计数器的计数值,程序将产生驱动LED所需的不同形状的波形。
(五)模块资源使用情况
设计有16个琴键输入口,10个LED控制输出口,一个复位端口,一个时钟输入口,一个播放控制口,一个音频输出口,共30个I/O口。采用ask2cd系列FPGA 开发板,板载芯片为EP2C8Q208C,该开发板资源丰富,本设计中,主要使用其并行接口、按键开关、拨码开关、蜂鸣器等资源,使用时将自制的键盘,LED指示等电路通过并行接口与开发板连接,即可满足硬件要求。