Reply To: Problems with OSVVM Functional Coverage

Why OSVVM™? Forums OSVVM Problems with OSVVM Functional Coverage Reply To: Problems with OSVVM Functional Coverage

#2674
Jim Lewis
Member

Hi ALex,
I added the two suggestions I made previously to the code. Choose one of them.
I also changed the WaitForClock(clk, 2) to WaitForClock(InterruptRec, 2).
Usually I do not put clock in TestCtrl. The reason being is if you have lots of
different clocks in your system, it is easy to use the wrong one.

rx_process : process is 
      variable cnt : integer := 0; -- this value is applied at time 0 ns
      variable rd_data     : std_logic_vector(31 downto 0) := (others => '0');
    begin
              rx_cnt_s <= 0;
              RxCov <= NewID("RxCov") ;                         -- Get a Coverage ID

              wait for 0 ns ;

-- This puts all counts in a single bin with range 1 to 20
              osvvm.CoveragePkg.AddBins(RxCov, "count", GenBin(1,20,1) ) ;     
-- This puts all counts in a separate bins range 1 to 1, 2 to 2, ...
              osvvm.CoveragePkg.AddBins(RxCov, "count", GenBin(1,20) ) ;     

              loop

                WaitForClock(InterruptRec, 1) ;
                report "Interrupt Handler Started" ;

                Read(InterruptRec, X"A80", rd_data);
               
                if (rd_data(10) = '1') then 

                  Read(InterruptRec, x"920", rd_data);
                  if (rd_data(30 downto 26) = rd_data(20 downto 16)) then 
                     report "RX FIFO EMPTY";
                  else
-- The following is a problem if you do not have clk here - I generally recommend against clock here                                      
--                     osvvm.TbUtilPkg.WaitForClock(clk, 2);
-- Instead let the VC do the waiting
                     WaitForClock(InterruptRec, 2);  -- wait for VC number of clocks
-- Note the previous waits are not needed by OSVVM.

                     cnt := rx_cnt_s;
                     cnt := cnt + 1;
-- Either Check cnt in ICover because rx_cnt_s does not update until a delta cycle later                    
                     osvvm.CoveragePkg.ICover(RxCov, cnt) ;      -- Collect functional coverage
                     log("cnt value: " & to_string(cnt)) ;  -- log values of cnt to correlate with functional coverage
                     rx_cnt_s <= cnt;
-- Or add a delta cycle by doing wait for 0 ns here:
                     rx_cnt_s <= cnt;
                     wait for 0 ns ; 
                     osvvm.CoveragePkg.ICover(RxCov, rx_cnt_s ) ;      -- Collect functional coverage
                     log("cnt value: " & to_string(rx_cnt_s)) ;  -- log values of cnt to correlate with functional coverage
                  end if;
                end if;
                report "Interrupt Handler Done" ;
                InterruptReturn(InterruptRec) ;
                wait for 1 ns ;                

              end loop;
-- The loop is never exited so this code never runs.
              osvvm.CoveragePkg.WriteBin(RxCov); -- generates a test report 
              wait;

    end process;

Your control process cannot iterate, so change it as follows:


  ControlProc : process
  begin
    -- Initialization of test
    SetTestName("test") ;
    SetLogEnable(PASSED, TRUE) ;   -- Enable PASSED logs
    SetLogEnable(INFO, TRUE) ;     -- Enable INFO logs
    -- SetLogEnable(DEBUG, TRUE) ;    -- Enable INFO logs

    -- Wait for testbench initialization
    wait for 0 ns ;  wait for 0 ns ;
    TranscriptOpen(OSVVM_RESULTS_DIR & "test.txt") ;
    SetTranscriptMirror(TRUE) ;
    SetAlertLogOptions(WriteTimeLast => FALSE) ; 
    SetAlertLogOptions(TimeJustifyAmount => 15) ; 
    SetAlertLogJustify ; 

    -- Wait for Design Reset
    wait until nreset = '1' ;
    ClearAlerts ;

    -- Wait for test to finish
-- If you have a process that uses WaitForBarrier(TestDone) somewhere else the following is ok
    WaitForBarrier(TestDone, 20 ms) ;   -- note I change the wait time to match the timeout period
    AlertIf(now >= 20 ms, "Test finished due to timeout") ;
-- If not, replace the WaitForBarrier with
    wait for 20 ms ; 

    AlertIf(GetAffirmCount < 1, "Test is not Self-Checking");
   
    TranscriptClose ;

    EndOfTestReports ;
-- add stop, remove wait for 7 ms
   std.env.stop ;
   -- wait for 7ms ;
   wait ;  
 end process ControlProc ;