直接上代码,最后 的0开始为乐谱
module beep_music (clk, rst_n, beep);
input clk;
input rst_n;
output beep;
reg beep;
//------------时钟分频计数值-----------------------------------------------------------------
parameter SPEED = 6; //控制演奏的速度,如果是4,频率就是4hz
parameter COUNTER_6M = 50_000_000 / 6_000_000 / 2 - 1; //基准频率分频比
parameter COUNTER_4 = 50_000_000 / SPEED / 2 - 1; //演奏频率分频比
parameter LENGTH = 200;
//------------音阶分频预置数------------------------------------------------------------------
//预置数 = 16383 - (6_000_000 / 音阶频率 / 2 - 1)
//分频比 = 6_000_000 / 音阶频率 / 2 - 1
parameter REST = 2^14 - 1; //休止符 不发出声音 2^14 - 1 = 16383
parameter C_LOW = 16383 - (6_000_000 / 262 / 2 - 1); //低音C
parameter D_LOW = 16383 - (6_000_000 / 294 / 2 - 1);
parameter E_LOW = 16383 - (6_000_000 / 330 / 2 - 1);
parameter F_LOW = 16383 - (6_000_000 / 349 / 2 - 1);
parameter G_LOW = 16383 - (6_000_000 / 392 / 2 - 1);
parameter A_LOW = 16383 - (6_000_000 / 440 / 2 - 1);
parameter B_LOW = 16383 - (6_000_000 / 494 / 2 - 1);
parameter C_MID = 16383 - (6_000_000 / 523 / 2 - 1); //中音C
parameter D_MID = 16383 - (6_000_000 / 587 / 2 - 1);
parameter E_MID = 16383 - (6_000_000 / 659 / 2 - 1);
parameter F_MID = 16383 - (6_000_000 / 699 / 2 - 1);
parameter G_MID = 16383 - (6_000_000 / 784 / 2 - 1);
parameter A_MID = 16383 - (6_000_000 / 880 / 2 - 1);
parameter B_MID = 16383 - (6_000_000 / 988 / 2 - 1);
parameter C_HIGH = 16383 - (6_000_000 / 1047 / 2 - 1); //高音C
parameter D_HIGH = 16383 - (6_000_000 / 1175 / 2 - 1);
parameter E_HIGH = 16383 - (6_000_000 / 1319 / 2 - 1);
parameter F_HIGH = 16383 - (6_000_000 / 1397 / 2 - 1);
parameter G_HIGH = 16383 - (6_000_000 / 1568 / 2 - 1);
parameter A_HIGH = 16383 - (6_000_000 / 1760 / 2 - 1);
parameter B_HIGH = 16383 - (6_000_000 / 1976 / 2 - 1);
//---------------基准时钟分频6mhz--------------------------------------------------------------
reg [23:0] cnt_6m;
reg clk_6m;
always @(posedge clk or negedge rst_n)
begin
if (!rst_n)
begin
cnt_6m <= 0;
clk_6m <= 0;
end
else if (cnt_6m == COUNTER_6M)
begin
cnt_6m <= 0;
clk_6m <= ~ clk_6m;
end
else
cnt_6m <= cnt_6m + 1'b1;
end
//-----------------演奏时钟分频4hz---------------------------------------------------------------
reg [23:0] cnt_4;
reg clk_4;
always @(posedge clk or negedge rst_n)
begin
if (!rst_n)
begin
cnt_4 <= 0;
clk_4 <= 0;
end
else if (cnt_4 == COUNTER_4)
begin
cnt_4 <= 0;
clk_4 <= ~ clk_4;
end
else
cnt_4 <= cnt_4 + 1'b1;
end
//------------------------------------------------------------------------------------------------
reg [13:0] cnt;
always @(posedge clk_6m or negedge rst_n)
begin
if (!rst_n)
cnt <= 0;
else if (cnt == REST)
begin
cnt <= cnt_hz;
beep <= ~ beep; //无源蜂鸣器需要产生方波驱动
end
else
cnt <= cnt + 1'b1;
end
//------------------------------------------------------------------------------------------------
reg [13:0] cnt_hz;
always @(posedge clk_4 or negedge rst_n) //根据不同的音阶选择不同的预置数
begin
if (!rst_n)
cnt_hz <= REST;
else
case (music_scale)
0 : cnt_hz <= REST;
1 : cnt_hz <= C_LOW;
2 : cnt_hz <= D_LOW;
3 : cnt_hz <= E_LOW;
4 : cnt_hz <= F_LOW;
5 : cnt_hz <= G_LOW;
6 : cnt_hz <= A_LOW;
7 : cnt_hz <= B_LOW;
8 : cnt_hz <= C_MID;
9 : cnt_hz <= D_MID;
10 : cnt_hz <= E_MID;
11 : cnt_hz <= F_MID;
12 : cnt_hz <= G_MID;
13 : cnt_hz <= A_MID;
14 : cnt_hz <= B_MID;
15 : cnt_hz <= C_HIGH;
16 : cnt_hz <= D_HIGH;
17 : cnt_hz <= E_HIGH;
18 : cnt_hz <= F_HIGH;
19 : cnt_hz <= G_HIGH;
20 : cnt_hz <= A_HIGH;
21 : cnt_hz <= B_HIGH;
default : cnt_hz <= REST;
endcase
end
//------------------------------------------------------------------------------------------------
//如果SPEED = 4,那么就代表一个计数一次是0.25s
//如果SPEED = 8 ,那么就代表一次计数是0.125s
//每次只能演奏一首曲子,想演奏那首曲子,就将该曲子的注释去掉,把其他曲子注释掉
reg [23:0] cnt_l;//演奏计数器
reg [5:0] music_scale;//音阶
// 0 休止符 // 1-7 低音 // 8-14 中音 // 15-21 高音 //
//clk_4频率为4,那么每0.25秒计数一次即每0.25秒演奏一个音阶
//每个音阶的计数次数可以表示音长
always @ (posedge clk_4 or negedge rst_n)
begin
if (!rst_n)
begin
cnt_l <= 0;
music_scale <= 0;
end
else if (cnt_l == LENGTH)//每计数到LENGTH 循环一次
cnt_l <= 0;
else
cnt_l <= cnt_l + 1'b1;
case (cnt_l)
speed = 6
0:music_scale<=10;//乐谱