signals - "sc_signal<T> cannot have more than one driver" error, SystemC -


i tried test environment 1 of examples found on website systemc (this one). here code of example:

#include "scv.h"  const unsigned ram_size = 256;  class rw_task_if : virtual public sc_interface { public:    typedef sc_uint<8> addr_t;    typedef sc_uint<8> data_t;    struct write_t {      addr_t addr;      data_t data;    };     virtual data_t read(const addr_t*) = 0;    virtual void write(const write_t*) = 0; };  scv_extensions(rw_task_if::write_t) { public:    scv_extensions<rw_task_if::addr_t> addr;    scv_extensions<rw_task_if::data_t> data;    scv_extensions_ctor(rw_task_if::write_t) {      scv_field(addr);      scv_field(data);    } };  class pipelined_bus_ports : public sc_module { public:    sc_in< bool > clk;    sc_inout< bool > rw;    sc_inout< bool > addr_req;    sc_inout< bool > addr_ack;    sc_inout< sc_uint<8> > bus_addr;    sc_inout< bool > data_rdy;    sc_inout< sc_uint<8> > bus_data;     sc_ctor(pipelined_bus_ports)      : clk("clk"), rw("rw"),        addr_req("addr_req"),        addr_ack("addr_ack"), bus_addr("bus_addr"),        data_rdy("data_rdy"), bus_data("bus_data") {} };  class rw_pipelined_transactor    : public rw_task_if,      public pipelined_bus_ports {     sc_mutex addr_phase;    sc_mutex data_phase;     scv_tr_stream pipelined_stream;    scv_tr_stream addr_stream;    scv_tr_stream data_stream;    scv_tr_generator<sc_uint<8>, sc_uint<8> > read_gen;    scv_tr_generator<sc_uint<8>, sc_uint<8> > write_gen;    scv_tr_generator<sc_uint<8> > addr_gen;    scv_tr_generator<sc_uint<8> > data_gen;  public:    rw_pipelined_transactor(sc_module_name nm) :          pipelined_bus_ports(nm),        addr_phase("addr_phase"),        data_phase("data_phase"),        pipelined_stream("pipelined_stream", "transactor"),        addr_stream("addr_stream", "transactor"),        data_stream("data_stream", "transactor"),        read_gen("read",pipelined_stream,"addr","data"),        write_gen("write",pipelined_stream,"addr","data"),        addr_gen("addr",addr_stream,"addr"),        data_gen("data",data_stream,"data")    {}    virtual data_t read(const addr_t* p_addr);    virtual void write(const write_t * req); };  rw_task_if::data_t rw_pipelined_transactor::read(const rw_task_if::addr_t*  addr) {    addr_phase.lock();    scv_tr_handle h = read_gen.begin_transaction(*addr);     scv_tr_handle h1 = addr_gen.begin_transaction(*addr,"addr_phase",h);    wait(clk->posedge_event());    bus_addr = *addr;    addr_req = 1;    wait(addr_ack->posedge_event());    wait(clk->negedge_event());    addr_req = 0;    wait(addr_ack->negedge_event());    addr_gen.end_transaction(h1);    addr_phase.unlock();     data_phase.lock();    scv_tr_handle h2 = data_gen.begin_transaction("data_phase",h);    wait(data_rdy->posedge_event());    data_t data = bus_data.read();    wait(data_rdy->negedge_event());    data_gen.end_transaction(h2);    read_gen.end_transaction(h,data);    data_phase.unlock();     return data; }  void rw_pipelined_transactor::write(const write_t * req) {    scv_tr_handle h = write_gen.begin_transaction(req->addr);    // ...    write_gen.end_transaction(h,req->data); }  class test : public sc_module { public:    sc_port< rw_task_if > transactor;    sc_ctor(test) {      sc_thread(main);    }    void main(); };  class write_constraint : virtual public scv_constraint_base { public:    scv_smart_ptr<rw_task_if::write_t> write;    scv_constraint_ctor(write_constraint) {      scv_constraint( write->addr() <= ram_size );      scv_constraint( write->addr() != write->data() );    } };  inline void process(scv_smart_ptr<int> data) {}  inline void test::main() {    // simple sequential tests    (int i=0; i<3; i++) {      rw_task_if::addr_t addr = i;      rw_task_if::data_t data = transactor->read(&addr);      cout << "at time " << sc_time_stamp() << ": ";      cout << "received data : " << data << endl;    }     scv_smart_ptr<rw_task_if::addr_t> addr;    (int i=0; i<3; i++) {       addr->next();      rw_task_if::data_t data = transactor->read( addr->get_instance() );      cout << "data address " << *addr << " " << data << endl;    }     scv_smart_ptr<rw_task_if::write_t> write;    (int i=0; i<3; i++) {      write->next();      transactor->write( write->get_instance() );      cout << "send data : " << write->data << endl;    }     scv_smart_ptr<int> data;    scv_bag<int> distribution;    distribution.push(1,40);    distribution.push(2,60);    data->set_mode(distribution);    (int i=0;i<3; i++) { data->next(); process(data); } }  class design : public pipelined_bus_ports {    list< sc_uint<8> > outstandingaddresses;    list< bool > outstandingtype;    sc_uint<8>  memory[ram_size];  public:    sc_has_process(design);    design(sc_module_name nm) : pipelined_bus_ports(nm) {      (unsigned i=0; i<ram_size; ++i) { memory[i] = i; }      sc_thread(addr_phase);      sc_thread(data_phase);    }    void addr_phase();    void data_phase(); };  inline void design::addr_phase() {    while (1) {      while (addr_req.read() != 1) {        wait(addr_req->value_changed_event());      }      sc_uint<8> _addr = bus_addr.read();      bool _rw = rw.read();       int cycle = rand() % 10 + 1;      while (cycle-- > 0) {        wait(clk->posedge_event());      }       addr_ack = 1;      wait(clk->posedge_event());      addr_ack = 0;       outstandingaddresses.push_back(_addr);      outstandingtype.push_back(_rw);      cout << "at time " << sc_time_stamp() << ": ";      cout << "received request memory address " << _addr << endl;    } }  inline void design::data_phase() {    while (1) {      while (outstandingaddresses.empty()) {        wait(clk->posedge_event());      }      int cycle = rand() % 10 + 1;      while (cycle-- > 0) {        wait(clk->posedge_event());      }      if (outstandingtype.front() == 0) {        cout << "reading memory address " << outstandingaddresses.front()             << " value " << memory[outstandingaddresses.front()] << endl;        bus_data = memory[outstandingaddresses.front()];        data_rdy = 1;        wait(clk->posedge_event());        data_rdy = 0;       } else {        cout << "not implemented yet" << endl;      }      outstandingaddresses.pop_front();      outstandingtype.pop_front();    } }  int sc_main (int argc , char *argv[]) {    scv_startup();     scv_tr_text_init();    scv_tr_db db("my_db");    scv_tr_db::set_default_db(&db);     // create signals    sc_clock clk("clk",20,sc_ns,0.5,0,sc_ns,true);    sc_signal< bool > rw;    sc_signal< bool > addr_req;    sc_signal< bool > addr_ack;    sc_signal< sc_uint<8> > bus_addr;    sc_signal< bool > data_rdy;    sc_signal< sc_uint<8> > bus_data;     // create modules/channels    test t("t");    rw_pipelined_transactor tr("tr");    design duv("duv");     // connect them    t.transactor(tr);     tr.clk(clk);    tr.rw(rw);    tr.addr_req(addr_req);    tr.addr_ack(addr_ack);    tr.bus_addr(bus_addr);    tr.data_rdy(data_rdy);    tr.bus_data(bus_data);     duv.clk(clk);    duv.rw(rw);    duv.addr_req(addr_req);    duv.addr_ack(addr_ack);    duv.bus_addr(bus_addr);    duv.data_rdy(data_rdy);    duv.bus_data(bus_data);     // run simulation    sc_start(1000000, sc_ns);     return 0; } 

it's nothing much. transactor , duv extended classes of module , transactor generates address , sends duv , duv reads data memory address. looks fine when try run error:

tb transaction recording has started, file = my_db transaction recording closing file: my_db  error: (e115) sc_signal<t> cannot have more 1 driver:   signal 'signal_5' (sc_signal)  first driver 'duv.bus_data'  (sc_inout)  second driver 'tr.bus_data' (sc_inout) in file: ../../../../src/sysc/communication/sc_signal.cpp:73  

i can't see multiple drivers when duv sends signal , transactor reads signal. if delete of lines signal still shows same error.

the previous reply correct: error result of both duv.bus_data , tr.bus_data being sc_inout ports. systemc flags error because both ports could write signal.

there 3 solutions:

  1. set environment variable sc_signal_write_check disable before running simulation. method out dated.
  2. set sc_default_writer_policy preprocesor variable sc_many_writers when compiling code.
  3. define writer policy signal such allows many writers: sc_signal<sc_uint<8>, sc_many_writers> bus_data. best option.

see install file @ root of accellera systemc distribution more information.

use code proove above solutions:

#include <systemc.h>  sc_module(module) {     sc_inout< sc_uint<8> > bus_data;     sc_ctor(module): bus_data("bus_data") {} };  int sc_main (int argc , char *argv[]) {     // sc_signal< sc_uint<8> > bus_data;     sc_signal<sc_uint<8>, sc_many_writers> bus_data;     module m1("m1");     module m2("m2");     m1.bus_data(bus_data);     m2.bus_data(bus_data);      sc_start(1, sc_ns);      return 0; } 

Comments

Popular posts from this blog

angular - Is it possible to get native element for formControl? -

unity3d - Rotate an object to face an opposite direction -

javascript - Why jQuery Select box change event is now working? -