电子大神的日记本,供应链专家的功夫茶盘,在这里记录、分享与共鸣。

登录以开始

FPGA_简单的流水灯

10ms内依次点亮四个LED。

  • 0~2.5ms 点亮第一个
  • 2.5ms~5ms点亮第二个
  • 5ms~7.5ms点亮第三个
  • 7.5ms~10ms点亮第四个

法一:可以清楚的看到这样一个流水灯的周期为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) ;

可以看到法二相比法以节约了一些资源。以后在计数器位的选取上要仔细思考,尽可能的节约逻辑资源。

博主
544532103
544532103's Blog
544532103
点击跳转