Search code examples
initializationvhdlsimulation

Where should I call an initializer function of a protected type in VHDL?


I have a protected type in VHDL, which implements a initializer function or procedure.

Here is my code with an initializer procedure:

type T_SIM_STATUS is protected
  procedure init;
  procedure fail(Message : in STRING := "") ;
  procedure simAssert(condition : BOOLEAN; Message : STRING := "") ;
  procedure simReport;
end protected;

type T_SIM_STATUS is protected body
  variable NotImplemented : BOOLEAN := TRUE;
  variable Passed : BOOLEAN := TRUE;

  procedure init is
  begin
    NotImplemented := FALSE;
  end procedure;

  procedure fail(Message : in STRING := "") is
  begin
    if (Message'length > 0) then
      report Message severity error;
    end if;
    Passed := FALSE;
  end procedure;

  procedure simAssert(condition : BOOLEAN; Message : STRING := "") is
  begin
    if (condition = FALSE) then
      fail(Message);
    end if;
  end procedure;

  procedure simReport is
    variable l : LINE;
  begin
    write(l, STRING'("SIMULATION RESULT = "));
    if (NotImplemented = TRUE) then
      write(l, STRING'("NOT IMPLEMENTED"));
    elsif (Passed = TRUE) then
      write(l, STRING'("PASSED"));
    else
      write(l, STRING'("FAILED"));
    end if;
  end procedure;
end protected body;

shared variable simStatus : T_SIM_STATUS;

Where should I call the init procedure?

My current solution calls init in a seperate process in the testbench's architecture body:

architecture rtl of test is
  -- ...
begin
  procInit : process
  begin
    simStatus.init;
    wait;
  end process;

  procGenerator : process
  begin
    -- generate stimuli
    wait;
  end process;

  procTester : process
  begin
    -- check results by using simStatus.simAssert

   simStatus.simReport;
   wait;
  end process;
 end architecture;

Are there better solutions?


Solution

  • Based on your code, and assuming effect of init should be made before any use of other procedures (methods) in the protected type, it looks like init procedure could be removed if NotImplemented if given an initial value of FALSE instead of TRUE.

    Otherwise, if init is to be called first, just make sure that other uses of the shared variable are not called at time 0, in which case the call to init can be made as concurrent, thus without the process wrapper, but simply like:

    simStatus.init;
    

    If more complex setup must be done through a init call, then it could be called automatically when instantiating the shared variable if init is made as a function, that is then called from within the body of the shared variable, like:

    type T_SIM_STATUS is protected
      -- No init function is made public
      procedure fail(Message : in STRING := "") ;
      procedure simAssert(condition : BOOLEAN; Message : STRING := "") ;
      procedure simReport;
    end protected;
    
    type T_SIM_STATUS is protected body
      variable NotImplemented : BOOLEAN := TRUE;
      variable Passed : BOOLEAN := TRUE;
      ...  # Other code
      impure function init return boolean is
      begin
        NotImplemented := FALSE;
        ...  -- Or other more complex code
        return TRUE;
      end function;
      variable dummy : boolean := init;  -- Calling init with side effects
    end protected body;