要求:让无源蜂鸣器依次循环发出七个音阶的响声,每个音阶持续0.5秒
说明:让蜂鸣器发出固定音阶的声音,需要让蜂鸣器工作的频率固定,并且循环七个不同的音阶,所以这里要用到PWM波形调制,指定频率,占空比为50%。
这里蜂鸣器每个音阶持续0.5秒的话,不可能每个音阶频率计算下来刚好有整数个周期,这里做的操作是,循环计数,但是到了0.5秒,计数做清零处理
各个音阶的频率:DO:262 RE:294 MI:330 FA:349 SO:392 LA:440 XI:494
//分频数/2 (约) 95420 85034 75757 71633 63775 56818 50607
module beep
#(
parameter clk_500ms_max = 25'd24_999_999, //0.5秒计数
parameter DO = 17'd95419,
parameter RE = 17'd85033,
parameter MI = 17'd75756,
parameter FA = 17'd71632,
parameter SO = 17'd63774,
parameter LA = 17'd56817,
parameter XI = 17'd50606
)
(
input wire sys_clk,
input wire rst_n,
output reg out_beep
);
reg [2:0] state; //对应音阶时间
reg [16:0] count; //音阶分频数
reg [16:0] count_max;
reg [24:0] count_500ms;
always @ (posedge sys_clk or negedge rst_n) //对0.5秒计数
if (~rst_n)
count_500ms <= 25'd0;
else if (count_500ms == clk_500ms_max)
count_500ms <= 25'd0;
else
count_500ms <= count_500ms + 25'd1;
always @ (posedge sys_clk or negedge rst_n) //控制每个状态循环
if (~rst_n)
state <= 3'd1;
else if ((state == 3'd7) && (count_500ms == clk_500ms_max))
state <= 3'd1;
else if (count_500ms == clk_500ms_max)
state <= state +3'd1;
else
state <= state;
always @ (posedge sys_clk or negedge rst_n) //不同阶段,音阶需要的分频数
if (~rst_n)
count_max <= DO;
else case(state)
3'd1:count_max <= DO;
3'd2:count_max <= RE;
3'd3:count_max <= MI;
3'd4:count_max <= FA;
3'd5:count_max <= SO;
3'd6:count_max <= LA;
3'd7:count_max <= XI;
default : count_max <= DO;
endcase
always @ (posedge sys_clk or negedge rst_n) //音阶分频计数
if (~rst_n)
count <=17'd0;
else if ((count_500ms == clk_500ms_max) || ( count==count_max))
count <= 17'd0;
else
count <= count +17'd1;
always @ (posedge sys_clk or negedge rst_n) //音阶分频
if (~rst_n)
out_beep <= 1'b1;
else if ( count==count_max )
out_beep <= ~out_beep;
else
out_beep <= out_beep;
endmodule
module vtf_beep;
// Inputs
reg sys_clk;
reg rst_n;
// Outputs
wire out_beep;
// Instantiate the Unit Under Test (UUT)
beep
#(
.clk_500ms_max (25'd249), //0.5秒计数
.DO (17'd15),
.RE (17'd3),
.MI (17'd5),
.FA (17'd7),
.SO (17'd9),
.LA (17'd11),
.XI (17'd13)
)
uut (
.sys_clk(sys_clk),
.rst_n(rst_n),
.out_beep(out_beep)
);
initial begin
// Initialize Inputs
sys_clk = 0;
rst_n = 0;
// Wait 100 ns for global reset to finish
#100;
rst_n <=1'b1;
// Add stimulus here
end
always #10 sys_clk = ~sys_clk;
endmodule