FPGA学习—流水灯

FPGA学习—流水灯,第1张

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的输出进行控制。总体还是比较简单的,如果有误请大佬指出,后续将附上工程文件。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/794499.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-06
下一篇 2022-05-06

发表评论

登录后才能评论

评论列表(0条)

保存