10ms内依次点亮四个LED。
法一:可以清楚的看到这样一个流水灯的周期为10ms,这里每四分之一个周期拉高一个LED,如此反复。
module lliushuideng(rst_n,clk,led) ;
input rst_n;
input clk;
output[3:0]led;
reg[3:0]led_r ;
reg[17:0] cnt;
always @(posedge clk or negedge rst_n)//计数10ms,晶振为25M的即时钟周期为50ns
if(~rst_n)
cnt<=1'b0;
else if(cnt==18'd199_999)
cnt<=1'b0;
else
cnt<=cnt+1'b1;
always @(posedge clk or negedge rst_n)//每四分之一个流水灯周期依次拉高一个LED
if(~rst_n)
led_r<=4'd0;
else if( (cnt>=18'd0)&&(cnt<18'd50000) )
led_r<=4'd1;
else if( (cnt>=18'd50000)&&(cnt<18'd100000) )
led_r<=4'd2;
else if( (cnt>=18'd100000)&&(cnt<18'd150000) )
led_r<=4'd4;
else
led_r<=4'd8;
assign led=led_r;
endmodule
法二:在法一里面采用了10ms的计数,仔细想想其实可以只用2.5ms计数,然后依靠移位可以实现一样的效果
下面代码是和上面代码不同的地方。
reg[15:0]cnt;
always @(posedge clk or negedge rst_n)
if(~rst_n)
cnt<=1'b0;
else if(cnt==16'd49999)
cnt<=1'b0;
else
cnt<=cnt+1'b1;
always @(posedge clk or negedge rst_n) //每计满2.5ms右移一次
if(~rst_n)
led_r<=4'd1;
else if(led_r==4'd0)//短暂的停留在0000马上变为0001
led_r<=4'd1;
else if(cnt==16'd49999)
led_r<=(led_r<<1) ;
可以看到法二相比法以节约了一些资源。以后在计数器位的选取上要仔细思考,尽可能的节约逻辑资源。
文章评论(0条评论)
登录后参与讨论