FPGA流水灯

FPGA流水灯

参考博客:(一)FPGA流水灯的实现
第一次在CSDN上写博客,记录一下自己学习FPGA的历程吧,也是对CSDN这个平台的回馈。过去大半年在这上面学习了不少知识,现在也希望能给别人一些帮助。下面言归正传:
“流水灯”应该是每一个开发板的初学者都要做的一步吧,这两天对FPGA的板子有了一个初步的认识,今天就花了半天(原谅我学得有点慢),写了一个八位的LED流水灯。
用的是Quartus 13.0,代码如下:

module self_train1(clk,rst_n,led);//8位LED流水灯

input clk;	 	//系统时钟,50MHz
input rst_n; 	//全局复位,低电平有效

output reg[7:0] led;		//led输出,高电平灯亮
	
//定义时间计数器
	reg [31:0] timer;
	
//计数进程
always@(posedge clk or negedge rst_n)//只要括号中的任意信号发生变化,就执行always@里面的内容
	begin
		if(rst_n==1'b0)//'b'表示二进制
			timer<=32'd0;//'d'表示十进制;如果复位键按下,时间计数归零
		else if(timer==32'd199_999_999)//'_'占位符,没有实际意义
			timer<=32'd0;//如果时间计数到4s,时间计数归零
		else
		timer<=timer+32'd1;//正常情况下,每来一个时钟脉冲,时间计数加1
		
end

//led控制进程
always@(posedge clk or negedge rst_n)
	begin
		if(rst_n==1'b0)
			led<=8'b0000_0000;//如果复位键按下,所有的灯都为'0',熄灭
		else if(timer==32'd24_999_999)
			led<=8'b0000_0001;//当时间计到0.5s时,第一个LED灯亮
		else if(timer==32'd49_999_999)
			led<=8'b0000_0010;//当时间计到1s时,第二个LED灯亮
		else if(timer==32'd74_999_999)
			led<=8'b0000_0100;
		else if(timer==32'd99_999_999)
			led<=8'b0000_1000;
		else if(timer==32'd124_999_999)
			led<=8'b0001_0000;
		else if(timer==32'd149_999_999)
			led<=8'b0010_0000;
		else if(timer==32'd174_999_999)
			led<=8'b0100_0000;
		else if(timer==32'd199_999_999)
			led<=8'b1000_0000;
	
end

endmodule

代码的原理还是很简单的,具体可以参考我开头的参考博客,我只是比他多了4个LED灯,位数相应的增加了。
代码编写完了之后,我们让软件给我们分析一遍,看有没有错误。点击软件最上方Processing / Start / Start Analysis & Synthesis,或者直接点击下图红色方框中的键:
或者直接点击红色方框中的键
分析成功的话会显示如下图:在这里插入图片描述

·
·
然后,我们进行功能仿真,也叫RTL行为级仿真或者前仿真。

首先编辑test bench文件,代码如下:

`timescale 1ns/1ns//前面的1ns表示时延单位,后面的1ns表示时延精度

module self_train1_tb;
reg clk;
reg rst_n;

wire [7:0]led;

self_train1 u1(
.clk(clk),
.rst_n(rst_n),
.led(led)
);

initial clk=1;//任意赋予clk一个初值,也可赋值0
always #10 clk = ~clk;//让clk的值每10ns反向变化一次,形成50MHz的脉冲

initial begin
	rst_n=1'b0;
	#100;//'#'表示延时
	rst_n=1'b1;
	#1000000000;//我在这里只仿真了初始的1s,因为电脑太老了,运行速度太慢
	$stop;
end

endmodule

我稍后会再写一篇功能仿真的软件操作步骤,毕竟Quartus是英文的,对自学的同学来说不太友好,并且这部分操作确实有点麻烦,将心比心,我尽量把我觉得在初学阶段可能碰到的问题写清楚,多帮助一些人。

下面,我们运行RTL Simulation,结果如下:
在这里插入图片描述
我们可以看到。在500ms的时候,第一个LED灯的状态由0变为1,第一个灯亮。1000ms的时候,第一个灯由1变为0,第一个灯灭,同时,第二个LED灯由0变为1,第二个灯亮。以此类推,仿真结果和我们想要的结果一样。因为电脑太老了,运行速度慢,我就只仿真了初始的1s。
·
还有一个时序仿真我就不做了,它在功能仿真的基础上加入了时延,更接近板子运行时候的真实情况。

下面进行全编译,点击Start Complation。

PS:
quartus软件可以根据我们编写的程序生成下面类似数电里的电路图:
在这里插入图片描述
大家可以在左侧找到,双击即可:
在这里插入图片描述

然后,我们进行烧写前的最后一步,分配IO:
点击Assignments / Pin Planner
在这里插入图片描述
根据查找板子的使用说明书,找到合适的引脚,相对应的输入红色方框中。可以直接在其中输入“y2”、“g21”等引脚号,不用区分大小写,然后按回车键;也可以直接复制粘贴引脚表格中的引脚号,这里就不详细说了。
设置好引脚后,不需要保存,直接关闭引脚设置窗口。

最后就是将我们的程序烧写到板子里去。

将开发板与电脑连接(如果在电脑上读不出开发板,可能是需要手动安装板子的驱动,我当时也碰到了这个问题,可以百度解决),点击Programmer,在跳出的窗口中点击Add File…,将output_files文件夹里面的.sof文件打开到刚刚跳出的窗口,最后点击Start,就将程序烧入FPGA开发板中了。

如果到这里一切顺利,那么恭喜你,完成了开发板的第一个基础程序开发,完结撒花!!!

ps:文中如有错误或不足,欢迎各位大佬予以批评指正。

猜你喜欢

转载自blog.csdn.net/m0_47868423/article/details/109895726