【问题标题】:Why a delay of 1 clock period in simple counter为什么在简单计数器中延迟 1 个时钟周期
【发布时间】:2012-11-19 13:36:38
【问题描述】:

下面是一个简单的 3 位计数器。

当 reset(rst) 为 0 时,计数器值为“000”,否则在每个时钟的上升沿递增 1。

 LIBRARY ieee;
 USE ieee.std_logic_1164.all;
 use IEEE.std_logic_unsigned.all;
 use IEEE.numeric_std.all;
 ---------------------------------------------
 ENTITY counter IS
 PORT (clk : IN STD_LOGIC;
    rst : in std_logic;
       digit : out std_logic_vector (2 downto 0)
       );
 END counter;
 ---------------------------------------------
 ARCHITECTURE counter OF counter IS
 BEGIN

 count: PROCESS(clk,rst)
 VARIABLE temp : std_logic_vector(2 downto 0);
 BEGIN
 IF (clk'EVENT AND clk='1') THEN
     if (rst = '1') then
        temp := temp + "001";
     else
        temp := "000";
     END IF;
 END IF;
 digit <= temp;
 END PROCESS count;
 END counter;

下面是我得到的模拟结果:

在结果中,输出是正确的。但是在时间 rst = 1 和 output='001' 之间有一个时钟延迟。即当rst = '1' 时,计数器不会立即增加。

根据我的理解,只要 clk 或 rst 发生变化,就会执行进程。所以当 rst 从低变高时,就会发生一个事件。进程检查 clk 的上升沿是否为 YES。然后检查rst = 1,是。因此,通常计数器必须在该 clk 本身中增加。但事实并非如此。

问题:

  1. 为什么在复位 = 1 和输出 = 001 之间有一个时钟周期延迟?
  2. 我的理解有什么问题?

【问题讨论】:

  • 糟糕,图片的问题似乎很小。请打开图片看清楚。
  • 如果加法答案在下一个上升沿之前很久就可用,为什么它没有传递到输出并显示在模拟结果中?为什么要等到时钟的下一个上升沿?
  • 问题是:它可用吗?它在哪里?它可以在触发器的 inputs 内部使用。切换复位使其在输出端可用。通常你只是不能探测 temp 寄存器,它与触发器的输入相同。
  • 那么,有没有办法在 rst = 1 的同时增加计数器?
  • 这样说吧:不。如果您可以在相同的时钟周期内输出,您将拥有无限快的机器。

标签: delay simulation counter vhdl


【解决方案1】:

“rst”最可能的原因是由时钟进程生成的,由相同的“clk”信号时钟。

所以“rst”出现在“clk”之后的一个增量周期。当“rst”改变时,它会唤醒进程,但“clk'event”在前一个增量周期,因此“if”语句不会执行。

在下一个时钟沿,rst = 1,因此计数器按预期工作。

三个小点:

  • 值得将复位信号命名为 rst_n 以更清楚地表明它是 低电平有效复位!
  • rst 确实不需要在敏感度列表中
  • 布尔表达式不需要括号

【讨论】:

    【解决方案2】:

    (免责声明:我已经很久没有用 VHDL 编程了,所以这仅适用于通用逻辑设计。)

    无论如何,当一个进程被触发时,不能期望加法的结果立即准备好。关键是,即使是计算 000 + 001 的第一位也会受到相当于一次异或运算的传播延迟的影响。第二位是根据第一位的进位(如果两个位都是 1)和第二位的异或运算来计算的。等等。

    如果有人异步探测“temp”变量,则会看到如下内容:

                            ^ ________________
    result_bit_0    __________|
                            0123456789
                    _____________
    result_bit_1            ^    |____________
                            0123456789
                    ____________ _____
    result_bit_2            ^  |_|   |________
                            0123456789abcde
                            ________       
    clock:          ________|      |______|
    

    该图试图更详细地说明通用加法运算的波形。
    在时间 0 开始添加过程。
    在短暂的延迟“2”之后,第一位稳定为 1。
    在时间“5”第二位稳定为 0,在时间“9”第三位稳定为 0。 但也很常见,就像在 result_bit_2 中一样,输出在各种状态之间切换。

    确定最小时钟周期的是每个临时变量的总延迟/最大延迟。在这种情况下,时刻“e”是那个时刻,我们已经确定计数器递增的结果可用。

    不过,从result(它是一个向量)的角度来看,一切都会在下一个时钟周期立即发生。

    【讨论】:

      【解决方案3】:

      “问题”在于您描述“第一个”的方式。 您这样做的方式会导致“同步”重置,即重置只会在时钟上升沿后生效。

      一般来说,这只是编码风格/偏好的问题。 我通常更喜欢异步重置(可能在顶层使用重置同步器以避免释放重置时的亚稳定性),但采用同步重置方法并没有错。

      如果发生异步重置,您需要将代码更改为以下内容:

      PROCESS (clk, rst_n) BEGIN
         IF rst_n = '0' THEN
            ...
         ELSIF rising_edge(clk) THEN
          ...
         END IF;
      END PROCESS;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-17
        • 1970-01-01
        • 1970-01-01
        • 2016-07-09
        • 2017-02-23
        • 2014-07-29
        相关资源
        最近更新 更多