Jump to content

Error: (E100) port specified outside of module: port 'simple_target_socket_0_port_0' (sc_port_base)


Recommended Posts

Hi all,

I just working with TLM systemC, I'm trying to complete a simple example, but I got a error:

 

Error: (E100) port specified outside of module: port 'simple_target_socket_0_port_0' (sc_port_base)
In file: ..\..\src\sysc\communication\sc_port.cpp:231
 
Help me in the shortest time, please. My codes is attached below
.
Thansk all and sorry because my english is not good  :)

Initiator.txt

Memory.txt

main.txt

Link to post
Share on other sites

thank Alan for your interest,

I've fixed it but it still fails  :(

Error: (E100) port specified outside of module: port 'simple_initiator_socket_0' (sc_port_base)
In file: ..\..\src\sysc\communication\sc_port.cpp:231
And if I remove these lines of code:
tlm_utils::simple_initiator_socket<Initiator> socket1;
tlm_utils::simple_target_socket<Memory> socket2;

initiator.socket(socket1);
memory.socket(socket2);
It is an error:
Error: (E109) complete binding failed: port not bound: port 'top.memory.port_0' (sc_out)
In file: ..\..\src\sysc\communication\sc_port.cpp:231
#define SC_INCLUDE_DYNAMIC_PROCESSES
#include "systemc"
using namespace sc_core;
using namespace sc_dt;
using namespace std;
#include "tlm.h"
#include "tlm_utils/simple_initiator_socket.h"
#include "tlm_utils/simple_target_socket.h"
#include "Initiator.h"
#include "Memory.h"
struct Top : public sc_module
{
  Initiator *initiator;
  Memory    *memory;

  SC_CTOR(Top)
  {
    initiator = new Initiator("initiator");
    memory    = new Memory   ("memory");
    initiator->socket.bind( memory->socket );
  }
};

int sc_main(int argc, char* argv[])
{
  Top top("top");
  Initiator initiator("initiator");
  Memory memory("memory");

  sc_time t(100, SC_PS);

  sc_signal<bool> a,b,c,d;

  tlm_utils::simple_initiator_socket<Initiator> socket1;
  tlm_utils::simple_target_socket<Memory> socket2;

  initiator.socket(socket1);
  memory.socket(socket2);

  initiator.socket(memory.socket);

  initiator.a(a);
  initiator.b( ;
  initiator.c(c);

  memory.d(d);

  sc_trace_file *wf= sc_create_vcd_trace_file("and2");
  sc_trace(wf, initiator.a, "a");
  sc_trace(wf, initiator.b, "b");
  sc_trace(wf, initiator.c, "c");
  sc_trace(wf, memory.d, "d");

  a.write(0);
  b.write(0);
  sc_start(t);
  a.write(0);
  b.write(1);
  sc_start(t);
  a.write(1);
  b.write(0);
  sc_start(t);
  a.write(1);
  b.write(1);
  sc_start(t);
  a.write(0);
  b.write(0);
  sc_start(t);
  sc_stop();

  sc_close_vcd_trace_file(wf);
  return 0;
}

regards,
Huy

 

Link to post
Share on other sites

Hi Huy,

  I realised I did not read your code properly.

You have an instance Top *and* you have instances of Initiator and Memory in your sc_main.

 

I think the way you have written your code, you do not need Top.

 

So if you take out Top and also take out the socket declarations in sc_main that is better.

 

regards

Alan

Link to post
Share on other sites

Hi Alan,

I very happy when I receive your feedback.

I had fixed it, but it is run improperly. It does not perform the fuction "and" in Initiator and does not transmit result from Initiator throught Memory

#define SC_INCLUDE_DYNAMIC_PROCESSES

#include "systemc"
using namespace sc_core;
using namespace sc_dt;
using namespace std;

#include "tlm.h"
#include "tlm_utils/simple_initiator_socket.h"
#include "tlm_utils/simple_target_socket.h"
#include "Initiator.h"
#include "Memory.h"

int sc_main(int argc, char* argv[])
{
 
  Initiator initiator("initiator");
  Memory memory("memory");

  sc_time t(100, SC_PS);

  sc_signal<bool> a,b,c,d;

  initiator.a(a);
  initiator.b(;
  initiator.c(c);

  memory.d(d);

  sc_trace_file *wf= sc_create_vcd_trace_file("and2");
  sc_trace(wf, initiator.a, "a");
  sc_trace(wf, initiator.b, "b");
  sc_trace(wf, initiator.c, "c");
  sc_trace(wf, memory.d, "d");

  a.write(0);
  b.write(0);

  sc_start(t);
  a.write(0);
  b.write(1);

  sc_start(t);
  a.write(1);
  b.write(0);

  sc_start(t);
  a.write(1);
  b.write(1);

  sc_start(t);
  a.write(0);
  b.write(0);

  sc_start(t);
  sc_stop();

  sc_close_vcd_trace_file(wf);
  return 0;
}
#define SC_INCLUDE_DYNAMIC_PROCESSES

#include "systemc"
using namespace sc_core;
using namespace sc_dt;
using namespace std;

#include "tlm.h"
#include "tlm_utils/simple_initiator_socket.h"
#include "tlm_utils/simple_target_socket.h"

struct Initiator: sc_module
{
  tlm_utils::simple_initiator_socket<Initiator> socket;

	sc_in<bool> a,b;
	sc_out<bool> c;

  SC_CTOR(Initiator) : socket("socket")
  {
    SC_THREAD(do_and);
	sensitive << a << b;
  }

  void do_and()
  {
	c.write(a.read()& b.read());

    tlm::tlm_generic_payload* trans = new tlm::tlm_generic_payload;
    sc_time delay = sc_time(10, SC_NS);

      tlm::tlm_command cmd = tlm::TLM_WRITE_COMMAND;

      trans->set_command( cmd );
      trans->set_address(0);
      trans->set_data_ptr( reinterpret_cast<unsigned char*>(&c) );
      trans->set_data_length( 4 );
      trans->set_streaming_width( 4 ); // = data_length to indicate no streaming
      trans->set_byte_enable_ptr( 0 ); // 0 indicates unused
      trans->set_dmi_allowed( false ); // Mandatory initial value
      trans->set_response_status( tlm::TLM_INCOMPLETE_RESPONSE ); // Mandatory initial value

      socket->b_transport( *trans, delay );  // Blocking transport call
      
      // Initiator obliged to check response status and delay
      //if ( trans->is_response_error() )
        //SC_REPORT_ERROR("TLM-2", "Response error from b_transport");
  }
};
#define SC_INCLUDE_DYNAMIC_PROCESSES

#include "systemc"
using namespace sc_core;
using namespace sc_dt;
using namespace std;

#include "tlm.h"
#include "tlm_utils/simple_initiator_socket.h"
#include "tlm_utils/simple_target_socket.h"

// Target module representing a simple memory

struct Memory: sc_module
{
	sc_out<bool> d;

	enum { SIZE = 256 };
	int mem[SIZE];

	tlm_utils::simple_target_socket<Memory> socket;

  SC_CTOR(Memory) : socket("socket")
  {
    socket.register_b_transport(this, &Memory::b_transport);
  }

  // TLM-2 blocking transport method
	virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay )
  {
     tlm::tlm_command	cmd = trans.get_command();
     sc_dt::uint64		adr = trans.get_address() / 4;
     unsigned char*		ptr = trans.get_data_ptr();
     unsigned int		len = trans.get_data_length();
     unsigned char*		byt = trans.get_byte_enable_ptr();
     unsigned int		wid = trans.get_streaming_width();

    // Obliged to check address range and check for unsupported features,
    //   i.e. byte enables, streaming, and bursts
    // Can ignore DMI hint and extensions
    // Using the SystemC report handler is an acceptable way of signalling an error

    if (adr >= sc_dt::uint64(SIZE) || byt != 0 || len > 4 || wid < len)
      SC_REPORT_ERROR("TLM-2", "Target does not support given generic payload transaction");

    // Obliged to implement read and write commands
    if ( cmd == tlm::TLM_READ_COMMAND )
      memcpy(ptr, &mem[adr], len);
    else if ( cmd == tlm::TLM_WRITE_COMMAND )
      memcpy(&mem[adr], ptr, len);

	d.write(mem[adr]);
	}
};

2016-02-264.png

Link to post
Share on other sites

Hi Alan,

I have bound the socket in sc_main: initiator.socket(memory.socket);

#define SC_INCLUDE_DYNAMIC_PROCESSES

#include "systemc"
using namespace sc_core;
using namespace sc_dt;
using namespace std;

#include "tlm.h"
#include "tlm_utils/simple_initiator_socket.h"
#include "tlm_utils/simple_target_socket.h"
#include "Initiator.h"
#include "Memory.h"

int sc_main(int argc, char* argv[])
{
  Initiator initiator("initiator");
  Memory memory("memory");

  sc_time t(100, SC_PS);

  sc_signal<bool> a,b,c,d;

  initiator.socket(memory.socket);

  initiator.a(a);
  initiator.b(;
  initiator.c(c);

  memory.d(d);

  sc_trace_file *wf= sc_create_vcd_trace_file("and2");
  sc_trace(wf, initiator.a, "a");
  sc_trace(wf, initiator.b, "b");
  sc_trace(wf, initiator.c, "c");
  sc_trace(wf, memory.d, "d");

  a.write(0);
  b.write(0);

  sc_start(t);
  a.write(0);
  b.write(1);

  sc_start(t);
  a.write(1);
  b.write(0);

  sc_start(t);
  a.write(1);
  b.write(1);

  sc_start(t);
  a.write(0);
  b.write(0);

  sc_start(t);
  sc_stop();

  sc_close_vcd_trace_file(wf);
  return 0;
} 

And I added an infinite loop inside my do_and thread, but it still fails  :(

 

Untitled.png

 

And if I add the code  if ( trans->is_response_error() ) SC_REPORT_ERROR("TLM-2", "Response error from b_transport"); into Initiator, it is error as below

#define SC_INCLUDE_DYNAMIC_PROCESSES

#include "systemc"
using namespace sc_core;
using namespace sc_dt;
using namespace std;

#include "tlm.h"
#include "tlm_utils/simple_initiator_socket.h"
#include "tlm_utils/simple_target_socket.h"

struct Initiator: sc_module
{
  tlm_utils::simple_initiator_socket<Initiator> socket;

	sc_in<bool> a,b;
	sc_out<bool> c;

  SC_CTOR(Initiator) : socket("socket")
  {
    SC_THREAD(do_and);
	sensitive << a << b;
  }

  void do_and()
  {
	  while(true)
	  {
		c.write(a.read()&b.read());

		tlm::tlm_generic_payload* trans = new tlm::tlm_generic_payload;
		sc_time delay = sc_time(10, SC_NS);

		tlm::tlm_command cmd = tlm::TLM_WRITE_COMMAND;

		trans->set_command( cmd );
		trans->set_address(0);
		trans->set_data_ptr( reinterpret_cast<unsigned char*>(&c) );
		trans->set_data_length( 4 );
		trans->set_streaming_width( 4 ); // = data_length to indicate no streaming
		trans->set_byte_enable_ptr( 0 ); // 0 indicates unused
		trans->set_dmi_allowed( false ); // Mandatory initial value
		trans->set_response_status( tlm::TLM_INCOMPLETE_RESPONSE ); // Mandatory initial value

		socket->b_transport( *trans, delay );  // Blocking transport call
      
		 //Initiator obliged to check response status and delay
		if ( trans->is_response_error() )
			SC_REPORT_ERROR("TLM-2", "Response error from b_transport");
	  }
  }
}; 

Untitleda0307.png

 

regards,

Huy

Link to post
Share on other sites

The TLM function calls use an array of character.

What I suggest you do is actually use a character, then it will be easier to understand.

 

So in the initiator

 unsigned char c_char[4]; 
 while(true)
	  {
		c_char[0] = a.read()&b.read();
                c.write(c_char[0]);

 ...
 		trans->set_data_ptr( c_char);

I.e. put the boolean value into byte 0 of an array of 4 bytes. Then you don't need the reinterpret_cast etc,

 

regards

Alan

Link to post
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...