1. 呼吸灯
呼吸灯指LED灯从暗逐渐变亮,然后又逐渐变暗,本质上就是控制PWM波的占空比,从低到高,再从高到低,不断循环。
FPGA实现呼吸灯代码实现如下:
module led(
input sys_clk,
input sys_rst_n,
output reg led
);
parameter cnt_2us_max=100 -1;
parameter cnt_2ms_max=1000 -1;
parameter cnt_2s_max=1000 -1;
reg [7:0] cnt_2us; //0-99计数 到达99时,得到时间2us
reg [9:0] cnt_2ms; //0-999计数 到达999时,得到时间2ms
reg [9:0] cnt_2s; //0-999计数 到达999时,得到时间2s
reg cnt_flag; //0代表LED逐渐增亮,1代表LED逐渐变暗
//定时器计数
always @ (posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n) begin
cnt_2us<=0;
cnt_2ms<=0;
cnt_2s<=0;
cnt_flag<=1;
end
else begin
cnt_2us<=cnt_2us+1;
if(cnt_2us>=cnt_2us_max) begin
cnt_2us<=0;
cnt_2ms<=cnt_2ms+1;
end
if(cnt_2ms>=cnt_2ms_max && cnt_flag==0) begin
cnt_2ms<=0;
cnt_2s<=cnt_2s+1;
end
if(cnt_2ms>=cnt_2ms_max && cnt_flag==1) begin
cnt_2ms<=0;
cnt_2s<=cnt_2s-1;
end
if(cnt_2s>=cnt_2s_max) begin
cnt_flag=1;
end
if(cnt_2s<=0) begin
cnt_flag=0;
end
end
end
//当cnt_2ms小于cnt_2s时输出高电平,否则输出低电平
always @ (posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n) begin
led<=0;
end
else begin
if(cnt_2ms<=cnt_2s) begin
led<=1;
end
else led<=0;
end
end
endmodule
2.在线逻辑分析仪
这个代码里面有很多个信号,实际写代码时很难一下子全部调通,写出一个没有Bug的代码,
如果烧录到FPGA里面发现LED出现期待的情况咋办?
使用在线逻辑分析仪(ILA)。
在线逻辑分析仪通过一个或多个探针(Probe)来采集希望观察的信号,然后通过片内的 JTAG 硬核组件,将捕获到的数据传送给下载器,进而上传到 Vivado 供用户查看。
三种方法实现ILA的调用
2.1 调IP核:
调用ILA IP核,设置信号个数,以及带宽,然后在模块中调用这个IP核。
缺点:比较麻烦,调试完成后又要重新编译
进入方法:vivado点这个IP Catalog
然后搜索ILA,在Debug里面这里面,点进去之后就可以设置模块属性了,设置信号个数,以及带宽。然后在自己的模块中调用这个IP核
2.2 综合前的信号标记:
调IP核太麻烦了咋办?只有一两个信号也要从到到尾设置一遍,头都大了。
对想要观察的 reg 或 wire 信号添加“Mark Debug”综合属性。
例如:
(* mark_debug = “true” *)reg [6:0] cnt_2us;
这个是在综合之前写在代码里面的,到最后还是得删掉,然后重新编译,也是很麻烦。
2.3 综合后的信号标记:
在综合后的网表中,分别标记要进行调试观察的信号,然后通过一个简单的“Setup Debug”向导来设置各个探针和 ILA IP 核的工作参数,
进入方法:Synthesized design中的Debug里面
找到想要标记的信号,右键进行Mark Debug,我这里已经标记了,所以是灰的
3.在线看信号波形
对信号标记完成之后,接下来就要对在线运行了,将程序烧录到FPGA中。
烧录完成之后,可以发现这里多了一个叫ila的东西,就是前面说的在线逻辑分析仪了
双击打开,然后点击加号就可以添加前面第二节中所标记的信号了
时钟频率50MHz,很快啊,1秒钟50M个数据,那我们咋看嘛,设置触发属性,当信号达到触发条件时,就将把数据传给vivado上面
设置完成之后,就进行数据采集,当ILA发现触发条件到达之后了,就显示出数据了
根据显示的数据,对代码进行调整。不断重复