从sc_signal驱动sc_out

时间:2016-09-19 13:52:45

标签: c++ systemc

考虑以下示例,其中一个模块的输出(inner::out)应该驱动上层级别的两个输出(outer::outouter::out2):

#include <systemc.h>

SC_MODULE(inner) {
    sc_out<bool> out;

    SC_CTOR(inner) : out("out") {
        SC_THREAD(doit);
    };

    void doit() {
        for (int i=0; i<10; ++i) {
            out != out;
            wait(10, SC_NS);
        }
    }
};


SC_MODULE(outer) {
    sc_out<bool> out, out2;

    SC_CTOR(outer) : out("out"), out2("out2"), i("inner"), out_s("out_s") {
        i.out(out_s);

        out(out_s);
        out2(out_s);
    }

    inner i;

    sc_signal<bool> out_s;
};


int sc_main(int argc, char **argv) {
    outer o("outer");

    sc_start(1, SC_MS);

    return 0;
}

https://www.edaplayground.com/x/5s2C#

运行此操作会导致以下错误:

Error: (E115) sc_signal<T> cannot have more than one driver: 
 signal `outer.out_s' (sc_signal)
 first driver `outer.inner.out'  (sc_out)
 second driver `outer.out2' (sc_out)
In file: ../../../../src/sysc/communication/sc_signal.cpp:73

似乎outer::out2被认为是驱动 out_s而不是驱动。我有什么可以忽视的东西吗?有没有办法让这项工作不使用SC_METHOD inner::outouter的明确{{1}}敏感?

2 个答案:

答案 0 :(得分:1)

您的设计描述了由三个不同输出端口驱动的信号 - 而不是您想要的信号。

您可能希望使用端口到端口绑定。如果您不熟悉这个概念,SystemC LRM中的第4.1.3节“端口绑定和导出绑定”描述如下:

  

当端口A绑定到端口B,端口B绑定到通道C时,效果应与端口A直接绑定到通道C的效果相同。无论此标准是指端口A绑定到通道C ,应该假设这意味着端口A直接绑定到通道C或绑定到通道C的另一个端口,根据这个相同的规则。绑定出口时,同样的规则也适用。

使用端口到端口绑定,您可以将inner::out直接绑定到outer::outouter::out2,而不会在其间发出信号。例如:

#include <systemc.h>

SC_MODULE(inner) {
    sc_port<sc_signal_inout_if<bool>, 2> out;

    SC_CTOR(inner) : out("out") {
        SC_THREAD(doit);
    };

    void doit() {
        for (int i=0; i<10; ++i) {
            out[0]->write(!out[0]->read());
            out[1]->write(!out[1]->read());
            wait(10, SC_NS);
        }
    }
};


SC_MODULE(outer) {
    sc_out<bool> out, out2;

    SC_CTOR(outer) : out("out"), out2("out2"), i("inner") {
        i.out(out);
        i.out(out2);
    }

    inner i;
};


int sc_main(int argc, char **argv) {
    outer o("outer");
    sc_signal<bool> out_s;
    sc_signal<bool> out2_s;

    o.out(out_s);
    o.out2(out2_s);

    sc_trace_file *tf = sc_create_vcd_trace_file("trace");
    sc_trace(tf, out_s, "out_s");
    sc_trace(tf, out2_s, "out2_s");

    sc_start(1, SC_MS);

    sc_core::sc_close_vcd_trace_file(tf);

    return 0;
}

上面的代码中有几点需要注意:

  • inner::out被声明为sc_port<sc_signal_inout_if<bool>, 2>,它与sc_out基本相同,但允许端口绑定到两个通道。 sc_out只能绑定到一个频道。
  • 写入inner::out时,您必须指定您正在驾驶的绑定频道。这是通过[]运算符完成的 - 请参阅上面的inner::doit(),其中两个绑定通道都已被驱动。

运行时,上面的代码会生成一个trace.vcd文件,显示两个信号out_sout2_s的切换级别。

解释了所有这些,我不确定它真的是你想要的。让输出端口像这样扇出非常不寻常。你真的需要outer上的两个输出端口吗?

答案 1 :(得分:1)

错误:(E115)sc_signal不能有多个驱动程序:

可以使用SC_MANY_WRITERS解决。

例如:

sc_signal < bool, SC_MANY_WRITERS > reset_sig;

然后对于一个名为initializer的模块,我们可以这样绑定这个信号:

initializer<int, 16> init("init");

init.reset(reset_sig);

现在用于另一个模块,生产者模块,它使用相同的信号:

producer<int, 16> prc("prc");

prc.resetIn(reset_sig);
prc.resetOut(reset_sig);