一、 设计课题的任务要求
1、基本要求
1、 用8×8点阵显示“1 2 3 4 5 6 7”七个音符构成的电子琴键盘。其中点阵的第一列用一个 LED点亮表示音符“1”,第二列用二个 LED点亮表示音符“2”,依此类推。当音符为低音 1至7时,点阵显示为绿色;当音符为中音1至7时,点阵显示为红色;当音符为高音1~7 时,点阵显示为黄色;
2、 用BTN7~BTN1七个按键模拟电子琴手动演奏时的“1 2 3 4 5 6 7”七个音符。当某个按键按下时,数码管DISP7显示相应的音符,点阵上与之对应的音符显示列全灭,同时蜂鸣器演奏相应的声音;当按键放开时数码管显示的音符灭掉,点阵显示恢复,蜂鸣器停止声音的输出。
2、提高要求
1、增加手动演奏的音符存储、播放功能。
2、自拟其他功能。
3、实验原理
因为音阶的频率我们是知道的,设为f,而maxII板上的clk信号是50MHz,所以要得到需要的f,只需要n=50M/f就可以得到分频的倍数了。以下是己知的所需频率f。
二、 系统设计
1、设计思路
本实验主要涉及到了数码管的译码、点阵、不同音符所对应分频系数的选择、音乐的存储和自动播放五部分。
①数码管的译码:BTN7~BTN1分别对应1234567,同时要求只有一个七段数码管DISP7显示,故cat阵列应为“01111111”。
②点阵:G_COL:绿色发光二极管列信号;R_COL:红色发光二极管列信号;ROW:行信号(发光二极管公共端)。点阵上某个点显示红色(中音)的条件:控制该点行的引脚输出低电平,控制该点红色发光二极管列信号引脚输出高电平,控制该点绿色发光二极管列信号引脚输出低电平。点阵上某个点显示绿色(低音)的条件:控制该点行的引脚输出低电平,控制该点红色发光二极管列信号引脚输出低电平,控制该点绿色发光二极管列信号引脚输出高电平。点阵上某个点显示黄色(高音)的条件:控制该点行的引脚输出低电平,控制该点红色发光二极管列信号引脚输出高电平,控制该点绿色发光二极管列信号引脚输出高电平。
③分频系数的选择:首先对高中低音进行判断,然后再根据BTN输出相应的频率。
④音乐的存储:首先做一个计数器(取决于储存音乐的长度,我取的是模8计数器),然后根据计数器的计数依次输出BTN。
⑤自动播放:根据存储部分依次输出的BTN经过第③部分,得到相应的分频系数,就能得到相应的音符。
2、总体框图
三、仿真波形及波形分析
10000分频器divider
clk:初始时钟信号;
rclk:经过10000分频后的时钟信号,10000个clk周期=1个rclk周期即10000分频;
这里用10000分频器的目的是为了将50MHz频率的时钟信号变为较小频率(5000Hz)的时钟信号,从而减小运算时间。
1250分频器
clk:初始时钟信号;
rclk:经过1250分频后的时钟信号,1250个clk周期=1个rclk周期即1250分频。
目的是为了将经过divider得到的5000Hz的时钟信号转换为4Hz即周期为0.25s的时钟信号,对应的是1/4个节拍,为以后存储的音乐做好准备。
模8计数器count_8421
clk:时钟信号;
a:三位二进制数,每经过一个时钟上升沿计数,计数结果为“012345670123……”;
SW1:复位信号,当SW1=1时,计数归零;当SW1=0时,正常计数。
模8计数器count_8;
clk:时钟信号;
a:三位二进制数,每经过一个时钟上升沿计数,计数结果为“012345670123……”;
自动播放autoplay
a:前面的模8计数器输入的计数信号;由于我的电子琴自动播放的乐曲是“1234567”,所以采用模8计数器来完成自动演奏。
clk:时钟信号;
BTN:BTN7~BTN0分别对应音符1234567;
BTN_OUT:实际输出的BTN;
SW0:选择手动演奏或自动播放
由上仿真图可见,此时SW0=1,为自动播放,输出存储的音乐“1234567”。
不同音符对应分频系数的选择e_organ
a:模8计数,实现点阵G_COL、R_COL、ROW的扫描;
BTN:BTN7~BTN1分别对应音符1234567;
G_COL:绿色发光二极管列信号;
R_COL:红色发光二极管列信号;
ROW:发光二极管公共端行信号;
symbol:检测BTN是否为有效信号,1代表有效,0代表无效;
tone:根据音符选择出的分频系数;
SW[7:5]:100,高音黄色;010,中音红色;001,低音绿色;else不发音且数码管不显示。且只有SW为100、010、001时BTN信号才有效即symbol=1。
用tone=1100 0101 1010 1111时来分析,1100 0101 1010 1111换算成十进制数为50607。则50607对应的就是中音7的分频系数,50MHz/50607Hz=988Hz,对应中音7的987Hz。
根据输入的分频系数发出相应频率的音div
clk:时钟信号;
beep:分频后的信号;
symbol:判断信号tone的有效性,1有效,0无效;
tone:输入的分频系数。
数码管译码器deco
BTN:按键BTN7~BTN0分别对应1234567;
y:7段数码管;
cat:分别代表8个7段数码管模块。
由图可见:cat=01111111表示只有第一个7段数码管有显示;当BTN=1000000,此时y=00000110即数字1;当BTN=0010000,此时y=01001111即数字3;当BTN=0000100,此时y=01101101即数字5;当BTN=0000001,此时y=00000111即数字7,以此类推。
顶层文件elec_organ
BTN:BTN7~BTN1分别对应音符1234567;
clk:时钟信号;
G_COL:绿色发光二极管列信号;
R_COL:红色发光二极管列信号;
seg:7段数码管;
cat:分别代表8个7段数码管模块;
frq:输出的分频系数;
SW[7:5]:100高音黄色;010中音红色;001低音绿色;
SW0:控制手动演奏或者自动播放;
SW1:复位信号,当SW1=1时,计数归0,当SW1=0时,正常计数。
SW0=1即自动播放,此时播放的音乐为储存的音乐,当SW1=1时,自动播放会一直播放当前的那一个音符,当SW=0时,自动播放将按照存储的音符按顺序播放。
四、源程序
10000分频器divider
module divider(clk, rclk);
input clk;
output rclk;//经过4分频后的时钟信号
reg rclk;
reg [13:0] n;
always @(posedge clk)
begin
if (n == 9999)
n <= 0;
else
n <= n + 1;
if (n < 5000)
rclk <= 1'b0;
else
rclk <= 1'b1;
end
endmodule
模8计数器
module count_8(clk, a);
input clk;
output [2:0] a;
reg [2:0] a;
always @(posedge clk)
begin
if (a == 7)
a <= 0;
else
a <= a + 1;
end
endmodule
不同音符对应分频系数的选择e_organ
module e_organ(BTN, SW, a, clk, tone, symbol, G_COL, R_COL, ROW);
input [7:1] BTN;//音符1234567
input [7:5] SW;//高中低音
input [2:0] a;//模8计数,实现点阵G_COL、R_COL、ROW的扫描
input clk;
output [17:0] tone;//根据音符选择出的分频系数
reg [17:0] tone;
output symbol;//检测BTN是否有效(100、010、001),1有效,0无效
reg symbol;
output [7:0] G_COL;//绿色发光二极管列信号
reg [7:0] G_COL;
output [7:0] R_COL;//红色发光二极管列信号
reg [7:0] R_COL;
output [7:0] ROW;//发光二极管公共端行信号
reg [7:0] ROW;
always @(SW or BTN or a or clk)
begin
if (SW == 3'b001) //低音
begin
R_COL <= 8'b00000000;
if (BTN == 7'b1000000)
begin
tone <= 190839;
symbol <= 1'b1;
if (a == 3'b000)
begin
G_COL <= 8'b00000000;
ROW <= 8'b01111111;
end
else if (a == 3'b001)
begin
G_COL <= 8'b01000000;
ROW <= 8'b10111111;
end
else if (a == 3'b010)
begin
G_COL <= 8'b01100000;
ROW <= 8'b11011111;
end
else if (a == 3'b011)
begin
G_COL <= 8'b01110000;
ROW <= 8'b11101111;
end
else if (a == 3'b100)
begin
G_COL <= 8'b01111000;
ROW <= 8'b11110111;
end
else if (a == 3'b101)
begin
G_COL <= 8'b01111100;
ROW <= 8'b11111011;
end
else if (a == 3'b110)
begin
G_COL <= 8'b01111110;
ROW <= 8'b11111101;
end
else if (a == 3'b111)
begin
G_COL <= 8'b01111110;
ROW <= 8'b11111110;
end
end
else if (BTN == 7'b0100000)
begin
tone <= 168919;
symbol <= 1'b1;
if (a == 3'b000)
begin
G_COL <= 8'b00000000;
ROW <= 8'b01111111;
end
else if (a == 3'b001)
begin
G_COL <= 8'b01000000;
ROW <= 8'b10111111;
end
else if (a == 3'b010)
begin
G_COL <= 8'b01100000;
ROW <= 8'b11011111;
end
else if (a == 3'b011)
begin
G_COL <= 8'b01110000;
ROW <= 8'b11101111;
end
else if (a == 3'b100)
begin
G_COL <= 8'b01111000;
ROW <= 8'b11110111;
end
else if (a == 3'b101)
begin
G_COL <= 8'b01111100;
ROW <= 8'b11111011;
end
else if (a == 3'b110)
begin
G_COL <= 8'b01111100;
ROW <= 8'b11111101;
end
else if (a == 3'b111)
begin
G_COL <= 8'b01111101;
ROW <= 8'b11111110;
end
end
else if (BTN == 7'b0010000)
begin
tone <= 151515;
symbol <= 1'b1;
if (a == 3'b000)
begin
G_COL <= 8'b00000000;
ROW <= 8'b01111111;
end
else if (a == 3'b001)
begin
G_COL <= 8'b01000000;
ROW <= 8'b10111111;
end
else if (a == 3'b010)
begin
G_COL <= 8'b01100000;
ROW <= 8'b11011111;
end
else if (a == 3'b011)
begin
G_COL <= 8'b01110000;
ROW <= 8'b11101111;
end
else if (a == 3'b100)
begin
G_COL <= 8'b01111000;
ROW <= 8'b11110111;
end
else if (a == 3'b101)
begin
G_COL <= 8'b01111000;
ROW <= 8'b11111011;
end
else if (a == 3'b110)
begin
G_COL <= 8'b01111010;
ROW <= 8'b11111101;
end
else if (a == 3'b111)
begin
G_COL <= 8'b01111011;
ROW <= 8'b11111110;
end
end
else if (BTN == 7'b0001000)
begin
tone <= 143267;
symbol <= 1'b1;
if (a == 3'b000)
begin
G_COL <= 8'b00000000;
ROW <= 8'b01111111;
end
else if (a == 3'b001)
begin
G_COL <= 8'b01000000;
ROW <= 8'b10111111;
end
else if (a == 3'b010)
begin
G_COL <= 8'b01100000;
ROW <= 8'b11011111;
end
else if (a == 3'b011)
begin
G_COL <= 8'b01110000;
ROW <= 8'b11101111;
end
else if (a == 3'b100)
begin
G_COL <= 8'b01110000;
ROW <= 8'b11110111;
end
else if (a == 3'b101)
begin
G_COL <= 8'b01110100;
ROW <= 8'b11111011;
end
else if (a == 3'b110)
begin
G_COL <= 8'b01110110;
ROW <= 8'b11111101;
end
else if (a == 3'b111)
begin
G_COL <= 8'b01110111;
ROW <= 8'b11111110;
end
end
else if (BTN == 7'b0000100)
begin
tone <= 127551;
symbol <= 1'b1;
if (a == 3'b000)
begin
G_COL <= 8'b00000000;
ROW <= 8'b01111111;
end
else if (a == 3'b001)
begin
G_COL <= 8'b01000000;
ROW <= 8'b10111111;
end
else if (a == 3'b010)
begin
G_COL <= 8'b01100000;
ROW <= 8'b11011111;
end
else if (a == 3'b011)
begin
G_COL <= 8'b01100000;
ROW <= 8'b11101111;
end
else if (a == 3'b100)
begin
G_COL <= 8'b01101000;
ROW <= 8'b11110111;
end
else if (a == 3'b101)
begin
G_COL <= 8'b01101100;
ROW <= 8'b11111011;
end
else if (a == 3'b110)
begin
G_COL <= 8'b01101110;
ROW <= 8'b11111101;
end
else if (a == 3'b111)
begin
G_COL <= 8'b01101111;
ROW <= 8'b11111110;
end
end
else if (BTN == 7'b0000010)
begin
tone <= 113635;
symbol <= 1'b1;
if (a == 3'b000)
begin
G_COL <= 8'b00000000;
ROW <= 8'b01111111;
end
else if (a == 3'b001)
begin
G_COL <= 8'b01000000;
ROW <= 8'b10111111;
end
else if (a == 3'b010)
begin
G_COL <= 8'b01000000;
ROW <= 8'b11011111;
end
else if (a == 3'b011)
begin
G_COL <= 8'b01010000;
ROW <= 8'b11101111;
end
else if (a == 3'b100)
begin
G_COL <= 8'b01011000;
ROW <= 8'b11110111;
end
else if (a == 3'b101)
begin
G_COL <= 8'b01011100;
ROW <= 8'b11111011;
end
else if (a == 3'b110)
begin
G_COL <= 8'b01011110;
ROW <= 8'b11111101;
end
else if (a == 3'b111)
begin
G_COL <= 8'b01011111;
ROW <= 8'b11111110;
end
end
else if (BTN == 7'b0000001)
begin
tone <= 101215;
symbol <= 1'b1;
if (a == 3'b000)
begin
G_COL <= 8'b00000000;
ROW <= 8'b01111111;
end
else if (a == 3'b001)
begin
G_COL <= 8'b00000000;
ROW <= 8'b10111111;
end
else if (a == 3'b010)
begin
G_COL <= 8'b00100000;
ROW <= 8'b11011111;
end
else if (a == 3'b011)
begin
G_COL <= 8'b00110000;
ROW <= 8'b11101111;
end
else if (a == 3'b100)
begin
G_COL <= 8'b00111000;
ROW <= 8'b11110111;
end
else if (a == 3'b101)
begin
G_COL <= 8'b00111100;
ROW <= 8'b11111011;
end
else if (a == 3'b110)
begin
G_COL <= 8'b00111110;
ROW <= 8'b11111101;
end
else if (a == 3'b111)
begin
G_COL <= 8'b00111111;
ROW <= 8'b11111110;
end
end
else
begin
tone <= 0;
symbol <= 1'b0;
if (a == 3'b000)
begin
G_COL <= 8'b00000000;
ROW <= 8'b01111111;
end
else if (a == 3'b001)
begin
G_COL <= 8'b01000000;
ROW <= 8'b10111111;
end
else if (a == 3'b010)
begin
G_COL <= 8'b01100000;
ROW <= 8'b11011111;
end
else if (a == 3'b011)
begin
G_COL <= 8'b01110000;
ROW <= 8'b11101111;
end
else if (a == 3'b100)
begin
G_COL <= 8'b01111000;
ROW <= 8'b11110111;
end
else if (a == 3'b101)
begin
G_COL <= 8'b01111100;
ROW <= 8'b11111011;
end
else if (a == 3'b110)
begin
G_COL <= 8'b01111110;
ROW <= 8'b11111101;
end
else if (a == 3'b111)
begin
G_COL <= 8'b01111111;
ROW <= 8'b11111110;
end
end
end
else if (SW == 3'b010) //中音
begin
G_COL <= 8'b00000000;
if (BTN == 7'b1000000)
begin
tone <= 95601;
symbol <= 1'b1;
if (a == 3'b000)
begin
R_COL <= 8'b00000000;
ROW <= 8'b01111111;
end
else if (a == 3'b001)
begin
R_COL <= 8'b01000000;
ROW <= 8'b10111111;
end
else if (a == 3'b010)
begin
R_COL <= 8'b01100000;
ROW <= 8'b11011111;
end
else if (a == 3'b011)
begin
R_COL <= 8'b01110000;
ROW <= 8'b11101111;
end
else if (a == 3'b100)
begin
R_COL <= 8'b01111000;
ROW <= 8'b11110111;
end
else if (a == 3'b101)
begin
R_COL <= 8'b01111100;
ROW <= 8'b11111011;
end
else if (a == 3'b110)
begin
R_COL <= 8'b01111110;
ROW <= 8'b11111101;
end
else if (a == 3'b111)
begin
R_COL <= 8'b01111110;
ROW <= 8'b11111110;
end
end
else if (BTN == 7'b0100000)
begin
tone <= 85179;
symbol <= 1'b1;
if (a == 3'b000)
begin
R_COL <= 8'b00000000;
ROW <= 8'b01111111;
end
else if (a == 3'b001)
begin
R_COL <= 8'b01000000;
ROW <= 8'b10111111;
end
else if (a == 3'b010)
begin
R_COL <= 8'b01100000;
ROW <= 8'b11011111;
end
else if (a == 3'b011)
begin
R_COL <= 8'b01110000;
ROW <= 8'b11101111;
end
else if (a == 3'b100)
begin
R_COL <= 8'b01111000;
ROW <= 8'b11110111;
end
else if (a == 3'b101)
begin
R_COL <= 8'b01111100;
ROW <= 8'b11111011;
end
else if (a == 3'b110)
begin
R_COL <= 8'b01111100;
ROW <= 8'b11111101;
end
else if (a == 3'b111)
begin
R_COL <= 8'b01111101;
ROW <= 8'b11111110;
end
end
else if (BTN == 7'b0010000)
begin
tone <= 75873;
symbol <= 1'b1;
if (a == 3'b000)
begin
R_COL <= 8'b00000000;
ROW <= 8'b01111111;
end
else if (a == 3'b001)
begin
R_COL <= 8'b01000000;
ROW <= 8'b10111111;
end
else if (a == 3'b010)
begin
R_COL <= 8'b01100000;
ROW <= 8'b11011111;
end
else if (a == 3'b011)
begin
R_COL <= 8'b01110000;
ROW <= 8'b11101111;
end
else if (a == 3'b100)
begin
R_COL <= 8'b01111000;
ROW <= 8'b11110111;
end
else if (a == 3'b101)
begin
R_COL <= 8'b01111000;
ROW <= 8'b11111011;
end
else if (a == 3'b110)
begin
R_COL <= 8'b01111010;
ROW <= 8'b11111101;
end
else if (a == 3'b111)
begin
R_COL <= 8'b01111011;
ROW <= 8'b11111110;
end
end
else if (BTN == 7'b0001000)
begin
tone <= 71633;
symbol <= 1'b1;
if (a == 3'b000)
begin
R_COL <= 8'b00000000;
ROW <= 8'b01111111;
end
else if (a == 3'b001)
begin
R_COL <= 8'b01000000;
ROW <= 8'b10111111;
end
else if (a == 3'b010)
begin
R_COL <= 8'b01100000;
ROW <= 8'b11011111;
end
else if (a == 3'b011)
begin
R_COL <= 8'b01110000;
ROW <= 8'b11101111;
end
else if (a == 3'b100)
begin
R_COL <= 8'b01110000;
ROW <= 8'b11110111;
end
else if (a == 3'b101)
begin
R_COL <= 8'b01110100;
ROW <= 8'b11111011;
end
else if (a == 3'b110)
begin
R_COL <= 8'b01110110;
ROW <= 8'b11111101;
end
else if (a == 3'b111)
begin
R_COL <= 8'b01110111;
ROW <= 8'b11111110;
end
end
else if (BTN == 7'b0000100)
begin
tone <= 63775;
symbol <= 1'b1;
if (a == 3'b000)
begin
R_COL <= 8'b00000000;
ROW <= 8'b01111111;
end
else if (a == 3'b001)
begin
R_COL <= 8'b01000000;
ROW <= 8'b10111111;
end
else if (a == 3'b010)
begin
R_COL <= 8'b01100000;
ROW <= 8'b11011111;
end
else if (a == 3'b011)
begin
R_COL <= 8'b01100000;
ROW <= 8'b11101111;
end
else if (a == 3'b100)
begin
R_COL <= 8'b01101000;
ROW <= 8'b11110111;
end
else if (a == 3'b101)
begin
R_COL <= 8'b01101100;
ROW <= 8'b11111011;
end
else if (a == 3'b110)
begin
R_COL <= 8'b01101110;
ROW <= 8'b11111101;
end
else if (a == 3'b111)
begin
R_COL <= 8'b01101111;
ROW <= 8'b11111110;
end
end
else if (BTN == 7'b0000010)
begin
tone <= 56817;
symbol <= 1'b1;
if (a == 3'b000)
begin
R_COL <= 8'b00000000;
ROW <= 8'b01111111;
end
else if (a == 3'b001)
begin
R_COL <= 8'b01000000;
ROW <= 8'b10111111;
end
else if (a == 3'b010)
begin
R_COL <= 8'b01000000;
ROW <= 8'b11011111;
end
else if (a == 3'b011)
begin
R_COL <= 8'b01010000;
ROW <= 8'b11101111;
end
else if (a == 3'b100)
begin
R_COL <= 8'b01011000;
ROW <= 8'b11110111;
end
else if (a == 3'b101)
begin
R_COL <= 8'b01011100;
ROW <= 8'b11111011;
end
else if (a == 3'b110)
begin
R_COL <= 8'b01011110;
ROW <= 8'b11111101;
end
else if (a == 3'b111)
begin
R_COL <= 8'b01011111;
ROW <= 8'b11111110;
end
end
else if (BTN == 7'b0000001)
begin
tone <= 50607;
symbol <= 1'b1;
if (a == 3'b000)
begin
R_COL <= 8'b00000000;
ROW <= 8'b01111111;
end
else if (a == 3'b001)
begin
R_COL <= 8'b00000000;
ROW <= 8'b10111111;
end
else if (a == 3'b010)
begin
R_COL <= 8'b00100000;
ROW <= 8'b11011111;
end
else if (a == 3'b011)
begin
R_COL <= 8'b00110000;
ROW <= 8'b11101111;
end
else if (a == 3'b100)
begin
R_COL <= 8'b00111000;
ROW <= 8'b11110111;
end
else if (a == 3'b101)
begin
R_COL <= 8'b00111100;
ROW <= 8'b11111011;
end
else if (a == 3'b110)
begin
R_COL <= 8'b00111110;
ROW <= 8'b11111101;
end
else if (a == 3'b111)
begin
R_COL <= 8'b00111111;
ROW <= 8'b11111110;
end
end
else
begin
tone <= 0;
symbol <= 1'b0;
if (a == 3'b000)
begin
R_COL <= 8'b00000000;
ROW <= 8'b01111111;
end
else if (a == 3'b001)
begin
R_COL <= 8'b01000000;
ROW <= 8'b10111111;
end
else if (a == 3'b010)
begin
R_COL <= 8'b01100000;
ROW <= 8'b11011111;
end
else if (a == 3'b011)
begin
R_COL <= 8'b01110000;
ROW <= 8'b11101111;
end
else if (a == 3'b100)
begin
R_COL <= 8'b01111000;
ROW <= 8'b11110111;
end
else if (a == 3'b101)
begin
R_COL <= 8'b01111100;
ROW <= 8'b11111011;
end
else if (a == 3'b110)
begin
R_COL <= 8'b01111110;
ROW <= 8'b11111101;
end
else if (a == 3'b111)
begin
R_COL <= 8'b01111111;
ROW <= 8'b11111110;
end
end
end
else if (SW == 3'b100) //高音
begin
if (BTN == 7'b1000000)
begin
tone <= 47755;
symbol <= 1'b1;
if (a == 3'b000)
begin
G_COL <= 8'b00000000;
R_COL <= 8'b00000000;
ROW <= 8'b01111111;
end
else if (a == 3'b001)
begin
G_COL <= 8'b01000000;
R_COL <= 8'b01000000;
ROW <= 8'b10111111;
end
else if (a == 3'b010)
begin
G_COL <= 8'b01100000;
R_COL <= 8'b01100000;
ROW <= 8'b11011111;
end
else if (a == 3'b011)
begin
G_COL <= 8'b01110000;
R_COL <= 8'b01110000;
ROW <= 8'b11101111;
end
else if (a == 3'b100)
begin
G_COL <= 8'b01111000;
R_COL <= 8'b01111000;
ROW <= 8'b11110111;
end
else if (a == 3'b101)
begin
G_COL <= 8'b01111100;
R_COL <= 8'b01111100;
ROW <= 8'b11111011;
end
else if (a == 3'b110)
begin
G_COL <= 8'b01111110;
R_COL <= 8'b01111110;
ROW <= 8'b11111101;
end
else if (a == 3'b111)
begin
G_COL <= 8'b01111110;
R_COL <= 8'b01111110;
ROW <= 8'b11111110;
end
end
else if (BTN == 7'b0100000)
begin
tone <= 42553;
symbol <= 1'b1;
if (a == 3'b000)
begin
G_COL <= 8'b00000000;
R_COL <= 8'b00000000;
ROW <= 8'b01111111;
end
else if (a == 3'b001)
begin
G_COL <= 8'b01000000;
R_COL <= 8'b01000000;
ROW <= 8'b10111111;
end
else if (a == 3'b010)
begin
G_COL <= 8'b01100000;
R_COL <= 8'b01100000;
ROW <= 8'b11011111;
end
else if (a == 3'b011)
begin
G_COL <= 8'b01110000;
R_COL <= 8'b01110000;
ROW <= 8'b11101111;
end
else if (a == 3'b100)
begin
G_COL <= 8'b01111000;
R_COL <= 8'b01111000;
ROW <= 8'b11110111;
end
else if (a == 3'b101)
begin
G_COL <= 8'b01111100;
R_COL <= 8'b01111100;
ROW <= 8'b11111011;
end
else if (a == 3'b110)
begin
G_COL <= 8'b01111100;
R_COL <= 8'b01111100;
ROW <= 8'b11111101;
end
else if (a == 3'b111)
begin
G_COL <= 8'b01111101;
R_COL <= 8'b01111101;
ROW <= 8'b11111110;
end
end
else if (BTN == 7'b0010000)
begin
tone <= 37907;
symbol <= 1'b1;
if (a == 3'b000)
begin
G_COL <= 8'b00000000;
R_COL <= 8'b00000000;
ROW <= 8'b01111111;
end
else if (a == 3'b001)
begin
G_COL <= 8'b01000000;
R_COL <= 8'b01000000;
ROW <= 8'b10111111;
end
else if (a == 3'b010)
begin
G_COL <= 8'b01100000;
R_COL <= 8'b01100000;
ROW <= 8'b11011111;
end
else if (a == 3'b011)
begin
G_COL <= 8'b01110000;
R_COL <= 8'b01110000;
ROW <= 8'b11101111;
end
else if (a == 3'b100)
begin
G_COL <= 8'b01111000;
R_COL <= 8'b01111000;
ROW <= 8'b11110111;
end
else if (a == 3'b101)
begin
G_COL <= 8'b01111000;
R_COL <= 8'b01111000;
ROW <= 8'b11111011;
end
else if (a == 3'b110)
begin
G_COL <= 8'b01111010;
R_COL <= 8'b01111010;
ROW <= 8'b11111101;
end
else if (a == 3'b111)
begin
G_COL <= 8'b01111011;
R_COL <= 8'b01111011;
ROW <= 8'b11111110;
end
end
else if (BTN == 7'b0001000)
begin
tone <= 35791;
symbol <= 1'b1;
if (a == 3'b000)
begin
G_COL <= 8'b00000000;
R_COL <= 8'b00000000;
ROW <= 8'b01111111;
end
else if (a == 3'b001)
begin
G_COL <= 8'b01000000;
R_COL <= 8'b01000000;
ROW <= 8'b10111111;
end
else if (a == 3'b010)
begin
G_COL <= 8'b01100000;
R_COL <= 8'b01100000;
ROW <= 8'b11011111;
end
else if (a == 3'b011)
begin
G_COL <= 8'b01110000;
R_COL <= 8'b01110000;
ROW <= 8'b11101111;
end
else if (a == 3'b100)
begin
G_COL <= 8'b01110000;
R_COL <= 8'b01110000;
ROW <= 8'b11110111;
end
else if (a == 3'b101)
begin
G_COL <= 8'b01110100;
R_COL <= 8'b01110100;
ROW <= 8'b11111011;
end
else if (a == 3'b110)
begin
G_COL <= 8'b01110110;
R_COL <= 8'b01110110;
ROW <= 8'b11111101;
end
else if (a == 3'b111)
begin
G_COL <= 8'b01110111;
R_COL <= 8'b01110111;
ROW <= 8'b11111110;
end
end
else if (BTN == 7'b0000100)
begin
tone <= 31887;
symbol <= 1'b1;
if (a == 3'b000)
begin
G_COL <= 8'b00000000;
R_COL <= 8'b00000000;
ROW <= 8'b01111111;
end
else if (a == 3'b001)
begin
G_COL <= 8'b01000000;
R_COL <= 8'b01000000;
ROW <= 8'b10111111;
end
else if (a == 3'b010)
begin
G_COL <= 8'b01100000;
R_COL <= 8'b01100000;
ROW <= 8'b11011111;
end
else if (a == 3'b011)
begin
G_COL <= 8'b01100000;
R_COL <= 8'b01100000;
ROW <= 8'b11101111;
end
else if (a == 3'b100)
begin
G_COL <= 8'b01101000;
R_COL <= 8'b01101000;
ROW <= 8'b11110111;
end
else if (a == 3'b101)
begin
G_COL <= 8'b01101100;
R_COL <= 8'b01101100;
ROW <= 8'b11111011;
end
else if (a == 3'b110)
begin
G_COL <= 8'b01101110;
R_COL <= 8'b01101110;
ROW <= 8'b11111101;
end
else if (a == 3'b111)
begin
G_COL <= 8'b01101111;
R_COL <= 8'b01101111;
ROW <= 8'b11111110;
end
end
else if (BTN == 7'b0000010)
begin
tone <= 28409;
symbol <= 1'b1;
if (a == 3'b000)
begin
G_COL <= 8'b00000000;
R_COL <= 8'b00000000;
ROW <= 8'b01111111;
end
else if (a == 3'b001)
begin
G_COL <= 8'b01000000;
R_COL <= 8'b01000000;
ROW <= 8'b10111111;
end
else if (a == 3'b010)
begin
G_COL <= 8'b01000000;
R_COL <= 8'b01000000;
ROW <= 8'b11011111;
end
else if (a == 3'b011)
begin
G_COL <= 8'b01010000;
R_COL <= 8'b01010000;
ROW <= 8'b11101111;
end
else if (a == 3'b100)
begin
G_COL <= 8'b01011000;
R_COL <= 8'b01011000;
ROW <= 8'b11110111;
end
else if (a == 3'b101)
begin
G_COL <= 8'b01011100;
R_COL <= 8'b01011100;
ROW <= 8'b11111011;
end
else if (a == 3'b110)
begin
G_COL <= 8'b01011110;
R_COL <= 8'b01011110;
ROW <= 8'b11111101;
end
else if (a == 3'b111)
begin
G_COL <= 8'b01011111;
R_COL <= 8'b01011111;
ROW <= 8'b11111110;
end
end
else if (BTN == 7'b0000001)
begin
tone <= 25303;
symbol <= 1'b1;
if (a == 3'b000)
begin
G_COL <= 8'b00000000;
R_COL <= 8'b00000000;
ROW <= 8'b01111111;
end
else if (a == 3'b001)
begin
G_COL <= 8'b00000000;
R_COL <= 8'b00000000;
ROW <= 8'b10111111;
end
else if (a == 3'b010)
begin
G_COL <= 8'b00100000;
R_COL <= 8'b00100000;
ROW <= 8'b11011111;
end
else if (a == 3'b011)
begin
G_COL <= 8'b00110000;
R_COL <= 8'b00110000;
ROW <= 8'b11101111;
end
else if (a == 3'b100)
begin
G_COL <= 8'b00111000;
R_COL <= 8'b00111000;
ROW <= 8'b11110111;
end
else if (a == 3'b101)
begin
G_COL <= 8'b00111100;
R_COL <= 8'b00111100;
ROW <= 8'b11111011;
end
else if (a == 3'b110)
begin
G_COL <= 8'b00111110;
R_COL <= 8'b00111110;
ROW <= 8'b11111101;
end
else if (a == 3'b111)
begin
G_COL <= 8'b00111111;
R_COL <= 8'b00111111;
ROW <= 8'b11111110;
end
end
else
begin
tone <= 0;
symbol <= 1'b0;
if (a == 3'b000)
begin
G_COL <= 8'b00000000;
R_COL <= 8'b00000000;
ROW <= 8'b01111111;
end
else if (a == 3'b001)
begin
G_COL <= 8'b01000000;
R_COL <= 8'b01000000;
ROW <= 8'b10111111;
end
else if (a == 3'b010)
begin
G_COL <= 8'b01100000;
R_COL <= 8'b01100000;
ROW <= 8'b11011111;
end
else if (a == 3'b011)
begin
G_COL <= 8'b01110000;
R_COL <= 8'b01110000;
ROW <= 8'b11101111;
end
else if (a == 3'b100)
begin
G_COL <= 8'b01111000;
R_COL <= 8'b01111000;
ROW <= 8'b11110111;
end
else if (a == 3'b101)
begin
G_COL <= 8'b01111100;
R_COL <= 8'b01111100;
ROW <= 8'b11111011;
end
else if (a == 3'b110)
begin
G_COL <= 8'b01111110;
R_COL <= 8'b01111110;
ROW <= 8'b11111101;
end
else if (a == 3'b111)
begin
G_COL <= 8'b01111111;
R_COL <= 8'b01111111;
ROW <= 8'b11111110;
end
end
end
else
begin
symbol <= 1'b0;
tone <= 0;
G_COL <= 8'b00000000;
R_COL <= 8'b00000000;
ROW <= 8'b11111111;
end
end
endmodule
根据输入的分频系数发出相应频率的音div
module div(clk, symbol, tone, beep);
input clk;
input symbol;//判断信号tone是否有效,1有效,0无效
input [17:0] tone;
output beep;//分频后的信号
reg beep;
reg [18:0] n;
always @(posedge clk)
if (symbol == 1'b0)
begin
beep <= 1'b0;
n <= 0;
end
else
if (tone == 0)
beep <= 1'b0;
else
if (clk)
begin
if (n == tone)
n <= 0;
else
n <= n + 1;
if (n < (tone + 1)/2)
beep <= 1'b0;
else
beep <= 1'b1;
end
endmodule
数码管编译器deco
module deco(BTN, y, cat);
input [7:1] BTN;
output [7:0] y;//7段数码管
reg [7:0] y;
output [7:0] cat;//8个7段数码管模块
reg [7:0] cat;
always @(BTN)
begin
case (BTN)
7'b1000000 :
y <= 8'b00000110;
7'b0100000 :
y <= 8'b01011011;
7'b0010000 :
y <= 8'b01001111;
7'b0001000 :
y <= 8'b01100110;
7'b0000100 :
y <= 8'b01101101;
7'b0000010 :
y <= 8'b01111101;
7'b0000001 :
y <= 8'b00000111;
default :
y <= 8'b00111111;
endcase
cat <= 8'b01111111;
end
endmodule
250分频器d_250
module d_250(clk, rclk);
input clk;//初始时钟信号
output rclk;//经过4分频后的时钟信号
reg rclk;
reg [10:0] n;
always @(posedge clk)
begin
if (n == 1249)
n <= 0;
else
n <= n + 1;
if (n < 625)
rclk <= 1'b0;
else
rclk <= 1'b1;
end
endmodule
模8计数器count_8421
module count_8421(clk, SW1, a);
input clk;
input SW1;
output [2:0] a;//三位二进制数,时钟上升沿计数,0123456701234...
reg [2:0] a;
always @(posedge clk)
if (SW1 == 1'b1)
a <= 0;
else if (clk)
begin
if (a == 7)
a <= 0;
else
a <= a + 1;
end
endmodule
自动播放autoplay
module autoplay(BTN, SW0, a, BTN_OUT);
input [7:1] BTN;
input SW0;//选择手动或者自动
input [2:0] a;//模8计数器输入的信号
output [7:1] BTN_OUT;//实际输出的BTN
reg [7:1] BTN_OUT;
always @(SW0)
if (SW0 == 1'b0)
BTN_OUT <= BTN;
else
case (a)
0 :
BTN_OUT <= 7'b1000000;
1 :
BTN_OUT <= 7'b0100000;
2 :
BTN_OUT <= 7'b0010000;
3 :
BTN_OUT <= 7'b0001000;
4 :
BTN_OUT <= 7'b0000100;
5 :
BTN_OUT <= 7'b0000010;
6 :
BTN_OUT <= 7'b0000001;
7 :
BTN_OUT <= 7'b1000000;
endcase
endmodule
顶层文件elec_organ
module elec_organ(clk, SW0, SW1, BTN, SW, R_COL, G_COL, ROW, seg, cat, voice);
input clk;//初始时钟信号
input SW0;//自动播放拨码开关(0手动演奏,1自动播放)
input SW1;//复位信号,当SW1=1时计数归0,SW=0时正常计数
input [7:1] BTN;
input [7:5] SW;//高、中、低音(高电平起效)
output [7:0] R_COL;//红色发光二极管列信号
output [7:0] G_COL;//绿色发光二极管列信号
output [7:0] ROW;//发光二极管公共端行信号
output [7:0] seg;//7段数码管
output [7:0] cat;//8个7段数码管模块
output voice;
wire rck;//经过4分频后的时钟信号
wire en;
wire rk;
wire [2:0] counter;
wire [2:0] coun;
wire [17:0] ton;//输入的分频系数
wire [7:1] BT;
divider u0(.clk(clk), .rclk(rck));
count_8 u1(.clk(rck), .a(counter));
e_organ u2(.R_COL(R_COL), .G_COL(G_COL), .ROW(ROW), .symbol(en), .clk(rck), .BTN(BT), .SW(SW), .a(counter), .tone(ton));
div u3(.clk(clk), .tone(ton), .beep(voice), .symbol(en));
deco u4(.BTN(BT), .y(seg), .cat(cat));
d_250 u5(.clk(rck), .rclk(rk));
count_8421 u6(.clk(rk), .a(coun), .SW1(SW1));
autoplay u7(.BTN(BTN), .SW0(SW0), .a(coun), .BTN_OUT(BT));
endmodule
五、功能说明及资源利用情况
1、功能说明
①拨码开关SW7,SW6,SW5(高电平有效)分别代表高、中、低音。
②BTN7~BTN1 七个按键分别代表电子琴手动演奏时的“1 2 3 4 5 6 7”七个音符。当某个按键按下时,数码管DISP7显示相应的音符,点阵上与之对应的音符显示列全灭,同时蜂鸣器演奏相应的声音;当按键放开时数码管显示的音符灭掉,点阵显示恢复,蜂鸣器停止声音的输出。
③拨码开关SW0=1,为自动播放,输出存储的音乐“12345671”,当SW0=0,为手动演奏。
④拨码开关SW1=1自动播放此时的音符延长,SW=0时,继续沿着存储的音符播放。
2、资源利用情况
本次实验逻辑门共用了275个,占比22%;引脚一共用了54个,占比47%。
六、故障及问题分析
1、因为基础时钟信号选择50MHz,各个音符的分频系数就会很大,所以我开始的时候就用的1Mhz的时钟信号,结果出来的很多音符的音都不准确,后来经过上网查阅资料了解到,实验所用的电路板上面其他频率的时钟信号是由50MHz转换过来的,所以其他频率的时钟信号不太准确,当使用50MHz的时钟的时候,所有的音符的音调基本都准确了。
2、仿真的时候有冒险,加一个时钟沿判断就没有了;
3、提高部分由于期末复习时间精力有限,很多想法都没能实现。