应用1:写一个周期变化的流水灯如下图
实现思路:用计数器计数一秒的周期,然后在指定位置实现变化(想象计数器是一个线性尺子,每一个时间长度单位就是一个刻度)
代码框架:计数器实现一秒周期——在0.25秒时拉低点评
module led_run(
Clk,
Reset_n,
Led
);
input Clk;
input Reset_n;
output reg Led;
//计数一秒钟
reg [24:0]counter;
parameter MCNT = 50000000-1;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
counter <= 0;
else if(counter == MCNT)
// else if(counter == 25'd24999)
counter <= 0;
else
counter <= counter + 1'b1;
//控制led
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
led <= 0;
else if(counter == 0)
led <= 1'b1;
else if(counter == 12500000)
led <= 1'b0;
endmodule
注意:为何在0.25秒counter == 12500000而不是== 12500000-1
答:最大值变零的时候还依旧需要耗费一个时钟周期,而在取值的过程中需不要耗费额外的周期
应用2:写一个周期变化的流水灯如下图
按照上面的常规写法就是多写几个else if的分支就行
下面介绍另一种思路,如图,吧最小的变化周期当作一个单位
代码框架:一个周期计数器——周期内最小单位的计数——对每一个单位的电平进行赋值
module led_run(
Clk,
Reset_n,
Led
);
input Clk;
input Reset_n;
output reg Led;
//计数一秒钟
reg [24:0]counter;
parameter MCNT = 50000000-1;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
counter <= 0;
else if(counter == MCNT)
counter <= 0;
else
counter <= counter + 1'b1;
//计数一个周期
reg [24:0]counter0;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
counter0 <= 0;
else if(counter == 12500000)
counter0 <= 0;
else
counter0 <= counter0 + 1'b1;
//控制每一个周期的电平
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
led <= 0;
else begin
case(counter0)
0: led <= 1;
1: led <= 0;
2: led <= 0;
3: led <= 1;
4: led <= 1;
5: led <= 1;
6: led <= 0;
7: led <= 0;
8: led <= 0;
9: led <= 0;
default: led <= led;
endcase
end
endmodule
应用3:每过一段时间执行一轮8个led的状态切换
在上一个代码进行修改即可,使用一个拨码开关来对八个led的状态进赋值,在case语句中把拨码开关赋值到led即可
module led_run(
Clk,
Reset_n,
sw,
Led
);
input Clk;
input Reset_n;
input [7:0] sw;
output reg Led;
//计数一秒钟
reg [24:0]counter;
parameter MCNT = 50000000-1;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
counter <= 0;
else if(counter == MCNT)
counter <= 0;
else
counter <= counter + 1'b1;
//计数一个周期
reg [24:0]counter0;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
counter0 <= 0;
else if(counter == 12500000)
counter0 <= 0;
else
counter0 <= counter0 + 1'b1;
//控制每一个周期的电平
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
led <= 0;
else begin
case(counter0)
0: led <= sw[0];
1: led <= sw[1];
2: led <= sw[2];
3: led <= sw[3];
4: led <= sw[4];
5: led <= sw[5];
6: led <= sw[6];
7: led <= sw[7];
default: led <= led;
endcase
end
endmodule