0

I have the following VHDL code:

pure function sInitSyncSupport( sState: TYPE_STATE; sCssi: TYPE_CSS_TO_SSM ) return TYPE_STATE is
    variable sStateOut:           TYPE_STATE;
begin
    sStateOut                     := sState;

    sStateOut.bAccWndOpen         := false;
    sStateOut.iCorrValue          := 0;
    sStateOut.nClockCorrected     := 3*sCssi.nSwAcceptanceWindowHalf + 1;
    sStateOut.nMsCountMax         := 0;

    return sStateOut;
end function sInitSyncSupport;

pure function sStartSync( sState: TYPE_STATE; sCssi: TYPE_CSS_TO_SSM; sFp2i: TYPE_FP2_TO_SSM; eState: TYPE_SSM_FSM ) return TYPE_STATE is
    variable sStateOut:           TYPE_STATE;
begin
    sStateOut                     := sState;

    sStateOut.nClock              := sCssi.nSwAcceptanceWindowHalf + sFp2i.nError + 1;
    sStateOut.nIntegrationCycle   := sFp2i.sPcf.nIntegrationCycle;
    sStateOut.uvMembershipComp    := sFp2i.sPcf.uvMembership;
    sStateOut.eState              := eState;

    sStateOut.bAccWndOpen         := true;
    sStateOut.nMsCountMax         := sState.nMsCount;

    return sStateOut;
end function sStartSync;

sync: process (bReset, uClk)
    variable s1:                   TYPE_STATE;
    variable s2:                   TYPE_STATE;
begin
    s1 := sInitSyncSupport( s, sCssi );
    s2 := sStartSync( s, sCssi, sFp2i, SW_SYNC );
end process sync;

The line s1 := is covered as all as all the statements inside the pure function sInitSyncSupport.

The line s2 := ... is covered tens of times in the code coverage reports generated by ModelSim_10.1c, but all the statements inside the pure function sStartSync appears uncovered.

Does anybody know why this happens? Thank you.

UPDATE:

Here is a more complete code:

library IEEE;
  use IEEE.std_logic_1164.all;

library work;
   ...

entity SSM is
  port (
    bReset:                       in boolean;
    uClk:                         in std_ulogic;
    ...
    sFp2i:                        in TYPE_FP2_TO_SSM;
    sCssi:                        in TYPE_CSS_TO_SSM;
    ...
  );
end SSM;

library work;
   ...

architecture RTL of SSM is

  type TYPE_STATE is record
    auvAsyncMembershipComp:       TYPE_ASYNC_MS_COUNT_ARRAY;
    bAccWndOpen:                  boolean;
    bAccWndToClose:               boolean;
    bAppliedCorrection:           boolean;
    bFsmError:                    boolean;
    ...
  end record;

  constant CONST_TYPE_STATE_RESET: TYPE_STATE := (
    auvAsyncMembershipComp        => CONST_TYPE_ASYNC_MS_COUNT_ARRAY_RESET,
    bAccWndOpen                   => false,
    bAccWndToClose                => false,
    bAppliedCorrection            => false,
    bFsmError                     => false,
    ...
  );

  signal r:                       TYPE_STATE
  -- pragma synthesis_off
                                             := CONST_TYPE_STATE_RESET
  -- pragma synthesis_on
  ;

  ---------------------------------------------------------------------------
  -- Function: sInitSyncSupport
  ---------------------------------------------------------------------------
  -- Purpose:
  --   This function initializes the support registers for time difference
  --   capturing 
  ---------------------------------------------------------------------------
  pure function sInitSyncSupport( sState: TYPE_STATE; sCssi: TYPE_CSS_TO_SSM ) return TYPE_STATE is
  ---------------------------------------------------------------------------
    variable sStateOut:           TYPE_STATE;
  begin
    sStateOut                     := sState; -- !!! all lines are covered
    sStateOut.bAccWndOpen         := false;
    sStateOut.iCorrValue          := 0;
    sStateOut.nClockCorrected     := 3*sCssi.nSwAcceptanceWindowHalf + 1;
    sStateOut.nMsCountMax         := 0;
    return sStateOut;
  end function sInitSyncSupport;

  ---------------------------------------------------------------------------
  -- Function: sStartSync
  ---------------------------------------------------------------------------
  -- Purpose:
  --   This function initializes the clock synchronization registers 
  ---------------------------------------------------------------------------
  pure function sStartSync( sState: TYPE_STATE; sCssi: TYPE_CSS_TO_SSM; sFp2i: TYPE_FP2_TO_SSM; eState: TYPE_SSM_FSM ) return TYPE_STATE is
  ---------------------------------------------------------------------------
    variable sStateOut:           TYPE_STATE;
  begin
    sStateOut                     := sState; -- !!! NONE of the lines are covered
    sStateOut.nClock              := sCssi.nSwAcceptanceWindowHalf + sFp2i.nError + 1;
    sStateOut.nIntegrationCycle   := sFp2i.sPcf.nIntegrationCycle;
    sStateOut.uvMembershipComp    := sFp2i.sPcf.uvMembership;
    sStateOut.eState              := eState;
    sStateOut.bAccWndOpen         := true;
    sStateOut.nMsCountMax         := sState.nMsCount;
    return sStateOut;
  end function sStartSync;

begin

  sync: process (bReset, uClk)
    variable s:                   TYPE_STATE;
    variable v:                   TYPE_VAR;
  begin
    if (bReset) then
      r                           <= CONST_TYPE_STATE_RESET;
    elsif ((uClk = '1') and uClk'event) then
      s                           := r;

      v                           := CONST_TYPE_VAR_RESET;
      v.bMembershipExceedsMax     := (r.bNextMembershipExceedsMax and (r.nClock >= sFp2i.nError));
      v.bInScheduleFrame          := (r.bNextInScheduleFrame and (r.nClock >= sFp2i.nError));
      v.bOutOfScheduleFrame       := (r.bNextOutOfScheduleFrame or (r.bNextInScheduleFrame and not v.bInScheduleFrame));

      s.nTimer      := nDecNoWrap( r.nTimer, 1 );
      s.bTimerEvent := (r.nTimer = 1);
      s             := sInitSyncSupport( s, sCssi );           -- !!! covered
      s             := sStartSync( s, sCssi, sFp2i, SW_SYNC ); -- !!! covered, but content of sStartSync not covered

      r                           <= s;
    end if;
  end process sync;

  sCsso                           <= r.sCsso;
  sSdo                            <= r.sSdo;
  sScho                           <= r.sScho;
  sPfgo                           <= r.sPfgo;
  bFsmErro                        <= r.bFsmError;

end RTL;

I marked with !!! the sensitive lines. Thank you very much.

Mihai Hangiu
  • 588
  • 4
  • 13
  • Add the declarations of the actual parameters. If these are constant, a pure function can be evaluated once during elaboration, and its return value used as a constant - hence it is never called at run time. –  Mar 10 '17 at 21:13
  • sStartSync is a selection permutation with no testable logic. In an elaborated design every place with the same net will used the same effective value. While not having an authoritative answer I wouldn't think assignment by itself as a basic operation would be seen as testable, these are the same wires with different names. –  Mar 12 '17 at 04:30

0 Answers0