ruby: Fix RubyMemory to work with the newer ruby.

This commit is contained in:
Nathan Binkert 2009-07-06 15:49:47 -07:00
parent a7904e2cf3
commit da704f52e5
15 changed files with 232 additions and 95 deletions

View file

@ -35,12 +35,11 @@ class RubyMemory(PhysicalMemory):
type = 'RubyMemory' type = 'RubyMemory'
clock = Param.Clock('1t', "ruby clock speed") clock = Param.Clock('1t', "ruby clock speed")
phase = Param.Latency('0ns', "ruby clock phase") phase = Param.Latency('0ns', "ruby clock phase")
config_file = Param.String("", "path to the Ruby config file") config_file = Param.String("path to the Ruby config file")
config_options = Param.String("", "extra Ruby options (one per line)")
stats_file = Param.String("ruby.stats", stats_file = Param.String("ruby.stats",
"file to which ruby dumps its stats") "file to which ruby dumps its stats")
num_cpus = Param.Int(1, "Number of CPUs connected to the Ruby memory") num_cpus = Param.Int(1, "Number of CPUs connected to the Ruby memory")
debug = Param.Bool(False, "Use ruby debug") debug = Param.Bool(False, "Use ruby debug")
debug_file = Param.String("", debug_file = Param.String("ruby.debug",
"path to the Ruby debug output file (stdout if blank)") "path to the Ruby debug output file (stdout if blank)")

View file

@ -36,7 +36,10 @@ if not main['RUBY']:
sticky_vars.AddVariables( sticky_vars.AddVariables(
BoolVariable('NO_VECTOR_BOUNDS_CHECKS', "Don't do bounds checks", True), BoolVariable('NO_VECTOR_BOUNDS_CHECKS', "Don't do bounds checks", True),
BoolVariable('RUBY_DEBUG', "Add debugging stuff to Ruby", False), BoolVariable('RUBY_DEBUG', "Add debugging stuff to Ruby", False),
('GEMS_ROOT', "Add debugging stuff to Ruby", Dir('..').srcnode().abspath)) ('GEMS_ROOT', "Add debugging stuff to Ruby", Dir('..').srcnode().abspath),
BoolVariable('RUBY_TSO_CHECKER', "Use the Ruby TSO Checker", False)
)
export_vars += [ 'NO_VECTOR_BOUNDS_CHECKS', 'RUBY_DEBUG', 'GEMS_ROOT' ] export_vars += [ 'NO_VECTOR_BOUNDS_CHECKS', 'RUBY_DEBUG', 'GEMS_ROOT',
'RUBY_TSO_CHECKER' ]

View file

@ -36,7 +36,7 @@
#include "mem/ruby/storebuffer/storebuffer.hh" #include "mem/ruby/storebuffer/storebuffer.hh"
#include "mem/ruby/common/Global.hh" #include "mem/ruby/common/Global.hh"
#ifdef RUBY_TSO_CHECKER #if RUBY_TSO_CHECKER
#include "TsoChecker.hh" #include "TsoChecker.hh"
#endif #endif
@ -46,7 +46,7 @@
// global map of request id_s to map them back to storebuffer pointers // global map of request id_s to map them back to storebuffer pointers
map <uint64_t, StoreBuffer *> request_map; map <uint64_t, StoreBuffer *> request_map;
#ifdef RUBY_TSO_CHECKER #if RUBY_TSO_CHECKER
Tso::TsoChecker * g_tsoChecker; Tso::TsoChecker * g_tsoChecker;
#endif #endif
@ -65,7 +65,7 @@ void hit(int64_t id) {
//***************************************************************************************** //*****************************************************************************************
StoreBuffer::StoreBuffer(uint32 id, uint32 block_bits, int storebuffer_size) { StoreBuffer::StoreBuffer(uint32 id, uint32 block_bits, int storebuffer_size) {
#ifdef RUBY_TSO_CHECKER #if RUBY_TSO_CHECKER
if (id == 0) { if (id == 0) {
g_tsoChecker = new Tso::TsoChecker(); g_tsoChecker = new Tso::TsoChecker();
g_tsoChecker->init(64); g_tsoChecker->init(64);
@ -99,7 +99,7 @@ StoreBuffer::StoreBuffer(uint32 id, uint32 block_bits, int storebuffer_size) {
//****************************************************************************************** //******************************************************************************************
StoreBuffer::~StoreBuffer(){ StoreBuffer::~StoreBuffer(){
#ifdef RUBY_TSO_CHECKER #if RUBY_TSO_CHECKER
if (m_id == 0) { if (m_id == 0) {
delete g_tsoChecker; delete g_tsoChecker;
} }
@ -272,7 +272,7 @@ void StoreBuffer::returnMatchedData(struct RubyRequest request) {
ASSERT(checkForLoadHit(request) != NO_MATCH); ASSERT(checkForLoadHit(request) != NO_MATCH);
physical_address_t lineaddr = physical_address & m_block_mask; physical_address_t lineaddr = physical_address & m_block_mask;
bool found = false; bool found = false;
#ifdef RUBY_TSO_CHECKER #if RUBY_TSO_CHECKER
Tso::TsoCheckerCmd * cmd; Tso::TsoCheckerCmd * cmd;
#endif #endif
deque<struct SBEntry>::iterator satisfying_store; deque<struct SBEntry>::iterator satisfying_store;
@ -280,7 +280,7 @@ void StoreBuffer::returnMatchedData(struct RubyRequest request) {
if ((it->m_request.paddr & m_block_mask) == lineaddr) { if ((it->m_request.paddr & m_block_mask) == lineaddr) {
if (!found) { if (!found) {
found = true; found = true;
#ifdef RUBY_TSO_CHECKER #if RUBY_TSO_CHECKER
satisfying_store = it; satisfying_store = it;
cmd = new Tso::TsoCheckerCmd(m_id, // this thread id cmd = new Tso::TsoCheckerCmd(m_id, // this thread id
iseq, // instruction sequence iseq, // instruction sequence
@ -313,7 +313,7 @@ void StoreBuffer::returnMatchedData(struct RubyRequest request) {
} }
} }
#ifdef RUBY_TSO_CHECKER #if RUBY_TSO_CHECKER
uint64_t tso_data = 0; uint64_t tso_data = 0;
memcpy(&tso_data, request.data, request.len); memcpy(&tso_data, request.data, request.len);
cmd->setData(tso_data); cmd->setData(tso_data);
@ -400,7 +400,7 @@ void StoreBuffer::complete(uint64_t id) {
m_buffer_size--; m_buffer_size--;
ASSERT(m_buffer_size >= 0); ASSERT(m_buffer_size >= 0);
#ifdef RUBY_TSO_CHECKER #if RUBY_TSO_CHECKER
int len = outstanding_requests.find(id)->second.len; int len = outstanding_requests.find(id)->second.len;
uint64_t data = 0; uint64_t data = 0;
memcpy(&data, from_buffer.m_request.data, 4); memcpy(&data, from_buffer.m_request.data, 4);
@ -462,7 +462,7 @@ void StoreBuffer::complete(uint64_t id) {
#endif #endif
} // end if (type == ST) } // end if (type == ST)
else if (type == RubyRequestType_LD) { else if (type == RubyRequestType_LD) {
#ifdef RUBY_TSO_CHECKER #if RUBY_TSO_CHECKER
RubyRequest request = outstanding_requests.find(id)->second; RubyRequest request = outstanding_requests.find(id)->second;
uint64_t data = 0; uint64_t data = 0;
memcpy(&data, request.data, request.len); memcpy(&data, request.data, request.len);
@ -511,7 +511,7 @@ void StoreBuffer::complete(uint64_t id) {
} }
} }
#ifdef RUBY_TSO_CHECKER #if RUBY_TSO_CHECKER
void StoreBuffer::insertTsoLL(Tso::TsoCheckerCmd * cmd) { void StoreBuffer::insertTsoLL(Tso::TsoCheckerCmd * cmd) {
uint64_t count = cmd->getIseq(); uint64_t count = cmd->getIseq();
Tso::TsoCheckerCmd * current = NULL; Tso::TsoCheckerCmd * current = NULL;

View file

@ -36,7 +36,7 @@
#include "mem/ruby/storebuffer/hfa.hh" #include "mem/ruby/storebuffer/hfa.hh"
#include "mem/ruby/libruby.hh" #include "mem/ruby/libruby.hh"
#ifdef RUBY_TSO_CHECKER #if RUBY_TSO_CHECKER
#include "TsoCheckerCmd.hh" #include "TsoCheckerCmd.hh"
#endif #endif
@ -53,13 +53,13 @@ enum load_match { NO_MATCH, PARTIAL_MATCH, FULL_MATCH };
struct SBEntry { struct SBEntry {
struct RubyRequest m_request; struct RubyRequest m_request;
#ifdef RUBY_TSO_CHECKER #if RUBY_TSO_CHECKER
Tso::TsoCheckerCmd * m_next_ptr; Tso::TsoCheckerCmd * m_next_ptr;
#endif #endif
SBEntry(struct RubyRequest request, void * ptr) SBEntry(struct RubyRequest request, void * ptr)
: m_request(request) : m_request(request)
{ {
#ifdef RUBY_TSO_CHECKER #if RUBY_TSO_CHECKER
m_next_ptr = (Tso::TsoCheckerCmd*) ptr; m_next_ptr = (Tso::TsoCheckerCmd*) ptr;
#endif #endif
} }
@ -101,7 +101,7 @@ class StoreBuffer {
/// prints out the contents of the Write Buffer /// prints out the contents of the Write Buffer
void print(); void print();
#ifdef RUBY_TSO_CHECKER #if RUBY_TSO_CHECKER
/// if load completes before store, insert correctly to be issued to TSOChecker /// if load completes before store, insert correctly to be issued to TSOChecker
void insertTsoLL(Tso::TsoCheckerCmd * cmd); void insertTsoLL(Tso::TsoCheckerCmd * cmd);
#endif #endif

View file

@ -33,9 +33,11 @@
#include "arch/isa_traits.hh" #include "arch/isa_traits.hh"
#include "base/output.hh" #include "base/output.hh"
#include "base/str.hh"
#include "base/types.hh" #include "base/types.hh"
#include "mem/ruby/common/Debug.hh" #include "mem/ruby/common/Debug.hh"
#include "mem/ruby/init.hh" #include "mem/ruby/libruby.hh"
#include "mem/ruby/system/RubyPort.hh"
#include "mem/ruby/system/Sequencer.hh" #include "mem/ruby/system/Sequencer.hh"
#include "mem/ruby/system/System.hh" #include "mem/ruby/system/System.hh"
#include "mem/rubymem.hh" #include "mem/rubymem.hh"
@ -45,33 +47,54 @@
using namespace std; using namespace std;
using namespace TheISA; using namespace TheISA;
map<int64_t, PacketPtr> RubyMemory::pending_requests;
RubyMemory::RubyMemory(const Params *p) RubyMemory::RubyMemory(const Params *p)
: PhysicalMemory(p) : PhysicalMemory(p)
{ {
config_file = p->config_file;
config_options = p->config_options;
stats_file = p->stats_file;
num_cpus = p->num_cpus;
ruby_clock = p->clock; ruby_clock = p->clock;
ruby_phase = p->phase; ruby_phase = p->phase;
debug = p->debug; ifstream config(p->config_file.c_str());
debug_file = p->debug_file;
vector<RubyObjConf> sys_conf;
while (!config.eof()) {
char buffer[4096];
config.getline(buffer, sizeof(buffer));
string line = buffer;
if (line.empty())
continue;
vector<string> tokens;
tokenize(tokens, line, ' ');
assert(tokens.size() >= 2);
vector<string> argv;
for (size_t i=2; i<tokens.size(); i++) {
std::replace(tokens[i].begin(), tokens[i].end(), '%', ' ');
std::replace(tokens[i].begin(), tokens[i].end(), '#', '\n');
argv.push_back(tokens[i]);
}
sys_conf.push_back(RubyObjConf(tokens[0], tokens[1], argv));
tokens.clear();
argv.clear();
}
RubySystem::create(sys_conf);
for (int i = 0; i < params()->num_cpus; i++) {
RubyPort *p = RubySystem::getPort(csprintf("Sequencer_%d", i),
ruby_hit_callback);
ruby_ports.push_back(p);
}
} }
void void
RubyMemory::init() RubyMemory::init()
{ {
init_variables(); if (params()->debug) {
g_NUM_PROCESSORS = num_cpus;
init_simulator(this);
if (debug) {
g_debug_ptr->setVerbosityString("high"); g_debug_ptr->setVerbosityString("high");
g_debug_ptr->setDebugTime(1); g_debug_ptr->setDebugTime(1);
if (debug_file != "") { if (!params()->debug_file.empty()) {
g_debug_ptr->setDebugOutputFile("ruby.debug"); g_debug_ptr->setDebugOutputFile(params()->debug_file.c_str());
} }
} }
@ -104,23 +127,21 @@ RubyMemory::init()
} }
//called by rubyTickEvent //called by rubyTickEvent
void RubyMemory::tick() { void
g_eventQueue_ptr->triggerEvents(g_eventQueue_ptr->getTime() + 1); RubyMemory::tick()
schedule(rubyTickEvent, curTick + ruby_clock); //dsm: clock_phase was added here. This is wrong, the phase is only added on the first tick {
RubyEventQueue *eq = RubySystem::getEventQueue();
eq->triggerEvents(eq->getTime() + 1);
schedule(rubyTickEvent, curTick + ruby_clock);
} }
RubyMemory::~RubyMemory()
RubyMemory::~RubyMemory() { {
delete g_system_ptr;
} }
void void
RubyMemory::hitCallback(Packet* pkt) RubyMemory::hitCallback(PacketPtr pkt, Port *port)
{ {
RubyMemoryPort* port = m_packet_to_port_map[pkt];
assert(port != NULL);
m_packet_to_port_map.erase(pkt);
DPRINTF(MemoryAccess, "Hit callback\n"); DPRINTF(MemoryAccess, "Hit callback\n");
bool needsResponse = pkt->needsResponse(); bool needsResponse = pkt->needsResponse();
@ -146,7 +167,7 @@ RubyMemory::getPort(const std::string &if_name, int idx)
// with places where this function is called from C++. I'd prefer // with places where this function is called from C++. I'd prefer
// to move all these into Python someday. // to move all these into Python someday.
if (if_name == "functional") { if (if_name == "functional") {
return new RubyMemoryPort(csprintf("%s-functional", name()), this); return new Port(csprintf("%s-functional", name()), this);
} }
if (if_name != "port") { if (if_name != "port") {
@ -161,22 +182,20 @@ RubyMemory::getPort(const std::string &if_name, int idx)
panic("RubyMemory::getPort: port %d already assigned", idx); panic("RubyMemory::getPort: port %d already assigned", idx);
} }
RubyMemoryPort *port = Port *port = new Port(csprintf("%s-port%d", name(), idx), this);
new RubyMemoryPort(csprintf("%s-port%d", name(), idx), this);
ports[idx] = port; ports[idx] = port;
return port; return port;
} }
RubyMemory::RubyMemoryPort::RubyMemoryPort(const std::string &_name, RubyMemory::Port::Port(const std::string &_name, RubyMemory *_memory)
RubyMemory *_memory)
: PhysicalMemory::MemoryPort::MemoryPort(_name, _memory) : PhysicalMemory::MemoryPort::MemoryPort(_name, _memory)
{ {
ruby_mem = _memory; ruby_mem = _memory;
} }
bool bool
RubyMemory::RubyMemoryPort::recvTiming(PacketPtr pkt) RubyMemory::Port::recvTiming(PacketPtr pkt)
{ {
DPRINTF(MemoryAccess, "Timing access caught\n"); DPRINTF(MemoryAccess, "Timing access caught\n");
@ -197,33 +216,83 @@ RubyMemory::RubyMemoryPort::recvTiming(PacketPtr pkt)
return true; return true;
} }
ruby_mem->m_packet_to_port_map[pkt] = this; // Save the port in the sender state object
pkt->senderState = new SenderState(this, pkt->senderState);
Sequencer* sequencer = g_system_ptr->getSequencer(pkt->req->contextId()); RubyRequestType type = RubyRequestType_NULL;
Addr pc = 0;
if (pkt->isRead()) {
if (pkt->req->isInstFetch()) {
type = RubyRequestType_IFETCH;
pc = pkt->req->getPC();
} else {
type = RubyRequestType_LD;
}
} else if (pkt->isWrite()) {
type = RubyRequestType_ST;
} else if (pkt->isReadWrite()) {
type = RubyRequestType_RMW;
}
if ( ! sequencer->isReady(pkt) ) { RubyRequest ruby_request(pkt->getAddr(), pkt->getPtr<uint8_t>(),
DPRINTF(MemoryAccess, "Sequencer isn't ready yet!!\n"); pkt->getSize(), pc, type,
RubyAccessMode_Supervisor);
// Submit the ruby request
RubyPort *ruby_port = ruby_mem->ruby_ports[pkt->req->contextId()];
int64_t req_id = ruby_port->makeRequest(ruby_request);
if (req_id == -1) {
RubyMemory::SenderState *senderState =
safe_cast<RubyMemory::SenderState *>(pkt->senderState);
// pop the sender state from the packet
pkt->senderState = senderState->saved;
delete senderState;
return false; return false;
} }
DPRINTF(MemoryAccess, "Issuing makeRequest\n"); // Save the request for the callback
RubyMemory::pending_requests[req_id] = pkt;
sequencer->makeRequest(pkt);
return true; return true;
} }
void void
RubyMemory::RubyMemoryPort::sendTiming(PacketPtr pkt) ruby_hit_callback(int64_t req_id)
{
typedef map<int64_t, PacketPtr> map_t;
map_t &prm = RubyMemory::pending_requests;
map_t::iterator i = prm.find(req_id);
if (i == prm.end())
panic("could not find pending request %d\n", req_id);
PacketPtr pkt = i->second;
prm.erase(i);
RubyMemory::SenderState *senderState =
safe_cast<RubyMemory::SenderState *>(pkt->senderState);
RubyMemory::Port *port = senderState->port;
// pop the sender state from the packet
pkt->senderState = senderState->saved;
delete senderState;
port->ruby_mem->hitCallback(pkt, port);
}
void
RubyMemory::Port::sendTiming(PacketPtr pkt)
{ {
schedSendTiming(pkt, curTick + 1); //minimum latency, must be > 0 schedSendTiming(pkt, curTick + 1); //minimum latency, must be > 0
} }
void RubyMemory::printConfigStats() void RubyMemory::printConfigStats()
{ {
std::ostream *os = simout.create(stats_file); std::ostream *os = simout.create(params()->stats_file);
g_system_ptr->printConfig(*os); RubySystem::printConfig(*os);
*os << endl; *os << endl;
g_system_ptr->printStats(*os); RubySystem::printStats(*os);
} }

View file

@ -32,20 +32,26 @@
#define __RUBY_MEMORY_HH__ #define __RUBY_MEMORY_HH__
#include <map> #include <map>
#include <vector>
#include "mem/physical.hh"
#include "params/RubyMemory.hh"
#include "base/callback.hh" #include "base/callback.hh"
#include "mem/ruby/common/Driver.hh" #include "mem/packet.hh"
#include "mem/physical.hh"
#include "mem/ruby/system/RubyPort.hh"
#include "params/RubyMemory.hh"
class RubyMemory : public PhysicalMemory, public Driver class RubyMemory : public PhysicalMemory
{ {
class RubyMemoryPort : public MemoryPort public:
std::vector<RubyPort *> ruby_ports;
class Port : public MemoryPort
{ {
RubyMemory* ruby_mem; friend void ruby_hit_callback(int64_t req_id);
RubyMemory *ruby_mem;
public: public:
RubyMemoryPort(const std::string &_name, RubyMemory *_memory); Port(const std::string &_name, RubyMemory *_memory);
void sendTiming(PacketPtr pkt); void sendTiming(PacketPtr pkt);
protected: protected:
@ -64,6 +70,15 @@ class RubyMemory : public PhysicalMemory, public Driver
virtual const char *description() const { return "ruby tick"; } virtual const char *description() const { return "ruby tick"; }
}; };
struct SenderState : public Packet::SenderState
{
Port *port;
Packet::SenderState *saved;
SenderState(Port *p, Packet::SenderState *s = NULL)
: port(p), saved(s)
{}
};
private: private:
// prevent copying of a RubyMemory object // prevent copying of a RubyMemory object
@ -77,14 +92,23 @@ class RubyMemory : public PhysicalMemory, public Driver
RubyMemory(const Params *p); RubyMemory(const Params *p);
virtual ~RubyMemory(); virtual ~RubyMemory();
const Params *
params() const
{
return safe_cast<const Params *>(_params);
}
public: public:
virtual Port *getPort(const std::string &if_name, int idx = -1); virtual ::Port *getPort(const std::string &if_name, int idx = -1);
void virtual init(); void virtual init();
//Ruby-related specifics //Ruby-related specifics
void printConfigStats(); //dsm: Maybe this function should disappear once the configuration options change & M5 determines the stats file to use void printConfigStats(); //dsm: Maybe this function should
//disappear once the configuration
//options change & M5 determines the
//stats file to use
void hitCallback(Packet* pkt); // called by the Ruby sequencer void hitCallback(PacketPtr pkt, Port *port);
void printStats(std::ostream & out) const; void printStats(std::ostream & out) const;
void clearStats(); void clearStats();
@ -93,15 +117,15 @@ class RubyMemory : public PhysicalMemory, public Driver
void tick(); void tick();
private: private:
//Parameters passed Tick ruby_clock;
std::string config_file, config_options, stats_file, debug_file; Tick ruby_phase;
bool debug;
int num_cpus;
Tick ruby_clock, ruby_phase;
std::map<Packet*, RubyMemoryPort*> m_packet_to_port_map; public:
static std::map<int64_t, PacketPtr> pending_requests;
}; };
void ruby_hit_callback(int64_t);
class RubyExitCallback : public Callback class RubyExitCallback : public Callback
{ {
private: private:

View file

@ -34,9 +34,12 @@ from m5.objects import *
nb_cores = 8 nb_cores = 8
cpus = [ MemTest() for i in xrange(nb_cores) ] cpus = [ MemTest() for i in xrange(nb_cores) ]
import ruby_config
ruby_memory = ruby_config.generate("MI_example-homogeneous.rb", nb_cores)
# system simulated # system simulated
system = System(cpu = cpus, funcmem = PhysicalMemory(), system = System(cpu = cpus, funcmem = PhysicalMemory(),
physmem = RubyMemory(num_cpus=nb_cores), physmem = ruby_memory,
membus = Bus(clock="500GHz", width=16)) membus = Bus(clock="500GHz", width=16))
for cpu in cpus: for cpu in cpus:

View file

@ -33,9 +33,11 @@ m5.AddToPath('../configs/common')
nb_cores = 4 nb_cores = 4
cpus = [ DerivO3CPU(cpu_id=i) for i in xrange(nb_cores) ] cpus = [ DerivO3CPU(cpu_id=i) for i in xrange(nb_cores) ]
import ruby_config
ruby_memory = ruby_config.generate("MI_example-homogeneous.rb", nb_cores)
# system simulated # system simulated
system = System(cpu = cpus, physmem = RubyMemory(num_cpus=nb_cores), system = System(cpu = cpus, physmem = ruby_memory, membus = Bus())
membus = Bus())
for cpu in cpus: for cpu in cpus:
cpu.connectMemPorts(system.membus) cpu.connectMemPorts(system.membus)

View file

@ -31,11 +31,14 @@ from m5.objects import *
m5.AddToPath('../configs/common') m5.AddToPath('../configs/common')
import ruby_config
ruby_memory = ruby_config.generate("MI_example-homogeneous.rb", 1)
cpu = DerivO3CPU(cpu_id=0) cpu = DerivO3CPU(cpu_id=0)
cpu.clock = '2GHz' cpu.clock = '2GHz'
system = System(cpu = cpu, system = System(cpu = cpu,
physmem = RubyMemory(), physmem = ruby_memory,
membus = Bus()) membus = Bus())
system.physmem.port = system.membus.port system.physmem.port = system.membus.port
cpu.connectMemPorts(system.membus) cpu.connectMemPorts(system.membus)

View file

@ -0,0 +1,20 @@
import os
import subprocess
from os.path import dirname, join as joinpath
import m5
def generate(config_file, cores=1, memories=1, memory_size=1024):
default = joinpath(dirname(__file__), '../../src/mem/ruby/config')
ruby_config = os.environ.get('RUBY_CONFIG', default)
args = [ "ruby", "-I", ruby_config, joinpath(ruby_config, "print_cfg.rb"),
"-r", joinpath(ruby_config, config_file), "-p", str(cores),
"-m", str(memories), "-s", str(memory_size)]
temp_config = joinpath(m5.options.outdir, "ruby.config")
ret = subprocess.call(args, stdout=file(temp_config, "w"))
if ret != 0:
raise RuntimeError, "subprocess failed!"
return m5.objects.RubyMemory(config_file=temp_config, num_cpus=cores)

View file

@ -33,9 +33,11 @@ from m5.objects import *
nb_cores = 4 nb_cores = 4
cpus = [ AtomicSimpleCPU(cpu_id=i) for i in xrange(nb_cores) ] cpus = [ AtomicSimpleCPU(cpu_id=i) for i in xrange(nb_cores) ]
import ruby_config
ruby_memory = ruby_config.generate("MI_example-homogeneous.rb", nb_cores)
# system simulated # system simulated
system = System(cpu = cpus, physmem = RubyMemory(num_cpus=nb_cores), system = System(cpu = cpus, physmem = ruby_memory, membus = Bus())
membus = Bus())
# add L1 caches # add L1 caches
for cpu in cpus: for cpu in cpus:

View file

@ -29,8 +29,11 @@
import m5 import m5
from m5.objects import * from m5.objects import *
import ruby_config
ruby_memory = ruby_config.generate("MI_example-homogeneous.rb", 1)
system = System(cpu = AtomicSimpleCPU(cpu_id=0), system = System(cpu = AtomicSimpleCPU(cpu_id=0),
physmem = RubyMemory(), physmem = ruby_memory,
membus = Bus()) membus = Bus())
system.physmem.port = system.membus.port system.physmem.port = system.membus.port
system.cpu.connectMemPorts(system.membus) system.cpu.connectMemPorts(system.membus)

View file

@ -32,9 +32,11 @@ from m5.objects import *
nb_cores = 4 nb_cores = 4
cpus = [ TimingSimpleCPU(cpu_id=i) for i in xrange(nb_cores) ] cpus = [ TimingSimpleCPU(cpu_id=i) for i in xrange(nb_cores) ]
import ruby_config
ruby_memory = ruby_config.generate("MI_example-homogeneous.rb", nb_cores)
# system simulated # system simulated
system = System(cpu = cpus, physmem = RubyMemory(num_cpus=nb_cores), system = System(cpu = cpus, physmem = ruby_memory, membus = Bus())
membus = Bus())
# add L1 caches # add L1 caches
for cpu in cpus: for cpu in cpus:

View file

@ -29,9 +29,12 @@
import m5 import m5
from m5.objects import * from m5.objects import *
import ruby_config
ruby_memory = ruby_config.generate("MI_example-homogeneous.rb", 1)
cpu = TimingSimpleCPU(cpu_id=0) cpu = TimingSimpleCPU(cpu_id=0)
system = System(cpu = cpu, system = System(cpu = cpu,
physmem = RubyMemory(), physmem = ruby_memory,
membus = Bus()) membus = Bus())
system.physmem.port = system.membus.port system.physmem.port = system.membus.port
cpu.connectMemPorts(system.membus) cpu.connectMemPorts(system.membus)

View file

@ -28,6 +28,9 @@
import os import os
import sys import sys
from os.path import join as joinpath
import m5 import m5
# Since we're in batch mode, dont allow tcp socket connections # Since we're in batch mode, dont allow tcp socket connections
@ -41,32 +44,33 @@ tests_root = os.path.dirname(__file__)
if os.path.isdir('/dist/m5/regression/test-progs'): if os.path.isdir('/dist/m5/regression/test-progs'):
test_progs = '/dist/m5/regression/test-progs' test_progs = '/dist/m5/regression/test-progs'
else: else:
test_progs = os.path.join(tests_root, 'test-progs') test_progs = joinpath(tests_root, 'test-progs')
# generate path to binary file # generate path to binary file
def binpath(app, file=None): def binpath(app, file=None):
# executable has same name as app unless specified otherwise # executable has same name as app unless specified otherwise
if not file: if not file:
file = app file = app
return os.path.join(test_progs, app, 'bin', isa, opsys, file) return joinpath(test_progs, app, 'bin', isa, opsys, file)
# generate path to input file # generate path to input file
def inputpath(app, file=None): def inputpath(app, file=None):
# input file has same name as app unless specified otherwise # input file has same name as app unless specified otherwise
if not file: if not file:
file = app file = app
return os.path.join(test_progs, app, 'input', file) return joinpath(test_progs, app, 'input', file)
# build configuration # build configuration
execfile(os.path.join(tests_root, 'configs', config + '.py')) sys.path.append(joinpath(tests_root, 'configs'))
execfile(joinpath(tests_root, 'configs', config + '.py'))
# set default maxtick... script can override # set default maxtick... script can override
# -1 means run forever # -1 means run forever
maxtick = m5.MaxTick maxtick = m5.MaxTick
# tweak configuration for specific test # tweak configuration for specific test
sys.path.append(joinpath(tests_root, category, name))
execfile(os.path.join(tests_root, category, name, 'test.py')) execfile(joinpath(tests_root, category, name, 'test.py'))
# instantiate configuration # instantiate configuration
m5.instantiate(root) m5.instantiate(root)