1.原理
计划是,生成不同的7个频率控制蜂鸣器发声,每个音调发声0.5秒。
50MHZ计数0.5秒,50MHZ一个周期20ns,要计数0.5秒 ,0.5/0.000_000_02s=25000_000个时钟周期。因为是从0开始计数,所以计数的最大值是0-2499_999。
用一个计数器计数发音的7个0.5秒,当成是一个循环。
1/262hz=0.0038167938931298s,约等于3816794 ns。因此3816794/20=190,839.7。约等于190840。也就是说要计数0-190839个时钟周期才是262hz。占空比是50%(占空比 :
是一个脉冲周期内,高电平的时间与整个周期时间的比例)。
注意:
最后一个else在时序逻辑中可以不写,但在组合逻辑中一定要写。
2.1 beep.v
module beep #(
parameter CNT_MAX=25'd24_999_999,
parameter DO =18'd190839,
parameter RE =18'd170067,
parameter MI =18'd151415,
parameter FA =18'd143265,
parameter SO =18'd127550,
parameter LA =18'd113635,
parameter XI =18'd101214
)
(
input wire sys_clk,
input wire sys_rst_n,
output reg beep
);
reg [24:0] cnt;
reg [2:0] cnt_500ms;
reg [17:0] freq_cnt;
reg [17:0] freq_data;
wire [16:0] duty_data;
assign duty_data=freq_data>>1;
always@(posedge sys_clk or negedge sys_rst_n )
if(sys_rst_n==1'b0)
cnt<=25'd0;
else if(cnt==CNT_MAX)
cnt<=25'd0;
else
cnt<=cnt+1'b1;
always@(posedge sys_clk or negedge sys_rst_n )
if(sys_rst_n==1'b0)
cnt_500ms<=3'd0;
else if((cnt_500ms==3'd6)&&(cnt==CNT_MAX))
cnt_500ms<=3'd0;
else if(cnt==CNT_MAX)
cnt_500ms<=cnt_500ms+1'b1;
else
cnt_500ms<=cnt_500ms;
always@(posedge sys_clk or negedge sys_rst_n )
if(sys_rst_n==1'b0)
freq_cnt<=18'd0;
else if((cnt==CNT_MAX)||(freq_cnt==freq_data))
freq_cnt<=18'd0;
else
freq_cnt<=freq_cnt+1'b1;
always@(posedge sys_clk or negedge sys_rst_n )
if(sys_rst_n==1'b0)
freq_data<=DO;
else case(cnt_500ms)
3'd0: freq_data=DO;
3'd1: freq_data=RE;
3'd2: freq_data=MI;
3'd3: freq_data=FA;
3'd4: freq_data=SO;
3'd5: freq_data=LA;
3'd6: freq_data=XI;
default: freq_data=DO;
endcase
always@(posedge sys_clk or negedge sys_rst_n )
if(sys_rst_n==1'b0)
beep<=1'b0;
else if(freq_cnt>=duty_data)
beep<=1'b1;
else
beep<=1'b0;
endmodule
tb_beep.v
`timescale 1ns/1ns
module tb_beep();
reg sys_clk;
reg sys_rst_n;
wire beep;
initial
begin
sys_clk=1'b1;
sys_rst_n<=1'b0;
#20
sys_rst_n<=1'b1;
end
always #10 sys_clk=~sys_clk;
beep #(
.CNT_MAX(25'd24_999_999),
.DO (18'd190839) ,
.RE (18'd170067) ,
.MI (18'd151415) ,
.FA (18'd143265) ,
.SO (18'd127550) ,
.LA (18'd113635) ,
.XI (18'd101214)
)
beep_inst(
.sys_clk (sys_clk),
.sys_rst_n(sys_rst_n),
.beep (beep)
);
endmodule