FPGA流水灯实验

来源:互联网 发布:淘宝助理5.8.5.0下载 编辑:程序博客网 时间:2024/05/06 10:16

           实验 :流水灯实验

一、实验目的  

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

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

 

 

二、实验内容

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

 

 

三、实验原理

1、流水灯电路

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



1、时钟分频模块

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

   

  reg [31:0] clk_count=0;     //寄存器变量,用于时钟分频计数       reg div_clk=0;            //分频后的时钟信号       always@(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 , 因为这里是先检测计数值有没有达到阈值,如果没有才加一,所以当计数值加一达到了阈值之后,要等待下一个时钟上升沿才能进行检测操作。


时钟分频举例:



这里的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 的循环。 



三、程序清单

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;            //分频后的时钟信号       always@(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