今天弄个led翻转,板子已经在路上了...周日应该就能拿到了。团队说要换地儿,下周搬家,现在都没通知去哪里,赶在兵荒马乱之前记录一下今天的学习成果。
小梅哥的教学视频里是让LED灯以1Hz的频率闪烁,那么我们在Vivado中完成仿真会很慢很慢,所以在代码中将闪烁频率提高改成了1kHz,能让仿真跑的快一些。
LED闪烁的本质就是输入电平的翻转,因此想要让LED灯按照我们期待的频率闪烁,需要根据板子的系统时钟和LED电平翻转频率之间的关系来实现。
系统时钟50MHz怎么转换为LED闪烁频率1kHz呢?我们可以采用计数器的方式,对系统的时钟周期进行计数。一个系统时钟周期为20ns,LED端口的信号周期为1ms(0.5ms进行翻转一次),也就是当系统时钟经过25000个周期后,LED端口的信号需要翻转一次。
(计算过程:一个计数周期是20ns,LED信号0.5ms翻转一次,0.5/20*10^-6=25000)
因此,需要使用一个具有计数功能的模块,每当计数次数达到25000时就对LED端口的输入信号进行翻转。由于计数器的次数需要设置为25000-1,因为是从0开始计数(0—>1,1—>2...24998—>24999,24999—>0)。
在代码实现上,需要先定义LED用到的输入输出端口(对LED_flash模块进行定义),需要用到系统时钟,低电平复位信号(ResetL=0时,所有操作复位)。每一个系统时钟的上升沿来临时触发计数程序,这样就能够统计经过了多少个时钟周期。每当计数达到24999时,LED信号翻转一次。
module LED_flash(
input CLK,
input ResetL,
output reg LED
);
reg[14:0] counter;
always@(posedge CLK or negedge ResetL)begin
if(!ResetL)begin
counter<=14'd0;
LED <= 0;
end
else if (counter==25000-1)begin
counter<=14'd0;
LED <= !LED;
end
else
counter<=counter+1'd1;
end
endmodule
上述设计成功生成组合逻辑电路后就可以在Vivado上进行仿真:
`timescale 1ns / 1ns
module LED_flash_tb();
reg CLK0;
reg ResetL0;
wire LED0;
LED_flash LED_flash_test(
.CLK(CLK0),
.ResetL(ResetL0),
.LED(LED0)
);
initial CLK0 = 1;
always#10 CLK0 = !CLK0;//模拟生成一个50Mhz的时钟信号
initial begin
ResetL0 = 0;
#201;
ResetL0 = 1;
#16000000;
$stop;
end
endmodule
进行仿真后得到如下波形,点击绿色圈内的图标可以标记坐标位置,右键该标签可以进行删除操作。可以看到仿真后输出的信号周期为1000ms。