# Copyright 2024 Apheleia
#
# Description:
# Apheleia Verification Library Coverage Container
from __future__ import annotations
import atexit
from typing import TYPE_CHECKING
import pandas as pd
if TYPE_CHECKING:
from .covergroup import CoverGroup
[docs]
class Coverage:
_instance = None
def __new__(cls) -> Coverage:
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
[docs]
def __init__(self) -> None:
"""
Initialize the coverage container
This method initializes the coverage container and registers the exit handler
to export coverage data when the program exits.
It checks if the `_cg_` attribute exists; if not, it initializes it as an empty list.
If the `_cg_` attribute already exists, it does nothing to avoid re-initialization.
"""
if hasattr(self, "_cg_"):
return
# Cover Groups
self._cg_ = []
# Register function to export coverage at exit
atexit.register(self.__at_exit__)
def __at_exit__(self) -> None:
"""
Export coverage data at exit
"""
if len(self._cg_) == 0:
return
df = None
for cg in self._cg_:
if df is None:
df = cg.report(full=True)
else:
df = pd.concat([df, cg.report(full=True)], ignore_index=True)
df.to_json("coverage.json", mode="w", orient="records")
[docs]
def add_covergroup(self, cg: CoverGroup) -> None:
"""
Add a covergroup to the coverage container
:param cg: The covergroup to add
"""
self._cg_.append(cg)
[docs]
def remove_covergroup(self, cg: CoverGroup) -> None:
"""
Remove a covergroup from the coverage container
:param cg: The covergroup to remove
"""
self._cg_.remove(cg)
__all__ = ["Coverage"]