FPGA学习—流水灯

FPGA学习系列

新人第一次写博客,该系列将不断更新fpga相关知识。有错误的地方希望大佬们可以指出,互相学习,提高水平。谢谢大家。


前言


我使用的是vivado,在编程部分应该就IP核的创建和quartusii不一样,模块代码是可以通用的。后面也会放出工程链接,也会有quartusii和vivado的工程。附带modelsim的仿真文件。

一、原理

(这里是达芬奇pro的原理图)
在这里插入图片描述
LED0~LED3S是FPGA的引脚,很明显当FPGA输出高电平时三极管导通,而FPGA输出电压大约为1.35V所以二极管导通所以点亮led,当FPGA输出低电平时三极管截止,灯灭。

本次我将实现间隔0.5s的流水灯,一共四个灯,系统频率50Mhz,也就是一个周期时20ns,所以要实现0.5s的间隔,相当于要0.5s/20ns个时钟周期,即25000000个时钟周期。

二.代码

代码如下:

module water_led
#(
	parameter	CNT_MAX=25'd25_000_000	
)
(
	input	wire			sys_clk		,	//系统时钟
	input	wire			sys_rst_n	,	//系统复位
	
	output	reg		[3:0]	led				//输出流水灯
);
reg	[24:0]	cnt			;	//间隔计数
reg	[1:0]	led_crtl	;	//流水灯状态
//计数到最大值清0 减1 是因为从0开始计数
always@(posedge sys_clk or negedge sys_rst_n)	begin
	if(!sys_rst_n)
		cnt <= 25'd0;
	else	if(cnt == CNT_MAX - 1'b1)
		cnt <= 25'd0;
	else	
		cnt <= cnt + 1'b1;
end
//每计数到最大值的时候 led_crtl+1 表示亮下一个灯 其余情况不变
always@(posedge sys_clk or negedge sys_rst_n)	begin
	if(!sys_rst_n)
		led_crtl <= 2'd0;
	else	if(cnt == CNT_MAX - 1'b1)
		led_crtl <= led_crtl + 1'b1;
	else
		led_crtl <= led_crtl;
end
//流水灯逻辑 判断led_crtl的值 亮不同的灯
always@(posedge sys_clk or negedge sys_rst_n)	begin
	if(!sys_rst_n)
		led <= 4'd0;
	else	begin
	case(led_crtl)
		2'b00	:	led <= 4'b0001;
		2'b01	:	led <= 4'b0010;
		2'b10	:	led <= 4'b0100;
		2'b11	:	led <= 4'b1000;
		default	:	led<=4'b0000;
		endcase
	end
endmodule



至此,就是一个简单流水灯工程,我是利用一个led_crtl相当于状态机来表示led的亮灭情况。
之所以一开始使用parameter定义CNT_MAX可以方便以后调用模块的时候,方便参数的修改。
cnt的位宽可以利用电脑自带的计算器去计算。如下.
在这里插入图片描述
在这里插入图片描述

看BIN一共25位,所以是25位宽

总结

该工程比较简单,一个计数器进行计数,还有一个led_crtl的状态标志位,对led的输出进行控制。总体还是比较简单的,如果有误请大佬指出,后续将附上工程文件。

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值