Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stop a simulation by timeout?

I have manageg to implement a simulation timeout in VHDL. If processes are running longer the MaxRuntime they get 'killed'.

Unfortunately, this does not work the other way around. If my simulation is finished before MaxRuntime, everything is waiting for the last wait statement on MaxRuntime.

I found that it's possible to combine wait on, wait for and wait until statements into one.

My current code in snippets. A full example is quite to long...

package sim is
  shared variable IsFinalized : BOOLEAN := FALSE;

  procedure initialize(MaxRuntime : TIME := TIME'high);
  procedure finalize;
end package;

package body sim is
  procedure initialize(MaxRuntime : TIME := TIME'high) is
  begin
    -- do init stuff
    if (MaxRuntime = TIME'high) then
      wait on IsFinalized for MaxRuntime;
      finalize;
    end if;
  end procedure;

  procedure finalize;
  begin
    if (not IsFinalized) then
      IsFinalized := TRUE;
      -- do finalize stuff:
      --  -> stop all clocks
      -- write a report
    end if;
  end procedure;
end package body;

entity test is
end entity;

architecture tb of test is
begin
  initialize(200 us);

  process
  begin
    -- simulate work
    wait for 160 us;
    finalize;
  end process;
end architecture;

The wait statement is not exited if IsFinalized changed. My simulation runs for circa 160 us. If I set MaxRuntime to 50 us, the simulation stops at circa 50 us (plus some extra cycles until each process noticed the stop condition). When I set MaxRuntime to 200 us, the simulation exits at 200 us and not after 162 us.

  • How can I exit/abort the wait statement?
  • Why can't I wait on a variable?

I don't want to use a command line switch for a simulator to set the max execution time.

like image 785
Paebbels Avatar asked Feb 09 '16 21:02

Paebbels


1 Answers

You cannot wait on a variable for the reasons given by user1155120. So, instead you need to use a signal. (A signal in a package is a global signal).

Unfortunately, even though the global signal is in scope, it still needs to be an output parameter of the procedure, which is ugly. Not only that, in your code, you will then be driving the signal from more than one place, this global signal needs to be a resolved type, eg std_logic. Which is also a bit ugly.

Here is a version of your code with the shared variable replaced by a signal, the boolean type replaced by a std_logic and the global signal added as output parameters:

library IEEE;
use IEEE.std_logic_1164.all;

package sim is
  signal IsFinalized : std_logic := '0';

  procedure initialize(signal f : out std_logic; MaxRuntime : TIME := TIME'high);
  procedure finalize (signal f : out std_logic);
end package;

package body sim is
  procedure initialize(signal f : out std_logic; MaxRuntime : TIME := TIME'high) is
  begin
    -- do init stuff
    if (MaxRuntime = TIME'high) then
      wait on IsFinalized for MaxRuntime;
      finalize(f);
    end if;
  end procedure;

  procedure finalize (signal f : out std_logic) is
  begin
    if (IsFinalized = '0') then
      f <= '1';
      -- do finalize stuff:
      --  -> stop all clocks
      -- write a report
      report "Finished!";
    end if;
  end procedure;
end package body;

use work.sim.all;

entity test is
end entity;

architecture tb of test is
begin
  initialize(IsFinalized, 200 us);

  process
  begin
    -- simulate work
    wait for 160 us;
    finalize(IsFinalized);
    wait;
  end process;
end architecture;

http://www.edaplayground.com/x/VBK

like image 153
Matthew Taylor Avatar answered Sep 29 '22 22:09

Matthew Taylor