112855Sgabeblack@google.com
212855Sgabeblack@google.com// Unit test for tlm_generic_payload update_original_from() method
312855Sgabeblack@google.com
412855Sgabeblack@google.com#include <iomanip>
512855Sgabeblack@google.com
612855Sgabeblack@google.com#define SC_INCLUDE_DYNAMIC_PROCESSES
712855Sgabeblack@google.com
812855Sgabeblack@google.com#include "systemc"
912855Sgabeblack@google.comusing namespace sc_core;
1012855Sgabeblack@google.comusing namespace sc_dt;
1112855Sgabeblack@google.comusing namespace std;
1212855Sgabeblack@google.com
1312855Sgabeblack@google.com#include "tlm.h"
1412855Sgabeblack@google.com#include "tlm_utils/simple_initiator_socket.h"
1512855Sgabeblack@google.com#include "tlm_utils/simple_target_socket.h"
1612855Sgabeblack@google.com
1712855Sgabeblack@google.com#include "mm.h"
1812855Sgabeblack@google.com
1912855Sgabeblack@google.comstruct my_extension: tlm::tlm_extension<my_extension>
2012855Sgabeblack@google.com{
2112855Sgabeblack@google.com  my_extension() {}
2212855Sgabeblack@google.com
2312855Sgabeblack@google.com  virtual tlm_extension_base* clone() const
2412855Sgabeblack@google.com  {
2512855Sgabeblack@google.com    my_extension* ext = new my_extension;
2612855Sgabeblack@google.com    ext->len = len;
2712855Sgabeblack@google.com    ext->bel = bel;
2812855Sgabeblack@google.com    ext->ptr = ptr;
2912855Sgabeblack@google.com    ext->byt = byt;
3012855Sgabeblack@google.com    return ext;
3112855Sgabeblack@google.com  }
3212855Sgabeblack@google.com
3312855Sgabeblack@google.com  virtual void copy_from(tlm_extension_base const &ext)
3412855Sgabeblack@google.com  {
3512855Sgabeblack@google.com    len = static_cast<my_extension const &>(ext).len;
3612855Sgabeblack@google.com    bel = static_cast<my_extension const &>(ext).bel;
3712855Sgabeblack@google.com    ptr = static_cast<my_extension const &>(ext).ptr;
3812855Sgabeblack@google.com    byt = static_cast<my_extension const &>(ext).byt;
3912855Sgabeblack@google.com  }
4012855Sgabeblack@google.com
4112855Sgabeblack@google.com  unsigned int len;
4212855Sgabeblack@google.com  unsigned int bel;
4312855Sgabeblack@google.com  unsigned char* ptr;
4412855Sgabeblack@google.com  unsigned char* byt;
4512855Sgabeblack@google.com};
4612855Sgabeblack@google.com
4712855Sgabeblack@google.com
4812855Sgabeblack@google.comstruct Initiator: sc_module
4912855Sgabeblack@google.com{
5012855Sgabeblack@google.com  tlm_utils::simple_initiator_socket<Initiator> socket;
5112855Sgabeblack@google.com
5212855Sgabeblack@google.com  typedef unsigned char uchar;
5312855Sgabeblack@google.com
5412855Sgabeblack@google.com  SC_CTOR(Initiator)
5512855Sgabeblack@google.com  : socket("socket")
5612855Sgabeblack@google.com  {
5712855Sgabeblack@google.com    SC_THREAD(thread_process);
5812855Sgabeblack@google.com    data = new uchar[32];
5912855Sgabeblack@google.com    byte_enable = new uchar[32];
6012855Sgabeblack@google.com  }
6112855Sgabeblack@google.com
6212855Sgabeblack@google.com  void thread_process()
6312855Sgabeblack@google.com  {
6412855Sgabeblack@google.com    tlm::tlm_generic_payload* trans;
6512855Sgabeblack@google.com    sc_time delay = SC_ZERO_TIME;
6612855Sgabeblack@google.com
6712855Sgabeblack@google.com    for (int i = 0; i < 1000000; i++)
6812855Sgabeblack@google.com    {
6912855Sgabeblack@google.com      int addr = 0;
7012855Sgabeblack@google.com      tlm::tlm_command cmd = static_cast<tlm::tlm_command>(rand() % 2);
7112855Sgabeblack@google.com
7212855Sgabeblack@google.com      unsigned int len = rand() % 33;
7312855Sgabeblack@google.com      unsigned int bel = rand() % (len + 1);
7412855Sgabeblack@google.com
7512855Sgabeblack@google.com      // Fix sizes when performing a speed test
7612855Sgabeblack@google.com      //cmd = tlm::TLM_READ_COMMAND;
7712855Sgabeblack@google.com      //len = 32;
7812855Sgabeblack@google.com      //bel = 8;
7912855Sgabeblack@google.com
8012855Sgabeblack@google.com
8112855Sgabeblack@google.com      for (unsigned int i = 0; i < len; i++)
8212855Sgabeblack@google.com        if (cmd == tlm::TLM_WRITE_COMMAND)
8312855Sgabeblack@google.com        {
8412855Sgabeblack@google.com          data[i] = rand() % 256;
8512855Sgabeblack@google.com        }
8612855Sgabeblack@google.com        else
8712855Sgabeblack@google.com          data[i] = 0x99;
8812855Sgabeblack@google.com
8912855Sgabeblack@google.com      trans = m_mm.allocate();
9012855Sgabeblack@google.com      trans->acquire();
9112855Sgabeblack@google.com
9212855Sgabeblack@google.com      trans->set_command( cmd );
9312855Sgabeblack@google.com      trans->set_address( addr );
9412855Sgabeblack@google.com      trans->set_data_ptr( data );
9512855Sgabeblack@google.com      trans->set_data_length( len );
9612855Sgabeblack@google.com      trans->set_streaming_width( len );
9712855Sgabeblack@google.com
9812855Sgabeblack@google.com      trans->set_byte_enable_length( bel );
9912855Sgabeblack@google.com
10012855Sgabeblack@google.com      for (unsigned int i = 0; i < bel; i++)
10112855Sgabeblack@google.com      {
10212855Sgabeblack@google.com        byte_enable[i] = (rand() % 2) ? 0xff : 0;
10312855Sgabeblack@google.com      }
10412855Sgabeblack@google.com
10512855Sgabeblack@google.com      if (bel)
10612855Sgabeblack@google.com        trans->set_byte_enable_ptr( byte_enable );
10712855Sgabeblack@google.com      else
10812855Sgabeblack@google.com        trans->set_byte_enable_ptr( 0 );
10912855Sgabeblack@google.com
11012855Sgabeblack@google.com      trans->set_dmi_allowed( false );
11112855Sgabeblack@google.com      trans->set_response_status( tlm::TLM_INCOMPLETE_RESPONSE );
11212855Sgabeblack@google.com
11312855Sgabeblack@google.com      // Add sticky extension diagnostics
11412855Sgabeblack@google.com      my_extension* ext;
11512855Sgabeblack@google.com      trans->get_extension(ext);
11612855Sgabeblack@google.com      if (!ext)
11712855Sgabeblack@google.com      {
11812855Sgabeblack@google.com        ext = new my_extension;
11912855Sgabeblack@google.com        trans->set_extension(ext);
12012855Sgabeblack@google.com      }
12112855Sgabeblack@google.com
12212855Sgabeblack@google.com      ext->len = len;
12312855Sgabeblack@google.com      ext->bel = bel;
12412855Sgabeblack@google.com      ext->ptr = data;
12512855Sgabeblack@google.com      ext->byt = byte_enable;
12612855Sgabeblack@google.com
12712855Sgabeblack@google.com      socket->b_transport( *trans, delay );  // Blocking transport call
12812855Sgabeblack@google.com
12912855Sgabeblack@google.com      if ( trans->is_response_error() )
13012855Sgabeblack@google.com        SC_REPORT_ERROR("TLM-2", "Response error from b_transport");
13112855Sgabeblack@google.com
13212855Sgabeblack@google.com      //cout << "cmd = " << cmd << ", len = " << len << ", bel = " << bel << endl;
13312855Sgabeblack@google.com      //cout << hex << setw(2) << setfill('0') << (unsigned int)data[i];
13412855Sgabeblack@google.com
13512855Sgabeblack@google.com      if (cmd == tlm::TLM_READ_COMMAND)
13612855Sgabeblack@google.com      {
13712855Sgabeblack@google.com        for (unsigned int i = 0; i < len; i++)
13812855Sgabeblack@google.com          if (bel)
13912855Sgabeblack@google.com            if (byte_enable[i % bel])
14012855Sgabeblack@google.com              sc_assert( data[i] == ext->ptr[i] );
14112855Sgabeblack@google.com            else
14212855Sgabeblack@google.com              sc_assert( data[i] == 0x99 );
14312855Sgabeblack@google.com          else
14412855Sgabeblack@google.com            sc_assert( data[i] == ext->ptr[i] );
14512855Sgabeblack@google.com
14612855Sgabeblack@google.com      }
14712855Sgabeblack@google.com      trans->release();
14812855Sgabeblack@google.com    }
14912855Sgabeblack@google.com  }
15012855Sgabeblack@google.com
15112855Sgabeblack@google.com  mm  m_mm;  // Memory manager
15212855Sgabeblack@google.com  unsigned char* data; // 32 bytes
15312855Sgabeblack@google.com  unsigned char* byte_enable;
15412855Sgabeblack@google.com};
15512855Sgabeblack@google.com
15612855Sgabeblack@google.com
15712855Sgabeblack@google.comstruct Interconnect: sc_module
15812855Sgabeblack@google.com{
15912855Sgabeblack@google.com  tlm_utils::simple_target_socket   <Interconnect> targ_socket;
16012855Sgabeblack@google.com  tlm_utils::simple_initiator_socket<Interconnect> init_socket;
16112855Sgabeblack@google.com
16212855Sgabeblack@google.com  SC_CTOR(Interconnect)
16312855Sgabeblack@google.com  : targ_socket("targ_socket")
16412855Sgabeblack@google.com  , init_socket("init_socket")
16512855Sgabeblack@google.com  {
16612855Sgabeblack@google.com    targ_socket.register_b_transport(this, &Interconnect::b_transport);
16712855Sgabeblack@google.com  }
16812855Sgabeblack@google.com
16912855Sgabeblack@google.com  virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay )
17012855Sgabeblack@google.com  {
17112855Sgabeblack@google.com    unsigned int     bel = trans.get_byte_enable_length();
17212855Sgabeblack@google.com
17312855Sgabeblack@google.com    trans2.set_data_ptr( data );
17412855Sgabeblack@google.com    if (bel)
17512855Sgabeblack@google.com      trans2.set_byte_enable_ptr( byte_enable );
17612855Sgabeblack@google.com    trans2.deep_copy_from(trans);
17712855Sgabeblack@google.com
17812855Sgabeblack@google.com    init_socket->b_transport( trans2, delay );
17912855Sgabeblack@google.com
18012855Sgabeblack@google.com    trans.update_original_from( trans2 );
18112855Sgabeblack@google.com  }
18212855Sgabeblack@google.com
18312855Sgabeblack@google.com  tlm::tlm_generic_payload trans2;
18412855Sgabeblack@google.com  unsigned char data[32];
18512855Sgabeblack@google.com  unsigned char byte_enable[32];
18612855Sgabeblack@google.com};
18712855Sgabeblack@google.com
18812855Sgabeblack@google.com
18912855Sgabeblack@google.comstruct Target: sc_module
19012855Sgabeblack@google.com{
19112855Sgabeblack@google.com  tlm_utils::simple_target_socket<Target> socket;
19212855Sgabeblack@google.com
19312855Sgabeblack@google.com  SC_CTOR(Target)
19412855Sgabeblack@google.com  : socket("socket")
19512855Sgabeblack@google.com  {
19612855Sgabeblack@google.com    socket.register_b_transport(this, &Target ::b_transport);
19712855Sgabeblack@google.com
19812855Sgabeblack@google.com    typedef unsigned char uchar;
19912855Sgabeblack@google.com    data = new uchar[32];
20012855Sgabeblack@google.com  }
20112855Sgabeblack@google.com
20212855Sgabeblack@google.com
20312855Sgabeblack@google.com  virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay )
20412855Sgabeblack@google.com  {
20512855Sgabeblack@google.com    tlm::tlm_command cmd = trans.get_command();
20612855Sgabeblack@google.com    unsigned char*   ptr = trans.get_data_ptr();
20712855Sgabeblack@google.com    unsigned int     len = trans.get_data_length();
20812855Sgabeblack@google.com    unsigned char*   byt = trans.get_byte_enable_ptr();
20912855Sgabeblack@google.com    unsigned int     bel = trans.get_byte_enable_length();
21012855Sgabeblack@google.com
21112855Sgabeblack@google.com    my_extension* ext;
21212855Sgabeblack@google.com    trans.get_extension(ext);
21312855Sgabeblack@google.com    sc_assert( ext );
21412855Sgabeblack@google.com
21512855Sgabeblack@google.com    sc_assert( len == ext->len );
21612855Sgabeblack@google.com    sc_assert( bel == ext->bel );
21712855Sgabeblack@google.com    for (unsigned int i = 0; i < bel; i++)
21812855Sgabeblack@google.com      sc_assert( byt[i] == ext->byt[i] );
21912855Sgabeblack@google.com    for (unsigned int i = 0; i < len; i++)
22012855Sgabeblack@google.com      sc_assert( ptr[i] == ext->ptr[i] );
22112855Sgabeblack@google.com
22212855Sgabeblack@google.com    if (cmd == tlm::TLM_READ_COMMAND)
22312855Sgabeblack@google.com    {
22412855Sgabeblack@google.com      for (unsigned int i = 0; i < len; i++)
22512855Sgabeblack@google.com      {
22612855Sgabeblack@google.com        data[i] = rand() % 256;
22712855Sgabeblack@google.com        ptr[i]  = data[i];
22812855Sgabeblack@google.com      }
22912855Sgabeblack@google.com      ext->ptr = data;
23012855Sgabeblack@google.com    }
23112855Sgabeblack@google.com
23212855Sgabeblack@google.com    trans.set_dmi_allowed( true );
23312855Sgabeblack@google.com    trans.set_response_status( tlm::TLM_OK_RESPONSE );
23412855Sgabeblack@google.com  }
23512855Sgabeblack@google.com
23612855Sgabeblack@google.com  unsigned char* data; // 32 bytes
23712855Sgabeblack@google.com};
23812855Sgabeblack@google.com
23912855Sgabeblack@google.com
24012855Sgabeblack@google.comSC_MODULE(Top)
24112855Sgabeblack@google.com{
24212855Sgabeblack@google.com  Initiator    *initiator;
24312855Sgabeblack@google.com  Interconnect *interconnect;
24412855Sgabeblack@google.com  Target       *target;
24512855Sgabeblack@google.com
24612855Sgabeblack@google.com  SC_CTOR(Top)
24712855Sgabeblack@google.com  {
24812855Sgabeblack@google.com    // Instantiate components
24912855Sgabeblack@google.com    initiator    = new Initiator   ("initiator");
25012855Sgabeblack@google.com    interconnect = new Interconnect("interconnect");
25112855Sgabeblack@google.com    target       = new Target      ("target");
25212855Sgabeblack@google.com
25312855Sgabeblack@google.com    // One initiator is bound directly to one target with no intervening bus
25412855Sgabeblack@google.com
25512855Sgabeblack@google.com    // Bind initiator socket to target socket
25612855Sgabeblack@google.com    initiator    ->socket     .bind( interconnect->targ_socket );
25712855Sgabeblack@google.com    interconnect ->init_socket.bind( target      ->socket );
25812855Sgabeblack@google.com  }
25912855Sgabeblack@google.com};
26012855Sgabeblack@google.com
26112855Sgabeblack@google.com
26212855Sgabeblack@google.comint sc_main(int argc, char* argv[])
26312855Sgabeblack@google.com{
26412855Sgabeblack@google.com  cout << "Unit test for update_original_from(). Should remain silent\n";
26512855Sgabeblack@google.com
26612855Sgabeblack@google.com  Top top("top");
26712855Sgabeblack@google.com  sc_start();
26812855Sgabeblack@google.com  return 0;
26912855Sgabeblack@google.com}
27012855Sgabeblack@google.com
271