欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

FPGA流水灯实验

程序员文章站 2022-07-12 22:36:29
...

           实验 :流水灯实验

一、实验目的  

(1)掌握分频电路的设计方法。

(2)掌握流水灯的设计方法。

 

 

二、实验内容

Basys 2开发板上的晶振产生的50M的脉冲作为时钟信号,先进行分频,然后驱动八个led显示按照设置的模式显示。

 

 

三、实验原理

1、流水灯电路

Basys2板载流水灯的电路如图所示,可以看出流水灯有一个公共地,所以只需要让FAGA引脚输出高电平就可以点亮流水灯

FPGA流水灯实验


1、时钟分频模块

此模块分频后的时钟信号为10HZ

   

  reg [31:0] clk_count=0;     //寄存器变量,用于时钟分频计数
       reg div_clk=0;            //分频后的时钟信号
       aaa@qq.com(posedge CLK or posedge RST)   //等待输入时钟的上升沿
       begin
           if(RST)
           begin
               div_clk<=0;    //复位清零操作
               clk_count<=0;
           end
           else if(clk_count==32'd2499_999)   //计数到达阈值
           begin
               clk_count<=0;               //清零计数值
               div_clk <= ~div_clk;    //div时钟翻转,实现分频
           end
           else
               clk_count <= clk_count+1;     //计数加一
       End

 

 

注意这里分频为什么是2499_999 , 因为这里是先检测计数值有没有达到阈值,如果没有才加一,所以当计数值加一达到了阈值之后,要等待下一个时钟上升沿才能进行检测操作。


时钟分频举例:

FPGA流水灯实验


这里的clk1是时钟取反,clk2为二分频,clk3是四分频


3.流水灯流动使用拼接的方法实现

 

 always @ (posedge div_clk  or posedge RST)
      begin
            if(RST)
                 led_reg <= 8'b0000_0001;   //流水灯复位
            else
                 led_reg<={led_reg[6:0],led_reg[7]};  //位的拼接

        End


 

这里的{led_reg[6:0],led_reg[7]}实际上就是把led寄存器的最高位循环转移到最低位,实现位的流动。利用之前一步分频好的时钟信号,实现以一定频率流动的流水灯。

 

 

4.流水灯相当于用D触发器组成的移位寄存器,如下图所示,若将D0D1相连,在初始给一个高电平脉冲,就可以实现0000 -> 1000 -> 0100 -> 0010 -> 0001 -> 1000 的循环。 

FPGA流水灯实验


三、程序清单

module flowing_led(
    input RST,
    input CLK,
    output [7:0] LED_OUT
    );
    
       reg [7:0] led_reg = 8'b0000_0001;
       
       reg [31:0] clk_count=0;     //寄存器变量,用于时钟分频计数
       reg div_clk=0;            //分频后的时钟信号
       aaa@qq.com(posedge CLK or posedge RST)   //等待输入时钟的上升沿
       begin
           if(RST)
           begin
               div_clk<=0;    //复位清零操作
               clk_count<=0;
           end
           else if(clk_count==32'd2499_999)   //计数到达一定值时
           begin
               clk_count<=0;               //清零计数值
               div_clk <= ~div_clk;    //div时钟翻转,实现分频
           end
           else
               clk_count <= clk_count+1;     //计数加一
       end
 
       
             
      always @ (posedge div_clk  or posedge RST)
      begin
            if(RST)
                 led_reg <= 8'b0000_0001;   //LED寄存器清零
            else      
                 led_reg<={led_reg[6:0],led_reg[7]};   //位的拼接         
        end
        
        assign LED_OUT = led_reg;
endmodule