首页 > 代码库 > 永远的流水灯(Verilog)

永远的流水灯(Verilog)

1. 为了更好地学习FPGA和深入理解Verilog语法,首先从最简单的流水灯做起。虽然简单,但是也包含了不少知识。通过这次实验项目,可以了解开发软件的使用及Verilog的编程方法,熟悉模块化设计的方法。

2. 该项目主要实现的功能为:

(1)10位的流水灯

(2)中间两个led灯每隔100ms闪烁一次

(3)两边的led灯每隔100ms流动一下,从中间向两边流水。

3.  具体实现如下

   (1)首先定义一个时间计数寄存器counter,每当达到预定的100ms时,计数寄存器就清零,否则的话寄存器就加1。然后计算计数器计数的最大值。时钟频率为50MHZ,也就是周期为1/50M 为20ns,要计数的最大值为T100MS= 100ms/20ns-1 = 4999_999。

代码实现为

always @ (posedge clk or negedge rst)

if(!rst)      //高电平复位

counter<=25‘d0;

else if(counter==T100ms)

counter<=25‘d0;

else

counter<=counter+1‘b1;

   (2)如何控制led的亮灭呢,无非就是给端口赋高低电平,有的是高电平亮,有的是低电平亮,我用的FPGA学习板为高电平亮。每隔100ms对其端口值取反就可以实现闪烁的led

   (3)流水灯的实现。在FPGA中实现流水灯的方法有很多种,我只列取了三种供参考学习。首先是运用FPGA的并行处理特点,建立四个always模块分别对每隔led分别控制,所对应的时序图如图1-a,每一个模块控制相应的led灯,彼此之间互不影响,依靠总的时钟进行工作。

技术分享

图1-a

这种方法能够充分体现FPGA并行处理的特点,实现起来也很容易。

顶层代码为

moduletop_module(CLK, RSTn, LED_Out);

       input CLK;

       input RSTn;

       output [3:0]LED_Out;

       wire LED1_Out;

       led1_module U1

       (

              .CLK(CLK),

              .RSTn(RSTn),

              .LED_Out(LED1_Out)

       );

       wire LED2_Out;

       led2_module U2

       (

              .CLK(CLK),

              .RSTn(RSTn),

              .LED_Out(LED2_Out)

       );

       wire LED3_Out;

       led3_module U3

       (

              .CLK(CLK),

              .RSTn(RSTn),

              .LED_Out(LED3_Out)

       );

       wire LED4_Out;

       led4_module U4

       (

              .CLK(CLK),

              .RSTn(RSTn),

              .LED_Out(LED4_Out)

       );

       assign LED_Out = {LED4_Out, LED3_Out,LED2_Out, LED1_Out};

第二种方法为循环移位法。通过给led赋初值,然后循环左移或者循环右移,但是需要设置一个条件。否则就会出现溢出的情况。如图2-a设置一个条件当要出现溢出的时候让它回到初始的状态,这样就可以实现流水了。

 技术分享

图2-a

代码实现为

always @(posedge clk or negedge rst)

if(!rst)

led<=4‘b0001;        //初值,最低位led[0]灯亮

else if(counter==T100ms)

begin

if(led==4‘b0000)      //当溢出最高位时

led<=4‘b0001;    //回到复位时的状态

else

led<=led<<1;     //循环左移一位

end

第三种数据拼接法,所谓的数据拼接就把原来的数据拆成一位一位的,在特定位置上拼接上一个数。例如在4位的led的低位拼接一个1. Led[3:0]<={led[2:0],1’b1};接即实现了数据的拼接,当然可以实现任意位,任意bit数的拼。和循环移位类似,数据拼接的实现只是把移位命令改成拼接的命令即可。

 

 

 

永远的流水灯(Verilog)