亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Industrial programming >> VHDL

如何在 VHDL 中创建计时器

在之前的教程中,我们使用了 wait for 在模拟中延迟时间的声明。但是生产模块呢? wait for 声明不能用于此。这仅在模拟中有效,因为我们不能只告诉电路中的电子暂停给定时间。那么我们如何在设计模块中跟踪时间呢?

答案只是简单地计算时钟周期。每个数字设计都可以访问以固定的已知频率振荡的时钟信号。因此,如果我们知道时钟频率为 100 MHz,我们可以通过计算一亿个时钟周期来测量一秒。

这篇博文是基本 VHDL 教程系列的一部分。

要在 VHDL 中计算秒数,我们可以实现一个计数器来计算经过的时钟周期数。当这个计数器达到时钟频率的值时,例如 1 亿,我们知道已经过了一秒钟,是时候增加另一个计数器了。我们称之为秒计数器。

要计算分钟数,我们可以实现另一个 Minutes 计数器,它会在 60 秒后递增。同样,我们可以创建一个 Hours 计数器来计算小时数,并在 60 分钟后递增。

我们也可以继续这种方法来计算天数、周数和月数。我们受到底层技术中可用物理资源以及计数器长度与时钟频率的限制。

随着计数器长度的增加,显然它会消耗更多的资源。但它的反应也会变慢,因为事件链变长了。

运动

在本视频教程中,我们将学习如何在 VHDL 中创建计时器模块:

计时器 testbench 的最终代码 :

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity T18_TimerTb is
end entity;

architecture sim of T18_TimerTb is

    -- We're slowing down the clock to speed up simulation time
    constant ClockFrequencyHz : integer := 10; -- 10 Hz
    constant ClockPeriod      : time := 1000 ms / ClockFrequencyHz;

    signal Clk     : std_logic := '1';
    signal nRst    : std_logic := '0';
    signal Seconds : integer;
    signal Minutes : integer;
    signal Hours   : integer;

begin

    -- The Device Under Test (DUT)
    i_Timer : entity work.T18_Timer(rtl)
    generic map(ClockFrequencyHz => ClockFrequencyHz)
    port map (
        Clk     => Clk,
        nRst    => nRst,
        Seconds => Seconds,
        Minutes => Minutes,
        Hours   => Hours);

    -- Process for generating the clock
    Clk <= not Clk after ClockPeriod / 2;

    -- Testbench sequence
    process is
    begin
        wait until rising_edge(Clk);
        wait until rising_edge(Clk);

        -- Take the DUT out of reset
        nRst <= '1';

        wait;
    end process;

end architecture;

计时器模块的最终代码 :

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity T18_Timer is
generic(ClockFrequencyHz : integer);
port(
    Clk     : in std_logic;
    nRst    : in std_logic; -- Negative reset
    Seconds : inout integer;
    Minutes : inout integer;
    Hours   : inout integer);
end entity;

architecture rtl of T18_Timer is

    -- Signal for counting clock periods
    signal Ticks : integer;

begin

    process(Clk) is
    begin
        if rising_edge(Clk) then

            -- If the negative reset signal is active
            if nRst = '0' then
                Ticks   <= 0;
                Seconds <= 0;
                Minutes <= 0;
                Hours   <= 0;
            else

                -- True once every second
                if Ticks = ClockFrequencyHz - 1 then
                    Ticks <= 0;

                    -- True once every minute
                    if Seconds = 59 then
                        Seconds <= 0;

                        -- True once every hour
                        if Minutes = 59 then
                            Minutes <= 0;

                            -- True once a day
                            if Hours = 23 then
                                Hours <= 0;
                            else
                                Hours <= Hours + 1;
                            end if;

                        else
                            Minutes <= Minutes + 1;
                        end if;

                    else
                        Seconds <= Seconds + 1;
                    end if;

                else
                    Ticks <= Ticks + 1;
                end if;

            end if;
        end if;
    end process;

end architecture;

Seconds 上放大的波形 信号:

Minutes 上放大的波形 信号:

Hours 上放大的波形 信号:

分析

为了运行 50 小时的模拟,我们给出了命令 run 50 hr 在 ModelSim 控制台中。 50 小时是一个非常长的模拟,因此我们不得不将测试台中的时钟频率降低到 10 Hz。如果我们将其保持在 100 MHz,则模拟将需要数天时间。为了让我们能够模拟设计,这种适应有时是必要的。

我们右键单击波形中的时间线并选择“网格、时间线和光标控制”。将时间单位从ns改为秒、分、小时后,我们可以看到定时器确实是实时工作的。

由于在模拟开始时模块的复位,定时器时间与模拟时间略有偏移。在第一个波形中可以看到,时间线上的 60 秒标记稍早于 Seconds 信号回绕到 0 时。

请注意,在模拟中,计数器值在时钟的上升沿以零时间更新。在现实世界中,计数器值需要一些时间才能从计数器的第一位传播到最后一位。随着计数器长度的增加,我们消耗了一个时钟周期的可用时间。

如果所有级联计数器的累加长度过长,编译后的布局布线步骤会产生错误。在消耗整个时钟周期之前,您可以实现一个计数器多长时间取决于 FPGA 或 ASIC 架构和时钟速度。

增加的时钟速度意味着计数器链会更长。这也意味着时钟周期时间会更短,让计数器链完成的时间更少。

外卖

转到下一个教程 »


VHDL

  1. 如何在 VHDL 中创建字符串列表
  2. 如何为 VHDL 代码锁定模块创建 Tcl 驱动的测试平台
  3. 如何在 VHDL 测试平台中停止仿真
  4. 如何在 VHDL 中创建 PWM 控制器
  5. 如何在 VHDL 中生成随机数
  6. 如何在 VHDL 中创建环形缓冲区 FIFO
  7. 如何创建自检测试平台
  8. 如何在 VHDL 中创建链接列表
  9. 如何在 VHDL 中的进程中使用过程
  10. 如何在 VHDL 中使用不纯函数
  11. 如何在 VHDL 中使用函数
  12. 如何在 VHDL 中创建有限状态机