调用两次进程时出现奇怪的延迟输出行为

时间:2016-12-02 11:31:13

标签: vhdl

我正在尝试编写一个具有输入(开始)和三个输出(tsy,tsr,tlg)的计数器,这些输出分别在4,6和16 clk_period之后为1 clk_period置位。以下代码适用于单个启动断言。

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

entity proj_test is
  port (
    clk, start : in bit;
    tsy, tsr, tlg : out bit
  ) ;
end entity ; -- proj_test

architecture behav of proj_test is

constant clk_period : time := 100 ns;

begin

process (start)
begin
    if (start='1') then
        tsy <= '1' after 4*clk_period, '0' after 5*clk_period;
        tsr <= '1' after 6*clk_period, '0' after 7*clk_period;
        tlg <= '1' after 16*clk_period, '0' after 17*clk_period;
    end if;
end process;

end architecture ; -- behav

Output for a single start

start脉冲相隔400 ns,由以下代码驱动:

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

entity proj_test_test is
end entity proj_test_test; 

architecture behav of proj_test_test is
  constant clk_period : time := 100 ns;
  signal clk, start :  bit;
  signal tsy, tsr, tlg : bit;
begin

  P : entity work.proj_test port map (clk, start, tsy, tsr, tlg);

  start <= '0', 
           '1' after  2*clk_period,
           '0' after  3*clk_period,
           '1' after 6*clk_period,
           '0' after 7*clk_period,
           '1' after 42*clk_period;

end architecture behav;

https://www.edaplayground.com/x/52mP

或以下模拟器命令:

force -freeze sim:/proj_test/clk 0 0, 1 {50 ns} -r 100
force -freeze sim:/proj_test/start 1 0, 0 100, 1 400, 0 500

但是,当我第二次断言输入start时,tsy会跨越多个时钟周期。

Output for an added start

我试图理解为什么。我的猜测是第二个进程调用“刷新”第一个进程的分配。另外,有没有更好的方法来编写此计数器的行为?

1 个答案:

答案 0 :(得分:2)

VHDL模拟器维护事件队列。这是模拟器的“待办事项”列表。使用信号分配执行任何VHDL行的效果是修改事件队列。通常,事件会添加到事件队列中,但通常也可以删除事件。将删除事件以模拟惯性延迟;在VHDL中,默认情况下延迟是惯性的。

  

为了模拟惯性延迟,将事件添加到事件中   队列,计划同时发生的任何事件或   之前被删除,除非该事件的效果与之相同   正在添加新事件的效果。

执行代码时,后续信号分配会从事件队列中删除事件。我们需要详细分析事件队列。

因此,在0 ns时,事件队列为空。该行在时间0执行

start <= '0', 
         '1' after  2*clk_period,
         '0' after  3*clk_period,
         '1' after  6*clk_period,
         '0' after  7*clk_period,
         '1' after 42*clk_period;

将6个事件放入事件队列。事件队列现在看起来像这样:

TIME      DELTA   SIGNAL    VALUE
   0 ns   1       start     '0'
 200 ns   0       start     '1'
 300 ns   0       start     '0'
 600 ns   0       start     '1'
 700 ns   0       start     '0'
4200 ns   0       start     '1'

在200 ns时,start被驱动到'1',因此执行以下三行:

tsy <= '1' after 4*clk_period, '0' after 5*clk_period;
tsr <= '1' after 6*clk_period, '0' after 7*clk_period;
tlg <= '1' after 16*clk_period, '0' after 17*clk_period;

将6个事件放到事件队列中。事件队列现在看起来像这样:

TIME      DELTA   SIGNAL    VALUE
 300 ns   0       start     '0'
 600 ns   0       start     '1'
 600 ns   0       tsy       '1'
 700 ns   0       start     '0'
 700 ns   0       tsy       '0'
 800 ns   0       tsr       '1'
 900 ns   0       tsr       '0'
1800 ns   0       tlg       '1'
1900 ns   0       tlg       '0'
4200 ns   0       start     '1'

然后在300 ns start被驱动到'0',因此事件队列现在看起来像这样:

TIME      DELTA   SIGNAL    VALUE
 600 ns   0       start     '1'
 600 ns   0       tsy       '1'
 700 ns   0       start     '0'
 700 ns   0       tsy       '0'
 800 ns   0       tsr       '1'
 900 ns   0       tsr       '0'
1800 ns   0       tlg       '1'
1900 ns   0       tlg       '0'
4200 ns   0       start     '1'

然后在600 ns start被驱动到'1'tsy也被驱动到'1',因此事件队列现在看起来像这样:

TIME      DELTA   SIGNAL    VALUE
 700 ns   0       start     '0'
 700 ns   0       tsy       '0'
 800 ns   0       tsr       '1'
 900 ns   0       tsr       '0'
1800 ns   0       tlg       '1'
1900 ns   0       tlg       '0'
4200 ns   0       start     '1'

并再次执行以下三行:

tsy <= '1' after 4*clk_period, '0' after 5*clk_period;
tsr <= '1' after 6*clk_period, '0' after 7*clk_period;
tlg <= '1' after 16*clk_period, '0' after 17*clk_period;

将另外6个事件添加到事件队列中:

TIME      DELTA   SIGNAL    VALUE
1000 ns   0       tsy       '1'
1100 ns   0       tsy       '0'
1200 ns   0       tsr       '1'
1300 ns   0       tsr       '0'
2200 ns   0       tlg       '1'
2300 ns   0       tlg       '0'

如果您遵循我上面给出的规则,您会看到事件队列如下所示:

TIME      DELTA   SIGNAL    VALUE
 700 ns   0       start     '0'
1000 ns   0       tsy       '1'
1100 ns   0       tsy       '0'
1200 ns   0       tsr       '1'
1300 ns   0       tsr       '0'
2200 ns   0       tlg       '1'
2300 ns   0       tlg       '0'
4200 ns   0       start     '1'

因为这五个事件被删除了:

TIME      DELTA   SIGNAL    VALUE
 700 ns   0       tsy       '0'
 800 ns   0       tsr       '1'  
 900 ns   0       tsr       '0'
1800 ns   0       tlg       '1'
1900 ns   0       tlg       '0'

如果查看跟踪,您会看到这些事件正是发生的事情:

  • 删除tsy的下降沿(因此宽脉冲);
  • tsr上的前两个事件被删除(因此只有一个脉冲);
  • tlg上的前两个事件被删除(因此只有一个脉冲)。