EMP570实验一:蜂鸣器
1.程序分析2.RTL分析
3.功能仿真
4.时序仿真
1.程序分析(参考iCore在CPLD上面实现):
//--------------------Timescale---------------------------//
`timescale 1 ns / 1 ps
//--------------------Module_Beep-------------------------//
module beep(
CPLD_CLK,
Beep
);
inputCPLD_CLK;
output Beep;
//板载晶振CPLD_CLK为50MHz
//--------------------RST_n-------------------------------//
/*
下面的这个程序非常的好,方便于那些没有外置复位按键的。
*/
reg 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 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 state = 3'd0; //8个发音状态
reg 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 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 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 看RTL视图是一个好习惯
功能仿真
`timescale 1 ns/ 1 ns
module beep_vlg_tst();
reg CPLD_CLK;
wire Beep;
beep i1 (
.Beep(Beep),
.CPLD_CLK(CPLD_CLK)
);
initial
begin
CPLD_CLK = 0;
forever
#10CPLD_CLK = ~CPLD_CLK;
end
endmodule
做完系统时钟的时钟约束以后的,modelsim仿真图如下
页:
[1]