|
1. 程序分析
2. RTL分析
3. 功能仿真
4. 时序仿真
1. 程序分析(参考iCore在CPLD上面实现):
//--------------------Timescale---------------------------//
`timescale 1 ns / 1 ps
//--------------------Module_Beep-------------------------//
module beep(
CPLD_CLK,
Beep
);
input CPLD_CLK;
output Beep;
//板载晶振CPLD_CLK为50MHz
//--------------------RST_n-------------------------------//
/*
下面的这个程序非常的好,方便于那些没有外置复位按键的。
*/
reg [1:0] cnt = 2'd0;
always @(posedge CPLD_CLK)
if (cnt == 2'd3)
cnt <= 2'd3;
else
cnt <= cnt + 1'd1;
wire RST_n = (cnt == 2'd3); //上电复位,3个时钟周期后RST_n一直为1
//--------------------CLK_5MHz----------------------------//
/*
下面的这个程序做一个十分频
*/
reg [4:0] cnt_5MHz = 4'd0;
always @(posedge CPLD_CLK or negedge RST_n)
if (!RST_n)
cnt_5MHz <= 4'd0;
else if (cnt_5MHz == 4'd9)
cnt_5MHz <= 4'd0;
else
cnt_5MHz <= cnt_5MHz + 1'd1;
wire CLK_5MHz = (cnt_5MHz == 4'd9); //经10分频得到CLK_5MHz
//--------------------T_600ms-----------------------------//
/*
这里是每过600毫秒状态切换一次
*/
parameter T_600ms = 22'd300_0000; //定时600ms
reg [2:0] state = 3'd0; //8个发音状态
reg [21:0] cnt_600ms = 22'd0; //定时600ms计数器
always @(posedge CPLD_CLK or negedge RST_n)
if (!RST_n)
begin
state <= 3'd0;
cnt_600ms <= 22'd0;
end
else if (CLK_5MHz)
begin
if (cnt_600ms == T_600ms) //计时600ms
begin
cnt_600ms <= 22'd0;
state <= state + 1'd1; //每600ms,state加1,从0~7循环计数
end //在8个状态之间一直循环
else
cnt_600ms <= cnt_600ms + 1'd1; //定时计数器计数
end
//--------------------Scale-------------------------------//
/*
选择相应的状态进行输出
*/
parameter scale1 = 12'd3822, //“duo”音对应的频率值
scale2 = 12'd3405, //“rui”音对应的频率值
scale3 = 12'd3034, //“mi”音对应的频率值
scale4 = 12'd2865, //“fa”音对应的频率值
scale5 = 12'd2551, //“se”音对应的频率值
scale6 = 12'd2273, //“la”音对应的频率值
scale7 = 12'd2024, //“xi”音对应的频率值
scale8 = 12'd1911; //“duo”音(比第一个“duo”音高一个八度)
reg [11:0] scale = 12'd0; //控制在每个状态的频率值
always @(posedge CPLD_CLK or negedge RST_n)
if (!RST_n)
scale <= 12'd0;
else
case (state)
3'd0: scale = scale1;
3'd1: scale = scale2;
3'd2: scale = scale3;
3'd3: scale = scale4;
3'd4: scale = scale5;
3'd5: scale = scale6;
3'd6: scale = scale7;
3'd7: scale = scale8;
endcase //在8个音之间一直循环,每个音发声时长600ms
//--------------------Beep--------------------------------//
reg Beep_r = 1'd0; //蜂鸣器寄存器
reg [11:0] cnt_scale = 12'd0; //频率计数器
always @(posedge CPLD_CLK or negedge RST_n)
if (!RST_n)
begin
Beep_r <= 1'd0;
cnt_scale <= 12'd0;
end
else if (CLK_5MHz)
begin
if (cnt_scale >= scale) //达到设定频率值
begin
cnt_scale <= 12'd0;
Beep_r <= !Beep_r; //蜂鸣器发出与设定频率值对于的音
end
else
cnt_scale <= cnt_scale + 1'd1; //频率计数器计数
end
assign Beep = Beep_r; //蜂鸣器发音
//--------------------Endmodule---------------------------//
endmodule |
|