diff options
Diffstat (limited to 'src/mem/ruby/system')
-rw-r--r-- | src/mem/ruby/system/Cache.py | 12 | ||||
-rw-r--r-- | src/mem/ruby/system/CacheMemory.cc | 59 | ||||
-rw-r--r-- | src/mem/ruby/system/CacheMemory.hh | 11 | ||||
-rw-r--r-- | src/mem/ruby/system/DMASequencer.cc | 25 | ||||
-rw-r--r-- | src/mem/ruby/system/DMASequencer.hh | 13 | ||||
-rw-r--r-- | src/mem/ruby/system/DirectoryMemory.cc | 31 | ||||
-rw-r--r-- | src/mem/ruby/system/DirectoryMemory.hh | 9 | ||||
-rw-r--r-- | src/mem/ruby/system/DirectoryMemory.py | 10 | ||||
-rw-r--r-- | src/mem/ruby/system/MemoryControl.cc | 77 | ||||
-rw-r--r-- | src/mem/ruby/system/MemoryControl.hh | 10 | ||||
-rw-r--r-- | src/mem/ruby/system/MemoryControl.py | 23 | ||||
-rw-r--r-- | src/mem/ruby/system/RubyPort.cc | 52 | ||||
-rw-r--r-- | src/mem/ruby/system/RubyPort.hh | 55 | ||||
-rw-r--r-- | src/mem/ruby/system/RubySystem.py | 18 | ||||
-rw-r--r-- | src/mem/ruby/system/SConscript | 6 | ||||
-rw-r--r-- | src/mem/ruby/system/Sequencer.cc | 75 | ||||
-rw-r--r-- | src/mem/ruby/system/Sequencer.hh | 12 | ||||
-rw-r--r-- | src/mem/ruby/system/Sequencer.py | 23 | ||||
-rw-r--r-- | src/mem/ruby/system/System.cc | 207 | ||||
-rw-r--r-- | src/mem/ruby/system/System.hh | 10 |
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; |