using namespace std;
-RubySystem* g_system_ptr = 0;
vector<map<uint32_t, AbstractController *> > g_abs_controls;
#include "base/str.hh"
#include "base/types.hh"
-class RubySystem;
-extern RubySystem* g_system_ptr;
-
class AbstractController;
extern std::vector<std::map<uint32_t, AbstractController *> > g_abs_controls;
MessageBuffer::MessageBuffer(const string &name)
: m_time_last_time_size_checked(0), m_time_last_time_enqueue(0),
- m_time_last_time_pop(0), m_last_arrival_time(0)
+ m_time_last_time_pop(0), m_last_arrival_time(0)
{
m_msg_counter = 0;
m_consumer = NULL;
DPRINTF(RubyNetwork, "throttle: %d my bw %d bw spent "
"enqueueing net msg %d time: %lld.\n",
m_node, getLinkBandwidth(), m_units_remaining[vnet],
- g_system_ptr->curCycle());
+ m_ruby_system->curCycle());
// Move the message
in->dequeue();
#include "mem/protocol/RubyRequest.hh"
#include "mem/ruby/profiler/AddressProfiler.hh"
#include "mem/ruby/profiler/Profiler.hh"
-#include "mem/ruby/system/System.hh"
using namespace std;
typedef AddressProfiler::AddressMap AddressMap;
void
printSorted(ostream& out, int num_of_sequencers, const AddressMap &record_map,
- string description)
+ string description, Profiler *profiler)
{
const int records_printed = 100;
out << "Total_entries_" << description << ": " << record_map.size()
<< endl;
- if (g_system_ptr->getProfiler()->getAllInstructions())
+ if (profiler->getAllInstructions())
out << "Total_Instructions_" << description << ": " << misses << endl;
else
out << "Total_data_misses_" << description << ": " << misses << endl;
<< endl;
}
-AddressProfiler::AddressProfiler(int num_of_sequencers)
+AddressProfiler::AddressProfiler(int num_of_sequencers, Profiler *profiler)
+ : m_profiler(profiler)
{
m_num_of_sequencers = num_of_sequencers;
clearStats();
out << "---------------" << endl;
out << endl;
printSorted(out, m_num_of_sequencers, m_dataAccessTrace,
- "block_address");
+ "block_address", m_profiler);
out << endl;
out << "Hot MacroData Blocks" << endl;
out << "--------------------" << endl;
out << endl;
printSorted(out, m_num_of_sequencers, m_macroBlockAccessTrace,
- "macroblock_address");
+ "macroblock_address", m_profiler);
out << "Hot Instructions" << endl;
out << "----------------" << endl;
out << endl;
printSorted(out, m_num_of_sequencers, m_programCounterAccessTrace,
- "pc_address");
+ "pc_address", m_profiler);
}
if (m_all_instructions) {
out << "-------------------------" << endl;
out << endl;
printSorted(out, m_num_of_sequencers, m_programCounterAccessTrace,
- "pc_address");
+ "pc_address", m_profiler);
out << endl;
}
out << endl;
printSorted(out, m_num_of_sequencers, m_retryProfileMap,
- "block_address");
+ "block_address", m_profiler);
out << endl;
}
}
#include "mem/protocol/AccessType.hh"
#include "mem/protocol/RubyRequest.hh"
#include "mem/ruby/common/Address.hh"
-#include "mem/ruby/common/Global.hh"
#include "mem/ruby/common/Histogram.hh"
#include "mem/ruby/profiler/AccessTraceForAddress.hh"
+#include "mem/ruby/profiler/Profiler.hh"
class Set;
typedef m5::hash_map<Address, AccessTraceForAddress> AddressMap;
public:
- AddressProfiler(int num_of_sequencers);
+ AddressProfiler(int num_of_sequencers, Profiler *profiler);
~AddressProfiler();
void printStats(std::ostream& out) const;
Histogram m_getx_sharing_histogram;
Histogram m_gets_sharing_histogram;
+ Profiler *m_profiler;
+
//added by SS
bool m_hot_lines;
bool m_all_instructions;
void printSorted(std::ostream& out, int num_of_sequencers,
const AddressProfiler::AddressMap &record_map,
- std::string description);
+ std::string description, Profiler *profiler);
inline std::ostream&
operator<<(std::ostream& out, const AddressProfiler& obj)
#include "mem/ruby/profiler/AddressProfiler.hh"
#include "mem/ruby/profiler/Profiler.hh"
#include "mem/ruby/system/Sequencer.hh"
-#include "mem/ruby/system/System.hh"
using namespace std;
using m5::stl_helpers::operator<<;
m_hot_lines = p->hot_lines;
m_all_instructions = p->all_instructions;
- m_address_profiler_ptr = new AddressProfiler(p->num_of_sequencers);
+ m_address_profiler_ptr = new AddressProfiler(p->num_of_sequencers, this);
m_address_profiler_ptr->setHotLines(m_hot_lines);
m_address_profiler_ptr->setAllInstructions(m_all_instructions);
if (m_all_instructions) {
- m_inst_profiler_ptr = new AddressProfiler(p->num_of_sequencers);
+ m_inst_profiler_ptr = new AddressProfiler(p->num_of_sequencers, this);
m_inst_profiler_ptr->setHotLines(m_hot_lines);
m_inst_profiler_ptr->setAllInstructions(m_all_instructions);
}
class Profiler
{
public:
- Profiler(const RubySystemParams *);
+ Profiler(const RubySystemParams *params);
~Profiler();
void wakeup();
#include "mem/ruby/system/System.hh"
BankedArray::BankedArray(unsigned int banks, Cycles accessLatency,
- unsigned int startIndexBit)
+ unsigned int startIndexBit, RubySystem *rs)
+ : m_ruby_system(rs)
{
this->banks = banks;
this->accessLatency = accessLatency;
busyBanks[bank].idx = idx;
busyBanks[bank].startAccess = curTick();
busyBanks[bank].endAccess = curTick() +
- (accessLatency-1) * g_system_ptr->clockPeriod();
+ (accessLatency-1) * m_ruby_system->clockPeriod();
return true;
}
#include <vector>
#include "mem/ruby/common/TypeDefines.hh"
+#include "mem/ruby/system/System.hh"
#include "sim/core.hh"
class BankedArray
Cycles accessLatency;
unsigned int bankBits;
unsigned int startIndexBit;
+ RubySystem *m_ruby_system;
class AccessRecord
{
public:
BankedArray(unsigned int banks, Cycles accessLatency,
- unsigned int startIndexBit);
+ unsigned int startIndexBit, RubySystem *rs);
// Note: We try the access based on the cache index, not the address
// This is so we don't get aliasing on blocks being replaced
# Brad Beckmann
from m5.params import *
+from m5.proxy import *
from m5.SimObject import SimObject
class RubyCache(SimObject):
dataAccessLatency = Param.Cycles(1, "cycles for a data array access")
tagAccessLatency = Param.Cycles(1, "cycles for a tag array access")
resourceStalls = Param.Bool(False, "stall if there is a resource failure")
+ ruby_system = Param.RubySystem(Parent.any, "")
CacheMemory::CacheMemory(const Params *p)
: SimObject(p),
- dataArray(p->dataArrayBanks, p->dataAccessLatency, p->start_index_bit),
- tagArray(p->tagArrayBanks, p->tagAccessLatency, p->start_index_bit)
+ dataArray(p->dataArrayBanks, p->dataAccessLatency,
+ p->start_index_bit, p->ruby_system),
+ tagArray(p->tagArrayBanks, p->tagAccessLatency,
+ p->start_index_bit, p->ruby_system)
{
m_cache_size = p->size;
m_latency = p->latency;
physical_address_t addr = memRef->m_addr;
int bank = getBank(addr);
- DPRINTF(RubyMemory,
- "New memory request%7d: %#08x %c arrived at %10d bank = %3x sched %c\n",
- m_msg_counter, addr, memRef->m_is_mem_read ? 'R':'W',
- memRef->m_time * g_system_ptr->clockPeriod(),
- bank, m_event.scheduled() ? 'Y':'N');
-
m_profiler_ptr->profileMemReq(bank);
m_input_queue.push_back(memRef);
#include "base/cprintf.hh"
#include "base/stl_helpers.hh"
-#include "mem/ruby/common/Global.hh"
#include "mem/ruby/structures/WireBuffer.hh"
#include "mem/ruby/system/System.hh"
: SimObject(p)
{
m_msg_counter = 0;
+ m_ruby_system = p->ruby_system;
}
void
WireBuffer::enqueue(MsgPtr message, Cycles latency)
{
m_msg_counter++;
- Cycles current_time = g_system_ptr->curCycle();
+ Cycles current_time = m_ruby_system->curCycle();
Cycles arrival_time = current_time + latency;
assert(arrival_time > current_time);
m_message_queue.push_back(message);
if (m_consumer_ptr != NULL) {
m_consumer_ptr->
- scheduleEventAbsolute(g_system_ptr->clockPeriod() * arrival_time);
+ scheduleEventAbsolute(m_ruby_system->clockPeriod() * arrival_time);
} else {
panic("No Consumer for WireBuffer! %s\n", *this);
}
MsgPtr node = m_message_queue.front();
pop_heap(m_message_queue.begin(), m_message_queue.end(), greater<MsgPtr>());
- node->setLastEnqueueTime(g_system_ptr->curCycle() + Cycles(1));
+ node->setLastEnqueueTime(m_ruby_system->curCycle() + Cycles(1));
m_message_queue.back() = node;
push_heap(m_message_queue.begin(), m_message_queue.end(),
greater<MsgPtr>());
m_consumer_ptr->
- scheduleEventAbsolute(g_system_ptr->curCycle() + Cycles(1));
+ scheduleEventAbsolute(m_ruby_system->curCycle() + Cycles(1));
}
bool
{
return ((!m_message_queue.empty()) &&
(m_message_queue.front()->getLastEnqueueTime() <=
- g_system_ptr->curCycle()));
+ m_ruby_system->curCycle()));
}
void
// queues where memory requests live
std::vector<MsgPtr> m_message_queue;
+ RubySystem * m_ruby_system;
+
};
std::ostream& operator<<(std::ostream& out, const WireBuffer& obj);
# Author: Lisa Hsu
from m5.params import *
+from m5.proxy import *
from m5.SimObject import SimObject
class RubyWireBuffer(SimObject):
type = 'RubyWireBuffer'
cxx_class = 'WireBuffer'
cxx_header = "mem/ruby/structures/WireBuffer.hh"
+ ruby_system = Param.RubySystem(Parent.any, "")
#include "sim/system.hh"
DMASequencer::DMASequencer(const Params *p)
- : MemObject(p), m_version(p->version), m_controller(NULL),
- m_mandatory_q_ptr(NULL), m_usingRubyTester(p->using_ruby_tester),
+ : MemObject(p), m_ruby_system(p->ruby_system), m_version(p->version),
+ m_controller(NULL), m_mandatory_q_ptr(NULL),
+ m_usingRubyTester(p->using_ruby_tester),
slave_port(csprintf("%s.slave", name()), this, 0, p->ruby_system,
p->ruby_system->getAccessBackingStore()),
system(p->system), retry(false)
DMASequencer *_port, PortID id, RubySystem* _ruby_system,
bool _access_backing_store)
: QueuedSlavePort(_name, _port, queue, id), queue(*_port, *this),
- ruby_system(_ruby_system), access_backing_store(_access_backing_store)
+ m_ruby_system(_ruby_system), access_backing_store(_access_backing_store)
{
DPRINTF(RubyDma, "Created slave memport on ruby sequencer %s\n", _name);
}
// turn packet around to go back to requester if response expected
if (access_backing_store) {
- ruby_system->getPhysMem()->access(pkt);
+ m_ruby_system->getPhysMem()->access(pkt);
} else if (needsResponse) {
pkt->makeResponse();
}
if (needsResponse) {
DPRINTF(RubyDma, "Sending packet back over port\n");
// send next cycle
- schedTimingResp(pkt, curTick() + g_system_ptr->clockPeriod());
+ DMASequencer *seq = static_cast<DMASequencer *>(&owner);
+ RubySystem *rs = seq->m_ruby_system;
+ schedTimingResp(pkt, curTick() + rs->clockPeriod());
} else {
delete pkt;
}
#include <memory>
#include <ostream>
+#include "mem/mem_object.hh"
#include "mem/protocol/DMASequencerRequestType.hh"
#include "mem/protocol/RequestStatus.hh"
#include "mem/ruby/common/DataBlock.hh"
#include "mem/ruby/network/MessageBuffer.hh"
#include "mem/ruby/system/System.hh"
-#include "mem/mem_object.hh"
#include "mem/simple_mem.hh"
#include "mem/tport.hh"
#include "params/DMASequencer.hh"
typedef DMASequencerParams Params;
DMASequencer(const Params *);
void init();
+ RubySystem *m_ruby_system;
public:
class MemSlavePort : public QueuedSlavePort
{
private:
RespPacketQueue queue;
- RubySystem* ruby_system;
+ RubySystem* m_ruby_system;
bool access_backing_store;
public:
#include "sim/system.hh"
RubyPort::RubyPort(const Params *p)
- : MemObject(p), m_version(p->version), m_controller(NULL),
- m_mandatory_q_ptr(NULL), m_usingRubyTester(p->using_ruby_tester),
- system(p->system),
+ : MemObject(p), m_ruby_system(p->ruby_system), m_version(p->version),
+ m_controller(NULL), m_mandatory_q_ptr(NULL),
+ m_usingRubyTester(p->using_ruby_tester), system(p->system),
pioMasterPort(csprintf("%s.pio-master-port", name()), this),
pioSlavePort(csprintf("%s.pio-slave-port", name()), this),
memMasterPort(csprintf("%s.mem-master-port", name()), this),
memSlavePort(csprintf("%s-mem-slave-port", name()), this,
- p->ruby_system, p->ruby_system->getAccessBackingStore(), -1),
+ p->ruby_system->getAccessBackingStore(), -1),
gotAddrRanges(p->port_master_connection_count)
{
assert(m_version != -1);
// create the slave ports based on the number of connected ports
for (size_t i = 0; i < p->port_slave_connection_count; ++i) {
slave_ports.push_back(new MemSlavePort(csprintf("%s.slave%d", name(),
- i), this, p->ruby_system,
- p->ruby_system->getAccessBackingStore(), i));
+ i), this, p->ruby_system->getAccessBackingStore(), i));
}
// create the master ports based on the number of connected ports
}
RubyPort::MemSlavePort::MemSlavePort(const std::string &_name, RubyPort *_port,
- RubySystem *_system,
bool _access_backing_store, PortID id)
: QueuedSlavePort(_name, _port, queue, id), queue(*_port, *this),
- ruby_system(_system), access_backing_store(_access_backing_store)
+ access_backing_store(_access_backing_store)
{
DPRINTF(RubyPort, "Created slave memport on ruby sequencer %s\n", _name);
}
bool
RubyPort::PioMasterPort::recvTimingResp(PacketPtr pkt)
{
- RubyPort *ruby_port = static_cast<RubyPort *>(&owner);
+ RubyPort *rp = static_cast<RubyPort *>(&owner);
DPRINTF(RubyPort, "Response for address: 0x%#x\n", pkt->getAddr());
// send next cycle
- ruby_port->pioSlavePort.schedTimingResp(
- pkt, curTick() + g_system_ptr->clockPeriod());
+ rp->pioSlavePort.schedTimingResp(
+ pkt, curTick() + rp->m_ruby_system->clockPeriod());
return true;
}
pkt->getAddr(), port->name());
// attempt to send the response in the next cycle
- port->schedTimingResp(pkt, curTick() + g_system_ptr->clockPeriod());
+ RubyPort *rp = static_cast<RubyPort *>(&owner);
+ port->schedTimingResp(pkt, curTick() + rp->m_ruby_system->clockPeriod());
return true;
}
pkt->pushSenderState(new SenderState(this));
// send next cycle
+ RubySystem *rs = ruby_port->m_ruby_system;
ruby_port->memMasterPort.schedTimingReq(pkt,
- curTick() + g_system_ptr->clockPeriod());
+ curTick() + rs->clockPeriod());
return true;
}
}
//
- // Unless one is using the ruby tester, record the stalled M5 port for
+ // Unless one is using the ruby tester, record the stalled M5 port for
// later retry when the sequencer becomes free.
//
if (!ruby_port->m_usingRubyTester) {
{
DPRINTF(RubyPort, "Functional access for address: %#x\n", pkt->getAddr());
+ RubyPort *rp M5_VAR_USED = static_cast<RubyPort *>(&owner);
+ RubySystem *rs = rp->m_ruby_system;
+
// Check for pio requests and directly send them to the dedicated
// pio port.
if (!isPhysMemAddress(pkt->getAddr())) {
- RubyPort *ruby_port M5_VAR_USED = static_cast<RubyPort *>(&owner);
- assert(ruby_port->memMasterPort.isConnected());
+ assert(rp->memMasterPort.isConnected());
DPRINTF(RubyPort, "Pio Request for address: 0x%#x\n", pkt->getAddr());
panic("RubyPort::PioMasterPort::recvFunctional() not implemented!\n");
}
// The following command performs the real functional access.
// This line should be removed once Ruby supplies the official version
// of data.
- ruby_system->getPhysMem()->functionalAccess(pkt);
+ rs->getPhysMem()->functionalAccess(pkt);
} else {
bool accessSucceeded = false;
bool needsResponse = pkt->needsResponse();
// Do the functional access on ruby memory
if (pkt->isRead()) {
- accessSucceeded = ruby_system->functionalRead(pkt);
+ accessSucceeded = rs->functionalRead(pkt);
} else if (pkt->isWrite()) {
- accessSucceeded = ruby_system->functionalWrite(pkt);
+ accessSucceeded = rs->functionalWrite(pkt);
} else {
panic("Unsupported functional command %s\n", pkt->cmdString());
}
DPRINTF(RubyPort, "Hit callback needs response %d\n", needsResponse);
+ RubyPort *ruby_port = static_cast<RubyPort *>(&owner);
+ RubySystem *rs = ruby_port->m_ruby_system;
if (accessPhysMem) {
- ruby_system->getPhysMem()->access(pkt);
+ rs->getPhysMem()->access(pkt);
} else if (needsResponse) {
pkt->makeResponse();
}
if (needsResponse) {
DPRINTF(RubyPort, "Sending packet back over port\n");
// send next cycle
- schedTimingResp(pkt, curTick() + g_system_ptr->clockPeriod());
+ schedTimingResp(pkt, curTick() + rs->clockPeriod());
} else {
delete pkt;
}
{
private:
RespPacketQueue queue;
- RubySystem* ruby_system;
bool access_backing_store;
public:
MemSlavePort(const std::string &_name, RubyPort *_port,
- RubySystem*_system, bool _access_backing_store, PortID id);
+ bool _access_backing_store, PortID id);
void hitCallback(PacketPtr pkt);
void evictionCallback(const Address& address);
*/
bool recvTimingResp(PacketPtr pkt, PortID master_port_id);
+ RubySystem *m_ruby_system;
uint32_t m_version;
AbstractController* m_controller;
MessageBuffer* m_mandatory_q_ptr;
#if 0
int total_demand = 0;
out << "Sequencer Stats Version " << m_version << endl;
- out << "Current time = " << g_system_ptr->getTime() << endl;
+ out << "Current time = " << m_ruby_system->getTime() << endl;
out << "---------------" << endl;
out << "outstanding requests" << endl;
delete srequest;
+ RubySystem *rs = m_ruby_system;
if (RubySystem::getWarmupEnabled()) {
assert(pkt->req);
delete pkt->req;
delete pkt;
- g_system_ptr->m_cache_recorder->enqueueNextFetchRequest();
+ rs->m_cache_recorder->enqueueNextFetchRequest();
} else if (RubySystem::getCooldownEnabled()) {
delete pkt;
- g_system_ptr->m_cache_recorder->enqueueNextFlushRequest();
+ rs->m_cache_recorder->enqueueNextFlushRequest();
} else {
ruby_hit_callback(pkt);
}
Sequencer::checkCoherence(const Address& addr)
{
#ifdef CHECK_COHERENCE
- g_system_ptr->checkGlobalCoherenceInvariant(addr);
+ m_ruby_system->checkGlobalCoherenceInvariant(addr);
#endif
}
mem_slave_port = SlavePort("Ruby memory port")
using_ruby_tester = Param.Bool(False, "")
- ruby_system = Param.RubySystem("")
+ ruby_system = Param.RubySystem(Parent.any, "")
system = Param.System(Parent.any, "system object")
support_data_reqs = Param.Bool(True, "data cache requests supported")
support_inst_reqs = Param.Bool(True, "inst cache requests supported")
class RubyPortProxy(RubyPort):
type = 'RubyPortProxy'
cxx_header = "mem/ruby/system/RubyPortProxy.hh"
-
+
class RubySequencer(RubyPort):
type = 'RubySequencer'
cxx_class = 'Sequencer'
RubySystem::RubySystem(const Params *p)
: ClockedObject(p), m_access_backing_store(p->access_backing_store)
{
- if (g_system_ptr != NULL)
- fatal("Only one RubySystem object currently allowed.\n");
-
m_random_seed = p->random_seed;
srandom(m_random_seed);
m_randomization = p->randomization;
m_block_size_bits = floorLog2(m_block_size_bytes);
m_memory_size_bits = p->memory_size_bits;
- // Setup the global variables used in Ruby
- g_system_ptr = this;
-
// Resize to the size of different machine types
g_abs_controls.resize(MachineType_NUM);
RubySystem::RubyEvent::process()
{
if (RubySystem::getWarmupEnabled()) {
- ruby_system->m_cache_recorder->enqueueNextFetchRequest();
+ m_ruby_system->m_cache_recorder->enqueueNextFetchRequest();
} else if (RubySystem::getCooldownEnabled()) {
- ruby_system->m_cache_recorder->enqueueNextFlushRequest();
+ m_ruby_system->m_cache_recorder->enqueueNextFlushRequest();
}
}
public:
RubyEvent(RubySystem* _ruby_system)
{
- ruby_system = _ruby_system;
+ m_ruby_system = _ruby_system;
}
private:
void process();
- RubySystem* ruby_system;
+ RubySystem* m_ruby_system;
};
friend class RubyEvent;
static uint32_t m_block_size_bytes;
static uint32_t m_block_size_bits;
static uint32_t m_memory_size_bits;
+
static bool m_warmup_enabled;
static unsigned m_systems_to_warmup;
static bool m_cooldown_enabled;
class RubyStatsCallback : public Callback
{
private:
- RubySystem *ruby_system;
+ RubySystem *m_ruby_system;
public:
virtual ~RubyStatsCallback() {}
- RubyStatsCallback(RubySystem *system) : ruby_system(system) {}
- void process() { ruby_system->collateStats(); }
+ RubyStatsCallback(RubySystem *system) : m_ruby_system(system) {}
+ void process() { m_ruby_system->collateStats(); }
};
#endif // __MEM_RUBY_SYSTEM_SYSTEM_HH__
event < ${ident}_Event_NUM; ++event) {
Stats::Vector *t = new Stats::Vector();
t->init(m_num_controllers);
- t->name(g_system_ptr->name() + ".${c_ident}." +
+ t->name(params()->ruby_system->name() + ".${c_ident}." +
${ident}_Event_to_string(event));
t->flags(Stats::pdf | Stats::total | Stats::oneline |
Stats::nozero);
Stats::Vector *t = new Stats::Vector();
t->init(m_num_controllers);
- t->name(g_system_ptr->name() + ".${c_ident}." +
+ t->name(params()->ruby_system->name() + ".${c_ident}." +
${ident}_State_to_string(state) +
"." + ${ident}_Event_to_string(event));
for dm in self.data_members.values():
code('out << "${{dm.ident}} = " << m_${{dm.ident}} << " ";''')
- if self.isMessage:
- code('out << "Time = " << g_system_ptr->clockPeriod() * getTime() << " ";')
code.dedent()
# Trailer