基于FPGA的流水灯设计

描述

设计规划

依次点亮4个LED灯,实现流水灯的效果,两灯之间点亮间隔为0.5s,LED灯一次点亮持续时间0.5s。

LED灯低电平点亮,因此流水灯应该是1110-1101-1011-0111-1110-1101-...

时钟信号

首先是时钟信号、复位信号,由于需要计时,我们还要产生一个计数器cnt。然后还需要产生一个cnt_flag脉冲标志信号作为流水切换的标志,每当计数器计数到24_999_998时拉高并只产生一个时钟的高电平(高电平出现LED状态就开始切换)。最重要的是,流水灯的实现是通过左移操作,无法直接通过led_out的左移实现,因此需要定义一个led_out_reg(led_out从1110左移一次是1100,会有两个灯点亮,而led_out_reg是LED的位反0001,左移一次是0010,取反后led_out是1101,就能实现流水的需求)。

编写代码

module water_led #( parameter CNT_MAX =25'd24_999_999) ( input wire sys_clk , input wire sys_rst_n , output wire [3:0] led_out );//reg definereg [24:0] cnt ; reg cnt_flag ; reg [3:0] led_out_reg ;//cnt:计数器计数500msalways@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n ==1'b0) cnt <=25'b0;elseif(cnt == CNT_MAX) cnt <=25'b0;elsecnt <= cnt +1'b1;//cnt_flag:计数器计数满500ms标志信号always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n ==1'b0) cnt_flag <=1'b0;elseif(cnt == CNT_MAX -1) cnt_flag <=1'b1;elsecnt_flag <=1'b0;//led_out_reg:led循环流水always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n ==1'b0) led_out_reg <=4'b0001;elseif(led_out_reg ==4'b1000&& cnt_flag ==1'b1) led_out_reg <=4'b0001;elseif(cnt_flag ==1'b1) led_out_reg <= led_out_reg < <1'b1;//左移assign led_out = ~led_out_reg; endmodule

三个中间信号的定义:cnt,cnt_flag,led_out_reg。

1、cnt:计数器变化的条件是时钟上升和复位有效(复位下降),复位信号有效时cnt变为低电平;计满时清零;其他时刻+1。

2、cnt_flag:计数器计满的脉冲标志信号,变化条件和cnt一样,复位有效时变为低电平;计满前一个时钟拉高;其他时刻都为0,这样就能成为一个脉冲信号,并在计满前拉高,标志led要左移。

3、led_out_reg:暂存led灯状态,可以直接对这个信号进行操作来控制LED灯。复位和初始时是最右边的灯亮,反推出led_out_reg=0001;当最左边的灯亮且计满标志信号拉高时,令最右边的灯亮led_out_reg=0001;当计满标志信号拉高时,led_out_reg左移。而控制LED电平的输出信号led_out是led_out_reg的按位取反。

时钟信号

编写testbench

`timescale1ns/1ns moduletb_water_led();//wire definewire [3:0] led_out ;//reg definereg sys_clk ; reg sys_rst_n ;//初始化系统时钟、全局复位initial begin sys_clk =1'b1; sys_rst_n <=1'b0;#20sys_rst_n <=1'b1; end//sys_clk:模拟系统时钟,每10ns电平翻转一次,周期为20ns,频率为50MHzalways#10 sys_clk = ~sys_clk;//-------------------- water_led_inst --------------------water_led#(.CNT_MAX (25'd24) ) water_led_inst ( .sys_clk (sys_clk ),//input sys_clk.sys_rst_n (sys_rst_n ),//input sys_rst_n.led_out (led_out )//output [3:0] led_out); endmodule

testbench代码是非常熟悉的,信号定义,初始化,实例化。

对比波形

时钟信号

时钟信号

1110-1101-1011-0111分别对应了十六进制的e,d,b,7

由于在testbench模块,为了节省时间将CNT_MAX设置成24,因此24个时钟脉冲LED的状态就会发生变化,波形和我们预想的一致。

分配管脚

时钟信号

时钟信号

时钟信号

时钟信号

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表德赢Vwin官网 网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分