summaryrefslogtreecommitdiff
path: root/src/mem/ruby/system
diff options
context:
space:
mode:
authorSteve Reinhardt <steve.reinhardt@amd.com>2010-01-29 20:29:17 -0800
committerSteve Reinhardt <steve.reinhardt@amd.com>2010-01-29 20:29:17 -0800
commit98c94cfe3ce83634f3bad79ca18263f42e36ca6a (patch)
treeb299448162932c5574b87238a3b02a01efd14db6 /src/mem/ruby/system
parentb43994ba45b7805da0d1d9600e5cbb8332057403 (diff)
downloadgem5-98c94cfe3ce83634f3bad79ca18263f42e36ca6a.tar.xz
ruby: Convert most Ruby objects to M5 SimObjects.
The necessary companion conversion of Ruby objects generated by SLICC are converted to M5 SimObjects in the following patch, so this patch alone does not compile. Conversion of Garnet network models is also handled in a separate patch; that code is temporarily disabled from compiling to allow testing of interim code.
Diffstat (limited to 'src/mem/ruby/system')
-rw-r--r--src/mem/ruby/system/Cache.py12
-rw-r--r--src/mem/ruby/system/CacheMemory.cc59
-rw-r--r--src/mem/ruby/system/CacheMemory.hh11
-rw-r--r--src/mem/ruby/system/DMASequencer.cc25
-rw-r--r--src/mem/ruby/system/DMASequencer.hh13
-rw-r--r--src/mem/ruby/system/DirectoryMemory.cc31
-rw-r--r--src/mem/ruby/system/DirectoryMemory.hh9
-rw-r--r--src/mem/ruby/system/DirectoryMemory.py10
-rw-r--r--src/mem/ruby/system/MemoryControl.cc77
-rw-r--r--src/mem/ruby/system/MemoryControl.hh10
-rw-r--r--src/mem/ruby/system/MemoryControl.py23
-rw-r--r--src/mem/ruby/system/RubyPort.cc52
-rw-r--r--src/mem/ruby/system/RubyPort.hh55
-rw-r--r--src/mem/ruby/system/RubySystem.py18
-rw-r--r--src/mem/ruby/system/SConscript6
-rw-r--r--src/mem/ruby/system/Sequencer.cc75
-rw-r--r--src/mem/ruby/system/Sequencer.hh12
-rw-r--r--src/mem/ruby/system/Sequencer.py23
-rw-r--r--src/mem/ruby/system/System.cc207
-rw-r--r--src/mem/ruby/system/System.hh10
20 files changed, 363 insertions, 375 deletions
diff --git a/src/mem/ruby/system/Cache.py b/src/mem/ruby/system/Cache.py
new file mode 100644
index 000000000..250d8e888
--- /dev/null
+++ b/src/mem/ruby/system/Cache.py
@@ -0,0 +1,12 @@
+from m5.params import *
+from m5.SimObject import SimObject
+from Controller import RubyController
+
+class RubyCache(SimObject):
+ type = 'RubyCache'
+ cxx_class = 'CacheMemory'
+ size = Param.Int("");
+ latency = Param.Int("");
+ assoc = Param.Int("");
+ replacement_policy = Param.String("PSEUDO_LRU", "");
+ controller = Param.RubyController("");
diff --git a/src/mem/ruby/system/CacheMemory.cc b/src/mem/ruby/system/CacheMemory.cc
index cf3e094ad..43a0e13e9 100644
--- a/src/mem/ruby/system/CacheMemory.cc
+++ b/src/mem/ruby/system/CacheMemory.cc
@@ -47,41 +47,20 @@ ostream& operator<<(ostream& out, const CacheMemory& obj)
// ****************************************************************
-CacheMemory::CacheMemory(const string & name)
- : m_cache_name(name)
+CacheMemory *
+RubyCacheParams::create()
{
- m_profiler_ptr = new CacheProfiler(name);
+ return new CacheMemory(this);
}
-void CacheMemory::init(const vector<string> & argv)
+CacheMemory::CacheMemory(const Params *p)
+ : SimObject(p)
{
- int cache_size = -1;
- string policy;
-
- m_num_last_level_caches =
- MachineType_base_count(MachineType_FIRST);
- m_controller = NULL;
- for (uint32 i=0; i<argv.size(); i+=2) {
- if (argv[i] == "size") {
- cache_size = atoi(argv[i+1].c_str());
- } else if (argv[i] == "latency") {
- m_latency = atoi(argv[i+1].c_str());
- } else if (argv[i] == "assoc") {
- m_cache_assoc = atoi(argv[i+1].c_str());
- } else if (argv[i] == "replacement_policy") {
- policy = argv[i+1];
- } else if (argv[i] == "controller") {
- m_controller = RubySystem::getController(argv[i+1]);
- if (m_last_level_machine_type < m_controller->getMachineType()) {
- m_num_last_level_caches =
- MachineType_base_count(m_controller->getMachineType());
- m_last_level_machine_type =
- m_controller->getMachineType();
- }
- } else {
- cerr << "WARNING: CacheMemory: Unknown configuration parameter: " << argv[i] << endl;
- }
- }
+ int cache_size = p->size;
+ m_latency = p->latency;
+ m_cache_assoc = p->assoc;
+ string policy = p->replacement_policy;
+ m_controller = p->controller;
int num_lines = cache_size/RubySystem::getBlockSizeBytes();
m_cache_num_sets = num_lines / m_cache_assoc;
@@ -95,6 +74,24 @@ void CacheMemory::init(const vector<string> & argv)
else
assert(false);
+}
+
+
+void CacheMemory::init()
+{
+ m_num_last_level_caches =
+ MachineType_base_count(MachineType_FIRST);
+#if 0
+ for (uint32 i=0; i<argv.size(); i+=2) {
+ if (m_last_level_machine_type < m_controller->getMachineType()) {
+ m_num_last_level_caches =
+ MachineType_base_count(m_controller->getMachineType());
+ m_last_level_machine_type =
+ m_controller->getMachineType();
+ }
+ }
+#endif
+
m_cache.setSize(m_cache_num_sets);
m_locked.setSize(m_cache_num_sets);
for (int i = 0; i < m_cache_num_sets; i++) {
diff --git a/src/mem/ruby/system/CacheMemory.hh b/src/mem/ruby/system/CacheMemory.hh
index 8b84f33ec..fac076da9 100644
--- a/src/mem/ruby/system/CacheMemory.hh
+++ b/src/mem/ruby/system/CacheMemory.hh
@@ -38,6 +38,9 @@
#ifndef CACHEMEMORY_H
#define CACHEMEMORY_H
+#include "sim/sim_object.hh"
+#include "params/RubyCache.hh"
+
#include "mem/ruby/common/Global.hh"
#include "mem/protocol/AccessPermission.hh"
#include "mem/ruby/common/Address.hh"
@@ -57,12 +60,14 @@
#include "base/hashmap.hh"
#include <vector>
-class CacheMemory {
+class CacheMemory : public SimObject {
public:
+ typedef RubyCacheParams Params;
// Constructors
- CacheMemory(const string & name);
- void init(const vector<string> & argv);
+ CacheMemory(const Params *p);
+ // CacheMemory(const string & name);
+ void init();
// Destructor
~CacheMemory();
diff --git a/src/mem/ruby/system/DMASequencer.cc b/src/mem/ruby/system/DMASequencer.cc
index 8af892007..330e9f6af 100644
--- a/src/mem/ruby/system/DMASequencer.cc
+++ b/src/mem/ruby/system/DMASequencer.cc
@@ -8,25 +8,13 @@
#include "mem/protocol/SequencerRequestType.hh"
#include "mem/ruby/system/System.hh"
-DMASequencer::DMASequencer(const string & name)
- : RubyPort(name)
+DMASequencer::DMASequencer(const Params *p)
+ : RubyPort(p)
{
}
-void DMASequencer::init(const vector<string> & argv)
+void DMASequencer::init()
{
- m_version = -1;
- m_controller = NULL;
- for (size_t i=0;i<argv.size();i+=2) {
- if (argv[i] == "controller")
- m_controller = RubySystem::getController(argv[i+1]);
- else if (argv[i] == "version")
- m_version = atoi(argv[i+1].c_str());
- }
- assert(m_controller != NULL);
- assert(m_version != -1);
-
- m_mandatory_q_ptr = m_controller->getMandatoryQueue();
m_is_busy = false;
m_data_block_mask = ~ (~0 << RubySystem::getBlockSizeBits());
}
@@ -135,3 +123,10 @@ void DMASequencer::printConfig(ostream & out)
{
}
+
+
+DMASequencer *
+DMASequencerParams::create()
+{
+ return new DMASequencer(this);
+}
diff --git a/src/mem/ruby/system/DMASequencer.hh b/src/mem/ruby/system/DMASequencer.hh
index 77c0a2258..12a5c790f 100644
--- a/src/mem/ruby/system/DMASequencer.hh
+++ b/src/mem/ruby/system/DMASequencer.hh
@@ -6,6 +6,8 @@
#include "mem/ruby/common/DataBlock.hh"
#include "mem/ruby/system/RubyPort.hh"
+#include "params/DMASequencer.hh"
+
struct DMARequest {
uint64_t start_paddr;
int len;
@@ -16,13 +18,11 @@ struct DMARequest {
int64_t id;
};
-class MessageBuffer;
-class AbstractController;
-
class DMASequencer :public RubyPort {
public:
- DMASequencer(const string & name);
- void init(const vector<string> & argv);
+ typedef DMASequencerParams Params;
+ DMASequencer(const Params *);
+ void init();
/* external interface */
int64_t makeRequest(const RubyRequest & request);
bool isReady(const RubyRequest & request, bool dont_set = false) { assert(0); return false;};
@@ -39,13 +39,10 @@ private:
void issueNext();
private:
- int m_version;
- AbstractController* m_controller;
bool m_is_busy;
uint64_t m_data_block_mask;
DMARequest active_request;
int num_active_requests;
- MessageBuffer* m_mandatory_q_ptr;
};
#endif // DMACONTROLLER_H
diff --git a/src/mem/ruby/system/DirectoryMemory.cc b/src/mem/ruby/system/DirectoryMemory.cc
index 9b2a3873c..b0b33b048 100644
--- a/src/mem/ruby/system/DirectoryMemory.cc
+++ b/src/mem/ruby/system/DirectoryMemory.cc
@@ -46,29 +46,17 @@ int DirectoryMemory::m_num_directories = 0;
int DirectoryMemory::m_num_directories_bits = 0;
uint64_t DirectoryMemory::m_total_size_bytes = 0;
-DirectoryMemory::DirectoryMemory(const string & name)
- : m_name(name)
+DirectoryMemory::DirectoryMemory(const Params *p)
+ : SimObject(p)
{
+ m_version = p->version;
+ m_size_bytes = p->size_mb * static_cast<uint64>(1<<20);
+ m_size_bits = log_int(m_size_bytes);
+ m_controller = p->controller;
}
-void DirectoryMemory::init(const vector<string> & argv)
+void DirectoryMemory::init()
{
- m_controller = NULL;
- for (vector<string>::const_iterator it = argv.begin(); it != argv.end(); it++) {
- if ( (*it) == "version" )
- m_version = atoi( (*(++it)).c_str() );
- else if ( (*it) == "size_mb" ) {
- m_size_bytes = atoi((*(++it)).c_str()) * static_cast<uint64>(1<<20);
- m_size_bits = log_int(m_size_bytes);
- } else if ( (*it) == "controller" ) {
- m_controller = RubySystem::getController((*(++it)));
- } else {
- cerr << "DirectoryMemory: Unkown config parameter: " << (*it) << endl;
- assert(0);
- }
- }
- assert(m_controller != NULL);
-
m_num_entries = m_size_bytes / RubySystem::getBlockSizeBytes();
m_entries = new Directory_Entry*[m_num_entries];
for (int i=0; i < m_num_entries; i++)
@@ -205,3 +193,8 @@ void DirectoryMemory::print(ostream& out) const
}
+DirectoryMemory *
+RubyDirectoryMemoryParams::create()
+{
+ return new DirectoryMemory(this);
+}
diff --git a/src/mem/ruby/system/DirectoryMemory.hh b/src/mem/ruby/system/DirectoryMemory.hh
index 09211fd83..1575187b0 100644
--- a/src/mem/ruby/system/DirectoryMemory.hh
+++ b/src/mem/ruby/system/DirectoryMemory.hh
@@ -43,14 +43,17 @@
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/system/MemoryVector.hh"
#include "mem/protocol/Directory_Entry.hh"
+#include "sim/sim_object.hh"
+#include "params/RubyDirectoryMemory.hh"
class AbstractController;
-class DirectoryMemory {
+class DirectoryMemory : public SimObject {
public:
// Constructors
- DirectoryMemory(const string & name);
- void init(const vector<string> & argv);
+ typedef RubyDirectoryMemoryParams Params;
+ DirectoryMemory(const Params *p);
+ void init();
// DirectoryMemory(int version);
// Destructor
diff --git a/src/mem/ruby/system/DirectoryMemory.py b/src/mem/ruby/system/DirectoryMemory.py
new file mode 100644
index 000000000..55c2d82bd
--- /dev/null
+++ b/src/mem/ruby/system/DirectoryMemory.py
@@ -0,0 +1,10 @@
+from m5.params import *
+from m5.proxy import *
+from m5.SimObject import SimObject
+
+class RubyDirectoryMemory(SimObject):
+ type = 'RubyDirectoryMemory'
+ cxx_class = 'DirectoryMemory'
+ version = Param.Int(0, "")
+ size_mb = Param.Int(1024, "")
+ controller = Param.RubyController(Parent.any, "")
diff --git a/src/mem/ruby/system/MemoryControl.cc b/src/mem/ruby/system/MemoryControl.cc
index 2ef7d8ffc..5a6c9e34c 100644
--- a/src/mem/ruby/system/MemoryControl.cc
+++ b/src/mem/ruby/system/MemoryControl.cc
@@ -151,61 +151,30 @@ ostream& operator<<(ostream& out, const MemoryControl& obj)
// ****************************************************************
// CONSTRUCTOR
-MemoryControl::MemoryControl(const string & name)
- : m_name(name)
+MemoryControl::MemoryControl(const Params *p)
+ : SimObject(p)
{
- m_name = name;
-// printf ("MemoryControl name is %s \n", m_name.c_str());
+ m_mem_bus_cycle_multiplier = p->mem_bus_cycle_multiplier;
+ m_banks_per_rank = p->banks_per_rank;
+ m_ranks_per_dimm = p->ranks_per_dimm;
+ m_dimms_per_channel = p->dimms_per_channel;
+ m_bank_bit_0 = p->bank_bit_0;
+ m_rank_bit_0 = p->rank_bit_0;
+ m_dimm_bit_0 = p->dimm_bit_0;
+ m_bank_queue_size = p->bank_queue_size;
+ m_bank_busy_time = p->bank_busy_time;
+ m_rank_rank_delay = p->rank_rank_delay;
+ m_read_write_delay = p->read_write_delay;
+ m_basic_bus_busy_time = p->basic_bus_busy_time;
+ m_mem_ctl_latency = p->mem_ctl_latency;
+ m_refresh_period = p->refresh_period;
+ m_tFaw = p->tFaw;
+ m_mem_random_arbitrate = p->mem_random_arbitrate;
+ m_mem_fixed_delay = p->mem_fixed_delay;
}
-void MemoryControl::init(const vector<string> & argv)
+void MemoryControl::init()
{
-
- for (vector<string>::const_iterator it = argv.begin(); it != argv.end(); it++) {
- if ( (*it) == "version" )
- m_version = atoi( (*(++it)).c_str() );
- else if ( (*it) == "mem_bus_cycle_multiplier" ) {
- m_mem_bus_cycle_multiplier = atoi((*(++it)).c_str());
- } else if ( (*it) == "banks_per_rank" ) {
- m_banks_per_rank = atoi((*(++it)).c_str());
- } else if ( (*it) == "ranks_per_dimm" ) {
- m_ranks_per_dimm = atoi((*(++it)).c_str());
- } else if ( (*it) == "dimms_per_channel" ) {
- m_dimms_per_channel = atoi((*(++it)).c_str());
- } else if ( (*it) == "bank_bit_0" ) {
- m_bank_bit_0 = atoi((*(++it)).c_str());
- } else if ( (*it) == "rank_bit_0" ) {
- m_rank_bit_0 = atoi((*(++it)).c_str());
- } else if ( (*it) == "dimm_bit_0" ) {
- m_dimm_bit_0 = atoi((*(++it)).c_str());
- } else if ( (*it) == "bank_queue_size" ) {
- m_bank_queue_size = atoi((*(++it)).c_str());
- } else if ( (*it) == "bank_busy_time" ) {
- m_bank_busy_time = atoi((*(++it)).c_str());
- } else if ( (*it) == "rank_rank_delay" ) {
- m_rank_rank_delay = atoi((*(++it)).c_str());
- } else if ( (*it) == "read_write_delay" ) {
- m_read_write_delay = atoi((*(++it)).c_str());
- } else if ( (*it) == "basic_bus_busy_time" ) {
- m_basic_bus_busy_time = atoi((*(++it)).c_str());
- } else if ( (*it) == "mem_ctl_latency" ) {
- m_mem_ctl_latency = atoi((*(++it)).c_str());
- } else if ( (*it) == "refresh_period" ) {
- m_refresh_period = atoi((*(++it)).c_str());
- } else if ( (*it) == "tFaw" ) {
- m_tFaw = atoi((*(++it)).c_str());
- } else if ( (*it) == "mem_random_arbitrate" ) {
- m_mem_random_arbitrate = atoi((*(++it)).c_str());
- } else if ( (*it) == "mem_fixed_delay" ) {
- m_mem_fixed_delay = atoi((*(++it)).c_str());
- }
-// } else
-// assert(0);
- }
-
-
-///////
- //m_version = version;
m_msg_counter = 0;
m_debug = 0;
@@ -351,7 +320,6 @@ void MemoryControl::print (ostream& out) const {
void MemoryControl::printConfig (ostream& out) {
- out << "Memory Control " << m_version << ":" << endl;
out << " Ruby cycles per memory cycle: " << m_mem_bus_cycle_multiplier << endl;
out << " Basic read latency: " << m_mem_ctl_latency << endl;
if (m_mem_fixed_delay) {
@@ -662,4 +630,9 @@ void MemoryControl::wakeup () {
}
}
+MemoryControl *
+RubyMemoryControlParams::create()
+{
+ return new MemoryControl(this);
+}
diff --git a/src/mem/ruby/system/MemoryControl.hh b/src/mem/ruby/system/MemoryControl.hh
index 3419f8c40..1570e81cd 100644
--- a/src/mem/ruby/system/MemoryControl.hh
+++ b/src/mem/ruby/system/MemoryControl.hh
@@ -51,6 +51,8 @@
#include "mem/protocol/MemoryMsg.hh"
#include "mem/ruby/common/Consumer.hh"
#include "mem/ruby/system/AbstractMemOrCache.hh"
+#include "sim/sim_object.hh"
+#include "params/RubyMemoryControl.hh"
#include <list>
@@ -62,12 +64,13 @@
class Consumer;
-class MemoryControl : public Consumer, public AbstractMemOrCache {
+class MemoryControl : public SimObject, public Consumer, public AbstractMemOrCache {
public:
// Constructors
- MemoryControl(const string & name);
- void init(const vector<string> & argv);
+ typedef RubyMemoryControlParams Params;
+ MemoryControl(const Params *p);
+ void init();
// Destructor
~MemoryControl ();
@@ -122,7 +125,6 @@ private:
Consumer* m_consumer_ptr; // Consumer to signal a wakeup()
string m_name;
string m_description;
- int m_version;
int m_msg_counter;
int m_awakened;
diff --git a/src/mem/ruby/system/MemoryControl.py b/src/mem/ruby/system/MemoryControl.py
new file mode 100644
index 000000000..6c8109728
--- /dev/null
+++ b/src/mem/ruby/system/MemoryControl.py
@@ -0,0 +1,23 @@
+from m5.params import *
+from m5.SimObject import SimObject
+
+class RubyMemoryControl(SimObject):
+ type = 'RubyMemoryControl'
+ cxx_class = 'MemoryControl'
+ mem_bus_cycle_multiplier = Param.Int(10, "");
+ banks_per_rank = Param.Int(8, "");
+ ranks_per_dimm = Param.Int(2, "");
+ dimms_per_channel = Param.Int(2, "");
+ bank_bit_0 = Param.Int(8, "");
+ rank_bit_0 = Param.Int(11, "");
+ dimm_bit_0 = Param.Int(12, "");
+ bank_queue_size = Param.Int(12, "");
+ bank_busy_time = Param.Int(11, "");
+ rank_rank_delay = Param.Int(1, "");
+ read_write_delay = Param.Int(2, "");
+ basic_bus_busy_time = Param.Int(2, "");
+ mem_ctl_latency = Param.Int(12, "");
+ refresh_period = Param.Int(1560, "");
+ tFaw = Param.Int(0, "");
+ mem_random_arbitrate = Param.Int(0, "");
+ mem_fixed_delay = Param.Int(0, "");
diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc
index 2a5c5f479..b83ba43e3 100644
--- a/src/mem/ruby/system/RubyPort.cc
+++ b/src/mem/ruby/system/RubyPort.cc
@@ -1,5 +1,57 @@
+/*
+ * Copyright (c) 2009 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "mem/physical.hh"
#include "mem/ruby/system/RubyPort.hh"
+#include "mem/ruby/slicc_interface/AbstractController.hh"
//void (*RubyPort::m_hit_callback)(int64_t) = NULL;
uint16_t RubyPort::m_num_ports = 0;
+
+RubyPort::RubyPort(const Params *p)
+ : MemObject(p)
+{
+ m_version = p->version;
+ assert(m_version != -1);
+ m_controller = p->controller;
+ assert(m_controller != NULL);
+
+ m_mandatory_q_ptr = m_controller->getMandatoryQueue();
+
+ m_port_id = m_num_ports++;
+ m_request_cnt = 0;
+ m_hit_callback = NULL;
+ assert(m_num_ports <= 2048); // see below for reason
+}
+
+Port *
+RubyPort::getPort(const std::string &if_name, int idx)
+{
+ return NULL;
+}
diff --git a/src/mem/ruby/system/RubyPort.hh b/src/mem/ruby/system/RubyPort.hh
index 2f391070f..20557669a 100644
--- a/src/mem/ruby/system/RubyPort.hh
+++ b/src/mem/ruby/system/RubyPort.hh
@@ -1,3 +1,32 @@
+
+/*
+ * Copyright (c) 2009 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
#ifndef RUBYPORT_H
#define RUBYPORT_H
@@ -5,20 +34,24 @@
#include <string>
#include <assert.h>
+#include "mem/mem_object.hh"
+#include "mem/tport.hh"
+
+#include "params/RubyPort.hh"
+
using namespace std;
-class RubyPort {
+class MessageBuffer;
+class AbstractController;
+
+class RubyPort : public MemObject {
public:
- RubyPort(const string & name)
- : m_name(name)
- {
- m_port_id = m_num_ports++;
- m_request_cnt = 0;
- m_hit_callback = NULL;
- assert(m_num_ports <= 2048); // see below for reason
- }
+ typedef RubyPortParams Params;
+ RubyPort(const Params *p);
virtual ~RubyPort() {}
+ Port *getPort(const std::string &if_name, int idx);
+
virtual int64_t makeRequest(const RubyRequest & request) = 0;
void registerHitCallback(void (*hit_callback)(int64_t request_id)) {
@@ -51,6 +84,10 @@ protected:
return id;
}
+ int m_version;
+ AbstractController* m_controller;
+ MessageBuffer* m_mandatory_q_ptr;
+
private:
static uint16_t m_num_ports;
uint16_t m_port_id;
diff --git a/src/mem/ruby/system/RubySystem.py b/src/mem/ruby/system/RubySystem.py
new file mode 100644
index 000000000..2c1d3d789
--- /dev/null
+++ b/src/mem/ruby/system/RubySystem.py
@@ -0,0 +1,18 @@
+from m5.params import *
+from m5.SimObject import SimObject
+
+class RubySystem(SimObject):
+ type = 'RubySystem'
+ random_seed = Param.Int(1234, "random seed used by the simulation");
+ randomization = Param.Bool(False,
+ "insert random delays on message enqueue times");
+ tech_nm = Param.Int(45,
+ "device size used to calculate latency and area information");
+ freq_mhz = Param.Int(3000, "default frequency for the system");
+ block_size_bytes = Param.Int(64,
+ "default cache block size; must be a power of two");
+ network = Param.RubyNetwork("")
+ debug = Param.RubyDebug("the default debug object")
+ profiler = Param.RubyProfiler("");
+ tracer = Param.RubyTracer("");
+
diff --git a/src/mem/ruby/system/SConscript b/src/mem/ruby/system/SConscript
index 4ca1af114..bd721e83d 100644
--- a/src/mem/ruby/system/SConscript
+++ b/src/mem/ruby/system/SConscript
@@ -33,6 +33,12 @@ Import('*')
if not env['RUBY']:
Return()
+SimObject('Cache.py')
+SimObject('Sequencer.py')
+SimObject('DirectoryMemory.py')
+SimObject('MemoryControl.py')
+SimObject('RubySystem.py')
+
Source('DMASequencer.cc')
Source('DirectoryMemory.cc')
Source('CacheMemory.cc')
diff --git a/src/mem/ruby/system/Sequencer.cc b/src/mem/ruby/system/Sequencer.cc
index b4716c346..ad219eab3 100644
--- a/src/mem/ruby/system/Sequencer.cc
+++ b/src/mem/ruby/system/Sequencer.cc
@@ -42,55 +42,44 @@
#include "mem/ruby/buffers/MessageBuffer.hh"
#include "mem/ruby/slicc_interface/AbstractController.hh"
+#include "params/RubySequencer.hh"
+
//Sequencer::Sequencer(int core_id, MessageBuffer* mandatory_q)
#define LLSC_FAIL -2
long int already = 0;
-Sequencer::Sequencer(const string & name)
- :RubyPort(name)
+
+Sequencer *
+RubySequencerParams::create()
{
- m_store_waiting_on_load_cycles = 0;
- m_store_waiting_on_store_cycles = 0;
- m_load_waiting_on_store_cycles = 0;
- m_load_waiting_on_load_cycles = 0;
+ return new Sequencer(this);
}
-
-void Sequencer::init(const vector<string> & argv)
+
+Sequencer::Sequencer(const Params *p)
+ : RubyPort(p)
{
- m_deadlock_check_scheduled = false;
- m_outstanding_count = 0;
-
- m_max_outstanding_requests = 0;
- m_deadlock_threshold = 0;
- m_version = -1;
- m_instCache_ptr = NULL;
- m_dataCache_ptr = NULL;
- m_controller = NULL;
- for (size_t i=0; i<argv.size(); i+=2) {
- if ( argv[i] == "controller") {
- m_controller = RubySystem::getController(argv[i+1]); // args[i] = "L1Cache"
- m_mandatory_q_ptr = m_controller->getMandatoryQueue();
- } else if ( argv[i] == "icache")
- m_instCache_ptr = RubySystem::getCache(argv[i+1]);
- else if ( argv[i] == "dcache")
- m_dataCache_ptr = RubySystem::getCache(argv[i+1]);
- else if ( argv[i] == "version")
- m_version = atoi(argv[i+1].c_str());
- else if ( argv[i] == "max_outstanding_requests")
- m_max_outstanding_requests = atoi(argv[i+1].c_str());
- else if ( argv[i] == "deadlock_threshold")
- m_deadlock_threshold = atoi(argv[i+1].c_str());
- else {
- cerr << "WARNING: Sequencer: Unkown configuration parameter: " << argv[i] << endl;
- assert(false);
- }
- }
- assert(m_max_outstanding_requests > 0);
- assert(m_deadlock_threshold > 0);
- assert(m_version > -1);
- assert(m_instCache_ptr != NULL);
- assert(m_dataCache_ptr != NULL);
- assert(m_controller != NULL);
+ m_store_waiting_on_load_cycles = 0;
+ m_store_waiting_on_store_cycles = 0;
+ m_load_waiting_on_store_cycles = 0;
+ m_load_waiting_on_load_cycles = 0;
+
+ m_deadlock_check_scheduled = false;
+ m_outstanding_count = 0;
+
+ m_max_outstanding_requests = 0;
+ m_deadlock_threshold = 0;
+ m_instCache_ptr = NULL;
+ m_dataCache_ptr = NULL;
+
+ m_instCache_ptr = p->icache;
+ m_dataCache_ptr = p->dcache;
+ m_max_outstanding_requests = p->max_outstanding_requests;
+ m_deadlock_threshold = p->deadlock_threshold;
+
+ assert(m_max_outstanding_requests > 0);
+ assert(m_deadlock_threshold > 0);
+ assert(m_instCache_ptr != NULL);
+ assert(m_dataCache_ptr != NULL);
}
Sequencer::~Sequencer() {
@@ -495,7 +484,7 @@ void Sequencer::issueRequest(const RubyRequest& request) {
// Send the message to the cache controller
assert(latency > 0);
-
+ assert(m_mandatory_q_ptr != NULL);
m_mandatory_q_ptr->enqueue(msg, latency);
}
/*
diff --git a/src/mem/ruby/system/Sequencer.hh b/src/mem/ruby/system/Sequencer.hh
index 1621bbbdc..d2dc5bbb3 100644
--- a/src/mem/ruby/system/Sequencer.hh
+++ b/src/mem/ruby/system/Sequencer.hh
@@ -51,7 +51,8 @@ class DataBlock;
class CacheMsg;
class MachineID;
class CacheMemory;
-class AbstractController;
+
+class RubySequencerParams;
struct SequencerRequest {
RubyRequest ruby_request;
@@ -65,11 +66,11 @@ struct SequencerRequest {
std::ostream& operator<<(std::ostream& out, const SequencerRequest& obj);
-class Sequencer : public Consumer, public RubyPort {
+class Sequencer : public RubyPort, public Consumer {
public:
+ typedef RubySequencerParams Params;
// Constructors
- Sequencer(const string & name);
- void init(const vector<string> & argv);
+ Sequencer(const Params *);
// Destructor
~Sequencer();
@@ -114,13 +115,10 @@ private:
int m_max_outstanding_requests;
int m_deadlock_threshold;
- AbstractController* m_controller;
- MessageBuffer* m_mandatory_q_ptr;
CacheMemory* m_dataCache_ptr;
CacheMemory* m_instCache_ptr;
// indicates what processor on the chip this sequencer is associated with
- int m_version;
int m_controller_type;
Map<Address, SequencerRequest*> m_writeRequestTable;
diff --git a/src/mem/ruby/system/Sequencer.py b/src/mem/ruby/system/Sequencer.py
new file mode 100644
index 000000000..add5a06a1
--- /dev/null
+++ b/src/mem/ruby/system/Sequencer.py
@@ -0,0 +1,23 @@
+from m5.params import *
+from MemObject import MemObject
+
+class RubyPort(MemObject):
+ type = 'RubyPort'
+ abstract = True
+ port = VectorPort("M5 port")
+ controller = Param.RubyController("")
+ version = Param.Int(0, "")
+
+class RubySequencer(RubyPort):
+ type = 'RubySequencer'
+ cxx_class = 'Sequencer'
+ icache = Param.RubyCache("")
+ dcache = Param.RubyCache("")
+ max_outstanding_requests = Param.Int(16,
+ "max requests (incl. prefetches) outstanding")
+ deadlock_threshold = Param.Int(500000,
+ "max outstanding cycles for a request before deadlock/livelock declared")
+ funcmem_port = Port("port to functional memory")
+
+class DMASequencer(RubyPort):
+ type = 'DMASequencer'
diff --git a/src/mem/ruby/system/System.cc b/src/mem/ruby/system/System.cc
index 4ce919618..0f5cae026 100644
--- a/src/mem/ruby/system/System.cc
+++ b/src/mem/ruby/system/System.cc
@@ -47,15 +47,14 @@
#include "mem/ruby/system/Sequencer.hh"
#include "mem/ruby/system/DMASequencer.hh"
#include "mem/ruby/system/MemoryVector.hh"
-#include "mem/protocol/ControllerFactory.hh"
#include "mem/ruby/slicc_interface/AbstractController.hh"
#include "mem/ruby/system/CacheMemory.hh"
#include "mem/ruby/system/DirectoryMemory.hh"
#include "mem/ruby/network/simple/Topology.hh"
#include "mem/ruby/network/simple/SimpleNetwork.hh"
#include "mem/ruby/system/RubyPort.hh"
-#include "mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh"
-#include "mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh"
+//#include "mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh"
+//#include "mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh"
#include "mem/ruby/system/MemoryControl.hh"
int RubySystem::m_random_seed;
@@ -84,180 +83,32 @@ Tracer* RubySystem::m_tracer_ptr;
MemoryVector* RubySystem::m_mem_vec_ptr;
-RubySystem* RubySystem::create(const vector <RubyObjConf> & sys_conf)
+RubySystem::RubySystem(const Params *p)
+ : SimObject(p)
{
- if (g_system_ptr == NULL)
- return new RubySystem(sys_conf);
- return g_system_ptr;
+ 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_tech_nm = p->tech_nm;
+ m_freq_mhz = p->freq_mhz;
+ m_block_size_bytes = p->block_size_bytes;
+ assert(is_power_of_2(m_block_size_bytes));
+ m_block_size_bits = log_int(m_block_size_bytes);
+ m_network_ptr = p->network;
+ g_debug_ptr = p->debug;
+ m_profiler_ptr = p->profiler;
+ m_tracer_ptr = p->tracer;
+
+ g_system_ptr = this;
+ m_mem_vec_ptr = new MemoryVector;
}
-void RubySystem::init(const vector<string> & argv)
-{
- for (size_t i=0; i < argv.size(); i+=2) {
- if (argv[i] == "random_seed") {
- m_random_seed = atoi(argv[i+1].c_str());
- srandom(m_random_seed);
- } else if (argv[i] == "randomization") {
- m_randomization = string_to_bool(argv[i+1]);
- } else if (argv[i] == "tech_nm") {
- m_tech_nm = atoi(argv[i+1].c_str());
- } else if (argv[i] == "freq_mhz") {
- m_freq_mhz = atoi(argv[i+1].c_str());
- } else if (argv[i] == "block_size_bytes") {
- m_block_size_bytes = atoi(argv[i+1].c_str());
- assert(is_power_of_2(m_block_size_bytes));
- m_block_size_bits = log_int(m_block_size_bytes);
- } else if (argv[i] == "debug") {
-
- } else if (argv[i] == "tracer") {
-
- } else if (argv[i] == "profiler") {
-
- // } else if (argv[i] == "MI_example") {
-
- } else {
- cerr << "Error: Unknown RubySystem config parameter -- " << argv[i] << endl;
- assert(0);
- }
- }
-}
-RubySystem::RubySystem(const vector <RubyObjConf> & sys_conf)
+void RubySystem::init()
{
- // DEBUG_MSG(SYSTEM_COMP, MedPrio,"initializing");
-
- for (size_t i=0;i<sys_conf.size(); i++) {
- const string & type = sys_conf[i].type;
- const string & name = sys_conf[i].name;
- const vector<string> & argv = sys_conf[i].argv;
- if (type == "System") {
- init(argv); // initialize system-wide variables before doing anything else!
- } else if (type == "Debug") {
- g_debug_ptr = new Debug(name, argv);
- }
- }
-
- assert( g_debug_ptr != NULL);
- g_eventQueue_ptr = new RubyEventQueue;
- g_system_ptr = this;
- m_mem_vec_ptr = new MemoryVector;
-
- /* object contruction is broken into two steps (Constructor and init) to avoid cyclic dependencies
- * e.g. a sequencer needs a pointer to a controller and a controller needs a pointer to a sequencer
- */
-
- vector<string> memory_control_names;
-
- for (size_t i=0;i<sys_conf.size(); i++) {
- const string & type = sys_conf[i].type;
- const string & name = sys_conf[i].name;
- if (type == "System" || type == "Debug")
- continue;
- else if (type == "SetAssociativeCache")
- m_caches[name] = new CacheMemory(name);
- else if (type == "DirectoryMemory")
- m_directories[name] = new DirectoryMemory(name);
- else if (type == "Sequencer") {
- m_sequencers[name] = new Sequencer(name);
- m_ports[name] = m_sequencers[name];
- } else if (type == "DMASequencer") {
- m_dma_sequencers[name] = new DMASequencer(name);
- m_ports[name] = m_dma_sequencers[name];
- } else if (type == "Topology") {
- assert(m_topologies.size() == 0); // only one toplogy at a time is supported right now
- m_topologies[name] = new Topology(name);
- } else if (type == "SimpleNetwork") {
- assert(m_network_ptr == NULL); // only one network at a time is supported right now
- m_network_ptr = new SimpleNetwork(name);
- } else if (type.find("generated") == 0) {
- string controller_type = type.substr(10);
- m_controllers[name] = ControllerFactory::createController(controller_type, name);
-// printf ("ss: generated %s \n", controller_type);
-//added by SS
- } else if (type == "Tracer") {
- //m_tracers[name] = new Tracer(name);
- m_tracer_ptr = new Tracer(name);
- } else if (type == "Profiler") {
- m_profiler_ptr = new Profiler(name);
- } else if (type == "GarnetNetwork") {
- assert(m_network_ptr == NULL); // only one network at a time is supported right now
- m_network_ptr = new GarnetNetwork(name);
- } else if (type == "GarnetNetwork_d") {
- assert(m_network_ptr == NULL); // only one network at a time is supported right now
- m_network_ptr = new GarnetNetwork_d(name);
- } else if (type == "MemoryControl") {
- m_memorycontrols[name] = new MemoryControl(name);
- memory_control_names.push_back (name);
- } else {
- cerr << "Error: Unknown object type -- " << type << endl;
- assert(0);
- }
- }
-
- for (size_t i=0;i<sys_conf.size(); i++) {
- string type = sys_conf[i].type;
- string name = sys_conf[i].name;
- const vector<string> & argv = sys_conf[i].argv;
- if (type == "Topology")
- m_topologies[name]->init(argv);
- }
-
- for (size_t i=0;i<sys_conf.size(); i++) {
- string type = sys_conf[i].type;
- string name = sys_conf[i].name;
- const vector<string> & argv = sys_conf[i].argv;
- if (type == "SimpleNetwork" || type == "GarnetNetwork" || type == "GarnetNetwork_d"){
- m_network_ptr->init(argv);
- }
- }
-
- for (size_t i=0;i<sys_conf.size(); i++) {
- string type = sys_conf[i].type;
- string name = sys_conf[i].name;
- const vector<string> & argv = sys_conf[i].argv;
- if (type == "MemoryControl" ){
- m_memorycontrols[name]->init(argv);
- }
- }
-
- for (size_t i=0;i<sys_conf.size(); i++) {
- string type = sys_conf[i].type;
- string name = sys_conf[i].name;
- const vector<string> & argv = sys_conf[i].argv;
- if (type == "System" || type == "Debug")
- continue;
- else if (type == "SetAssociativeCache")
- m_caches[name]->init(argv);
- else if (type == "DirectoryMemory")
- m_directories[name]->init(argv);
- else if (type == "MemoryControl")
- continue;
- else if (type == "Sequencer")
- m_sequencers[name]->init(argv);
- else if (type == "DMASequencer")
- m_dma_sequencers[name]->init(argv);
- else if (type == "Topology")
- continue;
- else if (type == "SimpleNetwork" || type == "GarnetNetwork" || type == "GarnetNetwork_d")
- continue;
- else if (type.find("generated") == 0) {
- string controller_type = type.substr(11);
- m_controllers[name]->init(m_network_ptr, argv);
- }
-//added by SS
- else if (type == "Tracer")
- //m_tracers[name]->init(argv);
- m_tracer_ptr->init(argv);
- else if (type == "Profiler")
- m_profiler_ptr->init(argv, memory_control_names);
-// else if (type == "MI_example"){
-// }
- else
- assert(0);
- }
-
-// m_profiler_ptr = new Profiler;
-
// calculate system-wide parameters
m_memory_size_bytes = 0;
DirectoryMemory* prev = NULL;
@@ -270,12 +121,9 @@ RubySystem::RubySystem(const vector <RubyObjConf> & sys_conf)
}
m_mem_vec_ptr->setSize(m_memory_size_bytes);
m_memory_size_bits = log_int(m_memory_size_bytes);
-
-// m_tracer_ptr = new Tracer;
- DEBUG_MSG(SYSTEM_COMP, MedPrio,"finished initializing");
- DEBUG_NEWLINE(SYSTEM_COMP, MedPrio);
}
+
RubySystem::~RubySystem()
{
@@ -423,5 +271,8 @@ void RubySystem::checkGlobalCoherenceInvariant(const Address& addr ) {
#endif
-
-
+RubySystem *
+RubySystemParams::create()
+{
+ return new RubySystem(this);
+}
diff --git a/src/mem/ruby/system/System.hh b/src/mem/ruby/system/System.hh
index 1d36de878..6f0261888 100644
--- a/src/mem/ruby/system/System.hh
+++ b/src/mem/ruby/system/System.hh
@@ -46,6 +46,8 @@
#include "mem/gems_common/Vector.hh"
#include "mem/ruby/eventqueue/RubyEventQueue.hh"
#include <map>
+#include "sim/sim_object.hh"
+#include "params/RubySystem.hh"
class Profiler;
class Network;
@@ -84,9 +86,10 @@ struct RubyObjConf {
{}
};
-class RubySystem {
+class RubySystem : public SimObject {
public:
- static RubySystem* create(const vector <RubyObjConf> & sys_conf);
+ typedef RubySystemParams Params;
+ RubySystem(const Params *p);
// Destructor
~RubySystem();
@@ -152,7 +155,7 @@ private:
RubySystem(const RubySystem& obj);
RubySystem& operator=(const RubySystem& obj);
- void init(const vector<string> & argv);
+ void init();
static void printSystemConfig(ostream& out);
@@ -181,6 +184,7 @@ private:
//added by SS
//static map< string, Tracer* > m_tracers;
+public:
static Profiler* m_profiler_ptr;
static Tracer* m_tracer_ptr;
static MemoryVector* m_mem_vec_ptr;