AVL Factory

Inheritance diagram of avl._core.factory

Overview

The AVL factory provides the same functionality as the UVM factory without the complexity of the class::type_id::create() syntax as the factory is native to the avl.Object class.

All classes that exend the avl.Object class can be overridden by the factory.

Override by Type

# Copyright 2024 Apheleia
#
# Description:
# Apheleia factory example


import avl
import cocotb


class example_env(avl.Env):
    def __init__(self, name, parent):
        super().__init__(name, parent)
        self.s = sub_comp_A("s", self)


class sub_comp_A(avl.Component):
    def __init__(self, name, parent):
        super().__init__(name, parent)
        self.error("sub_comp_A should have been overriden by sub_comp_B")


class sub_comp_B(avl.Component):
    def __init__(self, name, parent):
        super().__init__(name, parent)
        self.info("sub_comp_B successfully overriden sub_comp_A")


@cocotb.test
async def test(dut):
    avl.Factory.set_override_by_type(sub_comp_A, sub_comp_B)
    e = example_env("env", None)
    await e.start()

Override by Instance

There is no override by name in AVL. Instead, the factory can be used to override by instance. As wildcards (see below) are supported names can always be found.

# Copyright 2024 Apheleia
#
# Description:
# Apheleia factory example


import avl
import cocotb


class example_env(avl.Env):
    def __init__(self, name, parent):
        super().__init__(name, parent)
        self.s = sub_comp_A("s", self)
        self.o = object_A("o", self)


class sub_comp_A(avl.Component):
    def __init__(self, name, parent):
        super().__init__(name, parent)
        self.error("sub_comp_A should have been overriden by sub_comp_B")


class sub_comp_B(avl.Component):
    def __init__(self, name, parent):
        super().__init__(name, parent)
        self.info("sub_comp_B successfully overriden sub_comp_A")


class object_A(avl.Object):
    def __init__(self, name, parent):
        super().__init__(name, parent)
        self.error("object_A should have been overriden by object_B")


class object_B(avl.Object):
    def __init__(self, name, parent):
        super().__init__(name, parent)
        self.info("object_B successfully overriden object_A")


@cocotb.test
async def test(dut):
    avl.Factory.set_override_by_instance("env.s", sub_comp_B)
    avl.Factory.set_override_by_instance("env.o", object_B)

    e = example_env("env", None)
    await e.start()

Wildcards are also supported. These are implemented using the Python fnmatch module.

# Copyright 2024 Apheleia
#
# Description:
# Apheleia factory example


import avl
import cocotb


class example_env(avl.Env):
    def __init__(self, name, parent):
        super().__init__(name, parent)
        self.s = sub_comp_A("s", self)


class sub_comp_A(avl.Component):
    def __init__(self, name, parent):
        super().__init__(name, parent)
        self.error("sub_comp_A should have been overriden by sub_comp_B")


class sub_comp_B(avl.Component):
    def __init__(self, name, parent):
        super().__init__(name, parent)
        self.info("sub_comp_B successfully overriden sub_comp_A")


@cocotb.test
async def test(dut):
    avl.Factory.set_override_by_instance("*.s", sub_comp_B)
    avl.Factory.set_override_by_instance(
        "env.*", sub_comp_A
    )  # Shouldn't be used as not the closest match

    e = example_env("env", None)
    await e.start()

Variables

Similar to the UVM config_db / resource_db variables can be set and retrieved from the factory. No copying is done automatically, classes are passed by reference and literals by value.

This means avl.Var objects can be easily shared, as can cocotb hdl handles.

# Copyright 2024 Apheleia
#
# Description:
# Apheleia factory example


import avl
import cocotb


class example_env(avl.Env):
    def __init__(self, name, parent):
        super().__init__(name, parent)

        self.a = avl.Factory.get_variable(f"{self.get_full_name()}.a", 0)

        if self.a != 100:
            self.error(f"Expected a to be 100, got {self.a}")


@cocotb.test
async def test(dut):
    avl.Factory.set_variable("env.a", 100)

    e = example_env("env", None)
    await e.start()