Example of a simple initiator

This commit is contained in:
Éder F. Zulian
2016-06-27 13:40:35 +02:00
parent dab375b0cc
commit d60c28209a
6 changed files with 215 additions and 13 deletions

View File

@@ -1,9 +1,9 @@
<simulation>
<!-- General Simulator Configuration (used for all simulation setups) -->
<simconfig>
<Debug value="0" />
<DatabaseRecording value="1" />
<PowerAnalysis value="1" />
<Debug value="1" />
<DatabaseRecording value="0" />
<PowerAnalysis value="0" />
<NumberOfTimeWindows value="1000" />
<NumberOfTracePlayers value="1"/>
<NumberOfMemChannels value="4"/>

View File

@@ -165,7 +165,8 @@ HEADERS += \
src/controller/scheduler/FifoStrict.h \
src/controller/IController.h \
src/controller/core/configuration/ConfigurationLoader.h \
src/error/errormodel.h
src/error/errormodel.h \
src/simulation/exampleinitiator.h
thermalsim = $$(THERMALSIM)
isEmpty(thermalsim) {

View File

@@ -75,8 +75,8 @@ gp* MemoryManager::allocate()
void MemoryManager::free(gp* payload)
{
unsigned char *dptr = payload->get_data_ptr();
delete[] dptr;
//unsigned char *dptr = payload->get_data_ptr();
//delete[] dptr;
payload->reset(); //clears all extensions
freePayloads.push_back(payload);
}

View File

@@ -114,6 +114,7 @@ void Simulation::instantiateModules(const string &traceName, const string &pathT
// The same instance will be accessed by all other modules.
TemperatureController::getInstance();
#if 0
for (size_t i = 0; i < Configuration::getInstance().NumberOfTracePlayers; i++) {
std::string playerStr = "tracePlayer" + std::to_string(i);
TracePlayer<> *player;
@@ -138,7 +139,8 @@ void Simulation::instantiateModules(const string &traceName, const string &pathT
}
remainingTransactions = totalTransactions;
//player->remainingTransactions = player->totalTransactions;
player->remainingTransactions = player->totalTransactions;
#endif
// Create and properly initialize TLM recorders. They need to be ready before creating some modules.
setupTlmRecorders(traceName, pathToResources, devices);
@@ -146,6 +148,8 @@ void Simulation::instantiateModules(const string &traceName, const string &pathT
arbiter = new Arbiter<128>("arbiter");
arbiter->setTlmRecorders(tlmRecorders);
init = new ExampleInitiator<128>("init", this);
for (size_t i = 0; i < Configuration::getInstance().NumberOfMemChannels; i++) {
std::string str = "controller" + std::to_string(i);
Controller<> *controller = new Controller<>(str.c_str(), tlmRecorders[i]);
@@ -161,9 +165,11 @@ void Simulation::instantiateModules(const string &traceName, const string &pathT
void Simulation::bindSockets()
{
for (auto player : players) {
player->iSocket.bind(arbiter->tSocket);
}
//for (auto player : players) {
// player->iSocket.bind(arbiter->tSocket);
//}
init->socket.bind(arbiter->tSocket);
for (size_t i = 0; i < Configuration::getInstance().NumberOfMemChannels; i++) {
arbiter->iSocket.bind(controllers[i]->tSocket);
@@ -173,9 +179,9 @@ void Simulation::bindSockets()
Simulation::~Simulation()
{
for (auto player : players) {
delete player;
}
//for (auto player : players) {
// delete player;
//}
delete arbiter;

View File

@@ -50,6 +50,7 @@
#include "StlPlayer.h"
#include "../controller/Controller.h"
#include "../common/third_party/tinyxml2/tinyxml2.h"
#include "exampleinitiator.h"
struct DramSetup
{
@@ -98,6 +99,7 @@ private:
// and initiate transactions targeting the memory)
std::vector<TracePlayer<>*> players;
// All transactions pass through the same arbiter
ExampleInitiator<> *init;
Arbiter<> *arbiter;
// Each DRAM unit has a controller
std::vector<Controller<>*> controllers;

View File

@@ -0,0 +1,193 @@
#ifndef EXAMPLEINITIATOR
#define EXAMPLEINITIATOR
#include <stdlib.h>
#include <iostream>
#include "MemoryManager.h"
#include "../common/dramExtension.h"
#include "TracePlayer.h"
using namespace std;
template<unsigned int BUSWIDTH = 128>
struct ExampleInitiator: sc_module
{
// TLM-2 socket, defaults to 32-bits wide, base protocol
tlm_utils::simple_initiator_socket<ExampleInitiator, BUSWIDTH> socket;
SC_CTOR(ExampleInitiator)
: socket("socket") // Construct and name socket
, request_in_progress(0)
, m_peq(this, &ExampleInitiator::peq_cb)
{
socket.register_nb_transport_bw(this, &ExampleInitiator::nb_transport_bw);
SC_THREAD(thread_process);
}
void thread_process()
{
tlm::tlm_generic_payload* trans;
tlm::tlm_phase phase;
sc_time delay;
#if 0
// Make a call to b_transport
trans = m_mm.allocate();
trans->acquire();
int adr = 0;
data[0] = adr;
trans->set_command( tlm::TLM_WRITE_COMMAND );
trans->set_address( adr );
trans->set_data_ptr( reinterpret_cast<unsigned char*>(&data[0]) );
trans->set_data_length( 4 );
trans->set_streaming_width( 4 );
trans->set_byte_enable_ptr( 0 );
trans->set_dmi_allowed( false );
trans->set_response_status( tlm::TLM_INCOMPLETE_RESPONSE );
socket->b_transport( *trans, delay );
trans->release();
#endif
// Generate a sequence of random transactions
for (int i = 0; i < 1000; i++)
{
//int adr = rand();
int adr = 0;
//tlm::tlm_command cmd = static_cast<tlm::tlm_command>(rand() % 2);
tlm::tlm_command cmd = tlm::TLM_READ_COMMAND;
if (cmd == tlm::TLM_WRITE_COMMAND) data[i % 16] = adr;
// Grab a new transaction from the memory manager
trans = m_mm.allocate();
trans->acquire();
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 );
trans->set_byte_enable_ptr( 0 );
trans->set_dmi_allowed( false );
trans->set_response_status( tlm::TLM_INCOMPLETE_RESPONSE );
// ExampleInitiator 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);
delay = sc_time(100000, SC_PS);
cout << hex << adr << " new, cmd=" << (cmd ? "write" : "read")
<< ", data=" << hex << data[i % 16] << " at time " << sc_time_stamp()
<< " in " << name() << endl;
GenerationExtension* genExtension = new GenerationExtension(sc_time_stamp());
trans->set_auto_extension(genExtension);
// 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 );
// Allow the memory manager to free the transaction object
trans->release();
}
//wait( sc_time(rand_ps(), SC_PS) );
wait( sc_time(50000, SC_PS) );
}
}
// TLM-2 backward non-blocking transport method
virtual tlm::tlm_sync_enum nb_transport_bw( tlm::tlm_generic_payload& trans,
tlm::tlm_phase& phase, sc_time& delay )
{
m_peq.notify( trans, phase, delay );
return tlm::TLM_ACCEPTED;
}
// Payload event queue callback to handle transactions from target
// Transaction could have arrived through return path or backward path
void peq_cb(tlm::tlm_generic_payload& trans, const tlm::tlm_phase& phase)
{
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);
sc_time delay = sc_time(60000, SC_PS);
socket->nb_transport_fw( trans, fw_phase, delay );
// Ignore return value
// Allow the memory manager to free the transaction object
trans.release();
}
}
// Called on receiving BEGIN_RESP or TLM_COMPLETED
void check_transaction(tlm::tlm_generic_payload& trans)
{
if ( trans.is_response_error() )
{
char txt[100];
sprintf(txt, "Transaction returned with error, response status = %s",
trans.get_response_string().c_str());
SC_REPORT_ERROR("TLM-2", txt);
}
tlm::tlm_command cmd = trans.get_command();
sc_dt::uint64 adr = trans.get_address();
int* ptr = reinterpret_cast<int*>( trans.get_data_ptr() );
cout << hex << adr << " check, cmd=" << (cmd ? "write" : "read")
<< ", data=" << hex << *ptr << " at time " << sc_time_stamp()
<< " in " << name() << endl;
if (cmd == tlm::TLM_READ_COMMAND)
assert( *ptr == -int(adr) );
}
MemoryManager m_mm;
int data[16];
tlm::tlm_generic_payload* request_in_progress;
sc_event end_request_event;
tlm_utils::peq_with_cb_and_phase<ExampleInitiator> m_peq;
};
#endif // EXAMPLEINITIATOR