Jump to content

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


Recommended Posts

Posted

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

Posted

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

 

Posted

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

Posted

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

Posted

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

Posted

What are you trying to do with this line?

trans->set_data_ptr( reinterpret_cast<unsigned char*>(&c) );

It looks strange to me. c is class sc_out<bool> so casting "pointer to sc_out<bool>" to "pointer to unsigned char" doesn't make sense to me?

 

Alan

Posted

Hi Alan,

I want to transmit the value of 'c' in Initiator through Memory, but the attributes of payload transaction only have "set_data_ptr", 

I don't know what to do, can you help me, please?

I sorry because I'm a beginer

Posted (edited)

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

Edited by apfitch

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...