fpga学习day3 LED灯翻转(计数器)

今天弄个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。

  • 12
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值