вторник, 16 ноября 2010 г.

Что такое Callback в SystemVerilog?

 Начнем с определения из википедии:

Callback (англ. call — вызов, англ. back — обратный) или фу́нкция обра́тного вы́зова в программировании — передача исполняемого кода в качестве одного из параметров другого кода.

    Например, вам необходимо передать одну функцию в качестве входного параметра другой функции. Это и есть callback.

    Как это реализуется с помощью средств ООП в SystemVerilog? Рассмотрим пример:
Есть базовый класс my_transactor, который принимает транзакции от драйвера и пересылает их в монитор:

class my_transactor;
    ...
    task main();
        ...
        forever begin
            ...
            // Достаем из почтового ящика транзакцию,
            // которую прислал драйвер
            driver2xactor.get(in_tr);
            // Выполняем необходимые действия
            ...
            // Отправляем транзакцию в блок монитора
            xactor2monitor.put(out_tr);
            ...
        end
    endtask
endclass

    Предположим, мы хотим просто посмотреть содержимое принятой транзакции и содержимое транзакции, подготовленной для пересылки в монитор:

class my_transactor;
    ...
    task main();
        ...
        forever begin
            ...
            // Достаем из почтового ящика транзакцию,
            // которую прислал драйвер
            driver2xactor.get(in_tr);
            $display(" Input trans: a = %h, b = %h", in_tr.a, in_tr.b);
            // Выполняем необходимые действия
            ...
            // Отправляем транзакцию в блок монитора
            $display(" Output trans: a = %h, b = %h", out_tr.a, out_tr.b);
            xactor2monitor.put(out_tr);
            ...
        end
    endtask
endclass

    Теперь этот код непригоден для повторного использования, т.к. добавленные сообщения специфичны для конкретной тестируемой схемы (DUT) или для определенного теста. Это становится ощутимо, если поменять содержимое транзакции или попробовать не выводить содержимое транзакции в наследуемом классе. Необходимо избегать использования специфичного для данной реализации кода в тестовых окружениях, предназначенных для повторного использования. Эта проблема общая для повторно используемого кода, не только касательно верификации. И средства ООП предлагают решение этой проблемы: виртуальные методы. С помощью них можно расширить возможности транзактора при необходимости:

class my_transactor;
    virtual task pre_exec(in_trans tr);
    endtask
    virtual task post_exec(out_trans tr);
    endtask
    ...
    task main();
        ...
        forever begin
            ...
            // Достаем из почтового ящика транзакцию,
            // которую прислал драйвер
            driver2xactor.get(in_tr);
            this.pre_exec(in_tr);
            // Выполняем необходимые действия
            ...
            // Отправляем транзакцию в блок монитора
            this.post_exec(out_tr);
            xactor2monitor.put(out_tr);
            ...
        end
    endtask
endclass

class my_transactor_child extend my_transactor;
    virtual task pre_exec(in_trans tr);
        $display(" Input trans: a = %h, b = %h", tr.a, tr.b);
    endtask
    virtual task post_exec(out_trans tr);
        $display(" Output trans: a = %h, b = %h", tr.a, tr.b);
    endtask
    ...
endclass

    Как это работает? В базовом классе my_transactor есть 3 подзадачи task, 2 из которых виртуальные и не реализованы. Класс-потомок my_transactor_child наследует методы базового класса и может и заполняет виртуальные методы в соответствии со своими нуждами. Тем самым мы можем вносить изменения в метод main, не изменяя его код.
    Callback методы содержат фрагменты кода, функции и подзадачи, которые меняются от теста к тесту. Они очень полезны, когда идет речь о создании базового класса, который планируется использовать в нескольких тестовых окружениях.
    У приведенного выше примера callback есть некоторые ограничения, которые можно решить с помощью паттернов. Паттерны в ООП это не базовые классы или библиотеки. Это некий шаблон проектирования или техника для построения объектно-ориентированного кода, которая позволяет решить сложные задачи. Подробнее об этом в статье - Janick Bergeron "How to use VMM callbacks"

Комментариев нет:

Отправить комментарий