

module beep
#(
parameter MAX_500MS = 25'd25_000_000 ,
MAX_NOTE_7= 3'd7 ,
FRE_262 = 23'd190839 ,
FRE_294 = 23'd170068 ,
FRE_330 = 23'd151515 ,
FRE_349 = 23'd143266 ,
FRE_392 = 23'd127551 ,
FRE_440 = 23'd113636 ,
FRE_494 = 23'd101214 ,
DUT_262 = 22'd95419 ,
DUT_294 = 22'd85034 ,
DUT_330 = 22'd75757 ,
DUT_349 = 22'd71633 ,
DUT_392 = 22'd63775 ,
DUT_440 = 22'd56818 ,
DUT_494 = 22'd50607
)(
input wire sys_clk ,
input wire sys_rst_n ,
output reg beep
);
// reg signal define
reg [24:00] cnt_500ms ;
reg [02:00] cnt_7 ;
reg [22:00] fre_num ; // 音符频率 计数最大值 锁存器 组合逻辑赋值
reg [22:00] cnt_f ; // 音符频率 计数器 不同音符 所计满次数不同。随着音符而变换。
reg [21:00] duty_cycle; // 占空比锁存器 ; 组合逻辑
// cnt_500ms
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
cnt_500ms <= 0 ;
end else begin
if(cnt_500ms == (MAX_500MS - 1'b1)) begin
cnt_500ms <= 0 ;
end else begin
cnt_500ms <= cnt_500ms + 1'b1 ;
end
end
end
// cnt_7
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
cnt_7 <= 0 ;
end else begin
if(cnt_500ms == (MAX_500MS - 1'b1)) begin
if(cnt_7 == MAX_NOTE_7 - 1'b1) begin
cnt_7 <= 0 ;
end else begin
cnt_7 <= cnt_7 + 1'b1 ;
end
end else begin
cnt_7 <= cnt_7 ;
end
end
end
// fre_num
always @(*) begin
case (cnt_7)
0 : begin
fre_num <= FRE_262 ;
end
1 : begin
fre_num <= FRE_294 ;
end
2 : begin
fre_num <= FRE_330 ;
end
3 : begin
fre_num <= FRE_349 ;
end
4 : begin
fre_num <= FRE_392 ;
end
5 : begin
fre_num <= FRE_440 ;
end
6 : begin
fre_num <= FRE_494 ;
end
default: fre_num <= FRE_494 ;
endcase
end
// cnt_f
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
cnt_f <= 0 ;
end else begin
if(cnt_f == (fre_num - 1'b1) || (cnt_500ms == MAX_500MS - 1'b1)) begin
cnt_f <= 0 ;
end else begin
cnt_f <= cnt_f + 1'b1 ;
end
end
end
// duty_cycle
always @(*) begin
case (cnt_7)
0 : begin
duty_cycle <= DUT_262 ;
end
1 : begin
duty_cycle <= DUT_294 ;
end
2 : begin
duty_cycle <= DUT_330 ;
end
3 : begin
duty_cycle <= DUT_349 ;
end
4 : begin
duty_cycle <= DUT_392 ;
end
5 : begin
duty_cycle <= DUT_440 ;
end
6 : begin
duty_cycle <= DUT_494 ;
end
default: duty_cycle <= DUT_494 ;
endcase
end
// beep
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
beep <= 1'b1 ;
end else begin
if(cnt_f >= duty_cycle) begin
beep <= 1'b0 ;
end else begin
beep <= 1'b1 ;
end
end
end
endmodule
`timescale 1ns/1ns
module test();
reg sys_clk ;
reg sys_rst_n ;
wire beep ;
// Instantiation
beep
#(
.MAX_500MS ( 1000 ),
.MAX_NOTE_7 ( 7 ),
.FRE_262 ( 70 ),
.FRE_294 ( 60 ),
.FRE_330 ( 50 ),
.FRE_349 ( 40 ),
.FRE_392 ( 30 ),
.FRE_440 ( 20 ),
.FRE_494 ( 10 ),
.DUT_262 ( 35 ),
.DUT_294 ( 30 ),
.DUT_330 ( 25 ),
.DUT_349 ( 20 ),
.DUT_392 ( 15 ),
.DUT_440 ( 10 ),
.DUT_494 ( 5 )
)
beep_insert(
.sys_clk ( sys_clk ),
.sys_rst_n ( sys_rst_n ),
.beep ( beep )
);
parameter CYCLE = 20 ;
initial begin
sys_clk = 1'b1 ;
sys_rst_n <= 1'b0 ;
#( CYCLE * 10 ) ;
sys_rst_n <= 1'b1 ;
#( 210 ) ;
sys_rst_n <= 1'b0 ;
#( CYCLE * 10 ) ;
sys_rst_n <= 1'b1 ;
#( CYCLE * 1000 ) ;
end
always #( CYCLE / 2 ) sys_clk = ~sys_clk ;
endmodule
