基于FPGA四位闪烁灯的实现

1、设计要求

        本工程使用4个LED灯来实现闪烁功能。工程的工作时钟为50MHZ,即时钟周期为20ns。具体要求为:首先LED0灭一秒,接着亮1秒后变暗;接着LED1灭1秒,然后亮2秒后变暗,接着LED2灭1秒,然后亮3秒后变暗,最后LED3灭一秒,亮4秒后变暗,一个循环结束。之后按照此规律进行循环。也就是说,四个LED灯依次闪烁,达到隔1秒亮N秒的要求。N为1、2、3、4秒,之后循环。

2、设计实现   

         根据设计需求,将LED变化规律转化为数字信号。led0暗了1秒,亮了1秒,随后变暗,led1暗了1秒,亮了2秒,随后变暗,led2暗了1秒,亮了3秒,随后变暗,led3暗了1秒,亮了4秒,一个循环结束。由此可知一个循环持续14s的时间。画出如图2-1LED 变化规律波形图。

 图2-1  LED 变化规律图

         根据波形图,搭建设计框架。采用两个计数器来实现。一个计数器来计数时钟时间,另一个计数器来计数一个循环的第几个1秒。定义cnt0来计数时钟时间,cnt1来计数循环内的第几个1秒。

          确定顶层信号。想要控制led灯亮灭需要FPGA产生一个信号,假定这一信号为led,将其连接到led上。要控制led灯亮,FPGA将信号输出为0,要控制led灯灭,FPGA将信号输出为1。FPGA的时钟信号为clk,复位信号为rst_n。由此可知工程需要的信号:时钟clk,复位信号rst_n,输出信号led0、led1、led2、led3。

        2.1 时钟的计数

//计数器cnt0计数时钟个数
//便于仿真,此处将100看作是1s,实际应为50,000,000

reg [6:0]cnt0;   //cnt0位宽应为[25:0]cnt0;
wire add_cnt0;
wire end_cnt0;


always @(posedge clk or negedge rst_n)
	if (rst_n == 0) begin
		cnt0<=0;
	end
	else if(add_cnt0)begin
		if(end_cnt0)
			cnt0<=0;
		else 
			cnt0<=cnt0+1;
	end
 
 assign add_cnt0 =1;
 assign end_cnt0 = add_cnt0 && cnt0==100-1; 

        2.2循环内第几个1秒的实现

//计数器cnt1计数次数,即计第几个1s


reg [3:0]cnt1;
wire add_cnt1;
wire end_cnt1;


always @(posedge clk or negedge rst_n)
	if (rst_n == 0) begin
		cnt1<=0;
	end
	else if(add_cnt1)begin
		if(end_cnt1)
			cnt1<=0;
		else 
			cnt1<=cnt1+1;
	end
 
 assign add_cnt1 = end_cnt0;
 assign end_cnt1 = add_cnt1 && cnt1==14-1;

         2.3ledd灯的实现

//实现led0的功能
 
always @(posedge clk or negedge rst_n)
	if (rst_n == 0) begin
		led0<=1;
	end
	else if(add_cnt1 && cnt1==1-1)begin
		led0<=0;
		end
	else if(add_cnt1 && cnt1==2-1)begin
	   led0<=1;
		end

3、整体功能代码实现

module huxiled(
	clk  ,
	rst_n,
	led0 ,
	led1 ,
	led2 ,
	led3
	
);

//定义输入输出端口

input   clk  ;
input   rst_n;
output  led0 ;
output  led1 ;
output  led2 ;
output  led3 ;
reg     led0 ;
reg     led1 ;
reg     led2 ;
reg     led3 ;

//计数器cnt0计数时钟个数

reg [6:0]cnt0;
wire add_cnt0;
wire end_cnt0;


always @(posedge clk or negedge rst_n)
	if (rst_n == 0) begin
		cnt0<=0;
	end
	else if(add_cnt0)begin
		if(end_cnt0)
			cnt0<=0;
		else 
			cnt0<=cnt0+1;
	end
 
 assign add_cnt0 =1;
 assign end_cnt0 = add_cnt0 && cnt0==100-1; //便于仿真,此处将100看作是1s

//计数器cnt1计数次数,即计第几个1s


reg [3:0]cnt1;
wire add_cnt1;
wire end_cnt1;


always @(posedge clk or negedge rst_n)
	if (rst_n == 0) begin
		cnt1<=0;
	end
	else if(add_cnt1)begin
		if(end_cnt1)
			cnt1<=0;
		else 
			cnt1<=cnt1+1;
	end
 
 assign add_cnt1 = end_cnt0;
 assign end_cnt1 = add_cnt1 && cnt1==14-1;
 
 //实现led0的功能
 
always @(posedge clk or negedge rst_n)
	if (rst_n == 0) begin
		led0<=1;
	end
	else if(add_cnt1 && cnt1==1-1)begin
		led0<=0;
		end
	else if(add_cnt1 && cnt1==2-1)begin
	   led0<=1;
		end
 
 //实现led1的功能
 
always @(posedge clk or negedge rst_n)
	if (rst_n == 0) begin
		led1<=1;
	end
	else if(add_cnt1 && cnt1==3-1)begin
		led1<=0;
		end
	else if(add_cnt1 && cnt1==5-1)begin
	   led1<=1;
		end
		
//实现led2的功能
 
always @(posedge clk or negedge rst_n)
	if (rst_n == 0) begin
		led2<=1;
	end
	else if(add_cnt1 && cnt1==6-1)begin
		led2<=0;
		end
	else if(add_cnt1 && cnt1==9-1)begin
	   led2<=1;
		end
		
//实现led3的功能
 
always @(posedge clk or negedge rst_n)
	if (rst_n == 0) begin
		led3<=1;
	end
	else if(add_cnt1 && cnt1==10-1)begin
		led3<=0;
		end
	else if(add_cnt1 && cnt1==14-1)begin
	   led3<=1;
		end
		
		
endmodule 

4、基于modelsim仿真波形结果

 由上图仿真波形可知设计符合要求。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值