Example of a simple initiator
This commit is contained in:
@@ -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"/>
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
193
DRAMSys/simulator/src/simulation/exampleinitiator.h
Normal file
193
DRAMSys/simulator/src/simulation/exampleinitiator.h
Normal 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
|
||||
Reference in New Issue
Block a user