【问题标题】:Is it possible to bind the output of a submodule to two different output ports?是否可以将子模块的输出绑定到两个不同的输出端口?
【发布时间】:2019-10-21 01:18:16
【问题描述】:

我正在尝试制作一个计算加法进位的电路。

在这段代码中,我想将子模块pg的输出端口rOut连接到父模块的两个输出端口(@98​​7654323@和carries[0]),所以两者都得到相同的值.

template<>
struct Carries<1> : ::sc_core::sc_module {
    sc_vector<sc_in<bool>> a, b;
    sc_in<bool> rIn;
    sc_out<bool> p, g, rOut;
    sc_vector<sc_out<bool>> carries;

    CarryPropGen pg {"PG"};

    SC_CTOR(Carries)
        :   a {"vectA", 1}, b {"vectB", 1},
            rIn {"rIn"},
            p {"p"}, g {"g"}, rOut {"rOut"},
            carries {"vectCarries", 1} {
        pg.a(a[0]);
        pg.b(b[0]);
        pg.r(rIn);

        pg.p(p);
        pg.g(g);
        pg.rOut(rOut);
        pg.rOut(carries[0]);
    }
};

但是,我收到错误 (E109) complete binding failed: 2 binds exceeds maximum of 1 allowed: port 'Carries.PG.port_5' (sc_out)。 我还尝试了一个信号,无论有没有作者政策SC_MANY_WRITER,正如论坛上有人建议的那样,但它也不起作用。

我是 SystemC 的新手,虽然我理解错误,但我真的不明白为什么这不能工作以及如何以不同的方式做到这一点。 那么,有没有办法将一个子模块的输出绑定到父模块的多个sc_out,以及如何?

【问题讨论】:

    标签: systemc


    【解决方案1】:

    SystemC 中的端口不是连线,而是智能指针。与常规 C++ 指针不同,SystemC 端口是安全的并支持分层绑定。与常规指针类似,默认情况下您不能同时将端口连接到 2 个通道。

    虽然这对于低级建模可能不方便,但允许将端口与任何类型的高级通道(如 FIFO 或 TLM 通道)一起使用。

    看起来您需要广播端口之类的东西:当您写入此类端口时,应将消息写入所有连接的通道。

    要创建一个可以绑定到多个通道的端口,请使用 sc_port 的第二个模板参数 N

    // ----------------------------------------------------------------------------
    //  CLASS : sc_port
    //
    //  Generic port class and base class for other port classes.
    //  N is the maximum number of channels (with interface IF) that can be bound
    //  to this port. N <= 0 means no maximum.
    // ----------------------------------------------------------------------------
    template <class IF, int N = 1, sc_port_policy P=SC_ONE_OR_MORE_BOUND>
    class sc_port
    

    让我们测试一下:

    #include <systemc.h>
    
    SC_MODULE(test) {
      // Create broadcast_port that allows any number of binded channels
      sc_port<sc_signal_inout_if<int>, 0> SC_NAMED(broadcast_port);
    
      // create some signals
      sc_signal<int> SC_NAMED(a);
      sc_signal<int> SC_NAMED(b);
      sc_signal<int> SC_NAMED(c);
    
      SC_CTOR(test) {
        // bind port to signals
        broadcast_port(a);
        broadcast_port(b);
        broadcast_port(c);
    
        SC_THREAD(test_thread);
      }
    
      void test_thread() {
        // write 42 to all connected signals
        for (size_t ii = 0; ii < broadcast_port.size(); ++ii) {
          broadcast_port[ii]->write(42);
        }
    
        wait(SC_ZERO_TIME);
        // print results
        std::cout << a << "\n";
        std::cout << b << "\n";
        std::cout << c << "\n";
      }
    };
    
    int sc_main(int, char *[]) {
      test SC_NAMED(test_top);
      sc_start();
      return 0;
    }
    

    这并不是我们想要的:每次我们需要向广播端口写入内容时,我们都需要遍历所有连接的通道。

    让我们创建一个自动执行此操作的派生类:

    template <typename T>
    class sc_out_broadcast : public sc_port<sc_signal_inout_if<int>, 0>
    {
    public:
      explicit sc_out_broadcast(const char *name_) : sc_port(name_) {}
    
      // write the new value to all connected signals
      void write( const T& value_ )
      {
        for (size_t ii = 0; ii < this->size(); ++ii) {
          (*this)[ii]->write(value_);
        }
      }
    };
    

    这是我们在 test_thread 中使用它的方式:

      void test_thread() {
    
        broadcast_port.write(42);
    
        wait(SC_ZERO_TIME);
    
        std::cout << a << "\n";
        std::cout << b << "\n";
        std::cout << c << "\n";
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-25
      相关资源
      最近更新 更多