第一章 流水灯
目录
新建工程
套用正点原子FPGA教学视频工程文件模板
新建一个文件夹,起名test_led,用于本次流水灯实验。
打开quartus ii,新建一个工程,路径为刚刚新建的文件夹下的par文件,工程名为test_led。
注意:文件路径不要出现中文!!!
找到FPGA开发板的芯片系列和型号。
下一步,选取Verilog HDL语言。
完成。
新建一个Verilog HDL file。
好,工程新建完成。
Verilog HDL流水灯代码
任务:实现流水灯,流水灯速度为1s。
流程图:
代码:
module test_led
(
input clk, // 时钟
input rst_n, // 复位
output reg [3:0] led // led
);
reg [27:0] timer; //28位计数器
parameter time_count = 28'd199_999_999; //50M时钟,计满时间为(1/50M)*(time_count+1) = 4s,实际值28'd199_999_999,仿真把值改成28'd19
// 计数器,计满为4s
always@(posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
timer <= 28'd0;
else if (timer == time_count)
timer <= 28'd0;
else
timer <= timer + 28'd1;
end
//流水灯
always@(posedge clk or negedge rst_n)
begin
if (!rst_n)
led <= 4'b1111; //灯全灭
else if (timer == 28'd49_999_999) //计数在第一秒,实际值28'd49_999_999,仿真把值改成28'd4
led <= 4'b1110; //亮第一盏led
else if (timer == 28'd99_999_999) //计数在第二秒,实际值28'd99_999_999,仿真把值改成28'd9
led <= 4'b1101; //亮第二盏led
else if (timer == 28'd149_999_999) //计数在第三秒,实际值28'd149_999_999,仿真把值改成28'd14
led <= 4'b1011; //亮第三盏led
else if (timer == 28'd199_999_999) //计数在第四秒,实际值28'd199_999_999,仿真把值改成28'd19
led <= 4'b0111; //亮第四盏led
end
endmodule
代码讲解
配置输入、输出引脚
输出为4个led灯,所以定义为四位的寄存器类型。
定义计数器、参数类型变量
定义一个28位计数器用于计数。
这里说明一下为什么要定义28位的计数器,因为FPGA输入的时钟频率为50Mhz(外部晶振起振),有4盏led灯,需要计数4s,每隔一秒改变一次led的寄存器状态,以一次时钟周期计数一次,计满4s总共需要4s/20ns = 200000000次。
用计算机算一下,最后得出二进制数至少需要28位(可以多但是不可以少,少了会溢出)。
定义一个参数类型time_count用于判断计数是否达到200000000次,即4s的时间。
编写always块
计数器
这一段非常好理解。
每当时钟上升沿到来时判断计数器是否计满4s所需的次数,如果计满则清空计数器,如果没有计满,就自增。当复位下降沿信号到来时清空计数器。
流水灯
查看led对应的原理图。
得知4盏led是共阳的,即全部点亮需要拉低四个io口。
上面的计数器已经在计时,所以只需要判断计时是否达到想要的时间从而改变led寄存器状态。
当计数计数到49 999 999即第1s时,改变寄存器状态,点亮第一盏led。
当计数计数到99 999 999即第2s时,改变寄存器状态,点亮第二盏led。
当计数计数到49 999 999即第3s时,改变寄存器状态,点亮第三盏led。
当计数计数到49 999 999即第4s时,改变寄存器状态,点亮第四盏led。
如此循环形成流水灯。
程序综合与仿真
Verilog HDL代码写完检查无误后进行程序综合
综合完成,没有错误。
创建仿真文件
接下来需要设置一下引脚信号。
这里我们可以看到,其实仿真并没有我们想要的效果。
原因是因为仿真图形中是0ns~1000ns,而我们led寄存器变换时间是1s,远远大于这个范围,所以我们需要改一下源代码中的计数值。
再综合一次,综合好后打开我们刚才创建的仿真文件。
开始仿真
分析仿真图形证明代码逻辑是没有问题的。
再返回到源代码,把仿真值改成实际值,记得改完后要再综合一次!!!
进入下一步操作。
引脚分配与程序烧录
引脚分配
查询板子的引脚分配表。
Ok,引脚分配完成。
程序烧录
非固化烧录
非固化烧录程序是暂存在usb blester里面的,当断电重启时程序就会擦除,需要重新烧录。非固化烧录的操作比较快速、简单,一般用于调试程序。
没有驱动的话是因为驱动没有安装,网上有相关教程安装驱动。
给板子上电,上电后烧录!!!
实验现象
固化烧录
配置好后再综合一次!!!
实验现象
由于我的板子固化和非固化jtag的接口是不一样的,所以需要更改接口。
另一种配置固化烧录方式
这里需要根据你自己板子信号来选。
这时打开烧录,多了一个jic文件,用JTAG模式烧录就行,这种情况适应于非固化和固化共用一个JTAG口的时候。