1、实验平台
软件:PC、Quartus Prime 18.1、Modelsim 10.5b
硬件:Altera FPGA开发板(EP4CE6E22F17C8)
2、实验目的
编写Verilog HDL代码驱动开发板上8颗LED实现流水灯效果
2.1、实验要求
1、每次点亮一颗LED,持续(亮灯)时间,1S
2、方向从右到左,最左边LED亮满1s之后,实现最右边的灯亮
3、实验流程
3.1、实验原理
根据开发板的原理图,可得到以下资料
根据硬件原理图所示,8颗发光二极管,所有的阳极都接通3.3V的正电压,也即————高电平,所以如果我们想要
发光二极管导通的话,需要在阴极接通低电平,就可以让LED亮起来。
3.2、框架设计
由于只是驱动8颗LED,即发光二极管,故可得到以下框架
3.3、功能模块划分
由于本设计比较简单,故没有必要划分多个模块
信号定义
信号名 | 端口类型 | 信号说明 |
---|---|---|
Clk | i | 输入时钟信号,50MHz |
Rst_n | i | 输入复位信号,低电平有效 |
Led[7:0] | o | 输出LED信号,低电平有效 |
3.4、时序信号图
时钟信号:
频率为50MHz,对应周期20ns,50%占空比的方波信号,多用于时序逻辑电路的控制信号;
复位信号:
信号名后加上“_n”,表明该信号为低电平有效,当复位信号有效时,所有时序逻辑恒定在一个固定的状态;
计数器信号:
要产生计时/定时效果,则需要生成计数器完成相应逻辑控制。由于开发板所搭载的晶振为50MHz,也即是说,
1秒钟晶振产生50M—>5000_0000次振动。而verilog所描述的时序逻辑都是基于时钟信号的控制————
上升沿或者下降沿,更新寄存器/触发器的值,我们让计数器在每一次时钟信号的上升沿处更新(自加1),
那么,计数器每计满5000_0000次,就是1s;然后在计满1秒的时候产生1个有效期为1个时钟周期的脉冲信号,
用以驱动LED信号进行变化;
led信号:
系统处于复位状态时,LED全灭或者全亮,其后受计数器信号的驱动,做流水效果。
3.5、代码实现
相信基于以上的讲解,大家都能尝试着自己写出代码,这里给出一份Demo,以供参考:
/*================================================*\
Filename ﹕led_water.v
Author ﹕Adolph
Description ﹕8位流水灯
Called by ﹕No file
Revision History ﹕ 2022-4-18
Revision 1.0
Email﹕ adolph1354238998@gamil.com
\*================================================*/
module led_water(
//端口信号声明
input wire clk ,//50MHz
input wire rst_n ,//reset ,low valid
output [7:0]led_o //最后一个端口信号没有“,”
);
//参数定义
parameter CNT_MAX = 26'd5000_0000;
//内部信号声明
reg [25:0] cnt_1s;//1s 计数器,计数最大值 5000_0000 - 1
wire flag_1s;//计数器每计满1s,使能一个时钟周期
reg [7:0] led_reg;//输出信号的寄存信号
//逻辑实现
//时序逻辑描述1s计数器
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt_1s <= 26'd0;
else if(cnt_1s >= CNT_MAX - 26'd1) //归零条件
cnt_1s <= 26'd0;
else
cnt_1s <= cnt_1s + 26'd1;
end
assign flag_1s = cnt_1s >= CNT_MAX - 26'd1;
//移位实现流水灯
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
led_reg <= 8'b0000_0000;//全亮
else if(flag_1s)
if(led_reg == 8'b0000_0000)
led_reg <= 8'b1111_1110;
else
led_reg <= {led_reg[6:0],led_reg[7]};//拼接实现循环移位
else
led_reg <= led_reg;
end
assign led_o = led_reg;
endmodule
3.6、测试文件
/*================================================*\
Filename ﹕ tb_led_water
Author ﹕ Adolph
Description ﹕ 流水灯仿真测试文件
Called by ﹕ No file
Revision History ﹕ 2022-4-18
Revision 1.0
Email﹕ adolph1354238998@gmail.com
\*================================================*/
`timescale 1ns/100ps //定义仿真系统基本时间单位、时间精度
module tb_led_water();
//激励信号
reg tb_clk ;
reg tb_rst_n ;
//观测信号
wire [7:0] tb_led_o ;
//参数重定义
defparam U_led_water.CNT_MAX = 100;
//模块例化
led_water U_led_water/*例化名称*/(
/*input */.clk (tb_clk ),//50MHz
/*input */.rst_n(tb_rst_n),//low valid
/*output reg [7:0] */.led_o(tb_led_o)
);
//时间生成
initial tb_clk = 1'b0;
always #10 tb_clk = ~tb_clk;
//系统初始化
initial begin
tb_rst_n = 1'b0;
#38 ;
tb_rst_n = 1'b1;
#18000; //系统运行时间??? 2000ns * 9
$stop; //系统函数。暂停仿真
end
endmodule
仿真图
关于Modelsim的使用,请自行百度
跟据仿真波形图,可以看到一切如我们预期那样,实现了LED的循环流水效果。
3.7、上板验证
基于前面的步骤的结束,我们开始上板验证
在quartus的Pin planner 中进行引脚绑定
然后进行全编译,待到全编译通过后,连接好开发板,电源线和下载都要连接好,然后打开电源
下载编程文件
文章来源:https://www.toymoban.com/news/detail-506839.html
如果是第一次使用开发板的童鞋,参看这里更新驱动,切记,前提条件是开发板正确和PC连接,并且已经通电!!!
驱动更新成功后,点击“Start”进行编程,右上角的Progress为下载进度,成功后会有“100% Successful”提示字样,然后在开发板上可以看到相应的效果——流水灯。
文章来源地址https://www.toymoban.com/news/detail-506839.html
4、总结
到这里基本上就结束了,给大家提几点在学习过程中可能会出现的错误
1、我们的文件名和Module后面的模块名要保持一致,不然在仿真的时候会找不到文件的
2、文件编写过程中,除开注释部分,其他的全部使用英文输入法编辑,如果在代码部分出现了中文也会报错
3、reg信号只能在always进程中被赋值,wire型信号只能被assign赋值
...
然后大家可以在提供的基础代码上进行创新,比如:
1、实现流水灯的速率改变,提速或降速
2、流水的方式改变,实现从左至右,然后再从右至左,循环往复
到了这里,关于Verilog 实现流水灯的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!