Управление sc_signal с использованием sc_in, sc_out с помощью sc_signal

Вопрос или проблема

Учитывая модуль-обертку с некоторыми экспортами (sc_in, sc_out)

Мне хотелось бы использовать несколько сигналов sc_in в основных модулях и разрешить нескольким основным модулям управлять сигналами sc_out обертки (один драйвер на sc_out).

Я знаю, что связывание портов возможно, однако я настаиваю на использовании sc_signal в качестве промежуточного элемента, потому что у меня есть особые соглашения о наименовании для моей обертки/модулей, и использование sc_signal позволит мне сохранить оба.

Это должно быть довольно просто осуществимо, в Verilog это позволено с помощью провода. Однако я не смог найти много информации об этом в интернете.

В основном, я хотел бы сделать это (синтаксис очень грубый):

--------------- Где-то в обертке ------
sc_signal<bool> m1_sig_in_s;
sc_signal<bool> m0_sig_in_s;
sc_in<bool> port_in;
sc_out<bool> port_out;

m0_sig_in_s(port_in);
m1_sig_in_s(port_in);
port_out(m0_sig_out_s);

m0.in(m0_sig_in_s);
m0.out(m0_sig_out_s);

m1.in(m1_sig_in_s);
---------------- КОНЕЦ 
---------------- Где-то на верхнем уровне ----- 
sc_signal<bool> clock;
sc_signal<bool> result;

wrapper.port_in(clock);
wrapper.port_out(result);

// Выполните действия для управления сигналами clock и result //
---------------- КОНЕЦ 

Опять же, я знаю, что мог бы сделать связывание портов и напрямую связать port_in с m0.in и m1.in и т.д. Однако должен быть простой способ сделать то, что я показываю в SystemC, не так ли?

Предыдущий вопрос (Управление sc_out из sc_signal) также пытается сделать что-то подобное, однако без окончательного ответа.

П.С. Я знаю, что, вероятно, мог бы использовать некоторую вариацию read/write, чтобы добиться этого, но это было бы очень многословно для того, что я вижу как очень простое.

Ответ или решение

Для решения задачи, связанной с использованием sc_signal для управления sc_in и sc_out в вашем обертке, можно применить следующий подход. Основная идея заключается в том, чтобы использовать сигналы для связывания входных и выходных портов ваших модулей, что позволит сохранить вашу именовательную конвенцию.

Вот пример кода, который иллюстрирует, как можно это организовать:

#include <systemc.h>

// Определяем основной модуль
SC_MODULE(CORE) {
    sc_in<bool> in;
    sc_out<bool> out;

    SC_CTOR(CORE) {
        SC_METHOD(process);
        sensitive << in;
    }

    void process() {
        // Пример простой логики, которая может
        // использовать входной сигнал для генерации выходного
        out.write(in.read()); // Просто передаем вход на выход
    }
};

// Обертка, которая будет использовать sc_signal
SC_MODULE(Wrapper) {
    // Сигналы для внутреннего использования
    sc_signal<bool> m0_sig_in_s;
    sc_signal<bool> m1_sig_in_s;
    sc_signal<bool> m0_sig_out_s;

    // Вход и выход обертки
    sc_in<bool> port_in;
    sc_out<bool> port_out;

    CORE m0;
    CORE m1;

    SC_CTOR(Wrapper) : m0("m0"), m1("m1") {
        // Привязка сигналов ко входным и выходным портам
        m0_sig_in_s(port_in);
        m1_sig_in_s(port_in);
        port_out(m0_sig_out_s);

        // Подключаем модули к сигналам
        m0.in(m0_sig_in_s);
        m0.out(m0_sig_out_s);

        m1.in(m1_sig_in_s);
        m1.out(m0_sig_out_s); // Второй модуль пишет в тот же выходной сигнал
    }
};

// Топ-уровень, который включает обертку
SC_MODULE(Top) {
    sc_signal<bool> clock;
    sc_signal<bool> result;

    Wrapper wrapper;

    SC_CTOR(Top) : wrapper("wrapper") {
        wrapper.port_in(clock);
        wrapper.port_out(result);

        SC_THREAD(driver);
        // Добавьте необходимые временные задержки для управления.
    }

    void driver() {
        while (true) {
            clock.write(true);
            wait(10, SC_NS); // Приблизительная задержка
            clock.write(false);
            wait(10, SC_NS);
        }
    }
};

// Основная функция для запуска симуляции
int sc_main(int argc, char* argv[]) {
    Top top("top");
    sc_start(); // Запуск симуляции
    return 0;
}

Объяснение кода:

  1. CORE Модуль: Определяем базовый модуль, который принимает один входной сигнал и генерирует выходной. Метод process вызывается каждый раз, когда изменяется входной сигнал.

  2. Wrapper: В этом модуле мы создаем сигналы (m0_sig_in_s, m1_sig_in_s, m0_sig_out_s) для связывания с входами и выходами. Мы связываем порт port_in с внутренними сигналами и подключаем их к модулям m0 и m1.

  3. Top Модуль: В этом модуле мы инициализируем сигналы clock и result и связываем их с портами обертки. Затем мы создаем поток для управления сигналом clock.

Заключение:

Данный код демонстрирует, как можно использовать sc_signal для управления входами и выходами обертки, сохраняя при этом удобство в именовании. Вы без проблем сможете доработать механизм, чтобы добавить логическую часть или обрабатывать несколько сигналов в зависимости от вашей логики построения системы.

Оцените материал
Добавить комментарий

Капча загружается...