Beispiel #1
0
    void thread_process() {
        // TLM-2 generic payload transaction
        tlm::tlm_generic_payload* trans = new tlm::tlm_generic_payload;
        sc_time delay = sc_time(10, SC_NS);

        // Generate a random sequence of reads and writes
        for (int i = 0; i < 128; i += 4) {
            int data;
            tlm::tlm_command cmd = static_cast<tlm::tlm_command> (rand() % 2);
            if (cmd == tlm::TLM_WRITE_COMMAND) data = 0xFF000000 | i;

            trans->set_command(cmd);
            //address is set randomly within the address range
            trans->set_address(rand() % N_INIT);
            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

            // Blocking transport call
            socket->b_transport(*trans, delay);

            // Initiator obliged to check response status
            if (trans->is_response_error()) {
                // *********************
                // Print response string
                // *********************
                char txt[100];
                sprintf(txt, "Error from b_transport, response status = %s",
                        trans->get_response_string().c_str());
                SC_REPORT_ERROR("TLM-2", txt);

            }
            cout << sc_time_stamp() << " @ " << " trans = { " << (cmd ? 'W' : 'R') << ", " << hex << i
                    << " } , data = " << hex << data << " at time " << sc_time_stamp()
                    << " delay = " << delay << endl;
        }

        // ********************************************************
        // Use debug transaction interface to dump memory contents,
        // reusing same transaction object
        // ********************************************************
        trans->set_command(tlm::TLM_READ_COMMAND);
        trans->set_address(0);
        trans->set_read();
        trans->set_data_length(128);

        unsigned char* data = new unsigned char[128];
        trans->set_data_ptr(data);

        unsigned int n_bytes = socket->transport_dbg(*trans);

        for (unsigned int i = 0; i < n_bytes; i += 4) {
            cout << "mem[" << i << "] = "
                    << *(reinterpret_cast<unsigned int*> (&data[i])) << endl;
        }
    }
  void peq_cb(tlm::tlm_generic_payload& trans, const tlm::tlm_phase& phase)
  {
    #ifdef DEBUG
      if (phase == tlm::END_REQ)
        fout << hex << trans.get_address() << " " << name() << " END_REQ at " << sc_time_stamp() << endl;
      else if (phase == tlm::BEGIN_RESP)
        fout << hex << trans.get_address() << " " << name() << " BEGIN_RESP at " << sc_time_stamp() << endl;
    #endif

    if (phase == tlm::END_REQ || (&trans == request_in_progress && phase == tlm::BEGIN_RESP))
    {
      // The end of the BEGIN_REQ phase
      request_in_progress = 0;
      end_request_event.notify();
    }
    else if (phase == tlm::BEGIN_REQ || phase == tlm::END_RESP)
      SC_REPORT_FATAL("TLM-2", "Illegal transaction phase received by initiator");

    if (phase == tlm::BEGIN_RESP)
    {
      check_transaction( trans );

      // Send final phase transition to target
      tlm::tlm_phase fw_phase = tlm::END_RESP;
      sc_time delay = sc_time(rand_ps(), SC_PS);
      socket->nb_transport_fw( trans, fw_phase, delay );
      // Ignore return value
    }
  }
Beispiel #3
0
    void dump()
    {
        unsigned char buffer[64];
        // Use debug transaction interface to dump memory contents

        cout << "\nDump memories at time " << sc_time_stamp() << "\n";

        for (unsigned int k = 0; k < 4; k++)
        {
            tlm::tlm_generic_payload dbg;
            sc_dt::uint64 A = 64 * k;
            dbg.set_address(A);
            dbg.set_read();
            dbg.set_data_length(64);
            dbg.set_data_ptr(buffer);

            unsigned int n_bytes = socket->transport_dbg( dbg );

            for (unsigned int i = 0; i < n_bytes; i += 4)
            {
                cout << "mem[" << hex << (A + i) << "] = "
                     << *(reinterpret_cast<unsigned int*>( &buffer[i] )) << endl;
            }
        }
        cout << "\n";
    }
Beispiel #4
0
  virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay )
  {
    unsigned int     bel = trans.get_byte_enable_length();

    trans2.set_data_ptr( data );
    if (bel)
      trans2.set_byte_enable_ptr( byte_enable );
    trans2.deep_copy_from(trans);

    init_socket->b_transport( trans2, delay );

    trans.update_original_from( trans2 );
  }
Beispiel #5
0
    void thread_process()
    {
        tlm::tlm_generic_payload* trans;
        sc_time delay;

        // Reset the local quantum keeper
        m_qk.reset();
        wait(1, SC_US);

        for (int i = 0; i < RUN_LENGTH; i += 4)
        {
            // Grab a new transaction from the memory manager
            trans = m_mm.allocate();
            trans->acquire();

            data = i;

            trans->set_command( tlm::TLM_READ_COMMAND );
            trans->set_address( i );
            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

            delay = m_qk.get_local_time();

            socket->b_transport( *trans, delay );

            // Initiator obliged to check response status
            if (trans->is_response_error())
                SC_REPORT_ERROR("TLM-2", trans->get_response_string().c_str());
            if (data != i)
                SC_REPORT_ERROR("TLM-2", "Mismatch in initiator when reading back data");

            cout << "READ     addr = " << hex << i << ", data = " << data
                 << " at " << sc_time_stamp() << " delay = " << delay << "\n";
            trans->release();

            // Accumulate local time and synchronize when quantum is reached
            m_qk.set( delay );
            m_qk.inc( sc_time(100, SC_NS) );// Model time used for additional processing
            if (m_qk.need_sync()) m_qk.sync();
        }
    }
Beispiel #6
0
  void thread_process()
  {
    // TLM-2 generic payload transaction, reused across calls to b_transport
    tlm::tlm_generic_payload* trans = new tlm::tlm_generic_payload;
    sc_time delay = sc_time(10, SC_NS);

    // Generate a random sequence of reads and writes
    for (int i = 32; i < 96; i += 4)
    {

      tlm::tlm_command cmd = static_cast<tlm::tlm_command>(rand() % 2);
      if (cmd == tlm::TLM_WRITE_COMMAND) data = 0xFF000000 | i;

      // Initialize 8 out of the 10 attributes, byte_enable_length and extensions being unused
      trans->set_command( cmd );
      trans->set_address( i );
      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 << "trans = { " << (cmd ? 'W' : 'R') << ", " << hex << i
           << " } , data = " << hex << data << " at time " << sc_time_stamp()
           << " delay = " << delay << endl;

      // Realize the delay annotated onto the transport call
      wait(delay);
    }
  }
  void thread_process()
  {
    tlm::tlm_generic_payload* trans;
    tlm::tlm_phase phase;
    sc_time delay;

    // Generate a sequence of random transactions
    for (int i = 0; i < 1000; i++)
    {
      int adr = rand();
      tlm::tlm_command cmd = static_cast<tlm::tlm_command>(rand() % 2);
      if (cmd == tlm::TLM_WRITE_COMMAND) data[i % 16] = rand();

      // Grab a new transaction from the memory manager
      trans = m_mm.allocate();
      trans->acquire();

      // Set all attributes except byte_enable_length and extensions (unused)
      trans->set_command( cmd );
      trans->set_address( adr );
      trans->set_data_ptr( reinterpret_cast<unsigned char*>(&data[i % 16]) );
      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

      // Initiator must honor BEGIN_REQ/END_REQ exclusion rule
      if (request_in_progress)
        wait(end_request_event);
      request_in_progress = trans;
      phase = tlm::BEGIN_REQ;

      // Timing annotation models processing time of initiator prior to call
      delay = sc_time(rand_ps(), SC_PS);

      fout << hex << adr << " " << name() << " new, cmd=" << (cmd ? 'W' : 'R')
           << ", data=" << hex << data[i % 16] << " at time " << sc_time_stamp() << endl;

      // Non-blocking transport call on the forward path
      tlm::tlm_sync_enum status;
      status = socket->nb_transport_fw( *trans, phase, delay );

      // Check value returned from nb_transport_fw
      if (status == tlm::TLM_UPDATED)
      {
        // The timing annotation must be honored
        m_peq.notify( *trans, phase, delay );
      }
      else if (status == tlm::TLM_COMPLETED)
      {
        // The completion of the transaction necessarily ends the BEGIN_REQ phase
        request_in_progress = 0;

        // The target has terminated the transaction
        check_transaction( *trans );
      }
      wait( sc_time(rand_ps(), SC_PS) );
    }

    wait(100, SC_NS);

    // Allocate a transaction for one final, nominal call to b_transport
    trans = m_mm.allocate();
    trans->acquire();
    trans->set_command( tlm::TLM_WRITE_COMMAND );
    trans->set_address( 0 );
    trans->set_data_ptr( reinterpret_cast<unsigned char*>(&data[0]) );
    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

    delay = sc_time(rand_ps(), SC_PS);

    fout << "Calling b_transport at " << sc_time_stamp() << " with delay = " << delay << endl;

    // Call b_transport to demonstrate the b/nb conversion by the simple_target_socket
    socket->b_transport( *trans, delay );
    check_transaction( *trans );
  }
  void thread_process()
  {
    // TLM-2 generic payload transaction, reused across calls to b_transport, DMI and debug
    tlm::tlm_generic_payload* trans = new tlm::tlm_generic_payload;
    sc_time delay = sc_time(10, SC_NS);

    // Generate a random sequence of reads and writes
    for (int i = 0; i < 128; i += 4)
    {
      int data;
      tlm::tlm_command cmd = static_cast<tlm::tlm_command>(rand() % 2);
      if (cmd == tlm::TLM_WRITE_COMMAND) data = 0xFF000000 | i;

      // *********************************************
      // Use DMI if it is available, reusing same transaction object
      // *********************************************

      if (dmi_ptr_valid)
      {
        // Bypass transport interface and use direct memory interface
        // Implement target latency
        if ( cmd == tlm::TLM_READ_COMMAND )
        {
          assert( dmi_data.is_read_allowed() );
          memcpy(&data, dmi_data.get_dmi_ptr() + i, 4);
          wait( dmi_data.get_read_latency() );
        }
        else if ( cmd == tlm::TLM_WRITE_COMMAND )
        {
          assert( dmi_data.is_write_allowed() );
          memcpy(dmi_data.get_dmi_ptr() + i, &data, 4);
          wait( dmi_data.get_write_latency() );
        }

        cout << "DMI   = { " << (cmd ? 'W' : 'R') << ", " << hex << i
             << " } , data = " << hex << data << " at time " << sc_time_stamp() << endl;
      }
      else
      {
        trans->set_command( cmd );
        trans->set_address( i );
        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

#ifdef INJECT_ERROR
        if (i > 90) trans->set_streaming_width(2);
#endif

        // Other fields default: byte enable = 0, streaming width = 0, DMI_hint = false, no extensions

        socket->b_transport( *trans, delay  );  // Blocking transport call

        // Initiator obliged to check response status
        if ( trans->is_response_error() )
        {
          // *********************************************
          // Print response string
          // *********************************************

          char txt[100];
          sprintf(txt, "Error from b_transport, response status = %s",
                       trans->get_response_string().c_str());
          SC_REPORT_ERROR("TLM-2", txt);

        }

        // *********************************************
        // Check DMI hint
        // *********************************************

        if ( trans->is_dmi_allowed() )
        {
          // Re-user transaction object for DMI
          dmi_data.init();
          dmi_ptr_valid = socket->get_direct_mem_ptr( *trans, dmi_data );
        }

        cout << "trans = { " << (cmd ? 'W' : 'R') << ", " << hex << i
             << " } , data = " << hex << data << " at time " << sc_time_stamp()
             << " delay = " << delay << endl;
      }
    }

    // *********************************************
    // Use debug transaction interface to dump memory contents, reusing same transaction object
    // *********************************************

    trans->set_address(0);
    trans->set_read();
    trans->set_data_length(128);

    unsigned char* data = new unsigned char[128];
    trans->set_data_ptr(data);

    unsigned int n_bytes = socket->transport_dbg( *trans );

    for (unsigned int i = 0; i < n_bytes; i += 4)
    {
      cout << "mem[" << i << "] = "
           << *(reinterpret_cast<unsigned int*>( &data[i] )) << endl;
    }
  }
Beispiel #9
0
    void thread_process() {
        // Use debug transaction interface to dump entire memory contents
        dump();

        tlm::tlm_generic_payload* trans = new tlm::tlm_generic_payload;
        sc_time delay;

        for (int i = 0; i < RUN_LENGTH; i += 4)
        {
            data = i;
            delay = m_qk.get_local_time();

            if (dmi_ptr_valid && sc_dt::uint64(i) >= dmi_data.get_start_address()
                    && sc_dt::uint64(i) <= dmi_data.get_end_address())
            {
                // Bypass transport interface and use direct memory interface
                assert( dmi_data.is_write_allowed() );
                memcpy(dmi_data.get_dmi_ptr() + i - dmi_data.get_start_address(), &data, 4);

                // Accumulate memory latency into local time
                delay += dmi_data.get_write_latency();

                cout << "WRITE/DMI addr = " << hex << i << ", data = " << data
                     << " at " << sc_time_stamp() << " delay = " << delay << "\n";
            }
            else
            {
                // No DMI, so use blocking transport interface
                trans->set_command( tlm::TLM_WRITE_COMMAND );
                trans->set_address( i );
                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 );

                cout << "WRITE     addr = " << hex << i << ", data = " << data
                     << " at " << sc_time_stamp() << " delay = " << delay << "\n";

                // Initiator obliged to check response status
                if (trans->is_response_error())
                    SC_REPORT_ERROR("TLM-2", trans->get_response_string().c_str());

                if ( trans->is_dmi_allowed() )
                {
                    dmi_data.init();
                    dmi_ptr_valid = socket->get_direct_mem_ptr( *trans, dmi_data );
                }
            }

            // Accumulate local time and synchronize when quantum is reached
            m_qk.set( delay );
            m_qk.inc( sc_time(100, SC_NS) ); // Model time used for additional processing
            if (m_qk.need_sync()) m_qk.sync();
        }

        // Use debug transaction interface to dump entire memory contents
        dump();
    }
Beispiel #10
0
  void thread_process()
  {
    tlm::tlm_generic_payload* trans;
    sc_time delay = SC_ZERO_TIME;

    for (int i = 0; i < 1000000; i++)
    {
      int addr = 0;
      tlm::tlm_command cmd = static_cast<tlm::tlm_command>(rand() % 2);

      unsigned int len = rand() % 33;
      unsigned int bel = rand() % (len + 1);

      // Fix sizes when performing a speed test
      //cmd = tlm::TLM_READ_COMMAND;
      //len = 32;
      //bel = 8;


      for (unsigned int i = 0; i < len; i++)
        if (cmd == tlm::TLM_WRITE_COMMAND)
        {
          data[i] = rand() % 256;
        }
        else
          data[i] = 0x99;

      trans = m_mm.allocate();
      trans->acquire();

      trans->set_command( cmd );
      trans->set_address( addr );
      trans->set_data_ptr( data );
      trans->set_data_length( len );
      trans->set_streaming_width( len );

      trans->set_byte_enable_length( bel );

      for (unsigned int i = 0; i < bel; i++)
      {
        byte_enable[i] = (rand() % 2) ? 0xff : 0;
      }

      if (bel)
        trans->set_byte_enable_ptr( byte_enable );
      else
        trans->set_byte_enable_ptr( 0 );

      trans->set_dmi_allowed( false );
      trans->set_response_status( tlm::TLM_INCOMPLETE_RESPONSE );

      // Add sticky extension diagnostics
      my_extension* ext;
      trans->get_extension(ext);
      if (!ext)
      {
        ext = new my_extension;
        trans->set_extension(ext);
      }

      ext->len = len;
      ext->bel = bel;
      ext->ptr = data;
      ext->byt = byte_enable;

      socket->b_transport( *trans, delay );  // Blocking transport call

      if ( trans->is_response_error() )
        SC_REPORT_ERROR("TLM-2", "Response error from b_transport");

      //cout << "cmd = " << cmd << ", len = " << len << ", bel = " << bel << endl;
      //cout << hex << setw(2) << setfill('0') << (unsigned int)data[i];

      if (cmd == tlm::TLM_READ_COMMAND)
      {
        for (unsigned int i = 0; i < len; i++)
          if (bel)
            if (byte_enable[i % bel])
              assert( data[i] == ext->ptr[i] );
            else
              assert( data[i] == 0x99 );
          else
            assert( data[i] == ext->ptr[i] );

      }
      trans->release();
    }
  }