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 post
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 post
Share on other sites

Archived

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

×
×
  • Create New...