【FPGA】时序逻辑电路——基于计数器实现一个以1秒频率闪烁的LED灯

时序逻辑电路 计数器的实现

1 D触发器

image-20221112094647196

分析:

特性:输出端Q只在CK处于上升沿的时候变化

图中波形的形成过程:

  • 当D处于高电平时,CK未处于上升沿时,Q仍处于低电平

  • 当CK来到上升沿,Q需要根据D发生变化,由于D是高电平,所以Q要从低电平变化成高电平

  • D从高电平变化成低电平,但是此时CK未来到上升沿,所以Q不随着D变化(虽然D变了,Q仍保持刚刚的状态——存储功能)

  • CK来到上升沿,此时D又恢复了高电平,所以Q不变

2 计数器

原理:加法器基本结构图

image-20221112095528426

这样就能实现 每一个时序上升沿,计数器结果都加1

今天我们的任务是
设计一个以1秒频率闪烁的LED灯(亮灭各500ms)

怎么知道500ms亮,500ms灭呢?

  • 我们就需要一个计数器,计数到什么时候到了500ms

  • 时钟的频率我们设置为50MHz 20ns,也就是两个上升沿(一个周期)的时间是20ns

  • 每到一个上升沿,计数器的值加一次

  • 由于500ms亮和灭,所以我们需要计数器计数 500ms/20ns = 25000000次

  • 而一个四位计数器肯定计数不了这么多的值,那么需要多少位呢?

image-20221112104038009

  • 源代码
module led_flash(
    clk,
    reset_n,//reset是复位信号,  _n 表示低电平有效,也就是低电平时复位
    led
    );
    
   input clk;
   input reset_n;
   output reg led;
   
   reg [24:0] counter;//25位计数器
   
   always@(posedge clk or negedge reset_n)  //当clk处于上升沿或者reset处于下降沿的时候下面的代码就生效
   if(!reset_n) // if(reset_n == 0)
        counter <= 0;  // <= 是非阻塞赋值的意思
    else if (counter == 2500_0000) //-1)
        counter <= 0;
   else
        counter <= counter + 1'd1;
        
        
  //需要让 led 灯每500ms翻转一次
   always@(posedge clk or negedge reset_n)  
   if(!reset_n) 
        led <= 0;
    else if (counter == 2500_0000) //-1)  要减1
        led <= !led; //翻转

endmodule

仿真代码

`timescale 1ns / 1ps

module led_flash_tb(

    );
    reg clk;
    reg reset_n;
    wire led;
    
    led_flash UUT(
        .clk(clk),
        .reset_n(reset_n),
        .led(led)
        );
    
    initial clk = 1;
    always #10 clk =! clk; 
    
    initial begin 
        reset_n = 0;
        #201; //避开上升沿 
        reset_n = 1;
        #20_0000_0000;   // 2s
    end
    
endmodule

  • 仿真

从仿真的结果看

image-20221112114920018

比预想的500ms 多了 20ns

原因是这里如果想计数2500_0000次,应该写2499_9999

image-20221112115216247

这里以计数到4为例,如果要计数到4的话,实际上不是计数了4次,而是5次

  • 0-1
  • 1-2
  • 2-3
  • 3-4
  • 4-0

所以应该改为 2500_0000-1

改过之后 就可以了

image-20221112120351268

改过之后 就可以了

image-20221112120351268
  • 9
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值