Jump to content

Implement the function


VanTeo

Recommended Posts

Hi all,

I have a example with systemC. This example is implement and function. I have tried print results out to the monitor, but it seems to be incorrect ( it seems like the "c" variable updates slower than "a" and "b"  variable). Help me, please!  :wub:

 

Untitled08769.png

#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[])
{
  Initiator *initiator;
  Memory    *memory;

  initiator = new Initiator("initiator");
  memory    = new Memory   ("memory");

  initiator->socket( memory->socket );

  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()
  {
	  while(true)
	  {
		c.write(a.read()&b.read());
		data = 0xFF000000 | (c | 0x00000030);

		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*>(&data) );
		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");
		
		cout << " a = " << hex << a << " , b = " << hex << b << " , c = " <<  hex << c << " , data = " << hex << data << " , " << sc_time_stamp() << endl;

		wait();
	  }
  }

  int data;
};
#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);

	trans.set_response_status( tlm::TLM_OK_RESPONSE );

	if (mem[adr] == 0xFF000030)
	{
		d = false;
	}
	else
	{
		d = true;
	}

	//d = mem[adr];

	cout << " ptr = " << hex << ptr << " , mem[" << adr << "] = "  << mem[adr] << " , d = " << d << " , " << sc_time_stamp() << endl;
	
	}
};
Link to comment
Share on other sites

That's because c is connected to an sc_signal. An sc_signal only updates after the process suspends.

Probably the neatest solution is to use a variable in your do_and. I'd also move the wait() to the top of the process, otherwise the process will run at time 0 before a and have been assigned.

 

regards

Alan

void do_and()
{
     bool c_temp;
     while(true)
     {
        wait();
        c_temp = a.read()&b.read());
        c.write(c_temp);
        data = 0xFF000000 | (c_temp | 0x00000030);

        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*>(&data) );
        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");
        
        cout << " a = " << hex << a << " , b = " << hex << b << " , c = " << hex << c_temp << " , data = " << hex << data << " , " << sc_time_stamp() << endl;

//        wait();
     }
}

By the way, the code you've written is a very strange mixture of TLM and RTL style code :-)

Link to comment
Share on other sites

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...