FPGA开发(二) 第一个工程----------流水灯的实现

该工程主要是实现流水灯,即控制开发板上的四个LED灯间隔一秒钟,依次亮起,完成循环往复的流水。

首先我们打开Quartus,新建一个工程(file->new porject wizard)

选择一个合适的路径,

选择自己对应的Device类型,类型可以在自己的开发板上面看到,这里我是用的是黑金A301的开发板,选择Device如下:

之后点击Finish,完成工程的创建。

接下来我们新建一个Verilog HDL文件(File->new->Verilog HDL file)即可开始编写我们的控制程序。

       首先,我们分析一下需求,实现四个灯,间隔一秒,那么首先我们需要产生一个一秒钟的定时,而完成一个周期需要的时间是4秒钟。因此我们需要一个时钟信号,同时需要一个存储时间的变量,当变量到达4秒时清零重新计数,当变量是1秒、2秒、3秒、4秒的时候,我们对应不同灯的状态即可,博主使用的开发板的时钟为50M,一个脉冲为20ns,计时一秒钟需要计时到50 000 000,即从0到49 999 999。由于一般的程序都需要有复位操作,我们加入复位输入。

      因此,模型的输入为时钟信号和复位输入,输出为led控制信号。

      程序中一方面我们需要不断的根据时间单位更新变量的值,另一方面需要根据变量的值更新输出的状态,因此需要两个always语句。

      我们首先学习 一下timescale的用法:

       格式为:`timescale 仿真时间单位/时间精度

       用于说明仿真时间单位和时间精度的数字只能是1、10、100,不能为其它的数字。而且,时间精度不能比时间单位还要大。最多两则一样大。时间精度就是模块仿真时间和延时的精确程序,比如:定义时间精度为10ns, 那么时序中所有的延时至多能精确到10ns,而8ns或者18ns是不可能做到的。 在编译过程中,timescale指令影响这一编译器指令后面所有模块中的时延值,直至遇到另一个timescale指令resetall指令。在verilog中是没有默认timescale的,一个没有指定timescale的verilog模块就有可能错误的继承了前面编译模块的无效timescale参数。

       本次实验,我们采用的时间精度为1ps,仿真时间单位为1ns。相应的我们可以写出下面的程序。

`timescale 1ns/1ps//仿真时间单位1ns 时间精度1ps
module led_test
(
	input clk,
	input rst_n,//输入为时钟信号和复位信号
	output reg[3:0] led//输出为led控制信号
);
reg[31:0] timer;//中间变量存储时间

always@(posedge clk or negedge rst_n)// 在时钟的上升沿或者复位的下降沿执行
begin
	if(rst_n==1'b0)
		timer <= 32'd0;//如果按下复位键,变量清零
	else if(timer ==32'd199_999_999)
		timer <= 32'd0;//如果变量够4秒之后 ,清零
	else 
	timer <= timer +32'd1; //否则变量不断+1
end

always@(posedge clk or negedge rst_n)//检测变量的值,因为我们是50Mhz的晶振,因此可以确定下面的值 
begin
	if(rst_n == 1'b0)
		led <= 4'b0000;
	else if(timer ==32'd49_999_999)
		led <= 4'b0001;
	else if(timer == 32'd99_999_999)
		led <=4'b0010;
	else if(timer == 32'd149_999_999)
		led <=4'b0100;
	else if(timer == 32'd199_999_999)
		led <=4'b1000;
end

endmodule

点击保存之后,文件会默认添加至我们当前的工程,在project navigator中选择file即可查看当前添加的文件。我们选择一个文件可以右键set as top-level entity,将其设置为顶层实体。

由于我们在程序中没有同时使用所有的管脚,而这些管教通常接的其他原件,为了防止原件损坏,我们需要设置未使用管教的默认状态,(选择Assignment->Device->Device and pin Options->unused pin)将Reserve unused pins设置为As input tri-stated设置为三泰输入即可。此外还需要在Voltage选项,将Default I/O standard设置为3.3-V LVTTL。在Dual-Purpose Pins中设置多用途 IO,全部做为普通 IO如下图所示。

之后我们就可以进行预编译看看工程中是否有错误,在Task内选择compile  designe右键选择start即可。出现下图即没有编译错误。

 接下来即可进行管脚的映射分配,因为我们的模型中,只有输出的寄存器,我们需要将寄存器和实际进行连接。选择Assignment->Pin planner在location选项中选择对应的管脚即可。这里需要根据自己的开发板的电路图进行选择,否则不会有对应的现象,博主的电路图如下,

 因此对应的管教分配为

此时,再次进行编译 ,在output文件夹下可以看到test_led.sof的一个文件,点击上方的programmer图标即可出现下载界面,

此时点击start即可实现程序的下载,如果右侧出现100%successfully则表示程序下载成功,可以再开发板上看到流水灯的现象。

 

需要注意的是此时的程序并没有固化到Flash因此 断电之后程序就不存在了,需要固话可以采用以下的方式。

选择File -> Convert Programming Files 选择Programming file type为JTAG Indirect Configuration File(.jic) Configuration device根据开发板型号选择。点击Add Device,选择对应的开发板类型,在SOF Data栏,点击Add File.,选择前面生成的流水灯 led_test.sof 文件,点击generate之后生成jic文件。

之后打开下载管理界面,删除其他已有的下载文件,添加上面生成的 jic 文件,只保留一个 jic 文件。选择Program/Configure,点击start之后下载成功,程序固化到了flash。

本实验的工程下载地址:https://download.csdn.net/download/qq_34020487/12244599

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页