Вопрос или проблема
Учитывая модуль-обертку с некоторыми экспортами (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;
}
Объяснение кода:
-
CORE Модуль: Определяем базовый модуль, который принимает один входной сигнал и генерирует выходной. Метод
process
вызывается каждый раз, когда изменяется входной сигнал. -
Wrapper: В этом модуле мы создаем сигналы (
m0_sig_in_s
,m1_sig_in_s
,m0_sig_out_s
) для связывания с входами и выходами. Мы связываем портport_in
с внутренними сигналами и подключаем их к модулямm0
иm1
. -
Top Модуль: В этом модуле мы инициализируем сигналы
clock
иresult
и связываем их с портами обертки. Затем мы создаем поток для управления сигналомclock
.
Заключение:
Данный код демонстрирует, как можно использовать sc_signal
для управления входами и выходами обертки, сохраняя при этом удобство в именовании. Вы без проблем сможете доработать механизм, чтобы добавить логическую часть или обрабатывать несколько сигналов в зависимости от вашей логики построения системы.