diff -r 94383c5124d2 -r 9126cd4e98b0 configs/ruby/Ruby.py --- a/configs/ruby/Ruby.py Mon Nov 19 11:21:09 2012 -0500 +++ b/configs/ruby/Ruby.py Wed Dec 05 02:30:52 2012 -0500 @@ -57,6 +57,8 @@ help="'fixed'|'flexible'") parser.add_option("--network-fault-model", action="store_true", default=False, help="enable network fault model: see src/mem/ruby/network/fault_model/") + parser.add_option("--tile-width", type="float", default=1e-3, + help="the width of a tile in meter, which is the link length between adjacent tiles") # ruby mapping options parser.add_option("--numa-high-bit", type="int", default=0, @@ -153,14 +155,18 @@ net_topology.int_links = int_links net_topology.ext_links = ext_links + # Initialize DSENT interface + dsent_interface = DSENTInterface() if options.network_fault_model: assert(options.garnet_network == "fixed") fault_model = FaultModel() network = NetworkClass(ruby_system = ruby, topology = net_topology,\ - enable_fault_model=True, fault_model = fault_model) + enable_fault_model = True, fault_model = fault_model,\ + dsent_interface = dsent_interface) else: - network = NetworkClass(ruby_system = ruby, topology = net_topology) + network = NetworkClass(ruby_system = ruby, topology = net_topology,\ + dsent_interface = dsent_interface) # # Loop through the directory controlers. diff -r 94383c5124d2 -r 9126cd4e98b0 configs/topologies/Mesh.py --- a/configs/topologies/Mesh.py Mon Nov 19 11:21:09 2012 -0500 +++ b/configs/topologies/Mesh.py Wed Dec 05 02:30:52 2012 -0500 @@ -44,6 +44,7 @@ num_routers = options.num_cpus num_rows = options.mesh_rows + tile_width = options.tile_width # There must be an evenly divisible number of cntrls to routers # Also, obviously the number or rows must be <= the number of routers @@ -69,25 +70,30 @@ remainder_nodes.append(nodes[node_index]) # Connect each node to the appropriate router + # Assume the link length == 0 ext_links = [] for (i, n) in enumerate(network_nodes): cntrl_level, router_id = divmod(i, num_routers) assert(cntrl_level < cntrls_per_router) ext_links.append(ExtLink(link_id=link_count, ext_node=n, - int_node=routers[router_id])) + int_node=routers[router_id], + length=0.0)) link_count += 1 # Connect the remainding nodes to router 0. These should only be # DMA nodes. + # Assume the link length == 0 for (i, node) in enumerate(remainder_nodes): assert(node.type == 'DMA_Controller') assert(i < remainder) ext_links.append(ExtLink(link_id=link_count, ext_node=node, - int_node=routers[0])) + int_node=routers[0], + length=0.0)) link_count += 1 # Create the mesh links. First row (east-west) links then column # (north-south) links + # Assume the link length == tile_width int_links = [] for row in xrange(num_rows): for col in xrange(num_columns): @@ -97,7 +103,8 @@ int_links.append(IntLink(link_id=link_count, node_a=routers[east_id], node_b=routers[west_id], - weight=1)) + weight=1, + length=tile_width)) link_count += 1 for col in xrange(num_columns): @@ -108,7 +115,8 @@ int_links.append(IntLink(link_id=link_count, node_a=routers[north_id], node_b=routers[south_id], - weight=2)) + weight=2, + length=tile_width)) link_count += 1 return routers, int_links, ext_links diff -r 94383c5124d2 -r 9126cd4e98b0 configs/topologies/MeshDirCorners.py --- a/configs/topologies/MeshDirCorners.py Mon Nov 19 11:21:09 2012 -0500 +++ b/configs/topologies/MeshDirCorners.py Wed Dec 05 02:30:52 2012 -0500 @@ -47,6 +47,7 @@ num_routers = options.num_cpus num_rows = options.mesh_rows + tile_width = options.tile_width # First determine which nodes are cache cntrls vs. dirs vs. dma cache_nodes = [] @@ -79,35 +80,45 @@ link_count = 0 # Connect each cache controller to the appropriate router + # Assume link length == 0.0 ext_links = [] for (i, n) in enumerate(cache_nodes): cntrl_level, router_id = divmod(i, num_routers) assert(cntrl_level < caches_per_router) ext_links.append(ExtLink(link_id=link_count, ext_node=n, - int_node=routers[router_id])) + int_node=routers[router_id], + length=0.0)) link_count += 1 # Connect the dir nodes to the corners. + # Assume link length == 0.0 ext_links.append(ExtLink(link_id=link_count, ext_node=dir_nodes[0], - int_node=routers[0])) + int_node=routers[0], + length=0.0)) link_count += 1 ext_links.append(ExtLink(link_id=link_count, ext_node=dir_nodes[1], - int_node=routers[num_columns - 1])) + int_node=routers[num_columns - 1], + length=0.0)) link_count += 1 ext_links.append(ExtLink(link_id=link_count, ext_node=dir_nodes[2], - int_node=routers[num_routers - num_columns])) + int_node=routers[num_routers - num_columns], + length=0.0)) link_count += 1 ext_links.append(ExtLink(link_id=link_count, ext_node=dir_nodes[3], - int_node=routers[num_routers - 1])) + int_node=routers[num_routers - 1], + length=0.0)) link_count += 1 # Connect the dma nodes to router 0. These should only be DMA nodes. + # Assume link length == 0.0 for (i, node) in enumerate(dma_nodes): assert(node.type == 'DMA_Controller') - ext_links.append(ExtLink(link_id=link_count, ext_node=node, int_node=routers[0])) + ext_links.append(ExtLink(link_id=link_count, ext_node=node, int_node=routers[0], + length=0.0)) # Create the mesh links. First row (east-west) links then column # (north-south) links + # Assume link length == tile_width int_links = [] for row in xrange(num_rows): for col in xrange(num_columns): @@ -117,7 +128,8 @@ int_links.append(IntLink(link_id=link_count, node_a=routers[east_id], node_b=routers[west_id], - weight=1)) + weight=1, + length=tile_width)) link_count += 1 for col in xrange(num_columns): @@ -128,7 +140,8 @@ int_links.append(IntLink(link_id=link_count, node_a=routers[north_id], node_b=routers[south_id], - weight=2)) + weight=2, + length=tile_width)) link_count += 1 return routers, int_links, ext_links diff -r 94383c5124d2 -r 9126cd4e98b0 configs/topologies/Torus.py --- a/configs/topologies/Torus.py Mon Nov 19 11:21:09 2012 -0500 +++ b/configs/topologies/Torus.py Wed Dec 05 02:30:52 2012 -0500 @@ -49,6 +49,7 @@ num_routers = options.num_cpus num_rows = options.mesh_rows + tile_width = options.tile_width # There must be an evenly divisible number of cntrls to routers # Also, obviously the number or rows must be <= the number of routers @@ -74,26 +75,31 @@ remainder_nodes.append(nodes[node_index]) # Connect each node to the appropriate router + # Assume link length == 0.0 ext_links = [] for (i, n) in enumerate(network_nodes): cntrl_level, router_id = divmod(i, num_routers) assert(cntrl_level < cntrls_per_router) ext_links.append(ExtLink(link_id=link_count, ext_node=n, - int_node=routers[router_id])) + int_node=routers[router_id], + length=0.0)) link_count += 1 # Connect the remainding nodes to router 0. These should only be # DMA nodes. + # Assume link length == 0.0 for (i, node) in enumerate(remainder_nodes): assert(node.type == 'DMA_Controller') assert(i < remainder) ext_links.append(ExtLink(link_id=link_count, ext_node=node, - int_node=routers[0])) + int_node=routers[0], + length=0.0)) link_count += 1 # Create the torus links. First row (east-west) links then column # (north-south) links # column links are given higher weights to implement XY routing + # Assume link length == (2.0 * tile_width) int_links = [] for row in xrange(num_rows): for col in xrange(num_columns): @@ -106,7 +112,8 @@ node_a=routers[east_id], node_b=routers[west_id], latency=2, - weight=1)) + weight=1, + length=(2.0*tile_width))) link_count += 1 for col in xrange(num_columns): @@ -120,7 +127,8 @@ node_a=routers[north_id], node_b=routers[south_id], latency=2, - weight=2)) + weight=2, + length=(2.0*tile_width))) link_count += 1 return routers, int_links, ext_links diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/BasicLink.py --- a/src/mem/ruby/network/BasicLink.py Mon Nov 19 11:21:09 2012 -0500 +++ b/src/mem/ruby/network/BasicLink.py Wed Dec 05 02:30:52 2012 -0500 @@ -41,6 +41,9 @@ # with regard to the simple network. bandwidth_factor = Param.Int("generic bandwidth factor, usually in bytes") weight = Param.Int(1, "used to restrict routing in shortest path analysis") + # The length of the link in meter. The actual length is specified in the + # topology file. + length = Param.Float(1e-3, "length") class BasicExtLink(BasicLink): type = 'BasicExtLink' diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/Network.py --- a/src/mem/ruby/network/Network.py Mon Nov 19 11:21:09 2012 -0500 +++ b/src/mem/ruby/network/Network.py Wed Dec 05 02:30:52 2012 -0500 @@ -51,3 +51,4 @@ topology = Param.Topology(""); control_msg_size = Param.Int(8, ""); ruby_system = Param.RubySystem(""); + dsent_interface = Param.DSENTInterface(NULL, "DSENT interface"); diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/DSENTElectricalLink.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/DSENTElectricalLink.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENTElectricalLink_H__ +#define __DSENTElectricalLink_H__ + +#include "mem/ruby/network/dsent/Type.hh" +#include + +namespace dsent_contrib +{ + class DSENTInterface; + + // This class is responsible for calling DSENT for a repeated electrical link + class DSENTElectricalLink + { + public: + // Create a DSENT run for a link with these parameters + DSENTElectricalLink(float frequency_, double link_len_, unsigned int flit_width_, const DSENTInterface* dsent_interface_); + // Use this constructor if the frequency is set in the DSENTInterface + DSENTElectricalLink(double link_len_, unsigned int flit_width_, const DSENTInterface* dsent_interface_); + ~DSENTElectricalLink(); + + public: + // Get clock frequency + inline double get_frequency() const { return m_frequency_; } + + // Calculate dynamic energy consumed + inline double calc_dynamic_energy(unsigned int num_flits_) const { return (num_flits_ * m_dynamic_energy_per_flit_); } + // Get the static power consumption + inline double get_static_power() const { return m_static_power_; } + // Print information + void print() const; + + private: + // Helper function that actually calls DSENT + void init(float frequency_, double link_len_, unsigned int flit_width_, const DSENTInterface* dsent_interface_); + + private: + // User-defined clock frequency + double m_frequency_; + // Energy dissipated per flit + double m_dynamic_energy_per_flit_; + // Static power dissipation + double m_static_power_; + }; +} + +#endif + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/DSENTElectricalLink.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/DSENTElectricalLink.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/DSENTElectricalLink.hh" +#include "mem/ruby/network/dsent/DSENTInterface.hh" +#include "mem/ruby/network/dsent/dsent-core/libutil/String.hh" + +#include +#include + +using namespace std; +using namespace LibUtil; + +namespace dsent_contrib +{ + DSENTElectricalLink::DSENTElectricalLink(float frequency_, double link_len_, unsigned int flit_width_, const DSENTInterface* dsent_interface_) + { + init(frequency_, link_len_, flit_width_, dsent_interface_); + } + + DSENTElectricalLink::DSENTElectricalLink(double link_len_, unsigned int flit_width_, const DSENTInterface* dsent_interface_) + { + init(dsent_interface_->get_frequency(), link_len_, flit_width_, dsent_interface_); + } + + DSENTElectricalLink::~DSENTElectricalLink() + {} + + void DSENTElectricalLink::init(float frequency_, double link_len_, unsigned int flit_width_, const DSENTInterface* dsent_interface_) + { + assert(frequency_ > 0); + assert(link_len_ >= 0); + assert(flit_width_ > 0); + + // Create DSENT evaluate + vector eval = vector(); + // Create DSENT overwrites vector + vector overwrites = vector(); + // DSENT outputs + vector outputs; + + // Create evaluate String + eval.push_back("$(Energy>>RepeatedLink:Send)"); + eval.push_back("$(NddPower>>RepeatedLink:Leakage)"); + // Create overwrites + overwrites = dsent_interface_->get_link_cfg(); + overwrites.push_back(DSENTInterface::Overwrite("Delay", String(1.0 / frequency_))); + overwrites.push_back(DSENTInterface::Overwrite("WireLength", String(link_len_))); + overwrites.push_back(DSENTInterface::Overwrite("NumberBits", String(flit_width_))); + + // Run DSENT + //outputs = dsent_interface_->run_dsent(dsent_interface_->get_el_link_cfg_file_path(), eval, overwrites); + outputs = dsent_interface_->run_dsent("", eval, overwrites); + + // Check to make sure we get exactly 2 outputs + assert(outputs.size() == 2); + + // Store outputs + m_frequency_ = frequency_; + m_dynamic_energy_per_flit_ = outputs[0]; + m_static_power_ = outputs[1]; + + return; + } + + void DSENTElectricalLink::print() const + { + cout << "Link - Dynamic Energy Per Flit = " << calc_dynamic_energy(1) << endl; + cout << "Link - Static Power = " << get_static_power() << endl; + return; + } +} + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/DSENTInterface.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/DSENTInterface.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENTCONFIG_H__ +#define __DSENTCONFIG_H__ + +// C++ includes +#include +#include + +// GEM5 includes +#include "params/DSENTInterface.hh" +#include "sim/sim_object.hh" + +// DSENT includes +#include "mem/ruby/network/dsent/Type.hh" + +namespace dsent_contrib +{ + // This class contains the file locations of DSENT config files and some helpers + // used for getting data in/out of DSENT. Maybe other stuff will be added if the + // need should arise + class DSENTInterface : public SimObject + { + public: + typedef DSENTInterfaceParams Params; + + public: + class Overwrite + { + public: + Overwrite(const String& var_, const String& val_); + ~Overwrite(); + + public: + inline String get_string() const { return (get_var() + "=" + get_val()); } + inline const String& get_var() const { return m_var_; } + inline const String& get_val() const { return m_val_; } + + private: + String m_var_; + String m_val_; + }; + + public: + DSENTInterface(const String& dsent_path_, unsigned int tech_node_); + DSENTInterface(const Params* p_); + ~DSENTInterface(); + + public: + // Allocate/release singletons + static void allocate(const string& dsent_path_, unsigned int tech_node_); + static void release(); + static DSENTInterface* getSingleton(); + + // Get the file name of the config files used for various models + inline const String& get_el_link_cfg_file_path() const { return m_el_link_cfg_file_path_; } + inline const String& get_op_link_cfg_file_path() const { return m_op_link_cfg_file_path_; } + inline const String& get_router_cfg_file_path() const { return m_router_cfg_file_path_; } + // Get the name of the technology parameters + inline const String& get_tech_file_path() const { return m_tech_file_path_; } + // Get the config used for various models + inline const std::vector& get_router_cfg() const { return m_router_cfg_; } + inline const std::vector& get_link_cfg() const { return m_link_cfg_; } + // Get the clock frequency + inline double get_frequency() const { return m_frequency_; } + + // Run DSENT with some specified arguments, returning outputs + std::vector run_dsent(const String& cfg_file_path_, const std::vector& evals_, const std::vector& overwrites_) const; + + private: + // Config file paths + String m_el_link_cfg_file_path_; + String m_op_link_cfg_file_path_; + String m_router_cfg_file_path_; + // Tech file paths + String m_tech_file_path_; + // Configs + double m_frequency_; + std::vector m_router_cfg_; + std::vector m_link_cfg_; + + private: + // Singleton + static DSENTInterface* m_singleton; + // Constants + const static String el_link_cfg_file_name; + const static String op_link_cfg_file_name; + const static String router_cfg_file_name; + }; +} +#endif + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/DSENTInterface.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/DSENTInterface.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +// C includes +#include +#include + +// C++ includes +#include +#include + +// DSENT includes +#include "mem/ruby/network/dsent/DSENTInterface.hh" +#include "mem/ruby/network/dsent/dsent-core/libutil/LibUtil.hh" +#include "mem/ruby/network/dsent/dsent-core/DSENT.hh" + +using namespace std; +using namespace LibUtil; + +namespace dsent_contrib +{ + DSENTInterface* DSENTInterface::m_singleton = NULL; + + const String DSENTInterface::el_link_cfg_file_name = "electrical-link.cfg"; + const String DSENTInterface::op_link_cfg_file_name = "optical-link.cfg"; + const String DSENTInterface::router_cfg_file_name = "router.cfg"; + + DSENTInterface::Overwrite::Overwrite(const String& var_, const String& val_) : + m_var_(var_), m_val_(val_) + {} + + DSENTInterface::Overwrite::~Overwrite() + {} + + void DSENTInterface::allocate(const string& dsent_path_, unsigned int tech_node_) + { + assert(!m_singleton); + m_singleton = new DSENTInterface(String(dsent_path_), tech_node_); + } + + void DSENTInterface::release() + { + assert(m_singleton); + delete m_singleton; + } + + DSENTInterface* DSENTInterface::getSingleton() + { + assert(m_singleton); + return m_singleton; + } + + DSENTInterface::DSENTInterface(const String& dsent_path_, unsigned int tech_node_) + : SimObject(NULL) + { + m_el_link_cfg_file_path_ = dsent_path_ + "/dsent-core/configs/" + el_link_cfg_file_name; + m_op_link_cfg_file_path_ = dsent_path_ + "/dsent-core/configs/" + op_link_cfg_file_name; + m_router_cfg_file_path_ = dsent_path_ + "/dsent-core/configs/" + router_cfg_file_name; + + // Some hardcoded elements to this, depending on when graphite is able to parametrize the other parts + if (tech_node_ == 45) m_tech_file_path_ = dsent_path_ + "/dsent-core/tech/tech_models/" + "Bulk45LVT.model"; + else if (tech_node_ == 32) m_tech_file_path_ = dsent_path_ + "/dsent-core/tech/tech_models/" + "Bulk32LVT.model"; + else if (tech_node_ == 22) m_tech_file_path_ = dsent_path_ + "/dsent-core/tech/tech_models/" + "Bulk22LVT.model"; + else if (tech_node_ == 11) m_tech_file_path_ = dsent_path_ + "/dsent-core/tech/tech_models/" + "TG11LVT.model"; + else assert(false); + + } + + DSENTInterface::DSENTInterface(const Params* p_) + : SimObject(p_) + { + String tech_model_path_base = "src/mem/ruby/network/dsent/dsent-core/tech/tech_models/"; + + // Set technology model path + switch(p_->electrical_tech_node) + { + case 45: m_tech_file_path_ = tech_model_path_base + "Bulk45LVT.model"; break; + case 32: m_tech_file_path_ = tech_model_path_base + "Bulk32LVT.model"; break; + case 22: m_tech_file_path_ = tech_model_path_base + "Bulk22LVT.model"; break; + case 11: m_tech_file_path_ = tech_model_path_base + "TG11LVT.model"; break; + default: assert(false); + } + + // Copy all configuraiton to local + m_frequency_ = p_->frequency; + + m_router_cfg_.push_back(Overwrite("ModelName", p_->router_model)); + m_router_cfg_.push_back(Overwrite("InputPort->BufferModel", p_->router_input_port_buffer_model)); + m_router_cfg_.push_back(Overwrite("CrossbarModel", p_->router_crossbar_model)); + m_router_cfg_.push_back(Overwrite("SwitchAllocator->ArbiterModel", p_->router_sa_arbiter_model)); + m_router_cfg_.push_back(Overwrite("ClockTreeModel", p_->router_clk_tree_model)); + m_router_cfg_.push_back(Overwrite("ClockTree->NumberLevels", p_->router_clk_tree_num_levels)); + m_router_cfg_.push_back(Overwrite("ClockTree->WireLayer", p_->router_clk_tree_wire_layer)); + m_router_cfg_.push_back(Overwrite("ClockTree->WireWidthMultiplier", p_->router_clk_tree_wire_width_mult)); + + m_link_cfg_.push_back(Overwrite("ModelName", p_->link_model)); + m_link_cfg_.push_back(Overwrite("WireLayer", p_->link_wire_layer)); + m_link_cfg_.push_back(Overwrite("WireWidthMultiplier", p_->link_wire_width_mult)); + m_link_cfg_.push_back(Overwrite("WireSpacingMultiplier", p_->link_wire_spacing_mult)); + } + + DSENTInterface::~DSENTInterface() + {} + + vector DSENTInterface::run_dsent(const String& cfg_file_path_, const vector& evals_, const vector& overwrites_) const + { + // Create String stream to pass to DSENT + ostringstream dsent_ost; + // Create DSENT arguments vector + vector* dsent_args = new vector(); + // Overwrites string + String overrides_str = ""; + // DSENT output string + String dsent_out_string; + + // Specify the correct config file path + if(cfg_file_path_.size() != 0) + { + dsent_args->push_back("-cfg"); + dsent_args->push_back(cfg_file_path_); + } + + // Clear any queries + dsent_args->push_back("-query"); + dsent_args->push_back(" "); + + // Create evaluate String + if (!evals_.empty()) + { + String eval_str = ""; + for (vector::const_iterator it = evals_.begin(); it != evals_.end(); it++) + eval_str += "print " + *it + ";"; + dsent_args->push_back("-eval"); + dsent_args->push_back(eval_str); + } + + // Begin overrides + dsent_args->push_back("-overwrite"); + + // Add electrical technology model filename + overrides_str = "ElectricalTechModelFilename=" + get_tech_file_path() + ";"; + + // Add other overrides + for (vector::const_iterator it = overwrites_.begin(); it != overwrites_.end(); it++) + overrides_str += " " + it->get_string() + ";" ; + + // Append full overrides string + dsent_args->push_back(overrides_str); + + // Convert arguments vector to char** + char** dsent_args_raw = new char*[dsent_args->size()]; + for (unsigned int i = 0; i < dsent_args->size(); i++) + { + // Probably should check this is doing the right things + dsent_args_raw[i] = new char[dsent_args->at(i).size()+1]; + strcpy(dsent_args_raw[i], dsent_args->at(i).c_str()); + } + + // Run DSENT + DSENT::DSENT::run(int(dsent_args->size()), dsent_args_raw, dsent_ost); + + // Get DSENT output into a String + dsent_out_string = dsent_ost.str(); + + // Delete stuff + for (unsigned int i = 0; i < dsent_args->size(); i++) + delete dsent_args_raw[i]; + delete dsent_args_raw; + delete dsent_args; + + // Return split line-by-line outputs + return dsent_out_string.split("\n"); + } + +} + +dsent_contrib::DSENTInterface * +DSENTInterfaceParams::create() +{ + return new dsent_contrib::DSENTInterface(this); +} + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/DSENTInterface.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/DSENTInterface.py Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,54 @@ +# 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. +# +# Authors: Chia-Hsin Owen Chen + +from m5.params import * +from m5.SimObject import SimObject + +class DSENTInterface(SimObject): + type = 'DSENTInterface' + cxx_class = 'dsent_contrib::DSENTInterface' + + # Global configuration + electrical_tech_node = Param.Int(45, "Electrical technology node") + frequency = Param.Float(1.0e9, "Clock frequency") + + # Router configuration + router_model = Param.String("Router", "Router model") + router_input_port_buffer_model = Param.String("DFFRAM", "Router input port -> Buffer model") + router_crossbar_model = Param.String("MultiplexerCrossbar", "Router crossbar model") + router_sa_arbiter_model = Param.String("MatrixArbiter", "Router switch allocator -> Arbiter model") + router_clk_tree_model = Param.String("BroadcastHTree", "Router clock tree -> Model") + router_clk_tree_num_levels = Param.Int(5, "Router clock tree -> Number of levels") + router_clk_tree_wire_layer = Param.String("Global", "Router clock tree -> Wire layer") + router_clk_tree_wire_width_mult = Param.Float(1.0, "Router clock tree -> Width multiplier") + + # Link configuration + link_model = Param.String("RepeatedLink", "Link model") + link_wire_layer = Param.String("Global", "Link -> Wire layer") + link_wire_width_mult = Param.Float(1.0, "Link -> Wire width multiplier") + link_wire_spacing_mult = Param.Float(1.0, "Link -> Wire spacing multiplier") + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/DSENTRouter.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/DSENTRouter.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENTROUTER_H__ +#define __DSENTROUTER_H__ + +#include "mem/ruby/network/dsent/Type.hh" + +namespace dsent_contrib +{ + // This class is responsible for calling DSENT for a router + class DSENTInterface; + + class DSENTRouter + { + public: + // Create a DSENT run for a router with these parameters + DSENTRouter( + float frequency_, + unsigned int num_in_port_, + unsigned int num_out_port_, + unsigned int num_vclass_, + unsigned int num_vchannel_, + unsigned int num_buffers_, + unsigned int flit_width_, + const DSENTInterface* dsent_interface_ + ); + // The frequency is set in the DSENTInterface + DSENTRouter( + unsigned int num_in_port_, + unsigned int num_out_port_, + unsigned int num_vclass_, + const vector& num_vchannels_vec_, + const vector& num_buffers_vec_, + unsigned int flit_width_, + const DSENTInterface* dsent_interface_ + ); + ~DSENTRouter(); + + public: + // Get clock frequency + inline double get_frequency() const { return m_frequency_; } + + // Get dynamic energy components + inline double calc_dynamic_energy_buf_write(double num_req_) const { return (num_req_ * m_dynamic_energy_buf_write_); } + inline double calc_dynamic_energy_buf_read(double num_req_) const { return (num_req_ * m_dynamic_energy_buf_read_); } + inline double calc_dynamic_energy_sa_local(double num_req_) const { return (num_req_ * m_dynamic_energy_sa_local_); } + inline double calc_dynamic_energy_sa_global(double num_req_) const { return (num_req_ * m_dynamic_energy_sa_global_); } + inline double calc_dynamic_energy_xbar(double num_req_, unsigned int multicast_idx) const { return (num_req_ * m_dynamic_energy_xbar_->at(multicast_idx)); } + inline double calc_dynamic_energy_clock(double num_events_) const { return (num_events_ * m_dynamic_energy_clock_); } + + // Get static energy components + inline double get_static_power_buf() const { return m_static_power_buf_; } + inline double get_static_power_sa() const { return m_static_power_sa_; } + inline double get_static_power_xbar() const { return m_static_power_xbar_; } + inline double get_static_power_clock() const { return m_static_power_clock_; } + + void print() const; + + private: + void init( + float frequency_, + unsigned int num_in_port_, + unsigned int num_out_port_, + unsigned int num_vclass_, + const vector& num_vchannels_vec_, + const vector& num_buffers_vec_, + unsigned int flit_width_, + const DSENTInterface* dsent_interface_ + ); + + private: + // User-defined clock frequency + double m_frequency_; + + // Dynamic energy components + double m_dynamic_energy_buf_write_; + double m_dynamic_energy_buf_read_; + double m_dynamic_energy_sa_local_; + double m_dynamic_energy_sa_global_; + double m_dynamic_energy_clock_; + vector* m_dynamic_energy_xbar_; + + // Static power components + double m_static_power_buf_; + double m_static_power_xbar_; + double m_static_power_sa_; + double m_static_power_clock_; + + }; +} + +#endif + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/DSENTRouter.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/DSENTRouter.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/DSENTRouter.hh" +#include "mem/ruby/network/dsent/DSENTInterface.hh" +#include "mem/ruby/network/dsent/dsent-core/libutil/String.hh" + +#include +#include +#include + +using namespace std; +using namespace LibUtil; + +namespace dsent_contrib +{ + DSENTRouter::DSENTRouter( + float frequency_, + unsigned int num_in_port_, + unsigned int num_out_port_, + unsigned int num_vclass_, + unsigned int num_vchannel_, + unsigned int num_buffers_, + unsigned int flit_width_, + const DSENTInterface* dsent_interface_ + ) + { + // Create vector + m_dynamic_energy_xbar_ = new vector(); + + // Initialize everything else + init(frequency_, num_in_port_, num_out_port_, num_vclass_, + vector(num_vclass_, num_vchannel_), + vector(num_vclass_, num_buffers_), + flit_width_, dsent_interface_); + } + + DSENTRouter::DSENTRouter( + unsigned int num_in_port_, + unsigned int num_out_port_, + unsigned int num_vclass_, + const vector& num_vchannels_vec_, + const vector& num_buffers_vec_, + unsigned int flit_width_, + const DSENTInterface* dsent_interface_ + ) + { + // Create vector + m_dynamic_energy_xbar_ = new vector(); + + // Initialize everything else + init(dsent_interface_->get_frequency(), num_in_port_, num_out_port_, num_vclass_, + num_vchannels_vec_, num_buffers_vec_, flit_width_, dsent_interface_); + } + + DSENTRouter::~DSENTRouter() + { + delete m_dynamic_energy_xbar_; + m_dynamic_energy_xbar_ = NULL; + } + + void DSENTRouter::init( + float frequency_, + unsigned int num_in_port_, + unsigned int num_out_port_, + unsigned int num_vclass_, + const vector& num_vchannels_vec_, + const vector& num_buffers_vec_, + unsigned int flit_width_, + const DSENTInterface* dsent_interface_ + ) + { + // Check if the input parameters are valid + assert(frequency_ > 0.0); + assert(num_in_port_ != 0); + assert(num_out_port_ != 0); + assert(num_vclass_ != 0); + assert(num_vclass_ == num_vchannels_vec_.size()); + assert(num_vclass_ == num_buffers_vec_.size()); + assert(flit_width_ != 0); + assert(dsent_interface_ != NULL); + + for(unsigned int i = 0; i < num_vchannels_vec_.size(); i++) + assert(num_vchannels_vec_[i] != 0); + + // Create DSENT evaluate + vector eval = vector(); + // Create DSENT overwrites vector + vector overwrites = vector(); + // DSENT outputs + vector outputs; + + // Create evaluate String + // Dynamic power components + eval.push_back( "$(Energy>>Router:WriteBuffer)"); + eval.push_back( "$(Energy>>Router:ReadBuffer)"); + eval.push_back( "$(Energy>>Router:ArbitrateSwitch->ArbitrateStage1)"); + eval.push_back( "$(Energy>>Router:ArbitrateSwitch->ArbitrateStage2)"); + //eval.push_back( "($(Energy>>Router:ArbitrateSwitch->ArbitrateStage1) + " + // "$(Energy>>Router:ArbitrateSwitch->ArbitrateStage2))"); + // Crossbar multicast energy queries + for (unsigned int multicast = 1; multicast <= num_out_port_; ++multicast) + eval.push_back( "$(Energy>>Router:TraverseCrossbar->Multicast" + (String) multicast + ")"); + eval.push_back( "$(Energy>>Router:DistributeClock)"); + + // Static power components + eval.push_back( "$(NddPower>>Router->InputPort:Leakage) * $(NumberInputPorts) + " + "($(NddPower>>Router->PipelineReg0:Leakage) + $(NddPower>>Router->PipelineReg1:Leakage)) * " + "$(NumberInputPorts) * $(NumberBitsPerFlit)"); + eval.push_back( "$(NddPower>>Router->SwitchAllocator:Leakage)"); + eval.push_back( "$(NddPower>>Router->Crossbar:Leakage) + " + "$(NddPower>>Router->PipelineReg2_0:Leakage) * $(NumberOutputPorts) * $(NumberBitsPerFlit);"); + eval.push_back( "$(NddPower>>Router->ClockTree:Leakage)"); + + // Create overwrites + overwrites = dsent_interface_->get_router_cfg(); + overwrites.push_back(DSENTInterface::Overwrite("Frequency", String(frequency_))); + overwrites.push_back(DSENTInterface::Overwrite("NumberInputPorts", String(num_in_port_))); + overwrites.push_back(DSENTInterface::Overwrite("NumberOutputPorts", String(num_out_port_))); + overwrites.push_back(DSENTInterface::Overwrite("NumberVirtualNetworks", String(num_vclass_))); + overwrites.push_back(DSENTInterface::Overwrite("NumberVirtualChannelsPerVirtualNetwork", + vectorToString(num_vchannels_vec_))); + overwrites.push_back(DSENTInterface::Overwrite("NumberBuffersPerVirtualChannel", + vectorToString(num_buffers_vec_))); + overwrites.push_back(DSENTInterface::Overwrite("NumberBitsPerFlit", String(flit_width_))); + + // Run DSENT + //outputs = dsent_interface_->run_dsent(dsent_interface_->get_router_cfg_file_path(), eval, overwrites); + outputs = dsent_interface_->run_dsent("", eval, overwrites); + + // Check to make sure we get the expected number of outputs + assert(outputs.size() == 9 + num_out_port_); + + // Store outputs + // Clock frequency + m_frequency_ = frequency_; + + // Dynamic energy components + m_dynamic_energy_buf_write_ = outputs[0]; + m_dynamic_energy_buf_read_ = outputs[1]; + m_dynamic_energy_sa_local_ = outputs[2]; + m_dynamic_energy_sa_global_ = outputs[3]; + // Multicast energies (add a 0 for a multicast to 0 ports) + m_dynamic_energy_xbar_->push_back(0.0); + for (unsigned int multicast = 1; multicast <= num_out_port_; ++multicast) + m_dynamic_energy_xbar_->push_back(outputs[3 + multicast]); + m_dynamic_energy_clock_ = outputs[4 + num_out_port_]; + + // Static power components + m_static_power_buf_ = outputs[5 + num_out_port_]; + m_static_power_xbar_ = outputs[6 + num_out_port_]; + m_static_power_sa_ = outputs[7 + num_out_port_]; + m_static_power_clock_ = outputs[8 + num_out_port_]; + + return; + } + + void DSENTRouter::print() const + { + cout << "Router - Dynamic Energy" << endl; + cout << "\t" << "Buffer Write = " << calc_dynamic_energy_buf_write(1) << endl; + cout << "\t" << "Buffer Read = " << calc_dynamic_energy_buf_read(1) << endl; + cout << "\t" << "SW Allocator (local) = " << calc_dynamic_energy_sa_local(1) << endl; + cout << "\t" << "SW Allocator (global) = " << calc_dynamic_energy_sa_global(1) << endl; + cout << "\t" << "Crossbar" << endl; + for (unsigned int multicast = 0; multicast < m_dynamic_energy_xbar_->size(); ++multicast) + cout << "\t\t" << "Multicast " << multicast << " = " << calc_dynamic_energy_xbar(1, multicast) << endl; + cout << "\t" << "Clock = " << calc_dynamic_energy_clock(1) << endl; + cout << endl; + cout << "Router - Static Power" << endl; + cout << "\t" << "Buffer = " << get_static_power_buf() << endl; + cout << "\t" << "SW Allocator = " << get_static_power_sa() << endl; + cout << "\t" << "Crossbar = " << get_static_power_xbar() << endl; + cout << "\t" << "Clock = " << get_static_power_clock() << endl; + cout << endl; + return; + } +} + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/SConscript --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/SConscript Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,38 @@ +# 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. +# +# Authors: Chia-Hsin Owen Chen + +Import('*') + +if env['PROTOCOL'] == 'None': + Return() + +SimObject('DSENTInterface.py') + +Source('DSENTInterface.cc') +Source('DSENTRouter.cc') +Source('DSENTElectricalLink.cc') + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/Type.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/Type.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __TYPE_H__ +#define __TYPE_H__ + +#include +#include +#include "mem/ruby/network/dsent/dsent-core/libutil/String.hh" + +namespace dsent_contrib +{ + // Strings are nice, + using std::string; + // I love Strings + using LibUtil::String; + // Vectors too + using std::vector; +} + +#endif + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/DSENT.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/DSENT.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_DSENT_H__ +#define __DSENT_DSENT_H__ + +// For DSENT operations +#include + +#include "mem/ruby/network/dsent/dsent-core/libutil/OptionParser.hh" +#include "mem/ruby/network/dsent/dsent-core/libutil/Calculator.hh" +#include "mem/ruby/network/dsent/dsent-core/libutil/String.hh" + +namespace DSENT +{ + using std::ostream; + + using LibUtil::OptionParser; + using LibUtil::Calculator; + using LibUtil::String; + + class Model; + + class DSENT + { + protected: + class DSENTCalculator : public Calculator + { + public: + DSENTCalculator(); + virtual ~DSENTCalculator(); + + protected: + virtual double getEnvVar(const String& var_name_) const; + }; // class DSENTCalculator + + public: + // A full execution of DSENT, with output directed to the specified + // output stream + static void run(int argc_, char** argv_, ostream& ost_); + + protected: + static void setRuntimeOptions(OptionParser* option_parser_); + static void initialize(int argc_, char** argv_, ostream& ost_); + static void buildModel(ostream& ost_); + static void processQuery(ostream& ost_); + static const void* processQuery(const String& query_str_, bool is_print_, ostream& ost_); + static void finalize(); + + static void performTimingOpt(); + static void reportTiming(ostream& ost_); + + static void processEvaluate(ostream& ost_); + + protected: + static Model* ms_model_; + + static bool ms_is_verbose_; + + }; // class DSENT + +} // namespace DSENT + +#endif // __DSENT_DSENT_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/DSENT.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/DSENT.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,464 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +// C includes +#include + +// C++ includes +#include + +#include "mem/ruby/network/dsent/dsent-core/DSENT.hh" + +#include "mem/ruby/network/dsent/dsent-core/libutil/OptionParser.hh" +#include "mem/ruby/network/dsent/dsent-core/libutil/Calculator.hh" +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/util/Config.hh" +#include "mem/ruby/network/dsent/dsent-core/util/Result.hh" +#include "mem/ruby/network/dsent/dsent-core/model/Model.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ModelGen.hh" + +// For timing optimization +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingTree.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingOptimizer.hh" +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" + +namespace DSENT +{ + Model* DSENT::ms_model_ = NULL; + bool DSENT::ms_is_verbose_ = false; + + void DSENT::run(int argc_, char** argv_, ostream& ost_) + { + // Initialize DSENT framework (setup log file, config file, ...) + initialize(argc_, argv_, ost_); + + // Build the specified model in the config file + buildModel(ost_); + + // Process the specified queries + processQuery(ost_); + // Process the specified evaluation + processEvaluate(ost_); + + // Finalize DSENT framework (close log file, ...) + finalize(); + return; + } + + void DSENT::setRuntimeOptions(OptionParser* option_parser_) + { + option_parser_->addOption("-cfg", "ConfigFilename", true, "filename", true, "", + "Specify the config filename."); + + option_parser_->addOption("-available_models", "IsListModels", false, "", true, "false", + "List available DSENT models."); + + option_parser_->addOption("-log", "LogFilename", true, "filename", true, "./dsent.log", + "Specify the log filename."); + + option_parser_->addOption("-overwrite", "OverwriteString", true, "options", true, "", + "Overwrite dynamically the options set in the config file. Options are separated by a comma (;)."); + + option_parser_->addOption("-overwrite_tech", "OverwriteTechString", true, "options", true, "", + "Overwrite dynamically the options set in the technology file. Options are separated by a comma (;)."); + + option_parser_->addOption("-print_config", "IsPrintConfig", false, "", true, "false", + "Print the config used at DSENT runtime."); + + option_parser_->addOption("-query", "QueryString", true, "query string", true, "", + "Specify the list of items to query. This command is the same as owerwriting the 'QueryString'."); + + option_parser_->addOption("-eval", "EvaluateString", true, "evaluate string", true, "", + "Specify the list of statements to evaluate. This command is the same as owerwriting the 'EvaluateString'."); + + option_parser_->addOption("-verbose", "IsVerbose", false, "", true, "false", + "Enable verbose mode which prints out more detailed messages."); + return; + } + + void DSENT::initialize(int argc_, char** argv_, ostream& ost_) + { + OptionParser* option_parser = new OptionParser(); + + // Init the option parser and setup available options + setRuntimeOptions(option_parser); + + // Parse the options + option_parser->parseArguments(argc_, argv_); + + // If -available_models is specified, print out a list of available + // models and exit DSENT. + if(option_parser->get("IsListModels").toBool()) + { + ModelGen::printAvailableModels(ost_); + exit(0); + } + + // Init the log file + Log::allocate(option_parser->get("LogFilename")); + + // Init the config file + Config::allocate(option_parser->get("ConfigFilename")); + Config* dsent_config = Config::getSingleton(); + + // Overwrite the existing options + dsent_config->readString(option_parser->get("OverwriteString")); + + // Overwrite the technology file + dsent_config->constructTechModel(option_parser->get("OverwriteTechString")); + + ms_is_verbose_ = option_parser->get("IsVerbose").toBool(); + + // Overwrite the query string if it is specified from command line + if(option_parser->get("QueryString").size() != 0) + { + dsent_config->set("QueryString", option_parser->get("QueryString")); + } + // Overwrite the evaluation string if it is specified from command line + if(option_parser->get("EvaluateString").size() != 0) + { + dsent_config->set("EvaluateString", option_parser->get("EvaluateString")); + } + + // Print the config used for this run + if(option_parser->get("IsPrintConfig").toBool()) + { + if(ms_is_verbose_) + { + ost_ << "Configuration:" << endl; + ost_ << "==============" << endl; + } + ost_ << *dsent_config; + + if(ms_is_verbose_) + { + ost_ << "==============" << endl; + } + } + + delete option_parser; + return; + } + + void DSENT::buildModel(ostream& ost_) + { + Config* dsent_config = Config::getSingleton(); + + // Create the model specified + const String& model_name = dsent_config->get("ModelName"); + ms_model_ = ModelGen::createModel(model_name, model_name, dsent_config->getTechModel()); + + // Construct the model + // Read all parameters the model requires + const vector* parameter_names = ms_model_->getParameterNames(); + // For all parameters, grab values from the config file + for(vector::const_iterator it = parameter_names->begin(); it != parameter_names->end(); ++it) + { + const String& parameter_name = *it; + // If it exists in the config file, set the parameter + if(dsent_config->keyExist(parameter_name)) + { + ms_model_->setParameter(parameter_name, dsent_config->get(parameter_name)); + } + } + ms_model_->construct(); + + // Update the model + // Read all properties the model requires + const vector* property_names = ms_model_->getPropertyNames(); + // For all properties, grab values from the config file + for(vector::const_iterator it = property_names->begin(); it != property_names->end(); ++it) + { + const String& property_name = *it; + // If it exists in the config file, set the parameter + if(dsent_config->keyExist(property_name)) + { + ms_model_->setProperty(property_name, dsent_config->get(property_name)); + } + } + ms_model_->update(); + + // Evaluate the model + // Perform timing optimization if needed + if(dsent_config->getIfKeyExist("IsPerformTimingOptimization", "false").toBool()) + { + performTimingOpt(); + } + ms_model_->evaluate(); + + // Report timing if needed + if(dsent_config->getIfKeyExist("IsReportTiming", "false").toBool()) + { + reportTiming(ost_); + } + + return; + } + + void DSENT::processQuery(ostream& ost_) + { + Config* dsent_config = Config::getSingleton(); + vector queries = dsent_config->get("QueryString").split(" ;\r\n"); + + if(ms_is_verbose_) + { + ost_ << "Query results:" << endl; + ost_ << "==============" << endl; + } + + for(unsigned int i = 0; i < queries.size(); ++i) + { + const String& curr_query = queries[i]; + + if(ms_is_verbose_) + { + String str = "Process query: '" + curr_query + "'"; + ost_ << str << endl; + ost_ << String(str.size(), '-') << endl; + } + + processQuery(curr_query, true, ost_); + + if(ms_is_verbose_) + { + ost_ << endl; + } + } + if(ms_is_verbose_) + { + ost_ << "==============" << endl; + } + return; + } + + const void* DSENT::processQuery(const String& query_str_, bool is_print_, ostream& ost_) + { + vector type_split = query_str_.splitByString(Model::TYPE_SEPARATOR); + ASSERT((type_split.size() == 2), "[Error] Invalid query format: " + query_str_); + String query_type = type_split[0]; + + vector detail_split = type_split[1].splitByString(Model::DETAIL_SEPARATOR); + ASSERT((detail_split.size() == 2), "[Error] Invalid query format: " + query_str_); + String query_detail = detail_split[1]; + + vector subfield_split = detail_split[0].splitByString(Model::SUBFIELD_SEPARATOR); + ASSERT(((subfield_split.size() == 2) || (subfield_split.size() == 1)), "[Error] Invalid query format: " + query_str_); + String query_hier = subfield_split[0]; + String query_subfield = ""; + if(subfield_split.size() == 2) + { + query_subfield = subfield_split[1]; + } + + const void* query_result = ms_model_->parseQuery(query_type, query_hier, query_subfield); + if(query_type == "Property") + { + const PropertyMap* property = (const PropertyMap*)query_result; + if(is_print_) ost_ << *property; + } + else if(query_type == "Parameter") + { + const ParameterMap* parameter = (const ParameterMap*)query_result; + if(is_print_) ost_ << *parameter; + } + else if(query_type.contain("Hier")) + { + const Model* model = (const Model*)query_result; + if(is_print_) model->printHierarchy(query_type, query_subfield, "", query_detail, ost_); + } + else + { + const Result* result = (const Result*)query_result; + if(is_print_) + { + result->print(query_type + Model::TYPE_SEPARATOR + query_hier + + Model::SUBFIELD_SEPARATOR + query_subfield, query_detail, ost_); + } + } + return query_result; + } + + void DSENT::finalize() + { + // Release the constructed model + delete ms_model_; + ms_model_ = NULL; + + // Release the config file + Config::release(); + + // Release the log file + Log::release(); + + return; + } + + void DSENT::performTimingOpt() + { + Config* dsent_config = Config::getSingleton(); + + // Get the frequency it is optimizing to + double freq = dsent_config->get("Frequency").toDouble(); + + // Get all the starting net names + const vector& start_net_names = dsent_config->get("TimingOptimization->StartNetNames").split("[,]"); + + ASSERT((start_net_names.size() > 0), "[Error] Expecting net names in TimingOptimization->StartNetNames"); + + if(start_net_names[0] == "*") + { + // Optimize from all input ports + ElectricalModel* electrical_model = (ElectricalModel*)ms_model_; + + ElectricalTimingOptimizer timing_optimizer("Optimizer", electrical_model->getTechModel()); + timing_optimizer.setModel(electrical_model); + timing_optimizer.construct(); + timing_optimizer.update(); + + ElectricalTimingTree timing_tree(timing_optimizer.getInstanceName(), &timing_optimizer); + + const Map* input_ports = timing_optimizer.getInputs(); + Map::ConstIterator it_begin = input_ports->begin(); + Map::ConstIterator it_end = input_ports->end(); + Map::ConstIterator it; + for(it = it_begin; it != it_end; ++it) + { + const String& net_name = it->first; + Log::printLine("Optimizing net: " + net_name); + timing_tree.performTimingOpt(timing_optimizer.getNet(net_name, makeNetIndex(0)), 1.0 / freq); + //timing_tree.performTimingOpt(electrical_model->getNet(net_name, makeNetIndex(0)), 1.0 / freq); + } + // Loop the second times + for(it = it_begin; it != it_end; ++it) + { + const String& net_name = it->first; + Log::printLine("Optimizing net: " + net_name); + //timing_tree.performTimingOpt(timing_optimizer.getNet(net_name, makeNetIndex(0)), 1.0 / freq); + } + } + else + { + // TODO : parse the net name so that we could do hierarchical optimization + // Currently we can only optimize timing at the top level + ElectricalModel* electrical_model = (ElectricalModel*)ms_model_; + ElectricalTimingTree timing_tree(electrical_model->getInstanceName(), electrical_model); + for(unsigned int i = 0; i < start_net_names.size(); ++i) + { + const String& net_name = start_net_names[i]; + timing_tree.performTimingOpt(electrical_model->getNet(net_name), 1.0 / freq); + } + } + return; + } + + void DSENT::reportTiming(ostream& ost_) + { + Config* dsent_config = Config::getSingleton(); + + // Get all the starting net names + const vector& start_net_names = dsent_config->get("ReportTiming->StartNetNames").split("[,]"); + + ElectricalModel* electrical_model = (ElectricalModel*)ms_model_; + ElectricalTimingTree timing_tree(electrical_model->getInstanceName(), electrical_model); + + ost_ << "Report timing:" << endl; + ost_ << "==============" << endl; + for(unsigned int i = 0; i < start_net_names.size(); ++i) + { + const String& net_name = start_net_names[i]; + double timing = timing_tree.performCritPathExtract(electrical_model->getNet(net_name)); + ost_ << net_name << " = " << timing << endl; + } + ost_ << "==============" << endl; + return; + } + + void DSENT::processEvaluate(ostream& ost_) + { + Config* dsent_config = Config::getSingleton(); + + // Return if EvaluatString is empty or not exists + if(!dsent_config->keyExist("EvaluateString")) return; + + String eval_str = dsent_config->get("EvaluateString"); + + if(eval_str == "") return; + + if(ms_is_verbose_) + { + ost_ << "Eval results:" << endl; + ost_ << "==============" << endl; + } + + //if(ms_is_verbose_) + //{ + // String str = "Process evaluation: '" + eval_str + "'"; + // ost_ << str << endl; + // ost_ << String(str.size(), '-') << endl; + //} + DSENTCalculator calc; + calc.evaluateString(eval_str, ost_); + + if(ms_is_verbose_) + { + ost_ << "==============" << endl; + } + return; + return; + } + + DSENT::DSENTCalculator::DSENTCalculator() + {} + + DSENT::DSENTCalculator::~DSENTCalculator() + {} + + double DSENT::DSENTCalculator::getEnvVar(const String& var_name_) const + { + if(m_var_.keyExist(var_name_)) + { + return m_var_.get(var_name_); + } + else if(Config::getSingleton()->keyExist(var_name_)) + { + return Config::getSingleton()->get(var_name_); + } + else + { + // Wish there was a way to not have to pass in a stream if we aren't doing anything with it + const Result* result = (const Result*)DSENT::processQuery(var_name_ + "@0", false, cout); + return result->calculateSum(); + } + } +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/LICENSE --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/LICENSE Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,19 @@ +Copyright (c) 2012 Massachusetts Institute of Technology + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/README Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,361 @@ +DSENT (Design Space Exploration of Networks Tool) + +=============================================================================== +Overview +=============================================================================== +DSENT is a modeling tool designed for rapid design space exploration of both +electronical and emerging opto-electrical networks-on-chip (NoC). It provides +analytic and parameterized models for various network components and is +portable across a range of technology assumptions. Given architectural-level +parameters, DSENT builds the specified models hierarchically from electrical +and optical building blocks and outputs detailed power and area estimates. + + +=============================================================================== +Version +=============================================================================== +Current: 0.9 (22 May 2012) + +Latest version or additional information can be found at + + https://sites.google.com/site/mitdsent + +=============================================================================== +System requirements +=============================================================================== +We have tested DSENT on the following platforms: + +Linux GNU g++ 4.1.2 and glibc 2.5 +Linux GNU g++ 4.3.2 and glibc 2.7 +Linux GNU g++ 4.4.5 and glibc 2.11.3 +Cygwin g++ 4.5.3 and cygwin 1.7.14 + +=============================================================================== +License +=============================================================================== +Please refer to the LICENSE file for licensing and copyright information. + +If you use DSENT in your research, please acknowledge us by referencing our +NOCS 2012 paper: + +Chen Sun, Chia-Hsin Owen Chen, George Kurian, Lan Wei, Jason Miller, +Anant Agarwal, Li-Shiuan Peh, Vladimir Stojanovic, "DSENT - A Tool Connecting +Emerging Photonics with Electronics for Opto-Electronic Networks-on-Chip +Modeling." The 6th ACM/IEEE International Symposium on Networks-on-Chip +(NOCS), May 2012, Lyngby, Denmark. + + +=============================================================================== +Contact information +=============================================================================== +If you have any questions or comments, please contact us through our mailing +list at: mitdsent@mit.edu + +We will try to reply as soon as possible. + + +=============================================================================== +Build (installation) +=============================================================================== +To build DSENT: + + % make + +By default DSENT is built with logging disabled. Logging keeps track of what +happens while running DSENT. It is an option more for the DSENT framework and +DSNET models developers. If you want to enable this option, simply type the +following: + + % make LIBUTIL_IS_LOG=true + +To clean the build: + + % make clean + + +=============================================================================== +Usage +=============================================================================== +DSENT builds models and runs based on the specified configuration file. In the +configuration file, you specify a model name and necessary information +(parameters and properties) required to build the model. + +To run DSENT: + + % ./dsent -cfg + +To check what models are available: + + % ./dsent -available_models + +To overwrite the configuration file from command line: + Use ';' to separate different key/value pairs. + + % ./dsent -cfg -overwrite + % ./dsent -cfg configs/example.cfg -overwrite "NumberInputs=5; NumberOutputs=6;" + +To print out in a more human-friendly fasion: + + % ./dsent -cfg -verbose + +To check what options are available: + + % ./dsent -help + +Please see configs/example.cfg for an example of a configuration file. + +Please see configs/router.cfg for the router configuration file. + +Please see QueryString and EvaluateString specifications below to know more +about the usage. + +=============================================================================== +Advanced Usage +=============================================================================== +Since DSENT is a generic modeling framework for electrical and optical +components, you can create your own models. We will release guidelines on how +to create custom models on top of DSENT framework. You can use the provided +models as references. + + +=============================================================================== +Quick start for Orion users +=============================================================================== +Instead of using the SIM_port.h file, DSENT uses a text-based configuration +file to specify the router/link configurations. You do not need to recompile +if you change parameters. Even though we use different parameter names, the +ones we use should be self-explanatory. In this package, we provide template +configuration files for the router and link: + + router - configs/router.cfg + link - configs/electrical-link.cfg + + Technology + ---------- + We currently support 45, 32, 22, 11nm. You can specify the desired + frequency but not the nominal voltage level since it is normally + fixed in different processes. + + Router specs + ------------ + Currently we only support the model of a widely used 3-pipeline-stage + input-buffered virtual channel router and does not have distinction + from ports for different components (cache, memory controller, I/O). + + Input buffer specs + ------------------ + The number of virtual channels used for different message classes + might be different; hence, DSENT uses NumberVirtualNetworks to + specify the number of message classes and use + NumberVirtualChannelsPerVirtualNetwork and + NumberBuffersPerVirtualChannel to define the buffers needed for a + virtual network (message class). + + Currently only DFF-based RAM is supports. This is reasonable since + normally the buffer space needed at input port is small enough and + does not need to use SRAMs or RFs (register files). + + Crossbar specs + -------------- + Currently DSENT only supports multiplexer-based crossbars + (MULTREE_CROSSBAR). You no longer need to specify the degree of the + multiplexers. + + Switch allocator specs + ---------------------- + DSENT models a two-stage switch allocator. The first stage is used to + arbitrate between VCs in the same input port, and the second stage is + used to arbitrate between input ports. If there is only one VC in + the input port, then the energy/power/area cost for the first stage + will be zero. + + Currently, DSENT supports MatrixArbiter. + + VC allocator specs + ------------------ + We assume that the router uses a VC select scheme where the VC + allocation is done by just popping a FIFO. Currently DSENT ignores + this module since the FIFO that needs to keep the free VC information + should be small enough. + + Clock distribution specs + ------------------------ + Currently DSENT provides a broadcast H-Tree model. You can specify + the number of levels of the H-Tree (normally 4 or 5 levels should be + enough). + +DSENT replaces the original orion_router_power, orion_router_area and +orion_link with QueryString and EvaluateString (see below for more detailed +information on how to use them). + + +=============================================================================== +QueryString specifications +=============================================================================== +DSENT is a query-based model evaluator. You use QueryString to specify what +information you want DSENT to output. The syntax of a query string is shown as +follows: + + [Query type]>>[Instance name (with hierarchy)]:[Sub query type]@[Detail level] + + E.g., Area>>Router->Crossbar:Active@4 + * Query type: Area + * Instance name: Router->Crossbar + * Sub query type: Active + * Detail level: 4 + + Query type + ---------- + There are 9 types of queries: Parameter, Property, Energy, NddPower, + Area, InstHier, EventHier, NddPowerHier, AreaHier. + + Parameter - Print the model parameters needed to be specified + Property - Print the design constraints or utilization + Use these to check what needs to be specified in the configuration + file for the model. No sub query type is needed for these two + types. + + Energy - Print the data-dependent energy cost of an event + NddPower - Print the non-data-denepent power of an instance + Area - Print the area cost of an instance + Use these to obtain the costs of the specified model. + + InstHier - Print the instance name hierarchy + Use this to know what sub-instances are built for this model + + EventHier - Print the available events for Energy queries + NddPowerHier - Print the available non-data-dependent power types + AreaHier - Print the available area types + Use this to know what to specify in the "sub query type" field. + + Instance name (with hierarchy) + ------------------------------ + The (sub)instance that you want to perform query. The name should be + hierarchical starting from the top level model. Hierarchies are + separated by the symbol "->". + + Sub query type + -------------- + This field is not required for 'Parameter', 'Property' and 'InstHier'. + + For 'Energy', this field stands for the event that cause this energy + cost, such as 'WriteBuffer'. + + For 'NddPower' and 'Area', this field stands for the power and area + cost of the model, such as 'Leakage' and 'Active'. + + For 'EventHier', if this field is not specified, all events of this + instance will be printed; if this field is specified, then only + the specified event will be printed. 'AreaHier' and 'NddPowerHier' + also have the similar behavior. + + Detail level + ------------ + Defines the hierarchy depth to be printed. '0' means current level. + This field is needed for all query types for syntax correctness, + although it is not used for 'Parameter' and 'Property'. + + Multi-line queries + ------------------ + Query strings specified across multiple lines in the config file + must have each line be terminated by a '\'. It is whitespace sensitive, + so make sure there are no spaces after '\'. Note that the parser + prunes everything after the comment '#' character, including '\'! + See configs/router.cfg as an example. + + Examples of individual QueryString's: + + Parameter>>Router@0 + Property>>Router->Crossbar@0 + InstHier>>Router->InputPort@2 + Energy>>Router:WriteBuffer@2 + NddPower>>Router->Crossbar:Leakage@3 + Area>>Router->SwitchAllocator:Active@4 + + +=============================================================================== +EvaluateString specifications +=============================================================================== +DSENT provides a way to let users do custom calculations by specifying the +EvaluateString in the configuration file. EvaluateString constains a sequence +of statements separated by one ';'. DSENT reads through the sequence and +evaluates the statements one-by-one. + +Currently, DSENT supports: + Four arithmetic operations + -------------------------- + 3 + 4 * (5 + 6) / 7; + + Define local variables through assignments + ------------------------------------------ + variable 'a' will be mapped to 7 for future referencing + + a = 3 + 4; + + Global variable referencing + --------------------------- + $(var_name) indicates either a key in the configuration file or a + query string. If var_name exists in the configuration file, then the + corresponding value will be returned; otherwise, DSENT will do a query + using the string var_name@0 and return the query result. + + b = $(Energy>>Router:WriteBuffer) * $(Frequency); + + Printing outputs + ---------------- + DSENT prints the string following the keyword 'print'. + + print + print ""; + print "" ; + + print 3 + 4; # Output: 7 + print "Hello World"; # Output: Hello World + print "Hello World " 3 + 4; # Output: Hello World 7 + + Multi-line evaluate strings + --------------------------- + Evaluate strings specified across multiple lines in the config file + must have each line be terminated by a '\'. It is whitespace sensitive, + so make sure there are no spaces after '\'. Note that the parser + prunes everything after the comment '#' character, including '\'! + See configs/router.cfg as an example. + + +=============================================================================== +Units +=============================================================================== +DSENT uses only SI units for all inputs and outputs. For example: + time = s (second) + distance = m (meter) + capacitance = F (Farad) + power = W (Watt) + energy = J (Joule) + resistance = Ohm + loss = dB (Decibels) + + +=============================================================================== +Known Bugs and Issues +=============================================================================== + +1. If timing is not met, the timing optimizer will put the model in a state +where everything is the maximum size (huge power, area). Thus, model results +can be considered a gross over-estimate when timing isn't met. This is just the +nature of the greedy timing optimizer and it will be addressed in the future. + +2. The VC control and credit buffer component of the router is currently +not modeled, as they have always been assumed to be lumped into the "negligible +control cost" category in previous models and evaluations. Our recent +experiments have shown that this is not true and we will be adding this in the +next iteration. + +3. Some of the connectivity paths have not been checked thoroughly. Thus, +timing optimizer may miss some of the paths. However, we tried to make sure +that the critical paths are modeled properly. + +4. Local interconnect will have an ever-larger impact on power and timing as +technology scales. So far we have not implemented a method for automatically +estimating them but we will eventually address this. Evaluations for 22nm +and below will tend to underestimate as a result. + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/SConscript --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/SConscript Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,34 @@ +# 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. +# +# Authors: Chia-Hsin Owen Chen + +Import('*') + +if env['PROTOCOL'] == 'None': + Return() + +Source('DSENT.cc') + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/libutil/Assert.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/libutil/Assert.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __ASSERT_H__ +#define __ASSERT_H__ + +#include "mem/ruby/network/dsent/dsent-core/libutil/String.hh" +#include "mem/ruby/network/dsent/dsent-core/libutil/Exception.hh" + +#ifdef NDEBUG +#define ASSERT(test_value_,exception_msg_) +#else +#define ASSERT(test_value_,msg_) \ + do \ + { \ + if(!(test_value_)) \ + { \ + const LibUtil::String& exception_msg = LibUtil::String::format("\nAt %s:%d\n", __FILE__, __LINE__) + (String)(msg_); \ + throw LibUtil::Exception(exception_msg); \ + } \ + } while(0); +#endif + +#endif // __ASSERT_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/libutil/Calculator.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/libutil/Calculator.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __LIBUTIL_CALCULATOR_H__ +#define __LIBUTIL_CALCULATOR_H__ + +#include +#include + +#include "mem/ruby/network/dsent/dsent-core/libutil/String.hh" +#include "mem/ruby/network/dsent/dsent-core/libutil/Map.hh" +#include "mem/ruby/network/dsent/dsent-core/libutil/Assert.hh" + +namespace LibUtil +{ + using std::istringstream; + + /* + * program: + * END // END is end-of-input + * expr_list END + * + * expr_list: + * expression SEP expr_list // SEP is semicolon + * expression + * print expression + * print STRING + * print STRING expression + * print STRING expression SEP expr_list + * + * + * expression: + * expression + term + * expression - term + * term + * + * term: + * term / primary + * term * primary + * primary + * + * primary: + * NUMBER + * NAME + * NAME = expression + * NAME string expression // NAME is print + * - primary + * ( expression ) + * + * string: + * + **/ + + class Calculator + { + protected: + enum Token + { + NAME, NAME2, NUMBER, STRING, END, + PLUS = '+', MINUS = '-', MUL = '*', DIV = '/', + SEP = ';', ASSIGN = '=', LP = '(', RP = ')' + }; + + public: + Calculator(); + virtual ~Calculator(); + + public: + void reset(); + void evaluateString(const String& str_, std::ostream& ost_ = std::cout); + + protected: + Token getToken(istringstream& ist_); + double prim(istringstream& ist_, bool is_get_); + double term(istringstream& ist_, bool is_get_); + double expr(istringstream& ist_, bool is_get_); + virtual double getEnvVar(const String& var_name_) const; + + protected: + String m_reserved_chars_; + Map m_var_; + + Token m_curr_token_; + double m_value_number_; + String m_value_string_; + }; // class Calculator +} // namespace LibUtil + +#endif // __LIBUTIL_CALCULATOR_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/libutil/Calculator.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/libutil/Calculator.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/libutil/Calculator.hh" + +#include +#include + +namespace LibUtil +{ + using std::endl; + using std::ostream; + using std::scientific; + + Calculator::Calculator() + { + m_reserved_chars_ = "+-*/;=()\\"; + } + + Calculator::~Calculator() + {} + + void Calculator::reset() + { + m_var_.clear(); + return; + } + + void Calculator::evaluateString(const String& str_, ostream& ost_) + { + istringstream ist(str_); + while(ist) + { + getToken(ist); + if(m_curr_token_ == END) break; + if(m_curr_token_ == SEP) continue; + if((m_curr_token_ == NAME) && (m_value_string_ == "print")) + { + getToken(ist); + + while(1) + { + if((m_curr_token_ == SEP) || (m_curr_token_ == END)) + { + ost_ << endl; + break; + } + else if(m_curr_token_ == STRING) + { + ost_ << m_value_string_; + } + else + { + double v = expr(ist, false); + ost_ << scientific << v; + continue; + } + + getToken(ist); + } + } + else + { + expr(ist, false); + } + } + return; + } + + Calculator::Token Calculator::getToken(istringstream& ist_) + { + char ch; + do + { + ist_.get(ch); + if(!ist_) + { + m_curr_token_ = END; + return m_curr_token_; + } + } + while(ch != '\n' && isspace(ch)); + + switch(ch) + { + case '\n': + m_curr_token_ = END; + return m_curr_token_; + case ';': + m_curr_token_ = SEP; + return m_curr_token_; + case '*': + case '/': + case '+': + case '-': + case '(': + case ')': + case '=': + m_curr_token_ = Token(ch); + return m_curr_token_; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case '.': + ist_.putback(ch); + ist_ >> m_value_number_; + m_curr_token_ = NUMBER; + return m_curr_token_; + case '"': + ist_.get(ch); + m_value_string_ = ""; + while(ist_ && ('"' != ch)) + { + m_value_string_ += String(1, ch); + ist_.get(ch); + } + m_curr_token_ = STRING; + return m_curr_token_; + case '$': + ist_.get(ch); + ASSERT((ch == '('), "[Error] Bad token: '(' expected"); + ist_.get(ch); + m_value_string_ = ""; + while(ist_ && (!isspace(ch)) && (')' != ch)) + { + m_value_string_ += String(1, ch); + ist_.get(ch); + } + m_curr_token_ = NAME2; + return m_curr_token_; + default: + if(isalpha(ch)) + { + m_value_string_ = ch; + ist_.get(ch); + while(ist_ && (isalnum(ch) || ('_' == ch))) + { + m_value_string_ += String(1, ch); + ist_.get(ch); + } + ist_.putback(ch); + m_curr_token_ = NAME; + return m_curr_token_; + } + else + { + String error_msg = "[Error] Bad token: '" + String(ch) + "'"; + throw Exception(error_msg); + } + } + } + + double Calculator::prim(istringstream& ist_, bool is_get_) + { + if(is_get_) + { + getToken(ist_); + } + + double v; + switch(m_curr_token_) + { + case NUMBER: + v = m_value_number_; + getToken(ist_); + return v; + case NAME: + if(getToken(ist_) == ASSIGN) + { + String var_name = m_value_string_; + v = expr(ist_, true); + m_var_.set(var_name, v); + } + else + { + v = m_var_.get(m_value_string_); + } + return v; + case NAME2: + v = getEnvVar(m_value_string_); + getToken(ist_); + return v; + case MINUS: + return -prim(ist_, true); + case LP: + v = expr(ist_, true); + ASSERT((m_curr_token_ == RP), "[Error] ')' expected"); + getToken(ist_); + return v; + default: + ASSERT(0, "[Error] primary expected, get: '" + String(int(m_curr_token_)) + "'"); + } + } + + double Calculator::term(istringstream& ist_, bool is_get_) + { + double left = prim(ist_, is_get_); + + while(1) + { + double d; + switch(m_curr_token_) + { + case MUL: + left *= prim(ist_, true); + break; + case DIV: + d = prim(ist_, true); + ASSERT(d, "[Error] divided by 0"); + left /= d; + break; + default: + return left; + } + } + } + + double Calculator::expr(istringstream& ist_, bool is_get_) + { + double left = term(ist_, is_get_); + + while(1) + { + switch(m_curr_token_) + { + case PLUS: + left += term(ist_, true); + break; + case MINUS: + left -= term(ist_, true); + break; + default: + return left; + } + } + } + + double Calculator::getEnvVar(const String& var_name_) const + { + return m_var_.get(var_name_); + } +} // namespace LibUtil + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/libutil/Config.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/libutil/Config.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __LIBUTIL_CONFIG_H__ +#define __LIBUTIL_CONFIG_H__ + +#include + +#include "mem/ruby/network/dsent/dsent-core/libutil/Map.hh" + +namespace LibUtil +{ + class Config : public StringMap + { + public: + Config(const String& delimiter_ = "=", const String& comment_ = "#", const String& sentry_ = "End"); + Config(const Config& config_); + virtual ~Config(); + + public: + // Make a copy of this instance + virtual Config* clone() const; + // Load the config from file + virtual void readFile(const String& filename_); + // Parse string and overwrite the Config instance if keys exist + virtual void readString(const String& str_); + + // Write or read map using standard IO + friend std::ostream& operator<<(std::ostream& ost_, const Config& config_); + friend std::istream& operator>>(std::istream& ist_, Config& config_); + + protected: + String mDelimiter; + String mComment; + String mSentry; + }; +} + +#endif // __LIBUTIL_CONFIG_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/libutil/Config.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/libutil/Config.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/libutil/Config.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/libutil/Assert.hh" + +namespace LibUtil +{ + Config::Config(const String& delimiter_, const String& comment_, const String& sentry_) + : mDelimiter(delimiter_), mComment(comment_), mSentry(sentry_) + {} + + Config::Config(const Config& config_) + : StringMap(config_) + { + mDelimiter = config_.mDelimiter; + mComment = config_.mComment; + mSentry = config_.mSentry; + } + + Config::~Config() + {} + + Config* Config::clone() const + { + return new Config(*this); + } + + void Config::readFile(const String& filename_) + { + std::ifstream fin(filename_.c_str()); + + ASSERT(fin, "File not found: " + filename_); + fin >> (*this); + return; + } + + void Config::readString(const String& str_) + { + String newString = str_; + newString.substitute(";", "\n"); + std::istringstream iss(newString, std::istringstream::in); + + iss >> (*this); + } + + std::ostream& operator<<(std::ostream& ost_, const Config& config_) + { + Config::ConstIterator it; + for(it = config_.begin(); it != config_.end(); it++) + { + ost_ << it->first << " " << config_.mDelimiter << " "; + ost_ << it->second << std::endl; + } + return ost_; + } + + std::istream& operator>>(std::istream& ist_, Config& config_) + { + // Set a Config from ist_ + // Read in keys and values, keeping internal whitespace + typedef String::size_type pos; + const String& delim = config_.mDelimiter; // separator + const String& comm = config_.mComment; // comment + const String& sentry = config_.mSentry; // end of file sentry + const pos skip = delim.length(); // length of separator + + String nextline = ""; // might need to read ahead to see where value ends + + while(ist_ || nextline.length() > 0) + { + // Read an entire line at a time + String line; + if(nextline.length() > 0) + { + line = nextline; // we read ahead; use it now + nextline = ""; + } + else + { + //std::getline(ist_, line); + safeGetline(ist_, line); + } + + // Ignore comments and the spaces on both ends + line = line.substr(0, line.find(comm)); + line.trim(); + + // Check for end of file sentry + if((sentry != "") && (line.find(sentry) != String::npos)) return ist_; + + if(line.length() == 0) + continue; + + // Parse the line if it contains a delimiter + pos delimPos = line.find(delim); + ASSERT((delimPos < String::npos), "Invalid config line: '" + line + "'"); + + // Extract the key + String key = line.substr(0, delimPos); + line.replace(0, delimPos+skip, ""); + + // See if value continues on the next line + // Stop at blank line, next line with a key, end of stream, + // or end of file sentry + bool terminate = false; + while(!terminate && ist_) + { + if(line.at(line.size() - 1) == '\\') + line.erase(line.size() - 1); + else + break; + + //std::getline(ist_, nextline); + safeGetline(ist_, nextline); + terminate = true; + + String nlcopy = nextline; + nlcopy.trim(); + if(nlcopy == "") continue; + + nextline = nextline.substr(0, nextline.find(comm)); + //if(nextline.find(delim) != String::npos) + // continue; + if((sentry != "") && (nextline.find(sentry) != String::npos)) + continue; + + //nlcopy = nextline; + //nlcopy.trim(); + //if(nlcopy != "") line += "\n"; + line += nextline; + nextline = ""; + terminate = false; + } + + // Store key and value + key.trim(); + line.trim(); + config_.set(key, line); // overwrites if key is repeated + } + return ist_; + } +} + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/libutil/Exception.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/libutil/Exception.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __EXCEPTION_H__ +#define __EXCEPTION_H__ + +#include + +#include "mem/ruby/network/dsent/dsent-core/libutil/String.hh" + +namespace LibUtil +{ + using std::exception; + + // Exception class handles the all exception messages in the program + class Exception : public exception + { + public: + // All constructors/destructors/functions in this class don't throw any events + Exception(const String& exception_msg_) throw(); + ~Exception() throw(); + + // Derived from std::exception class that returns a null-terminated char string + const char* what() const throw(); + + private: + String mExceptionMsg; + }; +} + +#endif // __EXCEPTION_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/libutil/Exception.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/libutil/Exception.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/libutil/Exception.hh" + +namespace LibUtil +{ + Exception::Exception(const String& exception_msg_) throw() + : exception(), mExceptionMsg(exception_msg_) + {} + + Exception::~Exception() throw() + {} + + const char* Exception::what() const throw() + { + return mExceptionMsg.c_str(); + } +} + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/libutil/LibUtil.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/libutil/LibUtil.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __LIBUTIL_H__ +#define __LIBUTIL_H__ + +#include + +#include "mem/ruby/network/dsent/dsent-core/libutil/String.hh" +#include "mem/ruby/network/dsent/dsent-core/libutil/Exception.hh" +#include "mem/ruby/network/dsent/dsent-core/libutil/Assert.hh" +#include "mem/ruby/network/dsent/dsent-core/libutil/Map.hh" +#include "mem/ruby/network/dsent/dsent-core/libutil/Log.hh" +#include "mem/ruby/network/dsent/dsent-core/libutil/Config.hh" +#include "mem/ruby/network/dsent/dsent-core/libutil/MathUtil.hh" + +namespace LibUtil +{ + template void clearPtrVector(std::vector* vec_) + { + for(typename std::vector::iterator it = vec_->begin(); it != vec_->end(); ++it) + { + T* temp_T = (*it); + delete temp_T; + } + vec_->clear(); + return; + } + + template void deletePtrVector(std::vector* vec_) + { + clearPtrVector(vec_); + delete vec_; + return; + } + +} // namespace LibUtil + +#endif // __LIBUTIL_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/libutil/Log.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/libutil/Log.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __LOG_H__ +#define __LOG_H__ + +#include +#include +#include + +#include "mem/ruby/network/dsent/dsent-core/libutil/String.hh" + +#ifndef LIBUTIL_IS_LOG +#define LIBUTIL_IS_LOG false +#endif + +namespace LibUtil +{ + using std::cerr; + + class Log + { + public: + static void allocate(const String& log_file_name_); + static void release(); + + static void print(const String& str_); + static void print(std::ostream& stream_, const String& str_); + static void printLine(const String& str_); + static void printLine(std::ostream& stream_, const String& str_); + + protected: + static Log* msSingleton; + static const bool msIsLog; + + protected: + Log(const String& log_file_name_); + ~Log(); + + protected: + std::ofstream ofs; + }; +} + +#endif // __LOG_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/libutil/Log.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/libutil/Log.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/libutil/Log.hh" + +#include "mem/ruby/network/dsent/dsent-core/libutil/Assert.hh" + +namespace LibUtil +{ + using std::ostream; + using std::endl; + + Log* Log::msSingleton = NULL; + const bool Log::msIsLog = LIBUTIL_IS_LOG; + + void Log::allocate(const String& log_file_name_) + { + if(msIsLog) + { + // Allocate static Config instance + ASSERT(!msSingleton, "Log singleton is allocated"); + msSingleton = new Log(log_file_name_); + } + } + + void Log::release() + { + if(msIsLog) + { + ASSERT(msSingleton, "Log singleton is not allocated"); + delete msSingleton; + msSingleton = NULL; + } + return; + } + + void Log::print(const String& str_) + { + if(msIsLog) + { + ASSERT(msSingleton, "Log singleton is not allocated"); + msSingleton->ofs << str_; + } + return; + } + + void Log::print(ostream& stream_, const String& str_) + { + if(msIsLog) + { + ASSERT(msSingleton, "Log singleton is not allocated"); + msSingleton->ofs << str_; + } + stream_ << str_; + return; + } + + void Log::printLine(const String& str_) + { + if(msIsLog) + { + ASSERT(msSingleton, "Log singleton is not allocated"); + msSingleton->ofs << str_ << endl; + } + return; + } + + void Log::printLine(ostream& stream_, const String& str_) + { + if(msIsLog) + { + ASSERT(msSingleton, "Log singleton is not allocated"); + msSingleton->ofs << str_ << endl; + } + stream_ << str_ << endl; + return; + } + + Log::Log(const String& log_file_name_) + { + ofs.open(log_file_name_.c_str()); + } + + Log::~Log() + { + ofs.close(); + } +} + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/libutil/Map.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/libutil/Map.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __MAP_H__ +#define __MAP_H__ + +#include +#include + +#include "mem/ruby/network/dsent/dsent-core/libutil/String.hh" +#include "mem/ruby/network/dsent/dsent-core/libutil/Assert.hh" + +namespace LibUtil +{ + using std::map; + + template class Map + { + public: + typedef typename map::iterator Iterator; + typedef typename map::const_iterator ConstIterator; + typedef typename map::size_type SizeType; + + public: + Map(); + virtual ~Map(); + + public: + // Return a new copy of this Map instance + Map* clone() const; + // Copy map_ to this instance + void copyFrom(const Map* map_); + // Return the size of the map + SizeType size() const; + // Check if the map is empty + bool isEmpty() const; + // Check if the key exists + bool keyExist(const String& key_) const; + // Get the value_ corresponding to the key_ + const T& get(const String& key_) const; + // Get the value_ corresponding to the key_ if the key_ exist, otherwise, the default_value_is returned + const T& getIfKeyExist(const String& key_, const T& default_value_ = T()) const; + // Add/Update a entry + void set(const String& key_, const T& value_); + // Get iterator to the element + Iterator find(const String& key_); + ConstIterator find(const String& key_) const; + // Remove an entry corresponding to key_ + void remove(const String& key_); + // Remove an entry at 'it' + void remove(Iterator it); + // Remove all keys + void clear(); + // Merge a map. Values with same key will be overwritten. + void merge(const Map* map_); + // Returns a MapIterator referring to the first element in the map + Iterator begin(); + ConstIterator begin() const; + // Returns a MapIterator referring to the past-the-end element in the map + Iterator end(); + ConstIterator end() const; + + protected: + Map(const Map& map_); + + protected: + map mMap; + }; + + template Map::Map() + {} + + template Map::~Map() + {} + + template Map* Map::clone() const + { + return new Map(*this); + } + + template void Map::copyFrom(const Map* map_) + { + // Remove all keys (it won't free the content if T is a pointer) + mMap.clear(); + + // Copy the contents + mMap = map_->mMap; + } + + template typename Map::SizeType Map::size() const + { + return mMap.size(); + } + + template bool Map::isEmpty() const + { + return (mMap.empty()); + } + + template bool Map::keyExist(const String& key_) const + { + ConstIterator it = mMap.find(key_); + return (it != mMap.end()); + } + + template const T& Map::get(const String& key_) const + { + ConstIterator it; + + it = mMap.find(key_); + ASSERT((it != mMap.end()), "Key not found: " + key_); + return (it->second); + } + + template const T& Map::getIfKeyExist(const String& key_, const T& default_value_) const + { + if(keyExist(key_)) + { + return get(key_); + } + else + { + return default_value_; + } + } + + template void Map::set(const String& key_, const T& value_) + { + mMap[key_] = value_; + return; + } + + template typename Map::Iterator Map::find(const String& key_) + { + return mMap.find(key_); + } + + template typename Map::ConstIterator Map::find(const String& key_) const + { + return mMap.find(key_); + } + + template void Map::remove(const String& key_) + { + mMap.erase(key_); + return; + } + + template void Map::remove(Iterator it) + { + mMap.erase(it); + return; + } + + template void Map::clear() + { + mMap.clear(); + return; + } + + template void Map::merge(const Map* map_) + { + ConstIterator it; + for(it = map_->begin(); it != map_->end(); it++) + { + const String& key = it->first; + const T& value = it->second; + set(key, value); + } + return; + } + + template typename Map::Iterator Map::begin() + { + return mMap.begin(); + } + + template typename Map::ConstIterator Map::begin() const + { + return mMap.begin(); + } + + template typename Map::Iterator Map::end() + { + return mMap.end(); + } + + template typename Map::ConstIterator Map::end() const + { + return mMap.end(); + } + + inline std::ostream& operator<<(std::ostream& ost_, const Map& map_) + { + Map::ConstIterator it; + for(it = map_.begin(); it != map_.end(); it++) + { + ost_ << it->first << " = " << it->second << std::endl; + } + return ost_; + } + + template Map::Map(const Map& map_) + : mMap(map_.mMap) + {} + + typedef Map StringMap; + + + // Handy function to delete all pointers in a map + template void clearPtrMap(Map* map_) + { + for(typename Map::Iterator it = map_->begin(); it != map_->end(); ++it) + { + T* temp_T = it->second; + delete temp_T; + } + map_->clear(); + return; + } + + // Handy function to delete all pointers in a map and the map itself + template void deletePtrMap(Map* map_) + { + clearPtrMap(map_); + delete map_; + return; + } + + // Handy function to clone all pointers in a map + template Map* clonePtrMap(const Map* map_) + { + Map* new_T_map = new Map; + for(typename Map::ConstIterator it = map_->begin(); it != map_->end(); ++it) + { + const String& temp_name = it->first; + const T* temp_T = it->second; + new_T_map->set(temp_name, temp_T->clone()); + } + return new_T_map; + } +} + +#endif // __MAP_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/libutil/MathUtil.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/libutil/MathUtil.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __MATH_H__ +#define __MATH_H__ + +#include + +namespace LibUtil +{ + class Math + { + public: + static const double epsilon; + + static inline bool isEqual(double value1_, double value2_) + { + return (std::fabs(value1_ - value2_) < epsilon); + } + }; +} // namespace LibUtil + +#endif // __MATH_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/libutil/MathUtil.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/libutil/MathUtil.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/libutil/MathUtil.hh" + +namespace LibUtil +{ + const double Math::epsilon = 1e-15; +} // namespace LibUtil + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/libutil/OptionParser.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/libutil/OptionParser.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __LIBUTIL_OPTION_PARSER_H__ +#define __LIBUTIL_OPTION_PARSER_H__ + +#include +#include +#include + +#include "mem/ruby/network/dsent/dsent-core/libutil/Map.hh" + +namespace LibUtil +{ + using std::vector; + + // Simple option parser + class OptionParser : public StringMap + { + private: + class OptionInfo + { + public: + OptionInfo(const String& var_name_, bool has_arg_, const String& arg_name_, bool has_default_arg_value_, const String& default_arg_value_, const String& description_); + ~OptionInfo(); + + public: + inline const String& getVarName() const { return m_var_name_; } + inline bool hasArg() const { return m_has_arg_; } + inline const String& getArgName() const { return m_arg_name_; } + inline bool hasDefaultArgValue() const { return m_has_default_arg_value_; } + inline const String& getDefaultArgValue() const { return m_default_arg_value_; } + inline const String& getDescription() const { return m_description_; } + + private: + String m_var_name_; + bool m_has_arg_; + String m_arg_name_; + bool m_has_default_arg_value_; + String m_default_arg_value_; + String m_description_; + }; // class Option + + public: + OptionParser(); + virtual ~OptionParser(); + + public: + void addOption(const String& option_name_, const String& var_name_, bool has_arg_, const String& arg_name_, bool has_default_arg_value_, const String& default_arg_value_, const String& description_); + + void parseArguments(int argc_, char** argv_, std::ostream& ost_ = std::cout); + + void printOptions(std::ostream& ost_ = std::cout) const; + + protected: + vector m_option_names_; + Map m_option_infos_; + }; // class OptionParser +} // LibUtil + +#endif // __LIBUTIL_OPTION_PARSER_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/libutil/OptionParser.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/libutil/OptionParser.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/libutil/OptionParser.hh" + +#include +#include + +namespace LibUtil +{ + using std::cerr; + using std::ostream; + using std::endl; + + OptionParser::OptionInfo::OptionInfo( + const String& var_name_, + bool has_arg_, + const String& arg_name_, + bool has_default_arg_value_, + const String& default_arg_value_, + const String& description_ + ) + : m_var_name_(var_name_), + m_has_arg_(has_arg_), + m_arg_name_(arg_name_), + m_has_default_arg_value_(has_default_arg_value_), + m_default_arg_value_(default_arg_value_), + m_description_(description_) + {} + + OptionParser::OptionInfo::~OptionInfo() + { + } + + OptionParser::OptionParser() + {} + + OptionParser::~OptionParser() + { + clearPtrMap(&m_option_infos_); + } + + void OptionParser::addOption( + const String& option_name_, + const String& var_name_, + bool has_arg_, + const String& arg_name_, + bool has_default_arg_value_, + const String& default_arg_value_, + const String& description_) + { + OptionInfo* option_info = new OptionInfo(var_name_, has_arg_, arg_name_, + has_default_arg_value_, default_arg_value_, description_); + + ASSERT(!m_option_infos_.keyExist(option_name_), "Option exists: " + option_name_); + + // Add the option name to an array for sorting + m_option_names_.push_back(option_name_); + + // Add option info + m_option_infos_.set(option_name_, option_info); + + // Set the default argument value + if(has_default_arg_value_) + { + set(var_name_, default_arg_value_); + } + + return; + } + + void OptionParser::parseArguments(int argc_, char** argv_, ostream& ost_) + { + bool is_print_options = false; + int arg_idx = 0; + + while(arg_idx < argc_) + { + String option_name = String(argv_[arg_idx]); + + // Print the options page if -help is specified + if(option_name == "-help") + { + is_print_options = true; + break; + } + else if(m_option_infos_.keyExist(option_name)) + { + const OptionInfo* option_info = m_option_infos_.get(option_name); + const String& var_name = option_info->getVarName(); + if(option_info->hasArg()) + { + if((arg_idx + 1) >= argc_) + { + cerr << "[Error] Missing argument for option: '" << option_name << "'" << endl; + is_print_options = true; + break; + } + + String option_arg = String(argv_[arg_idx + 1]); + set(var_name, option_arg); + + arg_idx += 2; + } + else + { + // If the option does not require an argument + // then set it to true + set(var_name, "true"); + + arg_idx += 1; + } + } + else + { + cerr << "[Error] Unknown option: '" << option_name << "'" << endl; + is_print_options = true; + break; + } + } + + // Check if all required options are set (the ones without default values) + vector::const_iterator it; + for(it = m_option_names_.begin(); it != m_option_names_.end(); ++it) + { + const String& option_name = *it; + const OptionInfo* option_info = m_option_infos_.get(option_name); + + if(!option_info->hasDefaultArgValue()) + { + const String& var_name = option_info->getVarName(); + if(!keyExist(var_name)) + { + cerr << "[Error] Missing required option: '" << option_name << "'" << endl; + is_print_options = true; + } + } + } + + if(is_print_options) + { + printOptions(ost_); + exit(0); + } + return; + } + + void OptionParser::printOptions(ostream& ost_) const + { + ost_ << endl; + ost_ << "Available options:" << endl; + ost_ << "==================" << endl << endl; + + vector::const_iterator it; + for(it = m_option_names_.begin(); it != m_option_names_.end(); ++it) + { + const String& option_name = *it; + const OptionInfo* option_info = m_option_infos_.get(option_name); + + ost_ << option_name; + if(option_info->hasArg()) + { + ost_ << " <" << option_info->getArgName() << ">"; + } + ost_ << endl; + + ost_ << " " << option_info->getDescription() << endl; + if(option_info->hasArg() && option_info->hasDefaultArgValue()) + { + ost_ << " " << "Default: " << option_info->getDefaultArgValue() << endl; + } + ost_ << endl; + } + ost_ << "-help" << endl; + ost_ << " " << "Print this page" << endl; + ost_ << endl; + return; + } + +} // namespace LibUtil diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/libutil/SConscript --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/libutil/SConscript Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,40 @@ +# 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. +# +# Authors: Chia-Hsin Owen Chen + +Import('*') + +if env['PROTOCOL'] == 'None': + Return() + +Source('Exception.cc') +Source('Config.cc') +Source('String.cc') +Source('Log.cc') +Source('OptionParser.cc') +Source('MathUtil.cc') +Source('Calculator.cc') + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/libutil/String.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/libutil/String.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __STRING_H__ +#define __STRING_H__ + +#include +#include +#include +#include +#include + +namespace LibUtil +{ + using std::string; + using std::vector; + + class String : public string + { + public: + static String format(const String& format_, ...); + static String format(const String& format_, va_list args_); + template static String toString(const T& value_); + static String toBitString(unsigned int value_, unsigned int num_bits_); + template static T fromString(const String& str_); + + private: + static const unsigned int msBufferSize; + + public: + String(); + String(const string& str_); + String(const char* str_, size_t n); + String(const char* str_); + String(size_t n, char c); + String(int value_); + String(unsigned int value_); + String(long value_); + String(unsigned long value_); + String(float value_); + String(double value_); + String(bool value_); + ~String(); + + public: + // Remove leading and trailing whitespace + String& trim(); + // Substitute str1 with str2 + String& substitute(const String& str1_, const String& str2_); + // Split the String into vector of Strings separated by delimiters_ + vector split(const char* delimiters_) const; + vector split(const String* delimiters_, unsigned int num_delimiters_ = 1) const; + vector splitByString(const String& delimiters_) const; + + // Check if contains str + bool contain(const String& str_) const; + + public: + // Convertions + const char* toCString() const; + int toInt() const; + unsigned int toUInt() const; + long toLong() const; + unsigned long toULong() const; + float toFloat() const; + double toDouble() const; + bool toBool() const; + operator const char*() const; + operator int() const; + operator unsigned int() const; + operator long() const; + operator unsigned long() const; + operator float() const; + operator double() const; + operator bool() const; + String& operator=(char c_); + }; + + template String String::toString(const T& value_) + { + std::ostringstream ost; + ost << value_; + return ost.str(); + } + + template<> inline String String::toString(const bool& value_) + { + if(value_ == true) + { + return "TRUE"; + } + else + { + return "FALSE"; + } + } + + inline String String::toBitString(unsigned int value_, unsigned int num_bits_) + { + std::bitset bitSet(value_); + String ret = String(bitSet.to_string()); + ret = ret.substr(ret.length()-num_bits_); + return ret; + } + + template T String::fromString(const String& str_) + { + T ret; + std::istringstream ist(str_); + ist >> ret; + return ret; + } + + template<> inline String String::fromString(const String& str_) + { + return str_; + } + + template<> inline bool String::fromString(const String& str_) + { + bool ret; + if((str_ == String("TRUE")) || (str_ == String("true"))) + { + ret = true; + } + else if((str_ == string("FALSE")) || (str_ == String("false"))) + { + ret = false; + } + else + { + //std::cerr << "Invalid bool value: " << str_ << std::endl; + throw ("Invalid bool value: " + str_); + } + return ret; + } + + template String arrayToString( + const T* array_, unsigned int start_index_, unsigned int end_index_, + const String& delimiters_ + ) + { + // Ensure end_index_ >= start_index_ + 1 + if(end_index_ <= start_index_) + { + throw("Invalid index range: start_index = " + (String)start_index_ + ", end_index = " + (String)end_index_); + } + + String ret = "["; + for(unsigned int i = start_index_; i < (end_index_-1); ++i) + { + ret += (String)array_[i] + delimiters_; + } + ret += (String)array_[end_index_-1] + "]"; + return ret; + } + + template String arrayToString(const T* array_, unsigned int num_elements_) + { + return arrayToString(array_, 0, num_elements_, ", "); + } + + template String arrayToString(const T* array_, unsigned int start_index_, unsigned int end_index_) + { + return arrayToString(array_, start_index_, end_index_); + } + + template String vectorToString( + const vector& vector_, unsigned int start_index_, unsigned int end_index_, + const String& delimiters_ + ) + { + // Ensure end_index_ >= start_index_ + 1, or if the vector is empty + if((end_index_ <= start_index_) || (end_index_ > vector_.size())) + { + // If the vector is empty, return empty array + if (vector_.size() == 0) + return "[]"; + + throw("Invalid index range: start_index = " + (String)start_index_ + ", end_index = " + (String)end_index_); + } + + String ret = "["; + for(unsigned int i = start_index_; i < (end_index_-1); ++i) + { + ret += (String)vector_[i] + delimiters_; + } + ret += (String)vector_[end_index_-1] + "]"; + return ret; + } + + template String vectorToString(const vector& vector_) + { + return vectorToString(vector_, 0, vector_.size(), ", "); + } + + template String vectorToString(const vector& vector_, unsigned int num_elements_) + { + return vectorToString(vector_, 0, num_elements_, ", "); + } + + template String vectorToString(const vector& vector_, unsigned int start_index_, unsigned int end_index_) + { + return vectorToString(vector_, start_index_, end_index_); + } + + template vector castStringVector(const vector& vector_) + { + vector ret_vector; + for(unsigned int i = 0; i < vector_.size(); ++i) + { + ret_vector.push_back((T)vector_[i]); + } + return ret_vector; + } + + std::istream& safeGetline(std::istream& is_, String& str_); +} // namespace LibUtil + +#endif // __STRING_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/libutil/String.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/libutil/String.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,378 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/libutil/String.hh" + +#include +#include +#include +#include + +namespace LibUtil +{ + const unsigned int String::msBufferSize = 4096; + + String String::format(const String& format_, ...) + { + char buffer[msBufferSize]; + + va_list args; + va_start(args, format_); + vsnprintf(buffer, msBufferSize, format_.c_str(), args); + va_end(args); + + return (String)(buffer); + } + + String String::format(const String& format_, va_list args_) + { + char buffer[msBufferSize]; + + vsnprintf(buffer, msBufferSize, format_.c_str(), args_); + + return (String)(buffer); + } + + String::String() + {} + + String::String(const string& str_) + : string(str_) + {} + + String::String(const char* str_, size_t n_) + : string(str_, n_) + {} + + String::String(const char* str_) + : string(str_) + {} + + String::String(size_t n_, char c_) + : string(n_, c_) + {} + + String::String(int value_) + : string(toString(value_)) + {} + + String::String(unsigned int value_) + : string(toString(value_)) + {} + + String::String(long value_) + : string(toString(value_)) + {} + + String::String(unsigned long value_) + : string(toString(value_)) + {} + + String::String(float value_) + : string(toString(value_)) + {} + + String::String(double value_) + : string(toString(value_)) + {} + + String::String(bool value_) + : string(toString(value_)) + {} + + String::~String() + {} + + String& String::trim() + { + // Remove leading and trailing whitespace + static const char whitespace[] = " \n\t\v\r\f"; + erase(0, find_first_not_of(whitespace)); + erase(find_last_not_of(whitespace) + 1U); + return (*this); + } + + String& String::substitute(const String& str1_, const String& str2_) + { + size_t str1Size = str1_.size(); + size_t str2Size = str2_.size(); + + size_t pos; + pos = find(str1_); + while(pos != string::npos) + { + replace(pos, str1Size, str2_); + pos += str2Size; + pos = find(str1_, pos); + } + return (*this); + } + + vector String::split(const char* delimiters_) const + { + vector result; + + if(size() == 0) + { + return result; + } + + size_t currPos, nextPos; + currPos = 0; + nextPos = find_first_of(delimiters_); + while(1) + { + if(nextPos == string::npos) + { + if(currPos != size()) + { + result.push_back(substr(currPos)); + } + break; + } + + if(nextPos != currPos) + { + result.push_back(substr(currPos, nextPos - currPos)); + } + currPos = nextPos + 1; + nextPos = find_first_of(delimiters_, currPos); + } + + return result; + } + + vector String::split(const String* delimiters_, unsigned int num_delimiters_) const + { + vector result; + + if(size() == 0) + { + return result; + } + + if(num_delimiters_ == 1) + { + size_t currPos, nextPos; + currPos = 0; + nextPos = find(delimiters_[0]); + while(1) + { + if(nextPos == String::npos) + { + result.push_back(substr(currPos)); + break; + } + + if(nextPos != currPos) + { + result.push_back(substr(currPos, nextPos - currPos)); + } + currPos = nextPos + delimiters_[0].size(); + nextPos = find(delimiters_[0], currPos); + } + } + else + { + // Currently the length of the delimiters are not checked + unsigned int delimiterLength = 0; + size_t currPos, nextPos; + currPos = 0; + nextPos = size(); + for(unsigned int i = 0; i < num_delimiters_; ++i) + { + size_t tempPos = find(delimiters_[i], currPos); + if((tempPos != String::npos) && (tempPos < nextPos)) + { + nextPos = tempPos; + delimiterLength = delimiters_[i].size(); + } + } + while(1) + { + if((nextPos == String::npos) || (nextPos == size())) + { + result.push_back(substr(currPos)); + break; + } + + if(nextPos != currPos) + { + result.push_back(substr(currPos, nextPos - currPos)); + } + currPos = nextPos + delimiterLength; + nextPos = size(); + delimiterLength = 0; + for(unsigned int i = 0; i < num_delimiters_; ++i) + { + size_t tempPos = find(delimiters_[i], currPos); + if((tempPos != String::npos) && (tempPos < nextPos)) + { + nextPos = tempPos; + delimiterLength = delimiters_[i].size(); + } + } + } + } + return result; + } + + vector String::splitByString(const String& delimiter_) const + { + return split(&delimiter_, 1); + } + + bool String::contain(const String& str_) const + { + return (find(str_) != String::npos); + } + + const char* String::toCString() const + { + return this->c_str(); + } + + int String::toInt() const + { + return fromString(*this); + } + + unsigned int String::toUInt() const + { + return fromString(*this); + } + + long String::toLong() const + { + return fromString(*this); + } + + unsigned long String::toULong() const + { + return fromString(*this); + } + + float String::toFloat() const + { + return fromString(*this); + } + + double String::toDouble() const + { + return fromString(*this); + } + + bool String::toBool() const + { + return fromString(*this); + } + + String::operator const char*() const + { + return this->c_str(); + } + + String::operator int() const + { + return fromString(*this); + } + + String::operator unsigned int() const + { + return fromString(*this); + } + + String::operator long() const + { + return fromString(*this); + } + + String::operator unsigned long() const + { + return fromString(*this); + } + + String::operator float() const + { + return fromString(*this); + } + + String::operator double() const + { + return fromString(*this); + } + + String::operator bool() const + { + return fromString(*this); + } + + String& String::operator=(char c_) + { + this->assign(1, c_); + return *this; + } + + std::istream& safeGetline(std::istream& is_, String& str_) + { + str_.clear(); + + // The characters in the stream are read one-by-one using a std::streambuf. + // That is faster than reading them one-by-one using the std::istream. + // Code that uses streambuf this way must be guarded by a sentry object. + // The sentry object performs various tasks, + // such as thread synchronization and updating the stream state. + + std::istream::sentry se(is_, true); + std::streambuf* sb = is_.rdbuf(); + + while(1) + { + int c = sb->sbumpc(); + switch(c) + { + case '\r': + c = sb->sgetc(); + if(c == '\n') + sb->sbumpc(); + return is_; + case '\n': + return is_; + case EOF: + is_.setstate(std::ios_base::failbit|std::ios_base::eofbit); + return is_; + default: + str_ += String(1, (char)c); + } + } + } +} // namespace LibUtil + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_ELECTRICALMODEL_H__ +#define __DSENT_MODEL_ELECTRICALMODEL_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/Model.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" + +namespace DSENT +{ + class PortInfo; + class EventInfo; + class ElectricalDriver; + class ElectricalDriverMultiplier; + class ElectricalNet; + class ElectricalLoad; + class ElectricalDelay; + + // A Net index consisting of a start and end index + typedef std::pair NetIndex; + + // Helper function to make net index + inline NetIndex makeNetIndex(int start_index_, int end_index_) + { + ASSERT((end_index_ >= start_index_), (String)"[Error] Invalid net index range " + + + "[" + (String)start_index_ + ":" + (String)end_index_ + "]"); + + return NetIndex(start_index_, end_index_); + } + + // Helper function to make net index + inline NetIndex makeNetIndex(int index_) + { + return makeNetIndex(index_, index_); + } + + // Helper function to trun NetIndex to String + inline String toString(const NetIndex& net_index_) + { + return "[" + String(net_index_.second) + ":" + String(net_index_.first) + "]"; + } + + // ElectricalModel specifies physical connectivity to other models as well as the port + // parameters for the current model + class ElectricalModel : public Model + { + public: + ElectricalModel(const String& instance_name_, const TechModel* tech_model_); + virtual ~ElectricalModel(); + + public: + // Check if all properties needed exist in the m_properties_ + virtual void checkProperties() const; + // Set available driving strength vector from string + void setAvailableDrivingStrengths(const String& driving_strengths_); + + //----------------------------------------------------------------- + // Connectivity specification + //----------------------------------------------------------------- + // Net Indices + const Map* getNetReferences() const; + const NetIndex getNetReference(const String& name_) const; + // Input Ports + void createInputPort(const String& name_, const NetIndex& net_indices_ = NetIndex(0, 0)); + const Map* getInputs() const; + PortInfo* getInputPort(const String& name_); + const PortInfo* getInputPort(const String& name_) const; + // Output Ports + void createOutputPort(const String& name_, const NetIndex& net_indices_ = NetIndex(0, 0)); + const Map* getOutputs() const; + PortInfo* getOutputPort(const String& name_); + const PortInfo* getOutputPort(const String& name_) const; + // Electrical Nets + void createNet(const String& name_); + void createNet(const String& name_, const NetIndex& net_indices_); + const Map* getNets() const; + ElectricalNet* getNet(const String& name_); + ElectricalNet* getNet(const String& name_, const NetIndex& index_); + + // Assign a net to be downstream from another net + // case 1: 'assign downstream_net_name_ = upstream_net_name_' + void assign(const String& downstream_net_name_, const String& upstream_net_name_); + // case 2: 'assign downstream_net_name_[end:begin] = upstream_net_name_' + void assign(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_); + // case 3: 'assign downstream_net_name_ = upstream_net_name_[end:begin]' + void assign(const String& downstream_net_name_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_); + // case 4: 'assign downstream_net_name_[end:begin] = upstream_net_name_[end:begin]' + void assign(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_); + + // Connect a port (input or output) to some ElectricalNet + // case 1: .connect_port_name_(connect_net_name_) + void portConnect(ElectricalModel* connect_model_, const String& connect_port_name_, const String& connect_net_name_); + // case 2: .connect_port_name_(connect_net_name[end:begin]) + void portConnect(ElectricalModel* connect_model_, const String& connect_port_name_, const String& connect_net_name_, const NetIndex& connect_net_indices_); + + // Assign a net to be downstream from another net through a driver multipliers + void assignVirtualFanout(const String& downstream_net_name_, const String& upstream_net_name_); + void assignVirtualFanout(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_); + // Assign a net to be downstream from another net + // This is used to enable bit_duplication + void assignVirtualFanin(const String& downstream_net_name_, const String& upstream_net_name_); + void assignVirtualFanin(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_); + //----------------------------------------------------------------- + + //----------------------------------------------------------------- + // Timing Model Components + //----------------------------------------------------------------- + // Electrical Drivers + void createDriver(const String& name_, bool sizable_); + //void createDriver(const String& name_, bool sizable_, int start_index_, int end_index_); + const Map* getDrivers() const; + ElectricalDriver* getDriver(const String& name_); + // Electrical Driver Multipliers + void createDriverMultiplier(const String& name_); + const Map* getDriverMultipliers() const; + ElectricalDriverMultiplier* getDriverMultiplier(const String& name_); + + + // Electrical Loads + void createLoad(const String& name_); + //void createLoad(const String& name_, int start_index_, int end_index_); + const Map* getLoads() const; + ElectricalLoad* getLoad(const String& name_); + // Electrical Delay creation + void createDelay(const String& name_); + //void createDelay(const String& name_, int start_index_, int end_index_); + const Map* getDelays() const; + ElectricalDelay* getDelay(const String& name_); + //----------------------------------------------------------------- + + // Get current driving strength + double getDrivingStrength() const; + // Get current driving strength index + int getDrivingStrengthIdx() const; + // Set driving strength by index + void setDrivingStrengthIdx(int idx_); + // Set the instance to minimum driving strength + void setMinDrivingStrength(); + // Return true if the instance has minimum driving strength + bool hasMinDrivingStrength() const; + // Return true if the instance has maximum driving strength + bool hasMaxDrivingStrength() const; + // Increase driving strength index by 1 + void increaseDrivingStrength(); + // Decrease driving strength index by 1 + void decreaseDrivingStrength(); + + // Create the default sets of the electrical results + void createElectricalResults(); + // Add the default sets of the electrical results from a model + void addElectricalSubResults(const ElectricalModel* model_, double number_models_); + // Add extra wire sub results + void addElectricalWireSubResult(const String& wire_layer_, const Result* result_, const String& producer_, double number_results_); + // Create the default sets of the electrical atomic results + void createElectricalAtomicResults(); + // Accumulate the electrical atomic results' values + void addElecticalAtomicResultValues(const ElectricalModel* model_, double number_models_); + // Add extra wire sub results + void addElecticalWireAtomicResultValue(const String& wire_layer_, double value_); + // Reset the electrical atomic results' values + void resetElectricalAtomicResults(); + // Create an electrical event result. This will add an event associate to all input/output ports + void createElectricalEventResult(const String& name_); + // Create an electrical event atomic result + void createElectricalEventAtomicResult(const String& name_); + + //----------------------------------------------------------------- + // Helper functions to propagate transition information + //----------------------------------------------------------------- + void assignPortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const TransitionInfo& trans_info_); + void propagatePortTransitionInfo(const String& downstream_port_name_, const String& upstream_port_name_); + void propagatePortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const String& upstream_port_name_); + void propagatePortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const ElectricalModel* upstream_model_, const String& upstream_port_name_); + void propagatePortTransitionInfo(const String& downstream_port_name_, const ElectricalModel* upstream_model_, const String& upstream_port_name_); + virtual void propagateTransitionInfo(); + //----------------------------------------------------------------- + + //----------------------------------------------------------------- + // Helper functions to insert and remove buffers + //----------------------------------------------------------------- + + //----------------------------------------------------------------- + + virtual void useModel(const String& event_name_); + virtual void useModel(); + // TODO - add comments + void applyTransitionInfo(const String& event_name_); + // TODO - add comments + EventInfo* getEventInfo(const String& event_name_); + + protected: + // In an ElectricalModel, the complete port-to-port connectivity + // of all sub-instance must be specified. Addition/Removal ports or + // port-related nets cannot happen after this step + //virtual void constructModel() = 0; + // In an ElectricalModel, updateModel MUST finish all necessary + // calculations such that a timing model can be run + //virtual void updateModel() = 0; + // In an ElectricalModel, evaluateModel should calculate all + // event energies, now that the connectivity and timing has been + // completed + //virtual void evaluateModel() = 0; + + private: + // Private copy constructor. Use clone to perform copy operation. + ElectricalModel(const ElectricalModel& model_); + + private: + // Contains the driving strengths in increasing order + vector m_driving_strengths_; + // Driving strength index in the driving strength vector + int m_curr_driving_strengths_idx_; + + //Connectivity elements + // Nets can come in various bus widths. A net reference is really + // just a helper map mapping a referenced map name to a bunch of + // net indices. A net index returns the starting and end indices of + // a net if the net is a multi-bit bus of some sort + Map* m_net_references_; + // Map of the input ports + Map* m_input_ports_; + // Map of the output ports + Map* m_output_ports_; + // Map of all our electrical nets + Map* m_nets_; + + //Timing model elements + // Map of all our electrical drivers + Map* m_drivers_; + // Map of all our driver multipliers + Map* m_driver_multipliers_; + // Map of all our electrical loads + Map* m_loads_; + // Map of all our idealized delays + Map* m_delays_; + + // Map of the event infos + Map* m_event_infos_; + + }; // class ElectricalModel +} // namespace DSENT + +#endif // __DSENT_MODEL_ELECTRICALMODEL_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/ElectricalModel.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/ElectricalModel.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,902 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriver.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriverMultiplier.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalLoad.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDelay.hh" + +namespace DSENT +{ + ElectricalModel::ElectricalModel(const String& instance_name_, const TechModel* tech_model_) + : Model(instance_name_, tech_model_) + { + m_curr_driving_strengths_idx_ = -1; + m_input_ports_ = new Map; + m_output_ports_ = new Map; + m_net_references_ = new Map; + m_drivers_ = new Map; + m_driver_multipliers_ = new Map; + m_nets_ = new Map; + m_loads_ = new Map; + m_delays_ = new Map; + m_event_infos_ = new Map; + } + + ElectricalModel::~ElectricalModel() + { + deletePtrMap(m_input_ports_); + deletePtrMap(m_output_ports_); + delete m_net_references_; + deletePtrMap(m_drivers_); + deletePtrMap(m_driver_multipliers_); + deletePtrMap(m_nets_); + deletePtrMap(m_loads_); + deletePtrMap(m_delays_); + deletePtrMap(m_event_infos_); + m_input_ports_ = NULL; + m_output_ports_ = NULL; + m_net_references_ = NULL; + m_drivers_ = NULL; + m_driver_multipliers_ = NULL; + m_nets_ = NULL; + m_loads_ = NULL; + m_net_references_ = NULL; + m_event_infos_ = NULL; + } + + void ElectricalModel::checkProperties() const + { + // Check if the specified driving strength exists in the available driving strengths + if(getProperties()->keyExist("DrivingStrength")) + { + const double driving_strength = getProperty("DrivingStrength"); + bool is_found = false; + for(int i = 0; i < (int)m_driving_strengths_.size(); ++i) + { + if(driving_strength == m_driving_strengths_[i]) + { + is_found = true; + break; + } + } + ASSERT(is_found, "[Error] " + getInstanceName() + + " -> Driving strength (" + String(driving_strength) + ")" + " not found in available driving strengths (" + + getParameter("AvailableDrivingStrengths")); + } + + // Do normal check on the properties + Model::checkProperties(); + return; + } + + double ElectricalModel::getDrivingStrength() const + { + if(m_curr_driving_strengths_idx_ == -1) + { + return 0; + } + else + { + return m_driving_strengths_[m_curr_driving_strengths_idx_]; + } + } + + int ElectricalModel::getDrivingStrengthIdx() const + { + return m_curr_driving_strengths_idx_; + } + + void ElectricalModel::setDrivingStrengthIdx(int idx_) + { + ASSERT(((idx_ >= 0) && (idx_ < (int)m_driving_strengths_.size())), + "[Error] " + getInstanceName() + + " -> Driving strength index out of range (" + String(idx_) + ")"); + + m_curr_driving_strengths_idx_ = idx_; + setProperty("DrivingStrength", m_driving_strengths_[m_curr_driving_strengths_idx_]); + + Log::printLine(getInstanceName() + " -> Changing drive strength to " + (String) m_driving_strengths_[m_curr_driving_strengths_idx_]); + update(); + return; + } + + void ElectricalModel::setMinDrivingStrength() + { + setDrivingStrengthIdx(0); + return; + } + + bool ElectricalModel::hasMinDrivingStrength() const + { + return (m_curr_driving_strengths_idx_ == 0); + } + + bool ElectricalModel::hasMaxDrivingStrength() const + { + return (m_curr_driving_strengths_idx_ == ((int)m_driving_strengths_.size() - 1)); + } + + void ElectricalModel::increaseDrivingStrength() + { + if(!hasMaxDrivingStrength()) + { + setDrivingStrengthIdx(m_curr_driving_strengths_idx_ + 1); + } + return; + } + + void ElectricalModel::decreaseDrivingStrength() + { + if(!hasMinDrivingStrength()) + { + setDrivingStrengthIdx(m_curr_driving_strengths_idx_ - 1); + } + return; + } + + void ElectricalModel::setAvailableDrivingStrengths(const String& driving_strengths_) + { + setParameter("AvailableDrivingStrengths", driving_strengths_); + const vector& split_str = driving_strengths_.split("[,"); + + // Check if there is at least one driving strength specified + ASSERT(!split_str.empty(), "[Error] " + getInstanceName() + + " -> Specified driving strength string does not contain any driving strengths (" + + driving_strengths_ + ")"); + + // TODO - check if the driving strengths is sorted + + // Overwrite the available driving strengths + m_driving_strengths_.clear(); + for(int i = 0; i < (int)split_str.size(); ++i) + { + m_driving_strengths_.push_back(split_str[i].toDouble()); + } + + // Set the driving strength to minimum + m_curr_driving_strengths_idx_ = 0; + setProperty("DrivingStrength", m_driving_strengths_[m_curr_driving_strengths_idx_]); + return; + } + + // Connect a port (input or output) to some ElectricalNet + void ElectricalModel::portConnect(ElectricalModel* connect_model_, const String& connect_port_name_, const String& connect_net_name_) + { + ASSERT(m_net_references_->keyExist(connect_net_name_), "[Error] " + getInstanceName() + + " -> Net '" + connect_net_name_ + "' does not exist!"); + + portConnect(connect_model_, connect_port_name_, connect_net_name_, m_net_references_->get(connect_net_name_)); + } + + void ElectricalModel::portConnect(ElectricalModel* connect_model_, const String& connect_port_name_, const String& connect_net_name_, const NetIndex& connect_net_indices_) + { + ASSERT(m_net_references_->keyExist(connect_net_name_), "[Error] " + getInstanceName() + + " -> Net '" + connect_net_name_ + "' does not exist!"); + + // Check whether the port name is an input or output, ASSERTion error if neither + bool is_input = connect_model_->getInputs()->keyExist(connect_port_name_); + bool is_output = connect_model_->getOutputs()->keyExist(connect_port_name_); + + ASSERT(is_input || is_output, "[Error] " + getInstanceName() + " -> Model '" + connect_model_->getInstanceName() + + "' does not have a port named '" + connect_port_name_ + "'!"); + + int connect_net_width = connect_net_indices_.second - connect_net_indices_.first + 1; + const NetIndex& port_indices = connect_model_->getNetReference(connect_port_name_); + int port_width = port_indices.second - port_indices.first + 1; + + ASSERT(connect_net_width == port_width, "[Error] " + getInstanceName() + " -> Port width mismatch for Model '" + + connect_model_->getInstanceName() + "." + connect_port_name_ + toString(port_indices) + + "' and net '" + connect_net_name_ + toString(connect_net_indices_) + "'!"); + + int port_index = port_indices.first; + int connect_net_index = connect_net_indices_.first; + + if(is_input) + { + while(port_index <= port_indices.second) + { + getNet(connect_net_name_, makeNetIndex(connect_net_index))->addDownstreamNode( + connect_model_->getNet(connect_port_name_, makeNetIndex(port_index))); + ++port_index; + ++connect_net_index; + } + } + else if(is_output) + { + while (port_index <= port_indices.second) + { + connect_model_->getNet(connect_port_name_, makeNetIndex(port_index))->addDownstreamNode( + getNet(connect_net_name_, makeNetIndex(connect_net_index))); + ++port_index; + ++connect_net_index; + } + } + } + + //Get Drivers + const Map* ElectricalModel::getDrivers() const + { + return m_drivers_; + } + + ElectricalDriver* ElectricalModel::getDriver(const String& name_) + { + return m_drivers_->get(name_); + } + + //Get Driver Multipliers + const Map* ElectricalModel::getDriverMultipliers() const + { + return m_driver_multipliers_; + } + + ElectricalDriverMultiplier* ElectricalModel::getDriverMultiplier(const String& name_) + { + return m_driver_multipliers_->get(name_); + } + + //Get Nets + const Map* ElectricalModel::getNets() const + { + return m_nets_; + } + + ElectricalNet* ElectricalModel::getNet(const String& name_) + { + return getNet(name_, m_net_references_->get(name_)); + } + + ElectricalNet* ElectricalModel::getNet(const String& name_, const NetIndex& index_) + { + ASSERT(index_.first == index_.second, "[Error] " + getInstanceName() + + " -> Ambiguous get net since (" + name_ + ") is a bus consisting of several nets!"); + return m_nets_->get(name_ + "[" + (String) index_.first + "]"); + } + + //Get Loads + const Map* ElectricalModel::getLoads() const + { + return m_loads_; + } + + ElectricalLoad* ElectricalModel::getLoad(const String& name_) + { + return m_loads_->get(name_); + } + + //Get Delays + const Map* ElectricalModel::getDelays() const + { + return m_delays_; + } + + ElectricalDelay* ElectricalModel::getDelay(const String& name_) + { + return m_delays_->get(name_); + } + + //Get Inputs + const Map* ElectricalModel::getInputs() const + { + return m_input_ports_; + } + + PortInfo* ElectricalModel::getInputPort(const String& name_) + { + ASSERT(m_input_ports_->keyExist(name_), "[Error] " + getInstanceName() + + " -> Input port (" + name_ + ") does not exist"); + + return m_input_ports_->get(name_); + } + + const PortInfo* ElectricalModel::getInputPort(const String& name_) const + { + ASSERT(m_input_ports_->keyExist(name_), "[Error] " + getInstanceName() + + " -> Input port (" + name_ + ") does not exist"); + + return m_input_ports_->get(name_); + } + + //Get Outputs + const Map* ElectricalModel::getOutputs() const + { + return m_output_ports_; + } + + PortInfo* ElectricalModel::getOutputPort(const String& name_) + { + ASSERT(m_output_ports_->keyExist(name_), "[Error] " + getInstanceName() + + " -> Output port (" + name_ + ") does not exist"); + + return m_output_ports_->get(name_); + } + + const PortInfo* ElectricalModel::getOutputPort(const String& name_) const + { + ASSERT(m_output_ports_->keyExist(name_), "[Error] " + getInstanceName() + + " -> Output port (" + name_ + ") does not exist"); + + return m_output_ports_->get(name_); + } + + const Map* ElectricalModel::getNetReferences() const + { + return m_net_references_; + } + + const NetIndex ElectricalModel::getNetReference(const String& name_) const + { + return m_net_references_->get(name_); + } + + //------------------------------------------------------------------------- + // Electrical Connectivity and Timing Element Creation Functions + //------------------------------------------------------------------------- + + // Input Port creation + void ElectricalModel::createInputPort(const String& name_, const NetIndex& net_indices_) + { + // Create the new nets (including its net reference) + // This should already check that it has not been previously declared + createNet(name_, net_indices_); + // Add the net name to list of input ports + m_input_ports_->set(name_, new PortInfo(name_, net_indices_)); + return; + } + + // Output Port creation + void ElectricalModel::createOutputPort(const String& name_, const NetIndex& net_indices_) + { + // Create the new nets (including its net reference) + // This should already check that it has not been previously declared + createNet(name_, net_indices_); + // Add the net name to list of output ports + m_output_ports_->set(name_, new PortInfo(name_, net_indices_)); + return; + } + + // Net creation + void ElectricalModel::createNet(const String& name_) + { + // Creating a net with specifying an index range means that the net is just + // a 1-bit wire indexed at [0] + createNet(name_, makeNetIndex(0, 0)); + return; + } + + void ElectricalModel::createNet(const String& name_, const NetIndex& net_indices_) + { + // Check that it hasn't been previously declared + ASSERT( !m_nets_->keyExist(name_) && !m_net_references_->keyExist(name_), + "[Error] " + getInstanceName() + " -> Redeclaration of net " + name_); + + int start = net_indices_.first; + int end = net_indices_.second; + + for (int index = start; index <= end; ++index) + { + String indexed_name = name_ + "[" + (String) index + "]"; + // Create the new net + ElectricalNet* net = new ElectricalNet(indexed_name, this); + // Add the net to net map + m_nets_->set(indexed_name, net); + } + // Add net to net references + m_net_references_->set(name_, net_indices_); + return; + } + + // Driver creation + void ElectricalModel::createDriver(const String& name_, bool sizable_) + { + // Check that it hasn't been previously declared + ASSERT( !m_drivers_->keyExist(name_), + "[Error] " + getInstanceName() + " -> Redeclaration of driver " + name_); + + ElectricalDriver* driver = new ElectricalDriver(name_, this, sizable_); + m_drivers_->set(name_, driver); + return; + } + + /* + void ElectricalModel::createDriver(const String& name_, bool sizable_, int start_index_, int end_index_) + { + for (int index = start_index_; index <= end_index_; ++index) + { + createDriver(name_ + "[" + (String) index + "]", sizable_); + } + return; + } + */ + + // Driver Multiplier creation + void ElectricalModel::createDriverMultiplier(const String& name_) + { + // Check that it hasn't been previously declared + ASSERT( !m_driver_multipliers_->keyExist(name_), + "[Error] " + getInstanceName() + " -> Redeclaration of driver_multiplier " + name_); + + ElectricalDriverMultiplier* driver_multiplier = new ElectricalDriverMultiplier(name_, this); + m_driver_multipliers_->set(name_, driver_multiplier); + return; + } + + // Load creation + + void ElectricalModel::createLoad(const String& name_) + { + // Check that it hasn't been previously declared + ASSERT( !m_loads_->keyExist(name_), + "[Error] " + getInstanceName() + " -> Redeclaration of load " + name_); + + ElectricalLoad* load = new ElectricalLoad(name_, this); + m_loads_->set(name_, load); + return; + } + + /* + void ElectricalModel::createLoad(const String& name_, int start_index_, int end_index_) + { + for (int index = start_index_; index <= end_index_; ++index) + { + createLoad(name_ + "[" + (String) index + "]"); + } + return; + } + */ + + // Delay creation + void ElectricalModel::createDelay(const String& name_) + { + // Check that it hasn't been previously declared + ASSERT( !m_delays_->keyExist(name_), + "[Error] " + getInstanceName() + " -> Redeclaration of delay " + name_); + + ElectricalDelay* delay = new ElectricalDelay(name_, this); + m_delays_->set(name_, delay); + return; + } + + /* + void ElectricalModel::createDelay(const String& name_, int start_index_, int end_index_) + { + for (int index = start_index_; index <= end_index_; ++index) + { + createDelay(name_ + "[" + (String) index + "]"); + } + return; + } + */ + //------------------------------------------------------------------------- + + // Assign a net to be downstream from another net + // case 1: 'assign downstream_net_name_ = upstream_net_name_' + void ElectricalModel::assign(const String& downstream_net_name_, const String& upstream_net_name_) + { + ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + + downstream_net_name_ + "' does not exist!"); + + ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + + upstream_net_name_ + "' does not exist!"); + + assign(downstream_net_name_, getNetReference(downstream_net_name_), + upstream_net_name_, getNetReference(upstream_net_name_)); + + return; + } + + // case 2: 'assign downstream_net_name_[begin:end] = upstream_net_name_' + void ElectricalModel::assign(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_) + { + ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + + downstream_net_name_ + "' does not exist!"); + + ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + + upstream_net_name_ + "' does not exist!"); + + assign(downstream_net_name_, downstream_net_indices_, + upstream_net_name_, getNetReference(upstream_net_name_)); + + return; + } + + // case 3: 'assign downstream_net_name_ = upstream_net_name_[begin:end]' + void ElectricalModel::assign(const String& downstream_net_name_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_) + { + ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + + downstream_net_name_ + "' does not exist!"); + + ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + + upstream_net_name_ + "' does not exist!"); + + assign(downstream_net_name_, getNetReference(downstream_net_name_), + upstream_net_name_, upstream_net_indices_); + + return; + } + // case 4: 'assign downstream_net_name_[begin:end] = upstream_net_name_[begin:end]' + void ElectricalModel::assign(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_) + { + ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + + downstream_net_name_ + "' does not exist!"); + + ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + + upstream_net_name_ + "' does not exist!"); + + // Check that the assignment widths are the same + int downstream_width = downstream_net_indices_.second - downstream_net_indices_.first + 1; + int upstream_width = upstream_net_indices_.second - upstream_net_indices_.first + 1; + + ASSERT(downstream_width == upstream_width, "[Error] " + getInstanceName() + " -> Assignment width mismatch: " + + downstream_net_name_ + " (" + (String) downstream_width + ") and " + + upstream_net_name_ + " (" + (String) upstream_width + ")"); + + // Loop through indices and connect them together + int down_index = downstream_net_indices_.first; + int up_index = upstream_net_indices_.first; + while (down_index <= downstream_net_indices_.second) + { + getNet(upstream_net_name_, makeNetIndex(up_index))->addDownstreamNode( + getNet(downstream_net_name_, makeNetIndex(down_index))); + + ++up_index; + ++down_index; + } + + return; + } + + // Assign a net to another net through a driver multiplier + void ElectricalModel::assignVirtualFanout(const String& downstream_net_name_, const String& upstream_net_name_) + { + ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + + " -> Net '" + upstream_net_name_ + "' does not exist!"); + ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + + " -> Net '" + downstream_net_name_ + "' does not exist!"); + + assignVirtualFanout(downstream_net_name_, getNetReference(downstream_net_name_), upstream_net_name_, getNetReference(upstream_net_name_)); + return; + } + + // Assign a net to another net through a driver multiplier + void ElectricalModel::assignVirtualFanout(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_) + { + ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + + " -> Net '" + upstream_net_name_ + "' does not exist!"); + ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + + " -> Net '" + downstream_net_name_ + "' does not exist!"); + + const String& drive_mult_name = upstream_net_name_ + "_" + (String) upstream_net_indices_.first + "_DriverMultiplier"; + bool is_drive_mult_exist = getDriverMultipliers()->keyExist(drive_mult_name); + + // Create a driver multiplier and assign it to upstream_net since it doesn't exist + if(!is_drive_mult_exist) + { + createDriverMultiplier(drive_mult_name); + getNet(upstream_net_name_, upstream_net_indices_)->addDownstreamNode(getDriverMultiplier(drive_mult_name)); + } + + // Assign downstream_net_name_[end:begin] = driver_multiplier_name_ + ElectricalDriverMultiplier* drive_mult = getDriverMultiplier(drive_mult_name); + int begin_index = downstream_net_indices_.first; + int end_index = downstream_net_indices_.second; + for(int i = begin_index; i <= end_index; ++i) + { + drive_mult->addDownstreamNode(getNet(downstream_net_name_, makeNetIndex(i))); + } + return; + } + + void ElectricalModel::assignVirtualFanin(const String& downstream_net_name_, const String& upstream_net_name_) + { + ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + + " -> Net '" + upstream_net_name_ + "' does not exist!"); + ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + + " -> Net '" + downstream_net_name_ + "' does not exist!"); + + assignVirtualFanin(downstream_net_name_, getNetReference(downstream_net_name_), upstream_net_name_, getNetReference(upstream_net_name_)); + return; + } + + void ElectricalModel::assignVirtualFanin(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_) + { + ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + + " -> Net '" + upstream_net_name_ + "' does not exist!"); + ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + + " -> Net '" + downstream_net_name_ + "' does not exist!"); + + int begin_index = upstream_net_indices_.first; + int end_index = upstream_net_indices_.second; + + for(int i = begin_index; i <= end_index; ++i) + { + getNet(upstream_net_name_, makeNetIndex(i))->addDownstreamNode(getNet(downstream_net_name_, downstream_net_indices_)); + } + return; + } + + void ElectricalModel::createElectricalResults() + { + // Add active area result + addAreaResult(new Result("Active")); + + // Add wire area result + TechModel::ConstWireLayerIterator it_begin = getTechModel()->getAvailableWireLayers()->begin(); + TechModel::ConstWireLayerIterator it_end = getTechModel()->getAvailableWireLayers()->end(); + TechModel::ConstWireLayerIterator it; + for(it = it_begin; it != it_end; ++it) + { + const String& layer_name = (*it); + addAreaResult(new Result(layer_name + "Wire")); + } + + // Add leakage result + addNddPowerResult(new Result("Leakage")); + + // Add idle event result + createElectricalEventResult("Idle"); + return; + } + + void ElectricalModel::addElectricalSubResults(const ElectricalModel* model_, double number_models_) + { + // Add active area sub result + getAreaResult("Active")->addSubResult(model_->getAreaResult("Active"), model_->getInstanceName(), number_models_); + + // Add wire area sub result + TechModel::ConstWireLayerIterator it_begin = getTechModel()->getAvailableWireLayers()->begin(); + TechModel::ConstWireLayerIterator it_end = getTechModel()->getAvailableWireLayers()->end(); + TechModel::ConstWireLayerIterator it; + for(it = it_begin; it != it_end; ++it) + { + const String& layer_name = (*it); + const String& result_name = layer_name + "Wire"; + getAreaResult(result_name)->addSubResult(model_->getAreaResult(result_name), model_->getInstanceName(), number_models_); + } + + // Add leakage sub result + getNddPowerResult("Leakage")->addSubResult(model_->getNddPowerResult("Leakage"), model_->getInstanceName(), number_models_); + + // Add idle event sub result + getEventResult("Idle")->addSubResult(model_->getEventResult("Idle"), model_->getInstanceName(), number_models_); + return; + } + + void ElectricalModel::addElectricalWireSubResult(const String& wire_layer_, const Result* result_, const String& producer_, double number_results_) + { + getAreaResult(wire_layer_ + "Wire")->addSubResult(result_, producer_, number_results_); + return; + } + + void ElectricalModel::createElectricalAtomicResults() + { + // Add active area result + addAreaResult(new AtomicResult("Active")); + + // Add wire area result + TechModel::ConstWireLayerIterator it_begin = getTechModel()->getAvailableWireLayers()->begin(); + TechModel::ConstWireLayerIterator it_end = getTechModel()->getAvailableWireLayers()->end(); + TechModel::ConstWireLayerIterator it; + for(it = it_begin; it != it_end; ++it) + { + const String& layer_name = (*it); + addAreaResult(new AtomicResult(layer_name + "Wire")); + } + + // Add leakage result + addNddPowerResult(new AtomicResult("Leakage")); + + // Add idle event result + createElectricalEventAtomicResult("Idle"); + return; + } + + void ElectricalModel::addElecticalAtomicResultValues(const ElectricalModel* model_, double number_models_) + { + getAreaResult("Active")->addValue(model_->getAreaResult("Active")->calculateSum() * number_models_); + + // Add wire area sub result + TechModel::ConstWireLayerIterator it_begin = getTechModel()->getAvailableWireLayers()->begin(); + TechModel::ConstWireLayerIterator it_end = getTechModel()->getAvailableWireLayers()->end(); + TechModel::ConstWireLayerIterator it; + for(it = it_begin; it != it_end; ++it) + { + const String& layer_name = (*it); + const String& result_name = layer_name + "Wire"; + getAreaResult(result_name)->addValue(model_->getAreaResult(result_name)->calculateSum() * number_models_); + } + + // Add leakage sub result + getNddPowerResult("Leakage")->addValue(model_->getNddPowerResult("Leakage")->calculateSum() * number_models_); + + // Add idle event sub result + getEventResult("Idle")->addValue(model_->getEventResult("Idle")->calculateSum() * number_models_); + return; + } + + void ElectricalModel::addElecticalWireAtomicResultValue(const String& wire_layer_, double value_) + { + getAreaResult(wire_layer_ + "Wire")->addValue(value_); + return; + } + + void ElectricalModel::resetElectricalAtomicResults() + { + getAreaResult("Active")->setValue(0.0); + + // Reset wire area sub result + TechModel::ConstWireLayerIterator it_begin = getTechModel()->getAvailableWireLayers()->begin(); + TechModel::ConstWireLayerIterator it_end = getTechModel()->getAvailableWireLayers()->end(); + TechModel::ConstWireLayerIterator it; + for(it = it_begin; it != it_end; ++it) + { + const String& layer_name = (*it); + const String& result_name = layer_name + "Wire"; + getAreaResult(result_name)->setValue(0.0); + } + + // Reset leakage sub result + getNddPowerResult("Leakage")->setValue(0.0); + + // Reset idle event sub result + getEventResult("Idle")->setValue(0.0); + + return; + } + + void ElectricalModel::createElectricalEventResult(const String& name_) + { + // Add the event result + addEventResult(new Result(name_)); + // Add event info + m_event_infos_->set(name_, new EventInfo(name_, getInputs())); + return; + } + + void ElectricalModel::createElectricalEventAtomicResult(const String& name_) + { + // Add the event result + addEventResult(new AtomicResult(name_)); + // Add event info + m_event_infos_->set(name_, new EventInfo(name_, getInputs())); + return; + } + + void ElectricalModel::assignPortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const TransitionInfo& trans_info_) + { + ASSERT(downstream_model_ != NULL, "[Error] " + getInstanceName() + + " -> Downstream model does not exist"); + + downstream_model_->getInputPort(downstream_port_name_)->setTransitionInfo(trans_info_); + return; + } + + void ElectricalModel::propagatePortTransitionInfo(const String& downstream_port_name_, const String& upstream_port_name_) + { + const TransitionInfo& trans_info = getInputPort(upstream_port_name_)->getTransitionInfo(); + getOutputPort(downstream_port_name_)->setTransitionInfo(trans_info); + return; + } + + void ElectricalModel::propagatePortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const String& upstream_port_name_) + { + ASSERT(downstream_model_ != NULL, "[Error] " + getInstanceName() + + " -> Downstream model does not exist"); + + const TransitionInfo& trans_info = getInputPort(upstream_port_name_)->getTransitionInfo(); + downstream_model_->getInputPort(downstream_port_name_)->setTransitionInfo(trans_info); + return; + } + + void ElectricalModel::propagatePortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const ElectricalModel* upstream_model_, const String& upstream_port_name_) + { + ASSERT(downstream_model_ != NULL, "[Error] " + getInstanceName() + + " -> Downstream model does not exist"); + ASSERT(upstream_model_ != NULL, "[Error] " + getInstanceName() + + " -> Upstream model does not exist"); + + const TransitionInfo& trans_info = upstream_model_->getOutputPort(upstream_port_name_)->getTransitionInfo(); + + downstream_model_->getInputPort(downstream_port_name_)->setTransitionInfo(trans_info); + return; + } + + void ElectricalModel::propagatePortTransitionInfo(const String& downstream_port_name_, const ElectricalModel* upstream_model_, const String& upstream_port_name_) + { + ASSERT(upstream_model_ != NULL, "[Error] " + getInstanceName() + + " -> Upstream model does not exist"); + + const TransitionInfo& trans_info = upstream_model_->getOutputPort(upstream_port_name_)->getTransitionInfo(); + getOutputPort(downstream_port_name_)->setTransitionInfo(trans_info); + return; + } + + void ElectricalModel::propagateTransitionInfo() + { + // by default do nothing. + } + + void ElectricalModel::useModel(const String& event_name_) + { + getGenProperties()->set("UseModelEvent", event_name_); + applyTransitionInfo(event_name_); + useModel(); + return; + } + + void ElectricalModel::useModel() + { + propagateTransitionInfo(); + return; + } + + void ElectricalModel::applyTransitionInfo(const String& event_name_) + { + // Check if the event actually exists + ASSERT(hasEventResult(event_name_), "[Error] " + getInstanceName() + + " -> Event (" + event_name_ + ") does not exist in the result map"); + ASSERT(m_event_infos_->keyExist(event_name_), "[Error] " + getInstanceName() + + " -> Event (" + event_name_ + ") does not exist in the event info map"); + + const EventInfo* event_info = m_event_infos_->get(event_name_); + + // Set the input ports' transition information for the event + Map::ConstIterator it_begin = m_input_ports_->begin(); + Map::ConstIterator it_end = m_input_ports_->end(); + Map::ConstIterator it; + for(it = it_begin; it != it_end; ++it) + { + const String& port_name = it->first; + PortInfo* port_info = it->second; + const TransitionInfo& trans_info = event_info->getTransitionInfo(port_name); + port_info->setTransitionInfo(trans_info); + } + + return; + } + + EventInfo* ElectricalModel::getEventInfo(const String& event_name_) + { + ASSERT(m_event_infos_->keyExist(event_name_), "[Error] " + getInstanceName() + + " -> Event (" + event_name_ + ") does not exist"); + + return m_event_infos_->get(event_name_); + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/EventInfo.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/EventInfo.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_EVENT_INFO_H__ +#define __DSENT_MODEL_EVENT_INFO_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" + +namespace DSENT +{ + class PortInfo; + + class EventInfo + { + public: + EventInfo(const String& event_name_, const Map* port_infos_); + ~EventInfo(); + + public: + const String& getEventName() const; + void setTransitionInfo(const String& port_name_, const TransitionInfo& trans_info_); + void setStaticTransitionInfo(const String& port_name_); + void setRandomTransitionInfos(); + void setStaticTransitionInfos(); + const TransitionInfo& getTransitionInfo(const String& port_name_) const; + + private: + String m_event_name_; + Map* m_trans_info_map_; + }; // class EventInfo +} // namespace DSENT + +#endif // __DSENT_MODEL_EVENT_INFO_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/EventInfo.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/EventInfo.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" + +namespace DSENT +{ + EventInfo::EventInfo(const String& event_name_, const Map* port_infos_) + : m_event_name_(event_name_) + { + m_trans_info_map_ = new Map; + + // Get the name of each input port and add a transition info for it + Map::ConstIterator it_begin = port_infos_->begin(); + Map::ConstIterator it_end = port_infos_->end(); + Map::ConstIterator it; + for(it = it_begin; it != it_end; ++it) + { + const String& port_name = it->first; + m_trans_info_map_->set(port_name, TransitionInfo()); + } + } + + EventInfo::~EventInfo() + { + delete m_trans_info_map_; + } + + const String& EventInfo::getEventName() const + { + return m_event_name_; + } + + void EventInfo::setTransitionInfo(const String& port_name_, const TransitionInfo& trans_info_) + { + ASSERT(m_trans_info_map_->keyExist(port_name_), "[Error] " + getEventName() + + " -> Port (" + port_name_ + ") does not exist!"); + + m_trans_info_map_->set(port_name_, trans_info_); + return; + } + + void EventInfo::setStaticTransitionInfo(const String& port_name_) + { + ASSERT(m_trans_info_map_->keyExist(port_name_), "[Error] " + getEventName() + + " -> Port (" + port_name_ + ") does not exist!"); + + m_trans_info_map_->set(port_name_, TransitionInfo(0.5, 0.0, 0.5)); + return; + } + + void EventInfo::setRandomTransitionInfos() + { + Map::Iterator it_begin = m_trans_info_map_->begin(); + Map::Iterator it_end = m_trans_info_map_->end(); + Map::Iterator it; + for(it = it_begin; it != it_end; ++it) + { + TransitionInfo& trans_info = it->second; + trans_info = TransitionInfo(); + } + return; + } + + void EventInfo::setStaticTransitionInfos() + { + Map::Iterator it_begin = m_trans_info_map_->begin(); + Map::Iterator it_end = m_trans_info_map_->end(); + Map::Iterator it; + for(it = it_begin; it != it_end; ++it) + { + TransitionInfo& trans_info = it->second; + trans_info = TransitionInfo(0.5, 0.0, 0.5); + } + return; + } + + const TransitionInfo& EventInfo::getTransitionInfo(const String& port_name_) const + { + ASSERT(m_trans_info_map_->keyExist(port_name_), "[Error] " + getEventName() + + " -> Port (" + port_name_ + ") does not exist!"); + + return m_trans_info_map_->get(port_name_); + } +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/Model.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/Model.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_MODEL_H__ +#define __DSENT_MODEL_MODEL_H__ + +#include + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" + +namespace DSENT +{ + using std::vector; + + class TechModel; + class Result; + + // Base class for all the models + class Model + { + protected: + class SubModel + { + public: + SubModel(Model* model_, double num_models_); + ~SubModel(); + + public: + Model* getModel(); + const Model* getModel() const; + double getNumModels() const; + + SubModel* clone() const; + + protected: + SubModel(const SubModel& sub_model_); + + private: + // Pointer to the actual model instance + Model* m_model_; + // Number of models are added + double m_num_models_; + }; + + public: + // Model Constants + static const char TYPE_SEPARATOR[]; + static const char HIERARCHY_SEPARATOR[]; + static const char SUBFIELD_SEPARATOR[]; + static const char DETAIL_SEPARATOR[]; + + public: + Model(const String& instance_name_, const TechModel* tech_model_); + virtual ~Model(); + + public: + // Set the name of this instance + void setInstanceName(const String& instance_name_); + // Get the name of this instance + const String& getInstanceName() const; + + // Set if the model is the top model + void setIsTopModel(bool is_top_model_); + bool getIsTopModel() const; + + // Add a parameter name (with and without default) + void addParameterName(const String& parameter_name_); + void addParameterName(const String& parameter_name_, const String& parameter_default_); + const vector* getParameterNames() const; + + // Add a property name + void addPropertyName(const String& property_name_); + void addPropertyName(const String& property_name_, const String& property_default_); + const vector* getPropertyNames() const; + + // Check if all parameters needed exist in the m_parameters_ + void checkParameters() const; + // Check if all properties needed exist in the m_properties_ + void checkProperties() const; + + // Get the pointer to parameters + const ParameterMap* getParameters() const; + const String getParameter(const String& parameter_name_) const; + void setParameter(const String& parameter_name_, const String& parameter_value_); + + // Get the pointer to properties + const PropertyMap* getProperties() const; + const String getProperty(const String& property_name_) const; + void setProperty(const String& property_name_, const String& property_value_); + + // Get the pointer to generated properties + PropertyMap* getGenProperties(); + const PropertyMap* getGenProperties() const; + + // Add an instance to this model. num_sub_instances_ specifies the + // number of the same instance is added. + void addSubInstances(Model* sub_instance_, double num_sub_instances_); + // Get an instance by name. + Model* getSubInstance(const String& sub_instance_name_); + const Model* getSubInstance(const String& sub_instance_name_) const; + // Check if an instance exists + bool hasSubInstance(const String& sub_instance_name_) const; + + // Add a new area + void addAreaResult(Result* area_); + // Get the pointer to an area. The area is specified by name. + Result* getAreaResult(const String& area_name_); + const Result* getAreaResult(const String& area_name_) const; + // Check if an area exists + bool hasAreaResult(const String& area_name_) const; + + // Add a new ndd_power + void addNddPowerResult(Result* ndd_power_); + // Get the pointer to an ndd_power. The ndd_power is specified by name. + Result* getNddPowerResult(const String& ndd_power_name_); + const Result* getNddPowerResult(const String& ndd_power_name_) const; + // Check if a ndd_power exists + bool hasNddPowerResult(const String& ndd_power_name_) const; + + // Add a new event + void addEventResult(Result* event_); + // Get the pointer to an event. The event is specified by name. + Result* getEventResult(const String& event_name_); + const Result* getEventResult(const String& event_name_) const; + // Check if an event exists + bool hasEventResult(const String& event_name_) const; + + // Get the pointer to the TechModel. + const TechModel* getTechModel() const; + + // Clone and return a new instance + virtual Model* clone() const; + + // Checks to make sure all required parameters are present, makes sure that the model + // has not been constructed yet, and calls constructModel. This function is not meant + // to be overwritten by child classes; constructModel should be overwritten instead + void construct(); + // Update checks whether the model needs updating, whether all properties have been specified, + // and calls updateModel if update is necessary. This function is not meant + // to be overwritten by child classes; updateModel should be overwritten instead + void update(); + // Evaluate checks whether the model needs to be evaluated. Note that this function is + // not meant to be overwritten by child classes; evaluateModel should be overwritten + // instead + void evaluate(); + void use(const String& event_name_); + void use(); + + // Resolve query hierarchy and process query + const void* parseQuery(const String& query_type_, const String& query_hier_, const String& query_sub_field_); + // Process the query + virtual const void* processQuery(const String& query_type_, const String& query_sub_field_); + + // Print hierarchically + void printHierarchy(const String& query_type_, const String& query_sub_field_, const String& prepend_str_, int detail_level_, ostream& ost_) const; + void printInstHierarchy(const String& prepend_str_, int detail_level_, ostream& ost_) const; + + protected: + // Query area + const Result* queryArea(const String& area_name_) const; + // Query non-data-dependent power + const Result* queryNddPower(const String& ndd_power_name_); + // Query event energy cost + const Result* queryEventEnergyCost(const String& event_name_); + + // Constructs the model + virtual void constructModel() = 0; + // Updates timing related information of the model + virtual void updateModel(); + // Evaluate non data dependent power of the model + virtual void evaluateModel(); + virtual void useModel(const String& event_name_); + virtual void useModel(); + + private: + // Private copy constructor. Use clone to perform copy operation. + Model(const Model& model_); + + private: + // Name of this instance + String m_instance_name_; + // Set if this model is the top model + bool m_is_top_model_; + + // Contains the parameters of a model + // Parameters are needed in order to constructModel() and CANNOT be + // changed after constructModel() has been called + ParameterMap* m_parameters_; + // Contains the names of all model parameters + vector* m_parameter_names_; + // Contains the properties of a model + // Properties are required in order to updateModel() and CAN be + // changed be changed after constructModel(). Call updateModel() + // after properties have been changed to use the new properties + PropertyMap* m_properties_; + // Contains the property names needed to update the model + vector* m_property_names_; + // Contains generated properties of the model + // Generated properties are used mostly as a scratch space for + // variables used in the model that must be passed from one + // function to another + PropertyMap* m_generated_properties_; + + // Contains the instances of this model + Map* m_sub_instances_; + // Contains the area resulst of a model + Map* m_area_map_; + // Contains the noo power results of a model + Map* m_ndd_power_map_; + // Contains the event results of a model + Map* m_event_map_; + // Pointer to a TechModel which contains the technology information + const TechModel* m_tech_model_; + + // Set when a model is constructed + bool m_constructed_; + // Set when a model is updated + bool m_updated_; + // Set when a model is evaluated + bool m_evaluated_; + + }; // class Model +} // namespace DSENT + +#endif // __DSENT_MODEL_MODEL_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/Model.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/Model.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,729 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/Model.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/util/Result.hh" + +namespace DSENT +{ + using std::vector; + using LibUtil::deletePtrMap; + using LibUtil::clonePtrMap; + + Model::SubModel::SubModel(Model* model_, double num_models_) + : m_model_(model_), m_num_models_(num_models_) + {} + + Model::SubModel::~SubModel() + { + delete m_model_; + } + + Model* Model::SubModel::getModel() + { + return m_model_; + } + + const Model* Model::SubModel::getModel() const + { + return m_model_; + } + + double Model::SubModel::getNumModels() const + { + return m_num_models_; + } + + Model::SubModel* Model::SubModel::clone() const + { + return new SubModel(*this); + } + + Model::SubModel::SubModel(const SubModel& sub_model_) + { + m_model_ = sub_model_.m_model_->clone(); + m_num_models_ = sub_model_.m_num_models_; + } + + const char Model::TYPE_SEPARATOR[] = ">>"; + const char Model::HIERARCHY_SEPARATOR[] = "->"; + const char Model::SUBFIELD_SEPARATOR[] = ":"; + const char Model::DETAIL_SEPARATOR[] = "@"; + + Model::Model(const String& instance_name_, const TechModel* tech_model_) + : m_instance_name_(instance_name_), m_tech_model_(tech_model_), + m_constructed_(false), m_updated_(false), m_evaluated_(false) + { + m_property_names_ = new vector; + m_parameter_names_ = new vector; + m_parameters_ = new ParameterMap(); + m_properties_ = new PropertyMap(); + m_generated_properties_ = new PropertyMap(); + m_sub_instances_ = new Map(); + m_event_map_ = new Map(); + m_area_map_ = new Map(); + m_ndd_power_map_ = new Map(); + } + + Model::~Model() + { + // Clear parameter names + delete m_parameter_names_; + // Clear property name + delete m_property_names_; + + // Clear parameters + delete m_parameters_; + m_parameters_ = NULL; + // Clear input properties + delete m_properties_; + m_properties_ = NULL; + + // Clear generated properties + delete m_generated_properties_; + m_generated_properties_ = NULL; + + // Clear sub models + deletePtrMap(m_sub_instances_); + m_sub_instances_ = NULL; + + // Clear all results + deletePtrMap(m_event_map_); + m_event_map_ = NULL; + deletePtrMap(m_area_map_); + m_area_map_ = NULL; + deletePtrMap(m_ndd_power_map_); + m_ndd_power_map_ = NULL; + } + + void Model::setInstanceName(const String& instance_name_) + { + m_instance_name_ = instance_name_; + return; + } + + const String& Model::getInstanceName() const + { + return m_instance_name_; + } + + void Model::setIsTopModel(bool is_top_model_) + { + m_is_top_model_ = is_top_model_; + return; + } + + bool Model::getIsTopModel() const + { + return m_is_top_model_; + } + + //------------------------------------------------------------------------- + // Parameters and properties checks + //------------------------------------------------------------------------- + void Model::addParameterName(const String& parameter_name_) + { + ASSERT(!m_constructed_, "[Error] " + getInstanceName() + + " -> Cannot add additional parameters names after model is constructed!"); + m_parameter_names_->push_back(parameter_name_); + + return; + } + + void Model::addParameterName(const String& parameter_name_, const String& parameter_default_) + { + ASSERT(!m_constructed_, "[Error] " + getInstanceName() + + " -> Cannot add additional parameters names after model is constructed!"); + m_parameter_names_->push_back(parameter_name_); + setParameter(parameter_name_, parameter_default_); + return; + } + + const vector* Model::getParameterNames() const + { + return m_parameter_names_; + } + + void Model::addPropertyName(const String& property_name_) + { + ASSERT(!m_constructed_, "[Error] " + getInstanceName() + + " -> Cannot add additional property names after model is constructed!"); + m_property_names_->push_back(property_name_); + return; + } + + void Model::addPropertyName(const String& property_name_, const String& property_default_) + { + ASSERT(!m_constructed_, "[Error] " + getInstanceName() + + " -> Cannot add additional property names after model is constructed!"); + m_property_names_->push_back(property_name_); + setProperty(property_name_, property_default_); + return; + } + + const vector* Model::getPropertyNames() const + { + return m_property_names_; + } + + void Model::checkParameters() const + { + String missing_parameters = ""; + + for(int i = 0; i < (int)m_parameter_names_->size(); ++i) + { + const String& parameter_name = m_parameter_names_->at(i); + if (!m_parameters_->keyExist(parameter_name)) + missing_parameters += " " + parameter_name + "\n"; + } + + ASSERT(missing_parameters.size() == 0, "[Error] " + m_instance_name_ + + " -> Missing parameters:\n" + missing_parameters); + return; + } + + void Model::checkProperties() const + { + String missing_properties = ""; + + for(int i = 0; i < (int)m_property_names_->size(); ++i) + { + const String& property_name = m_property_names_->at(i); + if (!m_properties_->keyExist(property_name)) + missing_properties += " " + property_name + "\n"; + } + + ASSERT(missing_properties.size() == 0, "[Error] " + m_instance_name_ + + " -> Missing properties:\n" + missing_properties); + return; + } + //------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + // Parameters Manipulation + //------------------------------------------------------------------------- + const ParameterMap* Model::getParameters() const + { + return m_parameters_; + } + + const String Model::getParameter(const String& parameter_name_) const + { + return m_parameters_->get(parameter_name_); + } + + void Model::setParameter(const String& parameter_name_, const String& parameter_value_) + { + ASSERT(!m_constructed_, "[Error] " + getInstanceName() + + " -> Cannot set parameters after model is constructed!"); + m_parameters_->set(parameter_name_, parameter_value_); + } + //------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + // Properties Manipulation + //------------------------------------------------------------------------- + const PropertyMap* Model::getProperties() const + { + return m_properties_; + } + + const String Model::getProperty(const String& property_name_) const + { + return m_properties_->get(property_name_); + } + + void Model::setProperty(const String& property_name_, const String& property_value_) + { + // If any properties changed, reset updated and evaluated flags + m_updated_ = false; + m_evaluated_ = false; + m_properties_->set(property_name_, property_value_); + } + //------------------------------------------------------------------------- + + PropertyMap* Model::getGenProperties() + { + return m_generated_properties_; + } + + const PropertyMap* Model::getGenProperties() const + { + return m_generated_properties_; + } + + void Model::addSubInstances(Model* sub_instance_, double num_sub_instances_) + { + // Get instance name + const String& sub_instance_name = sub_instance_->getInstanceName(); + + // Check if the instance exists + if(m_sub_instances_->keyExist(sub_instance_name)) + { + const String& error_msg = "[Error] " + m_instance_name_ + + " -> Instance exists (" + sub_instance_name + ")"; + throw Exception(error_msg); + } + + // Check if the num_sub_instances_ is a positive number + ASSERT((num_sub_instances_ >= 0), "[Error] " + m_instance_name_ + + " -> Invalid number of instance (" + String(num_sub_instances_) + ")"); + + // Add the instance + m_sub_instances_->set(sub_instance_name, new SubModel(sub_instance_, num_sub_instances_)); + return; + } + + Model* Model::getSubInstance(const String& sub_instance_name_) + { + // Throw an Exception if the instance already exists + if(!m_sub_instances_->keyExist(sub_instance_name_)) + { + const String& error_msg = "[Error] " + m_instance_name_ + + " -> Instance not exists (" + sub_instance_name_ + ")"; + throw Exception(error_msg); + } + + return m_sub_instances_->get(sub_instance_name_)->getModel(); + } + + const Model* Model::getSubInstance(const String& sub_instance_name_) const + { + // Throw an Exception if the instance does not exist + if(!m_sub_instances_->keyExist(sub_instance_name_)) + { + const String& error_msg = "[Error] " + m_instance_name_ + + " -> Instance not exists (" + sub_instance_name_ + ")"; + throw Exception(error_msg); + } + + return m_sub_instances_->get(sub_instance_name_)->getModel(); + } + + bool Model::hasSubInstance(const String& sub_instance_name_) const + { + return m_sub_instances_->keyExist(sub_instance_name_); + } + + void Model::addAreaResult(Result* area_) + { + const String& area_name = area_->getName(); + + // Throw an Exception if the area already exists + if(m_area_map_->keyExist(area_name)) + { + const String& error_msg = "Internal error: area (" + area_name + + ") exists"; + throw Exception(error_msg); + } + + // Add the area + m_area_map_->set(area_name, area_); + return; + } + + Result* Model::getAreaResult(const String& area_name_) + { + return m_area_map_->get(area_name_); + } + + const Result* Model::getAreaResult(const String& area_name_) const + { + return m_area_map_->get(area_name_); + } + + bool Model::hasAreaResult(const String& area_name_) const + { + return m_area_map_->keyExist(area_name_); + } + + void Model::addNddPowerResult(Result* ndd_power_) + { + const String& ndd_power_name = ndd_power_->getName(); + + // Throw an Exception if the ndd_power already exists + if(m_ndd_power_map_->keyExist(ndd_power_name)) + { + const String& error_msg = "Internal error: ndd_power (" + ndd_power_name + + ") exists"; + throw Exception(error_msg); + } + + // Add the ndd_power + m_ndd_power_map_->set(ndd_power_name, ndd_power_); + return; + } + + Result* Model::getNddPowerResult(const String& ndd_power_name_) + { + return m_ndd_power_map_->get(ndd_power_name_); + } + + const Result* Model::getNddPowerResult(const String& ndd_power_name_) const + { + return m_ndd_power_map_->get(ndd_power_name_); + } + + bool Model::hasNddPowerResult(const String& ndd_power_name_) const + { + return m_ndd_power_map_->keyExist(ndd_power_name_); + } + + void Model::addEventResult(Result* event_) + { + const String& event_name = event_->getName(); + + // Throw an Exception if the event already exists + if(m_event_map_->keyExist(event_name)) + { + const String& error_msg = "Internal error: event (" + event_name + + ") exists"; + throw Exception(error_msg); + } + + // Add the event + m_event_map_->set(event_name, event_); + return; + } + + Result* Model::getEventResult(const String& event_name_) + { + return m_event_map_->get(event_name_); + } + + const Result* Model::getEventResult(const String& event_name_) const + { + return m_event_map_->get(event_name_); + } + + bool Model::hasEventResult(const String& event_name_) const + { + return m_event_map_->keyExist(event_name_); + } + + const TechModel* Model::getTechModel() const + { + return m_tech_model_; + } + + const void* Model::parseQuery(const String& query_type_, const String& query_hier_, const String& query_sub_field_) + { + // Break query by hierarchy separator + vector hier_split = query_hier_.splitByString(HIERARCHY_SEPARATOR); + + // Check if the query_hier matches the instance name + ASSERT((hier_split[0] == m_instance_name_), "[Error] " + + m_instance_name_ + " -> Mismatch in instance name (" + + hier_split[0] + ")"); + + // If there is no more hierarchy separator, this process the query + if(hier_split.size() == 1) + { + // Query the model + return processQuery(query_type_, query_sub_field_); + } + else + { + // Reconstruct the query + String temp_query_hier = hier_split[1]; + for(int i = 2; i < (int)hier_split.size(); ++i) + { + temp_query_hier += HIERARCHY_SEPARATOR + hier_split[i]; + } + + // Get sub instance's name + const String& temp_sub_instance_name = hier_split[1]; + ASSERT(m_sub_instances_->keyExist(temp_sub_instance_name), "[Error] " + + m_instance_name_ + " -> No sub-instances queried (" + + temp_sub_instance_name + ")"); + + return m_sub_instances_->get(temp_sub_instance_name)->getModel()->parseQuery(query_type_, temp_query_hier, query_sub_field_); + } + } + + const void* Model::processQuery(const String& query_type_, const String& query_sub_field_) + { + if(query_type_ == "Property") + { + return getProperties(); + } + else if(query_type_ == "Parameter") + { + return getParameters(); + } + else if(query_type_.contain("Hier")) + { + return this; + } + else if(query_type_ == "Area") + { + return queryArea(query_sub_field_); + } + else if(query_type_ == "NddPower") + { + return queryNddPower(query_sub_field_); + } + else if(query_type_ == "Energy") + { + return queryEventEnergyCost(query_sub_field_); + } + else + { + const String& error_msg = "[Error] " + m_instance_name_ + " -> Unknown query type (" + query_type_ + ")"; + throw Exception(error_msg); + return NULL; + } + } + + const Result* Model::queryArea(const String& area_name_) const + { + ASSERT(m_area_map_->keyExist(area_name_), "[Error] " + m_instance_name_ + + " -> Unknown queried area name (" + area_name_ + ")"); + return m_area_map_->get(area_name_); + } + + const Result* Model::queryNddPower(const String& ndd_power_name_) + { + ASSERT(m_ndd_power_map_->keyExist(ndd_power_name_), "[Error] " + m_instance_name_ + + " -> Unknown queried ndd power name (" + ndd_power_name_ + ")"); + + use("Idle"); + return m_ndd_power_map_->get(ndd_power_name_); + } + + const Result* Model::queryEventEnergyCost(const String& event_name_) + { + ASSERT(m_event_map_->keyExist(event_name_), "[Error] " + m_instance_name_ + + " -> Unknown queried event name (" + event_name_ + ")"); + + use(event_name_); + return m_event_map_->get(event_name_); + } + + // Update checks whether the model needs updating, whether all properties have been specified, + // and calls updateModel if update is necessary + void Model::construct() + { + // Model should not be constructed yet + ASSERT(!m_constructed_, "[Error] " + getInstanceName() + " -> Cannot construct an already contructed model!"); + // Check if whether all needed parameters are defined + checkParameters(); + constructModel(); + m_constructed_ = true; + m_updated_ = false; + m_evaluated_ = false; + return; + } + + // Update checks whether the model needs updating, whether all properties have been specified, + // and calls updateModel if update is necessary + void Model::update() + { + // Model should be constructed + ASSERT(m_constructed_, "[Error] " + getInstanceName() + " -> Cannot update an unconstructed model!"); + // If the model needs updating (due to property change) + // an update is necessary + if (!m_updated_) + { + // Check if all properties needed exist + checkProperties(); + updateModel(); + m_updated_ = true; + m_evaluated_ = false; + } + return; + } + + // Evaluate checks whether the model needs to be evaluated. + void Model::evaluate() + { + // Model should be constructed + ASSERT(m_constructed_, "[Error] " + getInstanceName() + " -> Cannot evaluate an unconstructed model!"); + // Model should be updated + ASSERT(m_updated_, "[Error] " + getInstanceName() + " -> Cannot evaluate without first updating!"); + // If the model needs evaluating + if (!m_evaluated_) + { + evaluateModel(); + m_evaluated_ = true; + } + + return; + } + + void Model::use(const String& event_name_) + { + useModel(event_name_); + return; + } + + void Model::use() + { + useModel(); + return; + } + + // By default, update model will iterate through all sub-instances and do updateModel on them + void Model::updateModel() + { + Map::Iterator iter = m_sub_instances_->begin(); + Map::Iterator end = m_sub_instances_->end(); + while (iter != end) + { + iter->second->getModel()->update(); + iter++; + } + return; + } + + // By default, update model will iterate through all sub-instances and do updateModel on them + void Model::evaluateModel() + { + Map::Iterator iter = m_sub_instances_->begin(); + Map::Iterator end = m_sub_instances_->end(); + while (iter != end) + { + iter->second->getModel()->evaluate(); + iter++; + } + return; + } + + void Model::useModel(const String& /* event_name_ */) + {} + + void Model::useModel() + {} + + void Model::printHierarchy(const String& query_type_, const String& query_sub_field_, const String& prepend_str_, int detail_level_, ostream& ost_) const + { + if(query_type_ == "InstHier") + { + ost_ << prepend_str_ << getInstanceName() << endl; + printInstHierarchy(prepend_str_, detail_level_, ost_); + //if(detail_level_ > 0) + //{ + //for(Map::ConstIterator it = m_sub_instances_->begin(); it != m_sub_instances_->end(); ++it) + //{ + //const Model* sub_model = (it->second)->getModel(); + //String temp_prepend_str = prepend_str_ + " "; + //sub_model->printHierarchy(query_type_, query_sub_field_, temp_prepend_str, detail_level_ - 1, ost_); + //} + //} + } + else + { + const Map* result_map; + + if(query_type_ == "AreaHier") + { + result_map = m_area_map_; + } + else if(query_type_ == "NddPowerHier") + { + result_map = m_ndd_power_map_; + } + else if(query_type_ == "EventHier") + { + result_map = m_event_map_; + } + else + { + const String& error_msg = "[Error] " + m_instance_name_ + " -> Unknown query type (" + query_type_ + ")"; + throw Exception(error_msg); + return; + } + + if(query_sub_field_ == "") + { + for(Map::ConstIterator it = result_map->begin(); it != result_map->end(); ++it) + { + const Result* result = it->second; + ost_ << prepend_str_ << getInstanceName() << "->" << result->getName() << endl; + result->printHierarchy(prepend_str_, detail_level_, ost_); + } + } + else + { + const Result* result = result_map->get(query_sub_field_); + ost_ << prepend_str_ << getInstanceName() << "->" << result->getName() << endl; + result->printHierarchy(prepend_str_, detail_level_, ost_); + } + } + return; + } + + void Model::printInstHierarchy(const String& prepend_str_, int detail_level_, ostream& ost_) const + { + if(detail_level_ > 0) + { + for(Map::ConstIterator it = m_sub_instances_->begin(); it != m_sub_instances_->end(); ++it) + { + const Model* sub_model = it->second->getModel(); + String temp_prepend_str = prepend_str_ + " "; + + ost_ << prepend_str_ << " |--" << sub_model->getInstanceName() << endl; + sub_model->printInstHierarchy(temp_prepend_str, detail_level_ - 1, ost_); + } + } + return; + } + + Model* Model::clone() const + { + throw Exception(getInstanceName() + " -> Cannot be cloned!"); + } + + Model::Model(const Model& model_) + { + // Copy instance's name + m_instance_name_ = model_.m_instance_name_; + + // Clone properties + m_properties_ = model_.m_properties_->clone(); + + // Clone instances + m_sub_instances_ = clonePtrMap(model_.m_sub_instances_); + + // Clone events, area, ndd_power + m_event_map_ = clonePtrMap(model_.m_event_map_); + m_area_map_ = clonePtrMap(model_.m_area_map_); + m_ndd_power_map_ = clonePtrMap(model_.m_ndd_power_map_); + + // Copy tech model pointer + m_tech_model_ = model_.m_tech_model_; + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/ModelGen.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/ModelGen.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_MODELGEN_H__ +#define __DSENT_MODEL_MODELGEN_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include + +namespace DSENT +{ + class Model; + class ElectricalModel; + class StdCell; + class TechModel; + + class ModelGen + { + public: + // Create the model corresponding to the given String + static Model* createModel(const String& model_name_, const String& instance_name_, const TechModel* tech_model_); + // Create the standard cell corresponding to the given String + static StdCell* createStdCell(const String& std_cell_name_, const String& instance_name_, const TechModel* tech_model_); + // Create the ram corresponding to the given String + static ElectricalModel* createRAM(const String& ram_name_, const String& instance_name_, const TechModel* tech_model_); + // Create the crossbar corresponding to the given String + static ElectricalModel* createCrossbar(const String& crossbar_name_, const String& instance_name_, const TechModel* tech_model_); + // Print the available models + static void printAvailableModels(std::ostream& ost_); + }; +} // namespace DSENT + +#endif // __DSENT_MODEL_MODELGEN_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/ModelGen.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/ModelGen.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/ModelGen.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/model/Model.hh" +// Standard cells +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/INV.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/NAND2.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/NOR2.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/MUX2.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/XOR2.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/DFFQ.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/LATQ.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/ADDF.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/OR2.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/AND2.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/BUF.hh" +// Electrical functional units +#include "mem/ruby/network/dsent/dsent-core/model/electrical/TestModel.hh" +#include "mem/ruby/network/dsent/dsent-core/model/electrical/RippleAdder.hh" +#include "mem/ruby/network/dsent/dsent-core/model/electrical/Multiplexer.hh" +#include "mem/ruby/network/dsent/dsent-core/model/electrical/MultiplexerCrossbar.hh" +#include "mem/ruby/network/dsent/dsent-core/model/electrical/OR.hh" +#include "mem/ruby/network/dsent/dsent-core/model/electrical/Decoder.hh" +#include "mem/ruby/network/dsent/dsent-core/model/electrical/DFFRAM.hh" +#include "mem/ruby/network/dsent/dsent-core/model/electrical/MatrixArbiter.hh" +#include "mem/ruby/network/dsent/dsent-core/model/electrical/SeparableAllocator.hh" +#include "mem/ruby/network/dsent/dsent-core/model/electrical/router/Router.hh" +#include "mem/ruby/network/dsent/dsent-core/model/electrical/RepeatedLink.hh" +#include "mem/ruby/network/dsent/dsent-core/model/electrical/BroadcastHTree.hh" +// Optical functional units +#include "mem/ruby/network/dsent/dsent-core/model/optical/OpticalLinkBackendTx.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical/OpticalLinkBackendRx.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical/SWMRLink.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical/SWSRLink.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical/LaserSource.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical/ThrottledLaserSource.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical/RingModulator.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical/RingDetector.hh" +// Networks +#include "mem/ruby/network/dsent/dsent-core/model/network/ElectricalMesh.hh" +#include "mem/ruby/network/dsent/dsent-core/model/network/ElectricalClos.hh" +#include "mem/ruby/network/dsent/dsent-core/model/network/PhotonicClos.hh" + +namespace DSENT +{ + using std::ostream; + using std::endl; + + //TODO: Eventually automate the creation of this file + + Model* ModelGen::createModel(const String& model_name_, const String& instance_name_, const TechModel* tech_model_) + { + Log::printLine("ModelGen::createModel -> " + model_name_); + + if("INV" == model_name_) + { + return new INV(instance_name_, tech_model_); + } + else if("NAND2" == model_name_) + { + return new NAND2(instance_name_, tech_model_); + } + else if("NOR2" == model_name_) + { + return new NOR2(instance_name_, tech_model_); + } + else if("MUX2" == model_name_) + { + return new MUX2(instance_name_, tech_model_); + } + else if("XOR2" == model_name_) + { + return new XOR2(instance_name_, tech_model_); + } + else if("DFFQ" == model_name_) + { + return new DFFQ(instance_name_, tech_model_); + } + else if("LATQ" == model_name_) + { + return new LATQ(instance_name_, tech_model_); + } + else if("ADDF" == model_name_) + { + return new ADDF(instance_name_, tech_model_); + } + else if("OR2" == model_name_) + { + return new OR2(instance_name_, tech_model_); + } + else if("AND2" == model_name_) + { + return new AND2(instance_name_, tech_model_); + } + else if("BUF" == model_name_) + { + return new BUF(instance_name_, tech_model_); + } + else if("TestModel" == model_name_) + { + return new TestModel(instance_name_, tech_model_); + } + else if("RippleAdder" == model_name_) + { + return new RippleAdder(instance_name_, tech_model_); + } + else if("Multiplexer" == model_name_) + { + return new Multiplexer(instance_name_, tech_model_); + } + else if("OR" == model_name_) + { + return new OR(instance_name_, tech_model_); + } + else if("MultiplexerCrossbar" == model_name_) + { + return new MultiplexerCrossbar(instance_name_, tech_model_); + } + else if("Decoder" == model_name_) + { + return new Decoder(instance_name_, tech_model_); + } + else if("DFFRAM" == model_name_) + { + return new DFFRAM(instance_name_, tech_model_); + } + else if("MatrixArbiter" == model_name_) + { + return new MatrixArbiter(instance_name_, tech_model_); + } + else if("SeparableAllocator" == model_name_) + { + return new SeparableAllocator(instance_name_, tech_model_); + } + else if("Router" == model_name_) + { + return new Router(instance_name_, tech_model_); + } + else if("OpticalLinkBackendTx" == model_name_) + { + return new OpticalLinkBackendTx(instance_name_, tech_model_); + } + else if("OpticalLinkBackendRx" == model_name_) + { + return new OpticalLinkBackendRx(instance_name_, tech_model_); + } + else if("SWMRLink" == model_name_) + { + return new SWMRLink(instance_name_, tech_model_); + } + else if("SWSRLink" == model_name_) + { + return new SWSRLink(instance_name_, tech_model_); + } + else if("LaserSource" == model_name_) + { + return new LaserSource(instance_name_, tech_model_); + } + else if("ThrottledLaserSource" == model_name_) + { + return new ThrottledLaserSource(instance_name_, tech_model_); + } + else if("RingModulator" == model_name_) + { + return new RingModulator(instance_name_, tech_model_); + } + else if("RingDetector" == model_name_) + { + return new RingDetector(instance_name_, tech_model_); + } + else if("RepeatedLink" == model_name_) + { + return new RepeatedLink(instance_name_, tech_model_); + } + else if("BroadcastHTree" == model_name_) + { + return new BroadcastHTree(instance_name_, tech_model_); + } + else if("ElectricalMesh" == model_name_) + { + return new ElectricalMesh(instance_name_, tech_model_); + } + else if("ElectricalClos" == model_name_) + { + return new ElectricalClos(instance_name_, tech_model_); + } + else if("PhotonicClos" == model_name_) + { + return new PhotonicClos(instance_name_, tech_model_); + } + else + { + const String& error_msg = "[Error] Invalid model name (" + model_name_ + ")"; + throw Exception(error_msg); + return NULL; + } + return NULL; + } + + StdCell* ModelGen::createStdCell(const String& std_cell_name_, const String& instance_name_, const TechModel* tech_model_) + { + Log::printLine("ModelGen::createStdCell -> " + std_cell_name_); + + if("INV" == std_cell_name_) + { + return new INV(instance_name_, tech_model_); + } + else if("NAND2" == std_cell_name_) + { + return new NAND2(instance_name_, tech_model_); + } + else if("NOR2" == std_cell_name_) + { + return new NOR2(instance_name_, tech_model_); + } + else if("MUX2" == std_cell_name_) + { + return new MUX2(instance_name_, tech_model_); + } + else if("XOR2" == std_cell_name_) + { + return new XOR2(instance_name_, tech_model_); + } + else if("DFFQ" == std_cell_name_) + { + return new DFFQ(instance_name_, tech_model_); + } + else if("LATQ" == std_cell_name_) + { + return new LATQ(instance_name_, tech_model_); + } + else if("ADDF" == std_cell_name_) + { + return new ADDF(instance_name_, tech_model_); + } + else if("OR2" == std_cell_name_) + { + return new OR2(instance_name_, tech_model_); + } + else if("AND2" == std_cell_name_) + { + return new AND2(instance_name_, tech_model_); + } + else if("BUF" == std_cell_name_) + { + return new BUF(instance_name_, tech_model_); + } + else + { + const String& error_msg = "[Error] Invalid Standard Cell name (" + std_cell_name_ + ")"; + throw Exception(error_msg); + return NULL; + } + return NULL; + } + + ElectricalModel* ModelGen::createRAM(const String& ram_name_, const String& instance_name_, const TechModel* tech_model_) + { + Log::printLine("ModelGen::createRAM -> " + ram_name_); + + if("DFFRAM" == ram_name_) + { + return new DFFRAM(instance_name_, tech_model_); + } + else + { + const String& error_msg = "[Error] Invalid RAM name (" + ram_name_ + ")"; + throw Exception(error_msg); + return NULL; + } + return NULL; + } + + ElectricalModel* ModelGen::createCrossbar(const String& crossbar_name_, const String& instance_name_, const TechModel* tech_model_) + { + Log::printLine("ModelGen::createCrossbar -> " + crossbar_name_); + + if("MultiplexerCrossbar" == crossbar_name_) + { + return new MultiplexerCrossbar(instance_name_, tech_model_); + } + else + { + const String& error_msg = "[Error] Invalid Crossbar name (" + crossbar_name_ + ")"; + throw Exception(error_msg); + return NULL; + } + return NULL; + } + //----------------------------------------------------------------- + + void ModelGen::printAvailableModels(ostream& ost_) + { + // TODO: Need more descriptions + ost_ << "INV NAND2 NOR2 MUX2 XOR2 DFFQ LATQ ADDF OR2 AND2 BUF" << endl; + ost_ << "RippleAdder Multiplexer OR RepeatedLink BroadcastHTree" << endl; + ost_ << "MultiplexerCrossbar Decoder DFFRAM MatrixArbiter SeparableAllocator Router" << endl; + ost_ << "OpticalLinkBackendTx OpticalLinkBackendRx SWMRLink SWSRLink" << endl; + ost_ << "LaserSource ThrottledLaserSource RingModulator RingDetector" << endl; + ost_ << "ElectricalMesh ElectricalClos PhotonicClos" << endl; + return; + } +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/OpticalModel.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/OpticalModel.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_OPTICALMODEL_H__ +#define __DSENT_MODEL_OPTICALMODEL_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" + +namespace DSENT +{ + class PortInfo; + class EventInfo; + class OpticalWaveguide; + class OpticalLaser; + class OpticalFilter; + class OpticalModulator; + class OpticalDetector; + class OpticalReceiver; + class OpticalTransmitter; + + // A Wavelength group consisting of start and end wavelength indices + // Assuming it is the same as a net index so I can use the PortInfo class + typedef NetIndex WavelengthGroup; + + // Helper function for making waveguide groups + inline WavelengthGroup makeWavelengthGroup(int start_index_, int end_index_) + { + ASSERT(end_index_ >= start_index_, (String) "[Error] Invalid wavelength group range " + + "[" + (String) start_index_ + ":" + (String) end_index_ + "]"); + + return WavelengthGroup(start_index_, end_index_); + } + + // Helper function for making wavelength groups + inline WavelengthGroup makeWavelengthGroup(int index_) + { + return makeWavelengthGroup(index_, index_); + } + + // OpticalModel specifies optical connectivity to other optical models as well + class OpticalModel : public ElectricalModel + { + + public: + OpticalModel(const String& instance_name_, const TechModel* tech_model_); + virtual ~OpticalModel(); + + public: + //----------------------------------------------------------------- + // Connectivity specification + //----------------------------------------------------------------- + + /* + + // Waveguide multiplier + void setWaveguideMultiplier(unsigned int waveguide_multiplier_); + unsigned int getWaveguideMultiplier(); + + */ + // Input Ports + void createOpticalInputPort(const String& name_, const WavelengthGroup& wavelengths_); + const Map* getOpticalInputs() const; + PortInfo* getOpticalInputPort(const String& name_); + const PortInfo* getOpticalInputPort(const String& name_) const; + + // Output Ports + void createOpticalOutputPort(const String& name_, const WavelengthGroup& wavelengths_); + const Map* getOpticalOutputs() const; + PortInfo* getOpticalOutputPort(const String& name_); + const PortInfo* getOpticalOutputPort(const String& name_) const; + + // Optical Waveguides + void createWaveguide(const String& name_, const WavelengthGroup& wavelengths_); + const Map* getWaveguides() const; + OpticalWaveguide* getWaveguide(const String& name_); + + // Assign a waveguide to be downstream from another waveguide + void opticalAssign(const String& downstream_waveguide_name_, const String& upstream_waveguide_name_); + + // Connect a port (input or output) to some waveguide + void opticalPortConnect(OpticalModel* connect_model_, const String& connect_port_name_, const String& connect_waveguide_name_); + //----------------------------------------------------------------- + + //----------------------------------------------------------------- + // Optical Graph Model Components + //----------------------------------------------------------------- + // Optical Laser Sources + + void createLaser(const String& name_, const WavelengthGroup& wavelengths_); + const Map* getLasers() const; + OpticalLaser* getLaser(const String& name_); + // Optical Laser Sources + void createFilter(const String& name_, const WavelengthGroup& wavelengths_, bool drop_all_, const WavelengthGroup& drop_wavelengths_); + const Map* getFilters() const; + OpticalFilter* getFilter(const String& name_); + // Optical Modulators + void createModulator(const String& name_, const WavelengthGroup& wavelengths_, bool opt_loss_, OpticalTransmitter* transmitter_); + const Map* getModulators() const; + OpticalModulator* getModulator(const String& name_); + // Optical Detectors + void createDetector(const String& name_, const WavelengthGroup& wavelengths_, OpticalReceiver* receiver_); + const Map* getDetectors() const; + OpticalDetector* getDetector(const String& name_); + + //----------------------------------------------------------------- + + protected: + // In an OpticalModel, the complete optical port-to-port connectivity + // of all sub-instances must be specified. Addition/Removal optical + // ports or port-related nets cannot happen after this step + //virtual void constructModel() = 0; + // In an OpticalModel, updateModel MUST finish all necessary + // calculations such that loss and wavelength power can be calculated + //virtual void updateModel() = 0; + // In an OpticalModel, evaluateModel should calculate all wavelength + // power, updating power and energy events as necessary + //virtual void evaluateModel() = 0; + + private: + // Private copy constructor. Use clone to perform copy operation. + OpticalModel(const OpticalModel& model_); + + private: + // Map of all input ports + Map* m_optical_input_ports_; + // Map of all output ports + Map* m_optical_output_ports_; + + // Optical graph model elements + // Map of all waveguides + Map* m_waveguides_; + // Map of all laser source elements + Map* m_lasers_; + // Map of all filter elements + Map* m_filters_; + // Map of all modulator elements + Map* m_modulators_; + // Map of all photodetector elements + Map* m_detectors_; + + }; // class OpticalModel +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICALMODEL_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/OpticalModel.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/OpticalModel.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/OpticalModel.hh" + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalWaveguide.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalNode.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalLaser.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalModulator.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalFilter.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalDetector.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalWavelength.hh" + +namespace DSENT +{ + OpticalModel::OpticalModel(const String& instance_name_, const TechModel* tech_model_) + : ElectricalModel(instance_name_, tech_model_) + { + m_optical_input_ports_ = new Map; + m_optical_output_ports_ = new Map; + + m_waveguides_ = new Map; + m_lasers_ = new Map; + m_modulators_ = new Map; + m_filters_ = new Map; + m_detectors_ = new Map; + } + + OpticalModel::~OpticalModel() + { + delete m_optical_input_ports_; + delete m_optical_output_ports_; + deletePtrMap(m_waveguides_); + deletePtrMap(m_lasers_); + deletePtrMap(m_modulators_); + deletePtrMap(m_filters_); + deletePtrMap(m_detectors_); + m_optical_input_ports_ = NULL; + m_optical_output_ports_ = NULL; + m_waveguides_ = NULL; + m_lasers_ = NULL; + m_modulators_ = NULL; + m_filters_ = NULL; + m_detectors_ = NULL; + } + + // Connect an optical port (input or output) to some OpticalWaveguide + void OpticalModel::opticalPortConnect(OpticalModel* connect_model_, const String& port_name_, const String& waveguide_name_) + { + // Check that the connecting waveguide exists + ASSERT(m_waveguides_->keyExist(waveguide_name_), "[Error] " + getInstanceName() + + " -> Waveguide '" + waveguide_name_ + "' does not exist!"); + + // Check whether the port name is an input or output, assertion error if neither + bool is_input = connect_model_->getOpticalInputs()->keyExist(port_name_); + bool is_output = connect_model_->getOpticalOutputs()->keyExist(port_name_); + ASSERT(is_input || is_output, "[Error] " + getInstanceName() + " -> Model '" + connect_model_->getInstanceName() + + "' does not have a port named '" + port_name_ + "'!"); + + // Get the two waveguides + OpticalWaveguide* port_waveguide = connect_model_->getWaveguide(port_name_); + OpticalWaveguide* connect_waveguide = getWaveguide(waveguide_name_); + + // Check that the two waveguides expect the same wavelengths + ASSERT((port_waveguide->getWavelengths().first == connect_waveguide->getWavelengths().first) && + (port_waveguide->getWavelengths().second == connect_waveguide->getWavelengths().second), + "[Error] " + getInstanceName() + " -> Optical port expects different wavelengths for Model '" + + connect_model_->getInstanceName() + "." + port_name_ + "' and waveguide '" + waveguide_name_ + "'!"); + + if(is_input) + { + connect_waveguide->addDownstreamNode(port_waveguide); + } + else if(is_output) + { + port_waveguide->addDownstreamNode(connect_waveguide); + } + } + + //Get Waveguides + const Map* OpticalModel::getWaveguides() const + { + return m_waveguides_; + } + + OpticalWaveguide* OpticalModel::getWaveguide(const String& name_) + { + return m_waveguides_->get(name_); + } + + //Get Lasers + const Map* OpticalModel::getLasers() const + { + return m_lasers_; + } + + OpticalLaser* OpticalModel::getLaser(const String& name_) + { + return m_lasers_->get(name_); + } + + //Get Modulators + const Map* OpticalModel::getModulators() const + { + return m_modulators_; + } + + OpticalModulator* OpticalModel::getModulator(const String& name_) + { + return m_modulators_->get(name_); + } + + //Get Filters + const Map* OpticalModel::getFilters() const + { + return m_filters_; + } + + OpticalFilter* OpticalModel::getFilter(const String& name_) + { + return m_filters_->get(name_); + } + + //Get Detectors + const Map* OpticalModel::getDetectors() const + { + return m_detectors_; + } + + OpticalDetector* OpticalModel::getDetector(const String& name_) + { + return m_detectors_->get(name_); + } + + //Get Inputs + const Map* OpticalModel::getOpticalInputs() const + { + return m_optical_input_ports_; + } + + PortInfo* OpticalModel::getOpticalInputPort(const String& name_) + { + ASSERT(m_optical_input_ports_->keyExist(name_), "[Error] " + getInstanceName() + + " -> Input port (" + name_ + ") does not exist"); + + return m_optical_input_ports_->get(name_); + } + + const PortInfo* OpticalModel::getOpticalInputPort(const String& name_) const + { + ASSERT(m_optical_input_ports_->keyExist(name_), "[Error] " + getInstanceName() + + " -> Input port (" + name_ + ") does not exist"); + + return m_optical_input_ports_->get(name_); + } + + //Get Outputs + const Map* OpticalModel::getOpticalOutputs() const + { + return m_optical_output_ports_; + } + + PortInfo* OpticalModel::getOpticalOutputPort(const String& name_) + { + ASSERT(m_optical_output_ports_->keyExist(name_), "[Error] " + getInstanceName() + + " -> Input port (" + name_ + ") does not exist"); + + return m_optical_output_ports_->get(name_); + } + + const PortInfo* OpticalModel::getOpticalOutputPort(const String& name_) const + { + ASSERT(m_optical_output_ports_->keyExist(name_), "[Error] " + getInstanceName() + + " -> Input port (" + name_ + ") does not exist"); + + return m_optical_output_ports_->get(name_); + } + + //------------------------------------------------------------------------- + // Optical Connectivity Creation Functions + //------------------------------------------------------------------------- + void OpticalModel::createOpticalInputPort(const String& name_, const WavelengthGroup& wavelength_group_) + { + // Create the new waveguides + // This should already check that it has not been previously declared + createWaveguide(name_, wavelength_group_); + // Add the waveguide name to list of input ports + m_optical_input_ports_->set(name_, new PortInfo(name_, wavelength_group_)); + return; + } + + void OpticalModel::createOpticalOutputPort(const String& name_, const WavelengthGroup& wavelength_group_) + { + // Create the new waveguides (including its waveguide reference) + // This should already check that it has not been previously declared + createWaveguide(name_, wavelength_group_); + // Add the waveguide name to list of output ports + m_optical_output_ports_->set(name_, new PortInfo(name_, wavelength_group_)); + return; + } + + // Waveguide creation + void OpticalModel::createWaveguide(const String& name_, const WavelengthGroup& wavelengths_) + { + // Check that the waveguide hasn't been previously declared + ASSERT( !m_waveguides_->keyExist(name_), "[Error] " + getInstanceName() + + " -> Redeclaration of waveguide " + name_); + m_waveguides_->set(name_, new OpticalWaveguide(name_, this, wavelengths_)); + return; + } + + // Laser creation + void OpticalModel::createLaser(const String& name_, const WavelengthGroup& wavelengths_) + { + // Check that the laser hasn't been previously declared + ASSERT( !m_lasers_->keyExist(name_), "[Error] " + getInstanceName() + + " -> Redeclaration of laser " + name_); + m_lasers_->set(name_, new OpticalLaser(name_, this, wavelengths_)); + return; + } + + // Modulator creation + void OpticalModel::createModulator(const String& name_, const WavelengthGroup& wavelengths_, bool opt_loss_, OpticalTransmitter* transmitter_) + { + // Check that the modulator hasn't been previously declared + ASSERT( !m_modulators_->keyExist(name_), "[Error] " + getInstanceName() + + " -> Redeclaration of modulator " + name_); + m_modulators_->set(name_, new OpticalModulator(name_, this, wavelengths_, opt_loss_, transmitter_)); + return; + } + + // Modulator Multiplier creation + void OpticalModel::createFilter(const String& name_, const WavelengthGroup& wavelengths_, bool drop_all_, const WavelengthGroup& drop_wavelengths_) + { + // Check that the filter hasn't been previously declared + ASSERT( !m_filters_->keyExist(name_), "[Error] " + getInstanceName() + + " -> Redeclaration of filter " + name_); + m_filters_->set(name_, new OpticalFilter(name_, this, wavelengths_, drop_all_, drop_wavelengths_)); + return; + } + + // Detector creation + void OpticalModel::createDetector(const String& name_, const WavelengthGroup& wavelengths_, OpticalReceiver* receiver_) + { + // Check that the detector hasn't been previously declared + ASSERT( !m_detectors_->keyExist(name_), "[Error] " + getInstanceName() + + " -> Redeclaration of detector " + name_); + m_detectors_->set(name_, new OpticalDetector(name_, this, wavelengths_, receiver_)); + return; + } + + //------------------------------------------------------------------------- + + // Assign a waveguide to be downstream from another waveguide + // assign downtream_waveguide_name_ = upstream_waveguide_name_ + void OpticalModel::opticalAssign(const String& downstream_waveguide_name_, const String& upstream_waveguide_name_) + { + ASSERT(getWaveguides()->keyExist(downstream_waveguide_name_), "[Error] " + getInstanceName() + " -> Waveguide '" + + downstream_waveguide_name_ + "' does not exist!"); + + ASSERT(getWaveguides()->keyExist(upstream_waveguide_name_), "[Error] " + getInstanceName() + " -> Waveguide '" + + upstream_waveguide_name_ + "' does not exist!"); + + // Get the two waveguides + OpticalWaveguide* upstream_waveguide = getWaveguide(upstream_waveguide_name_); + OpticalWaveguide* downstream_waveguide = getWaveguide(downstream_waveguide_name_); + + // Check that the two waveguides expect the same wavelengths + ASSERT((upstream_waveguide->getWavelengths().first == downstream_waveguide->getWavelengths().first) && + (upstream_waveguide->getWavelengths().second == downstream_waveguide->getWavelengths().second), + "[Error] " + getInstanceName() + " -> Assignment expects different wavelengths for waveguide '" + + upstream_waveguide_name_ + "' and waveguide '" + downstream_waveguide_name_ + "'!"); + + // Connect the downstream waveguide and the upstream waveguide + upstream_waveguide->addDownstreamNode(downstream_waveguide); + return; + } +} // namespace DSENT diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/PortInfo.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/PortInfo.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_PORT_INFO_H__ +#define __DSENT_MODEL_PORT_INFO_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" + +namespace DSENT +{ + class PortInfo + { + public: + PortInfo(const String& port_name_, const NetIndex& net_index_ = NetIndex(0, 0)); + ~PortInfo(); + + public: + // Get the port name + const String& getPortName() const; + // Get the net index + const NetIndex& getNetIndex() const; + // Set the transition information of this port + void setTransitionInfo(const TransitionInfo& trans_info_); + // Get the transition information of this port + const TransitionInfo& getTransitionInfo() const; + + private: + // Name of this port + String m_port_name_; + // Net index of the input port + NetIndex m_net_index_; + // Store the transition information of this port + TransitionInfo m_tran_info_; + }; // class PortInfo +} // namespace DSENT + +#endif // __DSENT_MODEL_PORT_INFO_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/PortInfo.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/PortInfo.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" + +namespace DSENT +{ + PortInfo::PortInfo(const String& port_name_, const NetIndex& net_index_) + : m_port_name_(port_name_), m_net_index_(net_index_), m_tran_info_(TransitionInfo()) + { + } + + PortInfo::~PortInfo() + { + } + + const String& PortInfo::getPortName() const + { + return m_port_name_; + } + + const NetIndex& PortInfo::getNetIndex() const + { + return m_net_index_; + } + + void PortInfo::setTransitionInfo(const TransitionInfo& trans_info_) + { + m_tran_info_ = trans_info_; + return; + } + + const TransitionInfo& PortInfo::getTransitionInfo() const + { + return m_tran_info_; + } +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/SConscript --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/SConscript Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,40 @@ +# 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. +# +# Authors: Chia-Hsin Owen Chen + +Import('*') + +if env['PROTOCOL'] == 'None': + Return() + +Source('EventInfo.cc') +Source('Model.cc') +Source('PortInfo.cc') +Source('TransitionInfo.cc') +Source('OpticalModel.cc') +Source('ElectricalModel.cc') +Source('ModelGen.cc') + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_TRANSITION_INFO_H__ +#define __DSENT_MODEL_TRANSITION_INFO_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" + +namespace DSENT +{ + /** + * \brief This class contains the number of transitions and the frequency multiplier information + */ + class TransitionInfo + { + public: + TransitionInfo(); + TransitionInfo(double number_transitions_00_, double number_transitions_01_, double number_transitions_11_); + ~TransitionInfo(); + + public: + inline double getNumberTransitions00() const { return m_number_transitions_00_; } + inline double getNumberTransitions01() const { return m_number_transitions_01_; } + inline double getNumberTransitions11() const { return m_number_transitions_11_; } + inline double getFrequencyMultiplier() const { return m_frequency_multiplier_; } + inline double getProbability0() const { return m_probability_1_; } + inline double getProbability1() const { return m_probability_1_; } + + inline void setNumberTransitions00(double value_) { m_number_transitions_00_ = value_; } + inline void setNumberTransitions01(double value_) { m_number_transitions_01_ = value_; } + inline void setNumberTransitions11(double value_) { m_number_transitions_11_ = value_; } + inline void setFrequencyMultiplier(double value_) { m_frequency_multiplier_ = value_; } + + void update(); + TransitionInfo scaleFrequencyMultiplier(double frequency_multiplier_) const; + + void print(std::ostream& ost_) const; + + private: + // m_number_transitions_xy_ defines number of transitions from x to y + double m_number_transitions_00_; + double m_number_transitions_01_; + double m_number_transitions_11_; + // The multiplier that defines the ratio of the transition frequency and the main core clock frequency + double m_frequency_multiplier_; + // Probability of being at state 0/1 + double m_probability_0_; + double m_probability_1_; + }; // class TransitionInfo +} // namespace DSENT + +#endif // __DSENT_MODEL_TRANSITION_INFO_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/TransitionInfo.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/TransitionInfo.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" + +namespace DSENT +{ + TransitionInfo::TransitionInfo() + : m_number_transitions_00_(0.25), m_number_transitions_01_(0.25), + m_number_transitions_11_(0.25), m_frequency_multiplier_(1.0) + { + update(); + } + + TransitionInfo::TransitionInfo(double number_transitions_00_, double number_transitions_01_, + double number_transitions_11_) + : m_number_transitions_00_(number_transitions_00_), m_number_transitions_01_(number_transitions_01_), + m_number_transitions_11_(number_transitions_11_) + { + m_frequency_multiplier_ = m_number_transitions_00_ + 2.0 * m_number_transitions_01_ + m_number_transitions_11_; + update(); + } + + TransitionInfo::~TransitionInfo() + {} + + void TransitionInfo::update() + { + ASSERT(m_number_transitions_00_ >= 0.0, "[Error] Number of 0->0 transitions (" + + (String)m_number_transitions_00_ + ") must be >= 0.0!"); + ASSERT(m_number_transitions_01_ >= 0.0, "[Error] Number of 0->1 transitions (" + + (String)m_number_transitions_01_ + ") must be >= 0.0!"); + ASSERT(m_number_transitions_11_ >= 0.0, "[Error] Number of 1->1 transitions (" + (String)m_number_transitions_11_ + ") must be >= 0.0!"); + + m_probability_1_ = (m_number_transitions_01_ + m_number_transitions_11_) / m_frequency_multiplier_; + m_probability_0_ = 1.0 - m_probability_1_; + return; + } + + TransitionInfo TransitionInfo::scaleFrequencyMultiplier(double frequency_multiplier_) const + { + // A short cut if frequency_multiplier_ == m_frequency_multiplier_ to avoid excess calculations + if(frequency_multiplier_ == m_frequency_multiplier_) + { + return TransitionInfo(m_number_transitions_00_, m_number_transitions_01_, m_number_transitions_11_); + } + else if (frequency_multiplier_ > m_frequency_multiplier_) + { + double freq_ratio = frequency_multiplier_ / m_frequency_multiplier_; + double diff_num_trans_01 = m_number_transitions_01_ * (freq_ratio - 1.0); + double norm_num_trans_00 = m_number_transitions_00_ * freq_ratio + diff_num_trans_01; + double norm_num_trans_01 = m_number_transitions_01_; + double norm_num_trans_11 = m_number_transitions_11_ * freq_ratio + diff_num_trans_01; + + return TransitionInfo(norm_num_trans_00, norm_num_trans_01, norm_num_trans_11); + } + else + { + ASSERT(false, "[Error] Cannot scale to frequency multiplier (" + (String) frequency_multiplier_ + + ") since current frequency multiplier (" + (String) m_frequency_multiplier_ + ") is bigger!"); + } + } + + void TransitionInfo::print(std::ostream& ost_) const + { + ost_ << "[" << m_number_transitions_00_ << ", " << m_number_transitions_01_ << ", " << m_number_transitions_11_ << "]"; + ost_ << " [" << m_number_transitions_00_ / m_frequency_multiplier_; + ost_ << ", " << m_number_transitions_01_*2.0 / m_frequency_multiplier_; + ost_ << ", " << m_number_transitions_11_ / m_frequency_multiplier_ << "]" << endl; + return; + } +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/BarrelShifter.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/BarrelShifter.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_ELECTRICAL_BARRELSHIFTER_H__ +#define __DSENT_MODEL_ELECTRICAL_BARRELSHIFTER_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" + +namespace DSENT +{ + // A model on N-bit barrel-shifter. Shifts to the right by X + class BarrelShifter : public ElectricalModel + { + public: + BarrelShifter(const String& instance_name_, const TechModel* tech_model_); + virtual ~BarrelShifter(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + + // Clone and return a new instance + virtual BarrelShifter* clone() const; + + protected: + // Build the model + virtual void constructModel(); + virtual void propagateTransitionInfo(); + + }; // class BarrelShifter +} // namespace DSENT + +#endif // __DSENT_MODEL_ELECTRICAL_MULTIPLEXER_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/BarrelShifter.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/BarrelShifter.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/electrical/BarrelShifter.hh" +#include "mem/ruby/network/dsent/dsent-core/model/electrical/Multiplexer.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriverMultiplier.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" + +namespace DSENT +{ + BarrelShifter::BarrelShifter(const String& instance_name_, const TechModel* tech_model_) + : ElectricalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + BarrelShifter::~BarrelShifter() + {} + + void BarrelShifter::initParameters() + { + addParameterName("NumberBits"); + addParameterName("ShiftIndexMin"); + addParameterName("ShiftIndexMax"); + addParameterName("BitDuplicate", "TRUE"); + return; + } + + void BarrelShifter::initProperties() + { + return; + } + + BarrelShifter* BarrelShifter::clone() const + { + return NULL; + } + + void BarrelShifter::constructModel() + { + // Get parameters + unsigned int number_bits = getParameter("NumberBits"); + unsigned int number_shift_bits = (unsigned int)ceil(log2((double) number_bits)); + unsigned int shift_index_min = getParameter("ShiftIndexMin"); + unsigned int shift_index_max = getParameter("ShiftIndexMax"); + bool bit_duplicate = (bool) getParameter("BitDuplicate"); + + ASSERT(number_bits > 0, "[Error] " + getInstanceName() + " -> Number of bits must be > 0!"); + // No need to check these if there arent any shifts + if (number_shift_bits > 0) + { + ASSERT(shift_index_min <= number_shift_bits, + "[Error] " + getInstanceName() + " -> Min shift index must be >= 0 and <= " + + "the total number of shift bits!"); + ASSERT(shift_index_max >= shift_index_min && shift_index_max <= number_shift_bits, + "[Error] " + getInstanceName() + " -> Max shift index must be >= minimum shift index and <= " + + "the total number of shift bits!"); + } + + //Construct electrical ports + //Create each input port + createInputPort( "In", makeNetIndex(0, number_bits-1)); + //Create output + createOutputPort( "Out", makeNetIndex(0, number_bits-1)); + + //Create shift ports (which only exists if there is something to shift) + if (shift_index_min != number_shift_bits) + for (unsigned int i = shift_index_min; i <= shift_index_max; ++i) + createInputPort( "Shift" + (String) i); + + //Create energy, power, and area results + createElectricalResults(); + createElectricalEventResult("BarrelShift"); + //Set conditions during idle event + getEventInfo("Idle")->setStaticTransitionInfos(); + + //If the input is only 1-bit, connect input to output and be done + if (number_shift_bits == 0 || (shift_index_min == number_shift_bits)) + assign("Out", "In"); + else + { + for (unsigned int i = shift_index_min; i <= shift_index_max; ++i) + { + //Create internally buffered shift select signals + createNet("Shift_b" + (String) i); + createNet("Shift_i" + (String) i); + } + + // Create shift and shifted signals + for (unsigned int i = shift_index_min; i <= shift_index_max; ++i) + { + unsigned int current_shifts = (unsigned int)pow(2, i); + const String& n = (String) current_shifts; + //Instantiate and connect intermediate nets. In a barrel-shifter, the nets do + //all the "shifting" and the muxes just select which to take + createNet("R_" + n, makeNetIndex(0, number_bits-1)); //wire R_n[number_bits-1:0] + createNet("RS_" + n, makeNetIndex(0, number_bits-1)); //wire RS_n[number_bits-1:0] + + //Implements the shifts + //assign RS_n[number_bits-1:number_bits-current_shifts] = R_n[current_shifts-1:0]; + assign("RS_" + n, makeNetIndex(number_bits-current_shifts, number_bits-1), + "R_" + n, makeNetIndex(0, current_shifts-1)); + //assign RS_n[number_bits-current_shifts-1:0] = R_n[current_shifts:number_bits-1]; + assign("RS_" + n, makeNetIndex(0, number_bits-current_shifts-1), + "R_" + n, makeNetIndex(current_shifts, number_bits-1)); + } + + const String& n_max = (String) pow(2, shift_index_max+1); + const String& n_min = (String) pow(2, shift_index_min); + // Create the R_(max) net + createNet("R_" + n_max, makeNetIndex(0, number_bits-1)); + // Set R_1 to be the input + assign("R_" + n_min, "In"); + // Set R_(max) to be the output + assign("Out", "R_" + n_max, makeNetIndex(0, number_bits-1)); + + for (unsigned int i = shift_index_min; i <= shift_index_max; ++i) + { + unsigned int current_shifts = (unsigned int)pow(2, i); + const String& n = (String) current_shifts; + const String& n_next = (String) (current_shifts * 2); + + const String& buf_inv_0_name = "ShiftBufInv0_" + (String) n; + const String& buf_inv_1_name = "ShiftBufInv1_" + (String) n; + // Create shift buffer inverters + StdCell* buf_inv_0 = getTechModel()->getStdCellLib()->createStdCell("INV", buf_inv_0_name); + buf_inv_0->construct(); + StdCell* buf_inv_1 = getTechModel()->getStdCellLib()->createStdCell("INV", buf_inv_1_name); + buf_inv_1->construct(); + + // Connect up shift buffer inverters + portConnect(buf_inv_0, "A", "Shift" + (String) i); + portConnect(buf_inv_0, "Y", "Shift_b" + (String) i); + portConnect(buf_inv_1, "A", "Shift_b" + (String) i); + portConnect(buf_inv_1, "Y", "Shift_i" + (String) i); + + // Add area, power, and event results for inverters + addSubInstances(buf_inv_0, 1.0); + addSubInstances(buf_inv_1, 1.0); + addElectricalSubResults(buf_inv_0, 1.0); + addElectricalSubResults(buf_inv_1, 1.0); + getEventResult("BarrelShift")->addSubResult(buf_inv_0->getEventResult("INV"), buf_inv_0_name, 1.0); + getEventResult("BarrelShift")->addSubResult(buf_inv_1->getEventResult("INV"), buf_inv_1_name, 1.0); + + //Instantiate 2:1 multiplexers, one for each shift bit. + const String& mux_name = "SRL" + n; + Multiplexer* mux = new Multiplexer(mux_name, getTechModel()); + mux->setParameter("NumberInputs", 2); + mux->setParameter("NumberBits", number_bits); + mux->setParameter("BitDuplicate", bit_duplicate); + mux->construct(); + + //Just have to connect the In0 and In1 inputs of the mux to the + //non-shifted and shifted intermediate signals, respectively. + portConnect(mux, "In0", "R_" + n); + portConnect(mux, "In1", "RS_" + n); + //Selector connects to the shift signal for that index + portConnect(mux, "Sel0", "Shift_i" + (String) i); + //Connect mux output + portConnect(mux, "Out", "R_" + n_next); + + //Add area, power, and event results for each mux + addSubInstances(mux, 1.0); + addElectricalSubResults(mux, 1.0); + getEventResult("BarrelShift")->addSubResult(mux->getEventResult("Mux"), mux_name, 1.0); + } + } + return; + } + + void BarrelShifter::propagateTransitionInfo() + { + // The only thing can be updated are the input probabilities...so we will update them + unsigned int number_bits = (unsigned int) getParameter("NumberBits"); + unsigned int number_shift_bits = (unsigned int) ceil(log2((double) number_bits)); + unsigned int shift_index_min = getParameter("ShiftIndexMin"); + unsigned int shift_index_max = getParameter("ShiftIndexMax"); + + // Keep track of the multiplexer of the last stage + ElectricalModel* last_mux = NULL; + // We only need to update stuff if we are not shifting by exact multiples + // of number of input bits + if (shift_index_min < number_shift_bits) + { + for (unsigned int i = shift_index_min; i <= shift_index_max; ++i) + { + unsigned int current_shifts = (unsigned int)pow(2, i); + String n = (String) current_shifts; + + // Set the + const String& buf_inv_0_name = "ShiftBufInv0_" + (String) n; + const String& buf_inv_1_name = "ShiftBufInv1_" + (String) n; + const String& mux_name = "SRL" + n; + + // Set the transition infos for the inverter buffers + ElectricalModel* buf_inv_0 = (ElectricalModel*) getSubInstance(buf_inv_0_name); + propagatePortTransitionInfo(buf_inv_0, "A", "Shift" + (String) i); + buf_inv_0->use(); + + ElectricalModel* buf_inv_1 = (ElectricalModel*) getSubInstance(buf_inv_1_name); + propagatePortTransitionInfo(buf_inv_1, "A", buf_inv_0, "Y"); + buf_inv_1->use(); + + // Set the transition infos for the shift multiplexers + ElectricalModel* mux = (ElectricalModel*) getSubInstance(mux_name); + propagatePortTransitionInfo(mux, "Sel0", buf_inv_1, "Y"); + if (last_mux == NULL) + { + propagatePortTransitionInfo(mux, "In0", "In"); + propagatePortTransitionInfo(mux, "In1", "In"); + } + else + { + propagatePortTransitionInfo(mux, "In0", last_mux, "Out"); + propagatePortTransitionInfo(mux, "In1", last_mux, "Out"); + } + mux->use(); + + // Set this to be the last mux visted + last_mux = mux; + } + } + + // If there isn't anything to shift + if (last_mux == NULL) + propagatePortTransitionInfo("Out", "In"); + // Take the transition info of the last mux + else + propagatePortTransitionInfo("Out", last_mux, "Out"); + + return; + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/BroadcastHTree.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/BroadcastHTree.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_ELECTRICAL_BROADCAST_HTREE_H__ +#define __DSENT_MODEL_ELECTRICAL_BROADCAST_HTREE_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" + +#include + +namespace DSENT +{ + using std::vector; + + class StdCell; + class ElectricalLoad; + class ElectricalTimingTree; + + class BroadcastHTree : public ElectricalModel + { + public: + BroadcastHTree(const String& instance_name_, const TechModel* tech_model_); + virtual ~BroadcastHTree(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + + // Clone and return a new instance + virtual BroadcastHTree* clone() const; + + protected: + // Build the model + virtual void constructModel(); + virtual void updateModel(); + virtual void useModel(); + virtual void propagateTransitionInfo(); + + private: + vector m_repeaters_; + vector m_repeater_loads_; + vector m_timing_trees_; + vector m_number_segments_; + + vector m_leaf_drivers_; + ElectricalLoad* m_leaf_load_; + StdCell* m_leaf_head_driver_; + ElectricalLoad* m_leaf_head_load_; + + }; // class BroadcastHTree +} // namespace DSENT + +#endif // __DSENT_MODEL_ELECTRICAL_BROADCAST_HTREE_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/BroadcastHTree.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/BroadcastHTree.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,431 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/electrical/BroadcastHTree.hh" + +#include +#include + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalLoad.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDelay.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriver.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingTree.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" + +namespace DSENT +{ + using std::pow; + using std::vector; + + BroadcastHTree::BroadcastHTree(const String& instance_name_, const TechModel* tech_model_) + : ElectricalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + + m_leaf_load_ = NULL; + m_leaf_head_driver_ = NULL; + m_leaf_head_load_ = NULL; + } + + BroadcastHTree::~BroadcastHTree() + { + clearPtrVector(&m_repeaters_); + clearPtrVector(&m_repeater_loads_); + clearPtrVector(&m_timing_trees_); + clearPtrVector(&m_leaf_drivers_); + delete m_leaf_load_; + delete m_leaf_head_driver_; + delete m_leaf_head_load_; + } + + void BroadcastHTree::initParameters() + { + addParameterName("NumberLevels"); + addParameterName("NumberBits"); + addParameterName("WireLayer"); + addParameterName("WireWidthMultiplier", 1.0); + addParameterName("WireSpacingMultiplier", 1.0); + return; + } + + void BroadcastHTree::initProperties() + { + addPropertyName("SitePitch"); + addPropertyName("TotalLoadCapPerBit"); + return; + } + + BroadcastHTree* BroadcastHTree::clone() const + { + // TODO + return NULL; + } + + void BroadcastHTree::constructModel() + { + // Get parameters + unsigned int number_levels = getParameter("NumberLevels").toUInt(); + unsigned int number_bits = getParameter("NumberBits").toUInt(); + const String& wire_layer = getParameter("WireLayer"); + double wire_width_multiplier = getParameter("WireWidthMultiplier").toDouble(); + double wire_spacing_multiplier = getParameter("WireSpacingMultiplier").toDouble(); + + ASSERT(number_levels > 0, "[Error] " + getInstanceName() + + " -> Number of levels must be > 0!"); + ASSERT(number_bits > 0, "[Error] " + getInstanceName() + + " -> Number of bits must be > 0!"); + ASSERT(getTechModel()->isWireLayerExist(wire_layer), "[Error] " + getInstanceName() + + " -> Wire layer does not exist!"); + ASSERT(wire_width_multiplier >= 1.0, "[Error] " + getInstanceName() + + " -> Wire width multiplier must be >= 1.0!"); + ASSERT(wire_spacing_multiplier >= 1.0, "[Error] " + getInstanceName() + + " -> Wire spacing multiplier must be >= 1.0!"); + + double wire_min_width = getTechModel()->get("Wire->" + wire_layer + "->MinWidth").toDouble(); + double wire_min_spacing = getTechModel()->get("Wire->" + wire_layer + "->MinSpacing").toDouble(); + + double wire_width = wire_min_width * wire_width_multiplier; + double wire_spacing = wire_min_spacing * wire_spacing_multiplier; + + double wire_cap_per_len = getTechModel()->calculateWireCapacitance(wire_layer, wire_width, wire_spacing, 1.0); + double wire_res_per_len = getTechModel()->calculateWireResistance(wire_layer, wire_width, 1.0); + + getGenProperties()->set("WireWidth", wire_width); + getGenProperties()->set("WireSpacing", wire_spacing); + getGenProperties()->set("WireCapacitancePerLength", wire_cap_per_len); + getGenProperties()->set("WireResistancePerLength", wire_res_per_len); + + // Create ports + createInputPort("In", makeNetIndex(0, number_bits-1)); + createOutputPort("Out", makeNetIndex(0, number_bits-1)); + + // Create connections + createNet("InTmp"); + createNet("OutTmp"); + assignVirtualFanin("InTmp", "In"); + assignVirtualFanout("Out", "OutTmp"); + + createLoad("In_Cap"); + createDelay("In_to_Out_delay"); + + ElectricalLoad* in_cap = getLoad("In_Cap"); + ElectricalDelay* in_to_out_delay = getDelay("In_to_Out_delay"); + + getNet("InTmp")->addDownstreamNode(in_cap); + in_cap->addDownstreamNode(in_to_out_delay); + + // Init + for(unsigned int i = 0; i < number_levels; ++i) + { + StdCell* repeater = getTechModel()->getStdCellLib()->createStdCell("INV", "Repeater" + (String)i); + ElectricalLoad* repeater_load = new ElectricalLoad("RepeaterIn_Cap" + (String)i, this); + ElectricalTimingTree* timing_tree = new ElectricalTimingTree("RepeatedLink" + (String)i, this); + + repeater->construct(); + repeater->getNet("Y")->addDownstreamNode(repeater_load); + m_repeaters_.push_back(repeater); + m_repeater_loads_.push_back(repeater_load); + m_timing_trees_.push_back(timing_tree); + } + + // Create area, power, and event results + createElectricalAtomicResults(); + createElectricalEventResult("Send"); + addEventResult(new AtomicResult("DriveLoad")); + addEventResult(new AtomicResult("DriveTree")); + + getEventResult("Send")->addSubResult(getEventResult("DriveLoad"), "Self", 1.0); + getEventResult("Send")->addSubResult(getEventResult("DriveTree"), "Self", 1.0); + return; + } + + void BroadcastHTree::updateModel() + { + // Get properties + double site_pitch = getProperty("SitePitch").toDouble(); + double total_load_cap_per_bit = getProperty("TotalLoadCapPerBit").toDouble(); + + ASSERT(site_pitch > 0, "[Error] " + getInstanceName() + + " -> Site pitch must be > 0!"); + ASSERT(total_load_cap_per_bit >= 0.0, "[Error] " + getInstanceName() + + " -> Total load capacitance per bit must be >= 0!"); + + // Get parameters + unsigned int number_levels = getParameter("NumberLevels"); + unsigned int number_bits = getParameter("NumberBits"); + + const String& wire_layer = getParameter("WireLayer"); + double wire_width = getGenProperties()->get("WireWidth").toDouble(); + double wire_spacing = getGenProperties()->get("WireSpacing").toDouble(); + double wire_cap_per_len = getGenProperties()->get("WireCapacitancePerLength").toDouble(); + double wire_res_per_len = getGenProperties()->get("WireResistancePerLength").toDouble(); + + double leaf_load_cap = total_load_cap_per_bit / pow(2.0, (double)(number_levels-1)); + + vector wire_caps(number_levels, 0.0); + vector wire_ress(number_levels, 0.0); + double wire_length = site_pitch / 2.0; + for(unsigned int i = 0; i < number_levels; ++i) + { + wire_caps[i] = wire_cap_per_len * wire_length; + wire_ress[i] = wire_res_per_len * wire_length; + wire_length /= 2.0; + } + + // Start sizing each stage of repeaters for a transition times. TODO: Find a heuristic about + // how the transition time is done...place and route tools make this user-specified + double required_transition = 40e-12; + m_number_segments_.resize(number_levels, 1); + for(unsigned int i = 0; i < number_levels; ++i) + { + Log::printLine(getInstanceName() + " -> Beginning Repeater Insertion " + (String)i); + + double transition; + unsigned int iteration = 0; + m_repeaters_[i]->setMinDrivingStrength(); + m_repeaters_[i]->getNet("Y")->setDistributedCap(wire_caps[i] / m_number_segments_[i]); + m_repeaters_[i]->getNet("Y")->setDistributedRes(wire_ress[i] / m_number_segments_[i]); + m_repeater_loads_[i]->setLoadCap(m_repeaters_[i]->getNet("A")->getTotalDownstreamCap()); + + transition = m_timing_trees_[i]->calculateNodeTransition(m_repeaters_[i]->getNet("Y")); + + while(required_transition < transition) + { + Log::printLine(getInstanceName() + " -> Repeater Insertion Iteration " + (String)iteration + + ": Required transition = " + (String)required_transition + + ", Transition = " + (String)transition + + ", Slack = " + (String)(required_transition - transition) + + ", Number of repeaters = " + (String)m_number_segments_[i]); + + // Size up if transition is not met + while(required_transition < transition) + { + if(m_repeaters_[i]->hasMaxDrivingStrength()) + { + break; + } + m_repeaters_[i]->increaseDrivingStrength(); + m_repeater_loads_[i]->setLoadCap(m_repeaters_[i]->getNet("A")->getTotalDownstreamCap()); + transition = m_timing_trees_[i]->calculateNodeTransition(m_repeaters_[i]->getNet("Y")); + + iteration++; + Log::printLine(getInstanceName() + " -> Slack: " + (String)(required_transition - transition)); + } + // Increase number of segments if thansition is not met + if(required_transition < transition) + { + m_number_segments_[i]++; + m_repeaters_[i]->setMinDrivingStrength(); + m_repeaters_[i]->getNet("Y")->setDistributedCap(wire_caps[i] / m_number_segments_[i]); + m_repeaters_[i]->getNet("Y")->setDistributedRes(wire_ress[i] / m_number_segments_[i]); + m_repeater_loads_[i]->setLoadCap(m_repeaters_[i]->getNet("A")->getTotalDownstreamCap()); + transition = m_timing_trees_[i]->calculateNodeTransition(m_repeaters_[i]->getNet("Y")); + } + } + Log::printLine(getInstanceName() + " -> Repeater Insertion " + (String)i + " Ended after Iteration: " + (String)iteration + + ": Required transition = " + (String)required_transition + + ", Transition = " + (String)transition + + ", Slack = " + (String)(required_transition - transition) + + ", Number of repeaters = " + (String)m_number_segments_[i]); + } + + // Insert inverters to ensure the transition time at the leaf + int min_driving_strength_idx = m_repeaters_[number_levels-1]->getDrivingStrengthIdx(); + + // Remove everything and rebuild again + clearPtrVector(&m_leaf_drivers_); + delete m_leaf_load_; + delete m_leaf_head_driver_; + delete m_leaf_head_load_; + + m_leaf_head_driver_ = getTechModel()->getStdCellLib()->createStdCell("INV", "LeafHeadDriver"); + m_leaf_head_driver_->construct(); + m_leaf_head_driver_->setDrivingStrengthIdx(min_driving_strength_idx); + + m_leaf_head_load_ = new ElectricalLoad("LeafHead_Cap", this); + m_leaf_head_driver_->getNet("Y")->addDownstreamNode(m_leaf_head_load_); + + m_leaf_load_ = new ElectricalLoad("Leaf_Cap", this); + m_leaf_load_->setLoadCap(leaf_load_cap); + + StdCell* inv = getTechModel()->getStdCellLib()->createStdCell("INV", "LeafDriver0"); + inv->construct(); + inv->getNet("Y")->addDownstreamNode(m_leaf_load_); + inv->setDrivingStrengthIdx(min_driving_strength_idx); + m_leaf_drivers_.push_back(inv); + + m_leaf_head_load_->setLoadCap(m_leaf_drivers_[0]->getNet("A")->getTotalDownstreamCap()); + + // Start inserting the buffers + ElectricalTimingTree t2("LeafHead", m_leaf_head_driver_); + int curr_driver = 0; + unsigned int iteration = 0; + while(true) + { + ElectricalTimingTree t("LeafDriver", m_leaf_drivers_[curr_driver]); + double transition = t.calculateNodeTransition(m_leaf_drivers_[curr_driver]->getNet("Y")); + Log::printLine(getInstanceName() + " -> Buffer Insertion : " + (String)iteration + + ": Required transition = " + (String)required_transition + + ", Transition = " + (String)transition + + ", Slack = " + (String)(required_transition - transition) + + ", Number of buffers = " + (String)(curr_driver+1)); + + // Size up the inverter at curr_driver so that it could drive the next stage + while(required_transition < transition) + { + if(m_leaf_drivers_[curr_driver]->hasMaxDrivingStrength()) + { + const String& warning_msg = "[Warning] " + getInstanceName() + " -> Transition not met" + + ": Required transition = " + (String)required_transition + + ", Transition = " + (String)transition + + ", Slack = " + (String)(required_transition - transition); + Log::printLine(std::cerr, warning_msg); + break; + } + m_leaf_drivers_[curr_driver]->increaseDrivingStrength(); + transition = t.calculateNodeTransition(m_leaf_drivers_[curr_driver]->getNet("Y")); + iteration++; + } + // Add an additional inverter if the transition for the first stage does not meet the required transition + m_leaf_head_load_->setLoadCap(m_leaf_drivers_[curr_driver]->getNet("A")->getTotalDownstreamCap()); + transition = t2.calculateNodeTransition(m_leaf_head_driver_->getNet("Y")); + if(required_transition < transition) + { + inv = getTechModel()->getStdCellLib()->createStdCell("INV", "LeafDriver" + (String)(curr_driver+1)); + inv->construct(); + inv->getNet("Y")->addDownstreamNode(m_leaf_drivers_[curr_driver]->getNet("A")); + inv->setDrivingStrengthIdx(min_driving_strength_idx); + m_leaf_drivers_.push_back(inv); + curr_driver++; + } + else + { + Log::printLine(getInstanceName() + " -> Buffer Insertion Ended after Iteration: " + (String)iteration + + ", Number of buffers = " + (String)(curr_driver+1)); + break; + } + } + + + // Update electrical interfaces + getLoad("In_Cap")->setLoadCap(m_repeaters_[0]->getNet("A")->getTotalDownstreamCap()); + // TODO + getDelay("In_to_Out_delay")->setDelay(0.0); + + // Reset all the atomic results to 0 before start updating new results + resetElectricalAtomicResults(); + + // Update area, power results + double wire_area = 0.0; + wire_length = site_pitch / 2.0; + unsigned int number_branches = 1; + for(unsigned int i = 0; i < number_levels; ++i) + { + wire_area += wire_length * (wire_width + wire_spacing) * number_branches * number_bits; + addElecticalAtomicResultValues(m_repeaters_[i], m_number_segments_[i] * number_branches * number_bits); + wire_length /= 2.0; + number_branches *= 2; + } + number_branches = (unsigned int)pow(2.0, (double)number_levels-1); + addElecticalAtomicResultValues(m_leaf_head_driver_, number_branches * number_bits); + for(unsigned int i = 0; i < m_leaf_drivers_.size(); ++i) + { + addElecticalAtomicResultValues(m_leaf_drivers_[i], number_branches * number_bits); + } + addElecticalWireAtomicResultValue(wire_layer, wire_area); + + return; + } + + void BroadcastHTree::useModel() + { + unsigned int number_bits = getParameter("NumberBits").toUInt(); + unsigned int number_levels = getParameter("NumberLevels").toUInt(); + + // Update the transition information for the modeled repeaters + // Since we only modeled one repeater. So the transition information for 0->0 and 1->1 + // is averaged out + const TransitionInfo& trans_In = getInputPort("In")->getTransitionInfo(); + double average_static_transition = (trans_In.getNumberTransitions00() + trans_In.getNumberTransitions11()) / 2.0; + TransitionInfo mod_trans_In(average_static_transition, trans_In.getNumberTransitions01(), average_static_transition); + + // Propagate the transition information + propagateTransitionInfo(); + + // Update leakage and event + double energy = 0.0; + double power = 0.0; + unsigned int number_branches = 1; + for(unsigned int i = 0; i < number_levels; ++i) + { + assignPortTransitionInfo(m_repeaters_[i], "A", mod_trans_In); + m_repeaters_[i]->use(); + power += m_repeaters_[i]->getNddPowerResult("Leakage")->calculateSum() * m_number_segments_[i] * number_branches; + energy += m_repeaters_[i]->getEventResult("INV")->calculateSum() * m_number_segments_[i] * number_branches; + number_branches *= 2; + } + energy *= number_bits; + getEventResult("DriveTree")->setValue(energy); + + energy = 0.0; + assignPortTransitionInfo(m_leaf_head_driver_, "A", mod_trans_In); + m_leaf_head_driver_->use(); + number_branches = (unsigned int)pow(2.0, (double)number_levels-1); + power += m_leaf_head_driver_->getNddPowerResult("Leakage")->calculateSum() * number_branches; + energy += m_leaf_head_driver_->getEventResult("INV")->calculateSum() * number_branches; + for(unsigned int i = 0; i < m_leaf_drivers_.size(); ++i) + { + assignPortTransitionInfo(m_leaf_drivers_[i], "A", mod_trans_In); + m_leaf_drivers_[i]->use(); + power += m_leaf_drivers_[i]->getNddPowerResult("Leakage")->calculateSum() * number_branches; + energy += m_leaf_drivers_[i]->getEventResult("INV")->calculateSum() * number_branches; + } + power *= number_bits; + energy *= number_bits; + getEventResult("DriveLoad")->setValue(energy); + getNddPowerResult("Leakage")->setValue(power); + + return; + } + + void BroadcastHTree::propagateTransitionInfo() + { + propagatePortTransitionInfo("Out", "In"); + return; + } +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/DFFRAM.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/DFFRAM.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_ELECTRICAL_DFFRAM_H__ +#define __DSENT_MODEL_ELECTRICAL_DFFRAM_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" + +namespace DSENT +{ + class DFFRAM : public ElectricalModel + { + public: + DFFRAM(const String& instance_name_, const TechModel* tech_model_); + virtual ~DFFRAM(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + + // Clone and return a new instance + virtual DFFRAM* clone() const; + + protected: + // Build the model + virtual void constructModel(); + virtual void propagateTransitionInfo(); + + }; // class DFFRAM +} // namespace DSENT + +#endif // __DSENT_MODEL_ELECTRICAL_BUFFER_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/DFFRAM.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/DFFRAM.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,352 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/electrical/DFFRAM.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriverMultiplier.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" +#include "mem/ruby/network/dsent/dsent-core/model/electrical/Decoder.hh" +#include "mem/ruby/network/dsent/dsent-core/model/electrical/Multiplexer.hh" + +namespace DSENT +{ + using std::ceil; + + DFFRAM::DFFRAM(const String& instance_name_, const TechModel* tech_model_) + : ElectricalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + DFFRAM::~DFFRAM() + {} + + void DFFRAM::initParameters() + { + addParameterName("NumberEntries"); + addParameterName("NumberBits"); + return; + } + + void DFFRAM::initProperties() + { + return; + } + + DFFRAM* DFFRAM::clone() const + { + // TODO + return NULL; + } + + void DFFRAM::constructModel() + { + // Get parameters + unsigned int number_bits = getParameter("NumberBits").toUInt(); + unsigned int number_entries = getParameter("NumberEntries").toUInt(); + + ASSERT(number_bits > 0, "[Error] " + getInstanceName() + + " -> Number of bits must be > 0!"); + ASSERT(number_entries > 0, "[Error] " + getInstanceName() + + " -> Number of entries must be > 0!"); + + unsigned int number_addr_bits = (unsigned int)ceil(log2(number_entries)); + + // Create ports + createInputPort("In", makeNetIndex(0, number_bits-1)); + for(unsigned int i = 0; i < number_addr_bits; ++i) + { + createInputPort("WRAddr" + (String)i); + createInputPort("RDAddr" + (String)i); + } + createInputPort("WE"); + createInputPort("CK"); + createOutputPort("Out", makeNetIndex(0, number_bits-1)); + + // Create energy, power, and area results + createElectricalResults(); + getEventInfo("Idle")->setStaticTransitionInfos(); + getEventInfo("Idle")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); + getEventInfo("Idle")->setTransitionInfo("WE", TransitionInfo(1.0, 0.0, 0.0)); + + createElectricalEventResult("Read"); + getEventInfo("Read")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); + getEventInfo("Read")->setTransitionInfo("WE", TransitionInfo(1.0, 0.0, 0.0)); + for(unsigned int i = 0; i < number_addr_bits; ++i) + { + getEventInfo("Read")->setTransitionInfo("WRAddr" + (String)i, TransitionInfo(0.5, 0.0, 0.5)); + } + createElectricalEventResult("Write"); + getEventInfo("Write")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); + getEventInfo("Write")->setTransitionInfo("WE", TransitionInfo(0.0, 0.0, 1.0)); + for(unsigned int i = 0; i < number_addr_bits; ++i) + { + getEventInfo("Write")->setTransitionInfo("RDAddr" + (String)i, TransitionInfo(0.5, 0.0, 0.5)); + } + + // Init components - DFF array, Dec, Mux + vector dff_names(number_entries, ""); + vector dffs(number_entries, NULL); + for(unsigned int i = 0; i < number_entries; ++i) + { + dff_names[i] = "DFF_" + (String)i; + dffs[i] = getTechModel()->getStdCellLib()->createStdCell("DFFQ", dff_names[i]); + dffs[i]->construct(); + } + + const String& dec_name = "Dec"; + Decoder* dec = new Decoder(dec_name, getTechModel()); + dec->setParameter("NumberOutputs", number_entries); + dec->construct(); + + const String& mux_name = "Mux"; + Multiplexer* mux = new Multiplexer(mux_name, getTechModel()); + mux->setParameter("NumberInputs", number_entries); + mux->setParameter("NumberBits", 1); + mux->setParameter("BitDuplicate", "TRUE"); + mux->construct(); + + // Init components - CK & WE + const String& nand2cg0_name = "NAND2_CKGate0"; + StdCell* nand2cg0 = getTechModel()->getStdCellLib()->createStdCell("NAND2", nand2cg0_name); + nand2cg0->construct(); + const String& invcg0_name = "INV_CKGate0"; + StdCell* invcg0 = getTechModel()->getStdCellLib()->createStdCell("INV", invcg0_name); + invcg0->construct(); + + // Init components - (CK & WE) & DecOut[i] + vector nand2cg1_names(number_entries, ""); + vector nand2cg1s(number_entries, NULL); + vector invcg1_names(number_entries, ""); + vector invcg1s(number_entries, NULL); + for(unsigned int i = 0; i < number_entries; ++i) + { + nand2cg1_names[i] = "NAND2_CKGate1_" + (String)i; + nand2cg1s[i] = getTechModel()->getStdCellLib()->createStdCell("NAND2", nand2cg1_names[i]); + nand2cg1s[i]->construct(); + + invcg1_names[i] = "INV_CKGate1_" + (String)i; + invcg1s[i] = getTechModel()->getStdCellLib()->createStdCell("INV", invcg1_names[i]); + invcg1s[i]->construct(); + } + + // Connect Decoder + for(unsigned int i = 0; i < number_addr_bits; ++i) + { + portConnect(dec, "Addr" + (String)i, "WRAddr" + (String)i); + } + for(unsigned int i = 0; i < number_entries; ++i) + { + createNet("Dec_Out" + (String)i); + portConnect(dec, "Out" + (String)i, "Dec_Out" + (String)i); + } + + // Connect CKGate0 - CK, WE + createNet("NAND2_CKGate0_Out"); + createNet("CKGate0_Out"); + portConnect(nand2cg0, "A", "CK"); + portConnect(nand2cg0, "B", "WE"); + portConnect(nand2cg0, "Y", "NAND2_CKGate0_Out"); + portConnect(invcg0, "A", "NAND2_CKGate0_Out"); + portConnect(invcg0, "Y", "CKGate0_Out"); + + // Connect CKGate1 - CKGate0, Dec_Out + for(unsigned int i = 0; i < number_entries; ++i) + { + createNet("NAND2_CKGate1_Outs" + (String)i); + createNet("CKGate1_Outs" + (String)i); + portConnect(nand2cg1s[i], "A", "CKGate0_Out"); + portConnect(nand2cg1s[i], "B", "Dec_Out" + (String)i); + portConnect(nand2cg1s[i], "Y", "NAND2_CKGate1_Outs" + (String)i); + portConnect(invcg1s[i], "A", "NAND2_CKGate1_Outs" + (String)i); + portConnect(invcg1s[i], "Y", "CKGate1_Outs" + (String)i); + } + + // Connect DFF array + for(unsigned int i = 0; i < number_entries; ++i) + { + createNet("DFF_Out" + (String)i); + for(unsigned int n = 0; n < number_bits; ++n) + { + portConnect(dffs[i], "D", "In", makeNetIndex(n)); + portConnect(dffs[i], "CK", "CKGate1_Outs" + (String)i); + } + portConnect(dffs[i], "Q", "DFF_Out" + (String)i); + } + + // Connect Multiplexer + createNet("Mux_Out"); + for(unsigned int i = 0; i < number_entries; ++i) + { + portConnect(mux, "In" + (String)i, "DFF_Out" + (String)i); + } + for(unsigned int i = 0; i < number_addr_bits; ++i) + { + portConnect(mux, "Sel" + (String)i, "RDAddr" + (String)i); + } + portConnect(mux, "Out", "Mux_Out"); + + // Use driver multiplier to connect Mux_Out to Out + createDriverMultiplier("OutMult"); + ElectricalDriverMultiplier* drive_mult = getDriverMultiplier("OutMult"); + getNet("Mux_Out")->addDownstreamNode(drive_mult); + for(unsigned int n = 0; n < number_bits; ++n) + { + drive_mult->addDownstreamNode(getNet("Out", makeNetIndex(n))); + } + + // Add area and power results + for(unsigned int i = 0; i < number_entries; ++i) + { + addSubInstances(dffs[i], number_bits); + addElectricalSubResults(dffs[i], number_bits); + } + + addSubInstances(dec, 1.0); + addElectricalSubResults(dec, 1.0); + + addSubInstances(mux, number_bits); + addElectricalSubResults(mux, number_bits); + + addSubInstances(nand2cg0, 1.0); + addElectricalSubResults(nand2cg0, 1.0); + + addSubInstances(invcg0, 1); + addElectricalSubResults(invcg0, 1.0); + + for(unsigned int i = 0; i < number_entries; ++i) + { + addSubInstances(nand2cg1s[i], 1); + addElectricalSubResults(nand2cg1s[i], 1.0); + + addSubInstances(invcg1s[i], 1); + addElectricalSubResults(invcg1s[i], 1.0); + } + + // Add write event + Result* write_event = getEventResult("Write"); + write_event->addSubResult(nand2cg0->getEventResult("NAND2"), nand2cg0_name, 1.0); + write_event->addSubResult(invcg0->getEventResult("INV"), invcg0_name, 1.0); + write_event->addSubResult(dec->getEventResult("Decode"), dec_name, 1.0); + for(unsigned int i = 0; i < number_entries; ++i) + { + write_event->addSubResult(nand2cg1s[i]->getEventResult("NAND2"), nand2cg1_names[i], 1.0); + write_event->addSubResult(invcg1s[i]->getEventResult("INV"), invcg1_names[i], 1.0); + write_event->addSubResult(dffs[i]->getEventResult("DFFD"), dff_names[i], number_bits); + write_event->addSubResult(dffs[i]->getEventResult("DFFQ"), dff_names[i], number_bits); + write_event->addSubResult(dffs[i]->getEventResult("CK"), dff_names[i], number_bits); + } + + // Add read event + Result* read_event = getEventResult("Read"); + //for(unsigned int i = 0; i < number_entries; ++i) + //{ + // read_event->addSubResult(dffs[i]->getEventResult("DFFQ"), dff_names[i], number_bits); + //} + read_event->addSubResult(mux->getEventResult("Mux"), mux_name, number_bits); + + return; + } + + void DFFRAM::propagateTransitionInfo() + { + // Update probability + unsigned int number_entries = (unsigned int)getParameter("NumberEntries"); + unsigned int number_addr_bits = (unsigned int)ceil(log2(number_entries)); + + // Update decoder + ElectricalModel* dec = (ElectricalModel*)getSubInstance("Dec"); + for(unsigned int i = 0; i < number_addr_bits; ++i) + { + propagatePortTransitionInfo(dec, "Addr" + (String)i, "WRAddr" + (String)i); + } + dec->use(); + + // Update CKGate0 nands + invs + ElectricalModel* nand2cg0 = (ElectricalModel*)getSubInstance("NAND2_CKGate0"); + propagatePortTransitionInfo(nand2cg0, "A", "CK"); + propagatePortTransitionInfo(nand2cg0, "B", "WE"); + nand2cg0->use(); + ElectricalModel* invcg0 = (ElectricalModel*)getSubInstance("INV_CKGate0"); + propagatePortTransitionInfo(invcg0, "A", nand2cg0, "Y"); + invcg0->use(); + + // Update CKGate1 nands + invs + vector nand2cg1s(number_entries, NULL); + vector invcg1s(number_entries, NULL); + for(unsigned int i = 0; i < number_entries; ++i) + { + nand2cg1s[i] = (ElectricalModel*)getSubInstance("NAND2_CKGate1_" + (String)i); + propagatePortTransitionInfo(nand2cg1s[i], "A", invcg0, "Y"); + propagatePortTransitionInfo(nand2cg1s[i], "B", dec, "Out" + (String)i); + nand2cg1s[i]->use(); + + invcg1s[i] = (ElectricalModel*)getSubInstance("INV_CKGate1_" + (String)i); + propagatePortTransitionInfo(invcg1s[i], "A", nand2cg1s[i], "Y"); + invcg1s[i]->use(); + } + + // Update DFF + vector dffs(number_entries, NULL); + for(unsigned int i = 0; i < number_entries; ++i) + { + dffs[i] = (ElectricalModel*)getSubInstance("DFF_" + (String)i); + propagatePortTransitionInfo(dffs[i], "D", "In"); + propagatePortTransitionInfo(dffs[i], "CK", invcg1s[i], "Y"); + dffs[i]->use(); + } + + // Update Mux + ElectricalModel* mux = (ElectricalModel*)getSubInstance("Mux"); + for(unsigned int i = 0; i < number_entries; ++i) + { + propagatePortTransitionInfo(mux, "In" + (String)i, dffs[i], "Q"); + } + for(unsigned int i = 0; i < number_addr_bits; ++i) + { + propagatePortTransitionInfo(mux, "Sel" + (String)i, "RDAddr" + (String)i); + } + mux->use(); + + // Set output probability + getOutputPort("Out")->setTransitionInfo(mux->getOutputPort("Out")->getTransitionInfo()); + return; + } +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/Decoder.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/Decoder.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_ELECTRICAL_DECODER_H__ +#define __DSENT_MODEL_ELECTRICAL_DECODER_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" + +namespace DSENT +{ + class Decoder : public ElectricalModel + { + public: + Decoder(const String& instance_name_, const TechModel* tech_model_); + virtual ~Decoder(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + + // Clone and return a new instance + virtual Decoder* clone() const; + + protected: + // Build the model + virtual void constructModel(); + virtual void propagateTransitionInfo(); + + }; // class Decoder +} // namespace DSENT + +#endif // __DSENT_MODEL_ELECTRICAL_DECODER_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/Decoder.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/Decoder.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/electrical/Decoder.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" + +namespace DSENT +{ + using std::ceil; + + Decoder::Decoder(const String& instance_name_, const TechModel* tech_model_) + : ElectricalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + Decoder::~Decoder() + {} + + void Decoder::initParameters() + { + addParameterName("NumberOutputs"); + } + + void Decoder::initProperties() + { + return; + } + + Decoder* Decoder::clone() const + { + // TODO + return NULL; + } + + void Decoder::constructModel() + { + // Get parameters + unsigned int number_outputs = getParameter("NumberOutputs").toUInt(); + + ASSERT(number_outputs > 0, "[Error] " + getInstanceName() + " -> Number of outputs must be > 0!"); + + unsigned int number_addr_bits = (unsigned int)ceil(log2(number_outputs)); + + // Create ports + for(unsigned int i = 0; i < number_addr_bits; ++i) + { + createInputPort("Addr" + (String)i); + } + for(unsigned int i = 0; i < number_outputs; ++i) + { + createOutputPort("Out" + (String)i); + } + + // Create energy, power, and area results + createElectricalResults(); + createElectricalEventResult("Decode"); + Result* decode_event = getEventResult("Decode"); + + getEventInfo("Idle")->setStaticTransitionInfos(); + + if(number_addr_bits == 0) + { + // Do not need a decoder + } + else if(number_addr_bits == 1) + { + const String& inv0_name = "Inv0"; + + StdCell* inv0 = getTechModel()->getStdCellLib()->createStdCell("INV", inv0_name); + inv0->construct(); + + // Connect inputs and outputs + portConnect(inv0, "A", "Addr0"); + portConnect(inv0, "Y", "Out0"); + assign("Out1", "Addr0"); + + // Add area, power, and event results + addSubInstances(inv0, 1.0); + addElectricalSubResults(inv0, 1.0); + decode_event->addSubResult(inv0->getEventResult("INV"), inv0_name, 1.0); + } + else + { + unsigned int number_addr_bits_0 = (unsigned int)ceil((double)number_addr_bits / 2.0); + unsigned int number_addr_bits_1 = (unsigned int)floor((double)number_addr_bits / 2.0); + + unsigned int number_outputs_0 = (unsigned int)pow(2.0, number_addr_bits_0); + unsigned int number_outputs_1 = (unsigned int)ceil((double)number_outputs / (double)number_outputs_0); + + const String& dec0_name = "Dec_way0"; + const String& dec1_name = "Dec_way1"; + vector nand2_names(number_outputs, ""); + vector inv_names(number_outputs, ""); + for(unsigned int i = 0; i < number_outputs; ++i) + { + nand2_names[i] = "NAND2_" + (String)i; + inv_names[i] = "INV_" + (String)i; + } + + Decoder* dec0 = new Decoder(dec0_name, getTechModel()); + dec0->setParameter("NumberOutputs", number_outputs_0); + dec0->construct(); + + Decoder* dec1 = new Decoder(dec1_name, getTechModel()); + dec1->setParameter("NumberOutputs", number_outputs_1); + dec1->construct(); + + vector nand2s(number_outputs, NULL); + vector invs(number_outputs, NULL); + for(unsigned int i = 0; i < number_outputs; ++i) + { + nand2s[i] = getTechModel()->getStdCellLib()->createStdCell("NAND2", nand2_names[i]); + nand2s[i]->construct(); + invs[i] = getTechModel()->getStdCellLib()->createStdCell("INV", inv_names[i]); + invs[i]->construct(); + } + + // Connect inputs and outputs + for(unsigned int i = 0; i < number_addr_bits_0; ++i) + { + portConnect(dec0, "Addr" + (String)i, "Addr" + (String)i); + } + for(unsigned int i = 0; i < number_addr_bits_1; ++i) + { + portConnect(dec1, "Addr" + (String)i, "Addr" + (String)(i + number_addr_bits_0)); + } + for(unsigned int i = 0; i < number_outputs_0; ++i) + { + createNet("way0Out" + (String)i); + portConnect(dec0, "Out" + (String)i, "way0Out" + (String)i); + } + for(unsigned int i = 0; i < number_outputs_1; ++i) + { + createNet("way1Out" + (String)i); + portConnect(dec1, "Out" + (String)i, "way1Out" + (String)i); + } + + for(unsigned int i = 0; i < number_outputs; ++i) + { + createNet("nand" + (String)i + "Out"); + portConnect(nand2s[i], "A", "way0Out" + (String)(i%number_outputs_0)); + portConnect(nand2s[i], "B", "way1Out" + (String)((unsigned int)floor(i/number_outputs_0))); + portConnect(nand2s[i], "Y", "nand" + (String)i + "Out"); + portConnect(invs[i], "A", "nand" + (String)i + "Out"); + portConnect(invs[i], "Y", "Out" + (String)i); + } + + // Add area, power, and event results + addSubInstances(dec0, 1.0); + addElectricalSubResults(dec0, 1.0); + decode_event->addSubResult(dec0->getEventResult("Decode"), dec0_name, 1.0); + addSubInstances(dec1, 1.0); + addElectricalSubResults(dec1, 1.0); + decode_event->addSubResult(dec1->getEventResult("Decode"), dec1_name, 1.0); + for(unsigned int i = 0; i < number_outputs; ++i) + { + addSubInstances(nand2s[i], 1.0); + addElectricalSubResults(nand2s[i], 1.0); + decode_event->addSubResult(nand2s[i]->getEventResult("NAND2"), nand2_names[i], 1.0); + + addSubInstances(invs[i], 1.0); + addElectricalSubResults(invs[i], 1.0); + decode_event->addSubResult(invs[i]->getEventResult("INV"), inv_names[i], 1.0); + } + } + return; + } + + void Decoder::propagateTransitionInfo() + { + // The only thing can be updated are the input probabilities + unsigned int number_outputs = getParameter("NumberOutputs").toUInt(); + + unsigned int number_addr_bits = (unsigned int)ceil(log2(number_outputs)); + + if(number_addr_bits == 0) + { + // Do not need a decoder + } + else if(number_addr_bits == 1) + { + ElectricalModel* inv0 = (ElectricalModel*)getSubInstance("Inv0"); + propagatePortTransitionInfo(inv0, "A", "Addr0"); + inv0->use(); + + // Since # addr bits is 1, the output 0 is directly connected + propagatePortTransitionInfo("Out0", inv0, "Y"); + propagatePortTransitionInfo("Out1", "Addr0"); + } + else + { + unsigned int number_addr_bits_0 = (unsigned int)ceil((double)number_addr_bits / 2.0); + unsigned int number_addr_bits_1 = (unsigned int)floor((double)number_addr_bits / 2.0); + + unsigned int number_outputs_0 = (unsigned int)pow(2.0, number_addr_bits_0); + + // Update decoders with probabilities + ElectricalModel* dec0 = (ElectricalModel*)getSubInstance("Dec_way0"); + for(unsigned int i = 0; i < number_addr_bits_0; ++i) + { + propagatePortTransitionInfo(dec0, "Addr" + (String)i, "Addr" + (String)i); + } + dec0->use(); + ElectricalModel* dec1 = (ElectricalModel*)getSubInstance("Dec_way1"); + for(unsigned int i = 0; i < number_addr_bits_1; ++i) + { + propagatePortTransitionInfo(dec1, "Addr" + (String)i, "Addr" + (String)(i + number_addr_bits_0)); + } + dec1->use(); + + for(unsigned int i = 0; i < number_outputs; ++i) + { + ElectricalModel* nand2 = (ElectricalModel*)getSubInstance("NAND2_" + (String)i); + propagatePortTransitionInfo(nand2, "A", dec0, "Out" + (String)(i%number_outputs_0)); + propagatePortTransitionInfo(nand2, "B", dec1, "Out" + (String)((unsigned int)floor(i/number_outputs_0))); + nand2->use(); + + ElectricalModel* inv = (ElectricalModel*)getSubInstance("INV_" + (String)i); + propagatePortTransitionInfo(inv, "A", nand2, "Y"); + inv->use(); + + propagatePortTransitionInfo("Out" + (String)i, inv, "Y"); + } + } + return; + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/DemuxTreeDeserializer.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/DemuxTreeDeserializer.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_ELECTRICAL_MULTIPHASEDESERIALIZER_H__ +#define __DSENT_MODEL_ELECTRICAL_MULTIPHASEDESERIALIZER_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" + +namespace DSENT +{ + class DemuxTreeDeserializer : public ElectricalModel + { + public: + DemuxTreeDeserializer(const String& instance_name_, const TechModel* tech_model_); + virtual ~DemuxTreeDeserializer(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + + // Clone and return a new instance + virtual DemuxTreeDeserializer* clone() const; + + protected: + // Build the model + virtual void constructModel(); + virtual void propagateTransitionInfo(); + + }; // class DemuxTreeDeserializer +} // namespace DSENT + +#endif // __DSENT_MODEL_ELECTRICAL_MULTIPHASEDESERIALIZER_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/DemuxTreeDeserializer.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/DemuxTreeDeserializer.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,409 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/electrical/DemuxTreeDeserializer.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" +#include "mem/ruby/network/dsent/dsent-core/model/electrical/Multiplexer.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" + +namespace DSENT +{ + using std::ceil; + + DemuxTreeDeserializer::DemuxTreeDeserializer(const String& instance_name_, const TechModel* tech_model_) + : ElectricalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + DemuxTreeDeserializer::~DemuxTreeDeserializer() + {} + + void DemuxTreeDeserializer::initParameters() + { + addParameterName("InDataRate"); + addParameterName("OutDataRate"); + addParameterName("OutBits"); //Output width will just be output width / serialization ratio + addParameterName("BitDuplicate", "TRUE"); + return; + } + + void DemuxTreeDeserializer::initProperties() + { + return; + } + + DemuxTreeDeserializer* DemuxTreeDeserializer::clone() const + { + // TODO + return NULL; + } + + void DemuxTreeDeserializer::constructModel() + { + + // Get parameters + double in_data_rate = getParameter("InDataRate"); + double out_data_rate = getParameter("OutDataRate"); + unsigned int out_bits = getParameter("OutBits"); + bool bit_duplicate = getParameter("BitDuplicate"); + + // Calculate deserialization ratio + unsigned int deserialization_ratio = (unsigned int) floor(in_data_rate / out_data_rate); + ASSERT(deserialization_ratio == in_data_rate / out_data_rate, + "[Error] " + getInstanceName() + " -> Cannot have non-integer deserialization ratios!"); + ASSERT((deserialization_ratio & (deserialization_ratio - 1)) == 0, + "[Error] " + getInstanceName() + " -> Deserialization ratio must be a power of 2"); + + // Calculate output width + unsigned int input_bits = out_bits / deserialization_ratio; + ASSERT(out_bits >= deserialization_ratio, "[Error] " + getInstanceName() + + " -> Output width must be >= deserialization ratio!"); + ASSERT(floor((double) out_bits / deserialization_ratio) == input_bits, + "[Error] " + getInstanceName() + " -> Output width must be a multiple of the serialization ratio!"); + + // Store calculated numbers + getGenProperties()->set("DeserializationRatio", deserialization_ratio); + getGenProperties()->set("InputBits", input_bits); + + // Create ports + createInputPort("In", makeNetIndex(0, input_bits-1)); + createInputPort("InCK"); + createOutputPort("Out", makeNetIndex(0, out_bits-1)); + + //Create energy, power, and area results + createElectricalResults(); + createElectricalEventResult("Deserialize"); + getEventInfo("Deserialize")->setTransitionInfo("InCK", TransitionInfo(0.0, (double) deserialization_ratio / 2.0, 0.0)); + // Set conditions during idle state + getEventInfo("Idle")->setStaticTransitionInfos(); + getEventInfo("Idle")->setTransitionInfo("InCK", TransitionInfo(0.0, (double) deserialization_ratio / 2.0, 0.0)); + + // Mark InCK as a false path (since timing tool will do strange stuff due to all the clock divides and stuff) + getNet("InCK")->setFalsePath(true); + + // Create deserializer + if (deserialization_ratio == 1) + { + // No need to do anything, hohoho + assign("Out", "In"); + } + else if (input_bits == 1) + { + //----------------------------------------------------------------- + // Create 2:1 demux deserializer + //----------------------------------------------------------------- + const String& des_dff_way0_name = "DesDFFWay0"; + const String& des_dff_way1_name = "DesDFFWay1"; + const String& des_latch_name = "DesLatch"; + const String& ck_dff_name = "CKDFF"; + const String& ck_inv_name = "CKINV"; + const String& out_way0_name = "OutWay0"; + const String& out_way1_name = "OutWay1"; + const String& mid_way0_name = "MidWay0"; + const String& ck_div2_name = "CK_div2"; + const String& ck_div2_b_name = "CK_div2_b"; + + // Create nets + createNet(out_way0_name); + createNet(out_way1_name); + createNet(mid_way0_name); + createNet(ck_div2_name); + createNet(ck_div2_b_name); + + // Create the dffs and latch needed on both ways + StdCell* des_dff_way0 = getTechModel()->getStdCellLib()->createStdCell("DFFQ", des_dff_way0_name); + des_dff_way0->construct(); + StdCell* des_dff_way1 = getTechModel()->getStdCellLib()->createStdCell("DFFQ", des_dff_way1_name); + des_dff_way1->construct(); + StdCell* des_latch = getTechModel()->getStdCellLib()->createStdCell("LATQ", des_latch_name); + des_latch->construct(); + + // Create clk divide circuit + StdCell* ck_dff = getTechModel()->getStdCellLib()->createStdCell("DFFQ", ck_dff_name); + ck_dff->construct(); + StdCell* ck_inv = getTechModel()->getStdCellLib()->createStdCell("INV", ck_inv_name); + ck_inv->construct(); + + // Connect ports + portConnect(des_dff_way0, "CK", "InCK"); + portConnect(des_dff_way0, "D", mid_way0_name); + portConnect(des_dff_way0, "Q", out_way0_name); + portConnect(des_latch, "G", "InCK"); + portConnect(des_latch, "D", "In"); + portConnect(des_latch, "Q", mid_way0_name); + portConnect(des_dff_way1, "CK", "InCK"); + portConnect(des_dff_way1, "D", "In"); + portConnect(des_dff_way1, "Q", out_way1_name); + portConnect(ck_dff, "CK", "InCK"); + portConnect(ck_dff, "D", ck_div2_b_name); + portConnect(ck_dff, "Q", ck_div2_name); + portConnect(ck_inv, "A", ck_div2_name); + portConnect(ck_inv, "Y", ck_div2_b_name); + + // Add sub instances + addSubInstances(des_dff_way0, 1.0); + addElectricalSubResults(des_dff_way0, 1.0); + addSubInstances(des_dff_way1, 1.0); + addElectricalSubResults(des_dff_way1, 1.0); + addSubInstances(des_latch, 1.0); + addElectricalSubResults(des_latch, 1.0); + addSubInstances(ck_dff, 1.0); + addElectricalSubResults(ck_dff, 1.0); + addSubInstances(ck_inv, 1.0); + addElectricalSubResults(ck_inv, 1.0); + + Result* deserialize = getEventResult("Deserialize"); + deserialize->addSubResult(des_dff_way0->getEventResult("CK"), des_dff_way0_name, 1.0); + deserialize->addSubResult(des_dff_way0->getEventResult("DFFD"), des_dff_way0_name, 1.0); + deserialize->addSubResult(des_dff_way0->getEventResult("DFFQ"), des_dff_way0_name, 1.0); + deserialize->addSubResult(des_dff_way1->getEventResult("CK"), des_dff_way1_name, 1.0); + deserialize->addSubResult(des_dff_way1->getEventResult("DFFD"), des_dff_way1_name, 1.0); + deserialize->addSubResult(des_dff_way1->getEventResult("DFFQ"), des_dff_way1_name, 1.0); + deserialize->addSubResult(des_latch->getEventResult("G"), des_latch_name, 1.0); + deserialize->addSubResult(des_latch->getEventResult("LATD"), des_latch_name, 1.0); + deserialize->addSubResult(des_latch->getEventResult("LATQ"), des_latch_name, 1.0); + deserialize->addSubResult(ck_dff->getEventResult("CK"), ck_dff_name, 1.0); + deserialize->addSubResult(ck_dff->getEventResult("DFFD"), ck_dff_name, 1.0); + deserialize->addSubResult(ck_dff->getEventResult("DFFQ"), ck_dff_name, 1.0); + deserialize->addSubResult(ck_inv->getEventResult("INV"), ck_inv_name, 1.0); + //----------------------------------------------------------------- + + //----------------------------------------------------------------- + // Create Sub-deserializers + //----------------------------------------------------------------- + // Create sub-deserializers + const String& demux_way0_name = "DemuxTree_way0_" + (String) deserialization_ratio + "_to_1"; + const String& demux_way1_name = "DemuxTree_way1_" + (String) deserialization_ratio + "_to_1"; + + DemuxTreeDeserializer* demux_way0 = new DemuxTreeDeserializer(demux_way0_name, getTechModel()); + demux_way0->setParameter("InDataRate", in_data_rate / 2.0); + demux_way0->setParameter("OutDataRate", out_data_rate); + demux_way0->setParameter("OutBits", out_bits / 2); + demux_way0->setParameter("BitDuplicate", "TRUE"); + demux_way0->construct(); + + DemuxTreeDeserializer* demux_way1 = new DemuxTreeDeserializer(demux_way1_name, getTechModel()); + demux_way1->setParameter("InDataRate", in_data_rate / 2.0); + demux_way1->setParameter("OutDataRate", out_data_rate); + demux_way1->setParameter("OutBits", out_bits / 2); + demux_way1->setParameter("BitDuplicate", "TRUE"); + demux_way1->construct(); + + // Connect ports + portConnect(demux_way0, "In", out_way0_name); + portConnect(demux_way0, "InCK", ck_div2_name); + portConnect(demux_way0, "Out", "Out", makeNetIndex(0, out_bits/2-1)); + + portConnect(demux_way1, "In", out_way1_name); + portConnect(demux_way1, "InCK", ck_div2_name); + portConnect(demux_way1, "Out", "Out", makeNetIndex(out_bits/2, out_bits-1)); + + // Add subinstances and area results + addSubInstances(demux_way0, 1.0); + addElectricalSubResults(demux_way0, 1.0); + addSubInstances(demux_way1, 1.0); + addElectricalSubResults(demux_way1, 1.0); + + deserialize->addSubResult(demux_way0->getEventResult("Deserialize"), demux_way0_name, 1.0); + deserialize->addSubResult(demux_way1->getEventResult("Deserialize"), demux_way1_name, 1.0); + //----------------------------------------------------------------- + + } + else if (bit_duplicate) + { + const String& demux_name = "DemuxTree_" + (String) deserialization_ratio + "_to_1"; + + DemuxTreeDeserializer* des_bit = new DemuxTreeDeserializer(demux_name, getTechModel()); + des_bit->setParameter("InDataRate", in_data_rate); + des_bit->setParameter("OutDataRate", out_data_rate); + des_bit->setParameter("OutBits", deserialization_ratio); + des_bit->setParameter("BitDuplicate", "TRUE"); + des_bit->construct(); + + // Create VFI and VFO nets + createNet("InVFI"); + createNet("OutVFO", makeNetIndex(0, deserialization_ratio-1)); + + // Connect ports + portConnect(des_bit, "In", "InVFI"); + portConnect(des_bit, "Out", "OutVFO"); + + // Do VFI and VFO + assignVirtualFanin("InVFI", "In"); + for (unsigned int i = 0; i < input_bits; ++i) + { + portConnect(des_bit, "InCK", "InCK"); + for (unsigned int j = 0; j < deserialization_ratio; ++j) + assignVirtualFanout("Out", makeNetIndex(i*deserialization_ratio + j), "OutVFO", makeNetIndex(j)); + } + // Add subinstances and area results + addSubInstances(des_bit, input_bits); + addElectricalSubResults(des_bit, input_bits); + getEventResult("Deserialize")->addSubResult(des_bit->getEventResult("Deserialize"), demux_name, input_bits); + } + else + { + //Instantiate a bunch of 1 input bit deserializers + for (unsigned int i = 0; i < input_bits; ++i) + { + const String& demux_name = "DemuxTree_" + (String) deserialization_ratio + "_to_1_bit" + (String) i; + + DemuxTreeDeserializer* des_bit = new DemuxTreeDeserializer(demux_name, getTechModel()); + des_bit->setParameter("InDataRate", in_data_rate); + des_bit->setParameter("OutDataRate", out_data_rate); + des_bit->setParameter("OutBits", deserialization_ratio); + des_bit->setParameter("BitDuplicate", "TRUE"); + des_bit->construct(); + + portConnect(des_bit, "In", "In", makeNetIndex(i)); + portConnect(des_bit, "InCK", "InCK"); + portConnect(des_bit, "Out", "Out", makeNetIndex(i*deserialization_ratio, (i+1)*deserialization_ratio-1)); + + addSubInstances(des_bit, 1.0); + addElectricalSubResults(des_bit, 1.0); + getEventResult("Deserialize")->addSubResult(des_bit->getEventResult("Deserialize"), demux_name, 1.0); + } + } + + return; + } + + void DemuxTreeDeserializer::propagateTransitionInfo() + { + // Get parameters + bool bit_duplicate = getParameter("BitDuplicate"); + // Get generated properties + unsigned int deserialization_ratio = getGenProperties()->get("DeserializationRatio"); + unsigned int input_bits = getGenProperties()->get("InputBits"); + + // Calculate output transitions and activities + if (deserialization_ratio == 1) + { + // If no deserialization, then just propagate input transition info to output port + propagatePortTransitionInfo("Out", "In"); + } + else if (input_bits == 1) + { + const String& des_dff_way0_name = "DesDFFWay0"; + const String& des_dff_way1_name = "DesDFFWay1"; + const String& des_latch_name = "DesLatch"; + const String& ck_dff_name = "CKDFF"; + const String& ck_inv_name = "CKINV"; + + // Sub-deserializer names + const String& demux_way0_name = "DemuxTree_way0_" + (String) deserialization_ratio + "_to_1"; + const String& demux_way1_name = "DemuxTree_way1_" + (String) deserialization_ratio + "_to_1"; + + // Update transition info for deserialization registers/latches + ElectricalModel* des_latch = (ElectricalModel*) getSubInstance(des_latch_name); + propagatePortTransitionInfo(des_latch, "G", "InCK"); + propagatePortTransitionInfo(des_latch, "D", "In"); + des_latch->use(); + + ElectricalModel* des_dff_way0 = (ElectricalModel*) getSubInstance(des_dff_way0_name); + propagatePortTransitionInfo(des_dff_way0, "CK", "InCK"); + propagatePortTransitionInfo(des_dff_way0, "D", des_latch, "Q"); + des_dff_way0->use(); + + ElectricalModel* des_dff_way1 = (ElectricalModel*) getSubInstance(des_dff_way1_name); + propagatePortTransitionInfo(des_dff_way1, "CK", "InCK"); + propagatePortTransitionInfo(des_dff_way1, "D", "In"); + des_dff_way1->use(); + + // Get input transitions of input clock + double P01_CK = getInputPort("InCK")->getTransitionInfo().getNumberTransitions01(); + // Update transition info for clk division DFF + ElectricalModel* ck_dff = (ElectricalModel*) getSubInstance(ck_dff_name); + propagatePortTransitionInfo(ck_dff, "CK", "InCK"); + // Since it is a clock divider, P01 is D and Q are simply half the P01 of D and Q of + // the input clock + if (P01_CK != 0) ck_dff->getInputPort("D")->setTransitionInfo(TransitionInfo(0.0, P01_CK * 0.5, 0.0)); + else ck_dff->getInputPort("D")->setTransitionInfo(TransitionInfo(0.5, 0.0, 0.5)); + + ck_dff->use(); + // Update transition info of clk divided inverter + ElectricalModel* ck_inv = (ElectricalModel*) getSubInstance(ck_inv_name); + propagatePortTransitionInfo(ck_inv, "A", ck_dff, "Q"); + ck_inv->use(); + + // Update transition info for next demux stages + ElectricalModel* demux_way0 = (ElectricalModel*) getSubInstance(demux_way0_name); + propagatePortTransitionInfo(demux_way0, "In", des_dff_way0, "Q"); + propagatePortTransitionInfo(demux_way0, "InCK", ck_dff, "Q"); + demux_way0->use(); + ElectricalModel* demux_way1 = (ElectricalModel*) getSubInstance(demux_way1_name); + propagatePortTransitionInfo(demux_way1, "In", des_dff_way1, "Q"); + propagatePortTransitionInfo(demux_way1, "InCK", ck_dff, "Q"); + demux_way1->use(); + + propagatePortTransitionInfo("Out", demux_way0, "Out"); + } + else if (bit_duplicate) + { + // Propagate transition info + const String& demux_name = "DemuxTree_" + (String) deserialization_ratio + "_to_1"; + ElectricalModel* demux = (ElectricalModel*) getSubInstance(demux_name); + propagatePortTransitionInfo(demux, "In", "In"); + propagatePortTransitionInfo(demux, "InCK", "InCK"); + demux->use(); + + propagatePortTransitionInfo("Out", demux, "Out"); + } + else + { + // Set output probability to be average that of probabilties of each output bit + // Update all 1 bit deserializers + for (unsigned int i = 0; i < input_bits; ++i) + { + const String& demux_name = "DemuxTree_" + (String) deserialization_ratio + "_to_1_bit" + (String) i; + ElectricalModel* demux_bit = (ElectricalModel*) getSubInstance(demux_name); + propagatePortTransitionInfo(demux_bit, "In", "In"); + propagatePortTransitionInfo(demux_bit, "InCK", "InCK"); + demux_bit->use(); + + propagatePortTransitionInfo("Out", demux_bit, "Out"); + } + } + + return; + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/MatrixArbiter.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/MatrixArbiter.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_ELECTRICAL_MATRIX_ARBITER_H__ +#define __DSENT_MODEL_ELECTRICAL_MATRIX_ARBITER_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" + +namespace DSENT +{ + class MatrixArbiter : public ElectricalModel + { + public: + MatrixArbiter(const String& instance_name_, const TechModel* tech_model_); + virtual ~MatrixArbiter(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + + // Clone and return a new instance + virtual MatrixArbiter* clone() const; + + protected: + // Build the model + virtual void constructModel(); + virtual void propagateTransitionInfo(); + + }; // class MatrixArbiter +} // namespace DSENT + +#endif // __DSENT_MODEL_ELECTRICAL_MATRIX_ARBITER_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/MatrixArbiter.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/MatrixArbiter.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,465 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/electrical/MatrixArbiter.hh" + +#include +#include + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ModelGen.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" + +namespace DSENT +{ + using std::abs; + using std::vector; + + MatrixArbiter::MatrixArbiter(const String& instance_name_, const TechModel* tech_model_) + : ElectricalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + MatrixArbiter::~MatrixArbiter() + {} + + void MatrixArbiter::initParameters() + { + addParameterName("NumberRequests"); + return; + } + + void MatrixArbiter::initProperties() + { + return; + } + + MatrixArbiter* MatrixArbiter::clone() const + { + // TODO + return NULL; + } + + void MatrixArbiter::constructModel() + { + // Get parameters + unsigned int number_requests = getParameter("NumberRequests").toUInt(); + + ASSERT(number_requests > 0, "[Error] " + getInstanceName() + + " -> Number of requests must be > 0!"); + + // Connect ports + createInputPort("CK"); + for(unsigned int i = 0; i < number_requests; ++i) + { + createInputPort("Request" + (String)i); + createOutputPort("Grant" + (String)i); + } + + // Create area, power, event results + createElectricalResults(); + getEventInfo("Idle")->setStaticTransitionInfos(); + getEventInfo("Idle")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); +// for(unsigned int i = 0; i <= number_requests; ++i) +// { +// // Create arbitrate event with i requests +// createElectricalEventResult("Arbitrate" + (String)i); +// EventInfo* event_info = getEventInfo("Arbitrate" + (String)i); +// event_info->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); +// +// for(unsigned int j = 0; j < i; ++j) +// { +// event_info->setTransitionInfo("Request" + (String)j, TransitionInfo(0.0, 0.0, 1.0)); +// } +// for(unsigned int j = i; j < number_requests; ++j) +// { +// event_info->setTransitionInfo("Request" + (String)j, TransitionInfo(1.0, 0.0, 0.0)); +// +// } +// //double P_0 = (double)(number_requests - i) / (double)(number_requests); +// //double P_1 = (double)(i) / (double)(number_requests); +// //TransitionInfo trans(P_0 * P_0, P_0 * P_1, P_1 * P_1); +// +// //for(unsigned int j = 0; j < number_requests; ++j) +// //{ +// // event_info->setTransitionInfo("Request" + (String)j, trans); +// //} +// } + createElectricalEventResult("Arbitrate"); + getEventInfo("Arbitrate")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); + for(unsigned int i = 0; i < number_requests; ++i) + { + getEventInfo("Arbitrate")->setTransitionInfo("Request" + (String)i, TransitionInfo(0.25, 0.25, 0.25)); + } + + if(number_requests == 1) + { + assign("Grant0", "Request0"); + } + else + { + // Init components + vector g_inv_names(number_requests, ""); + vector g_invs(number_requests, NULL); + vector g_and2_names(number_requests, ""); + vector g_and2s(number_requests, NULL); + for(unsigned int i = 0; i < number_requests; ++i) + { + g_inv_names[i] = "G_INV" + (String)i; + g_and2_names[i] = "G_AND2" + (String)i; + g_invs[i] = getTechModel()->getStdCellLib()->createStdCell("INV", g_inv_names[i]); + g_invs[i]->construct(); + g_and2s[i] = getTechModel()->getStdCellLib()->createStdCell("AND2", g_and2_names[i]); + g_and2s[i]->construct(); + } + + unsigned int number_states = (number_requests - 1) * number_requests / 2; + + vector w_or2_names(number_states, ""); + vector w_or2s(number_states, NULL); + vector w_and2_names(number_states, ""); + vector w_and2s(number_states, NULL); + vector w_inv_names(number_states, ""); + vector w_invs(number_states, NULL); + vector w_dff_names(number_states, ""); + vector w_dffs(number_states, NULL); + vector dis_and2_names(number_states * 2, ""); + vector dis_and2s(number_states * 2, NULL); + vector dis_inv_names(number_states, ""); + vector dis_invs(number_states, NULL); + unsigned int state_count = 0; + for(unsigned int i = 0; i < number_requests; ++i) + { + for(unsigned int j = i + 1; j < number_requests; ++j) + { + w_or2_names[state_count] = String::format("W_OR2_%d_%d", i, j); + w_and2_names[state_count] = String::format("W_AND2_%d_%d", i, j); + w_inv_names[state_count] = String::format("W_INV_%d_%d", i, j); + w_dff_names[state_count] = String::format("W_DFF_%d_%d", i, j); + w_or2s[state_count] = getTechModel()->getStdCellLib()->createStdCell("OR2", w_or2_names[state_count]); + w_or2s[state_count]->construct(); + w_and2s[state_count] = getTechModel()->getStdCellLib()->createStdCell("AND2", w_and2_names[state_count]); + w_and2s[state_count]->construct(); + w_invs[state_count] = getTechModel()->getStdCellLib()->createStdCell("INV", w_inv_names[state_count]); + w_invs[state_count]->construct(); + w_dffs[state_count] = getTechModel()->getStdCellLib()->createStdCell("DFFQ", w_dff_names[state_count]); + w_dffs[state_count]->construct(); + + dis_inv_names[state_count] = String::format("Dis_INV_%d_%d", i, j); + dis_and2_names[state_count] = String::format("Dis_AND2_%d_%d", i, j); + dis_and2_names[state_count + number_states] = String::format("Dis_AND2_%d_%d", j, i); + dis_invs[state_count] = getTechModel()->getStdCellLib()->createStdCell("INV", dis_inv_names[state_count]); + dis_invs[state_count]->construct(); + dis_and2s[state_count] = getTechModel()->getStdCellLib()->createStdCell("AND2", dis_and2_names[state_count]); + dis_and2s[state_count]->construct(); + dis_and2s[state_count + number_states] = getTechModel()->getStdCellLib()->createStdCell("AND2", dis_and2_names[state_count + number_states]); + dis_and2s[state_count + number_states]->construct(); + state_count++; + } + } + + vector dis_or_names(number_requests, ""); + vector dis_ors(number_requests, NULL); + for(unsigned int i = 0; i < number_requests; ++i) + { + dis_or_names[i] = "Dis_OR" + (String)i; + dis_ors[i] = (ElectricalModel*)ModelGen::createModel("OR", dis_or_names[i], getTechModel()); + dis_ors[i]->setParameter("NumberInputs", number_requests-1); + dis_ors[i]->setParameter("NumberBits", 1); + dis_ors[i]->construct(); + } + + state_count = 0; + for(unsigned int i = 0; i < number_requests; ++i) + { + createNet("Dis_OR_Out" + (String)i); + createNet("G_INV_Out" + (String)i); + portConnect(g_invs[i], "A", "Dis_OR_Out" + (String)i); + portConnect(g_invs[i], "Y", "G_INV_Out" + (String)i); + portConnect(g_and2s[i], "A", "Request" + (String)i); + portConnect(g_and2s[i], "B", "G_INV_Out" + (String)i); + portConnect(g_and2s[i], "Y", "Grant" + (String)i); + + for(unsigned int j = i + 1; j < number_requests; ++j) + { + createNet(String::format("W_INV_Out_%d_%d", i, j)); + createNet(String::format("W_OR2_Out_%d_%d", i, j)); + createNet(String::format("W_AND2_Out_%d_%d", i, j)); + createNet(String::format("W_DFF_Out_%d_%d", i, j)); + portConnect(w_invs[state_count], "A", "Grant" + (String)i); + portConnect(w_invs[state_count], "Y", String::format("W_INV_Out_%d_%d", i, j)); + portConnect(w_or2s[state_count], "A", String::format("W_DFF_Out_%d_%d", i, j)); + portConnect(w_or2s[state_count], "B", "Grant" + (String)j); + portConnect(w_or2s[state_count], "Y", String::format("W_OR2_Out_%d_%d", i, j)); + portConnect(w_and2s[state_count], "A", String::format("W_OR2_Out_%d_%d", i, j)); + portConnect(w_and2s[state_count], "B", String::format("W_INV_Out_%d_%d", i, j)); + portConnect(w_and2s[state_count], "Y", String::format("W_AND2_Out_%d_%d", i, j)); + portConnect(w_dffs[state_count], "D", String::format("W_AND2_Out_%d_%d", i, j)); + portConnect(w_dffs[state_count], "CK", "CK"); + portConnect(w_dffs[state_count], "Q", String::format("W_DFF_Out_%d_%d", i, j)); + + createNet(String::format("Dis_AND2_Out_%d_%d", i, j)); + createNet(String::format("Dis_AND2_Out_%d_%d", j, i)); + createNet(String::format("Dis_INV_Out_%d_%d", j, i)); + portConnect(dis_and2s[state_count], "A", "Request" + (String)i); + portConnect(dis_and2s[state_count], "B", String::format("W_DFF_Out_%d_%d", i, j)); + portConnect(dis_and2s[state_count], "Y", String::format("Dis_AND2_Out_%d_%d", i, j)); + + portConnect(dis_invs[state_count], "A", String::format("W_DFF_Out_%d_%d", i, j)); + portConnect(dis_invs[state_count], "Y", String::format("Dis_INV_Out_%d_%d", j, i)); + portConnect(dis_and2s[state_count + number_states], "A", "Request" + (String)j); + portConnect(dis_and2s[state_count + number_states], "B", String::format("Dis_INV_Out_%d_%d", j, i)); + portConnect(dis_and2s[state_count + number_states], "Y", String::format("Dis_AND2_Out_%d_%d", j, i)); + + state_count++; + } + } + for(unsigned int i = 0; i < number_requests; ++i) + { + unsigned int k = 0; + for(unsigned int j = 0; j < number_requests; ++j) + { + if(i != j) + { + portConnect(dis_ors[i], "In" + (String)k, String::format("Dis_AND2_Out_%d_%d", j, i)); + k++; + } + } + portConnect(dis_ors[i], "Out", "Dis_OR_Out" + (String)i); + } + + // Add instances + for(unsigned int i = 0; i < number_requests; ++i) + { + addSubInstances(g_invs[i], 1.0); + addElectricalSubResults(g_invs[i], 1.0); + addSubInstances(g_and2s[i], 1.0); + addElectricalSubResults(g_and2s[i], 1.0); + addSubInstances(dis_ors[i], 1.0); + addElectricalSubResults(dis_ors[i], 1.0); + } + for(unsigned int i = 0; i < number_states; ++i) + { + addSubInstances(w_or2s[i], 1.0); + addElectricalSubResults(w_or2s[i], 1.0); + addSubInstances(w_and2s[i], 1.0); + addElectricalSubResults(w_and2s[i], 1.0); + addSubInstances(w_invs[i], 1.0); + addElectricalSubResults(w_invs[i], 1.0); + addSubInstances(w_dffs[i], 1.0); + addElectricalSubResults(w_dffs[i], 1.0); + addSubInstances(dis_and2s[i], 1.0); + addElectricalSubResults(dis_and2s[i], 1.0); + addSubInstances(dis_and2s[i + number_states], 1.0); + addElectricalSubResults(dis_and2s[i + number_states], 1.0); + addSubInstances(dis_invs[i], 1.0); + addElectricalSubResults(dis_invs[i], 1.0); + } + + // Update event + //for(unsigned int i = 0; i <= number_requests; ++i) + //{ + //Result* arb_event = getEventResult("Arbitrate" + (String)i); + Result* arb_event = getEventResult("Arbitrate"); + for(unsigned int j = 0; j < number_requests; ++j) + { + arb_event->addSubResult(g_invs[j]->getEventResult("INV"), g_inv_names[j], 1.0); + arb_event->addSubResult(g_and2s[j]->getEventResult("AND2"), g_and2_names[j], 1.0); + arb_event->addSubResult(dis_ors[j]->getEventResult("OR"), dis_or_names[j], 1.0); + } + for(unsigned int j = 0; j < number_states; ++j) + { + arb_event->addSubResult(w_or2s[j]->getEventResult("OR2"), w_or2_names[j], 1.0); + arb_event->addSubResult(w_and2s[j]->getEventResult("AND2"), w_and2_names[j], 1.0); + arb_event->addSubResult(w_invs[j]->getEventResult("INV"), w_inv_names[j], 1.0); + arb_event->addSubResult(w_dffs[j]->getEventResult("DFFD"), w_dff_names[j], 1.0); + arb_event->addSubResult(w_dffs[j]->getEventResult("DFFQ"), w_dff_names[j], 1.0); + arb_event->addSubResult(w_dffs[j]->getEventResult("CK"), w_dff_names[j], 1.0); + arb_event->addSubResult(dis_and2s[j]->getEventResult("AND2"), dis_and2_names[j], 1.0); + arb_event->addSubResult(dis_and2s[j + number_states]->getEventResult("AND2"), dis_and2_names[j + number_states], 1.0); + arb_event->addSubResult(dis_invs[j]->getEventResult("INV"), dis_inv_names[j], 1.0); + } + //} + } + return; + } + + void MatrixArbiter::propagateTransitionInfo() + { + // Get parameters + unsigned int number_requests = getParameter("NumberRequests").toUInt(); + + if(number_requests == 1) + { + propagatePortTransitionInfo("Grant0", "Request0"); + } + else + { + unsigned int number_states = (number_requests - 1) * number_requests / 2; + + vector g_and2s(number_requests, NULL); + vector g_invs(number_requests, NULL); + vector w_invs(number_states, NULL); + vector w_or2s(number_states, NULL); + vector w_and2s(number_states, NULL); + vector w_dffs(number_states, NULL); + vector dis_invs(number_states, NULL); + vector dis_and2s(number_requests * number_requests, NULL); + vector dis_ors(number_requests, NULL); + for(unsigned int i = 0; i < number_requests; ++i) + { + g_and2s[i] = (ElectricalModel*)getSubInstance("G_AND2" + (String)i); + g_invs[i] = (ElectricalModel*)getSubInstance("G_INV" + (String)i); + dis_ors[i] = (ElectricalModel*)getSubInstance("Dis_OR" + (String)i); + } + unsigned int state_count = 0; + for(unsigned int i = 0; i < number_requests; ++i) + { + for(unsigned int j = i + 1; j < number_requests; ++j) + { + w_invs[state_count] = (ElectricalModel*)getSubInstance(String::format("W_INV_%d_%d", i, j)); + w_or2s[state_count] = (ElectricalModel*)getSubInstance(String::format("W_OR2_%d_%d", i, j)); + w_and2s[state_count] = (ElectricalModel*)getSubInstance(String::format("W_AND2_%d_%d", i, j)); + w_dffs[state_count] = (ElectricalModel*)getSubInstance(String::format("W_DFF_%d_%d", i, j)); + dis_invs[state_count] = (ElectricalModel*)getSubInstance(String::format("Dis_INV_%d_%d", i, j)); + dis_and2s[i * number_requests + j] = (ElectricalModel*)getSubInstance(String::format("Dis_AND2_%d_%d", i, j)); + dis_and2s[j * number_requests + i] = (ElectricalModel*)getSubInstance(String::format("Dis_AND2_%d_%d", j, i)); + + w_dffs[state_count]->getInputPort("D")->setTransitionInfo(TransitionInfo(0.5, 0.0, 0.5)); + propagatePortTransitionInfo(w_dffs[state_count], "CK", "CK"); + w_dffs[state_count]->use(); + + state_count++; + } + } + + unsigned int iteration = 1; + unsigned int max_number_iterations = 10; + //vector trans_vector(number_states, TransitionInfo(0.0, 0.0, 1.0)); + //vector total_P_vector(number_states, 0.0); + while(iteration < max_number_iterations) + { +// for(unsigned int i = 0; i < number_states; ++i) +// { +// w_dffs[i]->getInputPort("D")->setTransitionInfo(trans_vector[i]); +// propagatePortTransitionInfo(w_dffs[i], "CK", "CK"); +// w_dffs[i]->use(); +// } + state_count = 0; + for(unsigned int i = 0; i < number_requests; ++i) + { + for(unsigned int j = i + 1; j < number_requests; ++j) + { + propagatePortTransitionInfo(dis_and2s[i * number_requests + j], "A", "Request" + (String)i); + propagatePortTransitionInfo(dis_and2s[i * number_requests + j], "B", w_dffs[state_count], "Q"); + dis_and2s[i * number_requests + j]->use(); + propagatePortTransitionInfo(dis_invs[state_count], "A", w_dffs[state_count], "Q"); + dis_invs[state_count]->use(); + propagatePortTransitionInfo(dis_and2s[j * number_requests + i], "A", "Request" + (String)j); + propagatePortTransitionInfo(dis_and2s[j * number_requests + i], "B", dis_invs[state_count], "Y"); + dis_and2s[j * number_requests + i]->use(); + + state_count++; + } + } + for(unsigned int i = 0; i < number_requests; ++i) + { + unsigned int k = 0; + for(unsigned int j = 0; j < number_requests; ++j) + { + if(i != j) + { + propagatePortTransitionInfo(dis_ors[i], "In" + (String)k, dis_and2s[j * number_requests + i], "Y"); + k++; + } + } + dis_ors[i]->use(); + } + for(unsigned int i = 0; i < number_requests; ++i) + { + propagatePortTransitionInfo(g_invs[i], "A", dis_ors[i], "Out"); + g_invs[i]->use(); + propagatePortTransitionInfo(g_and2s[i], "A", "Request" + (String)i); + propagatePortTransitionInfo(g_and2s[i], "B", g_invs[i], "Y"); + g_and2s[i]->use(); + } + state_count = 0; + for(unsigned int i = 0; i < number_requests; ++i) + { + for(unsigned int j = i + 1; j < number_requests; ++j) + { + propagatePortTransitionInfo(w_invs[state_count], "A", g_and2s[i], "Y"); + w_invs[state_count]->use(); + propagatePortTransitionInfo(w_or2s[state_count], "A", w_dffs[state_count], "Q"); + propagatePortTransitionInfo(w_or2s[state_count], "B", g_and2s[j], "Y"); + w_or2s[state_count]->use(); + propagatePortTransitionInfo(w_and2s[state_count], "A", w_or2s[state_count], "Y"); + propagatePortTransitionInfo(w_and2s[state_count], "B", w_invs[state_count], "Y"); + w_and2s[state_count]->use(); + propagatePortTransitionInfo(w_dffs[state_count], "D", w_and2s[state_count], "Y"); + propagatePortTransitionInfo(w_dffs[state_count], "CK", "CK"); + w_dffs[state_count]->use(); + state_count++; + } + } + +// for(unsigned int i = 0; i < number_states; ++i) +// { +// const TransitionInfo& new_trans = w_dffs[i]->getOutputPort("Q")->getTransitionInfo(); +// total_P_vector[i] += new_trans.getProbability1(); +// trans_vector[i] = TransitionInfo((1.0 - total_P_vector[i] / iteration) * (1.0 - total_P_vector[i] / iteration), +// (1.0 - total_P_vector[i] / iteration) * (total_P_vector[i] / iteration), +// (total_P_vector[i] / iteration) * (total_P_vector[i] / iteration)); +// } +// +// for(unsigned int i = 0; i < number_requests; ++i) +// { +// g_and2s[i]->getOutputPort("Y")->getTransitionInfo().print(cout); +// } +// cout << endl; + iteration++; + } + + for(unsigned int i = 0; i < number_requests; ++i) + { + propagatePortTransitionInfo("Grant" + (String)i, g_and2s[i], "Y"); + } + } + + return; + } +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/Multiplexer.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/Multiplexer.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_ELECTRICAL_MULTIPLEXER_H__ +#define __DSENT_MODEL_ELECTRICAL_MULTIPLEXER_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" + +namespace DSENT +{ + // A model of an N-to-1 multiplexer + class Multiplexer : public ElectricalModel + { + public: + Multiplexer(const String& instance_name_, const TechModel* tech_model_); + virtual ~Multiplexer(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + + // Clone and return a new instance + virtual Multiplexer* clone() const; + + protected: + // Build the model + virtual void constructModel(); + virtual void propagateTransitionInfo(); + + }; // class Multiplexer +} // namespace DSENT + +#endif // __DSENT_MODEL_ELECTRICAL_MULTIPLEXER_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/Multiplexer.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/Multiplexer.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,378 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/electrical/Multiplexer.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriverMultiplier.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" + +namespace DSENT +{ + Multiplexer::Multiplexer(const String& instance_name_, const TechModel* tech_model_) + : ElectricalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + Multiplexer::~Multiplexer() + {} + + void Multiplexer::initParameters() + { + addParameterName("NumberInputs"); + addParameterName("NumberBits"); + addParameterName("BitDuplicate", "TRUE"); + addParameterName("IsTopLevel", "TRUE"); + return; + } + + void Multiplexer::initProperties() + { + return; + } + + Multiplexer* Multiplexer::clone() const + { + return NULL; + } + + void Multiplexer::constructModel() + { + // Get parameters + unsigned int number_bits = (unsigned int) getParameter("NumberBits"); + unsigned int number_inputs = (unsigned int) getParameter("NumberInputs"); + unsigned int number_selects = (unsigned int) ceil(log2((double) number_inputs)); + bool bit_duplicate = (bool) getParameter("BitDuplicate"); + bool is_top_level = getParameter("IsTopLevel").toBool(); + + ASSERT(number_inputs > 0, "[Error] " + getInstanceName() + " -> Number of inputs must be > 0!"); + ASSERT(number_bits > 0, "[Error] " + getInstanceName() + " -> Number of bits must be > 0!"); + + //Construct electrical ports and nets + //Create each input port + for(unsigned int i = 0; i < number_inputs; ++i) + createInputPort( "In" + (String) i, makeNetIndex(0, number_bits-1)); + //Create select signals + for(unsigned int i = 0; i < number_selects; ++i) + { + createInputPort( "Sel" + (String)i); + } + //Create output + createOutputPort( "Out", makeNetIndex(0, number_bits-1)); + + //Create energy, power, and area results + createElectricalResults(); + getEventInfo("Idle")->setStaticTransitionInfos(); + createElectricalEventResult("Mux"); + + //Number of inputs on the 0 side + unsigned int inputs_0 = (unsigned int) ceil((double) number_inputs / 2.0); + unsigned int selects_0 = (unsigned int) ceil(log2((double) inputs_0)); + //Number of inputs on the 1 side + unsigned int inputs_1 = (unsigned int) floor((double) number_inputs / 2.0); + unsigned int selects_1 = (unsigned int) ceil(log2((double) inputs_1)); + + //Depending on whether we want to create a 1-bit instance and have it multiplied + //up by number of bits or actually instantiate number_bits of 1-bit instances. + //Recursively instantiates smaller multiplexers + if (bit_duplicate || number_bits == 1) + { + //If it is just a 1-input multiplexer, just connect output to input and be done + if (number_inputs == 1) + { + assign("Out", "In0"); + } + else + { + //If it is more than 1 input, instantiate two sub multiplexers (Mux_way0 and Mux_way1) + //and create a final 2:1 mux (muxf) to select between them + String mux0_name = "Mux_way0"; + String mux1_name = "Mux_way1"; + String muxf_name = "Mux2_i" + (String)number_inputs; + + Multiplexer* mux0 = new Multiplexer(mux0_name, getTechModel()); + mux0->setParameter("NumberInputs", inputs_0); + mux0->setParameter("NumberBits", 1); + mux0->setParameter("BitDuplicate", "TRUE"); + mux0->setParameter("IsTopLevel", "FALSE"); + mux0->construct(); + + Multiplexer* mux1 = new Multiplexer(mux1_name, getTechModel()); + mux1->setParameter("NumberInputs", inputs_1); + mux1->setParameter("NumberBits", 1); + mux1->setParameter("BitDuplicate", "TRUE"); + mux1->setParameter("IsTopLevel", "FALSE"); + mux1->construct(); + + StdCell* muxf = getTechModel()->getStdCellLib()->createStdCell("MUX2", muxf_name); + muxf->construct(); + + // TODO hack + // create selector driver at the top level + if(is_top_level) + { + for(unsigned int i = 0; i < number_selects; ++i) + { + StdCell* selinv0 = getTechModel()->getStdCellLib()->createStdCell("INV", String::format("Sel%dInv0", i)); + StdCell* selinv1 = getTechModel()->getStdCellLib()->createStdCell("INV", String::format("Sel%dInv1", i)); + selinv0->construct(); + selinv1->construct(); + + addSubInstances(selinv0, 1.0); + addElectricalSubResults(selinv0, 1.0); + addSubInstances(selinv1, 1.0); + addElectricalSubResults(selinv1, 1.0); + getEventResult("Mux")->addSubResult(selinv0->getEventResult("INV"), String::format("Sel%dInv0", i), 1.0); + getEventResult("Mux")->addSubResult(selinv1->getEventResult("INV"), String::format("Sel%dInv1", i), 1.0); + } + } + + //Create outputs of way0 and way1 multiplexers with final mux + createNet("way0Out"); + createNet("way1Out"); + portConnect(mux0, "Out", "way0Out"); + portConnect(mux1, "Out", "way1Out"); + portConnect(muxf, "A", "way0Out"); + portConnect(muxf, "B", "way1Out"); + + // TODO hack + // Connect selector bits + if(is_top_level) + { + for(unsigned int i = 0; i < number_selects; ++i) + { + ElectricalModel* selinv0 = (ElectricalModel*)getSubInstance(String::format("Sel%dInv0", i)); + ElectricalModel* selinv1 = (ElectricalModel*)getSubInstance(String::format("Sel%dInv1", i)); + createNet("SelInv" + (String)i); + createNet("SelBuf" + (String)i); + portConnect(selinv0, "A", "Sel" + (String)i); + portConnect(selinv0, "Y", "SelInv" + (String)i); + portConnect(selinv1, "A", "SelInv" + (String)i); + portConnect(selinv1, "Y", "SelBuf" + (String)i); + } + } + //Connect inputs to the sub multiplexers. + //Note that multiple inputs are connected to the mux0 and mux1 input and the + //selector signals are connected multiple times. This is just so that everything + //is loaded appropriately since bit duplication is applied + for (unsigned int n = 0; n < number_bits; ++n) + { + //Connect inputs + for (unsigned int i = 0; i < inputs_0; ++i) + portConnect(mux0, "In" + (String) i, "In" + (String) i, makeNetIndex(n)); + for (unsigned int i = 0; i < inputs_1; ++i) + portConnect(mux1, "In" + (String) i, "In" + (String) (i + inputs_0), makeNetIndex(n)); + // TODO hack + if(is_top_level) + { + //Connect selector bits + for (unsigned int i = 0; i < selects_0; ++i) + portConnect(mux0, "Sel" + (String)i, "SelBuf" + (String)i); + for (unsigned int i = 0; i < selects_1; ++i) + portConnect(mux1, "Sel" + (String)i, "SelBuf" + (String)i); + portConnect(muxf, "S0", "SelBuf" + (String)(number_selects - 1)); + } + else + { + //Connect selector bits + for (unsigned int i = 0; i < selects_0; ++i) + portConnect(mux0, "Sel" + (String)i, "Sel" + (String)i); + for (unsigned int i = 0; i < selects_1; ++i) + portConnect(mux1, "Sel" + (String)i, "Sel" + (String)i); + portConnect(muxf, "S0", "Sel" + (String)(number_selects - 1)); + } + } + + //Connect final mux to outputs + //Because we use bit duplication and so there is only only one multiplexer + //instance, we must use driver multiplier to drive each output appropriately + if (number_bits == 1) + portConnect(muxf, "Y", "Out"); + else + { + createNet("OutTemp"); + createDriverMultiplier("OutMult"); + ElectricalDriverMultiplier* drive_mult = getDriverMultiplier("OutMult"); + portConnect(muxf, "Y", "OutTemp"); + getNet("OutTemp")->addDownstreamNode(drive_mult); + for (unsigned int n = 0; n < number_bits; ++n) + drive_mult->addDownstreamNode(getNet("Out", makeNetIndex(n))); + } + + //Add area, power, and event results for each mux + addSubInstances(mux0, number_bits); + addElectricalSubResults(mux0, number_bits); + addSubInstances(mux1, number_bits); + addElectricalSubResults(mux1, number_bits); + addSubInstances(muxf, number_bits); + addElectricalSubResults(muxf, number_bits); + getEventResult("Mux")->addSubResult(mux0->getEventResult("Mux"), mux0_name, number_bits); + getEventResult("Mux")->addSubResult(mux1->getEventResult("Mux"), mux1_name, number_bits); + getEventResult("Mux")->addSubResult(muxf->getEventResult("MUX2"), muxf_name, number_bits); + + } + + } + else + { + //Instantiate a bunch of 1-bit multiplexers + for (unsigned int n = 0; n < number_bits; ++n) + { + String mux_name = "Mux_bit" + (String) n; + + Multiplexer* mux = new Multiplexer(mux_name, getTechModel()); + mux->setParameter("NumberInputs", number_inputs); + mux->setParameter("NumberBits", 1); + mux->setParameter("BitDuplicate", "TRUE"); + mux->construct(); + + // Connect inputs + for (unsigned int i = 0; i < number_inputs; ++i) + portConnect(mux, "In" + (String) i, "In" + (String) i, makeNetIndex(n)); + for(unsigned int i = 0; i < number_selects; ++i) + portConnect(mux, "Sel" + (String)i, "Sel" + (String)i); + portConnect(mux, "Out", "Out", makeNetIndex(n)); + + //Add area, power, and event results for each mux + addSubInstances(mux, 1.0); + addElectricalSubResults(mux, 1.0); + getEventResult("Mux")->addSubResult(mux->getEventResult("Mux"), mux_name, 1.0); + } + } + + return; + } + + void Multiplexer::propagateTransitionInfo() + { + // The only thing can be updated are the input probabilities...so we will update them + unsigned int number_bits = (unsigned int) getParameter("NumberBits"); + unsigned int number_inputs = (unsigned int) getParameter("NumberInputs"); + unsigned int number_selects = (unsigned int) ceil(log2((double) number_inputs)); + bool bit_duplicate = (bool) getParameter("BitDuplicate"); + bool is_top_level = getParameter("IsTopLevel").toBool(); + + //Number of inputs on the 0 side + unsigned int inputs_0 = (unsigned int) ceil((double) number_inputs / 2.0); + unsigned int selects_0 = (unsigned int) ceil(log2((double) inputs_0)); + + //Number of inputs on the 1 side + unsigned int inputs_1 = (unsigned int) floor((double) number_inputs / 2.0); + unsigned int selects_1 = (unsigned int) ceil(log2((double) inputs_1)); + + if (bit_duplicate || number_bits == 1) + { + if (number_inputs == 1) + { + //If theres only 1 input, output transition = input transition + propagatePortTransitionInfo("Out", "In0"); + } + else + { + // Update sub muxes with appropriate probabilities + ElectricalModel* mux0 = (ElectricalModel*)getSubInstance("Mux_way0"); + for(unsigned int i = 0; i < inputs_0; ++i) + { + propagatePortTransitionInfo(mux0, "In" + (String)i, "In" + (String)i); + } + for(unsigned int i = 0; i < selects_0; ++i) + { + propagatePortTransitionInfo(mux0, "Sel" + (String)i, "Sel" + (String)i); + } + mux0->use(); + ElectricalModel* mux1 = (ElectricalModel*)getSubInstance("Mux_way1"); + for(unsigned int i = 0; i < inputs_1; ++i) + { + propagatePortTransitionInfo(mux1, "In" + (String)i, "In" + (String)(i + inputs_0)); + } + for(unsigned int i = 0; i < selects_1; ++i) + { + propagatePortTransitionInfo(mux1, "Sel" + (String)i, "Sel" + (String)i); + } + mux1->use(); + ElectricalModel* muxf = (ElectricalModel*)getSubInstance("Mux2_i" + (String)number_inputs); + propagatePortTransitionInfo(muxf, "A", mux0, "Out"); + propagatePortTransitionInfo(muxf, "B", mux1, "Out"); + propagatePortTransitionInfo(muxf, "S0", "Sel" + (String)(number_selects-1)); + muxf->use(); + + // TODO hack + if(is_top_level) + { + for(unsigned int i = 0; i < number_selects; ++i) + { + ElectricalModel* selinv0 = (ElectricalModel*)getSubInstance(String::format("Sel%dInv0", i)); + ElectricalModel* selinv1 = (ElectricalModel*)getSubInstance(String::format("Sel%dInv1", i)); + propagatePortTransitionInfo(selinv0, "A", "Sel" + (String)i); + selinv0->use(); + propagatePortTransitionInfo(selinv1, "A", selinv0, "Y"); + selinv1->use(); + } + } + + // Set output transition + propagatePortTransitionInfo("Out", muxf, "Y"); + } + } + else + { + // Go through each bit and set the appropriate probability + for (unsigned int n = 0; n < number_bits; ++n) + { + ElectricalModel* mux_bit = (ElectricalModel*)getSubInstance("Mux_bit" + (String) n); + for(unsigned int i = 0; i < number_inputs; ++i) + { + propagatePortTransitionInfo(mux_bit, "In" + (String)i, "In" + (String)i); + } + for(unsigned int i = 0; i < number_selects; ++i) + { + propagatePortTransitionInfo(mux_bit, "Sel" + (String)i, "Sel" + (String)i); + } + mux_bit->use(); + } + + // Set output probability to be average that of probabilties of each output bit + ElectricalModel* mux_bit = (ElectricalModel*)getSubInstance("Mux_bit0"); + propagatePortTransitionInfo("Out", mux_bit, "Out"); + } + return; + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/MultiplexerCrossbar.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/MultiplexerCrossbar.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_ELECTRICAL_MULTIPLEXER_CROSSBAR_H__ +#define __DSENT_MODEL_ELECTRICAL_MULTIPLEXER_CROSSBAR_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" + +namespace DSENT +{ + // A model for a NxM W-bit multiplexer-based crossbar + class MultiplexerCrossbar : public ElectricalModel + { + public: + MultiplexerCrossbar(const String& instance_name_, const TechModel* tech_model_); + virtual ~MultiplexerCrossbar(); + + public: + // Set a list of paramerters' name needed to construct model + void initParameters(); + // Set a list of peroperties' name needed to construct model + void initProperties(); + + // Clone and return a new instance + virtual MultiplexerCrossbar* clone() const; + + protected: + // Build the model + virtual void constructModel(); + virtual void updateModel(); + virtual void propagateTransitionInfo(); + + private: + // Disable copy constructor + MultiplexerCrossbar(const MultiplexerCrossbar& crossbar_); + }; // class MultiplexerCrossbar +} // namespace DSENT + +#endif // __DSENT_MODEL_ELECTRICAL_MULTIPLEXER_CROSSBAR_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/MultiplexerCrossbar.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/MultiplexerCrossbar.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/electrical/MultiplexerCrossbar.hh" + +#include +#include + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" +#include "mem/ruby/network/dsent/dsent-core/model/electrical/Multiplexer.hh" + +namespace DSENT +{ + using std::ceil; + using std::vector; + + MultiplexerCrossbar::MultiplexerCrossbar(const String& instance_name_, const TechModel* tech_model_) + : ElectricalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + MultiplexerCrossbar::~MultiplexerCrossbar() + {} + + void MultiplexerCrossbar::initParameters() + { + addParameterName("NumberInputs"); + addParameterName("NumberOutputs"); + addParameterName("NumberBits"); + addParameterName("BitDuplicate", "TRUE"); + return; + } + + void MultiplexerCrossbar::initProperties() + { + return; + } + + MultiplexerCrossbar* MultiplexerCrossbar::clone() const + { + // TODO + return NULL; + } + + void MultiplexerCrossbar::constructModel() + { + // Get Parameters + unsigned int number_inputs = getParameter("NumberInputs").toUInt(); + unsigned int number_outputs = getParameter("NumberOutputs").toUInt(); + unsigned int number_bits = getParameter("NumberBits").toUInt(); + bool bit_duplicate = getParameter("BitDuplicate").toBool(); + + ASSERT(number_inputs > 0, "[Error] " + getInstanceName() + " -> Number of inputs must be > 0!"); + ASSERT(number_outputs > 0, "[Error] " + getInstanceName() + " -> Number of outputs must be > 0!"); + ASSERT(number_bits > 0, "[Error] " + getInstanceName() + " -> Number of bits must be > 0!"); + + unsigned int number_selects = (unsigned int)ceil(log2((double)number_inputs)); + getGenProperties()->set("NumberSelectsPerPort", number_selects); + + // Construct electrical ports and nets + // Create input ports + for(unsigned int i = 0; i < number_inputs; ++i) + { + createInputPort("In" + (String)i, makeNetIndex(0, number_bits-1)); + } + // Create select signals + for(unsigned int i = 0; i < number_outputs; ++i) + { + for(unsigned int j = 0; j < number_selects; ++j) + { + createInputPort(String::format("Sel%d_%d", i, j)); + } + } + // Create output ports + for(unsigned int i = 0; i < number_outputs; ++i) + { + createOutputPort("Out" + (String)i, makeNetIndex(0, number_bits-1)); + } + + // Create energy, power, and area results + addAreaResult(new AtomicResult("CrossbarWire")); + addAreaResult(new AtomicResult("CrossbarFill")); + createElectricalResults(); + getEventInfo("Idle")->setStaticTransitionInfos(); + createElectricalEventResult("Multicast0"); + getEventInfo("Multicast0")->setStaticTransitionInfos(); + for(unsigned int i = 1; i <= number_outputs; ++i) + { + createElectricalEventResult("Multicast" + (String)i); + EventInfo* event_info = getEventInfo("Multicast" + (String)i); + // Assuming that In0 is sending to Out0, Out1, ..., Outi + // and other input ports are static + for(unsigned int j = 1; j < number_inputs; ++j) + { + event_info->setStaticTransitionInfo("In" + (String)j); + } + for(unsigned int j = i; j < number_outputs; ++j) + { + for(unsigned int k = 0; k < number_selects; ++k) + { + event_info->setStaticTransitionInfo(String::format("Sel%d_%d", j, k)); + } + } + } + createElectricalEventResult("Crossbar"); + + // Initiate multiplexers + vector mux_names(number_outputs, ""); + vector muxs(number_outputs, NULL); + for(unsigned int i = 0; i < number_outputs; ++i) + { + mux_names[i] = "Mux" + (String)i; + muxs[i] = new Multiplexer(mux_names[i], getTechModel()); + muxs[i]->setParameter("NumberInputs", number_inputs); + muxs[i]->setParameter("NumberBits", number_bits); + muxs[i]->setParameter("BitDuplicate", bit_duplicate); + muxs[i]->construct(); + } + + // Connect inputs and outputs to multiplexers + for(unsigned int i = 0; i < number_outputs; ++i) + { + // Connect inputs + for(unsigned int j = 0; j < number_inputs; ++j) + { + portConnect(muxs[i], "In" + (String)j, "In" + (String)j, makeNetIndex(0, number_bits-1)); + } + + // Connect select signals + for(unsigned int j = 0; j < number_selects; ++j) + { + portConnect(muxs[i], "Sel" + (String)j, String::format("Sel%d_%d", i, j)); + } + + // Connect outputs + portConnect(muxs[i], "Out", "Out" + (String)i, makeNetIndex(0, number_bits-1)); + } + + // Add area, power, and event results for each mux + for(unsigned int i = 0; i < number_outputs; ++i) + { + addSubInstances(muxs[i], 1.0); + addElectricalSubResults(muxs[i], 1.0); + for(unsigned int j = 0; j <= number_outputs; ++j) + { + getEventResult("Multicast" + (String)j)->addSubResult(muxs[i]->getEventResult("Mux"), mux_names[i], 1.0); + } + getEventResult("Crossbar")->addSubResult(muxs[i]->getEventResult("Mux"), mux_names[i], 1.0); + } + + // Estimate wiring area + const String& crossbar_wire_layer = "Intermediate"; + addElectricalWireSubResult(crossbar_wire_layer, getAreaResult("CrossbarWire"), "Self", 1.0); + double wire_width = getTechModel()->get("Wire->" + crossbar_wire_layer + "->MinWidth").toDouble(); + double wire_spacing = getTechModel()->get("Wire->" + crossbar_wire_layer + "->MinSpacing").toDouble(); + double wire_pitch = wire_width + wire_spacing; + double wire_area = (number_bits * number_inputs * wire_pitch) * (number_bits * number_outputs * wire_pitch); + getAreaResult("CrossbarWire")->setValue(wire_area); + + // Add filler area + getAreaResult("Active")->addSubResult(getAreaResult("CrossbarFill"), "Self", 1.0); + return; + } + + void MultiplexerCrossbar::updateModel() + { + // Update all sub instances + Model::updateModel(); + + // Update filler area + // Total Active area = max(stdcell active area, wiring area); + double wire_area = getAreaResult("CrossbarWire")->calculateSum(); + double active_area = getAreaResult("Active")->calculateSum(); + double fill_area = 0.0; + if(active_area < wire_area) + { + fill_area = wire_area - active_area; + } + getAreaResult("CrossbarFill")->setValue(fill_area); + return; + } + + void MultiplexerCrossbar::propagateTransitionInfo() + { + // The only thing can be updated are the input probabilities + const unsigned int number_inputs = getParameter("NumberInputs").toUInt(); + const unsigned int number_outputs = getParameter("NumberOutputs").toUInt(); + + const unsigned int number_selects = getGenProperties()->get("NumberSelectsPerPort").toUInt(); + + for(unsigned int i = 0; i < number_outputs; ++i) + { + ElectricalModel* muxi = (ElectricalModel*)getSubInstance("Mux" + (String)i); + for(unsigned int j = 0; j < number_inputs; ++j) + { + propagatePortTransitionInfo(muxi, "In" + (String)j, "In" + (String)j); + } + for(unsigned int j = 0; j < number_selects; ++j) + { + propagatePortTransitionInfo(muxi, "Sel" + (String)j, String::format("Sel%d_%d", i, j)); + } + muxi->use(); + + // Set output probability + propagatePortTransitionInfo("Out" + (String)i, muxi, "Out"); + } + + return; + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/MuxTreeSerializer.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/MuxTreeSerializer.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_ELECTRICAL_MUXTREESERIALIZER_H__ +#define __DSENT_MODEL_ELECTRICAL_MUXTREESERIALIZER_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" + +namespace DSENT +{ + class MuxTreeSerializer : public ElectricalModel + { + public: + MuxTreeSerializer(const String& instance_name_, const TechModel* tech_model_); + virtual ~MuxTreeSerializer(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + + // Clone and return a new instance + virtual MuxTreeSerializer* clone() const; + + protected: + // Build the model + virtual void constructModel(); + virtual void propagateTransitionInfo(); + + }; // class MuxTreeSerializer +} // namespace DSENT + +#endif // __DSENT_MODEL_ELECTRICAL_MUXTREESERIALIZER_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/MuxTreeSerializer.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/MuxTreeSerializer.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/electrical/MuxTreeSerializer.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" +#include "mem/ruby/network/dsent/dsent-core/model/electrical/Multiplexer.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" + +namespace DSENT +{ + using std::ceil; + + MuxTreeSerializer::MuxTreeSerializer(const String& instance_name_, const TechModel* tech_model_) + : ElectricalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + MuxTreeSerializer::~MuxTreeSerializer() + {} + + void MuxTreeSerializer::initParameters() + { + addParameterName("InDataRate"); + addParameterName("OutDataRate"); + addParameterName("InBits"); //Output width will just be input width / serialization ratio + } + + void MuxTreeSerializer::initProperties() + { + return; + } + + MuxTreeSerializer* MuxTreeSerializer::clone() const + { + // TODO + return NULL; + } + + void MuxTreeSerializer::constructModel() + { + // Get parameters + double in_data_rate = getParameter("InDataRate").toDouble(); + double out_data_rate = getParameter("OutDataRate").toDouble(); + unsigned int in_bits = getParameter("InBits").toUInt(); + + // Calculate serialization ratio + unsigned int serialization_ratio = (unsigned int) floor(out_data_rate / in_data_rate); + ASSERT(serialization_ratio == out_data_rate / in_data_rate, + "[Error] " + getInstanceName() + " -> Cannot have non-integer serialization ratios " + + "(" + (String) (in_data_rate / out_data_rate) + ")!"); + + // Calculate output width + ASSERT(floor((double) in_bits / serialization_ratio) == (double) in_bits / serialization_ratio, + "[Error] " + getInstanceName() + " -> Input width (" + (String) in_bits + ") " + + "must be a multiple of the serialization ratio (" + (String) serialization_ratio + ")!"); + unsigned int output_bits = in_bits / serialization_ratio; + + // Calculate the number of multiplexer stages + unsigned int number_stages = (unsigned int)ceil(log2((double) serialization_ratio)); + + // Store calculated values + getGenProperties()->set("SerializationRatio", serialization_ratio); + getGenProperties()->set("OutputBits", output_bits); + getGenProperties()->set("NumberStages", number_stages); + + // Create ports + createInputPort("In", makeNetIndex(0, in_bits-1)); + createInputPort("OutCK"); + createOutputPort("Out", makeNetIndex(0, output_bits-1)); + + //Create energy, power, and area results + createElectricalResults(); + createElectricalEventResult("Serialize"); + getEventInfo("Serialize")->setTransitionInfo("OutCK", TransitionInfo(0.0, (double) serialization_ratio / 2.0, 0.0)); + //Set conditions during idle state + getEventInfo("Idle")->setStaticTransitionInfos(); + getEventInfo("Idle")->setTransitionInfo("OutCK", TransitionInfo(0.0, (double) serialization_ratio / 2.0, 0.0)); + + // Mark OutCK as a false path (since timing tool will do strange stuff due to all the clock divides and stuff) + getNet("OutCK")->setFalsePath(true); + + // Create mux-tree instance + if (serialization_ratio == 1) + { + // No need to do anything, hohoho + assign("Out", "In"); + } + else + { + // Create multiplexer + String mux_tree_name = "MuxTree"; + ElectricalModel* mux_tree = new Multiplexer(mux_tree_name, getTechModel()); + mux_tree->setParameter("NumberInputs", serialization_ratio); + mux_tree->setParameter("NumberBits", output_bits); + mux_tree->setParameter("BitDuplicate", "TRUE"); + mux_tree->construct(); + // Create nets + if (number_stages > 1) + createNet("MuxSel_b", makeNetIndex(0, number_stages-2)); + createNet("MuxSel", makeNetIndex(0, number_stages-1)); + assign("MuxSel", makeNetIndex(number_stages-1), "OutCK"); + // Create reindexed net (to help out with indexing) + createNet("InTmp", makeNetIndex(0, in_bits-1)); + for (unsigned int i = 0; i < serialization_ratio; ++i) + for (unsigned int j = 0; j < output_bits; ++j) + assign("InTmp", makeNetIndex(i*output_bits+j), "In", makeNetIndex(j*serialization_ratio+i)); + + // Connect ports + for (unsigned int i = 0; i < serialization_ratio; ++i) + portConnect(mux_tree, "In" + (String) i, "InTmp", makeNetIndex(i*output_bits, (i+1)*output_bits-1)); + + for (unsigned int i = 0; i < number_stages; ++i) + portConnect(mux_tree, "Sel" + (String) i, "MuxSel", makeNetIndex(i)); + portConnect(mux_tree, "Out", "Out"); + + // Add subinstance and events + addSubInstances(mux_tree, 1.0); + addElectricalSubResults(mux_tree, 1.0); + // Add serialize event/power + getEventResult("Serialize")->addSubResult(mux_tree->getEventResult("Mux"), mux_tree_name, 1.0); + + // Create clock dividers (assumes power of 2...), don't need divider for fastest output stage + for (unsigned int i = 0; i < number_stages - 1; ++i) + { + // Clk dividing registers + const String& clk_div_dff_name = "ClkDivDFF_" + (String) i; + StdCell* clk_div_dff = getTechModel()->getStdCellLib()->createStdCell("DFFQ", clk_div_dff_name); + clk_div_dff->construct(); + portConnect(clk_div_dff, "D", "MuxSel_b", makeNetIndex(i)); + portConnect(clk_div_dff, "Q", "MuxSel", makeNetIndex(i)); + portConnect(clk_div_dff, "CK", "MuxSel", makeNetIndex(i+1)); + addSubInstances(clk_div_dff, 1.0); + addElectricalSubResults(clk_div_dff, 1.0); + + // Inversions + const String& clk_div_inv_name = "ClkDivINV_" + (String) i; + StdCell* clk_div_inv = getTechModel()->getStdCellLib()->createStdCell("INV", clk_div_inv_name); + clk_div_inv->construct(); + portConnect(clk_div_inv, "A", "MuxSel", makeNetIndex(i)); + portConnect(clk_div_inv, "Y", "MuxSel_b", makeNetIndex(i)); + addSubInstances(clk_div_inv, 1.0); + addElectricalSubResults(clk_div_inv, 1.0); + + getEventResult("Serialize")->addSubResult(clk_div_dff->getEventResult("CK"), clk_div_dff_name, 1.0); + getEventResult("Serialize")->addSubResult(clk_div_dff->getEventResult("DFFD"), clk_div_dff_name, 1.0); + getEventResult("Serialize")->addSubResult(clk_div_dff->getEventResult("DFFQ"), clk_div_dff_name, 1.0); + getEventResult("Serialize")->addSubResult(clk_div_inv->getEventResult("INV"), clk_div_inv_name, 1.0); + } + } + + return; + } + + void MuxTreeSerializer::propagateTransitionInfo() + { + // Get some generated properties + const unsigned int serialization_ratio = getGenProperties()->get("SerializationRatio"); + const unsigned int number_stages = getGenProperties()->get("NumberStages"); + + // Set transition info of the mux tree and clock divide DFF + if (serialization_ratio == 1) + { + // If no serialization, then just propagate input transition info to output port + propagatePortTransitionInfo("Out", "In"); + } + else + { + + // Propagate transition probabilities to the mux tree + ElectricalModel* mux_tree = (ElectricalModel*) getSubInstance("MuxTree"); + // All input ports of the mux have the same probability + for (unsigned int i = 0; i < serialization_ratio; ++i) + propagatePortTransitionInfo(mux_tree, "In" + (String) i, "In"); + // Connect last stage of the mux + propagatePortTransitionInfo(mux_tree, "Sel" + (String) (number_stages - 1), "OutCK"); + // Keep track of the last clock divider + ElectricalModel* last_clk_div_dff = NULL; + // Find P01 of OutCK + double last_P01_CK = getInputPort("OutCK")->getTransitionInfo().getNumberTransitions01(); + // Start from the last stage (since it is the stage with no clock division) + for (unsigned int i = 0; i < number_stages - 1; ++i) + { + const String& clk_div_dff_name = "ClkDivDFF_" + (String) (number_stages - i - 2); + const String& clk_div_inv_name = "ClkDivINV_" + (String) (number_stages - i - 2); + + ElectricalModel* clk_div_dff = (ElectricalModel*) getSubInstance(clk_div_dff_name); + if (last_clk_div_dff == NULL) + propagatePortTransitionInfo(clk_div_dff, "CK", "OutCK"); + else + propagatePortTransitionInfo(clk_div_dff, "CK", last_clk_div_dff, "Q"); + // Since it is a clock divider, P01 is D and Q are simply half the P01 of D and Q of + // the input clock + if (last_P01_CK != 0) clk_div_dff->getInputPort("D")->setTransitionInfo(TransitionInfo(0.0, last_P01_CK * 0.5, 0.0)); + else clk_div_dff->getInputPort("D")->setTransitionInfo(TransitionInfo(0.5, 0.0, 0.5)); + + clk_div_dff->use(); + + ElectricalModel* clk_div_inv = (ElectricalModel*) getSubInstance(clk_div_inv_name); + propagatePortTransitionInfo(clk_div_inv, "A", clk_div_dff, "Q"); + clk_div_inv->use(); + + // Connect select port of the mux + propagatePortTransitionInfo(mux_tree, "Sel" + (String) (number_stages - i - 2), clk_div_dff, "Q"); + + // Clk divide by 2; + last_P01_CK = last_P01_CK * 0.5; + // Remember the last clk div DFF + last_clk_div_dff = clk_div_dff; + } + + mux_tree->use(); + // Set output transition info to be the output transition info of the mux tree + propagatePortTransitionInfo("Out", mux_tree, "Out"); + } + + return; + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/OR.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/OR.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_ELECTRICAL_OR_H__ +#define __DSENT_MODEL_ELECTRICAL_OR_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" + +namespace DSENT +{ + /** + * \brief A class that implements a n-input OR gate + */ + class OR : public ElectricalModel + { + public: + OR(const String& instance_name_, const TechModel* tech_model_); + virtual ~OR(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + + // Clone and return a new instance + virtual OR* clone() const; + + protected: + // Build the model + virtual void constructModel(); + virtual void propagateTransitionInfo(); + + }; // class OR +} // namespace DSENT + +#endif // __DSENT_MODEL_ELECTRICAL_OR_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/OR.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/OR.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/electrical/OR.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" + +namespace DSENT +{ + using std::ceil; + using std::floor; + + OR::OR(const String& instance_name_, const TechModel* tech_model_) + : ElectricalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + OR::~OR() + {} + + void OR::initParameters() + { + addParameterName("NumberInputs"); + addParameterName("NumberBits"); + addParameterName("BitDuplicate", "TRUE"); + return; + } + + void OR::initProperties() + { + return; + } + + OR* OR::clone() const + { + // TODO + return NULL; + } + + void OR::constructModel() + { + // Get parameter + unsigned int number_inputs = getParameter("NumberInputs").toUInt(); + unsigned int number_bits = getParameter("NumberBits").toUInt(); + bool bit_duplicate = getParameter("BitDuplicate").toBool(); + + ASSERT(number_inputs > 0, "[Error] " + getInstanceName() + + " -> Number of inputs must be > 0!"); + ASSERT(number_bits > 0, "[Error] " + getInstanceName() + + " -> Number of bits must be > 0!"); + + + // Init ports + for(unsigned int i = 0; i < number_inputs; ++i) + { + createInputPort("In" + (String)i, makeNetIndex(0, number_bits-1)); + } + createOutputPort("Out", makeNetIndex(0, number_bits-1)); + + // Number of inputs on the 0 side + unsigned int or0_number_inputs = (unsigned int)ceil((double)number_inputs / 2.0); + // Number of inputs on the 1 side + unsigned int or1_number_inputs = (unsigned int)floor((double)number_inputs / 2.0); + + // Create area, power, and event results + createElectricalResults(); + createElectricalEventResult("OR"); + + getEventInfo("Idle")->setStaticTransitionInfos(); + + //Depending on whether we want to create a 1-bit instance and have it multiplied + //up by number of bits or actually instantiate number_bits of 1-bit instances. + //Recursively instantiates smaller ors + if(bit_duplicate || number_bits == 1) + { + // If it is just a 1-input or, just connect output to input + if(number_inputs == 1) + { + assign("Out", "In0"); + } + else + { + // If it is more than 1 input, instantiate two sub ors (OR_way0 and OR_way1) + // and create a final OR2 to OR them + const String& or0_name = "OR_way0"; + const String& or1_name = "OR_way1"; + const String& orf_name = "OR2_i" + (String)number_inputs; + + OR* or0 = new OR(or0_name, getTechModel()); + or0->setParameter("NumberInputs", or0_number_inputs); + or0->setParameter("NumberBits", 1); + or0->setParameter("BitDuplicate", "TRUE"); + or0->construct(); + + OR* or1 = new OR(or1_name, getTechModel()); + or1->setParameter("NumberInputs", or1_number_inputs); + or1->setParameter("NumberBits", 1); + or1->setParameter("BitDuplicate", "TRUE"); + or1->construct(); + + StdCell* orf = getTechModel()->getStdCellLib()->createStdCell("OR2", orf_name); + orf->construct(); + + // Create outputs of way0 and way1 ors with final or + createNet("way0_Out"); + createNet("way1_Out"); + portConnect(or0, "Out", "way0_Out"); + portConnect(or1, "Out", "way1_Out"); + portConnect(orf, "A", "way0_Out"); + portConnect(orf, "B", "way1_Out"); + + // Connect inputs to the sub ors. + for(unsigned int i = 0; i < or0_number_inputs; ++i) + { + createNet("way0_In" + (String)i); + portConnect(or0, "In" + (String)i, "way0_In" + (String)i); + assignVirtualFanin("way0_In" + (String)i, "In" + (String)i); + } + for(unsigned int i = 0; i < or1_number_inputs; ++i) + { + createNet("way1_In" + (String)i); + portConnect(or1, "In" + (String)i, "way1_In" + (String)i); + assignVirtualFanin("way1_In" + (String)i, "In" + (String)(i + or0_number_inputs)); + } + + // Connect outputs + createNet("OR2_Out"); + portConnect(orf, "Y", "OR2_Out"); + assignVirtualFanout("Out", "OR2_Out"); + + addSubInstances(or0, number_bits); + addElectricalSubResults(or0, number_bits); + addSubInstances(or1, number_bits); + addElectricalSubResults(or1, number_bits); + addSubInstances(orf, number_bits); + addElectricalSubResults(orf, number_bits); + + Result* or_event = getEventResult("OR"); + or_event->addSubResult(or0->getEventResult("OR"), or0_name, number_bits); + or_event->addSubResult(or1->getEventResult("OR"), or1_name, number_bits); + or_event->addSubResult(orf->getEventResult("OR2"), orf_name, number_bits); + + } + } + else + { + // Init a bunch of 1-bit ors + Result* or_event = getEventResult("OR"); + for(unsigned int n = 0; n < number_bits; ++n) + { + const String& or_name = "OR_bit" + (String)n; + + OR* ors = new OR(or_name, getTechModel()); + ors->setParameter("NumberInputs", number_inputs); + ors->setParameter("NumberBits", 1); + ors->setParameter("BitDuplicate", "TRUE"); + ors->construct(); + + for(unsigned int i = 0; i < number_inputs; ++i) + { + portConnect(ors, "In" + (String)i, "In" + (String)i, makeNetIndex(n)); + } + portConnect(ors, "Out", "Out", makeNetIndex(n)); + + addSubInstances(ors, 1.0); + addElectricalSubResults(ors, 1.0); + or_event->addSubResult(ors->getEventResult("OR"), or_name, 1.0); + } + } + return; + } + + void OR::propagateTransitionInfo() + { + // Get parameters + unsigned int number_inputs = getParameter("NumberInputs").toUInt(); + unsigned int number_bits = getParameter("NumberBits").toUInt(); + bool bit_duplicate = getParameter("BitDuplicate").toBool(); + + // Number of inputs on 0 side + unsigned int or0_number_inputs = (unsigned int)ceil((double)number_inputs / 2.0); + unsigned int or1_number_inputs = (unsigned int)floor((double)number_inputs / 2.0); + + if(bit_duplicate || number_bits == 1) + { + if(number_inputs == 1) + { + propagatePortTransitionInfo("Out", "In0"); + } + else + { + ElectricalModel* or0 = (ElectricalModel*)getSubInstance("OR_way0"); + for(unsigned int i = 0; i < or0_number_inputs; ++i) + { + propagatePortTransitionInfo(or0, "In" + (String)i, "In" + (String)i); + } + or0->use(); + + ElectricalModel* or1 = (ElectricalModel*)getSubInstance("OR_way1"); + for(unsigned int i = 0; i < or1_number_inputs; ++i) + { + propagatePortTransitionInfo(or1, "In" + (String)i, "In" + (String)i); + } + or1->use(); + + ElectricalModel* orf = (ElectricalModel*)getSubInstance("OR2_i" + (String)number_inputs); + propagatePortTransitionInfo(orf, "A", or0, "Out"); + propagatePortTransitionInfo(orf, "B", or1, "Out"); + orf->use(); + + // Set output probability + propagatePortTransitionInfo("Out", orf, "Y"); + } + } + else + { + for(unsigned int n = 0; n < number_bits; ++n) + { + ElectricalModel* or_bit = (ElectricalModel*)getSubInstance("OR_bit" + (String)n); + for(unsigned int i = 0; i < number_inputs; ++i) + { + propagatePortTransitionInfo(or_bit, "In" + (String)i, "In" + (String)i); + } + or_bit->use(); + } + + ElectricalModel* or_bit = (ElectricalModel*)getSubInstance("OR_bit0"); + propagatePortTransitionInfo("Out", or_bit, "Out"); + } + return; + } +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/RepeatedLink.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/RepeatedLink.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_ELECTRICAL_REPEATED_LINK_H__ +#define __DSENT_MODEL_ELECTRICAL_REPEATED_LINK_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" + +namespace DSENT +{ + class StdCell; + class ElectricalLoad; + class ElectricalTimingTree; + + class RepeatedLink : public ElectricalModel + { + public: + RepeatedLink(const String& instance_name_, const TechModel* tech_model_); + virtual ~RepeatedLink(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + + // Clone and return a new instance + virtual RepeatedLink* clone() const; + + protected: + // Build the model + virtual void constructModel(); + virtual void updateModel(); + virtual void useModel(); + virtual void propagateTransitionInfo(); + + private: + // Use a repeater and a load to mimic a segment of the repeated link + StdCell* m_repeater_; + ElectricalLoad* m_repeater_load_; + ElectricalTimingTree* m_timing_tree_; + }; // class RepeatedLink +} // namespace DSENT + +#endif // __DSENT_MODEL_ELECTRICAL_REPEATED_LINK_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/RepeatedLink.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/RepeatedLink.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,336 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/electrical/RepeatedLink.hh" + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingTree.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingNode.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriver.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDelay.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalLoad.hh" + +namespace DSENT +{ + RepeatedLink::RepeatedLink(const String& instance_name_, const TechModel* tech_model_) + : ElectricalModel(instance_name_, tech_model_) + { + m_repeater_ = NULL; + m_repeater_load_ = NULL; + m_timing_tree_ = NULL; + + initParameters(); + initProperties(); + } + + RepeatedLink::~RepeatedLink() + { + delete m_repeater_; + delete m_repeater_load_; + delete m_timing_tree_; + } + + void RepeatedLink::initParameters() + { + addParameterName("NumberBits"); + addParameterName("WireLayer"); + addParameterName("WireWidthMultiplier", 1.0); + addParameterName("WireSpacingMultiplier", 1.0); + return; + } + + void RepeatedLink::initProperties() + { + addPropertyName("WireLength"); + addPropertyName("Delay"); + addPropertyName("IsKeepParity", "TRUE"); + return; + } + + RepeatedLink* RepeatedLink::clone() const + { + // TODO + return NULL; + } + + void RepeatedLink::constructModel() + { + // Get parameters + unsigned int number_bits = getParameter("NumberBits").toUInt(); + const String& wire_layer = getParameter("WireLayer"); + double wire_width_multiplier = getParameter("WireWidthMultiplier").toDouble(); + double wire_spacing_multiplier = getParameter("WireSpacingMultiplier").toDouble(); + + ASSERT(number_bits > 0, "[Error] " + getInstanceName() + + " -> Number of bits must be > 0!"); + ASSERT(getTechModel()->isWireLayerExist(wire_layer), "[Error] " + getInstanceName() + + " -> Wire layer does not exist!"); + ASSERT(wire_width_multiplier >= 1.0, "[Error] " + getInstanceName() + + " -> Wire width multiplier must be >= 1.0!"); + ASSERT(wire_spacing_multiplier >= 1.0, "[Error] " + getInstanceName() + + " -> Wire spacing multiplier must be >= 1.0!"); + + double wire_min_width = getTechModel()->get("Wire->" + wire_layer + "->MinWidth").toDouble(); + double wire_min_spacing = getTechModel()->get("Wire->" + wire_layer + "->MinSpacing").toDouble(); + + double wire_width = wire_min_width * wire_width_multiplier; + double wire_spacing = wire_min_spacing * wire_spacing_multiplier; + + double wire_cap_per_len = getTechModel()->calculateWireCapacitance(wire_layer, wire_width, wire_spacing, 1.0); + double wire_res_per_len = getTechModel()->calculateWireResistance(wire_layer, wire_width, 1.0); + + getGenProperties()->set("WireWidth", wire_width); + getGenProperties()->set("WireSpacing", wire_spacing); + getGenProperties()->set("WireCapacitancePerLength", wire_cap_per_len); + getGenProperties()->set("WireResistancePerLength", wire_res_per_len); + + // Create ports + createInputPort("In", makeNetIndex(0, number_bits-1)); + createOutputPort("Out", makeNetIndex(0, number_bits-1)); + + // Create area, power, and event results + createElectricalAtomicResults(); + createElectricalEventAtomicResult("Send"); + + // Create connections + // Since the length is not set yet, we only to virtual fan-in and virtual fan-out + createNet("InTmp"); + createNet("OutTmp"); + assignVirtualFanin("InTmp", "In"); + assignVirtualFanout("Out", "OutTmp"); + + // Build Electrical Connectivity + createLoad("In_Cap"); + createDelay("In_to_Out_delay"); + createDriver("Out_Ron", false); // Indicate this driver is not sizable + + ElectricalLoad* in_cap = getLoad("In_Cap"); + ElectricalDelay* in_to_out_delay = getDelay("In_to_Out_delay"); + ElectricalDriver* out_ron = getDriver("Out_Ron"); + + getNet("InTmp")->addDownstreamNode(in_cap); + in_cap->addDownstreamNode(in_to_out_delay); + in_to_out_delay->addDownstreamNode(out_ron); + out_ron->addDownstreamNode(getNet("OutTmp")); + + // Init a repeater and a load to mimic a segment of a repeated link + m_repeater_ = getTechModel()->getStdCellLib()->createStdCell("INV", "Repeater"); + m_repeater_->construct(); + m_repeater_load_ = new ElectricalLoad("RepeaterIn_Cap", this); + // Make path repeater_ -> repeater_load_ + // to catch the repeater's input/output cap and ensure only one inverter delay + // is added + m_repeater_->getNet("Y")->addDownstreamNode(m_repeater_load_); + // Init a timing object to calculate delay + m_timing_tree_ = new ElectricalTimingTree("RepeatedLink", this); + m_timing_tree_->performCritPathExtract(m_repeater_->getNet("A")); + return; + } + + void RepeatedLink::updateModel() + { + unsigned int number_bits = getParameter("NumberBits").toUInt(); + + // Get properties + double wire_length = getProperty("WireLength").toDouble(); + double required_delay = getProperty("Delay").toDouble(); + bool isKeepParity = getProperty("IsKeepParity").toBool(); + + ASSERT(wire_length >= 0, "[Error] " + getInstanceName() + + " -> Wire length must be >= 0!"); + ASSERT(required_delay >= 0, "[Error] " + getInstanceName() + + " -> Required delay must be >= 0!"); + + const String& wire_layer = getParameter("WireLayer"); + double wire_width = getGenProperties()->get("WireWidth").toDouble(); + double wire_spacing = getGenProperties()->get("WireSpacing").toDouble(); + + // Calculate the total wire cap and total wire res + double wire_cap_per_len = getGenProperties()->get("WireCapacitancePerLength").toDouble(); + double wire_res_per_len = getGenProperties()->get("WireResistancePerLength").toDouble(); + double total_wire_cap = wire_cap_per_len * wire_length; + double total_wire_res = wire_res_per_len * wire_length; + + m_repeater_->update(); + + unsigned int increment_segments = (isKeepParity)? 2:1; + unsigned int number_segments = increment_segments; + double delay; + m_repeater_->setMinDrivingStrength(); + m_repeater_->getNet("Y")->setDistributedCap(total_wire_cap / number_segments); + m_repeater_->getNet("Y")->setDistributedRes(total_wire_res / number_segments); + m_repeater_load_->setLoadCap(m_repeater_->getNet("A")->getTotalDownstreamCap()); + m_timing_tree_->performCritPathExtract(m_repeater_->getNet("A")); + delay = m_timing_tree_->calculateCritPathDelay(m_repeater_->getNet("A")) * number_segments; + + // If everything is 0, use number_segments min-sized repeater + if(wire_length != 0) + { + // Set the initial number of segments based on isKeepParity + double last_min_size_delay = 0; + unsigned int iteration = 0; + + // First set the repeater to the minimum driving strength + last_min_size_delay = delay; + + Log::printLine(getInstanceName() + " -> Beginning Repeater Insertion"); + + while(required_delay < delay) + { + Log::printLine(getInstanceName() + " -> Repeater Insertion Iteration " + (String)iteration + + ": Required delay = " + (String)required_delay + + ", Delay = " + (String)delay + + ", Slack = " + (String)(required_delay - delay) + + ", Number of repeaters = " + (String)number_segments); + + // Size up if timing is not met + while(required_delay < delay) + { + if(m_repeater_->hasMaxDrivingStrength()) + { + break; + } + m_repeater_->increaseDrivingStrength(); + m_repeater_load_->setLoadCap(m_repeater_->getNet("A")->getTotalDownstreamCap()); + m_timing_tree_->performCritPathExtract(m_repeater_->getNet("A")); + delay = m_timing_tree_->calculateCritPathDelay(m_repeater_->getNet("A")) * number_segments; + + iteration++; + Log::printLine(getInstanceName() + " -> Slack: " + (String)(required_delay - delay)); + } + // Increase number of segments if timing is not met + if(required_delay < delay) + { + number_segments += increment_segments; + m_repeater_->setMinDrivingStrength(); + m_repeater_->getNet("Y")->setDistributedCap(total_wire_cap / number_segments); + m_repeater_->getNet("Y")->setDistributedRes(total_wire_res / number_segments); + m_repeater_load_->setLoadCap(m_repeater_->getNet("A")->getTotalDownstreamCap()); + m_timing_tree_->performCritPathExtract(m_repeater_->getNet("A")); + delay = m_timing_tree_->calculateCritPathDelay(m_repeater_->getNet("A")) * number_segments; + + // Abort if adding more min sized repeaters does not decrease the delay + if(delay > last_min_size_delay) + { + break; + } + last_min_size_delay = delay; + } + } + Log::printLine(getInstanceName() + " -> Repeater Insertion Ended after Iteration: " + (String)iteration + + ": Required delay = " + (String)required_delay + + ", Delay = " + (String)delay + + ", Slack = " + (String)(required_delay - delay) + + ", Number of repeaters = " + (String)number_segments); + + // Print a warning if the timing is not met + if(required_delay < delay) + { + const String& warning_msg = "[Warning] " + getInstanceName() + " -> Timing not met" + + ": Required delay = " + (String)required_delay + + ", Delay = " + (String)delay + + ", Slack = " + (String)(required_delay - delay) + + ", Number of repeaters = " + (String)number_segments; + Log::printLine(std::cerr, warning_msg); + } + } + + // Update electrical interfaces + getLoad("In_Cap")->setLoadCap(m_repeater_->getNet("A")->getTotalDownstreamCap()); + getDelay("In_to_Out_delay")->setDelay(delay); + getDriver("Out_Ron")->setOutputRes(m_repeater_->getDriver("Y_Ron")->getOutputRes() + (total_wire_res / number_segments)); + + getGenProperties()->set("NumberSegments", number_segments); + + // Update area, power results + resetElectricalAtomicResults(); + addElecticalAtomicResultValues(m_repeater_, number_segments * number_bits); + double wire_area = wire_length * (wire_width + wire_spacing) * number_bits; + addElecticalWireAtomicResultValue(wire_layer, wire_area); + + return; + } + + void RepeatedLink::useModel() + { + // Update the transition information for the modeled repeater + // Since we only modeled one repeater. So the transition information for 0->0 and 1->1 + // is averaged out + const TransitionInfo& trans_In = getInputPort("In")->getTransitionInfo(); + double average_static_transition = (trans_In.getNumberTransitions00() + trans_In.getNumberTransitions11()) / 2.0; + TransitionInfo mod_trans_In(average_static_transition, trans_In.getNumberTransitions01(), average_static_transition); + m_repeater_->getInputPort("A")->setTransitionInfo(mod_trans_In); + m_repeater_->use(); + + // Get parameters + unsigned int number_bits = getParameter("NumberBits").toUInt(); + unsigned int number_segments = getGenProperties()->get("NumberSegments").toUInt(); + + // Propagate the transition information + propagateTransitionInfo(); + + // Update leakage power + double power = 0.0; + power += m_repeater_->getNddPowerResult("Leakage")->calculateSum() * number_segments * number_bits; + getNddPowerResult("Leakage")->setValue(power); + + // Update event result + double energy = 0.0; + energy += m_repeater_->getEventResult("INV")->calculateSum() * number_segments * number_bits; + getEventResult("Send")->setValue(energy); + + return; + } + + void RepeatedLink::propagateTransitionInfo() + { + unsigned int number_segments = getGenProperties()->get("NumberSegments"); + + if((number_segments % 2) == 0) + { + propagatePortTransitionInfo("Out", "In"); + } + else + { + const TransitionInfo& trans_In = getInputPort("In")->getTransitionInfo(); + TransitionInfo trans_Out(trans_In.getNumberTransitions11(), trans_In.getNumberTransitions01(), trans_In.getNumberTransitions00()); + getOutputPort("Out")->setTransitionInfo(trans_Out); + } + return; + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/RippleAdder.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/RippleAdder.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_ELECTRICAL_RIPPLE_ADDER_H__ +#define __DSENT_MODEL_ELECTRICAL_RIPPLE_ADDER_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" + +namespace DSENT +{ + class RippleAdder : public ElectricalModel + { + public: + RippleAdder(const String& instance_name_, const TechModel* tech_model_); + virtual ~RippleAdder(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + + protected: + // Build the model + virtual void constructModel(); + virtual void propagateTransitionInfo(); + + }; // class RippleAdder +} // namespace DSENT + +#endif // __DSENT_MODEL_ELECTRICAL_TESTMODEL_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/RippleAdder.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/RippleAdder.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/electrical/RippleAdder.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" + +namespace DSENT +{ + RippleAdder::RippleAdder(const String& instance_name_, const TechModel* tech_model_) + : ElectricalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + RippleAdder::~RippleAdder() + {} + + void RippleAdder::initParameters() + { + addParameterName("NumberBits"); + return; + } + + void RippleAdder::initProperties() + { + return; + } + + void RippleAdder::constructModel() + { + // Get properties + unsigned int number_bits = (unsigned int) getParameter("NumberBits"); + + //Construct electrical ports and nets + createInputPort("CI"); + createOutputPort("CO"); + for(unsigned int i = 0; i < number_bits; ++i) + { + createInputPort("A" + String(i)); + createInputPort("B" + String(i)); + createOutputPort("S" + String(i)); + createNet("C" + String(i)); + } + createNet("C" + String(number_bits)); + + //Create energy, power, and area results + createElectricalResults(); + getEventInfo("Idle")->setStaticTransitionInfos(); + createElectricalEventResult("Add"); + Result* add_event = getEventResult("Add"); + + // Connect all nets + assign("C0", "CI"); + assign("CO", "C" + String(number_bits)); + for (unsigned int i = 0; i < number_bits; ++i) + { + String n = (String) i; + StdCell* adder = getTechModel()->getStdCellLib()->createStdCell("ADDF", "ADDF_" + n); + adder->construct(); + + //Build electrical connectivity + portConnect(adder, "A", "A" + String(i)); + portConnect(adder, "B", "B" + String(i)); + portConnect(adder, "CI", "C" + String(i)); + portConnect(adder, "S", "S" + String(i)); + portConnect(adder, "CO", "C" + String(i + 1)); + + //Add ADDF instance, leakage power, energy, and add event results + addSubInstances(adder, 1.0); + addElectricalSubResults(adder, 1.0); + add_event->addSubResult(adder->getEventResult("ADDF"), "ADDF_" + n, 1.0); + } + + return; + } + + void RippleAdder::propagateTransitionInfo() + { + unsigned int number_bits = getParameter("NumberBits").toUInt(); + + TransitionInfo current_trans_CI = getInputPort("CI")->getTransitionInfo(); + for(unsigned int i = 0; i < number_bits; ++i) + { + ElectricalModel* adder = (ElectricalModel*)getSubInstance("ADDF_" + String(i)); + + // Propagate input transition info + propagatePortTransitionInfo(adder, "A", "A" + String(i)); + propagatePortTransitionInfo(adder, "B", "B" + String(i)); + assignPortTransitionInfo(adder, "CI", current_trans_CI); + adder->use(); + + // Assign output transition info + propagatePortTransitionInfo("S" + String(i), adder, "S"); + current_trans_CI = adder->getOutputPort("CO")->getTransitionInfo(); + } + getOutputPort("CO")->setTransitionInfo(current_trans_CI); + return; + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/SConscript --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/SConscript Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,47 @@ +# 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. +# +# Authors: Chia-Hsin Owen Chen + +Import('*') + +if env['PROTOCOL'] == 'None': + Return() + +Source('RippleAdder.cc') +Source('BarrelShifter.cc') +Source('SeparableAllocator.cc') +Source('DFFRAM.cc') +Source('TestModel.cc') +Source('Decoder.cc') +Source('DemuxTreeDeserializer.cc') +Source('RepeatedLink.cc') +Source('MultiplexerCrossbar.cc') +Source('Multiplexer.cc') +Source('MatrixArbiter.cc') +Source('OR.cc') +Source('MuxTreeSerializer.cc') +Source('BroadcastHTree.cc') + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/SeparableAllocator.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/SeparableAllocator.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_ELECTRICAL_SEPARABLE_ALLOCATOR_H__ +#define __DSENT_MODEL_ELECTRICAL_SEPARABLE_ALLOCATOR_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" + +namespace DSENT +{ + class SeparableAllocator : public ElectricalModel + { + public: + SeparableAllocator(const String& instance_name_, const TechModel* tech_model_); + virtual ~SeparableAllocator(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + + // Clone and return a new instance + virtual SeparableAllocator* clone() const; + + protected: + // Build the model + virtual void constructModel(); + virtual void updateModel(); + + }; // class SeparableAllocator +} // namespace DSENT + +#endif // __DSENT_MODEL_ELECTRICAL_SEPARABLE_ALLOCATOR_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/SeparableAllocator.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/SeparableAllocator.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/electrical/SeparableAllocator.hh" + +#include "mem/ruby/network/dsent/dsent-core/model/ModelGen.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" + +namespace DSENT +{ + SeparableAllocator::SeparableAllocator(const String& instance_name_, const TechModel* tech_model_) + : ElectricalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + SeparableAllocator::~SeparableAllocator() + {} + + void SeparableAllocator::initParameters() + { + addParameterName("NumberRequesters"); + addParameterName("NumberResources"); + addParameterName("IsRequesterFirst", true); + addParameterName("Stage1->ArbiterModel"); + addParameterName("Stage2->ArbiterModel"); + return; + } + + void SeparableAllocator::initProperties() + { + addPropertyName("P(Request)"); + addPropertyName("Act(Request)"); + addPropertyName("P(CK)"); + addPropertyName("Act(CK)"); + return; + } + + SeparableAllocator* SeparableAllocator::clone() const + { + // TODO + return NULL; + } + + void SeparableAllocator::constructModel() + { + // Get parameters + unsigned int number_requesters = getParameter("NumberRequesters").toUInt(); + unsigned int number_resources = getParameter("NumberResources").toUInt(); + bool is_requester_first = getParameter("IsRequesterFirst").toBool(); + const String& stage1_arbiter_model = getParameter("Stage1->ArbiterModel"); + const String& stage2_arbiter_model = getParameter("Stage2->ArbiterModel"); + + ASSERT(number_requesters > 0, "[Error] " + getInstanceName() + + " -> Number of requesters must be > 0!"); + ASSERT(number_resources > 0, "[Error] " + getInstanceName() + + " -> Number of resources must be > 0!"); + + // Create area, power, and event results + createElectricalResults(); + addEventResult(new Result("Allocate")); + + // Create ports + createInputPort("CK"); + for(unsigned int i = 0; i < number_requesters; ++i) + { + createInputPort("Request" + (String)i, makeNetIndex(0, number_resources-1)); + createOutputPort("Grant" + (String)i, makeNetIndex(0, number_resources-1)); + } + + // If is_requester_first is set, requests from the same requester will be arbitrate + // on stage 1 + if(is_requester_first) + { + // Init stage 1 arbiters + for(unsigned int i = 0; i < number_requesters; ++i) + { + ElectricalModel* arb = (ElectricalModel*)ModelGen::createModel(stage1_arbiter_model, "Stage1Arb" + (String)i, getTechModel()); + arb->setParameter("NumberRequests", number_resources); + arb->construct(); + + addSubInstances(arb, 1.0); + addElectricalSubResults(arb, 1.0); + + getEventResult("Allocate")->addSubResult(arb->getEventResult("Arbitrate"), arb->getInstanceName(), 1.0); + + createNet("Stage1Arb_In" + (String)i, makeNetIndex(0, number_resources-1)); + createNet("Stage1Arb_Out" + (String)i, makeNetIndex(0, number_resources-1)); + + portConnect(arb, "CK", "CK"); + assign("Stage1Arb_In" + (String)i, "Request" + (String)i); + for(unsigned int j = 0; j < number_resources; ++j) + { + portConnect(arb, "Request" + (String)j, "Stage1Arb_In" + (String)i, makeNetIndex(j)); + portConnect(arb, "Grant" + (String)j, "Stage1Arb_Out" + (String)i, makeNetIndex(j)); + } + } + + // Init stage 2 arbiters + for(unsigned int i = 0; i < number_resources; ++i) + { + ElectricalModel* arb = (ElectricalModel*)ModelGen::createModel(stage2_arbiter_model, "Stage2Arb" + (String)i, getTechModel()); + arb->setParameter("NumberRequests", number_requesters); + arb->construct(); + + addSubInstances(arb, 1.0); + addElectricalSubResults(arb, 1.0); + + getEventResult("Allocate")->addSubResult(arb->getEventResult("Arbitrate"), arb->getInstanceName(), 1.0); + + createNet("Stage2Arb_In" + (String)i, makeNetIndex(0, number_requesters-1)); + createNet("Stage2Arb_Out" + (String)i, makeNetIndex(0, number_requesters-1)); + + portConnect(arb, "CK", "CK"); + for(unsigned int j = 0; j < number_requesters; ++j) + { + assign("Stage2Arb_In" + (String)i, makeNetIndex(j), "Stage1Arb_Out" + (String)j, makeNetIndex(i)); + portConnect(arb, "Request" + (String)j, "Stage2Arb_In" + (String)i, makeNetIndex(j)); + portConnect(arb, "Grant" + (String)j, "Stage2Arb_Out" + (String)i, makeNetIndex(j)); + assign("Grant" + (String)j, makeNetIndex(i), "Stage2Arb_Out" + (String)i, makeNetIndex(j)); + } + } + } + else + { + // Init stage 1 arbiters + for(unsigned int i = 0; i < number_resources; ++i) + { + ElectricalModel* arb = (ElectricalModel*)ModelGen::createModel(stage1_arbiter_model, "Stage1Arb" + (String)i, getTechModel()); + arb->setParameter("NumberRequests", number_requesters); + arb->construct(); + + addSubInstances(arb, 1.0); + addElectricalSubResults(arb, 1.0); + + getEventResult("Allocate")->addSubResult(arb->getEventResult("Arbitrate"), arb->getInstanceName(), 1.0); + + createNet("Stage1Arb_In" + (String)i, makeNetIndex(0, number_requesters-1)); + createNet("Stage1Arb_Out" + (String)i, makeNetIndex(0, number_requesters-1)); + + portConnect(arb, "CK", "CK"); + for(unsigned int j = 0; j < number_requesters; ++j) + { + assign("Stage1Arb_In" + (String)i, makeNetIndex(j), "Request" + (String)j, makeNetIndex(i)); + portConnect(arb, "Request" + (String)j, "Stage1Arb_In" + (String)i, makeNetIndex(j)); + portConnect(arb, "Grant" + (String)j, "Stage1Arb_Out" + (String)i, makeNetIndex(j)); + } + } + + // Init stage 2 arbiters + for(unsigned int i = 0; i < number_requesters; ++i) + { + ElectricalModel* arb = (ElectricalModel*)ModelGen::createModel(stage2_arbiter_model, "Stage2Arb" + (String)i, getTechModel()); + arb->setParameter("NumberRequests", number_requesters); + arb->construct(); + + addSubInstances(arb, 1.0); + addElectricalSubResults(arb, 1.0); + + getEventResult("Allocate")->addSubResult(arb->getEventResult("Arbitrate"), arb->getInstanceName(), 1.0); + + createNet("Stage2Arb_In" + (String)i, makeNetIndex(0, number_resources-1)); + createNet("Stage2Arb_Out" + (String)i, makeNetIndex(0, number_resources-1)); + + portConnect(arb, "CK", "CK"); + for(unsigned int j = 0; j < number_resources; ++j) + { + assign("Stage2Arb_In" + (String)i, makeNetIndex(j), "Stage1Arb_Out" + (String)j, makeNetIndex(i)); + portConnect(arb, "Request" + (String)j, "Stage2Arb_In", makeNetIndex(j)); + portConnect(arb, "Grant" + (String)j, "Stage2Arb_Out", makeNetIndex(j)); + } + assign("Grant" + (String)i, "Stage2Arb_Out" + (String)i); + } + } + return; + } + + void SeparableAllocator::updateModel() + { + // Get parameters + unsigned int number_requesters = getParameter("NumberRequesters").toUInt(); + unsigned int number_resources = getParameter("NumberResources").toUInt(); + bool is_requester_first = getParameter("IsRequesterFirst").toBool(); + + // Get probabilities from inputs + const String& P_request = getProperty("P(Request)"); + const String& act_request = getProperty("Act(Request)"); + const String& P_CK = getProperty("P(CK)"); + const String& act_CK = getProperty("Act(CK)"); + + const vector& P_request_vector = LibUtil::castStringVector(P_request.split("[,]")); + const vector& act_request_vector = LibUtil::castStringVector(act_request.split("[,]")); + + ASSERT(P_request_vector.size() == (number_requesters * number_resources), "[Error] " + getInstanceName() + + " -> Expecting " + (String)(number_requesters * number_resources) + + " request probabilities, but got " + P_request); + ASSERT(act_request_vector.size() == (number_requesters * number_resources), "[Error] " + getInstanceName() + + " -> Expecting " + (String)(number_requesters * number_resources) + + " request actvities multiplier, but got " + act_request); + + vector P_int_request_vector(number_requesters * number_resources, 0.0); + vector act_int_request_vector(number_requesters * number_resources, 0.0); + vector P_out_request_vector(number_requesters * number_resources, 0.0); + vector act_out_request_vector(number_requesters * number_resources, 0.0); + if(is_requester_first) + { + // Update stage1 arbiter + for(unsigned int i = 0; i < number_requesters; ++i) + { + vector P_arb_request_vector(number_resources, 0.0); + vector act_arb_request_vector(number_resources, 0.0); + for(unsigned int j = 0; j < number_resources; ++j) + { + P_arb_request_vector[j] = P_request_vector[i * number_resources + j]; + act_arb_request_vector[j] = act_request_vector[i * number_resources + j]; + } + + Model* arb = getSubInstance("Stage1Arb" + (String)i); + arb->setProperty("P(Request)", LibUtil::vectorToString(P_arb_request_vector)); + arb->setProperty("Act(Request)", LibUtil::vectorToString(act_arb_request_vector)); + arb->setProperty("P(CK)", P_CK); + arb->setProperty("Act(CK)", act_CK); + arb->update(); + + const vector& P_arb_out_request_vector = LibUtil::castStringVector(arb->getGenProperties()->get("P(Grant)").split("[,]")); + const vector& act_arb_out_request_vector = LibUtil::castStringVector(arb->getGenProperties()->get("Act(Grant)").split("[,]")); + for(unsigned int j = 0; j < number_resources; ++j) + { + P_int_request_vector[i * number_resources + j] = P_arb_out_request_vector[j]; + act_int_request_vector[i * number_resources + j] = act_arb_out_request_vector[j]; + } + } + // Update stage2 arbiter + for(unsigned int i = 0; i < number_resources; ++i) + { + vector P_arb_request_vector(number_requesters, 0.0); + vector act_arb_request_vector(number_requesters, 0.0); + for(unsigned int j = 0; j < number_requesters; ++j) + { + P_arb_request_vector[j] = P_int_request_vector[j * number_resources + i]; + act_arb_request_vector[j] = act_int_request_vector[j * number_resources + i]; + } + + Model* arb = getSubInstance("Stage2Arb" + (String)i); + arb->setProperty("P(Request)", LibUtil::vectorToString(P_arb_request_vector)); + arb->setProperty("Act(Request)", LibUtil::vectorToString(act_arb_request_vector)); + arb->setProperty("P(CK)", P_CK); + arb->setProperty("Act(CK)", act_CK); + arb->update(); + + const vector& P_arb_out_request_vector = LibUtil::castStringVector(arb->getGenProperties()->get("P(Grant)").split("[,]")); + const vector& act_arb_out_request_vector = LibUtil::castStringVector(arb->getGenProperties()->get("Act(Grant)").split("[,]")); + for(unsigned int j = 0; j < number_requesters; ++j) + { + P_out_request_vector[j * number_resources + i] = P_arb_out_request_vector[j]; + act_out_request_vector[j * number_resources + i] = act_arb_out_request_vector[j]; + } + } + } + else + { + + } + + // Update output probabilities + getGenProperties()->set("P(Grant)", LibUtil::vectorToString(P_out_request_vector)); + getGenProperties()->set("Act(Grant)", LibUtil::vectorToString(act_out_request_vector)); + + return; + } +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/TestModel.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/TestModel.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_ELECTRICAL_TESTMODEL_H__ +#define __DSENT_MODEL_ELECTRICAL_TESTMODEL_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" + +namespace DSENT +{ + class TestModel : public ElectricalModel + { + public: + TestModel(const String& instance_name_, const TechModel* tech_model_); + virtual ~TestModel(); + + public: + // Set a list of properties' name needed to construct model + void initProperties(); + + // Clone and return a new instance + virtual TestModel* clone() const; + + protected: + // Build the model + void constructModel(); + void updateModel(); + void evaluateModel(); + + }; // class TestModel +} // namespace DSENT + +#endif // __DSENT_MODEL_ELECTRICAL_TESTMODEL_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/TestModel.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/TestModel.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/electrical/TestModel.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" +#include "mem/ruby/network/dsent/dsent-core/model/electrical/RippleAdder.hh" +#include "mem/ruby/network/dsent/dsent-core/model/electrical/Multiplexer.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriver.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalLoad.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingTree.hh" + +namespace DSENT +{ + TestModel::TestModel(const String& instance_name_, const TechModel* tech_model_) + : ElectricalModel(instance_name_, tech_model_) + { + initProperties(); + } + + TestModel::~TestModel() + {} + + void TestModel::initProperties() + { + return; + } + + TestModel* TestModel::clone() const + { + return NULL; + } + + void TestModel::constructModel() + { + unsigned int num_bits = 64; + unsigned int mux_bits = 1; + + // Create the instance + createNet("CK"); + createNet("CI"); + getNet("CI")->setDistributedCap(100e-15); + getNet("CI")->setDistributedRes(10); + createNet("CO"); + createNet("A", makeNetIndex(0, num_bits - 1)); + createNet("B", makeNetIndex(0, num_bits - 1)); + createNet("S", makeNetIndex(0, num_bits - 1)); + + StdCell* ci_reg = getTechModel()->getStdCellLib()->createStdCell("DFFQ", "DFFQ-CI"); + ci_reg->setProperty("P(D)", 0.5); + ci_reg->setProperty("P(CK)", 0.5); + ci_reg->construct(); + portConnect(ci_reg, "Q", "CI"); + portConnect(ci_reg, "CK", "CK"); + //ci_reg->connect("Q", getNet("CI")); + //ci_reg->connect("CK", getNet("CK")); + addSubInstances(ci_reg, 1.0); + + StdCell* co_reg = getTechModel()->getStdCellLib()->createStdCell("DFFQ", "DFFQ-CO"); + co_reg->setProperty("P(D)", 0.5); + co_reg->setProperty("P(CK)", 0.5); + co_reg->construct(); + portConnect(co_reg, "D", "CO"); + portConnect(co_reg, "CK", "CK"); + //co_reg->connect("D", getNet("CO")); + //co_reg->connect("CK", getNet("CK")); + addSubInstances(co_reg, 1.0); + + for (unsigned int i = 0; i < num_bits; i++) + { + StdCell* a_reg = getTechModel()->getStdCellLib()->createStdCell("DFFQ", "DFFQ-A[" + (String) i + "]"); + a_reg->setProperty("P(D)", 0.5); + a_reg->setProperty("P(CK)", 0.5); + a_reg->construct(); + portConnect(a_reg, "Q", "A", makeNetIndex(i)); + portConnect(a_reg, "CK", "CK"); + //a_reg->connect("Q", getNet("A[" + (String) i + "]")); + //a_reg->connect("CK", getNet("CK")); + addSubInstances(a_reg, 1.0); + + StdCell* b_reg = getTechModel()->getStdCellLib()->createStdCell("DFFQ", "DFFQ-B[" + (String) i + "]"); + b_reg->setProperty("P(D)", 0.5); + b_reg->setProperty("P(CK)", 0.5); + b_reg->construct(); + portConnect(b_reg, "Q", "B", makeNetIndex(i)); + portConnect(b_reg, "CK", "CK"); + //b_reg->connect("Q", getNet("B[" + (String) i + "]")); + //b_reg->connect("CK", getNet("CK")); + addSubInstances(b_reg, 1.0); + + StdCell* s_reg = getTechModel()->getStdCellLib()->createStdCell("DFFQ", "DFFQ-S[" + (String) i + "]"); + s_reg->setProperty("P(D)", 0.5); + s_reg->setProperty("P(CK)", 0.5); + s_reg->construct(); + portConnect(s_reg, "D", "S", makeNetIndex(i)); + portConnect(s_reg, "CK", "CK"); + //s_reg->connect("D", getNet("A[" + (String) i + "]")); + //s_reg->connect("CK", getNet("CK")); + addSubInstances(s_reg, 1.0); + } + + + //Create some adders! + + ElectricalModel* ripple_adder = new RippleAdder("Adder_1", getTechModel()); + ripple_adder->setParameter("NumberBits", num_bits); + ripple_adder->setProperty("P(A)", 0.5); + ripple_adder->setProperty("P(B)", 0.5); + ripple_adder->setProperty("P(CI)", 0.5); + + ripple_adder->construct(); + addSubInstances(ripple_adder, 1.0); + portConnect(ripple_adder, "CI", "CI"); + portConnect(ripple_adder, "CO", "CO"); + portConnect(ripple_adder, "A", "A"); + portConnect(ripple_adder, "B", "B"); + portConnect(ripple_adder, "S", "S"); + + ElectricalModel* multiplexer = new Multiplexer("Mux_1", getTechModel()); + multiplexer->setParameter("NumberInputs", 2); + multiplexer->setParameter("NumberBits", mux_bits); + multiplexer->setParameter("BitDuplicate", "FALSE"); + //multiplexer->setProperty("P(In)", "[0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5]"); + //multiplexer->setProperty("P(Sel)", "[0.5, 0.5, 0.5]"); + //multiplexer->setProperty("Act(In)", "[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]"); + //multiplexer->setProperty("Act(Sel)", "[2.0, 4.0, 8.0]"); + multiplexer->setProperty("P(In)", "[0.5, 0.5]"); + multiplexer->setProperty("P(Sel)", "[0.5]"); + multiplexer->setProperty("Act(In)", "[1.0, 1.0]"); + multiplexer->setProperty("Act(Sel)", "[1.0]"); + multiplexer->construct(); + + createNet("In0", makeNetIndex(0, mux_bits-1)); + createNet("In1", makeNetIndex(0, mux_bits-1)); + createNet("In2", makeNetIndex(0, mux_bits-1)); + createNet("In3", makeNetIndex(0, mux_bits-1)); + createNet("In4", makeNetIndex(0, mux_bits-1)); + createNet("Out", makeNetIndex(0, mux_bits-1)); + + portConnect(multiplexer, "In0", "In0"); + portConnect(multiplexer, "In1", "In1"); + //portConnect(multiplexer, "In2", "In2"); + //portConnect(multiplexer, "In3", "In3"); + //portConnect(multiplexer, "In4", "In4"); + portConnect(multiplexer, "Out", "Out"); + + for (unsigned int i = 0; i < mux_bits; ++i) + { + String n = (String) i; + + createLoad("OutLoad[" + n + "]"); + getLoad("OutLoad[" + n + "]")->setLoadCap(100e-15); + + getNet("Out", makeNetIndex(i))->addDownstreamNode(getLoad("OutLoad[" + n + "]")); + } + createNet("Sel", makeNetIndex(0, 2)); + assign("Sel", makeNetIndex(0), "CK"); + assign("Sel", makeNetIndex(1), "CK"); + assign("Sel", makeNetIndex(2), "CK"); + + //portConnect(multiplexer, "Sel", "Sel"); + + addSubInstances(multiplexer, 1.0); + + //ElectricalTimingAbstract* abstract = new ElectricalTimingAbstract("HAHAHA", getTechModel(), ripple_adder); + //abstract->buildAbstract(); + + return; + } + + void TestModel::updateModel() + { + Model::updateModel(); + + //ElectricalTimingTree* t = new ElectricalTimingTree("Add", this); + //t->performTimingOpt(getNet("CK"), 4.21300e-8); + //t->performTimingOpt(getNet("CK"), 1e-9); + //delete t; + + ElectricalTimingTree* t2 = new ElectricalTimingTree("Mux", this); + t2->performTimingOpt(getNet("In1", makeNetIndex(0)), 500e-12); + delete t2; + + + } + + void TestModel::evaluateModel() + { + Model::evaluateModel(); + + //ripple_adder->getNddPowerResult("LeakagePower")->print("RippleAdder->Leakage", 10, cout); + getSubInstance("Adder_1")->getNddPowerResult("Leakage")->print("RippleAdder->Leakage", 0, cout); + //ripple_adder->getAreaResult("TotalArea")->print("RippleAdder->TotalArea", 10, cout); + getSubInstance("Adder_1")->getAreaResult("Active")->print("RippleAdder->ActiveArea", 0, cout); + //ripple_adder->getEventResult("AddEvent")->print("RippleAdder->AddEvent", 10, cout); + getSubInstance("Adder_1")->getEventResult("Add")->print("RippleAdder->Add", 0, cout); + + getSubInstance("Mux_1")->getNddPowerResult("Leakage")->print("Multiplexer->Leakage", 0, cout); + getSubInstance("Mux_1")->getAreaResult("Active")->print("Multiplexer->ActiveArea", 0, cout); + getSubInstance("Mux_1")->getEventResult("Mux")->print("Multiplexer->MuxEvent", 0, cout); + cout << "Multiplexer->P(Out) = " << getSubInstance("Mux_1")->getGenProperties()->get("P(Out)") << endl; + + getSubInstance("DFFQ-CI")->getNddPowerResult("Leakage")->print("DFFQ-CI->Leakage", 0, cout); + getSubInstance("DFFQ-CI")->getAreaResult("Active")->print("DFFQ-CI->ActiveArea", 0, cout); + getSubInstance("DFFQ-CI")->getEventResult("DFF")->print("DFFQ-CI->DFF", 0, cout); + getSubInstance("DFFQ-CI")->getEventResult("CK")->print("DFFQ-CI->CK", 0, cout); + + //ripple_adder->getNddPowerResult("LeakagePower")->print("RippleAdder->Leakage", 10, cout); + getSubInstance("Adder_1")->getNddPowerResult("Leakage")->print("RippleAdder->Leakage", 0, cout); + //ripple_adder->getAreaResult("TotalArea")->print("RippleAdder->TotalArea", 10, cout); + getSubInstance("Adder_1")->getAreaResult("Active")->print("RippleAdder->ActiveArea", 0, cout); + //ripple_adder->getEventResult("AddEvent")->print("RippleAdder->AddEvent", 10, cout); + getSubInstance("Adder_1")->getEventResult("Add")->print("RippleAdder->AddEvent", 0, cout); + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/router/Router.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/router/Router.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_ELECTRICAL_ROUTER_ROUTER_H__ +#define __DSENT_MODEL_ELECTRICAL_ROUTER_ROUTER_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" + +namespace DSENT +{ + /** \class Router + * \param Input ports: In[0-9]* + * \param Output ports: Out[0-9]* + */ + class Router : public ElectricalModel + { + public: + Router(const String& instance_name_, const TechModel* tech_model_); + virtual ~Router(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + + // Clone and return a new instance + virtual Router* clone() const; + + protected: + // Build the model + virtual void constructModel(); + virtual void updateModel(); + virtual void propagateTransitionInfo(); + + private: + void createRouterInputPort(); + void createVirtualChannelAllocator(); + void createSwitchAllocator(); + void createCrossbar(); + void createClockTree(); + void createPipelineReg(); + + }; // class Router +} // namespace DSENT + +#endif // __DSENT_MODEL_ELECTRICAL_ROUTER_ROUTER_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/router/Router.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/router/Router.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,567 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/electrical/router/Router.hh" + +#include +#include + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ModelGen.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" +#include "mem/ruby/network/dsent/dsent-core/model/electrical/router/RouterInputPort.hh" +#include "mem/ruby/network/dsent/dsent-core/model/electrical/router/RouterSwitchAllocator.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" + +namespace DSENT +{ + using std::sqrt; + using std::vector; + + using LibUtil::castStringVector; + using LibUtil::vectorToString; + + Router::Router(const String& instance_name_, const TechModel* tech_model_) + : ElectricalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + Router::~Router() + {} + + void Router::initParameters() + { + addParameterName("NumberInputPorts"); + addParameterName("NumberOutputPorts"); + addParameterName("NumberBitsPerFlit"); + addParameterName("NumberVirtualNetworks"); + addParameterName("NumberVirtualChannelsPerVirtualNetwork"); + addParameterName("NumberBuffersPerVirtualChannel"); + // Spec for input port + addParameterName("InputPort->BufferModel"); + // Spec for crossbar + addParameterName("CrossbarModel"); + // Spec for switch allocator + addParameterName("SwitchAllocator->ArbiterModel"); + // Spec for clock tree + addParameterName("ClockTreeModel"); + addParameterName("ClockTree->NumberLevels"); + addParameterName("ClockTree->WireLayer"); + addParameterName("ClockTree->WireWidthMultiplier"); + addParameterName("ClockTree->WireSpacingMultiplier", 3.0); + return; + } + + void Router::initProperties() + { + return; + } + + Router* Router::clone() const + { + // TODO + return NULL; + } + + void Router::constructModel() + { + // Get parameters + unsigned int number_input_ports = getParameter("NumberInputPorts").toUInt(); + unsigned int number_output_ports = getParameter("NumberOutputPorts").toUInt(); + unsigned int number_bits_per_flit = getParameter("NumberBitsPerFlit").toUInt(); + + ASSERT(number_input_ports > 0, "[Error] " + getInstanceName() + + " -> Number of input ports must be > 0!"); + ASSERT(number_output_ports > 0, "[Error] " + getInstanceName() + + " -> Number of output ports must be > 0!"); + ASSERT(number_bits_per_flit > 0, "[Error] " + getInstanceName() + + " -> Number of bits per buffer must be > 0!"); + + // Create ports + createInputPort("CK"); + for(unsigned int i = 0; i < number_input_ports; ++i) + { + createInputPort("FlitIn" + (String)i, makeNetIndex(0, number_bits_per_flit-1)); + } + for(unsigned int i = 0; i < number_output_ports; ++i) + { + createOutputPort("FlitOut" + (String)i, makeNetIndex(0, number_bits_per_flit-1)); + } + + // Create area, power, event results + createElectricalResults(); + getEventInfo("Idle")->setStaticTransitionInfos(); + getEventInfo("Idle")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); + + createElectricalEventResult("ReadBuffer"); + getEventInfo("ReadBuffer")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); + createElectricalEventResult("WriteBuffer"); + getEventInfo("WriteBuffer")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); + for(unsigned int i = 1; i <= number_output_ports; ++i) + { + createElectricalEventResult("TraverseCrossbar->Multicast" + (String)i); + getEventInfo("TraverseCrossbar->Multicast" + (String)i)->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); + } + createElectricalEventResult("ArbitrateSwitch->ArbitrateStage1"); + createElectricalEventResult("ArbitrateSwitch->ArbitrateStage2"); + createElectricalEventResult("DistributeClock"); + getEventInfo("DistributeClock")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); + + // Create intermediate nets + createNet("PipelineReg0_In"); + createNet("PipelineReg0_Out"); + createNet("PipelineReg1_In"); + createNet("PipelineReg1_Out"); + for(unsigned int i = 0; i < number_output_ports; ++i) + { + createNet("PipelineReg2_In" + (String)i); + createNet("PipelineReg2_Out" + (String)i); + } + + createRouterInputPort(); + createSwitchAllocator(); + createVirtualChannelAllocator(); + createCrossbar(); + createClockTree(); + createPipelineReg(); + + // Get generated numbers + unsigned int number_crossbar_selects = getGenProperties()->get("Crossbar->NumberSelects"); + + // Add write buffer event + getEventResult("WriteBuffer")->addSubResult(getSubInstance("PipelineReg0")->getEventResult("DFFD"), "PipelineReg0", number_bits_per_flit); + getEventResult("WriteBuffer")->addSubResult(getSubInstance("PipelineReg0")->getEventResult("DFFQ"), "PipelineReg0", number_bits_per_flit); + getEventResult("WriteBuffer")->addSubResult(getSubInstance("PipelineReg0")->getEventResult("CK"), "PipelineReg0", number_bits_per_flit); + getEventResult("WriteBuffer")->addSubResult(getSubInstance("InputPort")->getEventResult("WriteBuffer"), "InputPort", 1.0); + + // Add read buffer event + getEventResult("ReadBuffer")->addSubResult(getSubInstance("InputPort")->getEventResult("ReadBuffer"), "InputPort", 1.0); + getEventResult("ReadBuffer")->addSubResult(getSubInstance("PipelineReg1")->getEventResult("DFFD"), "PipelineReg1", number_bits_per_flit); + getEventResult("ReadBuffer")->addSubResult(getSubInstance("PipelineReg1")->getEventResult("DFFQ"), "PipelineReg1", number_bits_per_flit); + getEventResult("ReadBuffer")->addSubResult(getSubInstance("PipelineReg1")->getEventResult("CK"), "PipelineReg1", number_bits_per_flit); + + // Add crossbar traversal event + for(unsigned int i = 1; i <= number_output_ports; ++i) + { + Result* traverse_crossbar_event = getEventResult("TraverseCrossbar->Multicast" + (String)i); + traverse_crossbar_event->addSubResult(getSubInstance("Crossbar_Sel_DFF")->getEventResult("DFFD"), "Crossbar_Sel_DFF", number_crossbar_selects); + traverse_crossbar_event->addSubResult(getSubInstance("Crossbar_Sel_DFF")->getEventResult("DFFQ"), "Crossbar_Sel_DFF", number_crossbar_selects); + traverse_crossbar_event->addSubResult(getSubInstance("Crossbar_Sel_DFF")->getEventResult("CK"), "Crossbar_Sel_DFF", number_crossbar_selects); + traverse_crossbar_event->addSubResult(getSubInstance("Crossbar")->getEventResult("Multicast" + (String)i), "Crossbar", 1.0); + for(unsigned int j = 0; j < i; ++j) + { + traverse_crossbar_event->addSubResult(getSubInstance("PipelineReg2_" + (String)j)->getEventResult("DFFD"), "PipelineReg2_" + (String)j, number_bits_per_flit); + traverse_crossbar_event->addSubResult(getSubInstance("PipelineReg2_" + (String)j)->getEventResult("DFFQ"), "PipelineReg2_" + (String)j, number_bits_per_flit); + traverse_crossbar_event->addSubResult(getSubInstance("PipelineReg2_" + (String)j)->getEventResult("CK"), "PipelineReg2_" + (String)j, number_bits_per_flit); + } + } + + // Add stage1 allocator arbitrate + Result* arb_sw_stage1_event = getEventResult("ArbitrateSwitch->ArbitrateStage1"); + arb_sw_stage1_event->addSubResult(getSubInstance("SwitchAllocator")->getEventResult("ArbitrateStage1"), "SwitchAllocator", 1.0); + + // Add stage2 allocator arbitrate + Result* arb_sw_stage2_event = getEventResult("ArbitrateSwitch->ArbitrateStage2"); + arb_sw_stage2_event->addSubResult(getSubInstance("SwitchAllocator")->getEventResult("ArbitrateStage2"), "SwitchAllocator", 1.0); + + // Add CK event + getEventResult("DistributeClock")->addSubResult(getSubInstance("ClockTree")->getEventResult("Send"), "ClockTree", 1.0); + return; + } + + void Router::updateModel() + { + // Get parameters + unsigned int number_output_ports = getParameter("NumberOutputPorts").toUInt(); + + // Update other components + getSubInstance("PipelineReg0")->update(); + getSubInstance("InputPort")->update(); + getSubInstance("PipelineReg1")->update(); + getSubInstance("Crossbar_Sel_DFF")->update(); + getSubInstance("Crossbar")->update(); + for(unsigned int i = 0; i < number_output_ports; ++i) + { + getSubInstance("PipelineReg2_" + (String)i)->update(); + } + getSubInstance("SwitchAllocator")->update(); + + // Update clock tree + double total_clock_tree_cap = getNet("CK")->getTotalDownstreamCap(); + double router_area = getAreaResult("Active")->calculateSum(); + Model* clock_tree = getSubInstance("ClockTree"); + clock_tree->setProperty("SitePitch", sqrt(router_area)); + clock_tree->setProperty("TotalLoadCapPerBit", total_clock_tree_cap); + clock_tree->update(); + + return; + } + + void Router::propagateTransitionInfo() + { + // Update probability + unsigned int number_output_ports = getParameter("NumberOutputPorts"); + + // Current event + const String& current_event = getGenProperties()->get("UseModelEvent"); + + ElectricalModel* pipeline_reg0 = (ElectricalModel*)getSubInstance("PipelineReg0"); + propagatePortTransitionInfo(pipeline_reg0, "D", "FlitIn0"); + propagatePortTransitionInfo(pipeline_reg0, "CK", "CK"); + pipeline_reg0->use(); + + ElectricalModel* input_port = (ElectricalModel*)getSubInstance("InputPort"); + propagatePortTransitionInfo(input_port, "FlitIn", pipeline_reg0, "Q"); + propagatePortTransitionInfo(input_port, "CK", "CK"); + input_port->getGenProperties()->set("UseModelEvent", "ReadWrite"); + input_port->use(); + + ElectricalModel* pipeline_reg1 = (ElectricalModel*)getSubInstance("PipelineReg1"); + propagatePortTransitionInfo(pipeline_reg1, "D", "FlitIn0"); + propagatePortTransitionInfo(pipeline_reg1, "CK", "CK"); + pipeline_reg1->use(); + + ElectricalModel* crossbar_sel_dff = (ElectricalModel*)getSubInstance("Crossbar_Sel_DFF"); + assignPortTransitionInfo(crossbar_sel_dff, "D", TransitionInfo()); + propagatePortTransitionInfo(crossbar_sel_dff, "CK", "CK"); + crossbar_sel_dff->use(); + + ElectricalModel* crossbar = (ElectricalModel*)getSubInstance("Crossbar"); + bool is_crossbar_event = false; + for(unsigned int i = 1; i <= number_output_ports; ++i) + { + if(current_event == ("TraverseCrossbar->Multicast" + (String)i)) + { + is_crossbar_event = true; + // Assume the flit is sent from port 0 to port 0~i-1 + // Apply default transition info + crossbar->applyTransitionInfo("Multicast" + (String)i); + // Overwrite transition info + propagatePortTransitionInfo(crossbar, "In0", "FlitIn0"); + break; + } + } + if(is_crossbar_event == false) + { + crossbar->applyTransitionInfo("Multicast1"); + propagatePortTransitionInfo(crossbar, "In0", "FlitIn0"); + } + crossbar->use(); + + vector pipeline_reg2s(number_output_ports, NULL); + for(unsigned int i = 0; i < number_output_ports; ++i) + { + pipeline_reg2s[i] = (ElectricalModel*)getSubInstance("PipelineReg2_" + (String)i); + propagatePortTransitionInfo(pipeline_reg2s[i], "D", "FlitIn0"); + propagatePortTransitionInfo(pipeline_reg2s[i], "CK", "CK"); + pipeline_reg2s[i]->use(); + } + + ElectricalModel* sw_allocator = (ElectricalModel*)getSubInstance("SwitchAllocator"); + if(current_event == "ArbitrateSwitch->ArbitrateStage1") + { + sw_allocator->applyTransitionInfo("ArbitrateStage1"); + } + else if(current_event == "ArbitrateSwitch->ArbitrateStage2") + { + sw_allocator->applyTransitionInfo("ArbitrateStage2"); + } + else + { + sw_allocator->applyTransitionInfo("Idle"); + } + sw_allocator->use(); + + ElectricalModel* clock_tree = (ElectricalModel*)getSubInstance("ClockTree"); + propagatePortTransitionInfo(clock_tree, "In", "CK"); + clock_tree->use(); + return; + } + + void Router::createRouterInputPort() + { + // Get parameters + unsigned int number_input_ports = getParameter("NumberInputPorts").toUInt(); + unsigned int number_vns = getParameter("NumberVirtualNetworks").toUInt(); + const String& number_vcs_per_vn = getParameter("NumberVirtualChannelsPerVirtualNetwork"); + const String& number_bufs_per_vc = getParameter("NumberBuffersPerVirtualChannel"); + unsigned int number_bits_per_flit = getParameter("NumberBitsPerFlit").toUInt(); + const String& buffer_model = getParameter("InputPort->BufferModel"); + + // Init input port model + const String& input_port_name = "InputPort"; + RouterInputPort* input_port = new RouterInputPort(input_port_name, getTechModel()); + input_port->setParameter("NumberVirtualNetworks", number_vns); + input_port->setParameter("NumberVirtualChannelsPerVirtualNetwork", number_vcs_per_vn); + input_port->setParameter("NumberBuffersPerVirtualChannel", number_bufs_per_vc); + input_port->setParameter("NumberBitsPerFlit", number_bits_per_flit); + input_port->setParameter("BufferModel", buffer_model); + input_port->construct(); + + unsigned int number_input_port_outputs = input_port->getGenProperties()->get("NumberOutputs"); + unsigned int number_input_port_addr_bits = input_port->getGenProperties()->get("NumberAddressBits"); + getGenProperties()->set("InputPort->NumberOutputs", number_input_port_outputs); + getGenProperties()->set("InputPort->NumberAddressBits", number_input_port_addr_bits); + + unsigned int total_number_vcs = input_port->getGenProperties()->get("TotalNumberVirtualChannels"); + getGenProperties()->set("TotalNumberVirtualChannels", total_number_vcs); + + // Add the instance and the results + addSubInstances(input_port, number_input_ports); + addElectricalSubResults(input_port, number_input_ports); + + // Create connections + createNet("InputPort_In", makeNetIndex(0, number_bits_per_flit-1)); + createNet("InputPort_Out", makeNetIndex(0, number_bits_per_flit-1)); + + assignVirtualFanout("InputPort_In", "PipelineReg0_Out"); + portConnect(input_port, "FlitIn", "InputPort_In"); + portConnect(input_port, "CK", "CK"); + portConnect(input_port, "FlitOut", "InputPort_Out"); + assignVirtualFanin("PipelineReg1_In", "InputPort_Out"); + + return; + } + + void Router::createVirtualChannelAllocator() + {} + + void Router::createSwitchAllocator() + { + // Get parameters + unsigned int number_input_ports = getParameter("NumberInputPorts").toUInt(); + unsigned int number_output_ports = getParameter("NumberOutputPorts").toUInt(); + unsigned int total_number_vcs = getGenProperties()->get("TotalNumberVirtualChannels").toUInt(); + const String& arb_model = getParameter("SwitchAllocator->ArbiterModel"); + + // Init switch allocator model + const String& sw_allocator_name = "SwitchAllocator"; + RouterSwitchAllocator* sw_allocator = new RouterSwitchAllocator(sw_allocator_name, getTechModel()); + sw_allocator->setParameter("NumberInputPorts", number_input_ports); + sw_allocator->setParameter("NumberOutputPorts", number_output_ports); + sw_allocator->setParameter("TotalNumberVirtualChannels", total_number_vcs); + sw_allocator->setParameter("ArbiterModel", arb_model); + sw_allocator->construct(); + + // Add the instance and the results + addSubInstances(sw_allocator, 1.0); + addElectricalSubResults(sw_allocator, 1.0); + + // Create connections (currently connect CK only) + portConnect(sw_allocator, "CK", "CK"); + return; + } + + void Router::createCrossbar() + { + // Get parameters + const String& crossbar_model = getParameter("CrossbarModel"); + unsigned int number_input_ports = getParameter("NumberInputPorts").toUInt(); + unsigned int number_output_ports = getParameter("NumberOutputPorts").toUInt(); + unsigned int number_bits_per_flit = getParameter("NumberBitsPerFlit").toUInt(); + unsigned int number_input_port_outputs = getGenProperties()->get("InputPort->NumberOutputs").toUInt(); + + unsigned int number_crossbar_inputs = number_input_port_outputs * number_input_ports; + unsigned int number_crossbar_outputs = number_output_ports; + getGenProperties()->set("Crossbar->NumberInputs", number_crossbar_inputs); + getGenProperties()->set("Crossbar->NumberOutputs", number_crossbar_outputs); + + // Init crossbar model + const String& crossbar_name = "Crossbar"; + ElectricalModel* crossbar = ModelGen::createCrossbar(crossbar_model, crossbar_name, getTechModel()); + crossbar->setParameter("NumberInputs", number_crossbar_inputs); + crossbar->setParameter("NumberOutputs", number_crossbar_outputs); + crossbar->setParameter("NumberBits", number_bits_per_flit); + crossbar->setParameter("BitDuplicate", "TRUE"); + crossbar->construct(); + + unsigned int number_crossbar_selects = crossbar->getGenProperties()->get("NumberSelectsPerPort"); + getGenProperties()->set("Crossbar->NumberSelects", number_crossbar_selects); + + // Init DFF for crossbar selections + const String& crossbar_sel_dff_name = "Crossbar_Sel_DFF"; + StdCell* crossbar_sel_dff = getTechModel()->getStdCellLib()->createStdCell("DFFQ", crossbar_sel_dff_name); + crossbar_sel_dff->construct(); + + // Add instances and results + addSubInstances(crossbar, 1.0); + addElectricalSubResults(crossbar, 1.0); + + addSubInstances(crossbar_sel_dff, number_crossbar_outputs * number_crossbar_selects); + addElectricalSubResults(crossbar_sel_dff, number_crossbar_outputs * number_crossbar_selects); + + // Create connections + createNet("Crossbar_Sel_DFF_Out"); + for(unsigned int i = 0; i < number_crossbar_outputs; ++i) + { + for(unsigned int j = 0; j < number_crossbar_selects; ++j) + { + createNet(String::format("Crossbar_Sel%d_%d", i, j)); + } + createNet("Crossbar_Out" + (String)i, makeNetIndex(0, number_bits_per_flit-1)); + } + for(unsigned int i = 0; i < number_crossbar_inputs; ++i) + { + createNet("Crossbar_In" + (String)i, makeNetIndex(0, number_bits_per_flit-1)); + } + + for(unsigned int i = 0; i < number_crossbar_selects; ++i) + { + portConnect(crossbar_sel_dff, "CK", "CK"); + } + portConnect(crossbar_sel_dff, "Q", "Crossbar_Sel_DFF_Out"); + for(unsigned int i = 0; i < number_crossbar_inputs; ++i) + { + assignVirtualFanout("Crossbar_In" + (String)i, "PipelineReg1_Out"); + portConnect(crossbar, "In" + (String)i, "Crossbar_In" + (String)i); + } + for(unsigned int i = 0; i < number_crossbar_outputs; ++i) + { + for(unsigned int j = 0; j < number_crossbar_selects; ++j) + { + assignVirtualFanout(String::format("Crossbar_Sel%d_%d", i, j), "Crossbar_Sel_DFF_Out"); + portConnect(crossbar, String::format("Sel%d_%d", i, j), String::format("Crossbar_Sel%d_%d", i, j)); + } + portConnect(crossbar, "Out" + (String)i, "Crossbar_Out" + (String)i); + assignVirtualFanin("PipelineReg2_In" + (String)i, "Crossbar_Out" + (String)i); + } + + return; + } + + void Router::createPipelineReg() + { + // Get parameters + unsigned int number_input_ports = getParameter("NumberInputPorts").toUInt(); + unsigned int number_output_ports = getParameter("NumberOutputPorts").toUInt(); + unsigned int number_bits_per_flit = getParameter("NumberBitsPerFlit").toUInt(); + unsigned int number_crossbar_inputs = getGenProperties()->get("Crossbar->NumberInputs"); + + // Init pipeline reg model + // First stage: from router input to input port + const String& pipeline_reg0_name = "PipelineReg0"; + StdCell* pipeline_reg0 = getTechModel()->getStdCellLib()->createStdCell("DFFQ", pipeline_reg0_name); + pipeline_reg0->construct(); + // Second stage: from input port to crossbar + const String& pipeline_reg1_name = "PipelineReg1"; + StdCell* pipeline_reg1 = getTechModel()->getStdCellLib()->createStdCell("DFFQ", pipeline_reg1_name); + pipeline_reg1->construct(); + + // Third stage: from crossbar to router output + vector pipeline_reg2s(number_output_ports, (StdCell*)NULL); + vector pipeline_reg2_names(number_output_ports, ""); + for(unsigned int i = 0; i < number_output_ports; ++i) + { + pipeline_reg2_names[i] = "PipelineReg2_" + (String)i; + pipeline_reg2s[i] = getTechModel()->getStdCellLib()->createStdCell("DFFQ", pipeline_reg2_names[i]); + pipeline_reg2s[i]->construct(); + } + + // Add instances and results + addSubInstances(pipeline_reg0, number_input_ports * number_bits_per_flit); + addElectricalSubResults(pipeline_reg0, number_input_ports * number_bits_per_flit); + + addSubInstances(pipeline_reg1, number_crossbar_inputs * number_bits_per_flit); + addElectricalSubResults(pipeline_reg1, number_crossbar_inputs * number_bits_per_flit); + + for(unsigned int i = 0; i < number_output_ports; ++i) + { + addSubInstances(pipeline_reg2s[i], number_bits_per_flit); + addElectricalSubResults(pipeline_reg2s[i], number_bits_per_flit); + } + + // Create data connections + for(unsigned int i = 0; i < number_input_ports; ++i) + { + assignVirtualFanin("PipelineReg0_In", "FlitIn" + (String)i); + } + portConnect(pipeline_reg0, "D", "PipelineReg0_In"); + portConnect(pipeline_reg0, "Q", "PipelineReg0_Out"); + portConnect(pipeline_reg1, "D", "PipelineReg1_In"); + portConnect(pipeline_reg1, "Q", "PipelineReg1_Out"); + for(unsigned int i = 0; i < number_output_ports; ++i) + { + portConnect(pipeline_reg2s[i], "D", "PipelineReg2_In" + (String)i); + portConnect(pipeline_reg2s[i], "Q", "PipelineReg2_Out" + (String)i); + assignVirtualFanout("FlitOut" + (String)i, "PipelineReg2_Out" + (String)i); + } + + // Create CK connections + for(unsigned int n = 0; n < number_bits_per_flit; ++n) + { + for(unsigned int i = 0; i < number_input_ports; ++i) + { + portConnect(pipeline_reg0, "CK", "CK"); + } + for(unsigned int i = 0; i < number_crossbar_inputs; ++i) + { + portConnect(pipeline_reg1, "CK", "CK"); + } + for(unsigned int i = 0; i < number_output_ports; ++i) + { + portConnect(pipeline_reg2s[i], "CK", "CK"); + } + } + return; + } + + void Router::createClockTree() + { + // Get parameters + const String& clock_tree_model = getParameter("ClockTreeModel"); + const String& clock_tree_number_levels = getParameter("ClockTree->NumberLevels"); + const String& clock_tree_wire_layer = getParameter("ClockTree->WireLayer"); + const String& clock_tree_wire_width_multiplier = getParameter("ClockTree->WireWidthMultiplier"); + const String& clock_tree_wire_spacing_multiplier = getParameter("ClockTree->WireSpacingMultiplier"); + + // Init clock tree model + const String& clock_tree_name = "ClockTree"; + ElectricalModel* clock_tree = (ElectricalModel*)ModelGen::createModel(clock_tree_model, clock_tree_name, getTechModel()); + clock_tree->setParameter("NumberLevels", clock_tree_number_levels); + clock_tree->setParameter("NumberBits", 1); + clock_tree->setParameter("WireLayer", clock_tree_wire_layer); + clock_tree->setParameter("WireWidthMultiplier", clock_tree_wire_width_multiplier); + clock_tree->setParameter("WireSpacingMultiplier", clock_tree_wire_spacing_multiplier); + clock_tree->construct(); + + // Add instances and results + addSubInstances(clock_tree, 1.0); + addElectricalSubResults(clock_tree, 1.0); + + return; + } +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/router/RouterInputPort.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/router/RouterInputPort.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_ELECTRICAL_ROUTER_ROUTER_INPUT_PORT_H__ +#define __DSENT_MODEL_ELECTRICAL_ROUTER_ROUTER_INPUT_PORT_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" + +namespace DSENT +{ + class RouterInputPort : public ElectricalModel + { + public: + RouterInputPort(const String& instance_name_, const TechModel* tech_model_); + virtual ~RouterInputPort(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + + // Clone and return a new instance + virtual RouterInputPort* clone() const; + + protected: + // Build the model + virtual void constructModel(); + virtual void propagateTransitionInfo(); + + }; // class RouterInputPort +} // namespace DSENT + +#endif // __DSENT_MODEL_ELECTRICAL_ROUTER_ROUTER_INPUT_PORT_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/router/RouterInputPort.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/router/RouterInputPort.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/electrical/router/RouterInputPort.hh" + +#include +#include + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ModelGen.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" + +namespace DSENT +{ + using std::ceil; + using std::vector; + using LibUtil::castStringVector; + + RouterInputPort::RouterInputPort(const String& instance_name_, const TechModel* tech_model_) + : ElectricalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + RouterInputPort::~RouterInputPort() + {} + + void RouterInputPort::initParameters() + { + addParameterName("NumberVirtualNetworks"); + addParameterName("NumberVirtualChannelsPerVirtualNetwork"); + addParameterName("NumberBuffersPerVirtualChannel"); + addParameterName("NumberBitsPerFlit"); + addParameterName("BufferModel"); + return; + } + + void RouterInputPort::initProperties() + { + return; + } + + RouterInputPort* RouterInputPort::clone() const + { + // TODO + return NULL; + } + + void RouterInputPort::constructModel() + { + // Get parameters + unsigned int number_vns = getParameter("NumberVirtualNetworks").toUInt(); + const vector& number_vcs_per_vn_vector = castStringVector(getParameter("NumberVirtualChannelsPerVirtualNetwork").split("[,]")); + const vector& number_bufs_per_vc_vector = castStringVector(getParameter("NumberBuffersPerVirtualChannel").split("[,]")); + unsigned int number_bits_per_flit = getParameter("NumberBitsPerFlit").toUInt(); + const String& buffer_model = getParameter("BufferModel"); + + ASSERT(number_vns > 0, "[Error] " + getInstanceName() + + " -> Number of virtual networks must be > 0!"); + ASSERT(number_vcs_per_vn_vector.size() == number_vns, "[Error] " + getInstanceName() + + " -> Expecting " + (String)number_vns + " number of vcs, got " + + getParameter("NumberVirtualChannelsPerVirtualNetwork")); + for(unsigned int i = 0; i < number_vns; ++i) + { + ASSERT(number_vcs_per_vn_vector[i] > 0, "[Error] " + getInstanceName() + + " -> Number of virtual channels per virtual network must be > 0!"); + } + ASSERT(number_bufs_per_vc_vector.size() == number_vns, "[Error] " + getInstanceName() + + " -> Expecting " + (String)number_vns + " number of bufs per vc, got " + + getParameter("NumberBuffersPerVirtualChannel")); + for(unsigned int i = 0; i < number_vns; ++i) + { + ASSERT(number_bufs_per_vc_vector[i] > 0, "[Error] " + getInstanceName() + + " -> Number of buffers per virtual channel must be > 0!"); + } + ASSERT(number_bits_per_flit > 0, "[Error] " + getInstanceName() + + " -> Number of bits per buffer must be > 0!"); + + // Calculate total number of buffers needed in the RAM + unsigned int total_number_vcs = 0; + unsigned int total_number_bufs = 0; + for(unsigned int i = 0; i < number_vns; ++i) + { + total_number_vcs += number_vcs_per_vn_vector[i]; + total_number_bufs += number_vcs_per_vn_vector[i] * number_bufs_per_vc_vector[i]; + } + unsigned int number_addr_bits = (unsigned int)ceil(log2(total_number_bufs)); + + getGenProperties()->set("TotalNumberVirtualChannels", total_number_vcs); + getGenProperties()->set("TotalNumberBuffers", total_number_bufs); + getGenProperties()->set("NumberAddressBits", number_addr_bits); + getGenProperties()->set("NumberOutputs", 1); + + createInputPort("CK"); + createInputPort("FlitIn", makeNetIndex(0, number_bits_per_flit-1)); + createOutputPort("FlitOut", makeNetIndex(0, number_bits_per_flit-1)); + + // Create energy, power, and area results + createElectricalResults(); + getEventInfo("Idle")->setStaticTransitionInfos(); + getEventInfo("Idle")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); + + addEventResult(new Result("ReadBuffer")); + addEventResult(new Result("WriteBuffer")); + + // Init RAM + const String& ram_name = "RAM"; + ElectricalModel* ram = ModelGen::createRAM(buffer_model, ram_name, getTechModel()); + ram->setParameter("NumberEntries", total_number_bufs); + ram->setParameter("NumberBits", number_bits_per_flit); + ram->construct(); + + // Init DFF for read address + vector rd_addr_dff_names(number_addr_bits, ""); + vector rd_addr_dffs(number_addr_bits, NULL); + for(unsigned int i = 0; i < number_addr_bits; ++i) + { + rd_addr_dff_names[i] = "RDAddr_DFF" + (String)i; + rd_addr_dffs[i] = getTechModel()->getStdCellLib()->createStdCell("DFFQ", rd_addr_dff_names[i]); + rd_addr_dffs[i]->construct(); + } + + // Connect RDAddr_DFFs + for(unsigned int i = 0; i < number_addr_bits; ++i) + { + createNet("RDAddr_DFF_Out" + (String)i); + + portConnect(rd_addr_dffs[i], "CK", "CK"); + portConnect(rd_addr_dffs[i], "Q", "RDAddr_DFF_Out" + (String)i); + } + + // Connect RAM + portConnect(ram, "In", "FlitIn"); + for(unsigned int i = 0; i < number_addr_bits; ++i) + { + portConnect(ram, "WRAddr" + (String)i, "FlitIn", makeNetIndex(i)); + portConnect(ram, "RDAddr" + (String)i, "RDAddr_DFF_Out" + (String)i); + } + portConnect(ram, "WE", "FlitIn", makeNetIndex(number_bits_per_flit-1)); + portConnect(ram, "CK", "CK"); + portConnect(ram, "Out", "FlitOut"); + + // Add area, power, event results + for(unsigned int i = 0; i < number_addr_bits; ++i) + { + addSubInstances(rd_addr_dffs[i], number_addr_bits); + addElectricalSubResults(rd_addr_dffs[i], number_addr_bits); + } + addSubInstances(ram, 1.0); + addElectricalSubResults(ram, 1.0); + + getEventResult("WriteBuffer")->addSubResult(ram->getEventResult("Write"), ram_name, 1.0); + + for(unsigned int i = 0; i < number_addr_bits; ++i) + { + getEventResult("ReadBuffer")->addSubResult(rd_addr_dffs[i]->getEventResult("DFFD"), rd_addr_dff_names[i], number_addr_bits); + getEventResult("ReadBuffer")->addSubResult(rd_addr_dffs[i]->getEventResult("DFFQ"), rd_addr_dff_names[i], number_addr_bits); + getEventResult("ReadBuffer")->addSubResult(rd_addr_dffs[i]->getEventResult("CK"), rd_addr_dff_names[i], number_addr_bits); + } + getEventResult("ReadBuffer")->addSubResult(ram->getEventResult("Read"), ram_name, 1.0); + + return; + } + + void RouterInputPort::propagateTransitionInfo() + { + // Update probability and activity + unsigned int number_addr_bits = getGenProperties()->get("NumberAddressBits").toUInt(); + + vector rd_addr_dffs(number_addr_bits, NULL); + for(unsigned int i = 0; i < number_addr_bits; ++i) + { + rd_addr_dffs[i] = (ElectricalModel*)getSubInstance("RDAddr_DFF" + (String)i); + assignPortTransitionInfo(rd_addr_dffs[i], "D", TransitionInfo()); + propagatePortTransitionInfo(rd_addr_dffs[i], "CK", "CK"); + rd_addr_dffs[i]->use(); + } + + ElectricalModel* ram = (ElectricalModel*)getSubInstance("RAM"); + + // Setup default transition info + const String& current_event = getGenProperties()->get("UseModelEvent"); + if(current_event != "Idle") + { + propagatePortTransitionInfo(ram, "In", "FlitIn"); + propagatePortTransitionInfo(ram, "CK", "CK"); + assignPortTransitionInfo(ram, "WE", TransitionInfo(0.0, 0.0, 1.0)); + for(unsigned int i = 0; i < number_addr_bits; ++i) + { + assignPortTransitionInfo(ram, "WRAddr" + (String)i, TransitionInfo(0.25, 0.25, 0.25)); + assignPortTransitionInfo(ram, "RDAddr" + (String)i, TransitionInfo(0.25, 0.25, 0.25)); + } + } + ram->use(); + // Set output probability + propagatePortTransitionInfo("FlitOut", ram, "Out"); + return; + } +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/router/RouterSwitchAllocator.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/router/RouterSwitchAllocator.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_ELECTRICAL_ROUTER_ROUTER_SWITCH_ALLOCATOR_H__ +#define __DSENT_MODEL_ELECTRICAL_ROUTER_ROUTER_SWITCH_ALLOCATOR_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" + +namespace DSENT +{ + class RouterSwitchAllocator : public ElectricalModel + { + public: + RouterSwitchAllocator(const String& instance_name_, const TechModel* tech_model_); + virtual ~RouterSwitchAllocator(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + + // Clone and return a new instance + virtual RouterSwitchAllocator* clone() const; + + protected: + // Build the model + virtual void constructModel(); + virtual void propagateTransitionInfo(); + + }; // RouterSwitchAllocator +} // namespace DSENT + +#endif // __DSENT_MODEL_ELECTRICAL_ROUTER_ROUTER_SWITCH_ALLOCATOR_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/router/RouterSwitchAllocator.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/router/RouterSwitchAllocator.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/electrical/router/RouterSwitchAllocator.hh" + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ModelGen.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" + +namespace DSENT +{ + RouterSwitchAllocator::RouterSwitchAllocator(const String& instance_name_, const TechModel* tech_model_) + : ElectricalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + RouterSwitchAllocator::~RouterSwitchAllocator() + {} + + void RouterSwitchAllocator::initParameters() + { + addParameterName("NumberInputPorts"); + addParameterName("NumberOutputPorts"); + addParameterName("TotalNumberVirtualChannels"); + addParameterName("ArbiterModel"); + return; + } + + void RouterSwitchAllocator::initProperties() + {} + + RouterSwitchAllocator* RouterSwitchAllocator::clone() const + { + // TODO + return NULL; + } + + void RouterSwitchAllocator::constructModel() + { + // Get parameters + unsigned int number_input_ports = getParameter("NumberInputPorts").toUInt(); + unsigned int number_output_ports = getParameter("NumberOutputPorts").toUInt(); + unsigned int total_number_vcs = getParameter("TotalNumberVirtualChannels").toUInt(); + const String& arb_model = getParameter("ArbiterModel"); + + ASSERT(number_input_ports > 0, "[Error] " + getInstanceName() + + " -> Number of input ports must be > 0!"); + ASSERT(number_output_ports > 0, "[Error] " + getInstanceName() + + " -> Number of output ports must be > 0!"); + ASSERT(total_number_vcs > 0, "[Error] " + getInstanceName() + + " -> Total number of virtual channels must be > 0!"); + + unsigned int stage1_number_requests = total_number_vcs; + unsigned int number_stage1_arbiters = number_input_ports; + unsigned int stage2_number_requests = number_input_ports; + unsigned int number_stage2_arbiters = number_output_ports; + + getGenProperties()->set("NumberStage1Arbiters", number_stage1_arbiters); + getGenProperties()->set("Stage1->NumberRequests", stage1_number_requests); + getGenProperties()->set("NumberStage2Arbiters", number_stage2_arbiters); + getGenProperties()->set("Stage2->NumberRequests", stage2_number_requests); + + // Create ports + createInputPort("CK"); + for(unsigned int i = 0; i < number_stage1_arbiters; ++i) + { + for(unsigned int j = 0; j < stage1_number_requests; ++j) + { + createInputPort(String::format("Stage1Arb%d->Request%d", i, j)); + createInputPort(String::format("Stage1Arb%d->Grant%d", i, j)); + } + } + for(unsigned int i = 0; i < number_stage2_arbiters; ++i) + { + for(unsigned int j = 0; j < stage2_number_requests; ++j) + { + createInputPort(String::format("Stage2Arb%d->Request%d", i, j)); + createInputPort(String::format("Stage2Arb%d->Grant%d", i, j)); + } + } + + // Create area, power, and event results + createElectricalResults(); + getEventInfo("Idle")->setStaticTransitionInfos(); + getEventInfo("Idle")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); + + createElectricalEventResult("ArbitrateStage1"); + getEventInfo("ArbitrateStage1")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); + createElectricalEventResult("ArbitrateStage2"); + getEventInfo("ArbitrateStage2")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); + + // Init Stage1 arbiter + vector stage1_arb_dff_names(stage1_number_requests, ""); + vector stage1_arb_dffs(stage1_number_requests, NULL); + for(unsigned int i = 0; i < stage1_number_requests; ++i) + { + stage1_arb_dff_names[i] = "Stage1ArbDFF" + (String)i; + stage1_arb_dffs[i] = getTechModel()->getStdCellLib()->createStdCell("DFFQ", stage1_arb_dff_names[i]); + stage1_arb_dffs[i]->construct(); + } + const String& stage1_arb_name = "Stage1Arb"; + ElectricalModel* stage1_arb = (ElectricalModel*)ModelGen::createModel(arb_model, stage1_arb_name, getTechModel()); + stage1_arb->setParameter("NumberRequests", stage1_number_requests); + stage1_arb->construct(); + + // Init stage2 arbiter + vector stage2_arb_dff_names(stage2_number_requests, ""); + vector stage2_arb_dffs(stage2_number_requests, NULL); + for(unsigned int i = 0; i < stage2_number_requests; ++i) + { + stage2_arb_dff_names[i] = "Stage2ArbDFF" + (String)i; + stage2_arb_dffs[i] = getTechModel()->getStdCellLib()->createStdCell("DFFQ", stage2_arb_dff_names[i]); + stage2_arb_dffs[i]->construct(); + } + const String& stage2_arb_name = "Stage2Arb"; + ElectricalModel* stage2_arb = (ElectricalModel*)ModelGen::createModel(arb_model, stage2_arb_name, getTechModel()); + stage2_arb->setParameter("NumberRequests", stage2_number_requests); + stage2_arb->construct(); + + // Connect ports + for(unsigned int i = 0; i < stage1_number_requests; ++i) + { + const String& dff_in_name = "Stage1Arb_DFF_In" + (String)i; + const String& req_name = "Stage1Arb->Request" + (String)i; + const String& grant_name = "Stage1Arb->Grant" + (String)i; + createNet(dff_in_name); + createNet(req_name); + createNet(grant_name); + portConnect(stage1_arb_dffs[i], "D", dff_in_name); + portConnect(stage1_arb_dffs[i], "CK", "CK"); + portConnect(stage1_arb_dffs[i], "Q", req_name); + portConnect(stage1_arb, "Request" + (String)i, req_name); + portConnect(stage1_arb, "Grant" + (String)i, grant_name); + for(unsigned int j = 0; j < number_stage1_arbiters; ++j) + { + assignVirtualFanin(dff_in_name, String::format("Stage1Arb%d->Request%d", j, i)); + assignVirtualFanout(String::format("Stage1Arb%d->Grant%d", j, i), grant_name); + } + } + for(unsigned int i = 0; i < stage2_number_requests; ++i) + { + const String& dff_in_name = "Stage2Arb_DFF_In" + (String)i; + const String& req_name = "Stage2Arb->Request" + (String)i; + const String& grant_name = "Stage2Arb->Grant" + (String)i; + createNet(dff_in_name); + createNet(req_name); + createNet(grant_name); + portConnect(stage2_arb_dffs[i], "D", dff_in_name); + portConnect(stage2_arb_dffs[i], "CK", "CK"); + portConnect(stage2_arb_dffs[i], "Q", req_name); + portConnect(stage2_arb, "Request" + (String)i, req_name); + portConnect(stage2_arb, "Grant" + (String)i, grant_name); + for(unsigned int j = 0; j < number_stage2_arbiters; ++j) + { + assignVirtualFanin(dff_in_name, String::format("Stage2Arb%d->Request%d", j, i)); + assignVirtualFanout(String::format("Stage2Arb%d->Grant%d", j, i), grant_name); + } + } + + // Add sub components + for(unsigned int i = 0; i < stage1_number_requests; ++i) + { + addSubInstances(stage1_arb_dffs[i], 1.0); + addElectricalSubResults(stage1_arb_dffs[i], 1.0); + } + addSubInstances(stage1_arb, number_stage1_arbiters); + addElectricalSubResults(stage1_arb, number_stage1_arbiters); + for(unsigned int i = 0; i < stage2_number_requests; ++i) + { + addSubInstances(stage2_arb_dffs[i], 1.0); + addElectricalSubResults(stage2_arb_dffs[i], 1.0); + } + addSubInstances(stage2_arb, number_stage2_arbiters); + addElectricalSubResults(stage2_arb, number_stage2_arbiters); + + // Update stage1 arb arbitrate + getEventResult("ArbitrateStage1")->addSubResult(stage1_arb->getEventResult("Arbitrate"), stage1_arb_name, 1.0); + + // Update stage2 arb arbitrate + getEventResult("ArbitrateStage2")->addSubResult(stage2_arb->getEventResult("Arbitrate"), stage2_arb_name, 1.0); + return; + } + + void RouterSwitchAllocator::propagateTransitionInfo() + { + ElectricalModel* stage1_arb = (ElectricalModel*)getSubInstance("Stage1Arb"); + stage1_arb->applyTransitionInfo("Arbitrate"); + stage1_arb->use(); + + ElectricalModel* stage2_arb = (ElectricalModel*)getSubInstance("Stage2Arb"); + stage2_arb->applyTransitionInfo("Arbitrate"); + stage2_arb->use(); + + return; + } +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/electrical/router/SConscript --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/electrical/router/SConscript Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,36 @@ +# 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. +# +# Authors: Chia-Hsin Owen Chen + +Import('*') + +if env['PROTOCOL'] == 'None': + Return() + +Source('Router.cc') +Source('RouterSwitchAllocator.cc') +Source('RouterInputPort.cc') + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/network/ElectricalClos.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/network/ElectricalClos.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_NETWORK_ELECTRICAL_CLOS_H__ +#define __DSENT_MODEL_NETWORK_ELECTRICAL_CLOS_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" + +namespace DSENT +{ + /** + * \brief An electrical 3-stage clos network + */ + class ElectricalClos : public ElectricalModel + { + public: + ElectricalClos(const String& instance_name_, const TechModel* tech_model_); + virtual ~ElectricalClos(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + + // Clone and return a new instance + virtual ElectricalClos* clone() const; + + protected: + // Build the model + virtual void constructModel(); + virtual void updateModel(); + virtual void propagateTransitionInfo(); + + }; +} // namespace DSENT + +#endif // __DSENT_MODEL_NETWORK_ELECTRICAL_CLOS_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/network/ElectricalClos.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/network/ElectricalClos.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,520 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/network/ElectricalClos.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/model/ModelGen.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingTree.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" + +namespace DSENT +{ + using std::sqrt; + + ElectricalClos::ElectricalClos(const String& instance_name_, const TechModel* tech_model_) + : ElectricalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + ElectricalClos::~ElectricalClos() + {} + + void ElectricalClos::initParameters() + { + // Frequency + addParameterName("Frequency"); + // Physical Parameters + addParameterName("NumberInputSites"); + addParameterName("NumberOutputSites"); + addParameterName("NumberBitsPerFlit"); + // Number of each type of routers + addParameterName("NumberIngressRouters"); + addParameterName("NumberMiddleRouters"); + addParameterName("NumberEgressRouters"); + // Router parameters + addParameterName("Router->NumberVirtualNetworks"); + addParameterName("Router->NumberVirtualChannelsPerVirtualNetwork"); + addParameterName("Router->NumberBuffersPerVirtualChannel"); + addParameterName("Router->InputPort->BufferModel"); + addParameterName("Router->CrossbarModel"); + addParameterName("Router->SwitchAllocator->ArbiterModel"); + addParameterName("Router->ClockTreeModel"); + addParameterName("Router->ClockTree->NumberLevels"); + addParameterName("Router->ClockTree->WireLayer"); + addParameterName("Router->ClockTree->WireWidthMultiplier"); + addParameterName("Router->ClockTree->WireSpacingMultiplier", 3.0); + // Link parameters + addParameterName("Link->WireLayer"); + addParameterName("Link->WireWidthMultiplier"); + addParameterName("Link->WireSpacingMultiplier"); + return; + } + + void ElectricalClos::initProperties() + { + addPropertyName("InputSitePitch"); + addPropertyName("OutputSitePitch"); + return; + } + + ElectricalClos* ElectricalClos::clone() const + { + // TODO + return NULL; + } + + void ElectricalClos::constructModel() + { + // Get input parameters + unsigned int number_input_sites = getParameter("NumberInputSites").toUInt(); + unsigned int number_output_sites = getParameter("NumberOutputSites").toUInt(); + unsigned int number_bits_per_flit = getParameter("NumberBitsPerFlit").toUInt(); + unsigned int number_ingress_routers = getParameter("NumberIngressRouters").toUInt(); + unsigned int number_middle_routers = getParameter("NumberMiddleRouters").toUInt(); + unsigned int number_egress_routers = getParameter("NumberEgressRouters").toUInt(); + + ASSERT(number_input_sites > 0, "[Error] " + getInstanceName() + + " -> Number of input sites must be > 0!"); + ASSERT(number_output_sites > 0, "[Error] " + getInstanceName() + + " -> Number of output sites must be > 0!"); + ASSERT(number_bits_per_flit > 0, "[Error] " + getInstanceName() + + " -> Number of bits per flit must be > 0!"); + ASSERT(number_ingress_routers > 0, "[Error] " + getInstanceName() + + " -> Number of ingress routers must be > 0!"); + ASSERT(number_middle_routers > 0, "[Error] " + getInstanceName() + + " -> Number of middle routers must be > 0!"); + ASSERT(number_egress_routers > 0, "[Error] " + getInstanceName() + + " -> Number of egress routers must be > 0!"); + + // Get input parameters that will be forwarded to the sub instances + const String& router_number_vns = getParameter("Router->NumberVirtualNetworks"); + const String& router_number_vcs_per_vn = getParameter("Router->NumberVirtualChannelsPerVirtualNetwork"); + const String& router_number_bufs_per_vc = getParameter("Router->NumberBuffersPerVirtualChannel"); + const String& router_buffer_model = getParameter("Router->InputPort->BufferModel"); + const String& router_crossbar_model = getParameter("Router->CrossbarModel"); + const String& link_wire_layer = getParameter("Link->WireLayer"); + const String& link_wire_width_multiplier = getParameter("Link->WireWidthMultiplier"); + const String& link_wire_spacing_multiplier = getParameter("Link->WireSpacingMultiplier"); + + // Calculate properties from input parameters + unsigned int ingress_router_number_input_ports = number_input_sites / number_ingress_routers; + unsigned int ingress_router_number_output_ports = number_middle_routers; + unsigned int middle_router_number_input_ports = number_ingress_routers; + unsigned int middle_router_number_output_ports = number_egress_routers; + unsigned int egress_router_number_input_ports = number_middle_routers; + unsigned int egress_router_number_output_ports = number_output_sites / number_egress_routers; + unsigned int number_input_to_ingress_links = number_input_sites; + unsigned int number_ingress_to_middle_links = number_ingress_routers * number_middle_routers; + unsigned int number_middle_to_egress_links = number_middle_routers * number_egress_routers; + unsigned int number_egress_to_output_links = number_output_sites; + + getGenProperties()->set("NumberInputSitesPerIngressRouter", ingress_router_number_input_ports); + getGenProperties()->set("NumberOutputSitesPerEgressRouter", egress_router_number_output_ports); + getGenProperties()->set("IngressRouter->NumberInputPorts", ingress_router_number_input_ports); + getGenProperties()->set("IngressRouter->NumberOutputPorts", ingress_router_number_output_ports); + getGenProperties()->set("MiddleRouter->NumberInputPorts", middle_router_number_input_ports); + getGenProperties()->set("MiddleRouter->NumberOutputPorts", middle_router_number_output_ports); + getGenProperties()->set("EgressRouter->NumberInputPorts", egress_router_number_input_ports); + getGenProperties()->set("EgressRouter->NumberOutputPorts", egress_router_number_output_ports); + + // Create ports + createInputPort("CK"); + + // Init ingress router + ElectricalModel* ingress_router = (ElectricalModel*)ModelGen::createModel("Router", "IngressRouter", getTechModel()); + ingress_router->setParameter("NumberInputPorts", ingress_router_number_input_ports); + ingress_router->setParameter("NumberOutputPorts", ingress_router_number_output_ports); + ingress_router->setParameter("NumberVirtualNetworks", router_number_vns); + ingress_router->setParameter("NumberVirtualChannelsPerVirtualNetwork", router_number_vcs_per_vn); + ingress_router->setParameter("NumberBuffersPerVirtualChannel", router_number_bufs_per_vc); + ingress_router->setParameter("NumberBitsPerFlit", number_bits_per_flit); + ingress_router->setParameter("InputPort->BufferModel", router_buffer_model); + ingress_router->setParameter("CrossbarModel", router_crossbar_model); + ingress_router->setParameter("SwitchAllocator->ArbiterModel", getParameter("Router->SwitchAllocator->ArbiterModel")); + ingress_router->setParameter("ClockTreeModel", getParameter("Router->ClockTreeModel")); + ingress_router->setParameter("ClockTree->NumberLevels", getParameter("Router->ClockTree->NumberLevels")); + ingress_router->setParameter("ClockTree->WireLayer", getParameter("Router->ClockTree->WireLayer")); + ingress_router->setParameter("ClockTree->WireWidthMultiplier", getParameter("Router->ClockTree->WireWidthMultiplier")); + ingress_router->setParameter("ClockTree->WireSpacingMultiplier", getParameter("Router->ClockTree->WireSpacingMultiplier")); + ingress_router->construct(); + // Init middle routers + ElectricalModel* middle_router = (ElectricalModel*)ModelGen::createModel("Router", "MiddleRouter", getTechModel()); + middle_router->setParameter("NumberInputPorts", middle_router_number_input_ports); + middle_router->setParameter("NumberOutputPorts", middle_router_number_output_ports); + middle_router->setParameter("NumberVirtualNetworks", router_number_vns); + middle_router->setParameter("NumberVirtualChannelsPerVirtualNetwork", router_number_vcs_per_vn); + middle_router->setParameter("NumberBuffersPerVirtualChannel", router_number_bufs_per_vc); + middle_router->setParameter("NumberBitsPerFlit", number_bits_per_flit); + middle_router->setParameter("InputPort->BufferModel", router_buffer_model); + middle_router->setParameter("CrossbarModel", router_crossbar_model); + middle_router->setParameter("SwitchAllocator->ArbiterModel", getParameter("Router->SwitchAllocator->ArbiterModel")); + middle_router->setParameter("ClockTreeModel", getParameter("Router->ClockTreeModel")); + middle_router->setParameter("ClockTree->NumberLevels", getParameter("Router->ClockTree->NumberLevels")); + middle_router->setParameter("ClockTree->WireLayer", getParameter("Router->ClockTree->WireLayer")); + middle_router->setParameter("ClockTree->WireWidthMultiplier", getParameter("Router->ClockTree->WireWidthMultiplier")); + middle_router->setParameter("ClockTree->WireSpacingMultiplier", getParameter("Router->ClockTree->WireSpacingMultiplier")); + middle_router->construct(); + // Init egress routers + ElectricalModel* egress_router = (ElectricalModel*)ModelGen::createModel("Router", "EgressRouter", getTechModel()); + egress_router->setParameter("NumberInputPorts", egress_router_number_input_ports); + egress_router->setParameter("NumberOutputPorts", egress_router_number_output_ports); + egress_router->setParameter("NumberVirtualNetworks", router_number_vns); + egress_router->setParameter("NumberVirtualChannelsPerVirtualNetwork", router_number_vcs_per_vn); + egress_router->setParameter("NumberBuffersPerVirtualChannel", router_number_bufs_per_vc); + egress_router->setParameter("NumberBitsPerFlit", number_bits_per_flit); + egress_router->setParameter("InputPort->BufferModel", router_buffer_model); + egress_router->setParameter("CrossbarModel", router_crossbar_model); + egress_router->setParameter("SwitchAllocator->ArbiterModel", getParameter("Router->SwitchAllocator->ArbiterModel")); + egress_router->setParameter("ClockTreeModel", getParameter("Router->ClockTreeModel")); + egress_router->setParameter("ClockTree->NumberLevels", getParameter("Router->ClockTree->NumberLevels")); + egress_router->setParameter("ClockTree->WireLayer", getParameter("Router->ClockTree->WireLayer")); + egress_router->setParameter("ClockTree->WireWidthMultiplier", getParameter("Router->ClockTree->WireWidthMultiplier")); + egress_router->setParameter("ClockTree->WireSpacingMultiplier", getParameter("Router->ClockTree->WireSpacingMultiplier")); + egress_router->construct(); + // Init input to ingress link + ElectricalModel* input_to_ingress_link = (ElectricalModel*)ModelGen::createModel("RepeatedLink", "InputToIngressLink", getTechModel()); + input_to_ingress_link->setParameter("NumberBits", number_bits_per_flit); + input_to_ingress_link->setParameter("WireLayer", link_wire_layer); + input_to_ingress_link->setParameter("WireWidthMultiplier", link_wire_width_multiplier); + input_to_ingress_link->setParameter("WireSpacingMultiplier", link_wire_spacing_multiplier); + input_to_ingress_link->construct(); + // Init ingress to middle link + ElectricalModel* ingress_to_middle_link = (ElectricalModel*)ModelGen::createModel("RepeatedLink", "IngressToMiddleLink", getTechModel()); + ingress_to_middle_link->setParameter("NumberBits", number_bits_per_flit); + ingress_to_middle_link->setParameter("WireLayer", link_wire_layer); + ingress_to_middle_link->setParameter("WireWidthMultiplier", link_wire_width_multiplier); + ingress_to_middle_link->setParameter("WireSpacingMultiplier", link_wire_spacing_multiplier); + ingress_to_middle_link->construct(); + // Init middle to egress link + ElectricalModel* middle_to_egress_link = (ElectricalModel*)ModelGen::createModel("RepeatedLink", "MiddleToEgressLink", getTechModel()); + middle_to_egress_link->setParameter("NumberBits", number_bits_per_flit); + middle_to_egress_link->setParameter("WireLayer", link_wire_layer); + middle_to_egress_link->setParameter("WireWidthMultiplier", link_wire_width_multiplier); + middle_to_egress_link->setParameter("WireSpacingMultiplier", link_wire_spacing_multiplier); + middle_to_egress_link->construct(); + // Init egress to output link + ElectricalModel* egress_to_output_link = (ElectricalModel*)ModelGen::createModel("RepeatedLink", "EgressToOutputLink", getTechModel()); + egress_to_output_link->setParameter("NumberBits", number_bits_per_flit); + egress_to_output_link->setParameter("WireLayer", link_wire_layer); + egress_to_output_link->setParameter("WireWidthMultiplier", link_wire_width_multiplier); + egress_to_output_link->setParameter("WireSpacingMultiplier", link_wire_spacing_multiplier); + egress_to_output_link->construct(); + + // Connect ports + createNet("InputToIngressLink_Out", makeNetIndex(0, number_bits_per_flit-1)); + createNet("InputToIngressLink_In", makeNetIndex(0, number_bits_per_flit-1)); + portConnect(input_to_ingress_link, "In", "InputToIngressLink_In"); + portConnect(input_to_ingress_link, "Out", "InputToIngressLink_Out"); + + createNet("IngressToMiddleLink_In", makeNetIndex(0, number_bits_per_flit-1)); + createNet("IngressToMiddleLink_Out", makeNetIndex(0, number_bits_per_flit-1)); + portConnect(ingress_to_middle_link, "In", "IngressToMiddleLink_In"); + portConnect(ingress_to_middle_link, "Out", "IngressToMiddleLink_Out"); + + createNet("MiddleToEgressLink_In", makeNetIndex(0, number_bits_per_flit-1)); + createNet("MiddleToEgressLink_Out", makeNetIndex(0, number_bits_per_flit-1)); + portConnect(middle_to_egress_link, "In", "MiddleToEgressLink_In"); + portConnect(middle_to_egress_link, "Out", "MiddleToEgressLink_Out"); + + createNet("EgressToOutputLink_In", makeNetIndex(0, number_bits_per_flit-1)); + createNet("EgressToOutputLink_Out", makeNetIndex(0, number_bits_per_flit-1)); + portConnect(egress_to_output_link, "In", "EgressToOutputLink_In"); + portConnect(egress_to_output_link, "Out", "EgressToOutputLink_Out"); + + + portConnect(ingress_router, "CK", "CK"); + for(unsigned int i = 0; i < ingress_router_number_input_ports; ++i) + { + createNet("IngressRouter_In" + (String)i, makeNetIndex(0, number_bits_per_flit-1)); + for (unsigned int j = 0; j < number_bits_per_flit; ++j) + assignVirtualFanout("IngressRouter_In" + (String)i, makeNetIndex(j), "InputToIngressLink_Out", makeNetIndex(j)); + portConnect(ingress_router, "FlitIn" + (String)i, "IngressRouter_In" + (String)i); + } + for(unsigned int i = 0; i < ingress_router_number_output_ports; ++i) + { + // VFI + portConnect(ingress_router, "FlitOut" + (String)i, "IngressToMiddleLink_In"); + } + + portConnect(middle_router, "CK", "CK"); + for(unsigned int i = 0; i < middle_router_number_input_ports; ++i) + { + createNet("MiddleRouter_In" + (String)i, makeNetIndex(0, number_bits_per_flit-1)); + for (unsigned int j = 0; j < number_bits_per_flit; ++j) + assignVirtualFanout("MiddleRouter_In" + (String)i, makeNetIndex(j), "IngressToMiddleLink_Out", makeNetIndex(j)); + portConnect(middle_router, "FlitIn" + (String)i, "MiddleRouter_In" + (String)i); + } + for(unsigned int i = 0; i < middle_router_number_output_ports; ++i) + { + // VFI + portConnect(middle_router, "FlitOut" + (String)i, "MiddleToEgressLink_In"); + } + + portConnect(egress_router, "CK", "CK"); + for(unsigned int i = 0; i < egress_router_number_input_ports; ++i) + { + createNet("EgressRouter_In" + (String)i, makeNetIndex(0, number_bits_per_flit-1)); + for (unsigned int j = 0; j < number_bits_per_flit; ++j) + assignVirtualFanout("EgressRouter_In" + (String)i, makeNetIndex(j), "MiddleToEgressLink_Out", makeNetIndex(j)); + portConnect(egress_router, "FlitIn" + (String)i, "EgressRouter_In" + (String)i); + } + for(unsigned int i = 0; i < egress_router_number_output_ports; ++i) + { + // VFI + portConnect(egress_router, "FlitOut" + (String)i, "EgressToOutputLink_In"); + } + + // Create area, power, and event results + createElectricalResults(); + createElectricalEventResult("AvgUnicast"); + createElectricalEventResult("AvgBroadcast"); + + // Add all instances + addSubInstances(ingress_router, number_ingress_routers); + addElectricalSubResults(ingress_router, number_ingress_routers); + addSubInstances(middle_router, number_middle_routers); + addElectricalSubResults(middle_router, number_middle_routers); + addSubInstances(egress_router, number_egress_routers); + addElectricalSubResults(egress_router, number_egress_routers); + addSubInstances(input_to_ingress_link, number_input_to_ingress_links); + addElectricalSubResults(input_to_ingress_link, number_input_to_ingress_links); + addSubInstances(ingress_to_middle_link, number_ingress_to_middle_links); + addElectricalSubResults(ingress_to_middle_link, number_ingress_to_middle_links); + addSubInstances(middle_to_egress_link, number_middle_to_egress_links); + addElectricalSubResults(middle_to_egress_link, number_middle_to_egress_links); + addSubInstances(egress_to_output_link, number_egress_to_output_links); + addElectricalSubResults(egress_to_output_link, number_egress_to_output_links); + + // Update unicast event + Result* avg_unicast_event = getEventResult("AvgUnicast"); + avg_unicast_event->addSubResult(input_to_ingress_link->getEventResult("Send"), "InputToIngressLink", 1.0); + if(ingress_router->hasEventResult("WriteBuffer")) + { + avg_unicast_event->addSubResult(ingress_router->getEventResult("WriteBuffer"), "IngressRouter", 1.0); + } + if(ingress_router->hasEventResult("ReadBuffer")) + { + avg_unicast_event->addSubResult(ingress_router->getEventResult("ReadBuffer"), "IngressRouter", 1.0); + } + avg_unicast_event->addSubResult(ingress_router->getEventResult("TraverseCrossbar->Multicast1"), "IngressRouter", 1.0); + avg_unicast_event->addSubResult(ingress_to_middle_link->getEventResult("Send"), "IngressToMiddleLink", 1.0); + if(middle_router->hasEventResult("WriteBuffer")) + { + avg_unicast_event->addSubResult(middle_router->getEventResult("WriteBuffer"), "MiddleRouter", 1.0); + } + if(middle_router->hasEventResult("ReadBuffer")) + { + avg_unicast_event->addSubResult(middle_router->getEventResult("ReadBuffer"), "MiddleRouter", 1.0); + } + avg_unicast_event->addSubResult(middle_router->getEventResult("TraverseCrossbar->Multicast1"), "MiddleRouter", 1.0); + avg_unicast_event->addSubResult(middle_to_egress_link->getEventResult("Send"), "MiddleToEgressLink", 1.0); + if(egress_router->hasEventResult("WriteBuffer")) + { + avg_unicast_event->addSubResult(egress_router->getEventResult("WriteBuffer"), "EgressRouter", 1.0); + } + if(egress_router->hasEventResult("ReadBuffer")) + { + avg_unicast_event->addSubResult(egress_router->getEventResult("ReadBuffer"), "EgressRouter", 1.0); + } + avg_unicast_event->addSubResult(egress_router->getEventResult("TraverseCrossbar->Multicast1"), "EgressRouter", 1.0); + avg_unicast_event->addSubResult(egress_to_output_link->getEventResult("Send"), "EgressToOutputLink", 1.0); + + // Update broadcast event + Result* avg_broadcast_event = getEventResult("AvgBroadcast"); + avg_broadcast_event->addSubResult(input_to_ingress_link->getEventResult("Send"), "InputToIngressLink", 1.0); + if(ingress_router->hasEventResult("WriteBuffer")) + { + avg_broadcast_event->addSubResult(ingress_router->getEventResult("WriteBuffer"), "IngressRouter", 1.0); + } + if(ingress_router->hasEventResult("ReadBuffer")) + { + avg_broadcast_event->addSubResult(ingress_router->getEventResult("ReadBuffer"), "IngressRouter", 1.0); + } + avg_broadcast_event->addSubResult(ingress_router->getEventResult("TraverseCrossbar->Multicast1"), "IngressRouter", 1.0); + avg_broadcast_event->addSubResult(ingress_to_middle_link->getEventResult("Send"), "IngressToMiddleLink", 1.0); + if(middle_router->hasEventResult("WriteBuffer")) + { + avg_broadcast_event->addSubResult(middle_router->getEventResult("WriteBuffer"), "MiddleRouter", 1.0); + } + if(middle_router->hasEventResult("ReadBuffer")) + { + avg_broadcast_event->addSubResult(middle_router->getEventResult("ReadBuffer"), "MiddleRouter", 1.0); + } + avg_broadcast_event->addSubResult(middle_router->getEventResult("TraverseCrossbar->Multicast1"), "MiddleRouter", 1.0); + avg_broadcast_event->addSubResult(middle_to_egress_link->getEventResult("Send"), "MiddleToEgressLink", number_egress_routers); + if(egress_router->hasEventResult("WriteBuffer")) + { + avg_broadcast_event->addSubResult(egress_router->getEventResult("WriteBuffer"), "EgressRouter", number_egress_routers); + } + if(egress_router->hasEventResult("ReadBuffer")) + { + avg_broadcast_event->addSubResult(egress_router->getEventResult("ReadBuffer"), "EgressRouter", number_egress_routers); + } + avg_broadcast_event->addSubResult(egress_router->getEventResult("TraverseCrossbar->Multicast" + (String)number_egress_routers), "EgressRouter", 1.0); + avg_broadcast_event->addSubResult(egress_to_output_link->getEventResult("Send"), "EgressToOutputLink", number_output_sites); + return; + } + + void ElectricalClos::updateModel() + { + // Get properties + double input_site_pitch = getProperty("InputSitePitch").toDouble(); + double output_site_pitch = getProperty("OutputSitePitch").toDouble(); + double clock_freq = getParameter("Frequency"); + + ASSERT(input_site_pitch > 0, "[Error] " + getInstanceName() + + " -> Input site pitch must be > 0!"); + ASSERT(output_site_pitch > 0, "[Error] " + getInstanceName() + + " -> Output site pitch must be > 0!"); + ASSERT(clock_freq > 0, "[Error] " + getInstanceName() + + " -> Clock frequency must be > 0!"); + + unsigned int number_input_sites_per_ingress_router = getGenProperties()->get("NumberInputSitesPerIngressRouter"); + unsigned int number_ingress_routers = getParameter("NumberIngressRouters"); + unsigned int number_output_sites_per_egress_router = getGenProperties()->get("NumberOutputSitesPerEgressRouter"); + unsigned int number_egress_routers = getParameter("NumberEgressRouters"); + double delay = 1.0 / clock_freq; + + double input_to_ingress_link_length = input_site_pitch * (sqrt(number_input_sites_per_ingress_router) - 1.0); + double input_to_ingress_link_delay = delay * 0.8; + double ingress_to_middle_link_length = input_site_pitch * (sqrt(number_input_sites_per_ingress_router) * sqrt(number_ingress_routers)); + double ingress_to_middle_link_delay = delay * 0.8; + double middle_to_egress_link_length = output_site_pitch * (sqrt(number_output_sites_per_egress_router) * sqrt(number_egress_routers)); + double middle_to_egress_link_delay = delay * 0.8; + double egress_to_output_link_length = output_site_pitch * (sqrt(number_output_sites_per_egress_router) - 1.0); + double egress_to_output_link_delay = delay * 0.8; + double ingress_router_delay = delay; + double middle_router_delay = delay; + double egress_router_delay = delay; + + Model* input_to_ingress_link = getSubInstance("InputToIngressLink"); + input_to_ingress_link->setProperty("WireLength", input_to_ingress_link_length); + input_to_ingress_link->setProperty("Delay", input_to_ingress_link_delay); + input_to_ingress_link->setProperty("IsKeepParity", "TRUE"); + input_to_ingress_link->update(); + + Model* ingress_to_middle_link = getSubInstance("IngressToMiddleLink"); + ingress_to_middle_link->setProperty("WireLength", ingress_to_middle_link_length); + ingress_to_middle_link->setProperty("Delay", ingress_to_middle_link_delay); + ingress_to_middle_link->setProperty("IsKeepParity", "TRUE"); + ingress_to_middle_link->update(); + + Model* middle_to_egress_link = getSubInstance("MiddleToEgressLink"); + middle_to_egress_link->setProperty("WireLength", middle_to_egress_link_length); + middle_to_egress_link->setProperty("Delay", middle_to_egress_link_delay); + middle_to_egress_link->setProperty("IsKeepParity", "TRUE"); + middle_to_egress_link->update(); + + Model* egress_to_output_link = getSubInstance("EgressToOutputLink"); + egress_to_output_link->setProperty("WireLength", egress_to_output_link_length); + egress_to_output_link->setProperty("Delay", egress_to_output_link_delay); + egress_to_output_link->setProperty("IsKeepParity", "TRUE"); + egress_to_output_link->update(); + + ElectricalModel* ingress_router = (ElectricalModel*)getSubInstance("IngressRouter"); + ingress_router->update(); + + ElectricalTimingTree ingress_router_timing_tree("IngressRouter", ingress_router); + ingress_router_timing_tree.performTimingOpt(ingress_router->getNet("CK"), ingress_router_delay); + + ElectricalModel* middle_router = (ElectricalModel*)getSubInstance("MiddleRouter"); + middle_router->update(); + + ElectricalTimingTree middle_router_timing_tree("MiddleRouter", middle_router); + middle_router_timing_tree.performTimingOpt(middle_router->getNet("CK"), middle_router_delay); + + ElectricalModel* egress_router = (ElectricalModel*)getSubInstance("EgressRouter"); + egress_router->update(); + + ElectricalTimingTree egress_router_timing_tree("EgressRouter", egress_router); + egress_router_timing_tree.performTimingOpt(egress_router->getNet("CK"), egress_router_delay); + + return; + } + + void ElectricalClos::propagateTransitionInfo() + { + // Get properties + unsigned int ingress_router_number_input_ports = getGenProperties()->get("IngressRouter->NumberInputPorts"); + unsigned int middle_router_number_input_ports = getGenProperties()->get("MiddleRouter->NumberInputPorts"); + unsigned int egress_router_number_input_ports = getGenProperties()->get("EgressRouter->NumberInputPorts"); + + ElectricalModel* input_to_ingress_link = (ElectricalModel*)getSubInstance("InputToIngressLink"); + assignPortTransitionInfo(input_to_ingress_link, "In", TransitionInfo(0.25, 0.25, 0.25)); + input_to_ingress_link->use(); + + ElectricalModel* ingress_to_middle_link = (ElectricalModel*)getSubInstance("IngressToMiddleLink"); + assignPortTransitionInfo(ingress_to_middle_link, "In", TransitionInfo(0.25, 0.25, 0.25)); + ingress_to_middle_link->use(); + + ElectricalModel* middle_to_egress_link = (ElectricalModel*)getSubInstance("MiddleToEgressLink"); + assignPortTransitionInfo(middle_to_egress_link, "In", TransitionInfo(0.25, 0.25, 0.25)); + middle_to_egress_link->use(); + + ElectricalModel* egress_to_output_link = (ElectricalModel*)getSubInstance("EgressToOutputLink"); + assignPortTransitionInfo(egress_to_output_link, "In", TransitionInfo(0.25, 0.25, 0.25)); + egress_to_output_link->use(); + + ElectricalModel* ingress_router = (ElectricalModel*)getSubInstance("IngressRouter"); + for(unsigned int i = 0; i < ingress_router_number_input_ports; ++i) + { + assignPortTransitionInfo(ingress_router, "FlitIn" + (String)i, TransitionInfo(0.25, 0.25, 0.25)); + } + assignPortTransitionInfo(ingress_router, "CK", TransitionInfo(0.0, 1.0, 0.0)); + ingress_router->getGenProperties()->set("UseModelEvent", ""); + ingress_router->use(); + + ElectricalModel* middle_router = (ElectricalModel*)getSubInstance("MiddleRouter"); + for(unsigned int i = 0; i < middle_router_number_input_ports; ++i) + { + assignPortTransitionInfo(middle_router, "FlitIn" + (String)i, TransitionInfo(0.25, 0.25, 0.25)); + } + assignPortTransitionInfo(middle_router, "CK", TransitionInfo(0.0, 1.0, 0.0)); + middle_router->getGenProperties()->set("UseModelEvent", ""); + middle_router->use(); + + ElectricalModel* egress_router = (ElectricalModel*)getSubInstance("EgressRouter"); + for(unsigned int i = 0; i < egress_router_number_input_ports; ++i) + { + assignPortTransitionInfo(egress_router, "FlitIn" + (String)i, TransitionInfo(0.25, 0.25, 0.25)); + } + assignPortTransitionInfo(egress_router, "CK", TransitionInfo(0.0, 1.0, 0.0)); + egress_router->getGenProperties()->set("UseModelEvent", ""); + egress_router->use(); + + return; + } +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/network/ElectricalMesh.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/network/ElectricalMesh.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_NETWORK_ELECTRICAL_MESH_H__ +#define __DSENT_MODEL_NETWORK_ELECTRICAL_MESH_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" + +namespace DSENT +{ + /** + * \brief An electrical mesh network + */ + class ElectricalMesh : public ElectricalModel + { + public: + ElectricalMesh(const String& instance_name_, const TechModel* tech_model_); + virtual ~ElectricalMesh(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + + // Clone and return a new instance + virtual ElectricalMesh* clone() const; + + protected: + // Build the model + virtual void constructModel(); + virtual void updateModel(); + virtual void propagateTransitionInfo(); + + }; // class ElectricalMesh +} // namespace DSENT + +#endif // __DSENT_MODEL_NETWORK_ELECTRICAL_MESH_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/network/ElectricalMesh.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/network/ElectricalMesh.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/network/ElectricalMesh.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ModelGen.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingTree.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" + +namespace DSENT +{ + using std::sqrt; + + ElectricalMesh::ElectricalMesh(const String& instance_name_, const TechModel* tech_model_) + : ElectricalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + ElectricalMesh::~ElectricalMesh() + {} + + void ElectricalMesh::initParameters() + { + // Clock Frequency + addParameterName("Frequency"); + // Physical Parameters + addParameterName("NumberSites"); + addParameterName("NumberBitsPerFlit"); + // Concentration factor + addParameterName("NumberSitesPerRouter"); + // Router parameters + addParameterName("Router->NumberVirtualNetworks"); + addParameterName("Router->NumberVirtualChannelsPerVirtualNetwork"); + addParameterName("Router->NumberBuffersPerVirtualChannel"); + addParameterName("Router->InputPort->BufferModel"); + addParameterName("Router->CrossbarModel"); + addParameterName("Router->SwitchAllocator->ArbiterModel"); + addParameterName("Router->ClockTreeModel"); + addParameterName("Router->ClockTree->NumberLevels"); + addParameterName("Router->ClockTree->WireLayer"); + addParameterName("Router->ClockTree->WireWidthMultiplier"); + addParameterName("Router->ClockTree->WireSpacingMultiplier", 3.0); + // Link parameters + addParameterName("Link->WireLayer"); + addParameterName("Link->WireWidthMultiplier"); + addParameterName("Link->WireSpacingMultiplier"); + return; + } + + void ElectricalMesh::initProperties() + { + addPropertyName("SitePitch"); + return; + } + + ElectricalMesh* ElectricalMesh::clone() const + { + // TODO + return NULL; + } + + void ElectricalMesh::constructModel() + { + // Get input paramters + unsigned int number_sites = getParameter("NumberSites").toUInt(); + unsigned int number_bits_per_flit = getParameter("NumberBitsPerFlit").toUInt(); + unsigned int number_sites_per_router = getParameter("NumberSitesPerRouter").toUInt(); + + ASSERT(number_sites > 0, "[Error] " + getInstanceName() + + " -> Number of sites must be > 0!"); + ASSERT(number_bits_per_flit > 0, "[Error] " + getInstanceName() + + " -> Number of bits per flit must be > 0!"); + ASSERT(number_sites_per_router > 0, "[Error] " + getInstanceName() + + " -> Number of sites per router must be > 0!"); + + // Get input parameters that will be forwarded to the sub instances + const String& router_number_vns = getParameter("Router->NumberVirtualNetworks"); + const String& router_number_vcs_per_vn = getParameter("Router->NumberVirtualChannelsPerVirtualNetwork"); + const String& router_number_bufs_per_vc = getParameter("Router->NumberBuffersPerVirtualChannel"); + const String& link_wire_layer = getParameter("Link->WireLayer"); + const String& link_wire_width_multiplier = getParameter("Link->WireWidthMultiplier"); + const String& link_wire_spacing_multiplier = getParameter("Link->WireSpacingMultiplier"); + + // Calculate properties from input parameters + unsigned int number_routers = number_sites / number_sites_per_router; + unsigned int number_router_to_router_links = 4 * number_routers; + unsigned int number_router_to_site_links = 2 * number_sites; + unsigned int router_number_input_ports = 4 + number_sites_per_router; + unsigned int router_number_output_ports = 4 + number_sites_per_router; + + getGenProperties()->set("NumberRouters", number_routers); + getGenProperties()->set("NumberRouterToRouterLinks", number_router_to_router_links); + getGenProperties()->set("NumberRouterToSiteLinks", number_router_to_site_links); + getGenProperties()->set("Router->NumberInputPorts", router_number_input_ports); + getGenProperties()->set("Router->NumberOutputPorts", router_number_output_ports); + + // Create ports + createInputPort("CK"); + + // Init mesh routers + ElectricalModel* router = (ElectricalModel*)ModelGen::createModel("Router", "MeshRouter", getTechModel()); + router->setParameter("NumberInputPorts", router_number_input_ports); + router->setParameter("NumberOutputPorts", router_number_output_ports); + router->setParameter("NumberVirtualNetworks", router_number_vns); + router->setParameter("NumberVirtualChannelsPerVirtualNetwork", router_number_vcs_per_vn); + router->setParameter("NumberBuffersPerVirtualChannel", router_number_bufs_per_vc); + router->setParameter("NumberBitsPerFlit", number_bits_per_flit); + router->setParameter("InputPort->BufferModel", getParameter("Router->InputPort->BufferModel")); + router->setParameter("CrossbarModel", getParameter("Router->CrossbarModel")); + router->setParameter("SwitchAllocator->ArbiterModel", getParameter("Router->SwitchAllocator->ArbiterModel")); + router->setParameter("ClockTreeModel", getParameter("Router->ClockTreeModel")); + router->setParameter("ClockTree->NumberLevels", getParameter("Router->ClockTree->NumberLevels")); + router->setParameter("ClockTree->WireLayer", getParameter("Router->ClockTree->WireLayer")); + router->setParameter("ClockTree->WireWidthMultiplier", getParameter("Router->ClockTree->WireWidthMultiplier")); + router->setParameter("ClockTree->WireSpacingMultiplier", getParameter("Router->ClockTree->WireSpacingMultiplier")); + router->construct(); + + // Init router to router links + ElectricalModel* rr_link = (ElectricalModel*)ModelGen::createModel("RepeatedLink", "RouterToRouterLink", getTechModel()); + rr_link->setParameter("NumberBits", number_bits_per_flit); + rr_link->setParameter("WireLayer", link_wire_layer); + rr_link->setParameter("WireWidthMultiplier", link_wire_width_multiplier); + rr_link->setParameter("WireSpacingMultiplier", link_wire_spacing_multiplier); + rr_link->construct(); + + // Init router to site links + ElectricalModel* rs_link = (ElectricalModel*)ModelGen::createModel("RepeatedLink", "RouterToSiteLink", getTechModel()); + rs_link->setParameter("NumberBits", number_bits_per_flit); + rs_link->setParameter("WireLayer", link_wire_layer); + rs_link->setParameter("WireWidthMultiplier", link_wire_width_multiplier); + rs_link->setParameter("WireSpacingMultiplier", link_wire_spacing_multiplier); + rs_link->construct(); + + // Connect ports + createNet("RR_Link_Out", makeNetIndex(0, number_bits_per_flit-1)); + createNet("RR_Link_In", makeNetIndex(0, number_bits_per_flit-1)); + portConnect(rr_link, "In", "RR_Link_In"); + portConnect(rr_link, "Out", "RR_Link_Out"); + + createNet("RS_Link_Out", makeNetIndex(0, number_bits_per_flit-1)); + createNet("RS_Link_In", makeNetIndex(0, number_bits_per_flit-1)); + portConnect(rs_link, "In", "RS_Link_In"); + portConnect(rs_link, "Out", "RS_Link_Out"); + + portConnect(router, "CK", "CK"); + for(unsigned int i = 0; i < router_number_input_ports; ++i) + { + createNet("Router_In" + (String)i, makeNetIndex(0, number_bits_per_flit-1)); + portConnect(router, "FlitIn" + (String)i, "Router_In" + (String)i); + } + for(unsigned int i = 0; i < router_number_output_ports; ++i) + { + createNet("Router_Out" + (String)i, makeNetIndex(0, number_bits_per_flit-1)); + portConnect(router, "FlitOut" + (String)i, "Router_Out" + (String)i); + } + for(unsigned int i = 0; i < number_bits_per_flit; ++i) + { + for(unsigned int j = 0; j < 4; ++j) + { + assignVirtualFanout("Router_In" + (String)j, makeNetIndex(i), "RR_Link_Out", makeNetIndex(i)); + assignVirtualFanin("RR_Link_In", makeNetIndex(i), "Router_Out" + (String)j, makeNetIndex(i)); + } + for(unsigned int j = 4; j < router_number_input_ports; ++j) + { + assignVirtualFanout("Router_In" + (String)j, makeNetIndex(i), "RS_Link_Out", makeNetIndex(i)); + assignVirtualFanin("RS_Link_In", makeNetIndex(i), "Router_Out" + (String)j, makeNetIndex(i)); + } + } + + // Create area, power and event results + createElectricalResults(); + createElectricalEventResult("AvgUnicast"); + createElectricalEventResult("AvgBroadcast"); + + // Add all instances + addSubInstances(router, number_routers); + addElectricalSubResults(router, number_routers); + addSubInstances(rr_link, number_router_to_router_links); + addElectricalSubResults(rr_link, number_router_to_router_links); + addSubInstances(rs_link, number_router_to_site_links); + addElectricalSubResults(rs_link, number_router_to_site_links); + + double number_routers_per_side = sqrt(number_routers); + + // Update unicast event + double avg_number_unicast_hop = 2.0 * number_routers_per_side / 3.0; + double avg_number_unicast_rr_links_traveled = avg_number_unicast_hop; + double avg_number_unicast_rs_links_traveled = 2.0; + double avg_number_unicast_router_traveled = avg_number_unicast_hop + 1.0; + Result* avg_unicast_flit = getEventResult("AvgUnicast"); + avg_unicast_flit->addSubResult(rr_link->getEventResult("Send"), "RouterToRouterLink", avg_number_unicast_rr_links_traveled); + avg_unicast_flit->addSubResult(rs_link->getEventResult("Send"), "RouterToSiteLink", avg_number_unicast_rs_links_traveled); + if(router->hasEventResult("WriteBuffer")) + { + avg_unicast_flit->addSubResult(router->getEventResult("WriteBuffer"), "MeshRouter", avg_number_unicast_router_traveled); + } + if(router->hasEventResult("ReadBuffer")) + { + avg_unicast_flit->addSubResult(router->getEventResult("ReadBuffer"), "MeshRouter", avg_number_unicast_router_traveled); + } + avg_unicast_flit->addSubResult(router->getEventResult("TraverseCrossbar->Multicast1"), "MeshRouter", avg_number_unicast_router_traveled); + + // Update broadcast event + double avg_number_broadcast_rr_links_traveled = (number_routers_per_side - 1.0) * number_routers_per_side + number_routers_per_side - 1.0; + double avg_number_broadcast_rs_links_traveled = number_sites; + double avg_number_broadcast_router_crossbar_traveled = number_routers * (number_sites_per_router + 1.0) - 2.0; + Result* avg_broadcast_flit = getEventResult("AvgBroadcast"); + avg_broadcast_flit->addSubResult(rr_link->getEventResult("Send"), "RouterToRouterLink", avg_number_broadcast_rr_links_traveled); + avg_broadcast_flit->addSubResult(rs_link->getEventResult("Send"), "RouterToSiteLink", avg_number_broadcast_rs_links_traveled); + if(router->hasEventResult("WriteBuffer")) + { + avg_broadcast_flit->addSubResult(router->getEventResult("WriteBuffer"), "MeshRouter", number_routers); + } + if(router->hasEventResult("ReadBuffer")) + { + avg_broadcast_flit->addSubResult(router->getEventResult("ReadBuffer"), "MeshRouter", number_routers); + } + avg_broadcast_flit->addSubResult(router->getEventResult("TraverseCrossbar->Multicast1"), "MeshRouter", avg_number_broadcast_router_crossbar_traveled); + + return; + } + + void ElectricalMesh::updateModel() + { + // Get properties + double site_pitch = getProperty("SitePitch").toDouble(); + double clock_freq = getParameter("Frequency"); + + ASSERT(site_pitch > 0, "[Error] " + getInstanceName() + + " -> Site pitch must be > 0!"); + ASSERT(clock_freq > 0, "[Error] " + getInstanceName() + + " -> Clock frequency must be > 0!"); + + unsigned int number_sites_per_router = getParameter("NumberSitesPerRouter"); + // Get margin on link delays, since there are registers before and after the link + double delay_ck_to_q = getTechModel()->getStdCellLib()->getStdCellCache()->get("DFFQ_X1->Delay->CK_to_Q"); + double delay_setup = getTechModel()->getStdCellLib()->getStdCellCache()->get("DFFQ_X1->Delay->CK_to_Q"); + double link_delay_margin = (delay_ck_to_q + delay_setup) * 1.5; + + double rr_link_length = site_pitch * sqrt(number_sites_per_router); + double rr_link_delay = std::max(1e-99, 1.0 / clock_freq - link_delay_margin); + double rs_link_length = site_pitch * (sqrt(number_sites_per_router) - 1.0); + double rs_link_delay = std::max(1e-99, 1.0 / clock_freq - link_delay_margin ); + double router_delay = 1.0 / clock_freq; + + Model* rr_link = getSubInstance("RouterToRouterLink"); + rr_link->setProperty("WireLength", rr_link_length); + rr_link->setProperty("Delay", rr_link_delay); + rr_link->setProperty("IsKeepParity", "TRUE"); + rr_link->update(); + + Model* rs_link = getSubInstance("RouterToSiteLink"); + rs_link->setProperty("WireLength", rs_link_length); + rs_link->setProperty("Delay", rs_link_delay); + rs_link->setProperty("IsKeepParity", "TRUE"); + rs_link->update(); + + ElectricalModel* router = (ElectricalModel*)getSubInstance("MeshRouter"); + router->update(); + + ElectricalTimingTree router_timing_tree("MeshRouter", router); + router_timing_tree.performTimingOpt(router->getNet("CK"), router_delay); + return; + } + + void ElectricalMesh::propagateTransitionInfo() + { + // Get parameters + unsigned int router_number_input_ports = getGenProperties()->get("Router->NumberInputPorts"); + + ElectricalModel* rr_link = (ElectricalModel*)getSubInstance("RouterToRouterLink"); + assignPortTransitionInfo(rr_link, "In", TransitionInfo(0.25, 0.25, 0.25)); + rr_link->use(); + + ElectricalModel* rs_link = (ElectricalModel*)getSubInstance("RouterToSiteLink"); + assignPortTransitionInfo(rs_link, "In", TransitionInfo(0.25, 0.25, 0.25)); + rs_link->use(); + + ElectricalModel* router = (ElectricalModel*)getSubInstance("MeshRouter"); + for(unsigned int i = 0; i < router_number_input_ports; ++i) + { + assignPortTransitionInfo(router, "FlitIn" + (String)i, TransitionInfo(0.25, 0.25, 0.25)); + } + assignPortTransitionInfo(router, "CK", TransitionInfo(0.0, 1.0, 0.0)); + router->getGenProperties()->set("UseModelEvent", ""); + router->use(); + + return; + } +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/network/PhotonicClos.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/network/PhotonicClos.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_NETWORK_PHOTONIC_CLOS_H__ +#define __DSENT_MODEL_NETWORK_PHOTONIC_CLOS_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" + +namespace DSENT +{ + /** + * \brief An 3-stage clos network implemented with photonic router-to-router links + */ + class PhotonicClos : public ElectricalModel + { + public: + PhotonicClos(const String& instance_name_, const TechModel* tech_model_); + virtual ~PhotonicClos(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + + // Clone and return a new instance + virtual PhotonicClos* clone() const; + + protected: + // Build the model + virtual void constructModel(); + virtual void updateModel(); + virtual void propagateTransitionInfo(); + + }; +} // namespace DSENT + +#endif // __DSENT_MODEL_NETWORK_PHOTONIC_CLOS_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/network/PhotonicClos.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/network/PhotonicClos.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,543 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/network/PhotonicClos.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/model/ModelGen.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingTree.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" + +namespace DSENT +{ + using std::sqrt; + + PhotonicClos::PhotonicClos(const String& instance_name_, const TechModel* tech_model_) + : ElectricalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + PhotonicClos::~PhotonicClos() + {} + + void PhotonicClos::initParameters() + { + // Clock Frequency + addParameterName("Frequency"); + // Physical Parameters + addParameterName("NumberInputSites"); + addParameterName("NumberOutputSites"); + addParameterName("NumberBitsPerFlit"); + // Number of each type of routers + addParameterName("NumberIngressRouters"); + addParameterName("NumberMiddleRouters"); + addParameterName("NumberEgressRouters"); + // Optical link parameters + addParameterName("SWSR->LinkDataRate"); + addParameterName("SWSR->LaserType"); + addParameterName("SWSR->RingTuningMethod"); + // Router parameters + addParameterName("Router->NumberVirtualNetworks"); + addParameterName("Router->NumberVirtualChannelsPerVirtualNetwork"); + addParameterName("Router->NumberBuffersPerVirtualChannel"); + addParameterName("Router->InputPort->BufferModel"); + addParameterName("Router->CrossbarModel"); + addParameterName("Router->SwitchAllocator->ArbiterModel"); + addParameterName("Router->ClockTreeModel"); + addParameterName("Router->ClockTree->NumberLevels"); + addParameterName("Router->ClockTree->WireLayer"); + addParameterName("Router->ClockTree->WireWidthMultiplier"); + addParameterName("Router->ClockTree->WireSpacingMultiplier", 3.0); + // Link parameters + addParameterName("Link->WireLayer"); + addParameterName("Link->WireWidthMultiplier"); + addParameterName("Link->WireSpacingMultiplier"); + return; + } + + void PhotonicClos::initProperties() + { + addPropertyName("InputSitePitch"); + addPropertyName("OutputSitePitch"); + addPropertyName("SWSR->OptUtil", 1.0); + return; + } + + PhotonicClos* PhotonicClos::clone() const + { + // TODO + return NULL; + } + + void PhotonicClos::constructModel() + { + // Get input parameters + double clock_freq = getParameter("Frequency"); + unsigned int number_input_sites = getParameter("NumberInputSites").toUInt(); + unsigned int number_output_sites = getParameter("NumberOutputSites").toUInt(); + unsigned int number_bits_per_flit = getParameter("NumberBitsPerFlit").toUInt(); + unsigned int number_ingress_routers = getParameter("NumberIngressRouters").toUInt(); + unsigned int number_middle_routers = getParameter("NumberMiddleRouters").toUInt(); + unsigned int number_egress_routers = getParameter("NumberEgressRouters").toUInt(); + + ASSERT(clock_freq > 0, "[Error] " + getInstanceName() + + " -> Clock frequency must be > 0!"); + ASSERT(number_input_sites > 0, "[Error] " + getInstanceName() + + " -> Number of input sites must be > 0!"); + ASSERT(number_output_sites > 0, "[Error] " + getInstanceName() + + " -> Number of output sites must be > 0!"); + ASSERT(number_bits_per_flit > 0, "[Error] " + getInstanceName() + + " -> Number of bits per flit must be > 0!"); + ASSERT(number_ingress_routers > 0, "[Error] " + getInstanceName() + + " -> Number of ingress routers must be > 0!"); + ASSERT(number_middle_routers > 0, "[Error] " + getInstanceName() + + " -> Number of middle routers must be > 0!"); + ASSERT(number_egress_routers > 0, "[Error] " + getInstanceName() + + " -> Number of egress routers must be > 0!"); + + // Get input parameters that will be forwarded to the sub instances + const String& swsr_link_data_rate = getParameter("SWSR->LinkDataRate"); + const String& swsr_laser_type = getParameter("SWSR->LaserType"); + const String& swsr_ring_tuning_method = getParameter("SWSR->RingTuningMethod"); + const String& router_number_vns = getParameter("Router->NumberVirtualNetworks"); + const String& router_number_vcs_per_vn = getParameter("Router->NumberVirtualChannelsPerVirtualNetwork"); + const String& router_number_bufs_per_vc = getParameter("Router->NumberBuffersPerVirtualChannel"); + const String& router_buffer_model = getParameter("Router->InputPort->BufferModel"); + const String& router_crossbar_model = getParameter("Router->CrossbarModel"); + const String& link_wire_layer = getParameter("Link->WireLayer"); + const String& link_wire_width_multiplier = getParameter("Link->WireWidthMultiplier"); + const String& link_wire_spacing_multiplier = getParameter("Link->WireSpacingMultiplier"); + + // Calculate properties from input parameters + unsigned int ingress_router_number_input_ports = number_input_sites / number_ingress_routers; + unsigned int ingress_router_number_output_ports = number_middle_routers; + unsigned int middle_router_number_input_ports = number_ingress_routers; + unsigned int middle_router_number_output_ports = number_egress_routers; + unsigned int egress_router_number_input_ports = number_middle_routers; + unsigned int egress_router_number_output_ports = number_output_sites / number_egress_routers; + unsigned int number_input_to_ingress_links = number_input_sites; + unsigned int number_ingress_to_middle_links = number_ingress_routers * number_middle_routers; + unsigned int number_middle_to_egress_links = number_middle_routers * number_egress_routers; + unsigned int number_egress_to_output_links = number_output_sites; + + getGenProperties()->set("NumberInputSitesPerIngressRouter", ingress_router_number_input_ports); + getGenProperties()->set("NumberOutputSitesPerEgressRouter", egress_router_number_output_ports); + getGenProperties()->set("IngressRouter->NumberInputPorts", ingress_router_number_input_ports); + getGenProperties()->set("IngressRouter->NumberOutputPorts", ingress_router_number_output_ports); + getGenProperties()->set("MiddleRouter->NumberInputPorts", middle_router_number_input_ports); + getGenProperties()->set("MiddleRouter->NumberOutputPorts", middle_router_number_output_ports); + getGenProperties()->set("EgressRouter->NumberInputPorts", egress_router_number_input_ports); + getGenProperties()->set("EgressRouter->NumberOutputPorts", egress_router_number_output_ports); + + // Create ports + createInputPort("CK"); + + // Init ingress router + ElectricalModel* ingress_router = (ElectricalModel*)ModelGen::createModel("Router", "IngressRouter", getTechModel()); + ingress_router->setParameter("NumberInputPorts", ingress_router_number_input_ports); + ingress_router->setParameter("NumberOutputPorts", ingress_router_number_output_ports); + ingress_router->setParameter("NumberVirtualNetworks", router_number_vns); + ingress_router->setParameter("NumberVirtualChannelsPerVirtualNetwork", router_number_vcs_per_vn); + ingress_router->setParameter("NumberBuffersPerVirtualChannel", router_number_bufs_per_vc); + ingress_router->setParameter("NumberBitsPerFlit", number_bits_per_flit); + ingress_router->setParameter("InputPort->BufferModel", router_buffer_model); + ingress_router->setParameter("CrossbarModel", router_crossbar_model); + ingress_router->setParameter("SwitchAllocator->ArbiterModel", getParameter("Router->SwitchAllocator->ArbiterModel")); + ingress_router->setParameter("ClockTreeModel", getParameter("Router->ClockTreeModel")); + ingress_router->setParameter("ClockTree->NumberLevels", getParameter("Router->ClockTree->NumberLevels")); + ingress_router->setParameter("ClockTree->WireLayer", getParameter("Router->ClockTree->WireLayer")); + ingress_router->setParameter("ClockTree->WireWidthMultiplier", getParameter("Router->ClockTree->WireWidthMultiplier")); + ingress_router->setParameter("ClockTree->WireSpacingMultiplier", getParameter("Router->ClockTree->WireSpacingMultiplier")); + ingress_router->construct(); + // Init middle routers + ElectricalModel* middle_router = (ElectricalModel*)ModelGen::createModel("Router", "MiddleRouter", getTechModel()); + middle_router->setParameter("NumberInputPorts", middle_router_number_input_ports); + middle_router->setParameter("NumberOutputPorts", middle_router_number_output_ports); + middle_router->setParameter("NumberVirtualNetworks", router_number_vns); + middle_router->setParameter("NumberVirtualChannelsPerVirtualNetwork", router_number_vcs_per_vn); + middle_router->setParameter("NumberBuffersPerVirtualChannel", router_number_bufs_per_vc); + middle_router->setParameter("NumberBitsPerFlit", number_bits_per_flit); + middle_router->setParameter("InputPort->BufferModel", router_buffer_model); + middle_router->setParameter("CrossbarModel", router_crossbar_model); + middle_router->setParameter("SwitchAllocator->ArbiterModel", getParameter("Router->SwitchAllocator->ArbiterModel")); + middle_router->setParameter("ClockTreeModel", getParameter("Router->ClockTreeModel")); + middle_router->setParameter("ClockTree->NumberLevels", getParameter("Router->ClockTree->NumberLevels")); + middle_router->setParameter("ClockTree->WireLayer", getParameter("Router->ClockTree->WireLayer")); + middle_router->setParameter("ClockTree->WireWidthMultiplier", getParameter("Router->ClockTree->WireWidthMultiplier")); + middle_router->setParameter("ClockTree->WireSpacingMultiplier", getParameter("Router->ClockTree->WireSpacingMultiplier")); + middle_router->construct(); + // Init egress routers + ElectricalModel* egress_router = (ElectricalModel*)ModelGen::createModel("Router", "EgressRouter", getTechModel()); + egress_router->setParameter("NumberInputPorts", egress_router_number_input_ports); + egress_router->setParameter("NumberOutputPorts", egress_router_number_output_ports); + egress_router->setParameter("NumberVirtualNetworks", router_number_vns); + egress_router->setParameter("NumberVirtualChannelsPerVirtualNetwork", router_number_vcs_per_vn); + egress_router->setParameter("NumberBuffersPerVirtualChannel", router_number_bufs_per_vc); + egress_router->setParameter("NumberBitsPerFlit", number_bits_per_flit); + egress_router->setParameter("InputPort->BufferModel", router_buffer_model); + egress_router->setParameter("CrossbarModel", router_crossbar_model); + egress_router->setParameter("SwitchAllocator->ArbiterModel", getParameter("Router->SwitchAllocator->ArbiterModel")); + egress_router->setParameter("ClockTreeModel", getParameter("Router->ClockTreeModel")); + egress_router->setParameter("ClockTree->NumberLevels", getParameter("Router->ClockTree->NumberLevels")); + egress_router->setParameter("ClockTree->WireLayer", getParameter("Router->ClockTree->WireLayer")); + egress_router->setParameter("ClockTree->WireWidthMultiplier", getParameter("Router->ClockTree->WireWidthMultiplier")); + egress_router->setParameter("ClockTree->WireSpacingMultiplier", getParameter("Router->ClockTree->WireSpacingMultiplier")); + egress_router->construct(); + // Init input to ingress link + ElectricalModel* input_to_ingress_link = (ElectricalModel*)ModelGen::createModel("RepeatedLink", "InputToIngressLink", getTechModel()); + input_to_ingress_link->setParameter("NumberBits", number_bits_per_flit); + input_to_ingress_link->setParameter("WireLayer", link_wire_layer); + input_to_ingress_link->setParameter("WireWidthMultiplier", link_wire_width_multiplier); + input_to_ingress_link->setParameter("WireSpacingMultiplier", link_wire_spacing_multiplier); + input_to_ingress_link->construct(); + // Init ingress to middle link + ElectricalModel* ingress_to_middle_link = (ElectricalModel*)ModelGen::createModel("SWSRLink", "IngressToMiddleLink", getTechModel()); + ingress_to_middle_link->setParameter("NumberBits", number_bits_per_flit); + ingress_to_middle_link->setParameter("CoreDataRate", clock_freq); + ingress_to_middle_link->setParameter("LinkDataRate", swsr_link_data_rate); + ingress_to_middle_link->setParameter("LaserType", swsr_laser_type); + ingress_to_middle_link->setParameter("RingTuningMethod", swsr_ring_tuning_method); + ingress_to_middle_link->construct(); + // Init middle to egress link + ElectricalModel* middle_to_egress_link = (ElectricalModel*)ModelGen::createModel("SWSRLink", "MiddleToEgressLink", getTechModel()); + middle_to_egress_link->setParameter("NumberBits", number_bits_per_flit); + middle_to_egress_link->setParameter("CoreDataRate", clock_freq); + middle_to_egress_link->setParameter("LinkDataRate", swsr_link_data_rate); + middle_to_egress_link->setParameter("LaserType", swsr_laser_type); + middle_to_egress_link->setParameter("RingTuningMethod", swsr_ring_tuning_method); + middle_to_egress_link->construct(); + // Init egress to output link + ElectricalModel* egress_to_output_link = (ElectricalModel*)ModelGen::createModel("RepeatedLink", "EgressToOutputLink", getTechModel()); + egress_to_output_link->setParameter("NumberBits", number_bits_per_flit); + egress_to_output_link->setParameter("WireLayer", link_wire_layer); + egress_to_output_link->setParameter("WireWidthMultiplier", link_wire_width_multiplier); + egress_to_output_link->setParameter("WireSpacingMultiplier", link_wire_spacing_multiplier); + egress_to_output_link->construct(); + + // Connect ports + createNet("InputToIngressLink_Out", makeNetIndex(0, number_bits_per_flit - 1)); + createNet("InputToIngressLink_In", makeNetIndex(0, number_bits_per_flit - 1)); + portConnect(input_to_ingress_link, "In", "InputToIngressLink_In"); + portConnect(input_to_ingress_link, "Out", "InputToIngressLink_Out"); + + createNet("IngressToMiddleLink_In", makeNetIndex(0, number_bits_per_flit - 1)); + createNet("IngressToMiddleLink_Out", makeNetIndex(0, number_bits_per_flit - 1)); + portConnect(ingress_to_middle_link, "In", "IngressToMiddleLink_In"); + portConnect(ingress_to_middle_link, "Out", "IngressToMiddleLink_Out"); + + createNet("MiddleToEgressLink_In", makeNetIndex(0, number_bits_per_flit - 1)); + createNet("MiddleToEgressLink_Out", makeNetIndex(0, number_bits_per_flit - 1)); + portConnect(middle_to_egress_link, "In", "MiddleToEgressLink_In"); + portConnect(middle_to_egress_link, "Out", "MiddleToEgressLink_Out"); + + createNet("EgressToOutputLink_In", makeNetIndex(0, number_bits_per_flit - 1)); + createNet("EgressToOutputLink_Out", makeNetIndex(0, number_bits_per_flit - 1)); + portConnect(egress_to_output_link, "In", "EgressToOutputLink_In"); + portConnect(egress_to_output_link, "Out", "EgressToOutputLink_Out"); + + portConnect(ingress_router, "CK", "CK"); + for(unsigned int i = 0; i < ingress_router_number_input_ports; ++i) + { + createNet("IngressRouter_In" + (String)i, makeNetIndex(0, number_bits_per_flit-1)); + for (unsigned int j = 0; j < number_bits_per_flit; ++j) + assignVirtualFanout("IngressRouter_In" + (String)i, makeNetIndex(j), "InputToIngressLink_Out", makeNetIndex(j)); + portConnect(ingress_router, "FlitIn" + (String)i, "IngressRouter_In" + (String)i); + } + for(unsigned int i = 0; i < ingress_router_number_output_ports; ++i) + { + // VFI + portConnect(ingress_router, "FlitOut" + (String)i, "IngressToMiddleLink_In"); + } + portConnect(middle_router, "CK", "CK"); + for(unsigned int i = 0; i < middle_router_number_input_ports; ++i) + { + createNet("MiddleRouter_In" + (String)i, makeNetIndex(0, number_bits_per_flit-1)); + for (unsigned int j = 0; j < number_bits_per_flit; ++j) + assignVirtualFanout("MiddleRouter_In" + (String)i, makeNetIndex(j), "IngressToMiddleLink_Out", makeNetIndex(j)); + portConnect(middle_router, "FlitIn" + (String)i, "MiddleRouter_In" + (String)i); + } + for(unsigned int i = 0; i < middle_router_number_output_ports; ++i) + { + // VFI + portConnect(middle_router, "FlitOut" + (String)i, "MiddleToEgressLink_In"); + } + portConnect(egress_router, "CK", "CK"); + for(unsigned int i = 0; i < egress_router_number_input_ports; ++i) + { + createNet("EgressRouter_In" + (String)i, makeNetIndex(0, number_bits_per_flit-1)); + for (unsigned int j = 0; j < number_bits_per_flit; ++j) + assignVirtualFanout("EgressRouter_In" + (String)i, makeNetIndex(j), "MiddleToEgressLink_Out", makeNetIndex(j)); + portConnect(egress_router, "FlitIn" + (String)i, "EgressRouter_In" + (String)i); + } + for(unsigned int i = 0; i < egress_router_number_output_ports; ++i) + { + // VFI + portConnect(egress_router, "FlitOut" + (String)i, "EgressToOutputLink_In"); + } + + // Create area, power, and event results + createElectricalResults(); + createElectricalEventResult("AvgUnicast"); + createElectricalEventResult("AvgBroadcast"); + addNddPowerResult(new Result("Laser")); + addNddPowerResult(new Result("RingTuning")); + addAreaResult(new Result("Photonic")); + + // Add all instances + addSubInstances(ingress_router, number_ingress_routers); + addElectricalSubResults(ingress_router, number_ingress_routers); + addSubInstances(middle_router, number_middle_routers); + addElectricalSubResults(middle_router, number_middle_routers); + addSubInstances(egress_router, number_egress_routers); + addElectricalSubResults(egress_router, number_egress_routers); + addSubInstances(input_to_ingress_link, number_input_to_ingress_links); + addElectricalSubResults(input_to_ingress_link, number_input_to_ingress_links); + addSubInstances(ingress_to_middle_link, number_ingress_to_middle_links); + addElectricalSubResults(ingress_to_middle_link, number_ingress_to_middle_links); + getAreaResult("Photonic")->addSubResult(ingress_to_middle_link->getAreaResult("Photonic"), "IngressToMiddleLink", number_ingress_to_middle_links); + getNddPowerResult("Laser")->addSubResult(ingress_to_middle_link->getNddPowerResult("Laser"), "IngressToMiddleLink", number_ingress_to_middle_links); + getNddPowerResult("RingTuning")->addSubResult(ingress_to_middle_link->getNddPowerResult("RingTuning"), "IngressToMiddleLink", number_ingress_to_middle_links); + addSubInstances(middle_to_egress_link, number_middle_to_egress_links); + addElectricalSubResults(middle_to_egress_link, number_middle_to_egress_links); + getAreaResult("Photonic")->addSubResult(middle_to_egress_link->getAreaResult("Photonic"), "MiddletoEgressLink", number_middle_to_egress_links); + getNddPowerResult("Laser")->addSubResult(middle_to_egress_link->getNddPowerResult("Laser"), "MiddleToEgressLink", number_middle_to_egress_links); + getNddPowerResult("RingTuning")->addSubResult(middle_to_egress_link->getNddPowerResult("RingTuning"), "MiddleToEgressLink", number_middle_to_egress_links); + addSubInstances(egress_to_output_link, number_egress_to_output_links); + addElectricalSubResults(egress_to_output_link, number_egress_to_output_links); + + // Update unicast event + Result* avg_unicast_event = getEventResult("AvgUnicast"); + avg_unicast_event->addSubResult(input_to_ingress_link->getEventResult("Send"), "InputToIngressLink", 1.0); + if(ingress_router->hasEventResult("WriteBuffer")) + { + avg_unicast_event->addSubResult(ingress_router->getEventResult("WriteBuffer"), "IngressRouter", 1.0); + } + if(ingress_router->hasEventResult("ReadBuffer")) + { + avg_unicast_event->addSubResult(ingress_router->getEventResult("ReadBuffer"), "IngressRouter", 1.0); + } + avg_unicast_event->addSubResult(ingress_router->getEventResult("TraverseCrossbar->Multicast1"), "IngressRouter", 1.0); + avg_unicast_event->addSubResult(ingress_to_middle_link->getEventResult("Send"), "IngressToMiddleLink", 1.0); + if(middle_router->hasEventResult("WriteBuffer")) + { + avg_unicast_event->addSubResult(middle_router->getEventResult("WriteBuffer"), "MiddleRouter", 1.0); + } + if(middle_router->hasEventResult("ReadBuffer")) + { + avg_unicast_event->addSubResult(middle_router->getEventResult("ReadBuffer"), "MiddleRouter", 1.0); + } + avg_unicast_event->addSubResult(middle_router->getEventResult("TraverseCrossbar->Multicast1"), "MiddleRouter", 1.0); + avg_unicast_event->addSubResult(middle_to_egress_link->getEventResult("Send"), "MiddleToEgressLink", 1.0); + if(egress_router->hasEventResult("WriteBuffer")) + { + avg_unicast_event->addSubResult(egress_router->getEventResult("WriteBuffer"), "EgressRouter", 1.0); + } + if(egress_router->hasEventResult("ReadBuffer")) + { + avg_unicast_event->addSubResult(egress_router->getEventResult("ReadBuffer"), "EgressRouter", 1.0); + } + avg_unicast_event->addSubResult(egress_router->getEventResult("TraverseCrossbar->Multicast1"), "EgressRouter", 1.0); + avg_unicast_event->addSubResult(egress_to_output_link->getEventResult("Send"), "EgressToOutputLink", 1.0); + + // Update broadcast event + Result* avg_broadcast_event = getEventResult("AvgBroadcast"); + avg_broadcast_event->addSubResult(input_to_ingress_link->getEventResult("Send"), "InputToIngressLink", 1.0); + if(ingress_router->hasEventResult("WriteBuffer")) + { + avg_broadcast_event->addSubResult(ingress_router->getEventResult("WriteBuffer"), "IngressRouter", 1.0); + } + if(ingress_router->hasEventResult("ReadBuffer")) + { + avg_broadcast_event->addSubResult(ingress_router->getEventResult("ReadBuffer"), "IngressRouter", 1.0); + } + avg_broadcast_event->addSubResult(ingress_router->getEventResult("TraverseCrossbar->Multicast1"), "IngressRouter", 1.0); + avg_broadcast_event->addSubResult(ingress_to_middle_link->getEventResult("Send"), "IngressToMiddleLink", 1.0); + if(middle_router->hasEventResult("WriteBuffer")) + { + avg_broadcast_event->addSubResult(middle_router->getEventResult("WriteBuffer"), "MiddleRouter", 1.0); + } + if(middle_router->hasEventResult("ReadBuffer")) + { + avg_broadcast_event->addSubResult(middle_router->getEventResult("ReadBuffer"), "MiddleRouter", 1.0); + } + avg_broadcast_event->addSubResult(middle_router->getEventResult("TraverseCrossbar->Multicast1"), "MiddleRouter", 1.0); + avg_broadcast_event->addSubResult(middle_to_egress_link->getEventResult("Send"), "MiddleToEgressLink", number_egress_routers); + if(egress_router->hasEventResult("WriteBuffer")) + { + avg_broadcast_event->addSubResult(egress_router->getEventResult("WriteBuffer"), "EgressRouter", number_egress_routers); + } + if(egress_router->hasEventResult("ReadBuffer")) + { + avg_broadcast_event->addSubResult(egress_router->getEventResult("ReadBuffer"), "EgressRouter", number_egress_routers); + } + avg_broadcast_event->addSubResult(egress_router->getEventResult("TraverseCrossbar->Multicast" + (String)number_egress_routers), "EgressRouter", 1.0); + avg_broadcast_event->addSubResult(egress_to_output_link->getEventResult("Send"), "EgressToOutputLink", number_output_sites); + return; + } + + void PhotonicClos::updateModel() + { + // Assumes waveguide runs adjacent to ingress and egress routers + // Assumes input sites belonging to each ingress router are centered around the ingress router + // Assumes middle routers are distributed around the chip adjacent to the main waveguide + // Assumes output sites belonging to each egress router are centered around the egress router + + // Get properties + double input_site_pitch = getProperty("InputSitePitch").toDouble(); + double output_site_pitch = getProperty("OutputSitePitch").toDouble(); + double clock_freq = getParameter("Frequency"); + const double swsr_opt_util = getProperty("SWSR->OptUtil"); + + ASSERT(input_site_pitch > 0, "[Error] " + getInstanceName() + + " -> Input site pitch must be > 0!"); + ASSERT(output_site_pitch > 0, "[Error] " + getInstanceName() + + " -> Output site pitch must be > 0!"); + + unsigned int number_input_sites_per_ingress_router = getGenProperties()->get("NumberInputSitesPerIngressRouter"); + unsigned int number_ingress_routers = getParameter("NumberIngressRouters"); + unsigned int number_output_sites_per_egress_router = getGenProperties()->get("NumberOutputSitesPerEgressRouter"); + unsigned int number_egress_routers = getParameter("NumberEgressRouters"); + double delay = 1.0 / clock_freq; + + //Calculate the length of the waveguide + double input_to_ingress_link_length = input_site_pitch * (sqrt(number_input_sites_per_ingress_router) - 1.0); + double input_to_ingress_link_delay = delay * 0.8; + double ingress_to_middle_link_length = input_site_pitch * (sqrt(number_input_sites_per_ingress_router) * number_ingress_routers); + double middle_to_egress_link_length = output_site_pitch * (sqrt(number_output_sites_per_egress_router) * number_egress_routers); + double egress_to_output_link_length = output_site_pitch * (sqrt(number_output_sites_per_egress_router) - 1.0); + double egress_to_output_link_delay = delay * 0.8; + double ingress_router_delay = delay; + double middle_router_delay = delay; + double egress_router_delay = delay; + + Model* input_to_ingress_link = getSubInstance("InputToIngressLink"); + input_to_ingress_link->setProperty("WireLength", input_to_ingress_link_length); + input_to_ingress_link->setProperty("Delay", input_to_ingress_link_delay); + input_to_ingress_link->setProperty("IsKeepParity", "TRUE"); + input_to_ingress_link->update(); + + Model* ingress_to_middle_link = getSubInstance("IngressToMiddleLink"); + ingress_to_middle_link->setProperty("Length", ingress_to_middle_link_length); + ingress_to_middle_link->setProperty("OptUtil", swsr_opt_util); + ingress_to_middle_link->update(); + + Model* middle_to_egress_link = getSubInstance("MiddleToEgressLink"); + middle_to_egress_link->setProperty("Length", middle_to_egress_link_length); + middle_to_egress_link->setProperty("OptUtil", swsr_opt_util); + middle_to_egress_link->update(); + + Model* egress_to_output_link = getSubInstance("EgressToOutputLink"); + egress_to_output_link->setProperty("WireLength", egress_to_output_link_length); + egress_to_output_link->setProperty("Delay", egress_to_output_link_delay); + egress_to_output_link->setProperty("IsKeepParity", "TRUE"); + egress_to_output_link->update(); + + ElectricalModel* ingress_router = (ElectricalModel*)getSubInstance("IngressRouter"); + ingress_router->update(); + ElectricalTimingTree ingress_router_timing_tree("IngressRouter", ingress_router); + ingress_router_timing_tree.performTimingOpt(ingress_router->getNet("CK"), ingress_router_delay); + + ElectricalModel* middle_router = (ElectricalModel*)getSubInstance("MiddleRouter"); + middle_router->update(); + ElectricalTimingTree middle_router_timing_tree("MiddleRouter", middle_router); + middle_router_timing_tree.performTimingOpt(middle_router->getNet("CK"), middle_router_delay); + + ElectricalModel* egress_router = (ElectricalModel*)getSubInstance("EgressRouter"); + egress_router->update(); + ElectricalTimingTree egress_router_timing_tree("EgressRouter", egress_router); + egress_router_timing_tree.performTimingOpt(egress_router->getNet("CK"), egress_router_delay); + + return; + } + + void PhotonicClos::propagateTransitionInfo() + { + // Get parameters + double clock_freq = getParameter("Frequency"); + double swsr_link_data_rate = getParameter("SWSR->LinkDataRate"); + + // Get properties + unsigned int ingress_router_number_input_ports = getGenProperties()->get("IngressRouter->NumberInputPorts"); + unsigned int middle_router_number_input_ports = getGenProperties()->get("MiddleRouter->NumberInputPorts"); + unsigned int egress_router_number_input_ports = getGenProperties()->get("EgressRouter->NumberInputPorts"); + + ElectricalModel* input_to_ingress_link = (ElectricalModel*)getSubInstance("InputToIngressLink"); + assignPortTransitionInfo(input_to_ingress_link, "In", TransitionInfo(0.25, 0.25, 0.25)); + input_to_ingress_link->use(); + + ElectricalModel* ingress_to_middle_link = (ElectricalModel*)getSubInstance("IngressToMiddleLink"); + assignPortTransitionInfo(ingress_to_middle_link, "LinkCK", TransitionInfo(0.0, (double) clock_freq / (swsr_link_data_rate * 2.0), 0.0)); + assignPortTransitionInfo(ingress_to_middle_link, "In", TransitionInfo(0.25, 0.25, 0.25)); + ingress_to_middle_link->use(); + + ElectricalModel* middle_to_egress_link = (ElectricalModel*)getSubInstance("MiddleToEgressLink"); + assignPortTransitionInfo(middle_to_egress_link, "LinkCK", TransitionInfo(0.0, (double) clock_freq / (swsr_link_data_rate * 2.0), 0.0)); + assignPortTransitionInfo(middle_to_egress_link, "In", TransitionInfo(0.25, 0.25, 0.25)); + middle_to_egress_link->use(); + + ElectricalModel* egress_to_output_link = (ElectricalModel*)getSubInstance("EgressToOutputLink"); + assignPortTransitionInfo(egress_to_output_link, "In", TransitionInfo(0.25, 0.25, 0.25)); + egress_to_output_link->use(); + + ElectricalModel* ingress_router = (ElectricalModel*)getSubInstance("IngressRouter"); + for(unsigned int i = 0; i < ingress_router_number_input_ports; ++i) + { + assignPortTransitionInfo(ingress_router, "FlitIn" + (String)i, TransitionInfo(0.25, 0.25, 0.25)); + } + assignPortTransitionInfo(ingress_router, "CK", TransitionInfo(0.0, 1.0, 0.0)); + ingress_router->getGenProperties()->set("UseModelEvent", ""); + ingress_router->use(); + + ElectricalModel* middle_router = (ElectricalModel*)getSubInstance("MiddleRouter"); + for(unsigned int i = 0; i < middle_router_number_input_ports; ++i) + { + assignPortTransitionInfo(middle_router, "FlitIn" + (String)i, TransitionInfo(0.25, 0.25, 0.25)); + } + assignPortTransitionInfo(middle_router, "CK", TransitionInfo(0.0, 1.0, 0.0)); + middle_router->getGenProperties()->set("UseModelEvent", ""); + middle_router->use(); + + ElectricalModel* egress_router = (ElectricalModel*)getSubInstance("EgressRouter"); + for(unsigned int i = 0; i < egress_router_number_input_ports; ++i) + { + assignPortTransitionInfo(egress_router, "FlitIn" + (String)i, TransitionInfo(0.25, 0.25, 0.25)); + } + assignPortTransitionInfo(egress_router, "CK", TransitionInfo(0.0, 1.0, 0.0)); + egress_router->getGenProperties()->set("UseModelEvent", ""); + egress_router->use(); + + return; + } +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/network/SConscript --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/network/SConscript Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,36 @@ +# 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. +# +# Authors: Chia-Hsin Owen Chen + +Import('*') + +if env['PROTOCOL'] == 'None': + Return() + +Source('ElectricalMesh.cc') +Source('PhotonicClos.cc') +Source('ElectricalClos.cc') + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical/GatedLaserSource.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical/GatedLaserSource.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_OPTICAL_GATEDLASERSOURCE_H__ +#define __DSENT_MODEL_OPTICAL_GATEDLASERSOURCE_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/OpticalModel.hh" + +namespace DSENT +{ + // A laser source that outputs some number of wavelengths. This laser + // full on/off power gating, thus all power are event-based energies + class GatedLaserSource : public OpticalModel + { + public: + GatedLaserSource(const String& instance_name_, const TechModel* tech_model_); + virtual ~GatedLaserSource(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + + protected: + // Build the model + void constructModel(); + void updateModel(); + void evaluateModel(); + + }; // class GatedLaserSource +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICAL_GATEDLASERSOURCE_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical/GatedLaserSource.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical/GatedLaserSource.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/optical/GatedLaserSource.hh" + +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalWaveguide.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalWavelength.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalLaser.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalGraph.hh" + +namespace DSENT +{ + GatedLaserSource::GatedLaserSource(const String& instance_name_, const TechModel* tech_model_) + : OpticalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + GatedLaserSource::~GatedLaserSource() + {} + + void GatedLaserSource::initParameters() + { + addParameterName("OutStart"); + addParameterName("OutEnd"); + addParameterName("MaxDetectors"); + return; + } + + void GatedLaserSource::initProperties() + { + addPropertyName("OptUtil", 1.0); + addPropertyName("LaserEventTime"); + return; + } + + void GatedLaserSource::constructModel() + { + // Create Area result + Result* area_result = new AtomicResult("Photonic"); + addAreaResult(area_result); + // Create NDD power result + Result* energy_result = new AtomicResult("Laser"); + addEventResult(energy_result); + + // Get parameters + WavelengthGroup laser_wavelengths = makeWavelengthGroup(getParameter("OutStart"), getParameter("OutEnd")); + + // Create optical ports + createOpticalOutputPort( "Out", laser_wavelengths); + // Create the filter + createLaser( "Laser", laser_wavelengths); + OpticalLaser* laser = getLaser("Laser"); + // Connect the laser to the output + laser->addDownstreamNode(getWaveguide("Out")); + } + + void GatedLaserSource::updateModel() + { + // Get properties + double laser_efficiency = getTechModel()->get("Laser->CW->Efficiency"); + double laser_area = getTechModel()->get("Laser->CW->Area"); + double laser_diode_loss = getTechModel()->get("Laser->CW->LaserDiodeLoss"); + + // Get parameters + WavelengthGroup laser_wavelengths = makeWavelengthGroup(getParameter("OutStart"), getParameter("OutEnd")); + unsigned int number_wavelengths = laser_wavelengths.second - laser_wavelengths.first + 1; + // Update losses + OpticalLaser* laser = getLaser("Laser"); + laser->setLoss(laser_diode_loss); + laser->setEfficiency(laser_efficiency); + // Update area + getAreaResult("Photonic")->setValue(laser_area * number_wavelengths); + } + + void GatedLaserSource::evaluateModel() + { + // Get parameters + unsigned int max_detectors = getParameter("MaxDetectors"); + double laser_event_time = getProperty("LaserEventTime"); + WavelengthGroup laser_wavelengths = makeWavelengthGroup(getParameter("OutStart"), getParameter("OutEnd")); + + // Get properties + double opt_util = getProperty("OptUtil"); + + // Create optical graph object + OpticalGraph* optical_graph = new OpticalGraph("LaserTrace", this); + // Ask optical graph object to perform power optimization + bool success = optical_graph->performPowerOpt(getLaser("Laser"), laser_wavelengths, max_detectors, opt_util); + if (!success) + { + Log::printLine(std::cerr, "[Warning] " + getInstanceName() + + " -> Wavelengths contains data paths with no possible modulator configurations!"); + } + // Trace the wavelengths the laser is outputting to find the output + // power needed by the laser + OpticalWavelength* wavelength = optical_graph->traceWavelength(laser_wavelengths, getLaser("Laser")); + // Calculate the power needed by the wavelength + double laser_power = wavelength->getLaserPower(max_detectors); + // Calculate NDD power + getEventResult("Laser")->setValue(laser_power * laser_event_time); + + delete wavelength; + delete optical_graph; + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical/LaserSource.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical/LaserSource.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_OPTICAL_LASERSOURCE_H__ +#define __DSENT_MODEL_OPTICAL_LASERSOURCE_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/OpticalModel.hh" + +namespace DSENT +{ + // A laser source that outputs some number of wavelengths. This laser cannot + // be gated on/off at will and thus constitutes an NDD Power consumer + class LaserSource : public OpticalModel + { + public: + LaserSource(const String& instance_name_, const TechModel* tech_model_); + virtual ~LaserSource(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + + protected: + // Build the model + void constructModel(); + void updateModel(); + void evaluateModel(); + + }; // class LaserSource +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICAL_LASERSOURCE_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical/LaserSource.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical/LaserSource.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/optical/LaserSource.hh" + +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalWaveguide.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalWavelength.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalLaser.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalGraph.hh" + +namespace DSENT +{ + LaserSource::LaserSource(const String& instance_name_, const TechModel* tech_model_) + : OpticalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + LaserSource::~LaserSource() + {} + + void LaserSource::initParameters() + { + addParameterName("OutStart"); + addParameterName("OutEnd"); + addParameterName("MaxDetectors"); + return; + } + + void LaserSource::initProperties() + { + addPropertyName("OptUtil", 1.0); + return; + } + + void LaserSource::constructModel() + { + // Create Area result + Result* area_result = new AtomicResult("Photonic"); + addAreaResult(area_result); + // Create NDD power result + Result* power_result = new AtomicResult("Laser"); + addNddPowerResult(power_result); + + // Get parameters + WavelengthGroup laser_wavelengths = makeWavelengthGroup(getParameter("OutStart"), getParameter("OutEnd")); + + // Create optical ports + createOpticalOutputPort( "Out", laser_wavelengths); + // Create the filter + createLaser( "Laser", laser_wavelengths); + OpticalLaser* laser = getLaser("Laser"); + // Connect the laser to the output + laser->addDownstreamNode(getWaveguide("Out")); + } + + void LaserSource::updateModel() + { + // Get properties + double laser_efficiency = getTechModel()->get("Laser->CW->Efficiency").toDouble(); + double laser_area = getTechModel()->get("Laser->CW->Area").toDouble(); + double laser_diode_loss = getTechModel()->get("Laser->CW->LaserDiodeLoss"); + + // Get parameters + WavelengthGroup laser_wavelengths = makeWavelengthGroup(getParameter("OutStart"), getParameter("OutEnd")); + unsigned int number_wavelengths = laser_wavelengths.second - laser_wavelengths.first + 1; + // Update losses + OpticalLaser* laser = getLaser("Laser"); + laser->setLoss(laser_diode_loss); + laser->setEfficiency(laser_efficiency); + // Update area + getAreaResult("Photonic")->setValue(laser_area * number_wavelengths); + } + + void LaserSource::evaluateModel() + { + // Get parameters + unsigned int max_detectors = getParameter("MaxDetectors").toUInt(); + WavelengthGroup laser_wavelengths = makeWavelengthGroup(getParameter("OutStart"), getParameter("OutEnd")); + + // Get properties + double opt_util = getProperty("OptUtil"); + + // Create optical graph object + OpticalGraph* optical_graph = new OpticalGraph("LaserTrace", this); + // Ask optical graph object to perform power optimization + bool success = optical_graph->performPowerOpt(getLaser("Laser"), laser_wavelengths, max_detectors, opt_util); + if (!success) + { + Log::printLine(std::cerr, "[Warning] " + getInstanceName() + + " -> Wavelengths contains data paths with no possible modulator configurations!"); + } + // Trace the wavelengths the laser is outputting to find the output + // power needed by the laser + OpticalWavelength* wavelength = optical_graph->traceWavelength(laser_wavelengths, getLaser("Laser")); + // Calculate the power needed by the wavelength + double laser_power = wavelength->getLaserPower(max_detectors); + + // Calculate NDD power + getNddPowerResult("Laser")->setValue(laser_power); + + delete wavelength; + delete optical_graph; + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical/OpticalLinkBackendRx.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical/OpticalLinkBackendRx.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_OPTICAL_OPTICALLINKBACKENDRX_H__ +#define __DSENT_MODEL_OPTICAL_OPTICALLINKBACKENDRX_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" + +namespace DSENT +{ + class OpticalLinkBackendRx : public ElectricalModel + { + // An optical link backend rx contains everything needed for thermal + // tuning of rings, bit-reshuffling (if necessary), and deserialization (if necessary) + public: + OpticalLinkBackendRx(const String& instance_name_, const TechModel* tech_model_); + virtual ~OpticalLinkBackendRx(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + + protected: + // Build the model + virtual void constructModel(); + virtual void updateModel(); + virtual void propagateTransitionInfo(); + + private: + // Calculate ring tuning power + double getRingTuningPower(); + // Calculate the degree of bit re-order muxing (for the bit-reshuffler) + unsigned int getBitReorderDegree(); + + }; // class OpticalLinkBackendRx +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICAL_OPTICALLINKBACKENDRX_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical/OpticalLinkBackendRx.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical/OpticalLinkBackendRx.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,395 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/optical/OpticalLinkBackendRx.hh" + +#include "mem/ruby/network/dsent/dsent-core/util/Constants.hh" +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/electrical/DemuxTreeDeserializer.hh" +#include "mem/ruby/network/dsent/dsent-core/model/electrical/BarrelShifter.hh" +#include "mem/ruby/network/dsent/dsent-core/model/electrical/Multiplexer.hh" +#include + +namespace DSENT +{ + // TODO: Kind of don't like the way thermal tuning is written here. Maybe will switch + // to curve fitting the CICC paper, which uses results from a monte-carlo sim. Also, there is + // redundant code between this one and the tx one... + + OpticalLinkBackendRx::OpticalLinkBackendRx(const String& instance_name_, const TechModel* tech_model_) + : ElectricalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + OpticalLinkBackendRx::~OpticalLinkBackendRx() + {} + + void OpticalLinkBackendRx::initParameters() + { + addParameterName("OutBits"); + addParameterName("CoreDataRate"); + addParameterName("LinkDataRate"); + addParameterName("RingTuningMethod"); + addParameterName("BitDuplicate"); + return; + } + + void OpticalLinkBackendRx::initProperties() + { + return; + } + + void OpticalLinkBackendRx::constructModel() + { + unsigned int out_bits = getParameter("OutBits"); + double core_data_rate = getParameter("CoreDataRate"); + double link_data_rate = getParameter("LinkDataRate"); + const String& tuning_method = getParameter("RingTuningMethod"); + bool bit_duplicate = getParameter("BitDuplicate"); + + // Calculate deserialization ratio + unsigned int deserialization_ratio = (unsigned int) floor(link_data_rate / core_data_rate); + ASSERT(deserialization_ratio == link_data_rate / core_data_rate, + "[Error] " + getInstanceName() + " -> Cannot have non-integer deserialization ratios!"); + ASSERT((deserialization_ratio & (deserialization_ratio - 1)) == 0, + "[Error] " + getInstanceName() + " -> Deserialization ratio must be a power of 2"); + + // Calculate output width + unsigned int in_bits = out_bits / deserialization_ratio; + ASSERT(out_bits >= deserialization_ratio, "[Error] " + getInstanceName() + + " -> Output width must be >= deserialization ratio!"); + ASSERT(floor((double) out_bits / deserialization_ratio) == in_bits, + "[Error] " + getInstanceName() + " -> Output width must be a multiple of the serialization ratio!"); + + getGenProperties()->set("DeserializationRatio", deserialization_ratio); + getGenProperties()->set("InBits", in_bits); + + // Create ports + createInputPort("In", makeNetIndex(0, in_bits-1)); + createInputPort("LinkCK"); + createOutputPort("Out", makeNetIndex(0, out_bits-1)); + + //Create energy, power, and area results + createElectricalResults(); + // Create ring heating power cost + addNddPowerResult(new AtomicResult("RingTuning")); + // Create process bits event + createElectricalEventResult("ProcessBits"); + getEventInfo("ProcessBits")->setTransitionInfo("LinkCK", TransitionInfo(0.0, (double) deserialization_ratio / 2.0, 0.0)); + // Set conditions during idle state + getEventInfo("Idle")->setStaticTransitionInfos(); + getEventInfo("Idle")->setTransitionInfo("LinkCK", TransitionInfo(0.0, (double) deserialization_ratio / 2.0, 0.0)); + + // Create deserializer + const String& deserializer_name = "Deserializer"; + DemuxTreeDeserializer* deserializer = new DemuxTreeDeserializer(deserializer_name, getTechModel()); + deserializer->setParameter("OutBits", out_bits); + deserializer->setParameter("InDataRate", link_data_rate); + deserializer->setParameter("OutDataRate", core_data_rate); + deserializer->setParameter("BitDuplicate", bit_duplicate); + deserializer->construct(); + + addSubInstances(deserializer, 1.0); + addElectricalSubResults(deserializer, 1.0); + getEventResult("ProcessBits")->addSubResult(deserializer->getEventResult("Deserialize"), deserializer_name, 1.0); + + if ((tuning_method == "ThermalWithBitReshuffle") || (tuning_method == "ElectricalAssistWithBitReshuffle")) + { + // If a bit reshuffling backend is present, create the reshuffling backend + unsigned int reorder_degree = getBitReorderDegree(); + + // Create intermediate nets + createNet("ReorderIn", makeNetIndex(0, in_bits+reorder_degree-1)); + assign("ReorderIn", makeNetIndex(0, in_bits-1), "In"); + assign("ReorderIn", makeNetIndex(in_bits, in_bits+reorder_degree-1), "ReorderIn", makeNetIndex(0, reorder_degree-1)); + createNet("DeserializerIn", makeNetIndex(0, in_bits-1)); + createNet("BarrelShiftIn", makeNetIndex(0, out_bits-1)); + + // Create bit reorder muxes + const String& reorder_mux_name = "ReorderMux"; + Multiplexer* reorder_mux = new Multiplexer(reorder_mux_name, getTechModel()); + reorder_mux->setParameter("NumberBits", in_bits); + reorder_mux->setParameter("NumberInputs", reorder_degree); + reorder_mux->setParameter("BitDuplicate", bit_duplicate); + reorder_mux->construct(); + + // Create barrelshifter + unsigned int shift_index_min = (unsigned int)ceil(log2(deserialization_ratio)); + unsigned int shift_index_max = std::max(shift_index_min, (unsigned int) ceil(log2(out_bits)) - 1); + + // Remember some things + getGenProperties()->set("ReorderDegree", reorder_degree); + getGenProperties()->set("ShiftIndexMin", shift_index_min); + getGenProperties()->set("ShiftIndexMax", shift_index_max); + + const String& barrel_shift_name = "BarrelShifter"; + BarrelShifter* barrel_shift = new BarrelShifter(barrel_shift_name, getTechModel()); + barrel_shift->setParameter("NumberBits", out_bits); + barrel_shift->setParameter("ShiftIndexMax", shift_index_max); + barrel_shift->setParameter("ShiftIndexMin", shift_index_min); + barrel_shift->setParameter("BitDuplicate", bit_duplicate); + barrel_shift->construct(); + + // Connect serializer + portConnect(deserializer, "In", "DeserializerIn"); + portConnect(deserializer, "Out", "BarrelShiftIn"); + portConnect(deserializer, "InCK", "LinkCK"); + + // Connect barrelshifter + // TODO: Connect barrelshift shifts! + portConnect(barrel_shift, "In", "BarrelShiftIn"); + portConnect(barrel_shift, "Out", "Out"); + + // Connect bit reorder muxes + // TODO: Connect re-order multiplex select signals! + for (unsigned int i = 0; i < reorder_degree; i++) + portConnect(reorder_mux, "In" + (String) i, "ReorderIn", makeNetIndex(i, i+in_bits-1)); + portConnect(reorder_mux, "Out", "DeserializerIn"); + + addSubInstances(barrel_shift, 1.0); + addSubInstances(reorder_mux, 1.0); + addElectricalSubResults(barrel_shift, 1.0); + addElectricalSubResults(reorder_mux, 1.0); + getEventResult("ProcessBits")->addSubResult(barrel_shift->getEventResult("BarrelShift"), barrel_shift_name, 1.0); + getEventResult("ProcessBits")->addSubResult(reorder_mux->getEventResult("Mux"), reorder_mux_name, 1.0); + } + else if ((tuning_method == "FullThermal") || (tuning_method == "AthermalWithTrim")) + { + // If no bit reshuffling backend is present, then just connect deserializer up + portConnect(deserializer, "In", "In"); + portConnect(deserializer, "Out", "Out"); + portConnect(deserializer, "InCK", "LinkCK"); + } + else + { + ASSERT(false, "[Error] " + getInstanceName() + " -> Unknown ring tuning method '" + tuning_method + "'!"); + } + + return; + } + + void OpticalLinkBackendRx::updateModel() + { + // Update everyone + Model::updateModel(); + // Update ring tuning power + getNddPowerResult("RingTuning")->setValue(getRingTuningPower()); + return; + } + + void OpticalLinkBackendRx::propagateTransitionInfo() + { + // Get parameters + const String& tuning_method = getParameter("RingTuningMethod");; + + // Get properties + + // Update the deserializer + if ((tuning_method == "ThermalWithBitReshuffle") || (tuning_method == "ElectricalAssistWithBitReshuffle")) + { + // Get generated properties + unsigned int reorder_degree = getGenProperties()->get("ReorderDegree"); + unsigned int shift_index_min = getGenProperties()->get("ShiftIndexMin"); + unsigned int shift_index_max = getGenProperties()->get("ShiftIndexMax"); + + // Reorder mux shift select bits + unsigned int reorder_sel_bits = (unsigned int)ceil(log2(reorder_degree)); + + // Create bit reorder muxes + const String& reorder_mux_name = "ReorderMux"; + ElectricalModel* reorder_mux = (ElectricalModel*) getSubInstance(reorder_mux_name); + for (unsigned int i = 0; i < reorder_degree; ++i) + propagatePortTransitionInfo(reorder_mux, "In" + (String) i, "In"); + // Set select transitions to be 0, since these are statically configured + for (unsigned int i = 0; i < reorder_sel_bits; ++i) + reorder_mux->getInputPort("Sel" + (String) i)->setTransitionInfo(TransitionInfo(0.5, 0.0, 0.5)); + reorder_mux->use(); + + // Update the deserializer + ElectricalModel* deserializer = (ElectricalModel*) getSubInstance("Deserializer"); + propagatePortTransitionInfo(deserializer, "In", reorder_mux, "Out"); + propagatePortTransitionInfo(deserializer, "InCK", "LinkCK"); + deserializer->use(); + + // Update barrel shifter + const String& barrel_shift_name = "BarrelShifter"; + ElectricalModel* barrel_shift = (ElectricalModel*) getSubInstance(barrel_shift_name); + propagatePortTransitionInfo(barrel_shift, "In", deserializer, "Out"); + // Set shift transitions to be very low (since it is affected by slow temperature time constants) + for (unsigned int i = shift_index_min; i <= shift_index_max; ++i) + barrel_shift->getInputPort("Shift" + (String) i)->setTransitionInfo(TransitionInfo(0.499, 0.001, 0.499)); + barrel_shift->use(); + + // Set output transition info + propagatePortTransitionInfo("Out", barrel_shift, "Out"); + } + else if ((tuning_method == "FullThermal") || (tuning_method == "AthermalWithTrim")) + { + // Update the deserializer + ElectricalModel* deserializer = (ElectricalModel*) getSubInstance("Deserializer"); + propagatePortTransitionInfo(deserializer, "In", "In"); + propagatePortTransitionInfo(deserializer, "InCK", "LinkCK"); + deserializer->use(); + + // Set output transition info + propagatePortTransitionInfo("Out", deserializer, "Out"); + } + else + { + ASSERT(false, "[Error] " + getInstanceName() + " -> Unknown ring tuning method '" + tuning_method + "'!"); + } + + return; + } + + double OpticalLinkBackendRx::getRingTuningPower() + { + // Get properties + const String& tuning_method = getParameter("RingTuningMethod");; + unsigned int number_rings = getGenProperties()->get("InBits"); + + // Get tech model parameters + double R = getTechModel()->get("Ring->Radius"); + double n_g = getTechModel()->get("Ring->GroupIndex"); + double heating_efficiency = getTechModel()->get("Ring->HeatingEfficiency"); + // This can actually be derived if we know thermo-optic coefficient (delta n / delta T) + double tuning_efficiency = getTechModel()->get("Ring->TuningEfficiency"); + double sigma_r_local = getTechModel()->get("Ring->LocalVariationSigma"); + double sigma_r_systematic = getTechModel()->get("Ring->SystematicVariationSigma"); + double T_max = getTechModel()->get("Ring->TemperatureMax"); + double T_min = getTechModel()->get("Ring->TemperatureMin"); + double T = getTechModel()->get("Temperature"); + + // Get constants + double c = Constants::c; + double pi = Constants::pi; + + double tuning_power = 0.0; + + if (tuning_method == "ThermalWithBitReshuffle") + { + // When an electrical backend is present, rings only have to tune to the nearest channel + // This can be approximated as each ring tuning to something exactly 1 channel away + + // Setup calculations + double L = 2 * pi * R; // Optical length + double FSR = c / (n_g * L); // Free spectral range + double freq_sep = FSR / number_rings; // Channel separation + + // Calculate tuning power + tuning_power = number_rings * freq_sep / (tuning_efficiency * heating_efficiency); + } + else if (tuning_method == "ElectricalAssistWithBitReshuffle") + { + // Electrical assistance allows for a fraction of the tuning range to be + // covered electrically. This is most pronounced when the tuning range is small, + // such is the case when bit reshuffling is applied + + // Get electrically tunable range + double max_assist = getTechModel()->get("Ring->MaxElectricallyTunableFreq"); + + // Setup calculations + double L = 2 * pi * R; // Optical length + double FSR = c / (n_g * L); // Free spectral range + double freq_sep = FSR / number_rings; // Channel separation + double heating_range = std::max(0.0, freq_sep - max_assist); // The distance needed to bridge using heaters + + // Calculate tuning power, which is really only the power spent on heating since + // distance tuned electrically is pretty much free + tuning_power = number_rings * heating_range / (tuning_efficiency * heating_efficiency); + } + else if (tuning_method == "FullThermal") + { + // If there is no bit reshuffling backend, each ring must tune to an + // absolute channel frequency. Since we can only heat rings (and not cool), + // we can only red-shift (decrease frequency). Thus, a fabrication bias + // must be applied such that under any process and temperature corner, the + // ring resonance remains above channel resonance + // I'll use 3 sigmas of sigma_r_local and sigma_r_systematic, and bias against + // the full temperature range + double fabrication_bias_freq = 3.0 * sqrt(pow(sigma_r_local, 2) + pow(sigma_r_systematic, 2)) + + (T_max - T_min) * tuning_efficiency; + + // The local/systematic variations are 0 on average. Thus, the tuning distance can be calculated as + double tuning_distance = fabrication_bias_freq - (T - T_min) * tuning_efficiency; + + // Tuning power needed is just the number of rings * tuning distance / (tuning and heating efficiencies) + tuning_power = number_rings * tuning_distance / (tuning_efficiency * heating_efficiency); + } + else if (tuning_method == "AthermalWithTrim") + { + // Athermal! + tuning_power = 0; + } + else + { + ASSERT(false, "[Error] " + getInstanceName() + " -> Unknown ring tuning method '" + tuning_method + "'!"); + } + + return tuning_power; + } + + unsigned int OpticalLinkBackendRx::getBitReorderDegree() + { + // Get properties + unsigned int number_rings = getGenProperties()->get("InBits"); + + // Get tech model parameters + double R = getTechModel()->get("Ring->Radius"); + double n_g = getTechModel()->get("Ring->GroupIndex"); + // This can actually be derived if we know thermo-optic coefficient (delta n / delta T) + double sigma_r_local = getTechModel()->get("Ring->LocalVariationSigma"); + + // Get constants + double c = Constants::c; + double pi = Constants::pi; + + // Calculates the degree of bit re-order multiplexing needed for bit-reshuffling backend + // Bit reshuffling tuning is largely unaffected by sigma_r_systematic. However, sigma_r_local + // Can potentially throw each ring to a channel several channels away. This just calculates + // the degree of bit reorder muxing needed to realign bits in the correct order + + // Setup calculations + double L = 2 * pi * R; // Optical length + double FSR = c / (n_g * L); // Free spectral range + double freq_sep = FSR / number_rings; // Channel separation + // Using 4 sigmas as the worst re-ordering case (must double to get both sides) + unsigned int worst_case_channels = (unsigned int)ceil(2.0 * 4.0 * sigma_r_local / freq_sep); + + return worst_case_channels; + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical/OpticalLinkBackendTx.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical/OpticalLinkBackendTx.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_OPTICAL_OPTICALLINKBACKENDTX_H__ +#define __DSENT_MODEL_OPTICAL_OPTICALLINKBACKENDTX_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" + +namespace DSENT +{ + class OpticalLinkBackendTx : public ElectricalModel + { + // An optical link backend tx contains everything needed for thermal + // tuning of rings, bit-reshuffling (if necessary), and serialization (if necessary) + public: + OpticalLinkBackendTx(const String& instance_name_, const TechModel* tech_model_); + virtual ~OpticalLinkBackendTx(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + + protected: + // Build the model + virtual void constructModel(); + virtual void updateModel(); + virtual void propagateTransitionInfo(); + + private: + // Calculate ring tuning power + double getRingTuningPower(); + // Calculate the degree of bit re-order muxing (for the bit-reshuffler) + unsigned int getBitReorderDegree(); + + }; // class OpticalLinkBackendTx +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICAL_OPTICALLINKBACKENDTX_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical/OpticalLinkBackendTx.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical/OpticalLinkBackendTx.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,386 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/optical/OpticalLinkBackendTx.hh" + +#include "mem/ruby/network/dsent/dsent-core/util/Constants.hh" +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/electrical/MuxTreeSerializer.hh" +#include "mem/ruby/network/dsent/dsent-core/model/electrical/BarrelShifter.hh" +#include "mem/ruby/network/dsent/dsent-core/model/electrical/Multiplexer.hh" +#include + +namespace DSENT +{ + // TODO: Kind of don't like the way thermal tuning is written here. Maybe will switch + // to curve fitting the CICC paper, which uses results from a monte-carlo sim + + OpticalLinkBackendTx::OpticalLinkBackendTx(const String& instance_name_, const TechModel* tech_model_) + : ElectricalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + OpticalLinkBackendTx::~OpticalLinkBackendTx() + {} + + void OpticalLinkBackendTx::initParameters() + { + addParameterName("InBits"); + addParameterName("CoreDataRate"); + addParameterName("LinkDataRate"); + addParameterName("RingTuningMethod"); + addParameterName("BitDuplicate"); + return; + } + + void OpticalLinkBackendTx::initProperties() + { + return; + } + + void OpticalLinkBackendTx::constructModel() + { + unsigned int in_bits = getParameter("InBits"); + double core_data_rate = getParameter("CoreDataRate"); + double link_data_rate = getParameter("LinkDataRate"); + const String& tuning_method = getParameter("RingTuningMethod");; + bool bit_duplicate = getParameter("BitDuplicate"); + + // Calculate serialization ratio + unsigned int serialization_ratio = (unsigned int) floor(link_data_rate / core_data_rate); + ASSERT(serialization_ratio == link_data_rate / core_data_rate, + "[Error] " + getInstanceName() + " -> Cannot have non-integer serialization ratios " + + "(" + (String) (core_data_rate / link_data_rate) + ")!"); + + // Calculate output width + ASSERT(floor((double) in_bits / serialization_ratio) == (double) in_bits / serialization_ratio, + "[Error] " + getInstanceName() + " -> Input width (" + (String) in_bits + ") " + + "must be a multiple of the serialization ratio (" + (String) serialization_ratio + ")!"); + unsigned int out_bits = in_bits / serialization_ratio; + + getGenProperties()->set("SerializationRatio", serialization_ratio); + getGenProperties()->set("OutBits", out_bits); + + // Create ports + createInputPort("In", makeNetIndex(0, in_bits-1)); + createInputPort("LinkCK"); + createOutputPort("Out", makeNetIndex(0, out_bits-1)); + + //Create energy, power, and area results + createElectricalResults(); + // Create ring heating power cost + addNddPowerResult(new AtomicResult("RingTuning")); + // Create process bits event + createElectricalEventResult("ProcessBits"); + getEventInfo("ProcessBits")->setTransitionInfo("LinkCK", TransitionInfo(0.0, (double) serialization_ratio / 2.0, 0.0)); + // Set conditions during idle state + getEventInfo("Idle")->setStaticTransitionInfos(); + getEventInfo("Idle")->setTransitionInfo("LinkCK", TransitionInfo(0.0, (double) serialization_ratio / 2.0, 0.0)); + + // Create serializer + const String& serializer_name = "Serializer"; + MuxTreeSerializer* serializer = new MuxTreeSerializer(serializer_name, getTechModel()); + serializer->setParameter("InBits", in_bits); + serializer->setParameter("InDataRate", core_data_rate); + serializer->setParameter("OutDataRate", link_data_rate); + serializer->setParameter("BitDuplicate", bit_duplicate); + serializer->construct(); + + addSubInstances(serializer, 1.0); + addElectricalSubResults(serializer, 1.0); + getEventResult("ProcessBits")->addSubResult(serializer->getEventResult("Serialize"), serializer_name, 1.0); + + if ((tuning_method == "ThermalWithBitReshuffle") || (tuning_method == "ElectricalAssistWithBitReshuffle")) + { + // If a bit reshuffling backend is present, create the reshuffling backend + unsigned int reorder_degree = getBitReorderDegree(); + + // Create intermediate nets + createNet("SerializerIn", makeNetIndex(0, in_bits-1)); + createNet("ReorderIn", makeNetIndex(0, out_bits+reorder_degree-1)); + assign("ReorderIn", makeNetIndex(out_bits, out_bits+reorder_degree-1), "ReorderIn", makeNetIndex(0, reorder_degree-1)); + + // Create barrelshifter + unsigned int shift_index_min = (unsigned int)ceil(log2(serialization_ratio)); + unsigned int shift_index_max = std::max(shift_index_min, (unsigned int) ceil(log2(in_bits)) - 1); + + // Remember some things + getGenProperties()->set("ReorderDegree", reorder_degree); + getGenProperties()->set("ShiftIndexMin", shift_index_min); + getGenProperties()->set("ShiftIndexMax", shift_index_max); + + const String& barrel_shift_name = "BarrelShifter"; + BarrelShifter* barrel_shift = new BarrelShifter(barrel_shift_name, getTechModel()); + barrel_shift->setParameter("NumberBits", in_bits); + barrel_shift->setParameter("ShiftIndexMax", shift_index_max); + barrel_shift->setParameter("ShiftIndexMin", shift_index_min); + barrel_shift->setParameter("BitDuplicate", bit_duplicate); + barrel_shift->construct(); + + // Create bit reorder muxes + const String& reorder_mux_name = "ReorderMux"; + Multiplexer* reorder_mux = new Multiplexer(reorder_mux_name, getTechModel()); + reorder_mux->setParameter("NumberBits", out_bits); + reorder_mux->setParameter("NumberInputs", reorder_degree); + reorder_mux->setParameter("BitDuplicate", bit_duplicate); + reorder_mux->construct(); + + // Connect barrelshifter + // TODO: Connect barrelshift shifts! + portConnect(barrel_shift, "In", "In"); + portConnect(barrel_shift, "Out", "SerializerIn"); + + // Connect serializer + portConnect(serializer, "In", "SerializerIn"); + portConnect(serializer, "Out", "ReorderIn", makeNetIndex(0, out_bits-1)); + portConnect(serializer, "OutCK", "LinkCK"); + + // Connect bit reorder muxes + // TODO: Connect re-order multiplex select signals! + for (unsigned int i = 0; i < reorder_degree; i++) + portConnect(reorder_mux, "In" + (String) i, "ReorderIn", makeNetIndex(i, i+out_bits-1)); + portConnect(reorder_mux, "Out", "Out"); + + addSubInstances(barrel_shift, 1.0); + addSubInstances(reorder_mux, 1.0); + addElectricalSubResults(barrel_shift, 1.0); + addElectricalSubResults(reorder_mux, 1.0); + getEventResult("ProcessBits")->addSubResult(barrel_shift->getEventResult("BarrelShift"), barrel_shift_name, 1.0); + getEventResult("ProcessBits")->addSubResult(reorder_mux->getEventResult("Mux"), reorder_mux_name, 1.0); // This happens multiple times + } + else if ((tuning_method == "FullThermal") || (tuning_method == "AthermalWithTrim")) + { + // If no bit reshuffling backend is present, then just connect serializer up + portConnect(serializer, "In", "In"); + portConnect(serializer, "Out", "Out"); + portConnect(serializer, "OutCK", "LinkCK"); + } + else + { + ASSERT(false, "[Error] " + getInstanceName() + " -> Unknown ring tuning method '" + tuning_method + "'!"); + } + + return; + } + + void OpticalLinkBackendTx::updateModel() + { + // Update everyone + Model::updateModel(); + // Update ring tuning power + getNddPowerResult("RingTuning")->setValue(getRingTuningPower()); + return; + } + + void OpticalLinkBackendTx::propagateTransitionInfo() + { + // Get parameters + const String& tuning_method = getParameter("RingTuningMethod"); + + // Update the serializer + if ((tuning_method == "ThermalWithBitReshuffle") || (tuning_method == "ElectricalAssistWithBitReshuffle")) + { + // Get generated properties + unsigned int reorder_degree = getGenProperties()->get("ReorderDegree").toUInt(); + unsigned int shift_index_min = getGenProperties()->get("ShiftIndexMin").toUInt(); + unsigned int shift_index_max = getGenProperties()->get("ShiftIndexMax").toUInt(); + + // Update barrel shifter + const String& barrel_shift_name = "BarrelShifter"; + ElectricalModel* barrel_shift = (ElectricalModel*) getSubInstance(barrel_shift_name); + propagatePortTransitionInfo(barrel_shift, "In", "In"); + // Set shift transitions to be very low (since it is affected by slow temperature time constants) + for (unsigned int i = shift_index_min; i <= shift_index_max; ++i) + barrel_shift->getInputPort("Shift" + (String) i)->setTransitionInfo(TransitionInfo(0.499, 0.001, 0.499)); + barrel_shift->use(); + + // Set serializer transition info + ElectricalModel* serializer = (ElectricalModel*) getSubInstance("Serializer"); + propagatePortTransitionInfo(serializer, "In", barrel_shift, "Out"); + propagatePortTransitionInfo(serializer, "OutCK", "LinkCK"); + serializer->use(); + + // Reorder mux shift select bits + unsigned int reorder_sel_bits = (unsigned int)ceil(log2(reorder_degree)); + + // Reorder mux probabilities + const String& reorder_mux_name = "ReorderMux"; + ElectricalModel* reorder_mux = (ElectricalModel*) getSubInstance(reorder_mux_name); + for (unsigned int i = 0; i < reorder_degree; ++i) + propagatePortTransitionInfo(reorder_mux, "In" + (String) i, serializer, "Out"); + // Set select transitions to be 0, since these are statically configured + for (unsigned int i = 0; i < reorder_sel_bits; ++i) + reorder_mux->getInputPort("Sel" + (String) i)->setTransitionInfo(TransitionInfo(0.5, 0.0, 0.5)); + reorder_mux->use(); + + // Set output transition info + propagatePortTransitionInfo("Out", reorder_mux, "Out"); + } + else if ((tuning_method == "FullThermal") || (tuning_method == "AthermalWithTrim")) + { + // Set serializer transition info + ElectricalModel* serializer = (ElectricalModel*) getSubInstance("Serializer"); + propagatePortTransitionInfo(serializer, "In", "In"); + propagatePortTransitionInfo(serializer, "OutCK", "LinkCK"); + serializer->use(); + + // Set output transition info + propagatePortTransitionInfo("Out", serializer, "Out"); + } + + return; + } + + double OpticalLinkBackendTx::getRingTuningPower() + { + // Get properties + const String& tuning_method = getParameter("RingTuningMethod");; + unsigned int number_rings = getGenProperties()->get("OutBits"); + + // Get tech model parameters + double R = getTechModel()->get("Ring->Radius"); + double n_g = getTechModel()->get("Ring->GroupIndex"); + double heating_efficiency = getTechModel()->get("Ring->HeatingEfficiency"); + // This can actually be derived if we know thermo-optic coefficient (delta n / delta T) + double tuning_efficiency = getTechModel()->get("Ring->TuningEfficiency"); + double sigma_r_local = getTechModel()->get("Ring->LocalVariationSigma"); + double sigma_r_systematic = getTechModel()->get("Ring->SystematicVariationSigma"); + double T_max = getTechModel()->get("Ring->TemperatureMax"); + double T_min = getTechModel()->get("Ring->TemperatureMin"); + double T = getTechModel()->get("Temperature"); + + // Get constants + double c = Constants::c; + double pi = Constants::pi; + + double tuning_power = 0.0; + + if (tuning_method == "ThermalWithBitReshuffle") + { + // When an electrical backend is present, rings only have to tune to the nearest channel + // This can be approximated as each ring tuning to something exactly 1 channel away + + // Setup calculations + double L = 2 * pi * R; // Optical length + double FSR = c / (n_g * L); // Free spectral range + double freq_sep = FSR / number_rings; // Channel separation + + // Calculate tuning power + tuning_power = number_rings * freq_sep / (tuning_efficiency * heating_efficiency); + } + else if (tuning_method == "ElectricalAssistWithBitReshuffle") + { + // Electrical assistance allows for a fraction of the tuning range to be + // covered electrically. This is most pronounced when the tuning range is small, + // such is the case when bit reshuffling is applied. The electrically + // assisted part of it pretty much comes for free... + + // Get electrically tunable range + double max_assist = getTechModel()->get("Ring->MaxElectricallyTunableFreq"); + + // Setup calculations + double L = 2 * pi * R; // Optical length + double FSR = c / (n_g * L); // Free spectral range + double freq_sep = FSR / number_rings; // Channel separation + double heating_range = std::max(0.0, freq_sep - max_assist); // The distance needed to bridge using heaters + + // Calculate tuning power, which is really only the power spent on heating since + // distance tuned electrically is pretty much free + tuning_power = number_rings * heating_range / (tuning_efficiency * heating_efficiency); + } + else if (tuning_method == "FullThermal") + { + // If there is no bit reshuffling backend, each ring must tune to an + // absolute channel frequency. Since we can only heat rings (and not cool), + // we can only red-shift (decrease frequency). Thus, a fabrication bias + // must be applied such that under any process and temperature corner, the + // ring resonance remains above channel resonance + // I'll use 3 sigmas of sigma_r_local and sigma_r_systematic, and bias against + // the full temperature range + double fabrication_bias_freq = 3.0 * sqrt(pow(sigma_r_local, 2) + pow(sigma_r_systematic, 2)) + + (T_max - T_min) * tuning_efficiency; + + // The local/systematic variations are 0 on average. Thus, the tuning distance can be calculated as + double tuning_distance = fabrication_bias_freq - (T - T_min) * tuning_efficiency; + + // Tuning power needed is just the number of rings * tuning distance / (tuning and heating efficiencies) + tuning_power = number_rings * tuning_distance / (tuning_efficiency * heating_efficiency); + } + else if (tuning_method == "AthermalWithTrim") + { + // Athermal! Each ring's process variations are trimmed! Everything is free! + // Basically an ideal scenario + tuning_power = 0; + } + else + { + ASSERT(false, "[Error] " + getInstanceName() + " -> Unknown ring tuning method '" + tuning_method + "'!"); + } + + return tuning_power; + } + + unsigned int OpticalLinkBackendTx::getBitReorderDegree() + { + // Get properties + unsigned int number_rings = getGenProperties()->get("OutBits"); + + // Get tech model parameters + double R = getTechModel()->get("Ring->Radius"); + double n_g = getTechModel()->get("Ring->GroupIndex"); + // This can actually be derived if we know thermo-optic coefficient (delta n / delta T) + double sigma_r_local = getTechModel()->get("Ring->LocalVariationSigma"); + + // Get constants + double c = Constants::c; + double pi = Constants::pi; + + // Calculates the degree of bit re-order multiplexing needed for bit-reshuffling backend + // Bit reshuffling tuning is largely unaffected by sigma_r_systematic. However, sigma_r_local + // Can potentially throw each ring to a channel several channels away. This just calculates + // the degree of bit reorder muxing needed to realign bits in the correct order + + // Setup calculations + double L = 2 * pi * R; // Optical length + double FSR = c / (n_g * L); // Free spectral range + double freq_sep = FSR / number_rings; // Channel separation + // Using 4 sigmas as the worst re-ordering case (must double to get both sides) + unsigned int worst_case_channels = (unsigned int)ceil(2.0 * 4.0 * sigma_r_local / freq_sep); + + return worst_case_channels; + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical/OpticalTestModel.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical/OpticalTestModel.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_OPTICAL_OPTICALTESTMODEL_H__ +#define __DSENT_MODEL_OPTICAL_OPTICALTESTMODEL_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/OpticalModel.hh" + +namespace DSENT +{ + class OpticalTestModel : public OpticalModel + { + public: + OpticalTestModel(const String& instance_name_, const TechModel* tech_model_); + virtual ~OpticalTestModel(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + + protected: + // Build the model + virtual void constructModel(); + virtual void updateModel(); + + }; // class OpticalTestModel +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICAL_RINGLASERSOURCE_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical/OpticalTestModel.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical/OpticalTestModel.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/optical/OpticalTestModel.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalGraph.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalWaveguide.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical/RingModulator.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical/RingFilter.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical/RingDetector.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical/LaserSource.hh" + +namespace DSENT +{ + OpticalTestModel::OpticalTestModel(const String& instance_name_, const TechModel* tech_model_) + : OpticalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + OpticalTestModel::~OpticalTestModel() + {} + + void OpticalTestModel::initParameters() + { + return; + } + + void OpticalTestModel::initProperties() + { + return; + } + + void OpticalTestModel::constructModel() + { + unsigned int wavelengths = 64; + unsigned int number_readers = 1; + + createWaveguide("LaserToMod", makeWavelengthGroup(0, wavelengths-1)); + + // Create laser + LaserSource* laser = new LaserSource("Laser", getTechModel()); + laser->setParameter("OutStart", 0); + laser->setParameter("OutEnd", wavelengths-1); + laser->construct(); + + // Create modulator + RingModulator* modulator = new RingModulator("Modulator", getTechModel()); + modulator->setParameter("InStart", 0); + modulator->setParameter("InEnd", wavelengths-1); + modulator->setParameter("ModStart", 0); + modulator->setParameter("ModEnd", wavelengths-1); + modulator->construct(); + + for (unsigned int i = 0; i <= number_readers; ++i) + { + String n = (String) i; + createWaveguide("WaveguideDet-" + n, makeWavelengthGroup(0, wavelengths-1)); + } + + // Create a SWMR Configuration + for (unsigned int i = 0; i < number_readers; ++i) + { + String n = (String) i; + + // Create resonant ring detector + RingDetector* detector = new RingDetector("Detector-" + n, getTechModel()); + detector->setParameter("InStart", 0); + detector->setParameter("InEnd", wavelengths-1); + detector->setParameter("DetStart", 0); + detector->setParameter("DetEnd", wavelengths-1); + detector->setParameter("DropAll", "FALSE"); + detector->setParameter("SenseAmp", "TRUE"); + detector->construct(); + + opticalPortConnect(detector, "In", "WaveguideDet-" + n); + opticalPortConnect(detector, "Out", "WaveguideDet-" + (String) (i + 1)); + + addSubInstances(detector, 1.0); + } + + opticalPortConnect(laser, "Out", "LaserToMod"); + opticalPortConnect(modulator, "In", "LaserToMod"); + opticalPortConnect(modulator, "Out", "WaveguideDet-0"); + + addSubInstances(laser, 1.0); + addSubInstances(modulator, 1.0); + } + + void OpticalTestModel::updateModel() + { + double data_rate = 8e9; + double extinction_ratio = 5; + double insertion_loss = 3; + + Model* laser = getSubInstance("Laser"); + laser->update(); + + getWaveguide("LaserToMod")->setLoss(10); + + Model* modulator = getSubInstance("Modulator"); + modulator->setProperty("ExtinctionRatio", extinction_ratio); + modulator->setProperty("InsertionLoss", insertion_loss); + modulator->setProperty("DataRate", data_rate); + modulator->setProperty("P(In)", 0.5); + modulator->setProperty("Act(In)", 1.0); + modulator->update(); + + unsigned int number_readers = 1; + for (unsigned int i = 0; i < number_readers; ++i) + { + Model* detector = getSubInstance("Detector-" + (String) i); + detector->setProperty("ExtinctionRatio", extinction_ratio); + detector->setProperty("DataRate", data_rate); + detector->setProperty("P(In)", 0.5); + detector->setProperty("Act(In)", 1.0); + detector->update(); + } + + + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical/RingDetector.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical/RingDetector.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_OPTICAL_RINGDETECTOR_H__ +#define __DSENT_MODEL_OPTICAL_RINGDETECTOR_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/OpticalModel.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalReceiver.hh" + +namespace DSENT +{ + class RingDetector : public OpticalModel, public OpticalReceiver + { + public: + // Receiver topolgy strings + static const String INTEGRATINGSENSEAMP; + + public: + RingDetector(const String& instance_name_, const TechModel* tech_model_); + virtual ~RingDetector(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + // Returns the sensitivity of the receiver given an extinction ratio + double getSensitivity(double ER_dB_) const; + + private: + // Precompute values based on tech parameters + void precomputeTech(); + // Design the receiver helper function + void designReceiver(); + // Calculates inverse normal cdf + double calcInvNormCdf(double num_); + + protected: + // Build the model + virtual void constructModel(); + virtual void updateModel(); + virtual void useModel(); + virtual void propagateTransitionInfo(); + + private: + // Precomputed numbers + double m_quad_a_; + double m_quad_b1_; + double m_quad_b2_; + double m_quad_c_; + + }; // class RingDetector +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICAL_RINGDETECTOR_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical/RingDetector.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical/RingDetector.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,369 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/optical/RingDetector.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/util/Constants.hh" +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalWaveguide.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalDetector.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalFilter.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriver.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" + +namespace DSENT +{ + // TODOs for this model + // Add the other receiver topologies from [Georgas, CICC 2011] + // Split integ_time_ratio = SA integ time ratio + // Right now perfect clock gating is assumed...may not be what we want + + // Constants + const String RingDetector::INTEGRATINGSENSEAMP = "INTSA"; + + RingDetector::RingDetector(const String& instance_name_, const TechModel* tech_model_) + : OpticalModel(instance_name_, tech_model_), OpticalReceiver() + { + initParameters(); + initProperties(); + } + + RingDetector::~RingDetector() + {} + + void RingDetector::initParameters() + { + addParameterName("DataRate"); + addParameterName("InStart"); + addParameterName("InEnd"); + addParameterName("DetStart"); + addParameterName("DetEnd"); + addParameterName("DropAll"); + addParameterName("Topology"); + return; + } + + void RingDetector::initProperties() + { + return; + } + + void RingDetector::constructModel() + { + // Get parameters + WavelengthGroup in_wavelengths = makeWavelengthGroup(getParameter("InStart"), getParameter("InEnd")); + WavelengthGroup det_wavelengths = makeWavelengthGroup(getParameter("DetStart"), getParameter("DetEnd")); + int number_wavelengths = det_wavelengths.second - det_wavelengths.first + 1; + bool drop_all = getParameter("DropAll"); + const String& topology = getParameter("Topology"); + + // Set some generated properties + getGenProperties()->set("NumberWavelengths", number_wavelengths); + + // Create device area result + addAreaResult(new AtomicResult("Photonic")); + // Create electrical results + createElectricalAtomicResults(); + if (topology == INTEGRATINGSENSEAMP) addEventResult(new AtomicResult("Receive")); + else ASSERT(false, "[Error] " + getInstanceName() + " -> Unknown receiver topology (" + topology + ")!"); + + // Create optical ports + createOpticalInputPort( "In", in_wavelengths); + createOpticalOutputPort( "Out", in_wavelengths); + // Create the filter and modulator + createFilter( "RingFilter", in_wavelengths, drop_all, det_wavelengths); + createDetector( "RingDetector", det_wavelengths, this); + OpticalFilter* ring_filter = getFilter("RingFilter"); + OpticalDetector* ring_detector = getDetector("RingDetector"); + // Connect the filter and modulator + getWaveguide("In")->addDownstreamNode(ring_filter); + ring_filter->addDownstreamNode(getWaveguide("Out")); + ring_filter->setDropPort(ring_detector); + + // Create electrical ports + createOutputPort("Out", makeNetIndex(0, number_wavelengths-1)); + // Create net + createNet("OutVFO"); + // Create output driver + createDriver("OutDriver", false); + // Connect driver + getDriver("OutDriver")->addDownstreamNode(getNet("OutVFO")); + // Connect output + assignVirtualFanout("Out", "OutVFO"); + + // Precompute some technology values + precomputeTech(); + + return; + } + + void RingDetector::updateModel() + { + // Get some generated properties + unsigned int number_wavelengths = getGenProperties()->get("NumberWavelengths"); + + // Get tech model numbers + double ring_area = getTechModel()->get("Ring->Area"); + double thru_loss = getTechModel()->get("Ring->ThroughLoss"); + double drop_loss = getTechModel()->get("Ring->DropLoss"); + double pd_loss = getTechModel()->get("Photodetector->Loss"); + double pd_responsivity = getTechModel()->get("Photodetector->Responsivity"); + + // Design the receiver + designReceiver(); + + // Update losses + // Connect the filter and modulator + OpticalFilter* ring_filter = getFilter("RingFilter"); + OpticalDetector* ring_detector = getDetector("RingDetector"); + ring_filter->setLoss(thru_loss * number_wavelengths); + ring_filter->setDropLoss(drop_loss + thru_loss * number_wavelengths); + ring_detector->setLoss(pd_loss); + ring_detector->setResponsivity(pd_responsivity); + // Update device area + getAreaResult("Photonic")->setValue(ring_area * (number_wavelengths)); + + return; + } + + void RingDetector::useModel() + { + // Get parameters + const String& topology = getParameter("Topology"); + + // Get some generated properties + unsigned int number_wavelengths = getGenProperties()->get("NumberWavelengths"); + + // Get optical input transition info + const TransitionInfo& in_trans = getOpticalInputPort("In")->getTransitionInfo(); + + // Get tech models + double vdd = getTechModel()->get("Vdd"); + // Get caps + double unit_gate_cap = getTechModel()->get("Gate->MinWidth").toDouble() * getTechModel()->get("Gate->CapPerWidth").toDouble(); + double unit_drain_cap = getTechModel()->get("Gate->MinWidth").toDouble() * getTechModel()->get("Drain->CapPerWidth").toDouble(); + double inv_x1_gate_cap = getTechModel()->getStdCellLib()->getStdCellCache()->get("INV_X1->Cap->A"); + double inv_x1_drain_cap = getTechModel()->getStdCellLib()->getStdCellCache()->get("INV_X1->Cap->Y"); + + // Construct a simple sense-amp model + if(topology == INTEGRATINGSENSEAMP) + { + // Use ratios from the receiver published in [Georgas, ESSCIRC 2011] + // Note: + // The numbers in the paper (43fJ/b, 50 fJ/b in the cited work) is done with the clock buffer (there are 4 receivers), + // capacitive DAC, and extra output flops used in the physical layout, as the compared receiver is extremely conservative + // We simplified this model to not have the capacitive DAC, the clock buffer (since this is an individual receiver), or + // the extra output flops (since receiver structure is already a posedge flop functionally). + // Look for an upcoming paper [Georgas, JSSC 2012] (when it is published) for the power breakdown pie-chart for the receiver. + // This model only models the latch (sampler) and the dynamic to static (RS latch) part of the design, which is all you really + // need in the receiver. + + // Gate caps + double c_gate_sampler = unit_gate_cap * (4 * 2.0 + 2 * 1.0 + 2 * 3.0 + 2 * 5.0) + unit_gate_cap * (2 * 6.0 + 2 * 1.0) + inv_x1_gate_cap; + double c_gate_rslatch = unit_gate_cap * (4 * 1.0) + inv_x1_gate_cap; + // Drain caps + double c_drain_sampler = unit_drain_cap * (2 * 2.0 + 2 * 1.0 + 3 * 5.0 + 1 * 3.0) + inv_x1_drain_cap; + double c_drain_rslatch = unit_drain_cap * (2 * 6.0) + inv_x1_drain_cap; + // Sum up cap switched for the sampler + double c_sampler = c_gate_sampler + c_drain_sampler; + double c_rslatch = c_gate_rslatch + c_drain_rslatch; + // Average cap switched + // Sampler is differential, one side will always switch (R or S in the latch) regardless of probability + double avg_cap = c_sampler + c_rslatch * in_trans.getProbability0() * in_trans.getProbability1(); + + // Get parameters corresponding to a unit-inverter + double unit_leak_0 = getTechModel()->getStdCellLib()->getStdCellCache()->get("INV_X1->Leakage->!A"); + double unit_leak_1 = getTechModel()->getStdCellLib()->getStdCellCache()->get("INV_X1->Leakage->A"); + + // Approximate leakage (curve fit with design) + double total_leakage = 0.5 * (unit_leak_0 + unit_leak_1) * 7.43; + + // Create results + getEventResult("Receive")->setValue(vdd * vdd * avg_cap * number_wavelengths); + getNddPowerResult("Leakage")->setValue(total_leakage * number_wavelengths); + + } + else ASSERT(false, "[Error] " + getInstanceName() + " -> Unknown receiver topology (" + topology + ")!"); + + return; + } + + void RingDetector::propagateTransitionInfo() + { + // Propagate probabilities from optical input to electrical output port + getOutputPort("Out")->setTransitionInfo(getOpticalInputPort("In")->getTransitionInfo()); + + return; + } + + void RingDetector::precomputeTech() + { + // Get parameters + const double data_rate = getParameter("DataRate"); + const String& topology = getParameter("Topology"); + + // Get tech model numbers + double pd_cap = getTechModel()->get("Photodetector->Cap"); + double parasitic_cap = getTechModel()->get("Photodetector->ParasiticCap"); + double apd = getTechModel()->get("Photodetector->AvalancheGain"); + double vdd = getTechModel()->get("Vdd"); + + // Constants shortcuts + double pi = Constants::pi; + double k = Constants::k; + double q = Constants::q; + double T = getTechModel()->get("Temperature"); + + if(topology == INTEGRATINGSENSEAMP) + { + // Get more tech parameters + double integ_time_ratio = getTechModel()->get("Receiver->Int->IntegrationTimeRatio"); + double BER = getTechModel()->get("SenseAmp->BER"); + double CMRR = getTechModel()->get("SenseAmp->CMRR"); + double offset_comp_bits = getTechModel()->get("SenseAmp->OffsetCompensationBits"); + double offset = getTechModel()->get("SenseAmp->OffsetRatio").toDouble() * vdd; + double supply_noise_rand = getTechModel()->get("SenseAmp->SupplyNoiseRandRatio").toDouble() * vdd; + double supply_noise_det = getTechModel()->get("SenseAmp->SupplyNoiseDetRatio").toDouble() * vdd; + double noise_margin = getTechModel()->get("SenseAmp->NoiseMargin"); + double jitter_ratio = getTechModel()->get("SenseAmp->JitterRatio"); + + // Approximate tao using FO4 + double unit_drain_cap = getTechModel()->get("Gate->MinWidth").toDouble() * getTechModel()->get("Drain->CapPerWidth").toDouble(); + double c_g = getTechModel()->getStdCellLib()->getStdCellCache()->get("INV_X1->Cap->A"); + double c_d = getTechModel()->getStdCellLib()->getStdCellCache()->get("INV_X1->Cap->Y"); + double r_o = getTechModel()->getStdCellLib()->getStdCellCache()->get("INV_X1->DriveRes->Y"); + // Calculate sense amp tau from sense amp output loading + double tau = r_o * (c_g + c_d); + // Set output inverter drive strength + getDriver("OutDriver")->setOutputRes(r_o); + + // Calculate sense amp input cap based on schematic + double sense_amp_cap_in = unit_drain_cap * (2.0 + 3.0 + 5.0 + 1.0); + + // Residual offset + double v_residual = 3 * offset / pow(2, offset_comp_bits); + // Noise + double v_noise = supply_noise_rand * supply_noise_rand / (CMRR * CMRR); + // Sense amp voltage build-up minimum + double v_sense = vdd * exp(-(1 - integ_time_ratio) / (data_rate * tau)) + noise_margin + v_residual + supply_noise_det / CMRR; + // Sigmas corresponding to BER + double sigma = calcInvNormCdf(BER); + + //K_int is the time the bit is valid for evaluation + + // Total input cap load + double input_node_cap = sense_amp_cap_in + pd_cap + parasitic_cap; + double z_int = integ_time_ratio / (data_rate * input_node_cap); //should use K_int + + // Store precalculated values + m_quad_a_ = 1 - (sigma * sigma * jitter_ratio * jitter_ratio); + m_quad_b1_ = - 2 * pi / 2 * sigma * sigma * q * 0.7 * data_rate; + m_quad_b2_ = -2 * v_sense / (z_int * apd); + m_quad_c_ = 1 / (z_int * z_int) * (v_sense * v_sense - sigma * sigma * (k * T / input_node_cap + v_noise)); + } + else ASSERT(false, "[Error] " + getInstanceName() + " -> Unknown receiver topology (" + topology + ")!"); + + return; + } + + void RingDetector::designReceiver() + { + // Get some generated properties + unsigned int number_wavelengths = getGenProperties()->get("NumberWavelengths"); + + // Get relevant properties/parameters + const String& topology = getParameter("Topology"); + + // Construct a simple sense-amp model + if(topology == INTEGRATINGSENSEAMP) + { + // No really good way to estimate the area...can assume each receiver is the size of 40 inverters, which is + // about the right size for just the sense amp in the layout + double unit_area_active = getTechModel()->getStdCellLib()->getStdCellCache()->get("INV_X1->Area->Active"); + double unit_area_metal1 = getTechModel()->getStdCellLib()->getStdCellCache()->get("INV_X1->Area->Metal1Wire"); + getAreaResult("Active")->setValue(unit_area_active * 40 * number_wavelengths); + getAreaResult("Metal1Wire")->setValue(unit_area_metal1 * 40 * number_wavelengths); + } + else ASSERT(false, "[Error] " + getInstanceName() + " -> Unknown receiver topology (" + topology + ")!"); + + return; + } + + double RingDetector::getSensitivity(double ER_dB_) const + { + // Get parameters + const String& topology = getParameter("Topology"); + // Turn extinction ratio into a ratio from dB scale + double ER = pow(10, ER_dB_ / 10); + + // Initialize sensitivity + double sensitivity = 1e99; + // Construct a simple sense-amp model + if(topology == INTEGRATINGSENSEAMP) + { + // Scale photodetector shot noise using ER, add rest of noise source + double b = m_quad_b1_ * (1 + ER) / (2 * (ER - 1)) + m_quad_b2_; + + // Find sensitivity (-b + sqrt(b^2-4ac)) / 2a + sensitivity = ((-b + sqrt(b * b - 4 * m_quad_a_ * m_quad_c_)) / (2 * m_quad_a_)); + } + else ASSERT(false, "[Error] " + getInstanceName() + " -> Unknown receiver topology (" + topology + ")!"); + + return sensitivity; + } + + double RingDetector::calcInvNormCdf(double num_) + { + // 53 bit precision for double FP + unsigned int num_iterations = 20; + // Upperbound the step + double step = 20; + double out = step; + // Iteratively guess and check calculation + for (unsigned int i = 0; i < num_iterations; ++i) + { + double current = 0.5 * erfc(out / sqrt(2)); + if (current > num_) out += step; + else out -= step; + step = step * 0.5; + } + + return out; + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical/RingFilter.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical/RingFilter.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_OPTICAL_RINGFILTER_H__ +#define __DSENT_MODEL_OPTICAL_RINGFILTER_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/OpticalModel.hh" + +namespace DSENT +{ + class RingFilter : public OpticalModel + { + public: + RingFilter(const String& instance_name_, const TechModel* tech_model_); + virtual ~RingFilter(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + + protected: + // Build the model + virtual void constructModel(); + virtual void updateModel(); + + }; // class RingFilter +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICAL_RINGFILTER_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical/RingFilter.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical/RingFilter.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/optical/RingFilter.hh" + +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalWaveguide.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalFilter.hh" + +namespace DSENT +{ + RingFilter::RingFilter(const String& instance_name_, const TechModel* tech_model_) + : OpticalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + RingFilter::~RingFilter() + {} + + void RingFilter::initParameters() + { + addParameterName("InStart"); + addParameterName("InEnd"); + addParameterName("DropStart"); + addParameterName("DropEnd"); + addParameterName("DropAll", "TRUE"); + return; + } + + void RingFilter::initProperties() + { + return; + } + + void RingFilter::constructModel() + { + //TODO: Add tuning energy/ndd-power costs? + + // Create Area result + Result* area_result = new AtomicResult("Photonic"); + addAreaResult(area_result); + + // Get parameters + WavelengthGroup in_wavelengths = makeWavelengthGroup(getParameter("InStart"), getParameter("InEnd")); + WavelengthGroup drop_wavelengths = makeWavelengthGroup(getParameter("DropStart"), getParameter("DropEnd")); + bool drop_all = getParameter("DropAll"); + + // Create optical ports + createOpticalInputPort( "In", in_wavelengths); + createOpticalOutputPort( "Drop", drop_wavelengths); + createOpticalOutputPort( "Out", in_wavelengths); + // Create the filter + createFilter( "RingFilter", in_wavelengths, drop_all, drop_wavelengths); + OpticalFilter* ring_filter = getFilter("RingFilter"); + // Connect the filter + getWaveguide("In")->addDownstreamNode(ring_filter); + ring_filter->addDownstreamNode(getWaveguide("Out")); + ring_filter->setDropPort(getWaveguide("Drop")); + } + + void RingFilter::updateModel() + { + //TODO: Get numbers from tech model; + double ring_area = 200e-12; + double thru_loss = 1e-4; + double drop_loss = 1.0; + // Get parameters + WavelengthGroup drop_wavelengths = makeWavelengthGroup(getParameter("DropStart"), getParameter("DropEnd")); + int number_wavelengths = drop_wavelengths.second - drop_wavelengths.first + 1; + // Update losses + OpticalFilter* ring_filter = getFilter("RingFilter"); + ring_filter->setLoss(thru_loss * number_wavelengths); + ring_filter->setDropLoss(drop_loss + thru_loss * number_wavelengths); + // Update area + getAreaResult("Photonic")->setValue(ring_area * (number_wavelengths)); + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical/RingModulator.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical/RingModulator.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_OPTICAL_RINGMODULATOR_H__ +#define __DSENT_MODEL_OPTICAL_RINGMODULATOR_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/OpticalModel.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalTransmitter.hh" + +namespace DSENT +{ + class RingModulator : public OpticalModel, public OpticalTransmitter + { + public: + RingModulator(const String& instance_name_, const TechModel* tech_model_); + virtual ~RingModulator(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + // Set the transmitter specifications, returns whether it is possible + // to build a modulator that met those specs + bool setTransmitterSpec(double IL_dB_, double ER_dB_); + // Returns power of the transmitter at a given utilization + double getPower(double util_) const; + + private: + // Precompute values based on tech parameters + void precomputeTech(); + // Design ring modulator driver + bool designModulator(double IL_dB_, double ER_dB_); + // Calculate modulator energy + double calcModulatorEnergy() const; + + protected: + // Build the model + virtual void constructModel(); + virtual void updateModel(); + virtual void useModel(); + virtual void propagateTransitionInfo(); + + private: + // Some precomputed tech values + double m_precompute_V_bi_; + double m_precompute_x_d0_; + double m_precompute_C_j0_; + double m_precompute_Q_0_; + + + }; // class RingModulator +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICAL_RINGMODULATOR_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical/RingModulator.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical/RingModulator.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,434 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/optical/RingModulator.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/util/Constants.hh" +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalWaveguide.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalModulator.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalFilter.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalTransmitter.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalLoad.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingTree.hh" + +namespace DSENT +{ + using std::max; + using std::min; + + // TODO: Don't like the way this is written right now. Probably fix in a future version + + RingModulator::RingModulator(const String& instance_name_, const TechModel* tech_model_) + : OpticalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + RingModulator::~RingModulator() + {} + + void RingModulator::initParameters() + { + addParameterName("DataRate"); + addParameterName("InStart"); + addParameterName("InEnd"); + addParameterName("ModStart"); + addParameterName("ModEnd"); + addParameterName("OptimizeLoss", "TRUE"); + return; + } + + void RingModulator::initProperties() + { + addPropertyName("ExtinctionRatio", 6); //default properties + addPropertyName("InsertionLoss", 2); //default properties + return; + } + + void RingModulator::constructModel() + { + // Create electrical results + createElectricalAtomicResults(); + // Create Area result + addAreaResult(new AtomicResult("Photonic")); + // Create Modulate result + createElectricalEventAtomicResult("Modulate"); + + // Get parameters + WavelengthGroup in_wavelengths = makeWavelengthGroup(getParameter("InStart"), getParameter("InEnd")); + WavelengthGroup mod_wavelengths = makeWavelengthGroup(getParameter("ModStart"), getParameter("ModEnd")); + int number_wavelengths = mod_wavelengths.second - mod_wavelengths.first + 1; + bool optimize_loss = getParameter("OptimizeLoss"); + + getGenProperties()->set("NumberWavelengths", number_wavelengths); + + // Create optical ports + createOpticalInputPort( "In", in_wavelengths); + createOpticalOutputPort( "Out", in_wavelengths); + // Create the filter and modulator + createFilter( "RingFilter", in_wavelengths, true, mod_wavelengths); + createModulator( "RingModulator", mod_wavelengths, optimize_loss, this); + createWaveguide( "RingTemp", mod_wavelengths); + OpticalFilter* ring_filter = getFilter("RingFilter"); + OpticalModulator* ring_modulator = getModulator("RingModulator"); + // Connect the filter and modulator + getWaveguide("In")->addDownstreamNode(ring_filter); + ring_filter->addDownstreamNode(getWaveguide("Out")); + ring_filter->setDropPort(ring_modulator); + ring_modulator->addDownstreamNode(getWaveguide("Out")); + + // Create electrical ports + createInputPort( "In", makeNetIndex(0, number_wavelengths-1)); + // Create driver + createNet("PredriverIn"); + // VFI from In to PredriverIn + assignVirtualFanin("PredriverIn", "In"); + // Create input load (due to predrivers) + createLoad("PredriverCap"); + getNet("PredriverIn")->addDownstreamNode(getLoad("PredriverCap")); + + // Precompute some values + precomputeTech(); + + return; + } + + void RingModulator::updateModel() + { + // Get properties + double ER_dB = getProperty("ExtinctionRatio").toDouble(); + double IL_dB = getProperty("InsertionLoss").toDouble(); + + // Get Gen properties + int number_wavelengths = getGenProperties()->get("NumberWavelengths"); + + // Get tech model parameters + double ring_area = getTechModel()->get("Ring->Area").toDouble(); + double thru_loss = getTechModel()->get("Ring->ThroughLoss").toDouble(); + + // Design the modulator and the modulator driver + bool success = designModulator(IL_dB, ER_dB); + getGenProperties()->set("Success", success); + + // If not successful, make the modulate energy extremely large + if (!success) getEventResult("Modulate")->setValue(1e99); + + // Update losses + // Connect the filter and modulator + OpticalFilter* ring_filter = getFilter("RingFilter"); + ring_filter->setLoss(thru_loss * number_wavelengths); + ring_filter->setDropLoss(thru_loss * number_wavelengths); // Assume worst-case through loss for a dropped wavelength + // Update area + getAreaResult("Photonic")->setValue(ring_area * (number_wavelengths)); + } + + void RingModulator::useModel() + { + // Propagate the transition info and get the 0->1 transtion count + propagateTransitionInfo(); + double P_In = getInputPort("In")->getTransitionInfo().getProbability1(); + double P_num_trans_01 = getInputPort("In")->getTransitionInfo().getNumberTransitions01(); + + // Get Gen properties + int number_wavelengths = getGenProperties()->get("NumberWavelengths"); + + // If I can't build it...then it is infinitely expensive! + bool success = getGenProperties()->get("Success"); + double driver_size = 1e99; + double total_predriver_size = 1e99; + if (success) + { + driver_size = getGenProperties()->get("DriverSize"); + total_predriver_size = getGenProperties()->get("TotalPredriverSize"); + } + + // Get parameters corresponding to a unit-inverter + double unit_leak_0 = getTechModel()->getStdCellLib()->getStdCellCache()->get("INV_X1->Leakage->!A"); + double unit_leak_1 = getTechModel()->getStdCellLib()->getStdCellCache()->get("INV_X1->Leakage->A"); + + // Approximate leakage + double total_leakage = number_wavelengths * 0.5 * ((driver_size + total_predriver_size) * P_In * unit_leak_1 + + (driver_size + total_predriver_size) * (1 - P_In) * unit_leak_0); + + getNddPowerResult("Leakage")->setValue(total_leakage); + getEventResult("Modulate")->setValue(calcModulatorEnergy() * P_num_trans_01); + + return; + } + + void RingModulator::propagateTransitionInfo() + { + // Very simple...whatever comes in electrically is encoded optically + getOpticalOutputPort("Out")->setTransitionInfo(getInputPort("In")->getTransitionInfo()); + + return; + } + + void RingModulator::precomputeTech() + { + // Get parameters + double data_rate = getParameter("DataRate"); + + // Constants shortcuts + double pi = Constants::pi; + double c = Constants::c; + double k = Constants::k; + double e0 = Constants::e0; + double es = Constants::es; + double q = Constants::q; + double T = getTechModel()->get("Temperature"); + + // Get modulator parameters + double lambda = getTechModel()->get("Ring->Lambda").toDouble(); + double n_f = getTechModel()->get("Modulator->Ring->FCPDEffect").toDouble(); + double NA = getTechModel()->get("Modulator->Ring->NA").toDouble(); + double ND = getTechModel()->get("Modulator->Ring->ND").toDouble(); + double ni = getTechModel()->get("Modulator->Ring->ni").toDouble(); + double L_j = getTechModel()->get("Modulator->Ring->JunctionRatio").toDouble(); + double H = getTechModel()->get("Modulator->Ring->Height").toDouble(); + double W = getTechModel()->get("Modulator->Ring->Width").toDouble(); + double g_c = getTechModel()->get("Modulator->Ring->ConfinementFactor").toDouble(); + // Get ring parameters + double R = getTechModel()->get("Ring->Radius").toDouble(); + double n_g = getTechModel()->get("Ring->GroupIndex").toDouble(); + double Q_max = getTechModel()->get("Ring->MaxQualityFactor").toDouble(); + + // Setup calculations + double f0 = c / lambda; + double BW = data_rate; // Modulator bandwidth + double Q_f = std::min(f0 / BW, Q_max); // Quality factor + double L_tot = 2 * pi * R; // Optical length of the ring + + double V_bi = k * T / q * log(NA * ND / (ni * ni)); // Junction Built-in voltage + double x_d0 = sqrt(2 * e0 * es / q * V_bi * (NA + ND) / (NA * ND)); // Junction nominal depletion width + double C_j0 = e0 * es * L_tot * L_j * W / x_d0; // Junction nominal cap + double Q_0 = q * n_g * (L_tot * H * W) / (2 * n_f * Q_f * g_c); // Charge in depletion region + + // Store into precomputed values + m_precompute_V_bi_ = V_bi; + m_precompute_x_d0_ = x_d0; + m_precompute_C_j0_ = C_j0; + m_precompute_Q_0_ = Q_0; + + return; + } + + bool RingModulator::designModulator(double IL_dB_, double ER_dB_) + { + // Get parameters + double vdd = getTechModel()->get("Vdd"); + double data_rate = getParameter("DataRate"); + unsigned int max_predriver_stages = 20; //TODO: Make this not hardcoded + // Get modulator parameters + double boost_ratio = getTechModel()->get("Modulator->Ring->SupplyBoostRatio"); + double Tn = getTechModel()->get("Modulator->Ring->Tn").toDouble();; + double H = getTechModel()->get("Modulator->Ring->Height").toDouble(); + + // Get Gen properties + int number_wavelengths = getGenProperties()->get("NumberWavelengths"); + + // Checking ASSERTions (input properties that don't make any sense) + ASSERT(ER_dB_ > 0, "[Error] " + getInstanceName() + " -> Extinction ratio must be > 0!"); + ASSERT(IL_dB_ > 0, "[Error] " + getInstanceName() + " -> Insertion loss must be > 0!"); + + // Setup calculations + double ER = pow(10, ER_dB_ / 10); // Extinction ratio + double T1 = pow(10, -IL_dB_ / 10); // Transmisivity on + double T0 = T1 / ER; // Transmisivity off + + // Get precomputed values + double V_bi = m_precompute_V_bi_; + double x_d0 = m_precompute_x_d0_; + double C_j0 = m_precompute_C_j0_; + double Q_0 = m_precompute_Q_0_; + + // Charge + double int_c = -2 * V_bi * C_j0; + // Calculate shift using lorentzian + double gamma = sqrt((1 - Tn)/(1 - T1) - 1) - sqrt((1 - Tn)/(1 - T0) - 1); // gamma = delta_f / delta_f_FWHM + double Q = gamma * Q_0; // Charge required to hit given Tf + // Voltage required + double V_a = V_bi * (pow( (Q - int_c)/(2 * V_bi * C_j0), 2) - 1); + // Calculate driver vdd + double hvdd = V_a * boost_ratio; + // Depletion region required + double x_d = x_d0 * sqrt((V_bi + V_a) / V_bi); + + // Calculate C_eff + double c_eff = Q / V_a; + + // Feasibility checks + // Not feasible if the transmisivity when transmitting an optical 1 is greater than 1.0... + if (T1 >= 1) return false; + // Not feasible if the transmisivity when transmitting an optical 0 is smaller than the notch of the ring + if (T0 <= Tn) return false; + // Not feasible if the extinction ratio is greater than the notch of the ring + if (ER >= 1 / Tn) return false; + // Not feasible if the required depletion width is greater than the height of the junction + if (x_d >= H) return false; + + // Analytically calculate driver sizes + // Get parameters corresponding to a unit-inverter + double unit_c_g = getTechModel()->getStdCellLib()->getStdCellCache()->get("INV_X1->Cap->A"); + double unit_c_d = getTechModel()->getStdCellLib()->getStdCellCache()->get("INV_X1->Cap->Y"); + double unit_r_o = getTechModel()->getStdCellLib()->getStdCellCache()->get("INV_X1->DriveRes->Y"); + double unit_area_active = getTechModel()->getStdCellLib()->getStdCellCache()->get("INV_X1->Area->Active"); + double unit_area_metal1 = getTechModel()->getStdCellLib()->getStdCellCache()->get("INV_X1->Area->Metal1Wire"); + + // Get device resistance/cap + double device_par_res = getTechModel()->get("Modulator->Ring->ParasiticRes"); + double device_par_cap = getTechModel()->get("Modulator->Ring->ParasiticCap"); + + // Use timing tree to size modulator drivers + // Coefficient of R*C to give a 0->V_a transition + double transition_scale = log(hvdd / (hvdd - V_a)); + double transition_required = 1 / (4 * data_rate); // I am not sure what the factor of 4 is for... + + // Calculate inverter intrinsic transition time + double transition_intrinsic = transition_scale * unit_c_d * unit_r_o; + // Calculate minimum possible device transition time + double min_transition_intrinsic = transition_intrinsic + transition_scale * device_par_res * c_eff; + // If the minimum possible transition time is already bigger + // than the required transition, then this particular driver is not possible... + if (min_transition_intrinsic > transition_required) + return false; + + // Calculate driver size + double driver_size = max(1.0, transition_scale * unit_r_o * (c_eff + device_par_cap) / (transition_required - min_transition_intrinsic)); + // Keep track of the total multiplier of unit inverters (for area, leakage calculations) + double total_unit_inverters = driver_size * max(1.0, hvdd / vdd); + // Calculate load cap for predriver stages + double current_load_cap = driver_size * unit_c_g; + // Number of predriver stages + unsigned int predriver_stages = 0; + // Add predriver stages until the input cap is less than the unit INV_X1 gate cap or + // if the signal is still inverted (need an odd number of predriver stages) + while (current_load_cap > unit_c_g || (predriver_stages == 0) || ((predriver_stages & 0x1) == 0)) + { + // Calculate the size of the current predriver stage + double current_predriver_size = max(1.0, unit_r_o * current_load_cap / (transition_required - transition_intrinsic)); + // Calculate load cap for the next predriver stage + current_load_cap = current_predriver_size * unit_c_g; + // Add cap to total predriver total cap + total_unit_inverters += current_predriver_size; + // Consider this a failure if the number of predriver stages exceed some maximum + if (predriver_stages > max_predriver_stages) + return false; + + ++predriver_stages; + } + // Set the input load capacitance + getLoad("PredriverCap")->setLoadCap(current_load_cap); + + // Set generated properties + getGenProperties()->set("DriverSize", driver_size); + getGenProperties()->set("FirstPredriverSize", current_load_cap); + getGenProperties()->set("TotalPredriverSize", total_unit_inverters - driver_size); + getGenProperties()->set("Hvdd", hvdd); + getGenProperties()->set("Ceff", c_eff); + + // Calculate leakage, area, energy consumption + double area_active = total_unit_inverters * unit_area_active; + double area_metal1 = total_unit_inverters * unit_area_metal1; + + // Set results + getAreaResult("Active")->setValue(area_active * number_wavelengths); + getAreaResult("Metal1Wire")->setValue(area_metal1 * number_wavelengths); + + // Only if everything was successful do we set the modulator specification + getModulator("RingModulator")->setLosses(IL_dB_, ER_dB_); + return true; + } + + double RingModulator::calcModulatorEnergy() const + { + // Get tech parameters + double vdd = getTechModel()->get("Vdd"); + double device_par_cap = getTechModel()->get("Modulator->Ring->ParasiticCap"); + + // Get Gen properties + int number_wavelengths = getGenProperties()->get("NumberWavelengths"); + + bool success = getGenProperties()->get("Success"); + if (success) + { + double driver_size = getGenProperties()->get("DriverSize"); + double total_predriver_size = getGenProperties()->get("TotalPredriverSize"); + double first_predriver_size = getGenProperties()->get("FirstPredriverSize"); + double c_eff = getGenProperties()->get("Ceff"); + double hvdd = getGenProperties()->get("Hvdd"); + + // Get parameters corresponding to a unit-inverter + double unit_c_g = getTechModel()->getStdCellLib()->getStdCellCache()->get("INV_X1->Cap->A"); + double unit_c_d = getTechModel()->getStdCellLib()->getStdCellCache()->get("INV_X1->Cap->Y"); + + // Approximate leakage + double energy_predriver = number_wavelengths * vdd * vdd * ((unit_c_d * total_predriver_size + + unit_c_g * (total_predriver_size + driver_size - first_predriver_size))); + double energy_driver = number_wavelengths * hvdd * std::max(hvdd, vdd) * (driver_size * unit_c_d + c_eff + device_par_cap); + + return (energy_predriver + energy_driver); + } + else + return 1e99; // An infinitely expensive modulator + } + + bool RingModulator::setTransmitterSpec(double IL_dB_, double ER_dB_) + { + setProperty("InsertionLoss", IL_dB_); + setProperty("ExtinctionRatio", ER_dB_); + update(); + evaluate(); + + return getGenProperties()->get("Success"); + } + + double RingModulator::getPower(double util_) const + { + // Get parameters + double data_rate = getParameter("DataRate"); + // Check arguments + ASSERT((util_ <= 1.0) && (util_ >= 0.0), "[Error] " + getInstanceName() + " -> Modulator utilization must be between 0.0 and 1.0!"); + + return calcModulatorEnergy() * 0.25 * util_ * data_rate; + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical/SConscript --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical/SConscript Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,44 @@ +# 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. +# +# Authors: Chia-Hsin Owen Chen + +Import('*') + +if env['PROTOCOL'] == 'None': + Return() + +Source('OpticalLinkBackendRx.cc') +Source('GatedLaserSource.cc') +Source('OpticalLinkBackendTx.cc') +Source('RingFilter.cc') +Source('SWMRLink.cc') +Source('SWSRLink.cc') +Source('OpticalTestModel.cc') +Source('ThrottledLaserSource.cc') +Source('RingModulator.cc') +Source('LaserSource.cc') +Source('RingDetector.cc') + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical/SWMRLink.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical/SWMRLink.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_OPTICAL_SWMRLINK_H__ +#define __DSENT_MODEL_OPTICAL_SWMRLINK_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/OpticalModel.hh" + +namespace DSENT +{ + class SWMRLink : public OpticalModel + { + // A SWMR Link consists of a laser, a modulator (the writer) and a variable + // number of readers + public: + SWMRLink(const String& instance_name_, const TechModel* tech_model_); + virtual ~SWMRLink(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + + protected: + // Build the model + virtual void constructModel(); + virtual void updateModel(); + virtual void propagateTransitionInfo(); + + private: + void buildLaser(); + void buildModulator(); + void buildDetectors(); + + }; // class SWMRLink +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICAL_SWMRLINK_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical/SWMRLink.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical/SWMRLink.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,340 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/optical/SWMRLink.hh" + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalGraph.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalWaveguide.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical/RingModulator.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical/RingFilter.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical/RingDetector.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical/LaserSource.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical/ThrottledLaserSource.hh" + +namespace DSENT +{ + SWMRLink::SWMRLink(const String& instance_name_, const TechModel* tech_model_) + : OpticalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + SWMRLink::~SWMRLink() + {} + + void SWMRLink::initParameters() + { + addParameterName("NumberReaders"); + addParameterName("NumberWavelengths"); + addParameterName("DataRate"); + addParameterName("LaserType"); + addParameterName("MaxReaders"); + addParameterName("MinReaders"); + addParameterName("OptimizeLoss", "TRUE"); + return; + } + + void SWMRLink::initProperties() + { + addPropertyName("Length"); + addPropertyName("OptUtil", 0.5); // default to 50% utilization (a new word 50% of the time) + addPropertyName("ExtinctionRatio", 6); // default properties + addPropertyName("InsertionLoss", 2); // default properties + return; + } + + void SWMRLink::constructModel() + { + // Get parameters + unsigned int number_wavelengths = getParameter("NumberWavelengths"); + unsigned int number_readers = getParameter("NumberReaders"); + unsigned int number_max_readers = std::min(number_readers, getParameter("MaxReaders").toUInt()); + unsigned int number_min_readers = std::min(number_max_readers, getParameter("MinReaders").toUInt()); + + // Create electrical ports + createInputPort("CK"); + createInputPort("In", makeNetIndex(0, number_wavelengths-1)); + for (unsigned int i = 0; i < number_readers; ++i) + createOutputPort("Out" + (String) i, makeNetIndex(0, number_wavelengths-1)); + + // Create Waveguides + // Temporarily assume its all on one waveguide + createWaveguide("LaserToMod", makeWavelengthGroup(0, number_wavelengths-1)); + for (unsigned int i = 0; i <= number_readers; ++i) + createWaveguide("WaveguideSegment[" + (String) i + "]", makeWavelengthGroup(0, number_wavelengths-1)); + + // Add area results + addAreaResult(new Result("Photonic")); + createElectricalResults(); + // Setup idle event + getEventInfo("Idle")->setStaticTransitionInfos(); + // Create a waveguide area result + addAreaResult(new AtomicResult("Waveguide")); + getAreaResult("Photonic")->addSubResult(getAreaResult("Waveguide"), "Waveguide", 1.0); + // Add results + addNddPowerResult(new Result("Laser")); + // Add event result + createElectricalEventResult("BroadcastFlit"); + + for (unsigned int i = number_min_readers; i <= number_max_readers; ++i) + createElectricalEventResult("MulticastFlit" + (String) i); + + buildLaser(); + buildModulator(); + buildDetectors(); + + return; + } + + void SWMRLink::updateModel() + { + // Get parameters + double data_rate = getParameter("DataRate"); + unsigned int number_readers = getParameter("NumberReaders"); + + // Get properties + double length = getProperty("Length"); + const String& extinction_ratio = getProperty("ExtinctionRatio"); + const String& insertion_loss = getProperty("InsertionLoss"); + const double opt_util = getProperty("OptUtil"); + + // Calculate loss for each waveguide segment + double segment_length = (double) length / number_readers; + double segment_loss = getTechModel()->get("Waveguide->LossPerMeter").toDouble() * segment_length; + // Set loss of each waveguide segment + for (unsigned int i = 0; i < number_readers; ++i) + getWaveguide("WaveguideSegment[" + (String) i + "]")->setLoss(segment_loss); + // Calculate waveguide area + double waveguide_area = length * getTechModel()->get("Waveguide->Pitch").toDouble(); + getAreaResult("Waveguide")->setValue(waveguide_area); + + // Update the laser + Model* laser = getSubInstance("Laser"); + laser->setProperty("LaserEventTime", 1.0 / data_rate); + laser->setProperty("OptUtil", opt_util); + laser->update(); + + // Update the modulator + Model* modulator = getSubInstance("Modulator"); + modulator->setProperty("ExtinctionRatio", extinction_ratio); + modulator->setProperty("InsertionLoss", insertion_loss); + modulator->update(); + + // Update all receivers + for (unsigned int i = 0; i < number_readers; ++i) + { + Model* detector = getSubInstance("Detector_" + (String) i); + detector->update(); + } + + return; + } + + void SWMRLink::propagateTransitionInfo() + { + // Get parameters + const String& laser_type = getParameter("LaserType"); + unsigned int number_readers = getParameter("NumberReaders"); + + // Set transition info for the modulator + OpticalModel* modulator = (OpticalModel*) getSubInstance("Modulator"); + propagatePortTransitionInfo(modulator, "In", "In"); + modulator->use(); + + // Modulator out transition info + const TransitionInfo& mod_out_transitions = modulator->getOpticalOutputPort("Out")->getTransitionInfo(); + + // Set transition info for all receivers + for (unsigned int i = 0; i < number_readers; ++i) + { + OpticalModel* detector = (OpticalModel*) getSubInstance("Detector_" + (String) i); + detector->getOpticalInputPort("In")->setTransitionInfo(mod_out_transitions); + detector->use(); + + // Propagate output transition info to output + propagatePortTransitionInfo("Out" + (String) i, detector, "Out"); + } + + // Set enable signals for the laser, if applicable + if (laser_type == "Throttled") + { + // Figure out how many cycles the laser needs to be on + double cycles = getInputPort("In")->getTransitionInfo().getFrequencyMultiplier(); + + OpticalModel* laser = (OpticalModel*) getSubInstance("Laser"); + laser->getInputPort("LaserEnable")->setTransitionInfo(TransitionInfo(0.0, 1.0, cycles - 1.0)); + laser->use(); + } + return; + } + + void SWMRLink::buildLaser() + { + // Get parameters + unsigned int number_wavelengths = getParameter("NumberWavelengths"); + unsigned int number_readers = getParameter("NumberReaders"); + unsigned int number_max_readers = std::min(number_readers, getParameter("MaxReaders").toUInt()); + unsigned int number_min_readers = std::min(number_max_readers, getParameter("MinReaders").toUInt()); + const String& laser_type = getParameter("LaserType"); + + // Create laser + OpticalModel* laser = NULL; + if (laser_type == "Throttled") + laser = new ThrottledLaserSource("Laser", getTechModel()); + else if (laser_type == "Standard") + laser = new LaserSource("Laser", getTechModel()); + else + ASSERT(false, "[Error] " + getInstanceName() + " -> Unknown laser type '" + laser_type + "'!"); + + laser->setParameter("OutStart", 0); + laser->setParameter("OutEnd", number_wavelengths-1); + laser->setParameter("MaxDetectors", number_max_readers); + laser->setParameter("MinDetectors", number_min_readers); + laser->construct(); + + addSubInstances(laser, 1.0); + getAreaResult("Photonic")->addSubResult(laser->getAreaResult("Photonic"), "Laser", 1.0); + // Connect laser output port + opticalPortConnect(laser, "Out", "LaserToMod"); + + // Without laser gating, laser is pure NDD power + if (laser_type == "Standard") + getNddPowerResult("Laser")->addSubResult(laser->getNddPowerResult("Laser"), "Laser", 1.0); + // With laser power gating, laser is an event + else + { + // If laser is throttled, only pay for the amount needed to reach some number of readers + getEventResult("BroadcastFlit")->addSubResult(laser->getEventResult("Laser" + (String) number_max_readers), "Laser", 1.0); + for (unsigned int i = number_min_readers; i <= number_max_readers; ++i) + getEventResult("MulticastFlit" + (String) i)->addSubResult(laser->getEventResult("Laser" + (String) i), "Laser", 1.0); + } + + return; + } + + void SWMRLink::buildModulator() + { + // Get parameters + double data_rate = getParameter("DataRate"); + const String& optimize_loss = getParameter("OptimizeLoss"); + unsigned int number_wavelengths = getParameter("NumberWavelengths"); + unsigned int number_readers = getParameter("NumberReaders"); + unsigned int number_max_readers = std::min(number_readers, getParameter("MaxReaders").toUInt()); + unsigned int number_min_readers = std::min(number_max_readers, getParameter("MinReaders").toUInt()); + + // Create modulator + RingModulator* modulator = new RingModulator("Modulator", getTechModel()); + modulator->setParameter("DataRate", data_rate); + modulator->setParameter("InStart", 0); + modulator->setParameter("InEnd", number_wavelengths-1); + modulator->setParameter("ModStart", 0); + modulator->setParameter("ModEnd", number_wavelengths-1); + modulator->setParameter("OptimizeLoss", optimize_loss); + modulator->construct(); + addSubInstances(modulator, 1.0); + getAreaResult("Photonic")->addSubResult(modulator->getAreaResult("Photonic"), "Modulator", 1.0); + addElectricalSubResults(modulator, 1.0); + + // Connect electrical port + portConnect(modulator, "In", "In"); + // Connect modulator input, output port + opticalPortConnect(modulator, "In", "LaserToMod"); + opticalPortConnect(modulator, "Out", "WaveguideSegment[0]"); + + // Add modulator energy event for all broadcast events + getEventResult("BroadcastFlit")->addSubResult(modulator->getEventResult("Modulate"), "Modulator", 1.0); + for (unsigned int i = number_min_readers; i <= number_max_readers; ++i) + getEventResult("MulticastFlit" + (String) i)->addSubResult(modulator->getEventResult("Modulate"), "Modulator", 1.0); + + return; + } + + void SWMRLink::buildDetectors() + { + // Get parameters + double data_rate = getParameter("DataRate"); + unsigned int number_wavelengths = getParameter("NumberWavelengths"); + unsigned int number_readers = getParameter("NumberReaders"); + unsigned int number_max_readers = std::min(number_readers, getParameter("MaxReaders").toUInt()); + unsigned int number_min_readers = std::min(number_max_readers, getParameter("MinReaders").toUInt()); + + // Create a SWMR Configuration + for (unsigned int i = 0; i < number_readers; ++i) + { + String n = (String) i; + + // Create resonant ring detector + RingDetector* detector = new RingDetector("Detector_" + n, getTechModel()); + detector->setParameter("DataRate", data_rate); + detector->setParameter("InStart", 0); + detector->setParameter("InEnd", number_wavelengths-1); + detector->setParameter("DetStart", 0); + detector->setParameter("DetEnd", number_wavelengths-1); + detector->setParameter("DropAll", "FALSE"); + detector->setParameter("Topology", RingDetector::INTEGRATINGSENSEAMP); + detector->construct(); + addSubInstances(detector, 1.0); + getAreaResult("Photonic")->addSubResult(detector->getAreaResult("Photonic"), "Detector_" + n, 1.0); + addElectricalSubResults(detector, 1.0); + + // connect to electrical port + portConnect(detector, "Out", "Out" + (String) i); + // connect optical input, output port + opticalPortConnect(detector, "In", "WaveguideSegment[" + (String) i + "]"); + opticalPortConnect(detector, "Out", "WaveguideSegment[" + (String) (i + 1) + "]"); + } + + // Add an average receiver energy for all multicast events (and broadcast) + Result* broadcast_event = getEventResult("BroadcastFlit"); + for (unsigned int i = 0; i < number_readers; ++i) + { + const String detector_name = "Detector_" + (String) i; + broadcast_event->addSubResult(getSubInstance(detector_name)->getEventResult("Receive"), detector_name, 1.0); + } + for (unsigned int i = number_min_readers; i <= number_max_readers; ++i) + { + Result* multicast_event = getEventResult("MulticastFlit" + (String) i); + for (unsigned int j = 0; j < number_readers; ++j) + { + const String detector_name = "Detector_" + (String) j; + multicast_event->addSubResult(getSubInstance(detector_name)->getEventResult("Receive"), detector_name, (double) i / number_readers); + } + } + + return; + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical/SWSRLink.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical/SWSRLink.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_OPTICAL_SWSRLINK_H__ +#define __DSENT_MODEL_OPTICAL_SWSRLINK_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/OpticalModel.hh" + +namespace DSENT +{ + class SWSRLink : public OpticalModel + { + // A SWSR Link consists of a laser, a modulator (the writer) and a variable + // number of readers + public: + SWSRLink(const String& instance_name_, const TechModel* tech_model_); + virtual ~SWSRLink(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + + protected: + // Build the model + virtual void constructModel(); + virtual void updateModel(); + virtual void propagateTransitionInfo(); + + private: + void buildLaser(); + void buildModulator(); + void buildDetector(); + + }; // class SWSRLink +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICAL_SWSRLINK_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical/SWSRLink.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical/SWSRLink.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,359 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/optical/SWSRLink.hh" + +#include "mem/ruby/network/dsent/dsent-core/model/ModelGen.hh" +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalGraph.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalWaveguide.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical/RingModulator.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical/RingFilter.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical/RingDetector.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical/LaserSource.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical/ThrottledLaserSource.hh" + +namespace DSENT +{ + SWSRLink::SWSRLink(const String& instance_name_, const TechModel* tech_model_) + : OpticalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + SWSRLink::~SWSRLink() + {} + + void SWSRLink::initParameters() + { + addParameterName("NumberBits"); + addParameterName("CoreDataRate"); + addParameterName("LinkDataRate"); + + addParameterName("LaserType"); + addParameterName("RingTuningMethod"); + addParameterName("OptimizeLoss", "TRUE"); + + return; + } + + void SWSRLink::initProperties() + { + addPropertyName("Length"); + addPropertyName("OptUtil", 0.5); // default to 50% utilization (a new word 50% of the time) + addPropertyName("ExtinctionRatio", 6); // default properties + addPropertyName("InsertionLoss", 2); // default properties + return; + } + + void SWSRLink::constructModel() + { + // Get parameters + unsigned int number_bits = getParameter("NumberBits"); + double core_data_rate = getParameter("CoreDataRate"); + double link_data_rate = getParameter("LinkDataRate"); + + // Get directly propagated parameters + const String& ring_tuning_method = getParameter("RingTuningMethod"); + + // Calculate number of wavelengths needed + unsigned int number_wavelengths = (unsigned int)((double) number_bits * core_data_rate / link_data_rate); + + // Set some generated properties + getGenProperties()->set("NumberWavelengths", number_wavelengths); + + // Create electrical ports + createInputPort("LinkCK"); + createInputPort("In", makeNetIndex(0, number_bits-1)); + createOutputPort("Out", makeNetIndex(0, number_bits-1)); + + // Create Waveguides + // Temporarily assume its all on one waveguide + createWaveguide("LaserToMod", makeWavelengthGroup(0, number_wavelengths-1)); + createWaveguide("ModToDetector", makeWavelengthGroup(0, number_wavelengths-1)); + + // Add area results + addAreaResult(new Result("Photonic")); + createElectricalResults(); + // Setup idle event + getEventInfo("Idle")->setStaticTransitionInfos(); + // Create a waveguide area result + addAreaResult(new AtomicResult("Waveguide")); + getAreaResult("Photonic")->addSubResult(getAreaResult("Waveguide"), "Waveguide", 1.0); + // Add results + addNddPowerResult(new Result("Laser")); + addNddPowerResult(new Result("RingTuning")); + // Add event result + createElectricalEventResult("Send"); + + // Create Tx, Rx backends + // Create Tx electrical backend + ElectricalModel* tx_backend = (ElectricalModel*) ModelGen::createModel("OpticalLinkBackendTx", "OpticalLinkBackendTx", getTechModel()); + tx_backend->setParameter("InBits", number_bits); + tx_backend->setParameter("CoreDataRate", core_data_rate); + tx_backend->setParameter("LinkDataRate", link_data_rate); + tx_backend->setParameter("RingTuningMethod", ring_tuning_method); + tx_backend->setParameter("BitDuplicate", "TRUE"); + tx_backend->construct(); + + // Create Rx electrical backend + ElectricalModel* rx_backend = (ElectricalModel*) ModelGen::createModel("OpticalLinkBackendRx", "OpticalLinkBackendRx", getTechModel()); + rx_backend->setParameter("OutBits", number_bits); + rx_backend->setParameter("CoreDataRate", core_data_rate); + rx_backend->setParameter("LinkDataRate", link_data_rate); + rx_backend->setParameter("RingTuningMethod", ring_tuning_method); + rx_backend->setParameter("BitDuplicate", "TRUE"); + rx_backend->construct(); + + // Connect ports + createNet("TxBackendToTx", makeNetIndex(0, number_wavelengths-1)); + createNet("RxToRxBackend", makeNetIndex(0, number_wavelengths-1)); + portConnect(tx_backend, "In", "In"); + portConnect(tx_backend, "Out", "TxBackendToTx"); + portConnect(tx_backend, "LinkCK", "LinkCK"); + portConnect(rx_backend, "In", "RxToRxBackend"); + portConnect(rx_backend, "Out", "Out"); + portConnect(rx_backend, "LinkCK", "LinkCK"); + + // Add instances + addSubInstances(tx_backend, 1.0); + addSubInstances(rx_backend, 1.0); + + // Add electrical results + addElectricalSubResults(tx_backend, 1.0); + addElectricalSubResults(rx_backend, 1.0); + + // Add tuning power result + getNddPowerResult("RingTuning")->addSubResult(tx_backend->getNddPowerResult("RingTuning"), "OpticalLinkBackendTx", 1.0); + getNddPowerResult("RingTuning")->addSubResult(rx_backend->getNddPowerResult("RingTuning"), "OpticalLinkBackendRx", 1.0); + + // Add event results + getEventInfo("Send")->setTransitionInfo("LinkCK", TransitionInfo(0.0, (double) link_data_rate / (core_data_rate * 2.0), 0.0)); + + getEventResult("Send")->addSubResult(tx_backend->getEventResult("ProcessBits"), "OpticalLinkBackendTx", 1.0); + getEventResult("Send")->addSubResult(rx_backend->getEventResult("ProcessBits"), "OpticalLinkBackendRx", 1.0); + + buildLaser(); + buildModulator(); + buildDetector(); + + return; + } + + void SWSRLink::updateModel() + { + // Get parameters + double link_data_rate = getParameter("LinkDataRate"); + + // Get properties + double length = getProperty("Length"); + const String& extinction_ratio = getProperty("ExtinctionRatio"); + const String& insertion_loss = getProperty("InsertionLoss"); + const double opt_util = getProperty("OptUtil"); + + // Calculate loss for waveguide + double waveguide_loss = getTechModel()->get("Waveguide->LossPerMeter").toDouble() * length; + // Set loss of the waveguide + getWaveguide("ModToDetector")->setLoss(waveguide_loss); + // Calculate waveguide area + double waveguide_area = length * getTechModel()->get("Waveguide->Pitch").toDouble(); + getAreaResult("Waveguide")->setValue(waveguide_area); + + // Update the laser + Model* laser = getSubInstance("Laser"); + laser->setProperty("LaserEventTime", 1.0 / link_data_rate); + laser->setProperty("OptUtil", opt_util); + laser->update(); + + // Update the modulator + Model* modulator = getSubInstance("Modulator"); + modulator->setProperty("ExtinctionRatio", extinction_ratio); + modulator->setProperty("InsertionLoss", insertion_loss); + modulator->update(); + + Model* detector = getSubInstance("Detector"); + detector->update(); + + Model* tx_backend = getSubInstance("OpticalLinkBackendTx"); + tx_backend->update(); + + Model* rx_backend = getSubInstance("OpticalLinkBackendRx"); + rx_backend->update(); + + return; + } + + void SWSRLink::propagateTransitionInfo() + { + // Get parameters + const String& laser_type = getParameter("LaserType"); + + // Propagate transition info to tx backend + OpticalModel* tx_backend = (OpticalModel*) getSubInstance("OpticalLinkBackendTx"); + propagatePortTransitionInfo(tx_backend, "In", "In"); + propagatePortTransitionInfo(tx_backend, "LinkCK", "LinkCK"); + tx_backend->use(); + + // Set transition info for the modulator + OpticalModel* modulator = (OpticalModel*) getSubInstance("Modulator"); + propagatePortTransitionInfo(modulator, "In", tx_backend, "Out"); + modulator->use(); + + // Modulator out transition info + const TransitionInfo& mod_out_transitions = modulator->getOpticalOutputPort("Out")->getTransitionInfo(); + + // Set transition info for the receiver + OpticalModel* detector = (OpticalModel*) getSubInstance("Detector"); + detector->getOpticalInputPort("In")->setTransitionInfo(mod_out_transitions); + detector->use(); + + // Propagate transition info to tx backend + OpticalModel* rx_backend = (OpticalModel*) getSubInstance("OpticalLinkBackendRx"); + propagatePortTransitionInfo(rx_backend, "In", detector, "Out"); + propagatePortTransitionInfo(rx_backend, "LinkCK", "LinkCK"); + rx_backend->use(); + + // Propagate output transition info to output + propagatePortTransitionInfo("Out", rx_backend, "Out"); + + // Set enable signals for the laser, if applicable + if (laser_type == "Throttled") + { + // Figure out how many cycles the laser needs to be on + double cycles = getInputPort("In")->getTransitionInfo().getFrequencyMultiplier(); + + OpticalModel* laser = (OpticalModel*) getSubInstance("Laser"); + laser->getInputPort("LaserEnable")->setTransitionInfo(TransitionInfo(0.0, 1.0, cycles - 1.0)); + laser->use(); + } + + + return; + } + + void SWSRLink::buildLaser() + { + // Get parameters + unsigned int number_wavelengths = getGenProperties()->get("NumberWavelengths"); + const String& laser_type = getParameter("LaserType"); + + // Create laser + OpticalModel* laser = NULL; + if (laser_type == "Throttled") laser = new ThrottledLaserSource("Laser", getTechModel()); + else if (laser_type == "Standard") laser = new LaserSource("Laser", getTechModel()); + else ASSERT(false, "[Error] " + getInstanceName() + " -> Unknown laser type '" + laser_type + "'!"); + + laser->setParameter("OutStart", 0); + laser->setParameter("OutEnd", number_wavelengths-1); + laser->setParameter("MaxDetectors", 1); + laser->setParameter("MinDetectors", 1); + laser->construct(); + + addSubInstances(laser, 1.0); + getAreaResult("Photonic")->addSubResult(laser->getAreaResult("Photonic"), "Laser", 1.0); + // Connect laser output port + opticalPortConnect(laser, "Out", "LaserToMod"); + + // Without laser gating, laser is pure NDD power + if (laser_type == "Standard") getNddPowerResult("Laser")->addSubResult(laser->getNddPowerResult("Laser"), "Laser", 1.0); + // With laser power gating, laser is an event + else getEventResult("Send")->addSubResult(laser->getEventResult("Laser1"), "Laser", 1.0); + + return; + } + + void SWSRLink::buildModulator() + { + // Get parameters + double link_data_rate = getParameter("LinkDataRate"); + const String& optimize_loss = getParameter("OptimizeLoss"); + unsigned int number_wavelengths = getGenProperties()->get("NumberWavelengths"); + + // Create modulator + RingModulator* modulator = new RingModulator("Modulator", getTechModel()); + modulator->setParameter("DataRate", link_data_rate); + modulator->setParameter("InStart", 0); + modulator->setParameter("InEnd", number_wavelengths-1); + modulator->setParameter("ModStart", 0); + modulator->setParameter("ModEnd", number_wavelengths-1); + modulator->setParameter("OptimizeLoss", optimize_loss); + modulator->construct(); + addSubInstances(modulator, 1.0); + getAreaResult("Photonic")->addSubResult(modulator->getAreaResult("Photonic"), "Modulator", 1.0); + addElectricalSubResults(modulator, 1.0); + + // Connect electrical port + portConnect(modulator, "In", "TxBackendToTx"); + // Connect modulator input, output port + opticalPortConnect(modulator, "In", "LaserToMod"); + opticalPortConnect(modulator, "Out", "ModToDetector"); + + // Add modulator energy event for send events + getEventResult("Send")->addSubResult(modulator->getEventResult("Modulate"), "Modulator", 1.0); + return; + } + + void SWSRLink::buildDetector() + { + // Get parameters + double link_data_rate = getParameter("LinkDataRate"); + unsigned int number_wavelengths = getGenProperties()->get("NumberWavelengths"); + + // Create resonant ring detector + RingDetector* detector = new RingDetector("Detector", getTechModel()); + detector->setParameter("DataRate", link_data_rate); + detector->setParameter("InStart", 0); + detector->setParameter("InEnd", number_wavelengths-1); + detector->setParameter("DetStart", 0); + detector->setParameter("DetEnd", number_wavelengths-1); + detector->setParameter("DropAll", "TRUE"); + detector->setParameter("Topology", RingDetector::INTEGRATINGSENSEAMP); + detector->construct(); + addSubInstances(detector, 1.0); + getAreaResult("Photonic")->addSubResult(detector->getAreaResult("Photonic"), "Detector", 1.0); + addElectricalSubResults(detector, 1.0); + + // connect to electrical port + portConnect(detector, "Out", "RxToRxBackend"); + // connect optical input, output port + opticalPortConnect(detector, "In", "ModToDetector"); + + // Add receiver energy + getEventResult("Send")->addSubResult(detector->getEventResult("Receive"), "Detector", 1.0); + + return; + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical/ThrottledLaserSource.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical/ThrottledLaserSource.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_OPTICAL_THROTTLEDLASERSOURCE_H__ +#define __DSENT_MODEL_OPTICAL_THROTTLEDLASERSOURCE_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/OpticalModel.hh" + +namespace DSENT +{ + class OpticalWavelength; + + // A laser source that outputs some number of wavelengths. This laser + // full on/off power gating, thus all power are event-based energies + class ThrottledLaserSource : public OpticalModel + { + public: + ThrottledLaserSource(const String& instance_name_, const TechModel* tech_model_); + virtual ~ThrottledLaserSource(); + + public: + // Set a list of properties' name needed to construct model + void initParameters(); + // Set a list of properties' name needed to construct model + void initProperties(); + + protected: + // Build the model + void constructModel(); + void updateModel(); + void evaluateModel(); + void useModel(); + + private: + // Data structure containing the wavelengths that this laser outputs + OpticalWavelength* m_wavelength_; + + }; // class ThrottledLaserSource +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICAL_THROTTLEDLASERSOURCE_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical/ThrottledLaserSource.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical/ThrottledLaserSource.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/optical/ThrottledLaserSource.hh" + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalWaveguide.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalWavelength.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalLaser.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalGraph.hh" + +namespace DSENT +{ + ThrottledLaserSource::ThrottledLaserSource(const String& instance_name_, const TechModel* tech_model_) + : OpticalModel(instance_name_, tech_model_), m_wavelength_(NULL) + { + initParameters(); + initProperties(); + } + + ThrottledLaserSource::~ThrottledLaserSource() + { + if (m_wavelength_ != NULL) delete m_wavelength_; + } + + void ThrottledLaserSource::initParameters() + { + addParameterName("OutStart"); + addParameterName("OutEnd"); + addParameterName("MaxDetectors"); + addParameterName("MinDetectors"); + return; + } + + void ThrottledLaserSource::initProperties() + { + addPropertyName("OptUtil", 1.0); + addPropertyName("LaserEventTime"); + return; + } + + void ThrottledLaserSource::constructModel() + { + // Get parameters + WavelengthGroup laser_wavelengths = makeWavelengthGroup(getParameter("OutStart"), getParameter("OutEnd")); + unsigned int max_detectors = getParameter("MaxDetectors").toUInt(); + unsigned int min_detectors = getParameter("MinDetectors").toUInt(); + + // Create electrical input port for laser control + createInputPort( "LaserEnable"); + + // Create Area result + addAreaResult(new AtomicResult("Photonic")); + // Create event result for each detector number possibility + for (unsigned int i = min_detectors; i <= max_detectors; ++i) + { + createElectricalEventAtomicResult("Laser" + (String) i); + getEventInfo("Laser" + (String) i)->setTransitionInfo("LaserEnable", TransitionInfo(0.0, 1.0, 0.0)); + } + + // Create optical ports + createOpticalOutputPort( "Out", laser_wavelengths); + // Create the filter + createLaser( "Laser", laser_wavelengths); + OpticalLaser* laser = getLaser("Laser"); + // Connect the laser to the output + laser->addDownstreamNode(getWaveguide("Out")); + } + + void ThrottledLaserSource::updateModel() + { + // Get properties + double laser_efficiency = getTechModel()->get("Laser->CW->Efficiency").toDouble(); + double laser_area = getTechModel()->get("Laser->CW->Area").toDouble(); + double laser_diode_loss = getTechModel()->get("Laser->CW->LaserDiodeLoss"); + + // Get parameters + WavelengthGroup laser_wavelengths = makeWavelengthGroup(getParameter("OutStart"), getParameter("OutEnd")); + unsigned int number_wavelengths = laser_wavelengths.second - laser_wavelengths.first + 1; + // Update losses + OpticalLaser* laser = getLaser("Laser"); + laser->setLoss(laser_diode_loss); + laser->setEfficiency(laser_efficiency); + // Update area + getAreaResult("Photonic")->setValue(laser_area * number_wavelengths); + } + + void ThrottledLaserSource::evaluateModel() + { + // Get parameters + unsigned int max_detectors = getParameter("MaxDetectors"); + WavelengthGroup laser_wavelengths = makeWavelengthGroup(getParameter("OutStart"), getParameter("OutEnd")); + + // Get properties + double opt_util = getProperty("OptUtil"); + + // Create optical graph object + OpticalGraph* optical_graph = new OpticalGraph("LaserTrace", this); + // Ask optical graph object to perform power optimization + bool success = optical_graph->performPowerOpt(getLaser("Laser"), laser_wavelengths, max_detectors, opt_util); + if (!success) + { + Log::printLine(std::cerr, "[Warning] " + getInstanceName() + + " -> Wavelengths contains data paths with no possible modulator configurations!"); + } + + // Trace the wavelengths the laser is outputting to find the output + // power needed by the laser + if (m_wavelength_ != NULL) delete m_wavelength_; + m_wavelength_ = optical_graph->traceWavelength(laser_wavelengths, getLaser("Laser")); + + delete optical_graph; + } + + void ThrottledLaserSource::useModel() + { + // Get parameters + unsigned int max_detectors = getParameter("MaxDetectors"); + unsigned int min_detectors = getParameter("MinDetectors"); + + // Get properties + double laser_event_time = getProperty("LaserEventTime"); + // Get laser enable information + const TransitionInfo& enable_info = getInputPort("LaserEnable")->getTransitionInfo(); + + for (unsigned int i = min_detectors; i <= max_detectors; ++i) + { + // Calculate the power needed by the wavelength + double laser_power = m_wavelength_->getLaserPower(i); + // Calculate the laser event power by calculating the amount + // of time the laser is on + getEventResult("Laser" + (String) i)->setValue(laser_power * laser_event_time * + enable_info.getFrequencyMultiplier() * enable_info.getProbability1()); + } + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalDetector.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalDetector.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_OPTICALGRAPH_OPTICALDETECTOR_H__ +#define __DSENT_MODEL_OPTICALGRAPH_OPTICALDETECTOR_H__ + +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalNode.hh" +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" + +namespace DSENT +{ + class OpticalReceiver; + + class OpticalDetector : public OpticalNode + { + public: + OpticalDetector(const String& instance_name_, OpticalModel* model_, const WavelengthGroup& wavelengths_, OpticalReceiver* receiver_); + ~OpticalDetector(); + + public: + // Set the responsitivity of the photodetector + void setResponsivity(double responsivity_); + + // Get the detector sensitivity given an extinction ratio (in Watts) + double getSensitivity(double ER_dB_) const; + + // Ask the receiver for its power (ONLY use for power optimization, as this + // assumes an activity of 1.0) + double getPower() const; + + private: + // Disable copy constructor + OpticalDetector(const OpticalDetector& node_); + + private: + // The required laser power + double m_sensitivity_; + // The receiver connected to this detector + OpticalReceiver* m_receiver_; + // Responsivity of the photodetector + double m_responsivity_; + + }; + +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICALGRAPH_OPTICALDETECTOR_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalDetector.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalDetector.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + + +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalDetector.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalReceiver.hh" + +namespace DSENT +{ + OpticalDetector::OpticalDetector(const String& instance_name_, OpticalModel* model_, const WavelengthGroup& wavelengths_, OpticalReceiver* receiver_) + : OpticalNode(OpticalNode::DETECTOR, instance_name_, model_, wavelengths_), m_receiver_(receiver_), m_responsivity_(0) + { + m_sensitivity_ = 0.0; + } + + OpticalDetector::~OpticalDetector() + { + + } + + void OpticalDetector::setResponsivity(double responsivity_) + { + m_responsivity_ = responsivity_; + return; + } + + double OpticalDetector::getSensitivity(double ER_dB_) const + { + // Get responsivity (in Amps) of the receiver, divide by responsivity to get sensitivity in Watts + return m_receiver_->getSensitivity(ER_dB_) / m_responsivity_; + } + +} // namespace DSENT + + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalFilter.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalFilter.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_OPTICALGRAPH_OPTICALFILTER_H__ +#define __DSENT_MODEL_OPTICALGRAPH_OPTICALFILTER_H__ + +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalNode.hh" +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" + +namespace DSENT +{ + class OpticalFilter : public OpticalNode + { + public: + OpticalFilter(const String& instance_name_, OpticalModel* model_, const WavelengthGroup& wavelengths_, bool drop_all_, const WavelengthGroup& drop_wavelengths_); + ~OpticalFilter(); + + public: + // Get the drop all flag + bool getDropAll() const; + // Get drop wavelengths + WavelengthGroup getDropWavelengths() const; + // Set and get the drop loss + void setDropLoss(double drop_loss_); + double getDropLoss() const; + // Set and get drop port + void setDropPort(OpticalNode* drop_port_); + OpticalNode* getDropPort(); + // Checks to see if a set of wavelengths will be dropped + bool isDropped(const WavelengthGroup& wavelengths_) const; + + private: + // Disable copy constructor + OpticalFilter(const OpticalFilter& node_); + + private: + // Whether to drop all the optical signal for the drop wavelengths + // i.e. so that the drop wavelengths are not traced anymore + const bool m_drop_all_; + // The loss incurred from in to drop port + double m_drop_loss_; + // The wavelengths that are dropped + const WavelengthGroup m_drop_wavelengths_; + // The node at the drop port + OpticalNode* m_drop_port_; + }; + +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICALGRAPH_OPTICALFILTER_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalFilter.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalFilter.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + + +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalFilter.hh" + +namespace DSENT +{ + OpticalFilter::OpticalFilter(const String& instance_name_, OpticalModel* model_, const WavelengthGroup& wavelengths_, bool drop_all_, const WavelengthGroup& drop_wavelengths_) + : OpticalNode(OpticalNode::FILTER, instance_name_, model_, wavelengths_), m_drop_all_(drop_all_), m_drop_wavelengths_(drop_wavelengths_) + { + m_drop_loss_ = 0.0; + m_drop_port_ = NULL; + } + + OpticalFilter::~OpticalFilter() + { + + } + + bool OpticalFilter::getDropAll() const + { + return m_drop_all_; + } + + WavelengthGroup OpticalFilter::getDropWavelengths() const + { + return m_drop_wavelengths_; + } + + void OpticalFilter::setDropLoss(double drop_loss_) + { + m_drop_loss_ = drop_loss_; + return; + } + + double OpticalFilter::getDropLoss() const + { + return m_drop_loss_; + } + + void OpticalFilter::setDropPort(OpticalNode* drop_port_) + { + m_drop_port_ = drop_port_; + } + + OpticalNode* OpticalFilter::getDropPort() + { + return m_drop_port_; + } + + bool OpticalFilter::isDropped(const WavelengthGroup& wavelengths_) const + { + // Check that the lower limits are within bounds + bool lower_match = (wavelengths_.first >= getDropWavelengths().first); + // Check that the upper limits are within bounds + bool upper_match = (wavelengths_.second <= getDropWavelengths().second); + // Assert that there are no misalignments + ASSERT(lower_match == upper_match, "[Error] " + getInstanceName() + + " -> Wavelength group misalignment!" + + " InWavelength" + toString(wavelengths_) + + ", DropWavelength" + toString(getDropWavelengths())); + // Both upper and lower bounds must match + return (upper_match && lower_match); + } +} // namespace DSENT + + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalGraph.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalGraph.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_OPTICALGRAPH_OPTICALGRAPH_H__ +#define __DSENT_MODEL_OPTICALGRAPH_OPTICALGRAPH_H__ + +#include + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalNode.hh" + +namespace DSENT +{ + class OpticalNode; + class OpticalWavelength; + + class OpticalGraph + { + public: + // The visited number for the next timing run. This needs to be + // global because several timing trees may be created to evaluate + // a single timing path, causing problems + static int msTreeNum; + + public: + // Construct timing tree that watches over model_ + OpticalGraph(const String& instance_name_, OpticalModel* model_); + ~OpticalGraph(); + + public: + // Get graph name + const String& getInstanceName() const; + // Perform datapath power optimization by balancing insertion loss and extinction + // ratio with modulator/receiver and laser power, returns false if there are no + // designs that are possible + bool performPowerOpt(OpticalNode* node_, const WavelengthGroup& wavelengths_, unsigned int number_detectors_, double util_); + // Recursively trace a wavelength starting from an OpticalLaser + // source finding all lasers, modulators and detectors that a + // wavelength group hits. + OpticalWavelength* traceWavelength(const WavelengthGroup& wavelengths_, OpticalNode* node_); + OpticalWavelength* traceWavelength(OpticalWavelength* wavelength_, OpticalNode* node_, OpticalLaser* laser_, OpticalModulator* modulator_, double loss_); + // Return the model + OpticalModel* getModel(); + + private: + + // Disable the use of copy constructor + OpticalGraph(const OpticalGraph& graph_); + + public: + // Set the sequence number of the optical graph + static void setTreeNum(int tree_num_); + static int getTreeNum(); + + private: + // Name of the optical graph + const String m_instance_name_; + // A pointer to the model that contains this node + OpticalModel* m_model_; + + }; // class OpticalGraph +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICALGRAPH_OPTICALGRAPH_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalGraph.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalGraph.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + + +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalGraph.hh" + +#include "mem/ruby/network/dsent/dsent-core/model/OpticalModel.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalNode.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalLaser.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalModulator.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalFilter.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalDetector.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalWavelength.hh" + +namespace DSENT +{ + // Initialize the next visited number to be one above the initial number + // used by OpticalNode + int OpticalGraph::msTreeNum = OpticalNode::OPTICAL_NODE_INIT_VISITED_NUM + 1; + + OpticalGraph::OpticalGraph(const String& instance_name_, OpticalModel* model_) + : m_instance_name_(instance_name_), m_model_(model_) + { + + } + + OpticalGraph::~OpticalGraph() + { + + } + + const String& OpticalGraph::getInstanceName() const + { + return m_instance_name_; + } + + //------------------------------------------------------------------------- + // Perform Datapath power optimization + //------------------------------------------------------------------------- + bool OpticalGraph::performPowerOpt(OpticalNode* node_, const WavelengthGroup& wavelengths_, unsigned int number_detectors_, double util_) + { + // Total number of iterations + unsigned int number_iterations = 1250; + // Maximum IL + ER + double IL_ER_max = 10; + // Figure out the step size used in the sweep + double step = (double) (IL_ER_max / sqrt(2 * number_iterations)); + + // Assume it is possible + bool possible = true; + + // Begin optical data path power optimization + Log::printLine(getInstanceName() + " -> Beginning optical data path power optimization"); + + // Trace the specified wavelengths + OpticalWavelength* wavelength = traceWavelength(wavelengths_, node_); + + // For each data path found in the wavelength + const vector* data_paths = wavelength->getDataPaths(); + for (unsigned int i = 0; i < data_paths->size(); ++i) + { + const OpticalDataPath& data_path = data_paths->at(i); + // Default to worst possible modulator + double best_power = 1e99; + double best_IL = IL_ER_max - step; + double best_ER = step; + + // Perform power optimization for this data path + Log::printLine(getInstanceName() + " -> Optimize data path - Laser = " + data_path.laser->getInstanceName() + + ", Modulator = " + data_path.modulator->getInstanceName()); + + if (data_path.modulator->canOptimizeLoss()) + { + // Iterate over IL and ER to find optimal set of IL and ER + for (double IL = step; IL < IL_ER_max; IL += step) + { + for (double ER = step; ER <= (IL_ER_max - IL); ER += step) + { + // Ask the modulator to try this new ER and IL + bool success = data_path.modulator->setModulatorSpec(IL, ER); + // If the modulator was successful + if (success) + { + double laser_power = wavelength->getLaserPower(number_detectors_); + double modulator_power = data_path.modulator->getPower(util_); + double total_power = laser_power + modulator_power; + // If this is the new lowest power point + if (total_power < best_power) + { + best_power = total_power; + best_IL = IL; + best_ER = ER; + } + } + } + } + + // Set IL and ER to the best ones we found + bool success = data_path.modulator->setModulatorSpec(best_IL, best_ER); + // If the best one we found was still not possible... + possible = possible && success; + + // Print best IL and ER + Log::printLine(getInstanceName() + " -> Best IL=" + (String) best_IL + ", Best ER=" + (String) best_ER + + ", Best Laser/Mod Power=" + (String) best_power); + } + else + { + // Perform power optimization for this data path + Log::printLine(getInstanceName() + " -> Data path not set to allow optimization"); + } + } + + // End optical data path power optimization + Log::printLine(getInstanceName() + " -> End optical data path power optimization"); + + delete wavelength; + return possible; + } + + + //------------------------------------------------------------------------- + // Trace wavelength(s), returning a wavelength data structure + //------------------------------------------------------------------------- + OpticalWavelength* OpticalGraph::traceWavelength(const WavelengthGroup& wavelengths_, OpticalNode* node_) + { + setTreeNum(getTreeNum() + 1); + OpticalWavelength* wavelength = new OpticalWavelength("TraceWavelength", wavelengths_); + return traceWavelength(wavelength, node_, NULL, NULL, 0.0); + } + + OpticalWavelength* OpticalGraph::traceWavelength(OpticalWavelength* wavelength_, OpticalNode* node_, OpticalLaser* laser_, OpticalModulator* modulator_, double loss_) + { + // If the node has already been visited, don't do anything! + if (node_->getVisitedNum() != getTreeNum()) + { + // Set the new parity for this node + node_->setVisitedNum(getTreeNum()); + + // Calculate the loss of the current path + double current_loss = loss_ + node_->getLoss(); + // Check if the current node is a laser, modulator or detector + if(node_->getType() == OpticalNode::LASER) + { + // Set the laser lighting up the wavelength + ASSERT(laser_ == NULL, "[Error] " + getInstanceName() + " -> Multiple " + + "Lasers lighting up the wavelength!"); + laser_ = (OpticalLaser*) node_; + } + else if (node_->getType() == OpticalNode::MODULATOR) + { + // Check that the path already lit up by a laser and there are no + // modulators already driving data + ASSERT(laser_ != NULL, "[Error] " + getInstanceName() + " -> Wavelength reaches a " + + "modulator (" + node_->getInstanceName() + ") prior to being lit up by a laser!"); + ASSERT(modulator_ == NULL, "[Error] " + getInstanceName() + " -> Two modulators are driving" + + " the same optical data path (" + node_->getInstanceName() + ")!"); + modulator_ = (OpticalModulator*) node_; + } + else if (node_->getType() == OpticalNode::DETECTOR) + { + // Check that the path is both lit up by a laser and there is + // a modulator driving data + ASSERT(laser_ != NULL, "[Error] " + getInstanceName() + " -> Wavelength reaches a " + + "detector (" + node_->getInstanceName() + ") prior to being lit up by a laser!"); + ASSERT(modulator_ != NULL, "[Error] " + getInstanceName() + " -> Wavelength reaches a " + + "detector (" + node_->getInstanceName() + ") prior to being driven by a modulator!"); + // Add a detector to the wavelength + wavelength_->addDataPath(laser_, modulator_, (OpticalDetector*) node_, current_loss); + } + + // Traverse downstream nodes to calculate the delay through each downstream path + vector* d_nodes = node_->getDownstreamNodes(); + bool trace_downstream = (node_->getType() != OpticalNode::DETECTOR); + // Do special things when traversing filters + if (node_->getType() == OpticalNode::FILTER) + { + OpticalFilter* filter_node = (OpticalFilter*) node_; + if (filter_node->isDropped(wavelength_->getWavelengths())) + traceWavelength(wavelength_, filter_node->getDropPort(), laser_, modulator_, loss_ + filter_node->getDropLoss()); + + // If the filter is not modeled as a complete drop, continue tracing downstream + trace_downstream = !filter_node->getDropAll(); + } + + if (trace_downstream) + { + // Trace downstream nodes + for (unsigned int i = 0; i < d_nodes->size(); ++i) + traceWavelength(wavelength_, d_nodes->at(i), laser_, modulator_, current_loss); + } + } + return wavelength_; + } + + //------------------------------------------------------------------------- + OpticalGraph::OpticalGraph(const OpticalGraph& /* graph_ */) + { + // Disabled + } + + OpticalModel* OpticalGraph::getModel() + { + return m_model_; + } + + void OpticalGraph::setTreeNum(int tree_num_) + { + msTreeNum = tree_num_; + return; + } + + int OpticalGraph::getTreeNum() + { + return msTreeNum; + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalLaser.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalLaser.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_OPTICALGRAPH_OPTICALLASER_H__ +#define __DSENT_MODEL_OPTICALGRAPH_OPTICALLASER_H__ + +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalNode.hh" +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" + +namespace DSENT +{ + class OpticalLaser : public OpticalNode + { + public: + OpticalLaser(const String& instance_name_, OpticalModel* model_, const WavelengthGroup& wavelengths_); + ~OpticalLaser(); + + public: + void setEfficiency(double efficiency_); + double getEfficiency() const; + + private: + // Disable copy constructor + OpticalLaser(const OpticalLaser& node_); + + private: + // Laser efficiency + double m_efficiency_; + + }; + +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICALGRAPH_OPTICALLASER_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalLaser.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalLaser.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + + +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalLaser.hh" + +namespace DSENT +{ + OpticalLaser::OpticalLaser(const String& instance_name_, OpticalModel* model_, const WavelengthGroup& wavelengths_) + : OpticalNode(OpticalNode::LASER, instance_name_, model_, wavelengths_), m_efficiency_(0) + { + + } + + void OpticalLaser::setEfficiency(double efficiency_) + { + m_efficiency_ = efficiency_; + return; + } + + double OpticalLaser::getEfficiency() const + { + return m_efficiency_; + } + + OpticalLaser::~OpticalLaser() + { + + } + + +} // namespace DSENT + + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalModulator.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalModulator.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_OPTICALGRAPH_OPTICALMODULATOR_H__ +#define __DSENT_MODEL_OPTICALGRAPH_OPTICALMODULATOR_H__ + +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalNode.hh" +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" + +namespace DSENT +{ + class OpticalTransmitter; + + class OpticalModulator : public OpticalNode + { + public: + OpticalModulator(const String& instance_name_, OpticalModel* model_, const WavelengthGroup& wavelengths_, bool opt_loss_, OpticalTransmitter* transmitter_); + ~OpticalModulator(); + + public: + // Set losses + void setLosses(double IL_dB_, double ER_dB_); + // Tell the modulator to set a new insertion loss and extinction ratio + bool setModulatorSpec(double IL_dB_, double ER_dB_); + // Get modulator insertion loss + double getInsertionLoss() const; + // Get modulator extinction ratio + double getExtinctionRatio() const; + // Ask whether the model is able to optimize for insertion loss + // and extinction ratios + bool canOptimizeLoss() const; + // Ask the modulator for its power at a given utilization + double getPower(double util_) const; + + private: + // Disable copy constructor + OpticalModulator(const OpticalModulator& node_); + + private: + // Optical sender of the modulator + OpticalTransmitter* m_transmitter_; + // Insertion loss of the modulator + double m_insertion_loss_; + // Extinction ratio of the modulator + double m_extinction_ratio_; + // Whether the modulator can be optimized + bool m_opt_loss_; + + }; + +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICALGRAPH_OPTICALMODULATOR_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalModulator.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalModulator.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + + +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalModulator.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalTransmitter.hh" + +namespace DSENT +{ + OpticalModulator::OpticalModulator(const String& instance_name_, OpticalModel* model_, const WavelengthGroup& wavelengths_, bool opt_loss_, OpticalTransmitter* transmitter_) + : OpticalNode(OpticalNode::MODULATOR, instance_name_, model_, wavelengths_), m_transmitter_(transmitter_), m_insertion_loss_(0), m_extinction_ratio_(0), m_opt_loss_(opt_loss_) + { + + } + + OpticalModulator::~OpticalModulator() + { + + } + + bool OpticalModulator::canOptimizeLoss() const + { + return m_opt_loss_; + } + + void OpticalModulator::setLosses(double IL_dB_, double ER_dB_) + { + m_insertion_loss_ = IL_dB_; + m_extinction_ratio_ = ER_dB_; + + return; + } + + bool OpticalModulator::setModulatorSpec(double IL_dB_, double ER_dB_) + { + // Ask the transmitter to design to those specs, returns success or fail + return m_transmitter_->setTransmitterSpec(IL_dB_, ER_dB_); + } + + double OpticalModulator::getPower(double util_) const + { + return m_transmitter_->getPower(util_); + } + + double OpticalModulator::getInsertionLoss() const + { + return m_insertion_loss_; + } + + double OpticalModulator::getExtinctionRatio() const + { + return m_extinction_ratio_; + } + +} // namespace DSENT + + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalNode.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalNode.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_OPTICALGRAPH_OPTICALNODE_H__ +#define __DSENT_MODEL_OPTICALGRAPH_OPTICALNODE_H__ + +#include "mem/ruby/network/dsent/dsent-core/model/OpticalModel.hh" +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" + +namespace DSENT +{ + class OpticalNode; + + //TODO: Change to detector + typedef std::pair DetectorEntry; + typedef std::vector DetectorTable; + + class OpticalNode + { + public: + // The starting visited number flag of all optical nodes + static const int OPTICAL_NODE_INIT_VISITED_NUM; + + // The types of optical nodes that can exist + enum Type + { + WAVEGUIDE, + LASER, + MODULATOR, + FILTER, + DETECTOR + }; + + public: + OpticalNode(Type type_, const String& instance_name_, OpticalModel* model_, const WavelengthGroup& wavelengths_); + ~OpticalNode(); + + public: + // Get the type of optical node + Type getType() const; + // Return instance name + const String& getInstanceName() const; + // Get the downstream optical nodes + vector* getDownstreamNodes() const; + // Connect the downstream optical node + void addDownstreamNode(OpticalNode* node_); + // Return the node's parent model + OpticalModel* getModel(); + const OpticalModel* getModel() const; + // Get wavelength groups + WavelengthGroup getWavelengths() const; + // Returns whether the node is expecting a set of wavelengths + bool isExpected(const WavelengthGroup& wavelengths_) const; + + // Trace wavelengths, find and put all found lasers, modulators, and detectors + //virtual void traceWavelengths(const WavelengthGroup& wavelengths_, OpticalNode* laser_, + // OpticalNode* modulator_, DetectorTable* detectors_, double current_loss_) const; + + //----------------------------------------------------------------- + // Node variables for wavelength tracing + //----------------------------------------------------------------- + // Loss incurred at this optical node + void setLoss(double loss_); + double getLoss() const; + // Visited number marker + void setVisitedNum(int visited_num_); + int getVisitedNum() const; + //----------------------------------------------------------------- + + + private: + // Disable copy constructor + OpticalNode(const OpticalNode& node_); + + private: + // The type of optical node + const Type m_type_; + // Name of this instance + String m_instance_name_; + // A pointer to the model that contains this node + OpticalModel* m_model_; + // Downstream optical node + vector* m_downstream_nodes_; + // Path visited count (so that you don't have to clear it) + int m_visited_num_; + // The amount of loss incurred at this optical node + double m_loss_; + // The wavelengths this optical node is supposed to see + const WavelengthGroup m_wavelengths_; + }; + +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICALGRAPH_OPTICALNODE_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalNode.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalNode.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + + +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalNode.hh" + +namespace DSENT +{ + // Set the optical node initial visited num + const int OpticalNode::OPTICAL_NODE_INIT_VISITED_NUM = 0; + + OpticalNode::OpticalNode(Type type_, const String& instance_name_, OpticalModel* model_, const WavelengthGroup& wavelengths_) + :m_type_(type_), m_instance_name_(instance_name_), m_model_(model_), m_wavelengths_(wavelengths_) + { + m_loss_ = 0.0; + setVisitedNum(OpticalNode::OPTICAL_NODE_INIT_VISITED_NUM); + m_downstream_nodes_ = new vector; + } + + OpticalNode::~OpticalNode() + { + + } + + OpticalNode::Type OpticalNode::getType() const + { + return m_type_; + } + + vector* OpticalNode::getDownstreamNodes() const + { + return m_downstream_nodes_; + } + + const String& OpticalNode::getInstanceName() const + { + return m_instance_name_; + } + + OpticalModel* OpticalNode::getModel() + { + return m_model_; + } + + const OpticalModel* OpticalNode::getModel() const + { + return (const OpticalModel*) m_model_; + } + + void OpticalNode::addDownstreamNode(OpticalNode* node_) + { + ASSERT(node_->isExpected(getWavelengths()), "[Error] " + getInstanceName() + + " -> Downstream node not expecting a superset of the current wavelengths"); + m_downstream_nodes_->push_back(node_); + } + + WavelengthGroup OpticalNode::getWavelengths() const + { + return m_wavelengths_; + } + + bool OpticalNode::isExpected(const WavelengthGroup& wavelengths_) const + { + // Check that the lower limits are within bounds + bool lower_match = (wavelengths_.first >= getWavelengths().first); + // Check that the upper limits are within bounds + bool upper_match = (wavelengths_.second <= getWavelengths().second); + // Assert that there are no misalignments + ASSERT(lower_match == upper_match, "[Error] " + getInstanceName() + + " -> Wavelength group misalignment!"); + // Both upper and lower bounds must match + return (upper_match && lower_match); + } + + //------------------------------------------------------------------------- + void OpticalNode::setLoss(double loss_) + { + m_loss_ = loss_; + } + + double OpticalNode::getLoss() const + { + return m_loss_; + } + + void OpticalNode::setVisitedNum(int visited_num_) + { + m_visited_num_ = visited_num_; + } + + int OpticalNode::getVisitedNum() const + { + return m_visited_num_; + } + //------------------------------------------------------------------------- + +} // namespace DSENT + + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalReceiver.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalReceiver.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_OPTICALGRAPH_OPTICALRECEIVER_H__ +#define __DSENT_MODEL_OPTICALGRAPH_OPTICALRECEIVER_H__ + +#include "mem/ruby/network/dsent/dsent-core/model/OpticalModel.hh" +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" + +namespace DSENT +{ + // The job of an optical receiver interface is to provide a function to + // return a sensitivity (in Amps) + class OpticalReceiver + { + public: + OpticalReceiver(){}; + virtual ~OpticalReceiver(){}; + + public: + // Returns the sensitivity of the receiver given an extinction ratio + virtual double getSensitivity(double ER_dB_) const = 0; + }; + +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICALGRAPH_OPTICALRECEIVER_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalTransmitter.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalTransmitter.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_OPTICALGRAPH_OPTICALTRANSMITTER_H__ +#define __DSENT_MODEL_OPTICALGRAPH_OPTICALTRANSMITTER_H__ + +#include "mem/ruby/network/dsent/dsent-core/model/OpticalModel.hh" +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" + +namespace DSENT +{ + // The job of a optical sender interface is to provide a function to + // allow the insertion loss and extinction ratio to be changed + class OpticalTransmitter + { + public: + OpticalTransmitter(){}; + virtual ~OpticalTransmitter(){}; + + public: + // Set the transmitter specifications, returns whether it is possible + // to build a modulator that met those specs + virtual bool setTransmitterSpec(double IL_dB_, double ER_dB_) = 0; + // Returns power of the transmitter at a given utilization + virtual double getPower(double util_) const = 0; + }; // class OpticalTransmitter + +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICALGRAPH_OPTICALTRANSMITTER_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalWaveguide.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalWaveguide.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_OPTICALGRAPH_OPTICALWAVEGUIDE_H__ +#define __DSENT_MODEL_OPTICALGRAPH_OPTICALWAVEGUIDE_H__ + +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalNode.hh" +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" + +namespace DSENT +{ + class OpticalWaveguide : public OpticalNode + { + public: + OpticalWaveguide(const String& instance_name_, OpticalModel* model_, const WavelengthGroup& wavelengths_); + ~OpticalWaveguide(); + + public: + // Nothing here... + + private: + // Disable copy constructor + OpticalWaveguide(const OpticalWaveguide& node_); + + }; + +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICALGRAPH_OPTICALWAVEGUIDE_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalWaveguide.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalWaveguide.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + + +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalWaveguide.hh" + +namespace DSENT +{ + OpticalWaveguide::OpticalWaveguide(const String& instance_name_, OpticalModel* model_, const WavelengthGroup& wavelengths_) + : OpticalNode(OpticalNode::WAVEGUIDE, instance_name_, model_, wavelengths_) + { + + } + + OpticalWaveguide::~OpticalWaveguide() + { + + } + + +} // namespace DSENT + + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalWavelength.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalWavelength.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_OPTICALGRAPH_OPTICALWAVELENGTH_H__ +#define __DSENT_MODEL_OPTICALGRAPH_OPTICALWAVELENGTH_H__ + +#include "mem/ruby/network/dsent/dsent-core/model/OpticalModel.hh" +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" + +namespace DSENT +{ + // Optical datapath structure storing a detector table consisting of a + // detector, the loss to that detector, and the modulator driving + // the wavelength for that detector + struct OpticalDataPath + { + OpticalLaser* laser; + OpticalModulator* modulator; + vector detectors; + vector losses; + + OpticalDataPath(OpticalLaser* laser_, OpticalModulator* modulator_, OpticalDetector* detector_, double loss_) + : laser(laser_), modulator(modulator_), detectors(1, detector_), losses(1, loss_) {} + }; + + class OpticalWavelength + { + // A data structure of a wavelength (or a group of wavelengths). This + // keeps track of all lasers sources, modulators, and detectors that + // the wavelength hits. + public: + OpticalWavelength(const String& instance_name_, const WavelengthGroup& wavelengths_); + ~OpticalWavelength(); + + public: + // Get tree name + const String& getInstanceName() const; + // Get wavelength groups + WavelengthGroup getWavelengths() const; + // Add a datapath for this wavelength + void addDataPath(OpticalLaser* laser_, OpticalModulator* modulator_, OpticalDetector* detector_, double loss_); + const vector* getDataPaths() const; + // Calculate required wavelength power to reach some number of detectors + // If number_detectors < the number of total detectors this wavelength hits then + // it simply returns the laser power required to reach the worst-case detectors + double getLaserPower(unsigned int number_detectors_) const; + + private: + // Name of the wavelength + const String m_instance_name_; + // Keeps track of the wavelengths + const WavelengthGroup m_wavelengths_; + // Keeps track of a table of laser, detector, modulator mappings + vector* m_data_paths_; + }; + +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICALGRAPH_OPTICALWAVEGUIDE_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalWavelength.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalWavelength.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + + +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalWavelength.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalNode.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalLaser.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalModulator.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalFilter.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalDetector.hh" +#include "mem/ruby/network/dsent/dsent-core/model/optical_graph/OpticalWavelength.hh" +#include +#include + +namespace DSENT +{ + using std::list; + using std::min; + + OpticalWavelength::OpticalWavelength(const String& instance_name_, const WavelengthGroup& wavelengths_) + : m_instance_name_(instance_name_), m_wavelengths_(wavelengths_) + { + m_data_paths_ = new vector; + } + + OpticalWavelength::~OpticalWavelength() + { + delete m_data_paths_; + } + + const String& OpticalWavelength::getInstanceName() const + { + return m_instance_name_; + } + + void OpticalWavelength::addDataPath(OpticalLaser* laser_, OpticalModulator* modulator_, OpticalDetector* detector_, double loss_) + { + // Expected wavelengths check + ASSERT(laser_->isExpected(getWavelengths()), "[Error] " + getInstanceName() + + " -> " + laser_->getInstanceName() + " is not expecting the set wavelengths!"); + ASSERT(modulator_->isExpected(getWavelengths()), "[Error] " + getInstanceName() + + " -> " + modulator_->getInstanceName() + " is not expecting the set wavelengths!"); + ASSERT(detector_->isExpected(getWavelengths()), "[Error] " + getInstanceName() + + " -> " + detector_->getInstanceName() + " is not expecting the set wavelengths!"); + + // Check to see if the modulator and laser already have a data path entry + bool entry_exists = false; + for (unsigned int i = 0; i < m_data_paths_->size(); ++i) + { + OpticalDataPath& current = m_data_paths_->at(i); + bool current_laser = current.laser == laser_; + bool current_modulator = current.modulator == modulator_; + + ASSERT((current_modulator && current_laser) || !current_modulator, "[Error] " + + getInstanceName() + " -> Modulator is the same, but laser is different?"); + + // If it is already in the table + if (current_modulator) + { + entry_exists = true; + current.detectors.push_back(detector_); + current.losses.push_back(loss_); + } + } + + // If it wasn't found, add the entry + if (!entry_exists) + m_data_paths_->push_back(OpticalDataPath(laser_, modulator_, detector_, loss_)); + return; + } + + const vector* OpticalWavelength::getDataPaths() const + { + return (const vector*) m_data_paths_; + } + + WavelengthGroup OpticalWavelength::getWavelengths() const + { + return m_wavelengths_; + } + + double OpticalWavelength::getLaserPower(unsigned int number_detectors_) const + { + ASSERT(number_detectors_ > 0, "[Error] " + getInstanceName() + + " -> Number of detectors must be non-zero!"); + // Find the number of actual wavelengths + int number_wavelengths = getWavelengths().second - getWavelengths().first + 1; + // Laser power sum + double laser_power_sum = 0; + // Loop through all data paths + for (unsigned int i = 0; i < getDataPaths()->size(); ++i) + { + // Get the current data_path + const OpticalDataPath& current_path = getDataPaths()->at(i); + // Create data structure holding the worstcase detectors + list* detectors = new list(); + // Get the extinction ratio of the modulator + double ER_dB = current_path.modulator->getExtinctionRatio(); + // Get the insertion loss of the modulator + double IR_dB = current_path.modulator->getInsertionLoss(); + // Walk through all detectors in a data path + for (unsigned int j = 0; j < current_path.detectors.size(); ++j) + { + // Convert sensitivity, extinction ratio, and path loss to a required laser power + double current_laser_power = current_path.detectors[j]->getSensitivity(ER_dB) * + std::pow(10.0, (current_path.losses[j] + IR_dB) / 10.0) * + 1.0 / (1.0 - pow(10, -ER_dB / 10)); + + // Add the laser power + detectors->push_back(current_laser_power); + } + // Cap the number of detectors + number_detectors_ = std::min(number_detectors_, (unsigned int) current_path.detectors.size()); + // Sort the detectors list in ascending order, only necessary if the number + // of detectors is < total number of detectors + if (number_detectors_ < detectors->size()) + detectors->sort(); + // Sum up the laser power from the worst-case detectors + list::reverse_iterator iter = detectors->rbegin(); + for (unsigned int j = 0; j < number_detectors_; ++j) + { + laser_power_sum += (*iter) / current_path.laser->getEfficiency(); + ++iter; + } + delete detectors; + } + return number_wavelengths * laser_power_sum; + } + +} // namespace DSENT + + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/optical_graph/SConscript --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/optical_graph/SConscript Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,41 @@ +# 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. +# +# Authors: Chia-Hsin Owen Chen + +Import('*') + +if env['PROTOCOL'] == 'None': + Return() + +Source('OpticalWaveguide.cc') +Source('OpticalFilter.cc') +Source('OpticalNode.cc') +Source('OpticalGraph.cc') +Source('OpticalWavelength.cc') +Source('OpticalLaser.cc') +Source('OpticalModulator.cc') +Source('OpticalDetector.cc') + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/ADDF.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/ADDF.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_STD_CELLS_ADDF_H__ +#define __DSENT_MODEL_STD_CELLS_ADDF_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" + +namespace DSENT +{ + // A full adder standard cell + class ADDF : public StdCell + { + public: + ADDF(const String& instance_name_, const TechModel* tech_model_); + virtual ~ADDF(); + + public: + // Set a list of properties needed to update model + void initProperties(); + // Cache the standard cell + void cacheStdCell(StdCellLib* cell_lib_, double drive_strength_); + private: + TransitionInfo m_trans_P_; + TransitionInfo m_trans_G_; + TransitionInfo m_trans_CP_; + + protected: + // Build the model + virtual void constructModel(); + virtual void updateModel(); + virtual void evaluateModel(); + virtual void useModel(); + virtual void propagateTransitionInfo(); + + }; // class ADDF +} // namespace DSENT + +#endif // __DSENT_MODEL_STD_CELLS_ADDF_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/ADDF.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/ADDF.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,702 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/ADDF.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/CellMacros.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriver.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalLoad.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDelay.hh" + +namespace DSENT +{ + using std::ceil; + using std::max; + + ADDF::ADDF(const String& instance_name_, const TechModel* tech_model_) + : StdCell(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + ADDF::~ADDF() + {} + + void ADDF::initProperties() + { + return; + } + + void ADDF::constructModel() + { + // All constructModel should do is create Area/NDDPower/Energy Results as + // well as instantiate any sub-instances using only the hard parameters + + createInputPort("A"); + createInputPort("B"); + createInputPort("CI"); + createOutputPort("S"); + createOutputPort("CO"); + + createLoad("A_Cap"); + createLoad("B_Cap"); + createLoad("CI_Cap"); + createDelay("A_to_S_delay"); + createDelay("B_to_S_delay"); + createDelay("CI_to_S_delay"); + createDelay("A_to_CO_delay"); + createDelay("B_to_CO_delay"); + createDelay("CI_to_CO_delay"); + createDriver("S_Ron", true); + createDriver("CO_Ron", true); + + ElectricalLoad* a_cap = getLoad("A_Cap"); + ElectricalLoad* b_cap = getLoad("B_Cap"); + ElectricalLoad* ci_cap = getLoad("CI_Cap"); + ElectricalDelay* a_to_s_delay = getDelay("A_to_S_delay"); + ElectricalDelay* b_to_s_delay = getDelay("B_to_S_delay"); + ElectricalDelay* ci_to_s_delay = getDelay("CI_to_S_delay"); + ElectricalDelay* a_to_co_delay = getDelay("A_to_CO_delay"); + ElectricalDelay* b_to_co_delay = getDelay("B_to_CO_delay"); + ElectricalDelay* ci_to_co_delay = getDelay("CI_to_CO_delay"); + ElectricalDriver* s_ron = getDriver("S_Ron"); + ElectricalDriver* co_ron = getDriver("CO_Ron"); + + getNet("A")->addDownstreamNode(a_cap); + getNet("B")->addDownstreamNode(b_cap); + getNet("CI")->addDownstreamNode(ci_cap); + a_cap->addDownstreamNode(a_to_s_delay); + b_cap->addDownstreamNode(b_to_s_delay); + ci_cap->addDownstreamNode(ci_to_s_delay); + a_cap->addDownstreamNode(a_to_co_delay); + b_cap->addDownstreamNode(b_to_co_delay); + ci_cap->addDownstreamNode(ci_to_co_delay); + + a_to_s_delay->addDownstreamNode(s_ron); + b_to_s_delay->addDownstreamNode(s_ron); + ci_to_s_delay->addDownstreamNode(s_ron); + a_to_co_delay->addDownstreamNode(co_ron); + b_to_co_delay->addDownstreamNode(co_ron); + ci_to_co_delay->addDownstreamNode(co_ron); + + s_ron->addDownstreamNode(getNet("S")); + co_ron->addDownstreamNode(getNet("CO")); + + // Create Area result + // Create NDD Power result + createElectricalAtomicResults(); + // Create ADDF Event Energy Result + createElectricalEventAtomicResult("ADDF"); + + getEventInfo("Idle")->setStaticTransitionInfos(); + + return; + } + + void ADDF::updateModel() + { + // Get parameters + double drive_strength = getDrivingStrength(); + Map* cache = getTechModel()->getStdCellLib()->getStdCellCache(); + + // Standard cell cache string + String cell_name = "ADDF_X" + (String) drive_strength; + + // Get timing parameters + getLoad("A_Cap")->setLoadCap(cache->get(cell_name + "->Cap->A")); + getLoad("B_Cap")->setLoadCap(cache->get(cell_name + "->Cap->B")); + getLoad("CI_Cap")->setLoadCap(cache->get(cell_name + "->Cap->CI")); + + getDelay("A_to_S_delay")->setDelay(cache->get(cell_name + "->Delay->A_to_S")); + getDelay("B_to_S_delay")->setDelay(cache->get(cell_name + "->Delay->B_to_S")); + getDelay("CI_to_S_delay")->setDelay(cache->get(cell_name + "->Delay->CI_to_S")); + getDelay("A_to_CO_delay")->setDelay(cache->get(cell_name + "->Delay->A_to_CO")); + getDelay("B_to_CO_delay")->setDelay(cache->get(cell_name + "->Delay->B_to_CO")); + getDelay("CI_to_CO_delay")->setDelay(cache->get(cell_name + "->Delay->CI_to_CO")); + + getDriver("S_Ron")->setOutputRes(cache->get(cell_name + "->DriveRes->S")); + getDriver("CO_Ron")->setOutputRes(cache->get(cell_name + "->DriveRes->CO")); + + // Set the cell area + getAreaResult("Active")->setValue(cache->get(cell_name + "->Area->Active")); + getAreaResult("Metal1Wire")->setValue(cache->get(cell_name + "->Area->Metal1Wire")); + + return; + } + + void ADDF::evaluateModel() + { + return; + } + + void ADDF::useModel() + { + // Get parameters + double drive_strength = getDrivingStrength(); + Map* cache = getTechModel()->getStdCellLib()->getStdCellCache(); + + // Standard cell cache string + String cell_name = "ADDF_X" + (String) drive_strength; + + // Propagate the transition info and get the 0->1 transition count + propagateTransitionInfo(); + double P_A = getInputPort("A")->getTransitionInfo().getProbability1(); + double P_B = getInputPort("B")->getTransitionInfo().getProbability1(); + double P_CI = getInputPort("CI")->getTransitionInfo().getProbability1(); + double A_num_trans_01 = getInputPort("A")->getTransitionInfo().getNumberTransitions01(); + double B_num_trans_01 = getInputPort("B")->getTransitionInfo().getNumberTransitions01(); + double CI_num_trans_01 = getInputPort("CI")->getTransitionInfo().getNumberTransitions01(); + double P_num_trans_01 = m_trans_P_.getNumberTransitions01(); + double G_num_trans_01 = m_trans_G_.getNumberTransitions01(); + double CP_num_trans_01 = m_trans_CP_.getNumberTransitions01(); + double S_num_trans_01 = getOutputPort("S")->getTransitionInfo().getNumberTransitions01(); + double CO_num_trans_01 = getOutputPort("CO")->getTransitionInfo().getNumberTransitions01(); + + // Calculate leakage + double leakage = 0; + leakage += cache->get(cell_name + "->Leakage->!A!B!CI") * (1 - P_A) * (1 - P_B) * (1 - P_CI); + leakage += cache->get(cell_name + "->Leakage->!A!BCI") * (1 - P_A) * (1 - P_B) * P_CI; + leakage += cache->get(cell_name + "->Leakage->!AB!CI") * (1 - P_A) * P_B * (1 - P_CI); + leakage += cache->get(cell_name + "->Leakage->!ABCI") * (1 - P_A) * P_B * P_CI; + leakage += cache->get(cell_name + "->Leakage->A!B!CI") * P_A * (1 - P_B) * (1 - P_CI); + leakage += cache->get(cell_name + "->Leakage->A!BCI") * P_A * (1 - P_B) * P_CI; + leakage += cache->get(cell_name + "->Leakage->AB!CI") * P_A * P_B * (1 - P_CI); + leakage += cache->get(cell_name + "->Leakage->ABCI") * P_A * P_B * P_CI; + getNddPowerResult("Leakage")->setValue(leakage); + + // Get VDD + double vdd = getTechModel()->get("Vdd"); + + // Get capacitances + double a_b_cap = cache->get(cell_name + "->Cap->A_b"); + double b_b_cap = cache->get(cell_name + "->Cap->B_b"); + double ci_b_cap = cache->get(cell_name + "->Cap->CI_b"); + double p_cap = cache->get(cell_name + "->Cap->P"); + double p_b_cap = cache->get(cell_name + "->Cap->P_b"); + double s_cap = cache->get(cell_name + "->Cap->S"); + double cp_cap = cache->get(cell_name + "->Cap->CP"); + double g_cap = cache->get(cell_name + "->Cap->G"); + double co_cap = cache->get(cell_name + "->Cap->CO"); + double s_load_cap = getNet("S")->getTotalDownstreamCap(); + double co_load_cap = getNet("CO")->getTotalDownstreamCap(); + + // Calculate ADDF Event energy + double addf_event_energy = 0.0; + addf_event_energy += a_b_cap * A_num_trans_01; + addf_event_energy += b_b_cap * B_num_trans_01; + addf_event_energy += ci_b_cap * CI_num_trans_01; + addf_event_energy += (p_cap + p_b_cap) * P_num_trans_01; + addf_event_energy += (s_cap + s_load_cap) * S_num_trans_01; + addf_event_energy += cp_cap * CP_num_trans_01; + addf_event_energy += g_cap * G_num_trans_01; + addf_event_energy += (co_cap + co_load_cap) * CO_num_trans_01; + addf_event_energy *= vdd * vdd; + getEventResult("ADDF")->setValue(addf_event_energy); + + return; + } + + void ADDF::propagateTransitionInfo() + { + const TransitionInfo& trans_A = getInputPort("A")->getTransitionInfo(); + const TransitionInfo& trans_B = getInputPort("B")->getTransitionInfo(); + const TransitionInfo& trans_CI = getInputPort("CI")->getTransitionInfo(); + + double max_freq_mult = max(max(trans_A.getFrequencyMultiplier(), trans_B.getFrequencyMultiplier()), trans_CI.getFrequencyMultiplier()); + const TransitionInfo& scaled_trans_A = trans_A.scaleFrequencyMultiplier(max_freq_mult); + const TransitionInfo& scaled_trans_B = trans_B.scaleFrequencyMultiplier(max_freq_mult); + const TransitionInfo& scaled_trans_CI = trans_CI.scaleFrequencyMultiplier(max_freq_mult); + + double A_prob_00 = scaled_trans_A.getNumberTransitions00() / max_freq_mult; + double A_prob_01 = scaled_trans_A.getNumberTransitions01() / max_freq_mult; + double A_prob_10 = A_prob_01; + double A_prob_11 = scaled_trans_A.getNumberTransitions11() / max_freq_mult; + double B_prob_00 = scaled_trans_B.getNumberTransitions00() / max_freq_mult; + double B_prob_01 = scaled_trans_B.getNumberTransitions01() / max_freq_mult; + double B_prob_10 = B_prob_01; + double B_prob_11 = scaled_trans_B.getNumberTransitions11() / max_freq_mult; + double CI_prob_00 = scaled_trans_CI.getNumberTransitions00() / max_freq_mult; + double CI_prob_01 = scaled_trans_CI.getNumberTransitions01() / max_freq_mult; + double CI_prob_10 = CI_prob_01; + double CI_prob_11 = scaled_trans_CI.getNumberTransitions11() / max_freq_mult; + + // Set P transition info + double P_prob_00 = A_prob_00 * B_prob_00 + + A_prob_01 * B_prob_01 + + A_prob_10 * B_prob_10 + + A_prob_11 * B_prob_11; + double P_prob_01 = A_prob_00 * B_prob_01 + + A_prob_01 * B_prob_00 + + A_prob_10 * B_prob_11 + + A_prob_11 * B_prob_10; + double P_prob_10 = P_prob_01; + double P_prob_11 = A_prob_00 * B_prob_11 + + A_prob_01 * B_prob_10 + + A_prob_10 * B_prob_01 + + A_prob_11 * B_prob_00; + + // Set G transition info + double G_prob_00 = A_prob_11 * B_prob_11; + double G_prob_01 = A_prob_11 * B_prob_10 + + A_prob_10 * (B_prob_11 + B_prob_10); + double G_prob_10 = G_prob_01; + double G_prob_11 = A_prob_00 + + A_prob_01 * (B_prob_00 + B_prob_10) + + A_prob_10 * (B_prob_00 + B_prob_01) + + A_prob_11 * B_prob_00; + + // Set CP transition info + double CP_prob_00 = P_prob_11 * CI_prob_11; + double CP_prob_01 = P_prob_11 * CI_prob_10 + + P_prob_10 * (CI_prob_11 + CI_prob_10); + double CP_prob_10 = CP_prob_01; + double CP_prob_11 = P_prob_00 + + P_prob_01 * (CI_prob_00 + CI_prob_10) + + P_prob_10 * (CI_prob_00 + CI_prob_01) + + P_prob_11 * CI_prob_00; + + // Set S transition info + double S_prob_00 = P_prob_00 * CI_prob_00 + + P_prob_01 * CI_prob_01 + + P_prob_10 * CI_prob_10 + + P_prob_11 * CI_prob_11; + double S_prob_01 = P_prob_00 * CI_prob_01 + + P_prob_01 * CI_prob_00 + + P_prob_10 * CI_prob_11 + + P_prob_11 * CI_prob_10; + double S_prob_11 = P_prob_00 * CI_prob_11 + + P_prob_01 * CI_prob_10 + + P_prob_10 * CI_prob_01 + + P_prob_11 * CI_prob_00; + + // Set CO transition info + double CO_prob_00 = G_prob_11 * CP_prob_11; + double CO_prob_01 = G_prob_11 * CP_prob_10 + + G_prob_10 * (CP_prob_11 + CP_prob_10); + double CO_prob_11 = G_prob_00 + + G_prob_01 * (CP_prob_00 + CP_prob_10) + + G_prob_10 * (CP_prob_00 + CP_prob_01) + + G_prob_11 * CP_prob_00; + + m_trans_P_ = TransitionInfo(P_prob_00 * max_freq_mult, P_prob_01 * max_freq_mult, P_prob_11 * max_freq_mult); + m_trans_G_ = TransitionInfo(G_prob_00 * max_freq_mult, G_prob_01 * max_freq_mult, G_prob_11 * max_freq_mult); + m_trans_CP_ = TransitionInfo(CP_prob_00 * max_freq_mult, CP_prob_01 * max_freq_mult, CP_prob_11 * max_freq_mult); + + // Check that probabilities add up to 1.0 with some finite tolerance + ASSERT(LibUtil::Math::isEqual((S_prob_00 + S_prob_01 + S_prob_01 + S_prob_11), 1.0), + "[Error] " + getInstanceName() + "Output S transition probabilities must add up to 1 (" + + (String) S_prob_00 + ", " + (String) S_prob_01 + ", " + (String) S_prob_11 + ")!"); + + // Check that probabilities add up to 1.0 with some finite tolerance + ASSERT(LibUtil::Math::isEqual((CO_prob_00 + CO_prob_01 + CO_prob_01 + CO_prob_11), 1.0), + "[Error] " + getInstanceName() + "Output S transition probabilities must add up to 1 (" + + (String) CO_prob_00 + ", " + (String) CO_prob_01 + ", " + (String) CO_prob_11 + ")!"); + + // Turn probability of transitions per cycle into number of transitions per time unit + TransitionInfo trans_S(S_prob_00 * max_freq_mult, S_prob_01 * max_freq_mult, S_prob_11 * max_freq_mult); + getOutputPort("S")->setTransitionInfo(trans_S); + TransitionInfo trans_CO(CO_prob_00 * max_freq_mult, CO_prob_01 * max_freq_mult, CO_prob_11 * max_freq_mult); + getOutputPort("CO")->setTransitionInfo(trans_CO); + return; + } + + // Creates the standard cell, characterizes and abstracts away the details + void ADDF::cacheStdCell(StdCellLib* cell_lib_, double drive_strength_) + { + // Get parameters + double gate_pitch = cell_lib_->getTechModel()->get("Gate->PitchContacted"); + Map* cache = cell_lib_->getStdCellCache(); + + // Standard cell cache string + String cell_name = "ADDF_X" + (String) drive_strength_; + + Log::printLine("=== " + cell_name + " ==="); + + // Now actually build the full standard cell model + createInputPort("A"); + createInputPort("B"); + createInputPort("CI"); + createOutputPort("S"); + createOutputPort("CO"); + + createNet("A_b"); + createNet("B_b"); + createNet("CI_b"); + createNet("P"); + createNet("P_b"); + createNet("G"); //actually G_b since it is NAND'ed + createNet("CP"); //actually (CP)_b since it is NAND'ed + + // Adds macros + CellMacros::addInverter(this, "INV1", false, true, "A", "A_b"); + CellMacros::addInverter(this, "INV2", false, true, "B", "B_b"); + CellMacros::addInverter(this, "INV3", false, true, "CI", "CI_b"); + CellMacros::addInverter(this, "INV4", false, true, "P", "P_b"); + CellMacros::addTristate(this, "INVZ1", false, true, true, true, "B", "A", "A_b", "P"); + CellMacros::addTristate(this, "INVZ2", false, true, true, true, "B_b", "A_b", "A", "P"); + CellMacros::addTristate(this, "INVZ3", true, true, true, true, "P", "CI", "CI_b", "S"); + CellMacros::addTristate(this, "INVZ4", true, true, true, true, "P_b", "CI_b", "CI", "S"); + CellMacros::addNand2(this, "NAND1", false, true, true, "CI", "P", "CP"); + CellMacros::addNand2(this, "NAND2", false, true, true, "A", "B", "G"); + CellMacros::addNand2(this, "NAND3", true, true, true, "CP", "G", "CO"); + + // I have no idea how to size each of the parts haha + CellMacros::updateInverter(this, "INV1", drive_strength_ * 0.250); + CellMacros::updateInverter(this, "INV2", drive_strength_ * 0.250); + CellMacros::updateInverter(this, "INV3", drive_strength_ * 0.250); + CellMacros::updateInverter(this, "INV4", drive_strength_ * 0.500); + CellMacros::updateTristate(this, "INVZ1", drive_strength_ * 0.250); + CellMacros::updateTristate(this, "INVZ2", drive_strength_ * 0.250); + CellMacros::updateTristate(this, "INVZ3", drive_strength_ * 0.500); + CellMacros::updateTristate(this, "INVZ4", drive_strength_ * 0.500); + CellMacros::updateNand2(this, "NAND1", drive_strength_ * 0.500); + CellMacros::updateNand2(this, "NAND2", drive_strength_ * 0.500); + CellMacros::updateNand2(this, "NAND3", drive_strength_ * 1.000); + + // Cache area result + double area = 0.0; + area += gate_pitch * getTotalHeight() * 1; + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV1_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV2_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV3_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV4_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INVZ1_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INVZ2_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INVZ3_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INVZ4_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("NAND1_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("NAND2_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("NAND3_GatePitches").toDouble(); + cache->set(cell_name + "->Area->Active", area); + cache->set(cell_name + "->Area->Metal1Wire", area); + Log::printLine(cell_name + "->Area->Active=" + (String) area); + Log::printLine(cell_name + "->Area->Metal1Wire=" + (String) area); + + // -------------------------------------------------------------------- + // Leakage Model Calculation + // -------------------------------------------------------------------- + // Cache leakage power results (for every single signal combination) + double leakage_000 = 0; //!A, !B, !CI + double leakage_001 = 0; //!A, !B, CI + double leakage_010 = 0; //!A, B, !CI + double leakage_011 = 0; //!A, B, CI + double leakage_100 = 0; //A, !B, !CI + double leakage_101 = 0; //A, !B, CI + double leakage_110 = 0; //A, B, !CI + double leakage_111 = 0; //A, B, CI + + //This is so painful... + leakage_000 += getGenProperties()->get("INV1_LeakagePower_0").toDouble(); + leakage_000 += getGenProperties()->get("INV2_LeakagePower_0").toDouble(); + leakage_000 += getGenProperties()->get("INV3_LeakagePower_0").toDouble(); + leakage_000 += getGenProperties()->get("INV4_LeakagePower_0").toDouble(); + leakage_000 += getGenProperties()->get("INVZ1_LeakagePower_010_0").toDouble(); + leakage_000 += getGenProperties()->get("INVZ2_LeakagePower_101_0").toDouble(); + leakage_000 += getGenProperties()->get("INVZ3_LeakagePower_010_0").toDouble(); + leakage_000 += getGenProperties()->get("INVZ4_LeakagePower_101_0").toDouble(); + leakage_000 += getGenProperties()->get("NAND1_LeakagePower_00").toDouble(); + leakage_000 += getGenProperties()->get("NAND2_LeakagePower_00").toDouble(); + leakage_000 += getGenProperties()->get("NAND3_LeakagePower_11").toDouble(); + + leakage_001 += getGenProperties()->get("INV1_LeakagePower_0").toDouble(); + leakage_001 += getGenProperties()->get("INV2_LeakagePower_0").toDouble(); + leakage_001 += getGenProperties()->get("INV3_LeakagePower_1").toDouble(); + leakage_001 += getGenProperties()->get("INV4_LeakagePower_0").toDouble(); + leakage_001 += getGenProperties()->get("INVZ1_LeakagePower_010_0").toDouble(); + leakage_001 += getGenProperties()->get("INVZ2_LeakagePower_101_0").toDouble(); + leakage_001 += getGenProperties()->get("INVZ3_LeakagePower_100_1").toDouble(); + leakage_001 += getGenProperties()->get("INVZ4_LeakagePower_011_1").toDouble(); + leakage_001 += getGenProperties()->get("NAND1_LeakagePower_10").toDouble(); + leakage_001 += getGenProperties()->get("NAND2_LeakagePower_00").toDouble(); + leakage_001 += getGenProperties()->get("NAND3_LeakagePower_11").toDouble(); + + leakage_010 += getGenProperties()->get("INV1_LeakagePower_0").toDouble(); + leakage_010 += getGenProperties()->get("INV2_LeakagePower_1").toDouble(); + leakage_010 += getGenProperties()->get("INV3_LeakagePower_0").toDouble(); + leakage_010 += getGenProperties()->get("INV4_LeakagePower_1").toDouble(); + leakage_010 += getGenProperties()->get("INVZ1_LeakagePower_011_1").toDouble(); + leakage_010 += getGenProperties()->get("INVZ2_LeakagePower_100_1").toDouble(); + leakage_010 += getGenProperties()->get("INVZ3_LeakagePower_011_1").toDouble(); + leakage_010 += getGenProperties()->get("INVZ4_LeakagePower_100_1").toDouble(); + leakage_010 += getGenProperties()->get("NAND1_LeakagePower_01").toDouble(); + leakage_010 += getGenProperties()->get("NAND2_LeakagePower_01").toDouble(); + leakage_010 += getGenProperties()->get("NAND3_LeakagePower_11").toDouble(); + + leakage_011 += getGenProperties()->get("INV1_LeakagePower_0").toDouble(); + leakage_011 += getGenProperties()->get("INV2_LeakagePower_1").toDouble(); + leakage_011 += getGenProperties()->get("INV3_LeakagePower_1").toDouble(); + leakage_011 += getGenProperties()->get("INV4_LeakagePower_1").toDouble(); + leakage_011 += getGenProperties()->get("INVZ1_LeakagePower_011_1").toDouble(); + leakage_011 += getGenProperties()->get("INVZ2_LeakagePower_100_1").toDouble(); + leakage_011 += getGenProperties()->get("INVZ3_LeakagePower_101_0").toDouble(); + leakage_011 += getGenProperties()->get("INVZ4_LeakagePower_010_0").toDouble(); + leakage_011 += getGenProperties()->get("NAND1_LeakagePower_11").toDouble(); + leakage_011 += getGenProperties()->get("NAND2_LeakagePower_01").toDouble(); + leakage_011 += getGenProperties()->get("NAND3_LeakagePower_01").toDouble(); + + leakage_100 += getGenProperties()->get("INV1_LeakagePower_1").toDouble(); + leakage_100 += getGenProperties()->get("INV2_LeakagePower_0").toDouble(); + leakage_100 += getGenProperties()->get("INV3_LeakagePower_0").toDouble(); + leakage_100 += getGenProperties()->get("INV4_LeakagePower_1").toDouble(); + leakage_100 += getGenProperties()->get("INVZ1_LeakagePower_100_1").toDouble(); + leakage_100 += getGenProperties()->get("INVZ2_LeakagePower_011_1").toDouble(); + leakage_100 += getGenProperties()->get("INVZ3_LeakagePower_011_1").toDouble(); + leakage_100 += getGenProperties()->get("INVZ4_LeakagePower_100_1").toDouble(); + leakage_100 += getGenProperties()->get("NAND1_LeakagePower_01").toDouble(); + leakage_100 += getGenProperties()->get("NAND2_LeakagePower_10").toDouble(); + leakage_100 += getGenProperties()->get("NAND3_LeakagePower_11").toDouble(); + + leakage_101 += getGenProperties()->get("INV1_LeakagePower_1").toDouble(); + leakage_101 += getGenProperties()->get("INV2_LeakagePower_0").toDouble(); + leakage_101 += getGenProperties()->get("INV3_LeakagePower_1").toDouble(); + leakage_101 += getGenProperties()->get("INV4_LeakagePower_1").toDouble(); + leakage_101 += getGenProperties()->get("INVZ1_LeakagePower_100_1").toDouble(); + leakage_101 += getGenProperties()->get("INVZ2_LeakagePower_011_1").toDouble(); + leakage_101 += getGenProperties()->get("INVZ3_LeakagePower_101_0").toDouble(); + leakage_101 += getGenProperties()->get("INVZ4_LeakagePower_010_0").toDouble(); + leakage_101 += getGenProperties()->get("NAND1_LeakagePower_11").toDouble(); + leakage_101 += getGenProperties()->get("NAND2_LeakagePower_10").toDouble(); + leakage_101 += getGenProperties()->get("NAND3_LeakagePower_01").toDouble(); + + leakage_110 += getGenProperties()->get("INV1_LeakagePower_1").toDouble(); + leakage_110 += getGenProperties()->get("INV2_LeakagePower_1").toDouble(); + leakage_110 += getGenProperties()->get("INV3_LeakagePower_0").toDouble(); + leakage_110 += getGenProperties()->get("INV4_LeakagePower_0").toDouble(); + leakage_110 += getGenProperties()->get("INVZ1_LeakagePower_101_0").toDouble(); + leakage_110 += getGenProperties()->get("INVZ2_LeakagePower_010_0").toDouble(); + leakage_110 += getGenProperties()->get("INVZ3_LeakagePower_010_0").toDouble(); + leakage_110 += getGenProperties()->get("INVZ4_LeakagePower_101_0").toDouble(); + leakage_110 += getGenProperties()->get("NAND1_LeakagePower_00").toDouble(); + leakage_110 += getGenProperties()->get("NAND2_LeakagePower_11").toDouble(); + leakage_110 += getGenProperties()->get("NAND3_LeakagePower_10").toDouble(); + + leakage_111 += getGenProperties()->get("INV1_LeakagePower_1").toDouble(); + leakage_111 += getGenProperties()->get("INV2_LeakagePower_1").toDouble(); + leakage_111 += getGenProperties()->get("INV3_LeakagePower_1").toDouble(); + leakage_111 += getGenProperties()->get("INV4_LeakagePower_0").toDouble(); + leakage_111 += getGenProperties()->get("INVZ1_LeakagePower_101_0").toDouble(); + leakage_111 += getGenProperties()->get("INVZ2_LeakagePower_010_0").toDouble(); + leakage_111 += getGenProperties()->get("INVZ3_LeakagePower_100_1").toDouble(); + leakage_111 += getGenProperties()->get("INVZ4_LeakagePower_011_1").toDouble(); + leakage_111 += getGenProperties()->get("NAND1_LeakagePower_10").toDouble(); + leakage_111 += getGenProperties()->get("NAND2_LeakagePower_11").toDouble(); + leakage_111 += getGenProperties()->get("NAND3_LeakagePower_10").toDouble(); + + cache->set(cell_name + "->Leakage->!A!B!CI", leakage_000); + cache->set(cell_name + "->Leakage->!A!BCI", leakage_001); + cache->set(cell_name + "->Leakage->!AB!CI", leakage_010); + cache->set(cell_name + "->Leakage->!ABCI", leakage_011); + cache->set(cell_name + "->Leakage->A!B!CI", leakage_100); + cache->set(cell_name + "->Leakage->A!BCI", leakage_101); + cache->set(cell_name + "->Leakage->AB!CI", leakage_110); + cache->set(cell_name + "->Leakage->ABCI", leakage_111); + Log::printLine(cell_name + "->Leakage->!A!B!CI=" + (String) leakage_000); + Log::printLine(cell_name + "->Leakage->!A!BCI=" + (String) leakage_001); + Log::printLine(cell_name + "->Leakage->!AB!CI=" + (String) leakage_010); + Log::printLine(cell_name + "->Leakage->!ABCI=" + (String) leakage_011); + Log::printLine(cell_name + "->Leakage->A!B!CI=" + (String) leakage_100); + Log::printLine(cell_name + "->Leakage->A!BCI=" + (String) leakage_101); + Log::printLine(cell_name + "->Leakage->AB!CI=" + (String) leakage_110); + Log::printLine(cell_name + "->Leakage->ABCI=" + (String) leakage_111); + // -------------------------------------------------------------------- + + /* + // Cache event energy results + double event_a_flip = 0.0; + event_a_flip += getGenProperties()->get("INV1_A_Flip").toDouble() + getGenProperties()->get("INV1_ZN_Flip").toDouble(); + event_a_flip += getGenProperties()->get("INVZ1_OE_Flip").toDouble() + getGenProperties()->get("INVZ1_OEN_Flip").toDouble(); + event_a_flip += getGenProperties()->get("INVZ2_OE_Flip").toDouble() + getGenProperties()->get("INVZ2_OEN_Flip").toDouble(); + event_a_flip += getGenProperties()->get("NAND2_A1_Flip").toDouble(); + cache->set(cell_name + "->Event_A_Flip", event_a_flip); + Log::printLine(cell_name + "->Event_A_Flip=" + (String) event_a_flip); + + double event_b_flip = 0.0; + event_b_flip += getGenProperties()->get("INV2_A_Flip").toDouble() + getGenProperties()->get("INV2_ZN_Flip").toDouble(); + event_b_flip += getGenProperties()->get("INVZ1_A_Flip").toDouble(); + event_b_flip += getGenProperties()->get("INVZ2_A_Flip").toDouble(); + event_b_flip += getGenProperties()->get("NAND2_A1_Flip").toDouble(); + cache->set(cell_name + "->Event_B_Flip", event_b_flip); + Log::printLine(cell_name + "->Event_B_Flip=" + (String) event_b_flip); + + double event_ci_flip = 0.0; + event_ci_flip += getGenProperties()->get("INV3_A_Flip").toDouble() + getGenProperties()->get("INV3_ZN_Flip").toDouble(); + event_ci_flip += getGenProperties()->get("INVZ3_OE_Flip").toDouble() + getGenProperties()->get("INVZ3_OEN_Flip").toDouble(); + event_ci_flip += getGenProperties()->get("INVZ4_OE_Flip").toDouble() + getGenProperties()->get("INVZ4_OEN_Flip").toDouble(); + event_ci_flip += getGenProperties()->get("NAND1_A1_Flip").toDouble(); + cache->set(cell_name + "->Event_CI_Flip", event_ci_flip); + Log::printLine(cell_name + "->Event_CI_Flip=" + (String) event_ci_flip); + + double event_p_flip = 0.0; + event_p_flip += getGenProperties()->get("INV4_A_Flip").toDouble() + getGenProperties()->get("INV4_ZN_Flip").toDouble(); + event_p_flip += getGenProperties()->get("INVZ1_ZN_Flip").toDouble(); + event_p_flip += getGenProperties()->get("INVZ2_ZN_Flip").toDouble(); + event_p_flip += getGenProperties()->get("NAND1_A2_Flip").toDouble(); + cache->set(cell_name + "->Event_P_Flip", event_p_flip); + Log::printLine(cell_name + "->Event_P_Flip=" + (String) event_p_flip); + + double event_s_flip = 0.0; + event_s_flip += getGenProperties()->get("INVZ3_ZN_Flip").toDouble(); + event_s_flip += getGenProperties()->get("INVZ4_ZN_Flip").toDouble(); + cache->set(cell_name + "->Event_S_Flip", event_s_flip); + Log::printLine(cell_name + "->Event_S_Flip=" + (String) event_s_flip); + + double event_cp_flip = 0.0; + event_cp_flip += getGenProperties()->get("NAND1_ZN_Flip").toDouble(); + event_cp_flip += getGenProperties()->get("NAND3_A2_Flip").toDouble(); + cache->set(cell_name + "->Event_CP_Flip", event_cp_flip); + Log::printLine(cell_name + "->Event_CP_Flip=" + (String) event_cp_flip); + + double event_g_flip = 0.0; + event_g_flip += getGenProperties()->get("NAND2_ZN_Flip").toDouble(); + event_g_flip += getGenProperties()->get("NAND3_A2_Flip").toDouble(); + cache->set(cell_name + "->Event_G_Flip", event_g_flip); + Log::printLine(cell_name + "->Event_G_Flip=" + (String) event_g_flip); + + double event_co_flip = 0.0; + event_co_flip += getGenProperties()->get("NAND3_ZN_Flip").toDouble(); + cache->set(cell_name + "->Event_CO_Flip", event_co_flip); + Log::printLine(cell_name + "->Event_CO_Flip=" + (String) event_co_flip); + */ + // -------------------------------------------------------------------- + // Get Node Capacitances + // -------------------------------------------------------------------- + double a_cap = getNet("A")->getTotalDownstreamCap(); + double b_cap = getNet("B")->getTotalDownstreamCap(); + double ci_cap = getNet("CI")->getTotalDownstreamCap(); + double a_b_cap = getNet("A_b")->getTotalDownstreamCap(); + double b_b_cap = getNet("B_b")->getTotalDownstreamCap(); + double ci_b_cap = getNet("CI_b")->getTotalDownstreamCap(); + double p_cap = getNet("P")->getTotalDownstreamCap(); + double p_b_cap = getNet("P_b")->getTotalDownstreamCap(); + double s_cap = getNet("S")->getTotalDownstreamCap(); + double cp_cap = getNet("CP")->getTotalDownstreamCap(); + double g_cap = getNet("G")->getTotalDownstreamCap(); + double co_cap = getNet("CO")->getTotalDownstreamCap(); + + cache->set(cell_name + "->Cap->A", a_cap); + cache->set(cell_name + "->Cap->B", b_cap); + cache->set(cell_name + "->Cap->CI", ci_cap); + cache->set(cell_name + "->Cap->A_b", a_b_cap); + cache->set(cell_name + "->Cap->B_b", b_b_cap); + cache->set(cell_name + "->Cap->CI_b", ci_b_cap); + cache->set(cell_name + "->Cap->P", p_cap); + cache->set(cell_name + "->Cap->P_b", p_b_cap); + cache->set(cell_name + "->Cap->S", s_cap); + cache->set(cell_name + "->Cap->CP", cp_cap); + cache->set(cell_name + "->Cap->G", g_cap); + cache->set(cell_name + "->Cap->CO", co_cap); + + Log::printLine(cell_name + "->Cap->A=" + (String) a_cap); + Log::printLine(cell_name + "->Cap->B=" + (String) b_cap); + Log::printLine(cell_name + "->Cap->CI=" + (String) ci_cap); + Log::printLine(cell_name + "->Cap->A_b=" + (String) a_b_cap); + Log::printLine(cell_name + "->Cap->B_b=" + (String) b_b_cap); + Log::printLine(cell_name + "->Cap->CI_b=" + (String) ci_b_cap); + Log::printLine(cell_name + "->Cap->P=" + (String) p_cap); + Log::printLine(cell_name + "->Cap->P_b=" + (String) p_b_cap); + Log::printLine(cell_name + "->Cap->S=" + (String) s_cap); + Log::printLine(cell_name + "->Cap->CP=" + (String) cp_cap); + Log::printLine(cell_name + "->Cap->G=" + (String) g_cap); + Log::printLine(cell_name + "->Cap->CO=" + (String) co_cap); + // -------------------------------------------------------------------- + + // -------------------------------------------------------------------- + // Build Internal Delay Model + // -------------------------------------------------------------------- + // Build abstracted timing model + double s_ron = (getDriver("INVZ3_RonZN")->getOutputRes() + getDriver("INVZ4_RonZN")->getOutputRes()) / 2; + double co_ron = getDriver("NAND3_RonZN")->getOutputRes(); + + double a_to_s_delay = 0.0; + a_to_s_delay += getDriver("INV1_RonZN")->calculateDelay(); + a_to_s_delay += max(getDriver("INVZ1_RonZN")->calculateDelay(), getDriver("INVZ2_RonZN")->calculateDelay()); + a_to_s_delay += max(getDriver("INVZ3_RonZN")->calculateDelay(), getDriver("INV4_RonZN")->calculateDelay() + getDriver("INVZ4_RonZN")->calculateDelay()); + + double b_to_s_delay = 0.0; + b_to_s_delay += max(getDriver("INVZ1_RonZN")->calculateDelay(), getDriver("INV2_RonZN")->calculateDelay() + getDriver("INVZ2_RonZN")->calculateDelay()); + b_to_s_delay += max(getDriver("INVZ3_RonZN")->calculateDelay(), getDriver("INV4_RonZN")->calculateDelay() + getDriver("INVZ4_RonZN")->calculateDelay()); + + double ci_to_s_delay = 0.0; + ci_to_s_delay += getDriver("INV3_RonZN")->calculateDelay(); + ci_to_s_delay += max(getDriver("INVZ3_RonZN")->calculateDelay(), getDriver("INVZ4_RonZN")->calculateDelay()); + + double a_to_co_delay = 0.0; + a_to_co_delay += max(getDriver("NAND2_RonZN")->calculateDelay(), //Generate path + getDriver("INV1_RonZN")->calculateDelay() + //Carry propagate path + max(getDriver("INVZ1_RonZN")->calculateDelay(), getDriver("INVZ2_RonZN")->calculateDelay()) + + getDriver("NAND1_RonZN")->calculateDelay()); + a_to_co_delay += getDriver("NAND3_RonZN")->calculateDelay(); + + double b_to_co_delay = 0.0; + b_to_co_delay += max(getDriver("NAND2_RonZN")->calculateDelay(), //Generate path + max(getDriver("INVZ1_RonZN")->calculateDelay(), //Carry propagate path + getDriver("INV2_RonZN")->calculateDelay() + getDriver("INVZ2_RonZN")->calculateDelay()) + + getDriver("NAND1_RonZN")->calculateDelay()); + b_to_co_delay += getDriver("NAND3_RonZN")->calculateDelay(); + + double ci_to_co_delay = 0.0; + ci_to_co_delay += getDriver("NAND1_RonZN")->calculateDelay(); + ci_to_co_delay += getDriver("NAND3_RonZN")->calculateDelay(); + + cache->set(cell_name + "->DriveRes->S", s_ron); + cache->set(cell_name + "->DriveRes->CO", co_ron); + + cache->set(cell_name + "->Delay->A_to_S", a_to_s_delay); + cache->set(cell_name + "->Delay->B_to_S", b_to_s_delay); + cache->set(cell_name + "->Delay->CI_to_S", ci_to_s_delay); + cache->set(cell_name + "->Delay->A_to_CO", a_to_co_delay); + cache->set(cell_name + "->Delay->B_to_CO", b_to_co_delay); + cache->set(cell_name + "->Delay->CI_to_CO", ci_to_co_delay); + + Log::printLine(cell_name + "->DriveRes->S=" + (String) s_ron); + Log::printLine(cell_name + "->DriveRes->CO=" + (String) co_ron); + Log::printLine(cell_name + "->Delay->A_to_S=" + (String) a_to_s_delay); + Log::printLine(cell_name + "->Delay->B_to_S=" + (String) b_to_s_delay); + Log::printLine(cell_name + "->Delay->CI_to_S=" + (String) ci_to_s_delay); + Log::printLine(cell_name + "->Delay->A_to_CO=" + (String) a_to_co_delay); + Log::printLine(cell_name + "->Delay->B_to_CO=" + (String) b_to_co_delay); + Log::printLine(cell_name + "->Delay->CI_to_CO=" + (String) ci_to_co_delay); + // -------------------------------------------------------------------- + + return; + + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/AND2.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/AND2.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_STD_CELLS_AND2_H__ +#define __DSENT_MODEL_STD_CELLS_AND2_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" + +namespace DSENT +{ + class AND2 : public StdCell + { + public: + AND2(const String& instance_name_, const TechModel* tech_model_); + virtual ~AND2(); + + public: + // Set a list of properties' name needed to construct model + void initProperties(); + // Cache the standard cell + void cacheStdCell(StdCellLib* cell_lib_, double drive_strength_); + + protected: + // Build the model + virtual void constructModel(); + virtual void updateModel(); + virtual void evaluateModel(); + virtual void useModel(); + virtual void propagateTransitionInfo(); + }; // class AND2 +} // namespace DSENT + +#endif // __DSENT_MODEL_STD_CELLS_AND2_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/AND2.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/AND2.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/AND2.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/CellMacros.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriver.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalLoad.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDelay.hh" + +namespace DSENT +{ + using std::max; + + AND2::AND2(const String& instance_name_, const TechModel* tech_model_) + : StdCell(instance_name_, tech_model_) + { + initProperties(); + } + + AND2::~AND2() + {} + + void AND2::initProperties() + { + return; + } + + void AND2::constructModel() + { + // All constructModel should do is create Area/NDDPower/Energy Results as + // well as instantiate any sub-instances using only the hard parameters + + createInputPort("A"); + createInputPort("B"); + createOutputPort("Y"); + + createLoad("A_Cap"); + createLoad("B_Cap"); + createDelay("A_to_Y_delay"); + createDelay("B_to_Y_delay"); + createDriver("Y_Ron", true); + + ElectricalLoad* a_cap = getLoad("A_Cap"); + ElectricalLoad* b_cap = getLoad("B_Cap"); + ElectricalDelay* a_to_y_delay = getDelay("A_to_Y_delay"); + ElectricalDelay* b_to_y_delay = getDelay("B_to_Y_delay"); + ElectricalDriver* y_ron = getDriver("Y_Ron"); + + getNet("A")->addDownstreamNode(a_cap); + getNet("B")->addDownstreamNode(b_cap); + a_cap->addDownstreamNode(a_to_y_delay); + b_cap->addDownstreamNode(b_to_y_delay); + a_to_y_delay->addDownstreamNode(y_ron); + b_to_y_delay->addDownstreamNode(y_ron); + y_ron->addDownstreamNode(getNet("Y")); + + // Create Area result + // Create NDD Power result + createElectricalAtomicResults(); + getEventInfo("Idle")->setStaticTransitionInfos(); + // Create AND Event Energy Result + createElectricalEventAtomicResult("AND2"); + + return; + } + + void AND2::updateModel() + { + // All updateModel should do is calculate numbers for the Area/NDDPower/Energy + // Results as anything else that needs to be done using either soft or hard parameters + + // Get parameters + double drive_strength = getDrivingStrength(); + Map* cache = getTechModel()->getStdCellLib()->getStdCellCache(); + + // Standard cell cache string + String cell_name = "AND2_X" + (String) drive_strength; + + // Get timing parameters + getLoad("A_Cap")->setLoadCap(cache->get(cell_name + "->Cap->A")); + getLoad("B_Cap")->setLoadCap(cache->get(cell_name + "->Cap->B")); + getDelay("A_to_Y_delay")->setDelay(cache->get(cell_name + "->Delay->A_to_Y")); + getDelay("B_to_Y_delay")->setDelay(cache->get(cell_name + "->Delay->B_to_Y")); + getDriver("Y_Ron")->setOutputRes(cache->get(cell_name + "->DriveRes->Y")); + + // Set the cell area + getAreaResult("Active")->setValue(cache->get(cell_name + "->ActiveArea")); + getAreaResult("Metal1Wire")->setValue(cache->get(cell_name + "->ActiveArea")); + + return; + } + + void AND2::evaluateModel() + { + return; + } + + void AND2::useModel() + { + // Get parameters + double drive_strength = getDrivingStrength(); + Map* cache = getTechModel()->getStdCellLib()->getStdCellCache(); + + // Standard cell cache string + String cell_name = "AND2_X" + (String) drive_strength; + + // Propagate the transition info and get the 0->1 transtion count + propagateTransitionInfo(); + double P_A = getInputPort("A")->getTransitionInfo().getProbability1(); + double P_B = getInputPort("B")->getTransitionInfo().getProbability1(); + double Y_num_trans_01 = getOutputPort("Y")->getTransitionInfo().getNumberTransitions01(); + + // Calculate leakage + double leakage = 0; + leakage += cache->get(cell_name + "->Leakage->!A!B") * (1 - P_A) * (1 - P_B); + leakage += cache->get(cell_name + "->Leakage->!AB") * (1 - P_A) * P_B; + leakage += cache->get(cell_name + "->Leakage->A!B") * P_A * (1 - P_B); + leakage += cache->get(cell_name + "->Leakage->AB") * P_A * P_B; + getNddPowerResult("Leakage")->setValue(leakage); + + // Get VDD + double vdd = getTechModel()->get("Vdd"); + + // Get capacitances + double y_b_cap = cache->get(cell_name + "->Cap->Y_b"); + double y_cap = cache->get(cell_name + "->Cap->Y"); + double y_load_cap = getNet("Y")->getTotalDownstreamCap(); + + // Calculate AND2Event energy + double energy_per_trans_01 = (y_b_cap + y_cap + y_load_cap) * vdd * vdd; + getEventResult("AND2")->setValue(energy_per_trans_01 * Y_num_trans_01); + + return; + } + + void AND2::propagateTransitionInfo() + { + // Get input signal transition info + const TransitionInfo& trans_A = getInputPort("A")->getTransitionInfo(); + const TransitionInfo& trans_B = getInputPort("B")->getTransitionInfo(); + + double max_freq_mult = max(trans_A.getFrequencyMultiplier(), trans_B.getFrequencyMultiplier()); + const TransitionInfo& scaled_trans_A = trans_A.scaleFrequencyMultiplier(max_freq_mult); + const TransitionInfo& scaled_trans_B = trans_B.scaleFrequencyMultiplier(max_freq_mult); + + double A_prob_00 = scaled_trans_A.getNumberTransitions00() / max_freq_mult; + double A_prob_01 = scaled_trans_A.getNumberTransitions01() / max_freq_mult; + double A_prob_10 = A_prob_01; + double A_prob_11 = scaled_trans_A.getNumberTransitions11() / max_freq_mult; + double B_prob_00 = scaled_trans_B.getNumberTransitions00() / max_freq_mult; + double B_prob_01 = scaled_trans_B.getNumberTransitions01() / max_freq_mult; + double B_prob_10 = B_prob_01; + double B_prob_11 = scaled_trans_B.getNumberTransitions11() / max_freq_mult; + + // Set output transition info + double Y_prob_00 = A_prob_00 + + A_prob_01 * (B_prob_00 + B_prob_10) + + A_prob_10 * (B_prob_00 + B_prob_01) + + A_prob_11 * B_prob_00; + double Y_prob_01 = A_prob_01 * (B_prob_01 + B_prob_11) + + A_prob_11 * B_prob_01; + double Y_prob_11 = A_prob_11 * B_prob_11; + + // Check that probabilities add up to 1.0 with some finite tolerance + ASSERT(LibUtil::Math::isEqual(Y_prob_00 + Y_prob_01 + Y_prob_01 + Y_prob_11, 1.0), "[Error] " + getInstanceName() + + "Output transition probabilities must add up to 1 (" + (String) Y_prob_00 + ", " + + (String) Y_prob_01 + ", " + (String) Y_prob_11 + ")!"); + + // Turn probability of transitions per cycle into number of transitions per time unit + TransitionInfo trans_Y(Y_prob_00 * max_freq_mult, Y_prob_01 * max_freq_mult, Y_prob_11 * max_freq_mult); + getOutputPort("Y")->setTransitionInfo(trans_Y); + return; + } + + void AND2::cacheStdCell(StdCellLib* cell_lib_, double drive_strength_) + { + // Standard cell cache string + String cell_name = "AND2_X" + (String) drive_strength_; + + Log::printLine("=== " + cell_name + " ==="); + + // Get parameters + double gate_pitch = cell_lib_->getTechModel()->get("Gate->PitchContacted"); + Map* cache = cell_lib_->getStdCellCache(); + + // Now actually build the full standard cell model + // Create the two input ports + createInputPort("A"); + createInputPort("B"); + createOutputPort("Y"); + + createNet("Y_b"); + + // Adds macros + CellMacros::addNand2(this, "NAND2", false, true, true, "A", "B", "Y_b"); + CellMacros::addInverter(this, "INV", false, true, "Y_b", "Y"); + CellMacros::updateNand2(this, "NAND2", drive_strength_ * 0.5); + CellMacros::updateInverter(this, "INV", drive_strength_ * 1.0); + + // Cache area result + double area = 0.0; + area += gate_pitch * getTotalHeight() * 1; + area += gate_pitch * getTotalHeight() * getGenProperties()->get("NAND2_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV_GatePitches").toDouble(); + cache->set(cell_name + "->ActiveArea", area); + Log::printLine(cell_name + "->ActiveArea=" + (String) area); + + // -------------------------------------------------------------------- + // Leakage Model Calculation + // -------------------------------------------------------------------- + double leakage_00 = getGenProperties()->get("NAND2_LeakagePower_00").toDouble() + + getGenProperties()->get("INV_LeakagePower_0").toDouble(); + double leakage_01 = getGenProperties()->get("NAND2_LeakagePower_01").toDouble() + + getGenProperties()->get("INV_LeakagePower_0").toDouble(); + double leakage_10 = getGenProperties()->get("NAND2_LeakagePower_10").toDouble() + + getGenProperties()->get("INV_LeakagePower_0").toDouble(); + double leakage_11 = getGenProperties()->get("NAND2_LeakagePower_11").toDouble() + + getGenProperties()->get("INV_LeakagePower_1").toDouble(); + cache->set(cell_name + "->Leakage->!A!B", leakage_00); + cache->set(cell_name + "->Leakage->!AB", leakage_01); + cache->set(cell_name + "->Leakage->A!B", leakage_10); + cache->set(cell_name + "->Leakage->AB", leakage_11); + Log::printLine(cell_name + "->Leakage->!A!B=" + (String) leakage_00); + Log::printLine(cell_name + "->Leakage->!AB=" + (String) leakage_01); + Log::printLine(cell_name + "->Leakage->A!B=" + (String) leakage_10); + Log::printLine(cell_name + "->Leakage->AB=" + (String) leakage_11); + // -------------------------------------------------------------------- + + // -------------------------------------------------------------------- + // Get Node Capacitances + // -------------------------------------------------------------------- + double a_cap = getNet("A")->getTotalDownstreamCap(); + double b_cap = getNet("B")->getTotalDownstreamCap(); + double y_b_cap = getNet("Y_b")->getTotalDownstreamCap(); + double y_cap = getNet("Y")->getTotalDownstreamCap(); + + cache->set(cell_name + "->Cap->A", a_cap); + cache->set(cell_name + "->Cap->B", b_cap); + cache->set(cell_name + "->Cap->Y_b", y_b_cap); + cache->set(cell_name + "->Cap->Y", y_cap); + Log::printLine(cell_name + "->Cap->A=" + (String) a_cap); + Log::printLine(cell_name + "->Cap->B=" + (String) b_cap); + Log::printLine(cell_name + "->Cap->Y=" + (String) y_b_cap); + Log::printLine(cell_name + "->Cap->Y=" + (String) y_cap); + // -------------------------------------------------------------------- + + // -------------------------------------------------------------------- + // Build Internal Delay Model + // -------------------------------------------------------------------- + double y_ron = getDriver("INV_RonZN")->getOutputRes(); + double a_to_y_delay = getDriver("NAND2_RonZN")->calculateDelay() + + getDriver("INV_RonZN")->calculateDelay(); + double b_to_y_delay = getDriver("NAND2_RonZN")->calculateDelay() + + getDriver("INV_RonZN")->calculateDelay(); + + cache->set(cell_name + "->DriveRes->Y", y_ron); + cache->set(cell_name + "->Delay->A_to_Y", a_to_y_delay); + cache->set(cell_name + "->Delay->B_to_Y", b_to_y_delay); + Log::printLine(cell_name + "->DriveRes->Y=" + (String) y_ron); + Log::printLine(cell_name + "->Delay->A_to_Y=" + (String) a_to_y_delay); + Log::printLine(cell_name + "->Delay->B_to_Y=" + (String) b_to_y_delay); + // -------------------------------------------------------------------- + + return; + + } +} // namespace DSENT diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/BUF.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/BUF.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_STD_CELLS_BUF_H__ +#define __DSENT_MODEL_STD_CELLS_BUF_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" + +namespace DSENT +{ + class BUF : public StdCell + { + public: + BUF(const String& instance_name_, const TechModel* tech_model_); + virtual ~BUF(); + + public: + // Set a list of properties' name needed to construct model + void initProperties(); + // Cache the standard cell + void cacheStdCell(StdCellLib* cell_lib_, double drive_strength_); + + protected: + // Build the model + virtual void constructModel(); + virtual void updateModel(); + virtual void evaluateModel(); + virtual void useModel(); + virtual void propagateTransitionInfo(); + + }; // class BUF +} // namespace DSENT + +#endif // __DSENT_MODEL_STD_CELLS_BUF_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/BUF.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/BUF.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/BUF.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/CellMacros.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriver.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalLoad.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDelay.hh" + +namespace DSENT +{ + using std::max; + + BUF::BUF(const String& instance_name_, const TechModel* tech_model_) + : StdCell(instance_name_, tech_model_) + { + initProperties(); + } + + BUF::~BUF() + {} + + void BUF::initProperties() + { + return; + } + + void BUF::constructModel() + { + createInputPort("A"); + createOutputPort("Y"); + + createLoad("A_Cap"); + createDelay("A_to_Y_delay"); + createDriver("Y_Ron", true); + + ElectricalLoad* a_cap = getLoad("A_Cap"); + ElectricalDelay* a_to_y_delay = getDelay("A_to_Y_delay"); + ElectricalDriver* y_ron = getDriver("Y_Ron"); + + getNet("A")->addDownstreamNode(a_cap); + a_cap->addDownstreamNode(a_to_y_delay); + a_to_y_delay->addDownstreamNode(y_ron); + y_ron->addDownstreamNode(getNet("Y")); + + // Create Area result + // Create NDD Power result + createElectricalAtomicResults(); + // Create OR Event Energy Result + createElectricalEventAtomicResult("BUF"); + + getEventInfo("Idle")->setStaticTransitionInfos(); + + return; + } + + void BUF::updateModel() + { + // Get parameters + double drive_strength = getDrivingStrength(); + Map* cache = getTechModel()->getStdCellLib()->getStdCellCache(); + + // Standard cell cache string + const String& cell_name = "BUF_X" + (String) drive_strength; + + // Get timing parameters + getLoad("A_Cap")->setLoadCap(cache->get(cell_name + "->Cap->A")); + getDelay("A_to_Y_delay")->setDelay(cache->get(cell_name + "->Delay->A_to_Y")); + getDriver("Y_Ron")->setOutputRes(cache->get(cell_name + "->DriveRes->Y")); + + // Set the cell area + getAreaResult("Active")->setValue(cache->get(cell_name + "->ActiveArea")); + getAreaResult("Metal1Wire")->setValue(cache->get(cell_name + "->ActiveArea")); + + return; + } + + void BUF::evaluateModel() + { + return; + } + + void BUF::useModel() + { + // Get parameters + double drive_strength = getDrivingStrength(); + Map* cache = getTechModel()->getStdCellLib()->getStdCellCache(); + + // Stadard cell cache string + const String& cell_name = "BUF_X" + (String) drive_strength; + + // Propagate the transition info and get the 0->1 transtion count + propagateTransitionInfo(); + double P_A = getInputPort("A")->getTransitionInfo().getProbability1(); + double Y_num_trans_01 = getOutputPort("Y")->getTransitionInfo().getNumberTransitions01(); + + // Calculate leakage + double leakage = 0; + leakage += cache->get(cell_name + "->Leakage->!A") * (1 - P_A); + leakage += cache->get(cell_name + "->Leakage->A") * P_A; + getNddPowerResult("Leakage")->setValue(leakage); + + // Get VDD + double vdd = getTechModel()->get("Vdd"); + + // Get capacitances + double y_b_cap = cache->get(cell_name + "->Cap->Y_b"); + double y_cap = cache->get(cell_name + "->Cap->Y"); + double y_load_cap = getNet("Y")->getTotalDownstreamCap(); + + // Calculate BUFEvent energy + double energy_per_trans_01 = (y_b_cap + y_cap + y_load_cap) * vdd * vdd; + getEventResult("BUF")->setValue(energy_per_trans_01 * Y_num_trans_01); + + return; + } + + void BUF::propagateTransitionInfo() + { + // Get input signal transition info + const TransitionInfo& trans_A = getInputPort("A")->getTransitionInfo(); + + getOutputPort("Y")->setTransitionInfo(trans_A); + return; + } + + // Creates the standard cell, characterizes and abstracts away the details + void BUF::cacheStdCell(StdCellLib* cell_lib_, double drive_strength_) + { + // Get parameters + double gate_pitch = cell_lib_->getTechModel()->get("Gate->PitchContacted"); + Map* cache = cell_lib_->getStdCellCache(); + + // Stadard cell cache string + const String& cell_name = "BUF_X" + (String) drive_strength_; + + Log::printLine("=== " + cell_name + " ==="); + + // Now actually build the full standard cell model + createInputPort("A"); + createOutputPort("Y"); + + createNet("Y_b"); + + // Adds macros + CellMacros::addInverter(this, "INV0", false, true, "A", "Y_b"); + CellMacros::addInverter(this, "INV1", false, true, "Y_b", "Y"); + + // Update macros + CellMacros::updateInverter(this, "INV0", drive_strength_ * 0.367); + CellMacros::updateInverter(this, "INV1", drive_strength_ * 1.0); + + // Cache area result + double area = 0.0; + area += gate_pitch * getTotalHeight() * 1; + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV0_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV1_GatePitches").toDouble(); + cache->set(cell_name + "->ActiveArea", area); + Log::printLine(cell_name + "->ActiveArea=" + (String)area); + + // -------------------------------------------------------------------- + // Leakage Model Calculation + // -------------------------------------------------------------------- + // Cache leakage power results (for every single signal combination) + double leakage_0 = 0.0; // !A + double leakage_1 = 0.0; // A + + leakage_0 += getGenProperties()->get("INV0_LeakagePower_0").toDouble(); + leakage_0 += getGenProperties()->get("INV1_LeakagePower_1").toDouble(); + + leakage_1 += getGenProperties()->get("INV0_LeakagePower_1").toDouble(); + leakage_1 += getGenProperties()->get("INV1_LeakagePower_0").toDouble(); + + cache->set(cell_name + "->Leakage->!A", leakage_0); + cache->set(cell_name + "->Leakage->A", leakage_1); + Log::printLine(cell_name + "->Leakage->!A=" + (String) leakage_0); + Log::printLine(cell_name + "->Leakage->A=" + (String) leakage_1); + // -------------------------------------------------------------------- + + // -------------------------------------------------------------------- + // Get Node Capacitances + // -------------------------------------------------------------------- + double a_cap = getNet("A")->getTotalDownstreamCap(); + double y_b_cap = getNet("Y_b")->getTotalDownstreamCap(); + double y_cap = getNet("Y")->getTotalDownstreamCap(); + + cache->set(cell_name + "->Cap->A", a_cap); + cache->set(cell_name + "->Cap->Y_b", y_b_cap); + cache->set(cell_name + "->Cap->Y", y_cap); + Log::printLine(cell_name + "->Cap->A_Cap=" + (String) a_cap); + Log::printLine(cell_name + "->Cap->Y_b_Cap=" + (String) y_b_cap); + Log::printLine(cell_name + "->Cap->Y_Cap=" + (String) y_cap); + // -------------------------------------------------------------------- + + // -------------------------------------------------------------------- + // Build Internal Delay Model + // -------------------------------------------------------------------- + double y_ron = getDriver("INV1_RonZN")->getOutputRes(); + double a_to_y_delay = getDriver("INV0_RonZN")->calculateDelay() + + getDriver("INV1_RonZN")->calculateDelay(); + + cache->set(cell_name + "->DriveRes->Y", y_ron); + cache->set(cell_name + "->Delay->A_to_Y", a_to_y_delay); + Log::printLine(cell_name + "->DriveRes->Y=" + (String) y_ron); + Log::printLine(cell_name + "->Delay->A_to_Y=" + (String) a_to_y_delay); + // -------------------------------------------------------------------- + + return; + } +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/CellMacros.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/CellMacros.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_STD_CELLS_CELLMACROS_H__ +#define __DSENT_MODEL_STD_CELLS_CELLMACROS_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" + +namespace DSENT +{ + class StdCell; + + // Contains cell macros that can be created within standard cells + class CellMacros + { + private : + CellMacros(); + ~CellMacros(); + + public: + //NOR2 Macro + //Adds a NOR2 to the standard cell, normalized to some size + static void addNor2(StdCell* cell_, const String& name_, bool sizable_, bool a1_to_zn_path_, bool a2_to_zn_path_, + const String& a1_net_, const String& a2_net_, const String& zn_net_); + //Updates a NOR2 to to the standard cell, normalized to some size + static void updateNor2(StdCell* cell_, const String& name_, double normalized_size_); + + //NAND2 Macro + //Adds a NAND2 to the standard cell, normalized to some size + static void addNand2(StdCell* cell_, const String& name_, bool sizable_, bool a1_to_zn_path_, bool a2_to_zn_path_, + const String& a1_net_, const String& a2_net_, const String& zn_net_); + //Updates a NAND2 to to the standard cell, normalized to some size + static void updateNand2(StdCell* cell_, const String& name_, double normalized_size_); + + //INVERTER Macro + //Adds a inverter to the standard cell, normalized to some size + static void addInverter(StdCell* cell_, const String& name_, bool sizable_, bool a_to_zn_path_, + const String& a_net_, const String& zn_net_); + //Updates an inverter to to the standard cell, normalized to some size + static void updateInverter(StdCell* cell_, const String& name_, double normalized_size_); + + //INVZ Macro + //Adds a tristated inverter to the standard cell, normalized to some size + static void addTristate(StdCell* cell_, const String& name_, bool sizable_, bool a_to_zn_path_, bool oe_to_zn_path_, bool oen_to_zn_path_, + const String& a_net_, const String& oe_net_, const String& oen_net_, const String& zn_net_); + //Updates an tristated inverter to to the standard cell, normalized to some size + static void updateTristate(StdCell* cell_, const String& name_, double normalized_size_); + + //Helper functions + //Returns the width of NMOS transistors, given the NMOS and PMOS stacking + static double calculateNmosWidth(const StdCell* cell_, unsigned int max_stacked_nmos_, unsigned int max_stacked_pmos_, unsigned int current_stack_nmos_); + //Returns the width of PMOS transistors, given the NMOS and PMOS stacking + static double calculatePmosWidth(const StdCell* cell_, unsigned int max_stacked_nmos_, unsigned int max_stacked_pmos_, unsigned int current_stack_pmos_); + + }; // class CellMacros +} // namespace DSENT + +#endif // __DSENT_MODEL_STD_CELLS_CELLMACROS_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/CellMacros.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/CellMacros.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,508 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/CellMacros.hh" + +#include +#include + +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriver.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalLoad.hh" + +namespace DSENT +{ + //------------------------------------------------------------------------- + // NOR2 Macro (TODO: Generalize to N-input macro once leakage calc is done) + //------------------------------------------------------------------------- + void CellMacros::addNor2(StdCell* cell_, const String& name_, + bool sizable_, bool a1_to_zn_path_, bool a2_to_zn_path_, + const String& a1_net_, const String& a2_net_, const String& zn_net_) + { + //Create electrical timing model for the nand + // Construct loads and drivers + cell_->createLoad(name_ + "_CgA1"); + cell_->createLoad(name_ + "_CgA2"); + cell_->createLoad(name_ + "_CdZN"); + cell_->createDriver(name_ + "_RonZN", sizable_); + + //Get references to loads and drivers + ElectricalLoad* gate_a1_load = cell_->getLoad(name_ + "_CgA1"); + ElectricalLoad* gate_a2_load = cell_->getLoad(name_ + "_CgA2"); + ElectricalLoad* drain_load = cell_->getLoad(name_ + "_CdZN"); + ElectricalDriver* zn_drive = cell_->getDriver(name_ + "_RonZN"); + ElectricalNet* a1_net = cell_->getNet(a1_net_); + ElectricalNet* a2_net = cell_->getNet(a2_net_); + ElectricalNet* zn_net = cell_->getNet(zn_net_); + + //Add loads and drivers to the specified nets + a1_net->addDownstreamNode(gate_a1_load); + a2_net->addDownstreamNode(gate_a2_load); + zn_net->addDownstreamNode(drain_load); + if (a1_to_zn_path_) gate_a1_load->addDownstreamNode(zn_drive); + if (a2_to_zn_path_) gate_a2_load->addDownstreamNode(zn_drive); + zn_drive->addDownstreamNode(zn_net); + + return; + } + + void CellMacros::updateNor2(StdCell* cell_, const String& name_, double normalized_size_) + { + ASSERT(normalized_size_ >= 0.0, "[Error] " + cell_->getInstanceName() + + " -> Cannot update a macro with a negative normalized size!"); + + //Grab pointer to tech model + const TechModel* tech = cell_->getTechModel(); + + // Get technology parameters + double vdd = tech->get("Vdd"); + double gate_cap = tech->get("Gate->CapPerWidth"); + double drain_cap = tech->get("Drain->CapPerWidth"); + double nmos_eff_res = tech->get("Nmos->EffResWidth"); + double pmos_eff_res = tech->get("Pmos->EffResWidth"); + double pmos_eff_res_stack_ratio = tech->get("Pmos->EffResStackRatio"); + double gate_pitch_contacted = tech->get("Gate->PitchContacted"); + double metal1_wire_min_width = tech->get("Wire->Metal1->MinWidth"); + + //Calculate number of folds and gate pitches needed + unsigned int folds = (normalized_size_ < 1.0) ? 1 : (unsigned int)ceil(normalized_size_); + cell_->getGenProperties()->set(name_ + "_GatePitches", 2 * folds); + + //Calculate widths, making sure they are above the minimum width + double nmos_width = std::max(calculateNmosWidth(cell_, 1, 2, 1) * normalized_size_ / folds, (double) tech->get("Gate->MinWidth")); + double pmos_width = std::max(calculatePmosWidth(cell_, 1, 2, 2) * normalized_size_ / folds, (double) tech->get("Gate->MinWidth")); + + //Calculate leakage power for each given input state + double leakage_power_00 = vdd * folds * 2 * tech->calculateNmosLeakageCurrent(1, nmos_width, 0x0); + double leakage_power_01 = vdd * folds * tech->calculatePmosLeakageCurrent(2, pmos_width, ~0x1); + double leakage_power_10 = vdd * folds * tech->calculatePmosLeakageCurrent(2, pmos_width, ~0x2); + double leakage_power_11 = vdd * folds * tech->calculatePmosLeakageCurrent(2, pmos_width, ~0x3); + cell_->getGenProperties()->set(name_ + "_LeakagePower_00", leakage_power_00); + cell_->getGenProperties()->set(name_ + "_LeakagePower_01", leakage_power_01); + cell_->getGenProperties()->set(name_ + "_LeakagePower_10", leakage_power_10); + cell_->getGenProperties()->set(name_ + "_LeakagePower_11", leakage_power_11); + + //Calculate R_on and capacitances + double pmos_stack2_balance = 1.0 + pmos_eff_res_stack_ratio; + double c_g = (nmos_width + pmos_width) * gate_cap * folds; + double c_d = (2 * pmos_width + 2 * nmos_width) * drain_cap * folds; + double r_on = (nmos_eff_res / nmos_width + pmos_stack2_balance * pmos_eff_res / pmos_width) / (folds * 2.0); + + // Estimate the wire cap and add them all at the output + double cell_height = cell_->getTotalHeight(); + double wire_width = metal1_wire_min_width; + double wire_spacing = gate_pitch_contacted - metal1_wire_min_width; + double wire_length = 2.0 * folds * cell_height; + double wire_cap = tech->calculateWireCapacitance("Metal1", wire_width, wire_spacing, wire_length); + + // Construct equivalent load and drive strength + cell_->getLoad(name_ + "_CgA1")->setLoadCap(c_g); + cell_->getLoad(name_ + "_CgA2")->setLoadCap(c_g); + cell_->getLoad(name_ + "_CdZN")->setLoadCap(c_d + wire_cap); + cell_->getDriver(name_ + "_RonZN")->setOutputRes(r_on); + + // Calculate flip energies + double zn_flip_energy = 0.5 * (c_d + wire_cap) * vdd * vdd; + double a1_flip_energy = 0.5 * c_g * vdd * vdd; + double a2_flip_energy = 0.5 * c_g * vdd * vdd; + cell_->getGenProperties()->set(name_ + "_ZN_Flip", zn_flip_energy); + cell_->getGenProperties()->set(name_ + "_A1_Flip", a1_flip_energy); + cell_->getGenProperties()->set(name_ + "_A2_Flip", a2_flip_energy); + } + //------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + // NAND2 Macro (TODO: Generalize to N-input macro once leakage calc is done) + //------------------------------------------------------------------------- + //Adds a NAND2 to the standard cell, normalized to some size + void CellMacros::addNand2(StdCell* cell_, const String& name_, + bool sizable_, bool a1_to_zn_path_, bool a2_to_zn_path_, + const String& a1_net_, const String& a2_net_, const String& zn_net_) + { + //Create electrical timing model for the nor + // Construct loads and drivers + cell_->createLoad(name_ + "_CgA1"); + cell_->createLoad(name_ + "_CgA2"); + cell_->createLoad(name_ + "_CdZN"); + cell_->createDriver(name_ + "_RonZN", sizable_); + + //Get references to loads and drivers + ElectricalLoad* gate_a1_load = cell_->getLoad(name_ + "_CgA1"); + ElectricalLoad* gate_a2_load = cell_->getLoad(name_ + "_CgA2"); + ElectricalLoad* drain_load = cell_->getLoad(name_ + "_CdZN"); + ElectricalDriver* zn_drive = cell_->getDriver(name_ + "_RonZN"); + ElectricalNet* a1_net = cell_->getNet(a1_net_); + ElectricalNet* a2_net = cell_->getNet(a2_net_); + ElectricalNet* zn_net = cell_->getNet(zn_net_); + + a1_net->addDownstreamNode(gate_a1_load); + a2_net->addDownstreamNode(gate_a2_load); + zn_net->addDownstreamNode(drain_load); + if (a1_to_zn_path_) gate_a1_load->addDownstreamNode(zn_drive); + if (a2_to_zn_path_) gate_a2_load->addDownstreamNode(zn_drive); + zn_drive->addDownstreamNode(zn_net); + + return; + } + + //Updates a NAND2 to to the standard cell, normalized to some size + void CellMacros::updateNand2(StdCell* cell_, const String& name_, double normalized_size_) + { + ASSERT(normalized_size_ >= 0.0, "[Error] " + cell_->getInstanceName() + + " -> Cannot update a macro with a negative normalized size!"); + + //Grab pointer to tech model + const TechModel* tech = cell_->getTechModel(); + + // Get technology parameters + double vdd = tech->get("Vdd"); + double gate_cap = tech->get("Gate->CapPerWidth"); + double drain_cap = tech->get("Drain->CapPerWidth"); + double nmos_eff_res = tech->get("Nmos->EffResWidth"); + double pmos_eff_res = tech->get("Pmos->EffResWidth"); + double nmos_eff_res_stack_ratio = tech->get("Nmos->EffResStackRatio"); + double gate_pitch_contacted = tech->get("Gate->PitchContacted"); + double metal1_wire_min_width = tech->get("Wire->Metal1->MinWidth"); + + //Calculate number of folds needed + unsigned int folds = (normalized_size_ < 1.0) ? 1 : (unsigned int)ceil(normalized_size_); + cell_->getGenProperties()->set(name_ + "_GatePitches", 2 * folds); + + //Calculate widths, making sure they are above the minimum width + double nmos_width = std::max(calculateNmosWidth(cell_, 2, 1, 2) * normalized_size_ / folds, (double) tech->get("Gate->MinWidth")); + double pmos_width = std::max(calculatePmosWidth(cell_, 2, 1, 1) * normalized_size_ / folds, (double) tech->get("Gate->MinWidth")); + + // Leakage power calculation + double leakage_power_00 = vdd * folds * tech->calculateNmosLeakageCurrent(2, nmos_width, 0x0); + double leakage_power_01 = vdd * folds * tech->calculateNmosLeakageCurrent(2, nmos_width, 0x1); + double leakage_power_10 = vdd * folds * tech->calculateNmosLeakageCurrent(2, nmos_width, 0x2); + double leakage_power_11 = vdd * folds * 2 * tech->calculatePmosLeakageCurrent(1, pmos_width, ~0x3); + cell_->getGenProperties()->set(name_ + "_LeakagePower_00", leakage_power_00); + cell_->getGenProperties()->set(name_ + "_LeakagePower_01", leakage_power_01); + cell_->getGenProperties()->set(name_ + "_LeakagePower_10", leakage_power_10); + cell_->getGenProperties()->set(name_ + "_LeakagePower_11", leakage_power_11); + + // Get input parameters + double nmos_stack2_balance = 1.0 + nmos_eff_res_stack_ratio; + + //Calculate caps + double c_g = (nmos_width + pmos_width) * gate_cap * folds; + double c_d = (2 * pmos_width + 2 * nmos_width) * drain_cap * folds; + double r_on = (nmos_stack2_balance * nmos_eff_res / nmos_width + pmos_eff_res / pmos_width) / (folds * 2.0); + + // Estimate the wire cap and add them all at the output + double cell_height = cell_->getTotalHeight(); + double wire_width = metal1_wire_min_width; + double wire_spacing = gate_pitch_contacted - metal1_wire_min_width; + double wire_length = 2.0 * folds * cell_height; + double wire_cap = tech->calculateWireCapacitance("Metal1", wire_width, wire_spacing, wire_length); + + // Construct equivalent load and drive strength + cell_->getLoad(name_ + "_CgA1")->setLoadCap(c_g); + cell_->getLoad(name_ + "_CgA2")->setLoadCap(c_g); + cell_->getLoad(name_ + "_CdZN")->setLoadCap(c_d + wire_cap); + cell_->getDriver(name_ + "_RonZN")->setOutputRes(r_on); + + // Calculate flip energies + double zn_flip_energy = 0.5 * (c_d + wire_cap) * vdd * vdd; + double a1_flip_energy = 0.5 * c_g * vdd * vdd; + double a2_flip_energy = 0.5 * c_g * vdd * vdd; + cell_->getGenProperties()->set(name_ + "_ZN_Flip", zn_flip_energy); + cell_->getGenProperties()->set(name_ + "_A1_Flip", a1_flip_energy); + cell_->getGenProperties()->set(name_ + "_A2_Flip", a2_flip_energy); + } + //------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + // INV Macro + //------------------------------------------------------------------------- + //Adds an inverter to the model, normalized to some size + void CellMacros::addInverter(StdCell* cell_, const String& name_, + bool sizable_, bool a_to_zn_path_, + const String& a_net_, const String& zn_net_) + { + //Create electrical timing model for the inverter + // Construct loads and drivers + cell_->createLoad(name_ + "_CgA"); + cell_->createLoad(name_ + "_CdZN"); + cell_->createDriver(name_ + "_RonZN", sizable_); + + //Get references to loads and drivers + ElectricalLoad* gate_load = cell_->getLoad(name_ + "_CgA"); + ElectricalLoad* drain_load = cell_->getLoad(name_ + "_CdZN"); + ElectricalDriver* out_drive = cell_->getDriver(name_ + "_RonZN"); + ElectricalNet* a_net = cell_->getNet(a_net_); + ElectricalNet* zn_net = cell_->getNet(zn_net_); + + // Setup connectivity of loads and drivers + a_net->addDownstreamNode(gate_load); + if (a_to_zn_path_) gate_load->addDownstreamNode(out_drive); + zn_net->addDownstreamNode(drain_load); + out_drive->addDownstreamNode(zn_net); + + return; + } + + //Updates the numbers of an inverter for some normalized size + void CellMacros::updateInverter(StdCell* cell_, const String& name_, double normalized_size_) + { + ASSERT(normalized_size_ >= 0.0, "[Error] " + cell_->getInstanceName() + + " -> Cannot update a macro with a negative normalized size!"); + + //Grab pointer to tech model + const TechModel* tech = cell_->getTechModel(); + + //Get values from technology library + double vdd = tech->get("Vdd"); + double gate_cap = tech->get("Gate->CapPerWidth"); + double drain_cap = tech->get("Drain->CapPerWidth"); + double nmos_eff_res = tech->get("Nmos->EffResWidth"); + double pmos_eff_res = tech->get("Pmos->EffResWidth"); + double gate_pitch_contacted = tech->get("Gate->PitchContacted"); + double metal1_wire_min_width = tech->get("Wire->Metal1->MinWidth"); + + //Calculate number of folds needed + unsigned int folds = (normalized_size_ < 1.0) ? 1 : (unsigned int)ceil(normalized_size_); + cell_->getGenProperties()->set(name_ + "_GatePitches", folds); + + //Calculate widths, making sure they are above the minimum width + double nmos_width = std::max(calculateNmosWidth(cell_, 1, 1, 1) * normalized_size_ / folds, (double) tech->get("Gate->MinWidth")); + double pmos_width = std::max(calculatePmosWidth(cell_, 1, 1, 1) * normalized_size_ / folds, (double) tech->get("Gate->MinWidth")); + + //Calculate leakage power for each given input state + double leakage_power_0 = vdd * folds * tech->calculateNmosLeakageCurrent(1, nmos_width, 0x0); + double leakage_power_1 = vdd * folds * tech->calculatePmosLeakageCurrent(1, pmos_width, ~0x1); + cell_->getGenProperties()->set(name_ + "_LeakagePower_0", leakage_power_0); + cell_->getGenProperties()->set(name_ + "_LeakagePower_1", leakage_power_1); + + //Calculate caps + double c_g = (nmos_width + pmos_width) * gate_cap * folds; + double c_d = (pmos_width + nmos_width) * drain_cap * folds; + double r_on = (nmos_eff_res / nmos_width + pmos_eff_res / pmos_width) / (folds * 2.0); + + // Estimate the wire cap and add them all at the output + double cell_height = cell_->getTotalHeight(); + double wire_width = metal1_wire_min_width; + double wire_spacing = gate_pitch_contacted - metal1_wire_min_width; + double wire_length = folds * cell_height; + double wire_cap = tech->calculateWireCapacitance("Metal1", wire_width, wire_spacing, wire_length); + + // Construct equivalent load and drive strength + cell_->getLoad(name_ + "_CgA")->setLoadCap(c_g); + cell_->getLoad(name_ + "_CdZN")->setLoadCap(c_d + wire_cap); + cell_->getDriver(name_ + "_RonZN")->setOutputRes(r_on); + + // Calculate flip energy (output flip) + // Calculate flip energies + double zn_flip_energy = 0.5 * (c_d + wire_cap) * vdd * vdd; + double a_flip_energy = 0.5 * c_g * vdd * vdd; + cell_->getGenProperties()->set(name_ + "_ZN_Flip", zn_flip_energy); + cell_->getGenProperties()->set(name_ + "_A_Flip", a_flip_energy); + + return; + } + //------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + // INVZ Macro + //------------------------------------------------------------------------- + //Adds a tristated inverter to the model, normalized to some size + void CellMacros::addTristate(StdCell* cell_, const String& name_, + bool sizable_, bool a_to_zn_path_, bool oe_to_zn_path_, bool oen_to_zn_path_, + const String& a_net_, const String& oe_net_, const String& oen_net_, const String& zn_net_) + { + // Construct loads and drivers + cell_->createLoad(name_ + "_CgA"); + cell_->createLoad(name_ + "_CgOE"); + cell_->createLoad(name_ + "_CgOEN"); + cell_->createLoad(name_ + "_CdZN"); + cell_->createDriver(name_ + "_RonZN", sizable_); + + // Get references to loads, nets and drivers + ElectricalLoad* gate_a_load = cell_->getLoad(name_ + "_CgA"); + ElectricalLoad* gate_oe_load = cell_->getLoad(name_ + "_CgOE"); + ElectricalLoad* gate_oen_load = cell_->getLoad(name_ + "_CgOEN"); + ElectricalLoad* drain_load = cell_->getLoad(name_ + "_CdZN"); + ElectricalDriver* out_drive = cell_->getDriver(name_ + "_RonZN"); + ElectricalNet* a_net = cell_->getNet(a_net_); + ElectricalNet* oe_net = cell_->getNet(oe_net_); + ElectricalNet* oen_net = cell_->getNet(oen_net_); + ElectricalNet* zn_net = cell_->getNet(zn_net_); + + // Setup connectivity of loads and drivers + a_net->addDownstreamNode(gate_a_load); + oe_net->addDownstreamNode(gate_oe_load); + oen_net->addDownstreamNode(gate_oen_load); + if (a_to_zn_path_) gate_a_load->addDownstreamNode(out_drive); + if (oe_to_zn_path_) gate_oe_load->addDownstreamNode(out_drive); + if (oen_to_zn_path_) gate_oen_load->addDownstreamNode(out_drive); + zn_net->addDownstreamNode(drain_load); + out_drive->addDownstreamNode(zn_net); + + return; + } + + //Updates the numbers of an inverter for some normalized size + void CellMacros::updateTristate(StdCell* cell_, const String& name_, double normalized_size_) + { + ASSERT(normalized_size_ >= 0.0, "[Error] " + cell_->getInstanceName() + + " -> Cannot update a macro with a negative normalized size!"); + + //Grab pointer to tech model + const TechModel* tech = cell_->getTechModel(); + + //Get values from technology library + double vdd = tech->get("Vdd"); + double gate_cap = tech->get("Gate->CapPerWidth"); + double drain_cap = tech->get("Drain->CapPerWidth"); + double nmos_eff_res = tech->get("Nmos->EffResWidth"); + double pmos_eff_res = tech->get("Pmos->EffResWidth"); + double pmos_eff_res_stack_ratio = tech->get("Pmos->EffResStackRatio"); + double nmos_eff_res_stack_ratio = tech->get("Nmos->EffResStackRatio"); + double gate_pitch_contacted = tech->get("Gate->PitchContacted"); + double metal1_wire_min_width = tech->get("Wire->Metal1->MinWidth"); + + //Calculate number of folds and gate pitches needed + unsigned int folds = (normalized_size_ < 1.0) ? 1 : (unsigned int)ceil(normalized_size_); + cell_->getGenProperties()->set(name_ + "_GatePitches", 2 * folds); + + //Calculate widths, making sure they are above the minimum width + double nmos_width = std::max(calculateNmosWidth(cell_, 2, 2, 2) * normalized_size_ / folds, (double) tech->get("Gate->MinWidth")); + double pmos_width = std::max(calculatePmosWidth(cell_, 2, 2, 2) * normalized_size_ / folds, (double) tech->get("Gate->MinWidth")); + + //Calculate leakage power for each given input state + //if output_enable = 0, then it is possible that the PMOS may leak (if output = 0), + //or the NMOS will leak (if output = 1) + + //OE OEN A _ ZN + double leakage_power_010_0 = vdd * folds * tech->calculatePmosLeakageCurrent(2, pmos_width, ~0x2); + double leakage_power_010_1 = vdd * folds * tech->calculateNmosLeakageCurrent(2, nmos_width, 0x0); + double leakage_power_011_0 = vdd * folds * tech->calculatePmosLeakageCurrent(2, pmos_width, ~0x3); + double leakage_power_011_1 = vdd * folds * tech->calculateNmosLeakageCurrent(2, nmos_width, 0x1); + double leakage_power_100_1 = vdd * folds * tech->calculateNmosLeakageCurrent(2, nmos_width, 0x2); + double leakage_power_101_0 = vdd * folds * tech->calculatePmosLeakageCurrent(2, pmos_width, ~0x1); + cell_->getGenProperties()->set(name_ + "_LeakagePower_010_0", leakage_power_010_0); + cell_->getGenProperties()->set(name_ + "_LeakagePower_010_1", leakage_power_010_1); + cell_->getGenProperties()->set(name_ + "_LeakagePower_011_0", leakage_power_011_0); + cell_->getGenProperties()->set(name_ + "_LeakagePower_011_1", leakage_power_011_1); + cell_->getGenProperties()->set(name_ + "_LeakagePower_100_1", leakage_power_100_1); + cell_->getGenProperties()->set(name_ + "_LeakagePower_101_0", leakage_power_101_0); + + //Caculate stack balance + double pmos_stack2_balance = 1.0 + pmos_eff_res_stack_ratio; + double nmos_stack2_balance = 1.0 + nmos_eff_res_stack_ratio; + + //Calculate caps + double c_g_a = (nmos_width + pmos_width) * gate_cap * folds; + double c_g_oe = nmos_width * gate_cap * folds; + double c_g_oen = pmos_width * gate_cap * folds; + double c_d = (2 * pmos_width + 2 * nmos_width) * drain_cap * folds; + double r_on = (nmos_stack2_balance * nmos_eff_res / nmos_width + pmos_stack2_balance * pmos_eff_res / pmos_width) / (folds * 2.0); + + // Estimate the wire cap and add them all at the output + double cell_height = cell_->getTotalHeight(); + double wire_width = metal1_wire_min_width; + double wire_spacing = gate_pitch_contacted - metal1_wire_min_width; + double wire_length = 2.0 * folds * cell_height; + double wire_cap = tech->calculateWireCapacitance("Metal1", wire_width, wire_spacing, wire_length); + + // Construct equivalent load and drive strength + cell_->getLoad(name_ + "_CgA")->setLoadCap(c_g_a); + cell_->getLoad(name_ + "_CgOE")->setLoadCap(c_g_oe); + cell_->getLoad(name_ + "_CgOEN")->setLoadCap(c_g_oen); + cell_->getLoad(name_ + "_CdZN")->setLoadCap(c_d + wire_cap); + cell_->getDriver(name_ + "_RonZN")->setOutputRes(r_on); + + // Calculate flip energy (output flip) + double zn_flip_energy = 0.5 * (c_d + wire_cap) * vdd * vdd; + double a_flip_energy = 0.5 * c_g_a * vdd * vdd; + double oe_flip_energy = 0.5 * c_g_oe * vdd * vdd; + double oen_flip_energy = 0.5 * c_g_oen * vdd * vdd; + cell_->getGenProperties()->set(name_ + "_ZN_Flip", zn_flip_energy); + cell_->getGenProperties()->set(name_ + "_A_Flip", a_flip_energy); + cell_->getGenProperties()->set(name_ + "_OE_Flip", oe_flip_energy); + cell_->getGenProperties()->set(name_ + "_OEN_Flip", oen_flip_energy); + return; + } + //------------------------------------------------------------------------- + + + //------------------------------------------------------------------------- + // Helper Functions + //------------------------------------------------------------------------- + //Returns the width of NMOS transistors, given the NMOS and PMOS stacking + double CellMacros::calculateNmosWidth(const StdCell* cell_, unsigned int max_stacked_nmos_, unsigned int max_stacked_pmos_, unsigned int current_stacked_nmos_) + { + //Grab pointer to tech model + const TechModel* tech = cell_->getTechModel(); + + double nmos_eff_res_stack_ratio = tech->get("Nmos->EffResStackRatio"); + double pmos_eff_res_stack_ratio = tech->get("Pmos->EffResStackRatio"); + + double nmos_stack_balance = 1.0 + nmos_eff_res_stack_ratio * (double) (max_stacked_nmos_ - 1); + double pmos_stack_balance = 1.0 + pmos_eff_res_stack_ratio * (double) (max_stacked_pmos_ - 1); + double current_nmos_stack_balance = 1.0 + nmos_eff_res_stack_ratio * (double) (current_stacked_nmos_ - 1); + + double pn_ratio = cell_->getPToNRatio(); + double active_height = cell_->getActiveHeight(); + + //Calculate the width of the current device + double nmos_width = active_height * current_nmos_stack_balance / (nmos_stack_balance + pn_ratio * pmos_stack_balance); + + return nmos_width; + } + + //Returns the width of PMOS transistors, given the NMOS and PMOS stacking + double CellMacros::calculatePmosWidth(const StdCell* cell_, unsigned int max_stacked_nmos_, unsigned int max_stacked_pmos_, unsigned int current_stacked_pmos_) + { + //Grab pointer to tech model + const TechModel* tech = cell_->getTechModel(); + + double nmos_eff_res_stack_ratio = tech->get("Nmos->EffResStackRatio"); + double pmos_eff_res_stack_ratio = tech->get("Pmos->EffResStackRatio"); + + double nmos_stack_balance = 1.0 + nmos_eff_res_stack_ratio * (double) (max_stacked_nmos_ - 1); + double pmos_stack_balance = 1.0 + pmos_eff_res_stack_ratio * (double) (max_stacked_pmos_ - 1); + double current_pmos_stack_balance = 1.0 + pmos_eff_res_stack_ratio * (double) (current_stacked_pmos_ - 1); + + double pn_ratio = cell_->getPToNRatio(); + double active_height = cell_->getActiveHeight(); + + //Calculate the width of the current device + double pmos_width = active_height * current_pmos_stack_balance * pn_ratio / (nmos_stack_balance + pn_ratio * pmos_stack_balance); + + return pmos_width; + } + //------------------------------------------------------------------------- + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/DFFQ.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/DFFQ.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_STD_CELLS_DFFQ_H__ +#define __DSENT_MODEL_STD_CELLS_DFFQ_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" + +namespace DSENT +{ + class DFFQ : public StdCell + { + // A DQ flip-flop + public: + DFFQ(const String& instance_name_, const TechModel* tech_model_); + virtual ~DFFQ(); + + public: + // Set a list of properties' name needed to construct model + void initProperties(); + // Cache the standard cell + void cacheStdCell(StdCellLib* cell_lib_, double drive_strength_); + + private: + TransitionInfo m_trans_M_; + + protected: + // Build the model + virtual void constructModel(); + virtual void updateModel(); + virtual void evaluateModel(); + virtual void useModel(); + virtual void propagateTransitionInfo(); + + }; // class DFFQ +} // namespace DSENT + +#endif // __DSENT_MODEL_STD_CELLS_INV_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/DFFQ.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/DFFQ.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,567 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/DFFQ.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/CellMacros.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriver.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalLoad.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDelay.hh" + +namespace DSENT +{ + using std::ceil; + using std::max; + using std::min; + + DFFQ::DFFQ(const String& instance_name_, const TechModel* tech_model_) + : StdCell(instance_name_, tech_model_) + { + initProperties(); + } + + DFFQ::~DFFQ() + {} + + void DFFQ::initProperties() + { + return; + } + + void DFFQ::constructModel() + { + // All constructModel should do is create Area/NDDPower/Energy Results as + // well as instantiate any sub-instances using only the hard parameters + + createInputPort("D"); + createInputPort("CK"); + createOutputPort("Q"); + + createLoad("D_Cap"); + createLoad("CK_Cap"); + createDelay("D_Setup_delay"); + createDelay("CK_to_Q_delay"); + createDriver("Q_Ron", true); + + ElectricalLoad* d_cap = getLoad("D_Cap"); + ElectricalLoad* ck_cap = getLoad("CK_Cap"); + ElectricalDelay* d_setup_delay = getDelay("D_Setup_delay"); + ElectricalDelay* ck_to_q_delay = getDelay("CK_to_Q_delay"); + ElectricalDriver* q_ron = getDriver("Q_Ron"); + + getNet("D")->addDownstreamNode(d_cap); + getNet("CK")->addDownstreamNode(ck_cap); + d_cap->addDownstreamNode(d_setup_delay); + ck_cap->addDownstreamNode(ck_to_q_delay); + ck_to_q_delay->addDownstreamNode(q_ron); + q_ron->addDownstreamNode(getNet("Q")); + + // Create Area result + // Create NDD Power result + createElectricalAtomicResults(); + // Create CK Event Energy Result + createElectricalEventAtomicResult("CK"); + getEventInfo("CK")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); + // Create DFF Event Energy Result + createElectricalEventAtomicResult("DFFD"); + getEventInfo("DFFD")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); + createElectricalEventAtomicResult("DFFQ"); + getEventInfo("DFFQ")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); + + // Update Idle event for leakage + // CK pin is assumed to be on all the time + EventInfo* idle_event_info = getEventInfo("Idle"); + idle_event_info->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); + idle_event_info->setTransitionInfo("D", TransitionInfo(0.5, 0.0, 0.5)); + + return; + } + + void DFFQ::updateModel() + { + // Get parameters + double drive_strength = getDrivingStrength(); + Map* cache = getTechModel()->getStdCellLib()->getStdCellCache(); + + // Standard cell cache string + String cell_name = "DFFQ_X" + (String) drive_strength; + + // Get timing parameters + getLoad("D_Cap")->setLoadCap(cache->get(cell_name + "->Cap->D")); + getLoad("CK_Cap")->setLoadCap(cache->get(cell_name + "->Cap->CK")); + getDriver("Q_Ron")->setOutputRes(cache->get(cell_name + "->DriveRes->Q")); + getDelay("CK_to_Q_delay")->setDelay(cache->get(cell_name + "->Delay->CK_to_Q")); + getDelay("D_Setup_delay")->setDelay(cache->get(cell_name + "->Delay->D_Setup")); + + // Set the cell area + getAreaResult("Active")->setValue(cache->get(cell_name + "->Area->Active")); + getAreaResult("Metal1Wire")->setValue(cache->get(cell_name + "->Area->Metal1Wire")); + + return; + } + + void DFFQ::evaluateModel() + { + return; + } + + void DFFQ::useModel() + { + // Get parameters + double drive_strength = getDrivingStrength(); + Map* cache = getTechModel()->getStdCellLib()->getStdCellCache(); + + // Standard cell cache string + String cell_name = "DFFQ_X" + (String) drive_strength; + + // Propagate the transition info and get P_D, P_M, and P_Q + propagateTransitionInfo(); + double P_D = getInputPort("D")->getTransitionInfo().getProbability1(); + double P_CK = getInputPort("CK")->getTransitionInfo().getProbability1(); + double P_Q = getOutputPort("Q")->getTransitionInfo().getProbability1(); + double CK_num_trans_01 = getInputPort("CK")->getTransitionInfo().getNumberTransitions01(); + double D_num_trans_01 = getInputPort("D")->getTransitionInfo().getNumberTransitions01(); + double M_num_trans_01 = m_trans_M_.getNumberTransitions01(); + double Q_num_trans_01 = getOutputPort("Q")->getTransitionInfo().getNumberTransitions01(); + + // Calculate leakage + double leakage = 0; + leakage += cache->get(cell_name + "->Leakage->!D!CK!Q") * (1 - P_D) * (1 - P_CK) * (1 - P_Q); + leakage += cache->get(cell_name + "->Leakage->!D!CKQ") * (1 - P_D) * (1 - P_CK) * P_Q; + leakage += cache->get(cell_name + "->Leakage->!DCK!Q") * (1 - P_D) * P_CK * (1 - P_Q); + leakage += cache->get(cell_name + "->Leakage->!DCKQ") * (1 - P_D) * P_CK * P_Q; + leakage += cache->get(cell_name + "->Leakage->D!CK!Q") * P_D * (1 - P_CK) * (1 - P_Q); + leakage += cache->get(cell_name + "->Leakage->D!CKQ") * P_D * (1 - P_CK) * P_Q; + leakage += cache->get(cell_name + "->Leakage->DCK!Q") * P_D * P_CK * (1 - P_Q); + leakage += cache->get(cell_name + "->Leakage->DCKQ") * P_D * P_CK * P_Q; + getNddPowerResult("Leakage")->setValue(leakage); + + // Get VDD + double vdd = getTechModel()->get("Vdd"); + + // Get capacitances + double ck_b_cap = cache->get(cell_name + "->Cap->CK_b"); + double ck_i_cap = cache->get(cell_name + "->Cap->CK_i"); + double d_b_cap = cache->get(cell_name + "->Cap->D_b"); + double m_b_cap = cache->get(cell_name + "->Cap->M_b"); + double m_cap = cache->get(cell_name + "->Cap->M"); + double m_i_cap = cache->get(cell_name + "->Cap->M_i"); + double q_b_cap = cache->get(cell_name + "->Cap->Q_b"); + double q_cap = cache->get(cell_name + "->Cap->Q"); + double q_load_cap = getNet("Q")->getTotalDownstreamCap(); + + // Calculate CK Event energy + double ck_event_energy = 0.0; + ck_event_energy += (ck_b_cap + ck_i_cap) * CK_num_trans_01; + ck_event_energy *= vdd * vdd; + getEventResult("CK")->setValue(ck_event_energy); + // Calculate DFFD Event energy + double dffd_event_energy = 0.0; + dffd_event_energy += (d_b_cap) * D_num_trans_01; + dffd_event_energy += (m_b_cap + m_cap) * M_num_trans_01; + dffd_event_energy *= vdd * vdd; + getEventResult("DFFD")->setValue(dffd_event_energy); + // Calculate DFFQ Event energy + double dffq_event_energy = 0.0; + dffq_event_energy += (m_i_cap + q_b_cap + q_cap + q_load_cap) * Q_num_trans_01; + dffq_event_energy *= vdd * vdd; + getEventResult("DFFQ")->setValue(dffq_event_energy); + + return; + } + + void DFFQ::propagateTransitionInfo() + { + const TransitionInfo& trans_CK = getInputPort("CK")->getTransitionInfo(); + const TransitionInfo& trans_D = getInputPort("D")->getTransitionInfo(); + + double CK_num_trans_01 = trans_CK.getNumberTransitions01(); + double CK_num_trans_10 = CK_num_trans_01; + double CK_num_trans_00 = trans_CK.getNumberTransitions00(); + double D_freq_mult = trans_D.getFrequencyMultiplier(); + + // If thre is no activity on the clock or D, assume M node is randomly distributed among 0 and 1 + if(LibUtil::Math::isEqual(CK_num_trans_10 + CK_num_trans_00, 0.0) || LibUtil::Math::isEqual(D_freq_mult, 0.0)) + { + m_trans_M_ = TransitionInfo(0.5, 0.0, 0.5); + } + // If the master latch is sampling just as fast or faster than input data signal + // Then it can capture all transitions (though it should be normalized to clock) + else if((CK_num_trans_10 + CK_num_trans_00) >= D_freq_mult) + { + m_trans_M_ = trans_D.scaleFrequencyMultiplier(CK_num_trans_10 + CK_num_trans_00); + } + // If the master latch is sampling slower than the input data signal, then input + // will look like they transition more + else + { + // Calculate scale ratio + double scale_ratio = (CK_num_trans_10 + CK_num_trans_00) / D_freq_mult; + // 00 and 11 transitions become fewer + double D_scaled_diff = 0.5 * (1 - scale_ratio) * (trans_D.getNumberTransitions00() + trans_D.getNumberTransitions11()); + double D_scaled_num_trans_00 = trans_D.getNumberTransitions00() * scale_ratio; + double D_scaled_num_trans_11 = trans_D.getNumberTransitions11() * scale_ratio; + // 01 and 10 transitions become more frequent + double D_scaled_num_trans_10 = trans_D.getNumberTransitions01() + D_scaled_diff; + + // Create final transition info, remembering to apply scaling ratio to normalize to CK + m_trans_M_ = TransitionInfo(D_scaled_num_trans_00 * scale_ratio, + D_scaled_num_trans_10 * scale_ratio, + D_scaled_num_trans_11 * scale_ratio); + } + + // If the clock activity is 0 or if D activity is 0, then we assume that the output is randomly distributed among 0 and 1 + if(LibUtil::Math::isEqual(CK_num_trans_01, 0.0) || LibUtil::Math::isEqual(D_freq_mult, 0.0)) + { + getOutputPort("Q")->setTransitionInfo(TransitionInfo(0.5, 0.0, 0.5)); + } + // If the DFF's CK is running at a higher frequency than D, Q is just D with a + // scaled up frequency multiplier + else if(CK_num_trans_01 >= D_freq_mult) + { + const TransitionInfo& trans_Q = trans_D.scaleFrequencyMultiplier(CK_num_trans_01); + getOutputPort("Q")->setTransitionInfo(trans_Q); + } + // If the DFF is sampling slower than the input data signal, then inputs + // will look like they transition more + else + { + // Calculate scale ratio + double scale_ratio = CK_num_trans_01 / D_freq_mult; + // 00 and 11 transitions become fewer + double D_scaled_diff = 0.5 * (1 - scale_ratio) * (trans_D.getNumberTransitions00() + trans_D.getNumberTransitions11()); + double D_scaled_num_trans_00 = trans_D.getNumberTransitions00() * scale_ratio; + double D_scaled_num_trans_11 = trans_D.getNumberTransitions11() * scale_ratio; + // 01 and 10 transitions become more frequent + double D_scaled_num_trans_10 = trans_D.getNumberTransitions01() + D_scaled_diff; + const TransitionInfo trans_Q( D_scaled_num_trans_00 * scale_ratio, + D_scaled_num_trans_10 * scale_ratio, + D_scaled_num_trans_11 * scale_ratio); + getOutputPort("Q")->setTransitionInfo(trans_Q); + } + return; + } + + // Creates the standard cell, characterizes and abstracts away the details + void DFFQ::cacheStdCell(StdCellLib* cell_lib_, double drive_strength_) + { + // Get parameters + double gate_pitch = cell_lib_->getTechModel()->get("Gate->PitchContacted"); + Map* cache = cell_lib_->getStdCellCache(); + + // Standard cell cache string + String cell_name = "DFFQ_X" + (String) drive_strength_; + + Log::printLine("=== " + cell_name + " ==="); + + + // Now actually build the full standard cell model + createInputPort("D"); + createInputPort("CK"); + createOutputPort("Q"); + + createNet("D_b"); + createNet("M_b"); + createNet("M"); + createNet("M_i"); + createNet("Q_b"); + createNet("CK_b"); + createNet("CK_i"); + + // Adds macros + CellMacros::addInverter(this, "INV1", false, true, "D", "D_b"); + CellMacros::addInverter(this, "INV2", false, true, "M_b", "M"); + CellMacros::addInverter(this, "INV3", false, true, "M_i", "Q_b"); + CellMacros::addInverter(this, "INV4", true, true, "Q_b", "Q"); + CellMacros::addInverter(this, "INV5", false, true, "CK", "CK_b"); + CellMacros::addInverter(this, "INV6", false, true, "CK_b", "CK_i"); + CellMacros::addTristate(this, "INVZ1", false, true, false, false, "D_b", "CK_b", "CK_i", "M_b"); //trace timing through A->ZN path only + CellMacros::addTristate(this, "INVZ2", false, false, false, false, "M", "CK_i", "CK_b", "M_b"); //don't trace timing through the feedback path + CellMacros::addTristate(this, "INVZ3", false, false, true, true, "M", "CK_i", "CK_b", "M_i"); //trace timing from OE->ZN and OEN->ZN paths only + CellMacros::addTristate(this, "INVZ4", false, false, false, false, "Q_b", "CK_b", "CK_i", "M_i"); //don't trace timing through the feedback path + + // Update macros + CellMacros::updateInverter(this, "INV1", drive_strength_ * 0.125); + CellMacros::updateInverter(this, "INV2", drive_strength_ * 0.5); + CellMacros::updateInverter(this, "INV3", drive_strength_ * 0.5); + CellMacros::updateInverter(this, "INV4", drive_strength_ * 1.0); + CellMacros::updateInverter(this, "INV5", drive_strength_ * 0.125); + CellMacros::updateInverter(this, "INV6", drive_strength_ * 0.125); + CellMacros::updateTristate(this, "INVZ1", drive_strength_ * 0.5); + CellMacros::updateTristate(this, "INVZ2", drive_strength_ * 0.0625); + CellMacros::updateTristate(this, "INVZ3", drive_strength_ * 0.5); + CellMacros::updateTristate(this, "INVZ4", drive_strength_ * 0.0625); + + // Cache area result + double area = 0.0; + area += gate_pitch * getTotalHeight() * 1; + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV1_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV2_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV3_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV4_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV5_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV6_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INVZ1_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INVZ2_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INVZ3_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INVZ4_GatePitches").toDouble(); + cache->set(cell_name + "->Area->Active", area); + cache->set(cell_name + "->Area->Metal1Wire", area); + Log::printLine(cell_name + "->Area->Active=" + (String) area); + Log::printLine(cell_name + "->Area->Metal1Wire=" + (String) area); + + // -------------------------------------------------------------------- + // Leakage Model Calculation + // -------------------------------------------------------------------- + // Cache leakage power results (for every single signal combination) + double leakage_000 = 0; //!D, !CK, !Q + double leakage_001 = 0; //!D, !CK, Q + double leakage_010 = 0; //!D, CK, !Q + double leakage_011 = 0; //!D, CK, Q + double leakage_100 = 0; //D, !CK, !Q + double leakage_101 = 0; //D, !CK, Q + double leakage_110 = 0; //D, CK, !Q + double leakage_111 = 0; //D, CK, Q + + //This is so painful... + leakage_000 += getGenProperties()->get("INV1_LeakagePower_0").toDouble(); + leakage_000 += getGenProperties()->get("INV2_LeakagePower_0").toDouble(); + leakage_000 += getGenProperties()->get("INV3_LeakagePower_0").toDouble(); + leakage_000 += getGenProperties()->get("INV4_LeakagePower_1").toDouble(); + leakage_000 += getGenProperties()->get("INV5_LeakagePower_0").toDouble(); + leakage_000 += getGenProperties()->get("INV6_LeakagePower_1").toDouble(); + leakage_000 += getGenProperties()->get("INVZ1_LeakagePower_101_0").toDouble(); + leakage_000 += getGenProperties()->get("INVZ2_LeakagePower_011_0").toDouble(); + leakage_000 += getGenProperties()->get("INVZ3_LeakagePower_011_0").toDouble(); + leakage_000 += getGenProperties()->get("INVZ4_LeakagePower_101_0").toDouble(); + + leakage_001 += getGenProperties()->get("INV1_LeakagePower_0").toDouble(); + leakage_001 += getGenProperties()->get("INV2_LeakagePower_0").toDouble(); + leakage_001 += getGenProperties()->get("INV3_LeakagePower_1").toDouble(); + leakage_001 += getGenProperties()->get("INV4_LeakagePower_0").toDouble(); + leakage_001 += getGenProperties()->get("INV5_LeakagePower_0").toDouble(); + leakage_001 += getGenProperties()->get("INV6_LeakagePower_1").toDouble(); + leakage_001 += getGenProperties()->get("INVZ1_LeakagePower_101_0").toDouble(); + leakage_001 += getGenProperties()->get("INVZ2_LeakagePower_011_0").toDouble(); + leakage_001 += getGenProperties()->get("INVZ3_LeakagePower_011_1").toDouble(); + leakage_001 += getGenProperties()->get("INVZ4_LeakagePower_100_1").toDouble(); + + leakage_010 += getGenProperties()->get("INV1_LeakagePower_0").toDouble(); + leakage_010 += getGenProperties()->get("INV2_LeakagePower_0").toDouble(); + leakage_010 += getGenProperties()->get("INV3_LeakagePower_0").toDouble(); + leakage_010 += getGenProperties()->get("INV4_LeakagePower_1").toDouble(); + leakage_010 += getGenProperties()->get("INV5_LeakagePower_1").toDouble(); + leakage_010 += getGenProperties()->get("INV6_LeakagePower_0").toDouble(); + leakage_010 += getGenProperties()->get("INVZ1_LeakagePower_011_0").toDouble(); + leakage_010 += getGenProperties()->get("INVZ2_LeakagePower_101_0").toDouble(); + leakage_010 += getGenProperties()->get("INVZ3_LeakagePower_101_0").toDouble(); + leakage_010 += getGenProperties()->get("INVZ4_LeakagePower_011_0").toDouble(); + + leakage_011 += getGenProperties()->get("INV1_LeakagePower_0").toDouble(); + leakage_011 += getGenProperties()->get("INV2_LeakagePower_1").toDouble(); + leakage_011 += getGenProperties()->get("INV3_LeakagePower_1").toDouble(); + leakage_011 += getGenProperties()->get("INV4_LeakagePower_0").toDouble(); + leakage_011 += getGenProperties()->get("INV5_LeakagePower_1").toDouble(); + leakage_011 += getGenProperties()->get("INV6_LeakagePower_0").toDouble(); + leakage_011 += getGenProperties()->get("INVZ1_LeakagePower_011_1").toDouble(); + leakage_011 += getGenProperties()->get("INVZ2_LeakagePower_100_1").toDouble(); + leakage_011 += getGenProperties()->get("INVZ3_LeakagePower_100_1").toDouble(); + leakage_011 += getGenProperties()->get("INVZ4_LeakagePower_010_1").toDouble(); + + leakage_100 += getGenProperties()->get("INV1_LeakagePower_1").toDouble(); + leakage_100 += getGenProperties()->get("INV2_LeakagePower_1").toDouble(); + leakage_100 += getGenProperties()->get("INV3_LeakagePower_0").toDouble(); + leakage_100 += getGenProperties()->get("INV4_LeakagePower_1").toDouble(); + leakage_100 += getGenProperties()->get("INV5_LeakagePower_0").toDouble(); + leakage_100 += getGenProperties()->get("INV6_LeakagePower_1").toDouble(); + leakage_100 += getGenProperties()->get("INVZ1_LeakagePower_100_1").toDouble(); + leakage_100 += getGenProperties()->get("INVZ2_LeakagePower_010_1").toDouble(); + leakage_100 += getGenProperties()->get("INVZ3_LeakagePower_010_0").toDouble(); + leakage_100 += getGenProperties()->get("INVZ4_LeakagePower_101_0").toDouble(); + + leakage_101 += getGenProperties()->get("INV1_LeakagePower_1").toDouble(); + leakage_101 += getGenProperties()->get("INV2_LeakagePower_1").toDouble(); + leakage_101 += getGenProperties()->get("INV3_LeakagePower_1").toDouble(); + leakage_101 += getGenProperties()->get("INV4_LeakagePower_0").toDouble(); + leakage_101 += getGenProperties()->get("INV5_LeakagePower_0").toDouble(); + leakage_101 += getGenProperties()->get("INV6_LeakagePower_1").toDouble(); + leakage_101 += getGenProperties()->get("INVZ1_LeakagePower_100_1").toDouble(); + leakage_101 += getGenProperties()->get("INVZ2_LeakagePower_010_1").toDouble(); + leakage_101 += getGenProperties()->get("INVZ3_LeakagePower_010_1").toDouble(); + leakage_101 += getGenProperties()->get("INVZ4_LeakagePower_100_1").toDouble(); + + leakage_110 += getGenProperties()->get("INV1_LeakagePower_1").toDouble(); + leakage_110 += getGenProperties()->get("INV2_LeakagePower_0").toDouble(); + leakage_110 += getGenProperties()->get("INV3_LeakagePower_0").toDouble(); + leakage_110 += getGenProperties()->get("INV4_LeakagePower_1").toDouble(); + leakage_110 += getGenProperties()->get("INV5_LeakagePower_1").toDouble(); + leakage_110 += getGenProperties()->get("INV6_LeakagePower_0").toDouble(); + leakage_110 += getGenProperties()->get("INVZ1_LeakagePower_010_0").toDouble(); + leakage_110 += getGenProperties()->get("INVZ2_LeakagePower_101_0").toDouble(); + leakage_110 += getGenProperties()->get("INVZ3_LeakagePower_101_0").toDouble(); + leakage_110 += getGenProperties()->get("INVZ4_LeakagePower_011_0").toDouble(); + + leakage_111 += getGenProperties()->get("INV1_LeakagePower_1").toDouble(); + leakage_111 += getGenProperties()->get("INV2_LeakagePower_1").toDouble(); + leakage_111 += getGenProperties()->get("INV3_LeakagePower_1").toDouble(); + leakage_111 += getGenProperties()->get("INV4_LeakagePower_0").toDouble(); + leakage_111 += getGenProperties()->get("INV5_LeakagePower_1").toDouble(); + leakage_111 += getGenProperties()->get("INV6_LeakagePower_0").toDouble(); + leakage_111 += getGenProperties()->get("INVZ1_LeakagePower_010_1").toDouble(); + leakage_111 += getGenProperties()->get("INVZ2_LeakagePower_100_1").toDouble(); + leakage_111 += getGenProperties()->get("INVZ3_LeakagePower_100_1").toDouble(); + leakage_111 += getGenProperties()->get("INVZ4_LeakagePower_010_1").toDouble(); + + cache->set(cell_name + "->Leakage->!D!CK!Q", leakage_000); + cache->set(cell_name + "->Leakage->!D!CKQ", leakage_001); + cache->set(cell_name + "->Leakage->!DCK!Q", leakage_010); + cache->set(cell_name + "->Leakage->!DCKQ", leakage_011); + cache->set(cell_name + "->Leakage->D!CK!Q", leakage_100); + cache->set(cell_name + "->Leakage->D!CKQ", leakage_101); + cache->set(cell_name + "->Leakage->DCK!Q", leakage_110); + cache->set(cell_name + "->Leakage->DCKQ", leakage_111); + Log::printLine(cell_name + "->Leakage->!D!CK!Q=" + (String) leakage_000); + Log::printLine(cell_name + "->Leakage->!D!CKQ=" + (String) leakage_001); + Log::printLine(cell_name + "->Leakage->!DCK!Q=" + (String) leakage_010); + Log::printLine(cell_name + "->Leakage->!DCKQ=" + (String) leakage_011); + Log::printLine(cell_name + "->Leakage->D!CK!Q=" + (String) leakage_100); + Log::printLine(cell_name + "->Leakage->D!CKQ=" + (String) leakage_101); + Log::printLine(cell_name + "->Leakage->DCK!Q=" + (String) leakage_110); + Log::printLine(cell_name + "->Leakage->DCKQ=" + (String) leakage_111); + // -------------------------------------------------------------------- + + /* + // Cache event energy results + double event_ck_flip = 0.0; + event_ck_flip += getGenProperties()->get("INV5_A_Flip").toDouble() + getGenProperties()->get("INV5_ZN_Flip").toDouble(); + event_ck_flip += getGenProperties()->get("INV6_A_Flip").toDouble() + getGenProperties()->get("INV6_ZN_Flip").toDouble(); + event_ck_flip += getGenProperties()->get("INVZ1_OE_Flip").toDouble() + getGenProperties()->get("INVZ1_OEN_Flip").toDouble(); + event_ck_flip += getGenProperties()->get("INVZ2_OE_Flip").toDouble() + getGenProperties()->get("INVZ2_OEN_Flip").toDouble(); + event_ck_flip += getGenProperties()->get("INVZ3_OE_Flip").toDouble() + getGenProperties()->get("INVZ3_OEN_Flip").toDouble(); + event_ck_flip += getGenProperties()->get("INVZ4_OE_Flip").toDouble() + getGenProperties()->get("INVZ4_OEN_Flip").toDouble(); + cache->set(cell_name + "->Event_CK_Flip", event_ck_flip); + Log::printLine(cell_name + "->Event_CK_Flip=" + (String) event_ck_flip); + + // Update D flip results + double event_d_flip = 0.0; + event_d_flip += getGenProperties()->get("INV1_A_Flip").toDouble() + getGenProperties()->get("INV1_ZN_Flip").toDouble(); + event_d_flip += getGenProperties()->get("INVZ1_A_Flip").toDouble(); + cache->set(cell_name + "->Event_D_Flip", event_d_flip); + Log::printLine(cell_name + "->Event_D_Flip=" + (String) event_d_flip); + // Update M flip results + double event_m_flip = 0.0; + event_m_flip += getGenProperties()->get("INVZ1_ZN_Flip").toDouble(); + event_m_flip += getGenProperties()->get("INV2_A_Flip").toDouble() + getGenProperties()->get("INV2_ZN_Flip").toDouble(); + event_m_flip += getGenProperties()->get("INVZ2_A_Flip").toDouble() + getGenProperties()->get("INVZ2_ZN_Flip").toDouble(); + event_m_flip += getGenProperties()->get("INVZ3_A_Flip").toDouble(); + cache->set(cell_name + "->Event_M_Flip", event_m_flip); + Log::printLine(cell_name + "->Event_M_Flip=" + (String) event_m_flip); + // Update Q flip results + double event_q_flip = 0.0; + event_q_flip += getGenProperties()->get("INVZ3_ZN_Flip").toDouble(); + event_q_flip += getGenProperties()->get("INV3_A_Flip").toDouble() + getGenProperties()->get("INV3_ZN_Flip").toDouble(); + event_q_flip += getGenProperties()->get("INVZ4_A_Flip").toDouble() + getGenProperties()->get("INVZ4_ZN_Flip").toDouble(); + event_q_flip += getGenProperties()->get("INV4_A_Flip").toDouble() + getGenProperties()->get("INV4_ZN_Flip").toDouble(); + cache->set(cell_name + "->Event_Q_Flip", event_q_flip); + Log::printLine(cell_name + "->Event_Q_Flip=" + (String) event_q_flip); + */ + + // -------------------------------------------------------------------- + // Get Node Capacitances + // -------------------------------------------------------------------- + double d_cap = getNet("D")->getTotalDownstreamCap(); + double d_b_cap = getNet("D_b")->getTotalDownstreamCap(); + double m_b_cap = getNet("M_b")->getTotalDownstreamCap(); + double m_cap = getNet("M")->getTotalDownstreamCap(); + double m_i_cap = getNet("M_i")->getTotalDownstreamCap(); + double q_b_cap = getNet("Q_b")->getTotalDownstreamCap(); + double q_cap = getNet("Q")->getTotalDownstreamCap(); + double ck_cap = getNet("CK")->getTotalDownstreamCap(); + double ck_b_cap = getNet("CK_b")->getTotalDownstreamCap(); + double ck_i_cap = getNet("CK_i")->getTotalDownstreamCap(); + + cache->set(cell_name + "->Cap->D", d_cap); + cache->set(cell_name + "->Cap->D_b", d_b_cap); + cache->set(cell_name + "->Cap->M_b", m_b_cap); + cache->set(cell_name + "->Cap->M", m_cap); + cache->set(cell_name + "->Cap->M_i", m_i_cap); + cache->set(cell_name + "->Cap->Q_b", q_b_cap); + cache->set(cell_name + "->Cap->Q", q_cap); + cache->set(cell_name + "->Cap->CK", ck_cap); + cache->set(cell_name + "->Cap->CK_b", ck_b_cap); + cache->set(cell_name + "->Cap->CK_i", ck_i_cap); + + Log::printLine(cell_name + "->Cap->D=" + (String) d_cap); + Log::printLine(cell_name + "->Cap->D_b=" + (String) d_b_cap); + Log::printLine(cell_name + "->Cap->M_b=" + (String) m_b_cap); + Log::printLine(cell_name + "->Cap->M=" + (String) m_cap); + Log::printLine(cell_name + "->Cap->M_i=" + (String) m_i_cap); + Log::printLine(cell_name + "->Cap->Q_b=" + (String) q_b_cap); + Log::printLine(cell_name + "->Cap->Q=" + (String) q_cap); + Log::printLine(cell_name + "->Cap->CK=" + (String) ck_cap); + Log::printLine(cell_name + "->Cap->CK_b=" + (String) ck_b_cap); + Log::printLine(cell_name + "->Cap->CK_i=" + (String) ck_i_cap); + // -------------------------------------------------------------------- + + // -------------------------------------------------------------------- + // Build Internal Delay Model + // -------------------------------------------------------------------- + double q_ron = getDriver("INV4_RonZN")->getOutputRes(); + + double d_setup_delay = getDriver("INV1_RonZN")->calculateDelay() + + getDriver("INVZ1_RonZN")->calculateDelay() + + getDriver("INV2_RonZN")->calculateDelay(); + double ck_to_q_delay = getDriver("INV5_RonZN")->calculateDelay() + + getDriver("INV6_RonZN")->calculateDelay() + + getDriver("INVZ3_RonZN")->calculateDelay() + + getDriver("INV3_RonZN")->calculateDelay() + + getDriver("INV4_RonZN")->calculateDelay(); + + cache->set(cell_name + "->DriveRes->Q", q_ron); + cache->set(cell_name + "->Delay->D_Setup", d_setup_delay); + cache->set(cell_name + "->Delay->CK_to_Q", ck_to_q_delay); + Log::printLine(cell_name + "->DriveRes->Q=" + (String) q_ron); + Log::printLine(cell_name + "->Delay->D_Setup=" + (String) d_setup_delay); + Log::printLine(cell_name + "->Delay->CK_to_Q=" + (String) ck_to_q_delay); + + return; + // -------------------------------------------------------------------- + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/INV.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/INV.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_STD_CELLS_INV_H__ +#define __DSENT_MODEL_STD_CELLS_INV_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" + +namespace DSENT +{ + class INV : public StdCell + { + public: + INV(const String& instance_name_, const TechModel* tech_model_); + virtual ~INV(); + + public: + // Set a list of properties' name needed to construct model + void initProperties(); + + // Cache the standard cell + void cacheStdCell(StdCellLib* cell_lib_, double drive_strength_); + + protected: + // Build the model + virtual void constructModel(); + virtual void updateModel(); + virtual void evaluateModel(); + virtual void useModel(); + virtual void propagateTransitionInfo(); + + }; // class INV +} // namespace DSENT + +#endif // __DSENT_MODEL_STD_CELLS_INV_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/INV.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/INV.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/INV.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/CellMacros.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriver.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalLoad.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDelay.hh" + +namespace DSENT +{ + using std::ceil; + using std::max; + + INV::INV(const String& instance_name_, const TechModel* tech_model_) + : StdCell(instance_name_, tech_model_) + { + initProperties(); + } + + INV::~INV() + {} + + void INV::initProperties() + { + return; + } + + void INV::constructModel() + { + // All constructModel should do is create Area/NDDPower/Energy Results as + // well as instantiate any sub-instances using only the hard parameters + + // Build Electrical Connectivity + createInputPort("A"); + createOutputPort("Y"); + + createLoad("A_Cap"); + createDelay("A_to_Y_delay"); + createDriver("Y_Ron", true); + + ElectricalLoad* a_cap = getLoad("A_Cap"); + ElectricalDelay* a_to_y_delay = getDelay("A_to_Y_delay"); + ElectricalDriver* y_ron = getDriver("Y_Ron"); + + getNet("A")->addDownstreamNode(a_cap); + a_cap->addDownstreamNode(a_to_y_delay); + a_to_y_delay->addDownstreamNode(y_ron); + y_ron->addDownstreamNode(getNet("Y")); + + // Create Area result + // Create NDD Power result + createElectricalAtomicResults(); + // Create INV Event Energy Result + createElectricalEventAtomicResult("INV"); + + getEventInfo("Idle")->setStaticTransitionInfos(); + + return; + } + + void INV::updateModel() + { + // All updateModel should do is calculate numbers for the Area/NDDPower/Energy + // Results as anything else that needs to be done using either soft or hard parameters + + // Get parameters + double drive_strength = getDrivingStrength(); + Map* cache = getTechModel()->getStdCellLib()->getStdCellCache(); + + // Standard cell cache string + String cell_name = "INV_X" + (String) drive_strength; + + // Get timing parameters + getLoad("A_Cap")->setLoadCap(cache->get(cell_name + "->Cap->A")); + getDriver("Y_Ron")->setOutputRes(cache->get(cell_name + "->DriveRes->Y")); + getDelay("A_to_Y_delay")->setDelay(cache->get(cell_name + "->Delay->A_to_Y")); + + // Set the cell area + getAreaResult("Active")->setValue(cache->get(cell_name + "->Area->Active")); + getAreaResult("Metal1Wire")->setValue(cache->get(cell_name + "->Area->Metal1Wire")); + + return; + } + + void INV::evaluateModel() + { + return; + } + + void INV::useModel() + { + // Get parameters + double drive_strength = getDrivingStrength(); + Map* cache = getTechModel()->getStdCellLib()->getStdCellCache(); + + // Standard cell cache string + String cell_name = "INV_X" + (String) drive_strength; + + // Propagate the transition info and get the 0->1 transtion count + propagateTransitionInfo(); + double P_A = getInputPort("A")->getTransitionInfo().getProbability1(); + double Y_num_trans_01 = getOutputPort("Y")->getTransitionInfo().getNumberTransitions01(); + + // Calculate leakage + double leakage = 0; + leakage += cache->get(cell_name + "->Leakage->!A") * (1 - P_A); + leakage += cache->get(cell_name + "->Leakage->A") * P_A; + getNddPowerResult("Leakage")->setValue(leakage); + + // Get VDD + double vdd = getTechModel()->get("Vdd"); + + // Get capacitances + //double a_cap = cache->get(cell_name + "->Cap->A"); + double y_cap = cache->get(cell_name + "->Cap->Y"); + double y_load_cap = getNet("Y")->getTotalDownstreamCap(); + + // Calculate INV Event energy + double energy_per_trans_01 = (y_cap + y_load_cap) * vdd * vdd; + getEventResult("INV")->setValue(energy_per_trans_01 * Y_num_trans_01); + return; + } + + void INV::propagateTransitionInfo() + { + // Get input transition info + const TransitionInfo& trans_A = getInputPort("A")->getTransitionInfo(); + + // Set output transition info + double Y_num_trans_00 = trans_A.getNumberTransitions11(); + double Y_num_trans_01 = trans_A.getNumberTransitions01(); + double Y_num_trans_11 = trans_A.getNumberTransitions00(); + + TransitionInfo trans_Y(Y_num_trans_00, Y_num_trans_01, Y_num_trans_11); + getOutputPort("Y")->setTransitionInfo(trans_Y); + return; + } + + // Creates the standard cell, characterizes and abstracts away the details + void INV::cacheStdCell(StdCellLib* cell_lib_, double drive_strength_) + { + // Standard cell cache string + String cell_name = "INV_X" + (String) drive_strength_; + + Log::printLine("=== " + cell_name + " ==="); + + // Get parameters + double gate_pitch = cell_lib_->getTechModel()->get("Gate->PitchContacted"); + Map* cache = cell_lib_->getStdCellCache(); + + // Now actually build the full standard cell model + // Create the two input ports + createInputPort("A"); + createOutputPort("Y"); + + // Adds macros + CellMacros::addInverter(this, "INV", true, true, "A", "Y"); + CellMacros::updateInverter(this, "INV", drive_strength_); + + // Cache area result + double area = gate_pitch * getTotalHeight() * (1 + getGenProperties()->get("INV_GatePitches").toDouble()); + cache->set(cell_name + "->Area->Active", area); + cache->set(cell_name + "->Area->Metal1Wire", area); + Log::printLine(cell_name + "->Area->Active=" + (String) area); + Log::printLine(cell_name + "->Area->Metal1Wire=" + (String) area); + + // -------------------------------------------------------------------- + // Leakage Model Calculation + // -------------------------------------------------------------------- + double leakage_a0 = getGenProperties()->get("INV_LeakagePower_0").toDouble(); + double leakage_a1 = getGenProperties()->get("INV_LeakagePower_1").toDouble(); + cache->set(cell_name + "->Leakage->!A", leakage_a0); + cache->set(cell_name + "->Leakage->A", leakage_a1); + Log::printLine(cell_name + "->Leakage->!A=" + (String) leakage_a0); + Log::printLine(cell_name + "->Leakage->A=" + (String) leakage_a1); + // -------------------------------------------------------------------- + + /* + // Cache event energy results + double event_a_flip = getGenProperties()->get("INV_A_Flip").toDouble() + getGenProperties()->get("INV_ZN_Flip").toDouble(); + cache->set(cell_name + "->Event_A_Flip", event_a_flip); + Log::printLine(cell_name + "->Event_A_Flip=" + (String) event_a_flip); + */ + + // -------------------------------------------------------------------- + // Get Node Capacitances + // -------------------------------------------------------------------- + double a_cap = getNet("A")->getTotalDownstreamCap(); + double y_cap = getNet("Y")->getTotalDownstreamCap(); + + cache->set(cell_name + "->Cap->A", a_cap); + cache->set(cell_name + "->Cap->Y", y_cap); + Log::printLine(cell_name + "->Cap->A=" + (String) a_cap); + Log::printLine(cell_name + "->Cap->Y=" + (String) y_cap); + // -------------------------------------------------------------------- + + // -------------------------------------------------------------------- + // Build Internal Delay Model + // -------------------------------------------------------------------- + double y_ron = getDriver("INV_RonZN")->getOutputRes(); + double a_to_y_delay = getDriver("INV_RonZN")->calculateDelay(); + cache->set(cell_name + "->DriveRes->Y", y_ron); + cache->set(cell_name + "->Delay->A_to_Y", a_to_y_delay); + Log::printLine(cell_name + "->DriveRes->Y=" + (String) y_ron); + Log::printLine(cell_name + "->Delay->A_to_Y=" + (String) a_to_y_delay); + // -------------------------------------------------------------------- + + return; + + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/LATQ.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/LATQ.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_STD_CELLS_LATQ_H__ +#define __DSENT_MODEL_STD_CELLS_LATQ_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" + +namespace DSENT +{ + class LATQ : public StdCell + { + // A DQ flip-flop + public: + LATQ(const String& instance_name_, const TechModel* tech_model_); + virtual ~LATQ(); + + public: + // Set a list of properties' name needed to construct model + void initProperties(); + // Cache the standard cell + void cacheStdCell(StdCellLib* cell_lib_, double drive_strength_); + + protected: + // Build the model + virtual void constructModel(); + virtual void updateModel(); + virtual void evaluateModel(); + virtual void useModel(); + virtual void propagateTransitionInfo(); + + }; // class LATQ +} // namespace DSENT + +#endif // __DSENT_MODEL_STD_CELLS_LATQ_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/LATQ.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/LATQ.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,411 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/LATQ.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/CellMacros.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriver.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalLoad.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDelay.hh" + +namespace DSENT +{ + using std::ceil; + using std::max; + using std::min; + + LATQ::LATQ(const String& instance_name_, const TechModel* tech_model_) + : StdCell(instance_name_, tech_model_) + { + initProperties(); + } + + LATQ::~LATQ() + {} + + void LATQ::initProperties() + { + return; + } + + void LATQ::constructModel() + { + // All constructModel should do is create Area/NDDPower/Energy Results as + // well as instantiate any sub-instances using only the hard parameters + + createInputPort("D"); + createInputPort("G"); + createOutputPort("Q"); + + createLoad("D_Cap"); + createLoad("G_Cap"); + createDelay("D_to_Q_delay"); + createDelay("G_to_Q_delay"); + createDriver("Q_Ron", true); + + ElectricalLoad* d_cap = getLoad("D_Cap"); + ElectricalLoad* g_cap = getLoad("G_Cap"); + ElectricalDelay* d_to_q_delay = getDelay("D_to_Q_delay"); + ElectricalDelay* g_to_q_delay = getDelay("G_to_Q_delay"); + ElectricalDriver* q_ron = getDriver("Q_Ron"); + + getNet("D")->addDownstreamNode(d_cap); + getNet("G")->addDownstreamNode(g_cap); + d_cap->addDownstreamNode(d_to_q_delay); + g_cap->addDownstreamNode(g_to_q_delay); + g_to_q_delay->addDownstreamNode(q_ron); + q_ron->addDownstreamNode(getNet("Q")); + + // Create Area result + // Create NDD Power result + createElectricalAtomicResults(); + // Create G Event Energy Result + createElectricalEventAtomicResult("G"); + // Create DFF Event Energy Result + createElectricalEventAtomicResult("LATD"); + createElectricalEventAtomicResult("LATQ"); + // Create Idle event for leakage + // G pin is assumed to be on all the time + //createElectricalEventAtomicResult("Idle"); + getEventInfo("Idle")->setStaticTransitionInfos(); + return; + } + + void LATQ::updateModel() + { + // Get parameters + double drive_strength = getDrivingStrength(); + Map* cache = getTechModel()->getStdCellLib()->getStdCellCache(); + + // Standard cell cache string + String cell_name = "LATQ_X" + (String) drive_strength; + + // Get timing parameters + getLoad("D_Cap")->setLoadCap(cache->get(cell_name + "->Cap->D")); + getLoad("G_Cap")->setLoadCap(cache->get(cell_name + "->Cap->G")); + getDriver("Q_Ron")->setOutputRes(cache->get(cell_name + "->DriveRes->Q")); + getDelay("G_to_Q_delay")->setDelay(cache->get(cell_name + "->Delay->G_to_Q")); + getDelay("D_to_Q_delay")->setDelay(cache->get(cell_name + "->Delay->D_to_Q")); + + // Set the cell area + getAreaResult("Active")->setValue(cache->get(cell_name + "->Area->Active")); + getAreaResult("Metal1Wire")->setValue(cache->get(cell_name + "->Area->Metal1Wire")); + + return; + } + + void LATQ::evaluateModel() + { + return; + } + + void LATQ::useModel() + { + // Get parameters + double drive_strength = getDrivingStrength(); + Map* cache = getTechModel()->getStdCellLib()->getStdCellCache(); + + // Standard cell cache string + String cell_name = "LATQ_X" + (String) drive_strength; + + // Propagate the transition info and get P_D, P_M, and P_Q + propagateTransitionInfo(); + double P_D = getInputPort("D")->getTransitionInfo().getProbability1(); + double P_G = getInputPort("G")->getTransitionInfo().getProbability1(); + double P_Q = getOutputPort("Q")->getTransitionInfo().getProbability1(); + double G_num_trans_01 = getInputPort("G")->getTransitionInfo().getNumberTransitions01(); + double D_num_trans_01 = getInputPort("D")->getTransitionInfo().getNumberTransitions01(); + double Q_num_trans_01 = getOutputPort("Q")->getTransitionInfo().getNumberTransitions01(); + + // Calculate leakage + double leakage = 0; + leakage += cache->get(cell_name + "->Leakage->!D!G!Q") * (1 - P_D) * (1 - P_G) * (1 - P_Q); + leakage += cache->get(cell_name + "->Leakage->!D!GQ") * (1 - P_D) * (1 - P_G) * P_Q; + leakage += cache->get(cell_name + "->Leakage->!DG!Q") * (1 - P_D) * P_G * (1 - P_Q); + leakage += cache->get(cell_name + "->Leakage->D!G!Q") * P_D * (1 - P_G) * (1 - P_Q); + leakage += cache->get(cell_name + "->Leakage->D!GQ") * P_D * (1 - P_G) * P_Q; + leakage += cache->get(cell_name + "->Leakage->DGQ") * P_D * P_G * P_Q; + getNddPowerResult("Leakage")->setValue(leakage); + + // Get VDD + double vdd = getTechModel()->get("Vdd"); + + // Get capacitances + double g_b_cap = cache->get(cell_name + "->Cap->G_b"); + double d_b_cap = cache->get(cell_name + "->Cap->D_b"); + double q_i_cap = cache->get(cell_name + "->Cap->Q_i"); + double q_b_cap = cache->get(cell_name + "->Cap->Q_b"); + double q_cap = cache->get(cell_name + "->Cap->Q"); + double q_load_cap = getNet("Q")->getTotalDownstreamCap(); + + // Calculate G Event energy + double g_event_energy = 0.0; + g_event_energy += (g_b_cap) * G_num_trans_01; + g_event_energy *= vdd * vdd; + getEventResult("G")->setValue(g_event_energy); + // Calculate LATD Event energy + double latd_event_energy = 0.0; + latd_event_energy += (d_b_cap) * D_num_trans_01; + latd_event_energy *= vdd * vdd; + getEventResult("LATD")->setValue(latd_event_energy); + // Calculate LATQ Event energy + double latq_event_energy = 0.0; + latq_event_energy += (q_i_cap + q_b_cap + q_cap + q_load_cap) * Q_num_trans_01; + latq_event_energy *= vdd * vdd; + getEventResult("LATQ")->setValue(latq_event_energy); + + return; + } + + void LATQ::propagateTransitionInfo() + { + const TransitionInfo& trans_G = getInputPort("G")->getTransitionInfo(); + const TransitionInfo& trans_D = getInputPort("D")->getTransitionInfo(); + + double G_num_trans_01 = trans_G.getNumberTransitions01(); + double G_num_trans_10 = G_num_trans_01; + double G_num_trans_00 = trans_G.getNumberTransitions00(); + double D_freq_mult = trans_D.getFrequencyMultiplier(); + + // If the latch is sampling just as fast or faster than input data signal + // Then it can capture all transitions (though it should be normalized to clock) + if((G_num_trans_10 + G_num_trans_00) >= D_freq_mult) + { + const TransitionInfo& trans_Q = trans_D.scaleFrequencyMultiplier(G_num_trans_10 + G_num_trans_00); + getOutputPort("Q")->setTransitionInfo(trans_Q); + } + // If the latch is sampling slower than the input data signal, then input + // will look like they transition more + else + { + // Calculate scale ratio + double scale_ratio = (G_num_trans_10 + G_num_trans_00) / D_freq_mult; + // 00 and 11 transitions become fewer + double D_scaled_diff = 0.5 * (1 - scale_ratio) * (trans_D.getNumberTransitions00() + trans_D.getNumberTransitions11()); + double D_scaled_num_trans_00 = trans_D.getNumberTransitions00() * scale_ratio; + double D_scaled_num_trans_11 = trans_D.getNumberTransitions11() * scale_ratio; + // 01 and 10 transitions become more frequent + double D_scaled_num_trans_10 = trans_D.getNumberTransitions01() + D_scaled_diff; + + // Create final transition info, remembering to apply scaling ratio to normalize to G + const TransitionInfo trans_Q( D_scaled_num_trans_00 * scale_ratio, + D_scaled_num_trans_10 * scale_ratio, + D_scaled_num_trans_11 * scale_ratio); + getOutputPort("Q")->setTransitionInfo(trans_Q); + } + + return; + } + + // Creates the standard cell, characterizes and abstracts away the details + void LATQ::cacheStdCell(StdCellLib* cell_lib_, double drive_strength_) + { + // Get parameters + double gate_pitch = cell_lib_->getTechModel()->get("Gate->PitchContacted"); + Map* cache = cell_lib_->getStdCellCache(); + + // Standard cell cache string + String cell_name = "LATQ_X" + (String) drive_strength_; + + Log::printLine("=== " + cell_name + " ==="); + + + // Now actually build the full standard cell model + createInputPort("D"); + createInputPort("G"); + createOutputPort("Q"); + + createNet("D_b"); + createNet("Q_i"); + createNet("Q_b"); + createNet("G_b"); + + // Adds macros + CellMacros::addInverter(this, "INV1", false, true, "D", "D_b"); + CellMacros::addInverter(this, "INV2", false, true, "Q_i", "Q_b"); + CellMacros::addInverter(this, "INV3", false, true, "Q_b", "Q"); + CellMacros::addInverter(this, "INV4", false, true, "G", "G_b"); + CellMacros::addTristate(this, "INVZ1", false, true, false, false, "D_b", "G", "G_b", "Q_i"); //trace timing through A->ZN path only + CellMacros::addTristate(this, "INVZ2", false, false, false, false, "Q_b", "G_b", "G", "Q_i"); //don't trace timing through the feedback path + + // Update macros + CellMacros::updateInverter(this, "INV1", drive_strength_ * 0.125); + CellMacros::updateInverter(this, "INV2", drive_strength_ * 0.5); + CellMacros::updateInverter(this, "INV3", drive_strength_ * 1.0); + CellMacros::updateInverter(this, "INV4", drive_strength_ * 0.125); + CellMacros::updateTristate(this, "INVZ1", drive_strength_ * 0.5); + CellMacros::updateTristate(this, "INVZ2", drive_strength_ * 0.0625); + + // Cache area result + double area = 0.0; + area += gate_pitch * getTotalHeight() * 1; + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV1_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV2_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV3_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV4_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INVZ1_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INVZ2_GatePitches").toDouble(); + cache->set(cell_name + "->Area->Active", area); + cache->set(cell_name + "->Area->Metal1Wire", area); //Cover-block m1 area + Log::printLine(cell_name + "->Area->Active=" + (String) area); + Log::printLine(cell_name + "->Area->Metal1Wire=" + (String) area); + + // -------------------------------------------------------------------- + // Leakage Model Calculation + // -------------------------------------------------------------------- + // Cache leakage power results (for every single signal combination) + double leakage_000 = 0; //!D, !G, !Q + double leakage_001 = 0; //!D, !G, Q + double leakage_010 = 0; //!D, G, !Q + double leakage_100 = 0; //D, !G, !Q + double leakage_101 = 0; //D, !G, Q + double leakage_111 = 0; //D, G, Q + + //This is so painful... + leakage_000 += getGenProperties()->get("INV1_LeakagePower_0").toDouble(); + leakage_000 += getGenProperties()->get("INV2_LeakagePower_0").toDouble(); + leakage_000 += getGenProperties()->get("INV3_LeakagePower_1").toDouble(); + leakage_000 += getGenProperties()->get("INV4_LeakagePower_0").toDouble(); + leakage_000 += getGenProperties()->get("INVZ1_LeakagePower_011_0").toDouble(); + leakage_000 += getGenProperties()->get("INVZ2_LeakagePower_101_0").toDouble(); + + leakage_001 += getGenProperties()->get("INV1_LeakagePower_0").toDouble(); + leakage_001 += getGenProperties()->get("INV2_LeakagePower_0").toDouble(); + leakage_001 += getGenProperties()->get("INV3_LeakagePower_0").toDouble(); + leakage_001 += getGenProperties()->get("INV4_LeakagePower_0").toDouble(); + leakage_001 += getGenProperties()->get("INVZ1_LeakagePower_011_1").toDouble(); + leakage_001 += getGenProperties()->get("INVZ2_LeakagePower_100_1").toDouble(); + + leakage_010 += getGenProperties()->get("INV1_LeakagePower_0").toDouble(); + leakage_010 += getGenProperties()->get("INV2_LeakagePower_0").toDouble(); + leakage_010 += getGenProperties()->get("INV3_LeakagePower_1").toDouble(); + leakage_010 += getGenProperties()->get("INV4_LeakagePower_1").toDouble(); + leakage_010 += getGenProperties()->get("INVZ1_LeakagePower_101_0").toDouble(); + leakage_010 += getGenProperties()->get("INVZ2_LeakagePower_011_0").toDouble(); + + leakage_100 += getGenProperties()->get("INV1_LeakagePower_1").toDouble(); + leakage_100 += getGenProperties()->get("INV2_LeakagePower_1").toDouble(); + leakage_100 += getGenProperties()->get("INV3_LeakagePower_1").toDouble(); + leakage_100 += getGenProperties()->get("INV4_LeakagePower_0").toDouble(); + leakage_100 += getGenProperties()->get("INVZ1_LeakagePower_010_0").toDouble(); + leakage_100 += getGenProperties()->get("INVZ2_LeakagePower_101_0").toDouble(); + + leakage_101 += getGenProperties()->get("INV1_LeakagePower_1").toDouble(); + leakage_101 += getGenProperties()->get("INV2_LeakagePower_1").toDouble(); + leakage_101 += getGenProperties()->get("INV3_LeakagePower_0").toDouble(); + leakage_101 += getGenProperties()->get("INV4_LeakagePower_0").toDouble(); + leakage_101 += getGenProperties()->get("INVZ1_LeakagePower_010_1").toDouble(); + leakage_101 += getGenProperties()->get("INVZ2_LeakagePower_100_1").toDouble(); + + leakage_111 += getGenProperties()->get("INV1_LeakagePower_1").toDouble(); + leakage_111 += getGenProperties()->get("INV2_LeakagePower_1").toDouble(); + leakage_111 += getGenProperties()->get("INV3_LeakagePower_0").toDouble(); + leakage_111 += getGenProperties()->get("INV4_LeakagePower_1").toDouble(); + leakage_111 += getGenProperties()->get("INVZ1_LeakagePower_100_1").toDouble(); + leakage_111 += getGenProperties()->get("INVZ2_LeakagePower_010_1").toDouble(); + + cache->set(cell_name + "->Leakage->!D!G!Q", leakage_000); + cache->set(cell_name + "->Leakage->!D!GQ", leakage_001); + cache->set(cell_name + "->Leakage->!DG!Q", leakage_010); + cache->set(cell_name + "->Leakage->D!G!Q", leakage_100); + cache->set(cell_name + "->Leakage->D!GQ", leakage_101); + cache->set(cell_name + "->Leakage->DGQ", leakage_111); + Log::printLine(cell_name + "->Leakage->!D!G!Q=" + (String) leakage_000); + Log::printLine(cell_name + "->Leakage->!D!GQ=" + (String) leakage_001); + Log::printLine(cell_name + "->Leakage->!DG!Q=" + (String) leakage_010); + Log::printLine(cell_name + "->Leakage->D!G!Q=" + (String) leakage_100); + Log::printLine(cell_name + "->Leakage->D!GQ=" + (String) leakage_101); + Log::printLine(cell_name + "->Leakage->DGQ=" + (String) leakage_111); + // -------------------------------------------------------------------- + + // -------------------------------------------------------------------- + // Get Node Capacitances + // -------------------------------------------------------------------- + double d_cap = getNet("D")->getTotalDownstreamCap(); + double d_b_cap = getNet("D_b")->getTotalDownstreamCap(); + double q_i_cap = getNet("Q_i")->getTotalDownstreamCap(); + double q_b_cap = getNet("Q_b")->getTotalDownstreamCap(); + double q_cap = getNet("Q")->getTotalDownstreamCap(); + double g_cap = getNet("G")->getTotalDownstreamCap(); + double g_b_cap = getNet("G_b")->getTotalDownstreamCap(); + + cache->set(cell_name + "->Cap->D", d_cap); + cache->set(cell_name + "->Cap->D_b", d_b_cap); + cache->set(cell_name + "->Cap->Q_i", q_i_cap); + cache->set(cell_name + "->Cap->Q_b", q_b_cap); + cache->set(cell_name + "->Cap->Q", q_cap); + cache->set(cell_name + "->Cap->G", g_cap); + cache->set(cell_name + "->Cap->G_b", g_b_cap); + + Log::printLine(cell_name + "->Cap->D=" + (String) d_cap); + Log::printLine(cell_name + "->Cap->D_b=" + (String) d_b_cap); + Log::printLine(cell_name + "->Cap->Q_i=" + (String) q_i_cap); + Log::printLine(cell_name + "->Cap->Q_b=" + (String) q_b_cap); + Log::printLine(cell_name + "->Cap->Q=" + (String) q_cap); + Log::printLine(cell_name + "->Cap->G=" + (String) g_cap); + Log::printLine(cell_name + "->Cap->G_b=" + (String) g_b_cap); + // -------------------------------------------------------------------- + + // -------------------------------------------------------------------- + // Build Internal Delay Model + // -------------------------------------------------------------------- + double q_ron = getDriver("INV3_RonZN")->getOutputRes(); + + double d_to_q_delay = getDriver("INV1_RonZN")->calculateDelay() + + getDriver("INVZ1_RonZN")->calculateDelay() + + getDriver("INV2_RonZN")->calculateDelay() + + getDriver("INV3_RonZN")->calculateDelay(); + double g_to_q_delay = getDriver("INV4_RonZN")->calculateDelay() + + getDriver("INVZ1_RonZN")->calculateDelay() + + getDriver("INV2_RonZN")->calculateDelay() + + getDriver("INV3_RonZN")->calculateDelay(); + + cache->set(cell_name + "->DriveRes->Q", q_ron); + cache->set(cell_name + "->Delay->D_to_Q", d_to_q_delay); + cache->set(cell_name + "->Delay->G_to_Q", g_to_q_delay); + Log::printLine(cell_name + "->DriveRes->Q=" + (String) q_ron); + Log::printLine(cell_name + "->Delay->D_to_Q=" + (String) d_to_q_delay); + Log::printLine(cell_name + "->Delay->G_to_Q=" + (String) g_to_q_delay); + + return; + // -------------------------------------------------------------------- + + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/MUX2.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/MUX2.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_STD_CELLS_MUX2_H__ +#define __DSENT_MODEL_STD_CELLS_MUX2_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" + +namespace DSENT +{ + class MUX2 : public StdCell + { + // A 2-input MUX standard cell + public: + MUX2(const String& instance_name_, const TechModel* tech_model_); + virtual ~MUX2(); + + public: + // Set a list of properties' name needed to construct model + void initProperties(); + // Cache the standard cell + void cacheStdCell(StdCellLib* cell_lib_, double drive_strength_); + + protected: + // Build the model + virtual void constructModel(); + virtual void updateModel(); + virtual void evaluateModel(); + virtual void useModel(); + virtual void propagateTransitionInfo(); + + }; // class MUX2 +} // namespace DSENT + +#endif // __DSENT_MODEL_STD_CELLS_MUX2_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/MUX2.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/MUX2.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,451 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/MUX2.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/CellMacros.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriver.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalLoad.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDelay.hh" + +namespace DSENT +{ + using std::ceil; + using std::max; + + MUX2::MUX2(const String& instance_name_, const TechModel* tech_model_) + : StdCell(instance_name_, tech_model_) + { + initProperties(); + } + + MUX2::~MUX2() + {} + + void MUX2::initProperties() + { + return; + } + + void MUX2::constructModel() + { + // All constructModel should do is create Area/NDDPower/Energy Results as + // well as instantiate any sub-instances using only the hard parameters + + createInputPort("A"); + createInputPort("B"); + createInputPort("S0"); + createOutputPort("Y"); + + createLoad("A_Cap"); + createLoad("B_Cap"); + createLoad("S0_Cap"); + createDelay("A_to_Y_delay"); + createDelay("B_to_Y_delay"); + createDelay("S0_to_Y_delay"); + createDriver("Y_Ron", true); + + ElectricalLoad* a_cap = getLoad("A_Cap"); + ElectricalLoad* b_cap = getLoad("B_Cap"); + ElectricalLoad* s0_cap = getLoad("S0_Cap"); + ElectricalDelay* a_to_y_delay = getDelay("A_to_Y_delay"); + ElectricalDelay* b_to_y_delay = getDelay("B_to_Y_delay"); + ElectricalDelay* s0_to_y_delay = getDelay("S0_to_Y_delay"); + ElectricalDriver* y_ron = getDriver("Y_Ron"); + + getNet("A")->addDownstreamNode(a_cap); + getNet("B")->addDownstreamNode(b_cap); + getNet("S0")->addDownstreamNode(s0_cap); + a_cap->addDownstreamNode(a_to_y_delay); + b_cap->addDownstreamNode(b_to_y_delay); + s0_cap->addDownstreamNode(s0_to_y_delay); + a_to_y_delay->addDownstreamNode(y_ron); + b_to_y_delay->addDownstreamNode(y_ron); + s0_to_y_delay->addDownstreamNode(y_ron); + y_ron->addDownstreamNode(getNet("Y")); + + // Create Area result + createElectricalAtomicResults(); + getEventInfo("Idle")->setStaticTransitionInfos(); + // Create MUX2 Event Energy Result + createElectricalEventAtomicResult("MUX2"); + + + return; + } + + void MUX2::updateModel() + { + // Get parameters + double drive_strength = getDrivingStrength(); + Map* cache = getTechModel()->getStdCellLib()->getStdCellCache(); + + // Standard cell cache string + String cell_name = "MUX2_X" + (String) drive_strength; + + // Get timing parameters + getLoad("A_Cap")->setLoadCap(cache->get(cell_name + "->Cap->A")); + getLoad("B_Cap")->setLoadCap(cache->get(cell_name + "->Cap->B")); + getLoad("S0_Cap")->setLoadCap(cache->get(cell_name + "->Cap->S0")); + + getDelay("A_to_Y_delay")->setDelay(cache->get(cell_name + "->Delay->A_to_Y")); + getDelay("B_to_Y_delay")->setDelay(cache->get(cell_name + "->Delay->B_to_Y")); + getDelay("S0_to_Y_delay")->setDelay(cache->get(cell_name + "->Delay->S0_to_Y")); + + getDriver("Y_Ron")->setOutputRes(cache->get(cell_name + "->DriveRes->Y")); + + // Set the cell area + getAreaResult("Active")->setValue(cache->get(cell_name + "->ActiveArea")); + getAreaResult("Metal1Wire")->setValue(cache->get(cell_name + "->ActiveArea")); + + return; + } + + void MUX2::evaluateModel() + { + return; + } + + void MUX2::useModel() + { + // Get parameters + double drive_strength = getDrivingStrength(); + Map* cache = getTechModel()->getStdCellLib()->getStdCellCache(); + + // Standard cell cache string + String cell_name = "MUX2_X" + (String) drive_strength; + + // Propagate the transition and get the 0->1 transition count + propagateTransitionInfo(); + double P_A = getInputPort("A")->getTransitionInfo().getProbability1(); + double P_B = getInputPort("B")->getTransitionInfo().getProbability1(); + double P_S0 = getInputPort("S0")->getTransitionInfo().getProbability1(); + double S0_num_trans_01 = getInputPort("S0")->getTransitionInfo().getNumberTransitions01(); + double Y_num_trans_01 = getOutputPort("Y")->getTransitionInfo().getNumberTransitions01(); + + // Calculate leakage + double leakage = 0; + leakage += cache->get(cell_name + "->Leakage->!A!B!S0") * (1 - P_A) * (1 - P_B) * (1 - P_S0); + leakage += cache->get(cell_name + "->Leakage->!A!BS0") * (1 - P_A) * (1 - P_B) * P_S0; + leakage += cache->get(cell_name + "->Leakage->!AB!S0") * (1 - P_A) * P_B * (1 - P_S0); + leakage += cache->get(cell_name + "->Leakage->!ABS0") * (1 - P_A) * P_B * P_S0; + leakage += cache->get(cell_name + "->Leakage->A!B!S0") * P_A * (1 - P_B) * (1 - P_S0); + leakage += cache->get(cell_name + "->Leakage->A!BS0") * P_A * (1 - P_B) * P_S0; + leakage += cache->get(cell_name + "->Leakage->AB!S0") * P_A * P_B * (1 - P_S0); + leakage += cache->get(cell_name + "->Leakage->ABS0") * P_A * P_B * P_S0; + getNddPowerResult("Leakage")->setValue(leakage); + + // Get VDD + double vdd = getTechModel()->get("Vdd"); + + // Get capacitances + double s0_b_cap = cache->get(cell_name + "->Cap->S0_b"); + double y_bar_cap = cache->get(cell_name + "->Cap->Y_b"); + double y_cap = cache->get(cell_name + "->Cap->Y"); + double y_load_cap = getNet("Y")->getTotalDownstreamCap(); + // Create mux2 event energy + double mux2_event_energy = 0.0; + mux2_event_energy += (s0_b_cap) * S0_num_trans_01; + mux2_event_energy += (y_bar_cap + y_cap + y_load_cap) * Y_num_trans_01; + mux2_event_energy *= vdd * vdd; + getEventResult("MUX2")->setValue(mux2_event_energy); + + return; + } + + void MUX2::propagateTransitionInfo() + { + // Get input signal transition info + const TransitionInfo& trans_A = getInputPort("A")->getTransitionInfo(); + const TransitionInfo& trans_B = getInputPort("B")->getTransitionInfo(); + const TransitionInfo& trans_S0 = getInputPort("S0")->getTransitionInfo(); + + // Scale all transition information to the highest freq multiplier + double max_freq_mult = max(max(trans_A.getFrequencyMultiplier(), trans_B.getFrequencyMultiplier()), trans_S0.getFrequencyMultiplier()); + const TransitionInfo& scaled_trans_A = trans_A.scaleFrequencyMultiplier(max_freq_mult); + const TransitionInfo& scaled_trans_B = trans_B.scaleFrequencyMultiplier(max_freq_mult); + const TransitionInfo& scaled_trans_S0 = trans_S0.scaleFrequencyMultiplier(max_freq_mult); + + // Compute the probability of each transition on a given cycle + double A_prob_00 = scaled_trans_A.getNumberTransitions00() / max_freq_mult; + double A_prob_01 = scaled_trans_A.getNumberTransitions01() / max_freq_mult; + double A_prob_10 = A_prob_01; + double A_prob_11 = scaled_trans_A.getNumberTransitions11() / max_freq_mult; + double B_prob_00 = scaled_trans_B.getNumberTransitions00() / max_freq_mult; + double B_prob_01 = scaled_trans_B.getNumberTransitions01() / max_freq_mult; + double B_prob_10 = B_prob_01; + double B_prob_11 = scaled_trans_B.getNumberTransitions11() / max_freq_mult; + double S0_prob_00 = scaled_trans_S0.getNumberTransitions00() / max_freq_mult; + double S0_prob_01 = scaled_trans_S0.getNumberTransitions01() / max_freq_mult; + double S0_prob_10 = S0_prob_01; + double S0_prob_11 = scaled_trans_S0.getNumberTransitions11() / max_freq_mult; + + // Compute output probabilities + double Y_prob_00 = S0_prob_00 * A_prob_00 + + S0_prob_01 * (A_prob_00 + A_prob_01) * (B_prob_00 + B_prob_10) + + S0_prob_10 * (A_prob_00 + A_prob_10) * (B_prob_00 + B_prob_01) + + S0_prob_11 * B_prob_00; + double Y_prob_01 = S0_prob_00 * A_prob_01 + + S0_prob_01 * (A_prob_00 + A_prob_01) * (B_prob_01 + B_prob_11) + + S0_prob_10 * (A_prob_01 + A_prob_11) * (B_prob_00 + B_prob_01) + + S0_prob_11 * B_prob_01; + double Y_prob_11 = S0_prob_00 * A_prob_11 + + S0_prob_01 * (A_prob_10 + A_prob_11) * (B_prob_01 + B_prob_11) + + S0_prob_10 * (A_prob_01 + A_prob_11) * (B_prob_10 + B_prob_11) + + S0_prob_11 * B_prob_11; + + // Check that probabilities add up to 1.0 with some finite tolerance + ASSERT(LibUtil::Math::isEqual((Y_prob_00 + Y_prob_01 + Y_prob_01 + Y_prob_11), 1.0), + "[Error] " + getInstanceName() + "Output transition probabilities must add up to 1 (" + + (String) Y_prob_00 + ", " + (String) Y_prob_01 + ", " + (String) Y_prob_11 + ")!"); + + // Turn probability of transitions per cycle into number of transitions per time unit + TransitionInfo trans_Y(Y_prob_00 * max_freq_mult, Y_prob_01 * max_freq_mult, Y_prob_11 * max_freq_mult); + getOutputPort("Y")->setTransitionInfo(trans_Y); + + return; + } + + // Creates the standard cell, characterizes and abstracts away the details + void MUX2::cacheStdCell(StdCellLib* cell_lib_, double drive_strength_) + { + // Get parameters + double gate_pitch = cell_lib_->getTechModel()->get("Gate->PitchContacted"); + Map* cache = cell_lib_->getStdCellCache(); + + // Standard cell cache string + String cell_name = "MUX2_X" + (String) drive_strength_; + + Log::printLine("=== " + cell_name + " ==="); + + // Now actually build the full standard cell model + createInputPort("A"); + createInputPort("B"); + createInputPort("S0"); + createOutputPort("Y"); + + createNet("S0_b"); + createNet("Y_b"); + + // Adds macros + CellMacros::addInverter(this, "INV1", false, true, "S0", "S0_b"); + CellMacros::addInverter(this, "INV2", false, true, "Y_b", "Y"); + CellMacros::addTristate(this, "INVZ1", true, true, true, true, "A", "S0_b", "S0", "Y_b"); + CellMacros::addTristate(this, "INVZ2", true, true, true, true, "B", "S0", "S0_b", "Y_b"); + + // I have no idea how to size each of the parts haha + CellMacros::updateInverter(this, "INV1", drive_strength_ * 0.250); + CellMacros::updateInverter(this, "INV2", drive_strength_ * 1.000); + CellMacros::updateTristate(this, "INVZ1", drive_strength_ * 0.500); + CellMacros::updateTristate(this, "INVZ2", drive_strength_ * 0.500); + + // Cache area result + double area = 0.0; + area += gate_pitch * getTotalHeight() * 1; + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV1_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV2_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INVZ1_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INVZ2_GatePitches").toDouble(); + cache->set(cell_name + "->ActiveArea", area); + Log::printLine(cell_name + "->ActiveArea=" + (String) area); + + // -------------------------------------------------------------------- + // Cache Leakage Power (for every single signal combination) + // -------------------------------------------------------------------- + double leakage_000 = 0; //!A, !B, !S0 + double leakage_001 = 0; //!A, !B, S0 + double leakage_010 = 0; //!A, B, !S0 + double leakage_011 = 0; //!A, B, S0 + double leakage_100 = 0; //A, !B, !S0 + double leakage_101 = 0; //A, !B, S0 + double leakage_110 = 0; //A, B, !S0 + double leakage_111 = 0; //A, B, S0 + + //This is so painful... + leakage_000 += getGenProperties()->get("INV1_LeakagePower_0").toDouble(); + leakage_000 += getGenProperties()->get("INV2_LeakagePower_1").toDouble(); + leakage_000 += getGenProperties()->get("INVZ1_LeakagePower_100_1").toDouble(); + leakage_000 += getGenProperties()->get("INVZ2_LeakagePower_010_1").toDouble(); + + leakage_001 += getGenProperties()->get("INV1_LeakagePower_1").toDouble(); + leakage_001 += getGenProperties()->get("INV2_LeakagePower_1").toDouble(); + leakage_001 += getGenProperties()->get("INVZ1_LeakagePower_010_1").toDouble(); + leakage_001 += getGenProperties()->get("INVZ2_LeakagePower_100_1").toDouble(); + + leakage_010 += getGenProperties()->get("INV1_LeakagePower_0").toDouble(); + leakage_010 += getGenProperties()->get("INV2_LeakagePower_1").toDouble(); + leakage_010 += getGenProperties()->get("INVZ1_LeakagePower_100_1").toDouble(); + leakage_010 += getGenProperties()->get("INVZ2_LeakagePower_011_1").toDouble(); + + leakage_011 += getGenProperties()->get("INV1_LeakagePower_1").toDouble(); + leakage_011 += getGenProperties()->get("INV2_LeakagePower_0").toDouble(); + leakage_011 += getGenProperties()->get("INVZ1_LeakagePower_010_0").toDouble(); + leakage_011 += getGenProperties()->get("INVZ2_LeakagePower_101_0").toDouble(); + + leakage_100 += getGenProperties()->get("INV1_LeakagePower_0").toDouble(); + leakage_100 += getGenProperties()->get("INV2_LeakagePower_0").toDouble(); + leakage_100 += getGenProperties()->get("INVZ1_LeakagePower_101_0").toDouble(); + leakage_100 += getGenProperties()->get("INVZ2_LeakagePower_010_0").toDouble(); + + leakage_101 += getGenProperties()->get("INV1_LeakagePower_1").toDouble(); + leakage_101 += getGenProperties()->get("INV2_LeakagePower_0").toDouble(); + leakage_101 += getGenProperties()->get("INVZ1_LeakagePower_011_1").toDouble(); + leakage_101 += getGenProperties()->get("INVZ2_LeakagePower_100_1").toDouble(); + + leakage_110 += getGenProperties()->get("INV1_LeakagePower_1").toDouble(); + leakage_110 += getGenProperties()->get("INV2_LeakagePower_1").toDouble(); + leakage_110 += getGenProperties()->get("INVZ1_LeakagePower_101_0").toDouble(); + leakage_110 += getGenProperties()->get("INVZ2_LeakagePower_011_0").toDouble(); + + leakage_111 += getGenProperties()->get("INV1_LeakagePower_1").toDouble(); + leakage_111 += getGenProperties()->get("INV2_LeakagePower_1").toDouble(); + leakage_111 += getGenProperties()->get("INVZ1_LeakagePower_011_0").toDouble(); + leakage_111 += getGenProperties()->get("INVZ2_LeakagePower_101_0").toDouble(); + + cache->set(cell_name + "->Leakage->!A!B!S0", leakage_000); + cache->set(cell_name + "->Leakage->!A!BS0", leakage_001); + cache->set(cell_name + "->Leakage->!AB!S0", leakage_010); + cache->set(cell_name + "->Leakage->!ABS0", leakage_011); + cache->set(cell_name + "->Leakage->A!B!S0", leakage_100); + cache->set(cell_name + "->Leakage->A!BS0", leakage_101); + cache->set(cell_name + "->Leakage->AB!S0", leakage_110); + cache->set(cell_name + "->Leakage->ABS0", leakage_111); + Log::printLine(cell_name + "->Leakage->!A!B!S0=" + (String) leakage_000); + Log::printLine(cell_name + "->Leakage->!A!BS0=" + (String) leakage_001); + Log::printLine(cell_name + "->Leakage->!AB!S0=" + (String) leakage_010); + Log::printLine(cell_name + "->Leakage->!ABS0=" + (String) leakage_011); + Log::printLine(cell_name + "->Leakage->A!B!S0=" + (String) leakage_100); + Log::printLine(cell_name + "->Leakage->A!BS0=" + (String) leakage_101); + Log::printLine(cell_name + "->Leakage->AB!S0=" + (String) leakage_110); + Log::printLine(cell_name + "->Leakage->ABS0=" + (String) leakage_111); + + // Cache event energy results + /* + double event_a_flip = 0.0; + event_a_flip += getGenProperties()->get("INVZ1_A_Flip").toDouble(); + cache->set(cell_name + "->Event_A_Flip", event_a_flip); + Log::printLine(cell_name + "->Event_A_Flip=" + (String) event_a_flip); + + double event_b_flip = 0.0; + event_b_flip += getGenProperties()->get("INVZ1_A_Flip").toDouble(); + cache->set(cell_name + "->Event_B_Flip", event_b_flip); + Log::printLine(cell_name + "->Event_B_Flip=" + (String) event_b_flip); + + double event_s0_flip = 0.0; + event_s0_flip += getGenProperties()->get("INV1_A_Flip").toDouble(); + event_s0_flip += getGenProperties()->get("INV1_ZN_Flip").toDouble(); + event_s0_flip += getGenProperties()->get("INVZ1_OE_Flip").toDouble() + getGenProperties()->get("INVZ1_OEN_Flip").toDouble(); + event_s0_flip += getGenProperties()->get("INVZ2_OE_Flip").toDouble() + getGenProperties()->get("INVZ2_OEN_Flip").toDouble(); + cache->set(cell_name + "->Event_S0_Flip", event_s0_flip); + Log::printLine(cell_name + "->Event_S0_Flip=" + (String) event_s0_flip); + + double event_y_flip = 0.0; + event_y_flip += getGenProperties()->get("INVZ1_ZN_Flip").toDouble(); + event_y_flip += getGenProperties()->get("INVZ2_ZN_Flip").toDouble(); + event_y_flip += getGenProperties()->get("INV2_A_Flip").toDouble(); + event_y_flip += getGenProperties()->get("INV2_ZN_Flip").toDouble(); + cache->set(cell_name + "->Event_Y_Flip", event_y_flip); + Log::printLine(cell_name + "->Event_Y_Flip=" + (String) event_y_flip); + + double a_cap = getLoad("INVZ1_CgA")->getLoadCap(); + double b_cap = getLoad("INVZ2_CgA")->getLoadCap(); + double s0_cap = getLoad("INV1_CgA")->getLoadCap() + getLoad("INVZ1_CgOEN")->getLoadCap() + getLoad("INVZ2_CgOE")->getLoadCap(); + double y_ron = getDriver("INV2_RonZN")->getOutputRes(); + */ + // -------------------------------------------------------------------- + + // -------------------------------------------------------------------- + // Get Node capacitances + // -------------------------------------------------------------------- + double a_cap = getNet("A")->getTotalDownstreamCap(); + double b_cap = getNet("B")->getTotalDownstreamCap(); + double s0_cap = getNet("S0")->getTotalDownstreamCap(); + double s0_b_cap = getNet("S0_b")->getTotalDownstreamCap(); + double y_b_cap = getNet("Y_b")->getTotalDownstreamCap(); + double y_cap = getNet("Y")->getTotalDownstreamCap(); + + cache->set(cell_name + "->Cap->A", a_cap); + cache->set(cell_name + "->Cap->B", b_cap); + cache->set(cell_name + "->Cap->S0", s0_cap); + cache->set(cell_name + "->Cap->S0_b", s0_b_cap); + cache->set(cell_name + "->Cap->Y_b", y_b_cap); + cache->set(cell_name + "->Cap->Y", y_cap); + + Log::printLine(cell_name + "->Cap->A=" + (String) a_cap); + Log::printLine(cell_name + "->Cap->B=" + (String) b_cap); + Log::printLine(cell_name + "->Cap->S0=" + (String) s0_cap); + Log::printLine(cell_name + "->Cap->S0_b=" + (String) s0_b_cap); + Log::printLine(cell_name + "->Cap->Y_b=" + (String) y_b_cap); + Log::printLine(cell_name + "->Cap->Y=" + (String) y_cap); + // -------------------------------------------------------------------- + + // -------------------------------------------------------------------- + // Build Internal Delay Model + // -------------------------------------------------------------------- + // Build abstracted timing model + double y_ron = getDriver("INV2_RonZN")->getOutputRes(); + + double a_to_y_delay = 0.0; + a_to_y_delay += getDriver("INVZ1_RonZN")->calculateDelay(); + a_to_y_delay += getDriver("INV2_RonZN")->calculateDelay(); + + double b_to_y_delay = 0.0; + b_to_y_delay += getDriver("INVZ1_RonZN")->calculateDelay(); + b_to_y_delay += getDriver("INV2_RonZN")->calculateDelay(); + + double s0_to_y_delay = 0.0; + s0_to_y_delay += getDriver("INV1_RonZN")->calculateDelay(); + s0_to_y_delay += max(getDriver("INVZ1_RonZN")->calculateDelay(), getDriver("INVZ1_RonZN")->calculateDelay()); + s0_to_y_delay += getDriver("INV2_RonZN")->calculateDelay(); + + cache->set(cell_name + "->DriveRes->Y", y_ron); + cache->set(cell_name + "->Delay->A_to_Y", a_to_y_delay); + cache->set(cell_name + "->Delay->B_to_Y", b_to_y_delay); + cache->set(cell_name + "->Delay->S0_to_Y", s0_to_y_delay); + + Log::printLine(cell_name + "->DriveRes->Y=" + (String) y_ron); + Log::printLine(cell_name + "->Delay->A_to_Y=" + (String) a_to_y_delay); + Log::printLine(cell_name + "->Delay->B_to_Y=" + (String) b_to_y_delay); + Log::printLine(cell_name + "->Delay->S0_to_Y=" + (String) s0_to_y_delay); + // -------------------------------------------------------------------- + + return; + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/NAND2.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/NAND2.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_STD_CELLS_NAND2_H__ +#define __DSENT_MODEL_STD_CELLS_NAND2_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" + +namespace DSENT +{ + class NAND2 : public StdCell + { + public: + NAND2(const String& instance_name_, const TechModel* tech_model_); + virtual ~NAND2(); + + public: + // Set a list of properties' name needed to construct model + void initProperties(); + + // Cache the standard cell + void cacheStdCell(StdCellLib* cell_lib_, double drive_strength_); + + protected: + // Build the model + virtual void constructModel(); + virtual void updateModel(); + virtual void useModel(); + virtual void propagateTransitionInfo(); + + }; // class NAND2 +} // namespace DSENT + +#endif // __DSENT_MODEL_STD_CELLS_NAND2_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/NAND2.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/NAND2.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/NAND2.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/CellMacros.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriver.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalLoad.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDelay.hh" + +namespace DSENT +{ + using std::ceil; + using std::max; + + NAND2::NAND2(const String& instance_name_, const TechModel* tech_model_) + : StdCell(instance_name_, tech_model_) + { + initProperties(); + } + + NAND2::~NAND2() + {} + + void NAND2::initProperties() + { + return; + } + + void NAND2::constructModel() + { + // All constructModel should do is create Area/NDDPower/Energy Results as + // well as instantiate any sub-instances using only the hard parameters + + createInputPort("A"); + createInputPort("B"); + createOutputPort("Y"); + + createLoad("A_Cap"); + createLoad("B_Cap"); + createDelay("A_to_Y_delay"); + createDelay("B_to_Y_delay"); + createDriver("Y_Ron", true); + + ElectricalLoad* a_cap = getLoad("A_Cap"); + ElectricalLoad* b_cap = getLoad("A_Cap"); + ElectricalDelay* a_to_y_delay = getDelay("A_to_Y_delay"); + ElectricalDelay* b_to_y_delay = getDelay("B_to_Y_delay"); + ElectricalDriver* y_ron = getDriver("Y_Ron"); + + getNet("A")->addDownstreamNode(a_cap); + getNet("B")->addDownstreamNode(b_cap); + a_cap->addDownstreamNode(a_to_y_delay); + b_cap->addDownstreamNode(b_to_y_delay); + a_to_y_delay->addDownstreamNode(y_ron); + b_to_y_delay->addDownstreamNode(y_ron); + y_ron->addDownstreamNode(getNet("Y")); + + // Create Area result + // Create NDD Power result + createElectricalAtomicResults(); + // Create NAND Event Energy Result + createElectricalEventAtomicResult("NAND2"); + + getEventInfo("Idle")->setStaticTransitionInfos(); + + return; + } + + void NAND2::updateModel() + { + // All updateModel should do is calculate numbers for the Area/NDDPower/Energy + // Results as anything else that needs to be done using either soft or hard parameters + + // Get parameters + double drive_strength = getDrivingStrength(); + Map* cache = getTechModel()->getStdCellLib()->getStdCellCache(); + + // Standard cell cache string + String cell_name = "NAND2_X" + (String) drive_strength; + + // Get timing parameters + getLoad("A_Cap")->setLoadCap(cache->get(cell_name + "->Cap->A")); + getLoad("B_Cap")->setLoadCap(cache->get(cell_name + "->Cap->B")); + getDelay("A_to_Y_delay")->setDelay(cache->get(cell_name + "->Delay->A_to_Y")); + getDelay("B_to_Y_delay")->setDelay(cache->get(cell_name + "->Delay->B_to_Y")); + getDriver("Y_Ron")->setOutputRes(cache->get(cell_name + "->DriveRes->Y")); + + // Set the cell area + getAreaResult("Active")->setValue(cache->get(cell_name + "->Area->Active")); + getAreaResult("Metal1Wire")->setValue(cache->get(cell_name + "->Area->Active")); + + return; + } + + void NAND2::useModel() + { + // Get parameters + double drive_strength = getDrivingStrength(); + Map* cache = getTechModel()->getStdCellLib()->getStdCellCache(); + + // Standard cell cache string + String cell_name = "NAND2_X" + (String) drive_strength; + + // Propagate the transition info and get the 0->1 transtion count + propagateTransitionInfo(); + double P_A = getInputPort("A")->getTransitionInfo().getProbability1(); + double P_B = getInputPort("B")->getTransitionInfo().getProbability1(); + double Y_num_trans_01 = getOutputPort("Y")->getTransitionInfo().getNumberTransitions01(); + + // Calculate leakage + double leakage = 0; + leakage += cache->get(cell_name + "->Leakage->!A!B") * (1 - P_A) * (1 - P_B); + leakage += cache->get(cell_name + "->Leakage->!AB") * (1 - P_A) * P_B; + leakage += cache->get(cell_name + "->Leakage->A!B") * P_A * (1 - P_B); + leakage += cache->get(cell_name + "->Leakage->AB") * P_A * P_B; + getNddPowerResult("Leakage")->setValue(leakage); + + // Get capacitances + double y_cap = cache->get(cell_name + "->Cap->Y"); + double y_load_cap = getNet("Y")->getTotalDownstreamCap(); + + // Get VDD + double vdd = getTechModel()->get("Vdd"); + + // Calculate NAND2Event energy + double energy_per_trans_01 = (y_cap + y_load_cap) * vdd * vdd; + getEventResult("NAND2")->setValue(energy_per_trans_01 * Y_num_trans_01); + + return; + } + + void NAND2::propagateTransitionInfo() + { + // Get input signal transition info + const TransitionInfo& trans_A = getInputPort("A")->getTransitionInfo(); + const TransitionInfo& trans_B = getInputPort("B")->getTransitionInfo(); + + double max_freq_mult = max(trans_A.getFrequencyMultiplier(), trans_B.getFrequencyMultiplier()); + const TransitionInfo& scaled_trans_A = trans_A.scaleFrequencyMultiplier(max_freq_mult); + const TransitionInfo& scaled_trans_B = trans_B.scaleFrequencyMultiplier(max_freq_mult); + + double A_prob_00 = scaled_trans_A.getNumberTransitions00() / max_freq_mult; + double A_prob_01 = scaled_trans_A.getNumberTransitions01() / max_freq_mult; + double A_prob_10 = A_prob_01; + double A_prob_11 = scaled_trans_A.getNumberTransitions11() / max_freq_mult; + double B_prob_00 = scaled_trans_B.getNumberTransitions00() / max_freq_mult; + double B_prob_01 = scaled_trans_B.getNumberTransitions01() / max_freq_mult; + double B_prob_10 = B_prob_01; + double B_prob_11 = scaled_trans_B.getNumberTransitions11() / max_freq_mult; + + // Set output transition info + double Y_prob_00 = A_prob_11 * B_prob_11; + double Y_prob_01 = A_prob_11 * B_prob_10 + + A_prob_10 * (B_prob_11 + B_prob_10); + double Y_prob_11 = A_prob_00 + + A_prob_01 * (B_prob_00 + B_prob_10) + + A_prob_10 * (B_prob_00 + B_prob_01) + + A_prob_11 * B_prob_00; + + // Check that probabilities add up to 1.0 with some finite tolerance + ASSERT(LibUtil::Math::isEqual((Y_prob_00 + Y_prob_01 + Y_prob_01 + Y_prob_11), 1.0), + "[Error] " + getInstanceName() + "Output transition probabilities must add up to 1 (" + + (String) Y_prob_00 + ", " + (String) Y_prob_01 + ", " + (String) Y_prob_11 + ")!"); + + // Turn probability of transitions per cycle into number of transitions per time unit + TransitionInfo trans_Y(Y_prob_00 * max_freq_mult, Y_prob_01 * max_freq_mult, Y_prob_11 * max_freq_mult); + getOutputPort("Y")->setTransitionInfo(trans_Y); + return; + } + + void NAND2::cacheStdCell(StdCellLib* cell_lib_, double drive_strength_) + { + // Standard cell cache string + String cell_name = "NAND2_X" + (String) drive_strength_; + + Log::printLine("=== " + cell_name + " ==="); + + // Get parameters + double gate_pitch = cell_lib_->getTechModel()->get("Gate->PitchContacted"); + Map* cache = cell_lib_->getStdCellCache(); + + // Now actually build the full standard cell model + // Create the two input ports + createInputPort("A"); + createInputPort("B"); + createOutputPort("Y"); + + // Adds macros + CellMacros::addNand2(this, "NAND", true, true, true, "A", "B", "Y"); + CellMacros::updateNand2(this, "NAND", drive_strength_); + + // Cache area result + double area = gate_pitch * getTotalHeight() * (1 + getGenProperties()->get("NAND_GatePitches").toDouble()); + cache->set(cell_name + "->Area->Active", area); + Log::printLine(cell_name + "->Area->Active=" + (String) area); + + // -------------------------------------------------------------------- + // Leakage Model Calculation + // -------------------------------------------------------------------- + double leakage_00 = getGenProperties()->get("NAND_LeakagePower_00").toDouble(); + double leakage_01 = getGenProperties()->get("NAND_LeakagePower_01").toDouble(); + double leakage_10 = getGenProperties()->get("NAND_LeakagePower_10").toDouble(); + double leakage_11 = getGenProperties()->get("NAND_LeakagePower_11").toDouble(); + cache->set(cell_name + "->Leakage->!A!B", leakage_00); + cache->set(cell_name + "->Leakage->!AB", leakage_01); + cache->set(cell_name + "->Leakage->A!B", leakage_10); + cache->set(cell_name + "->Leakage->AB", leakage_11); + Log::printLine(cell_name + "->Leakage->!A!B=" + (String) leakage_00); + Log::printLine(cell_name + "->Leakage->!AB=" + (String) leakage_01); + Log::printLine(cell_name + "->Leakage->A!B=" + (String) leakage_10); + Log::printLine(cell_name + "->Leakage->AB=" + (String) leakage_11); + // -------------------------------------------------------------------- + + // Cache event energy results + /* + double event_a_flip = getGenProperties()->get("NAND_A1_Flip").toDouble(); + double event_b_flip = getGenProperties()->get("NAND_A2_Flip").toDouble(); + double event_y_flip = getGenProperties()->get("NAND_ZN_Flip").toDouble(); + + cache->set(cell_name + "->Event_A_Flip", event_a_flip); + cache->set(cell_name + "->Event_B_Flip", event_b_flip); + cache->set(cell_name + "->Event_Y_Flip", event_y_flip); + Log::printLine(cell_name + "->Event_A_Flip=" + (String) event_a_flip); + Log::printLine(cell_name + "->Event_B_Flip=" + (String) event_b_flip); + Log::printLine(cell_name + "->Event_Y_Flip=" + (String) event_y_flip); + */ + // -------------------------------------------------------------------- + // Get Node Capacitances + // -------------------------------------------------------------------- + double a_cap = getNet("A")->getTotalDownstreamCap(); + double b_cap = getNet("B")->getTotalDownstreamCap(); + double y_cap = getNet("Y")->getTotalDownstreamCap(); + + cache->set(cell_name + "->Cap->A", a_cap); + cache->set(cell_name + "->Cap->B", b_cap); + cache->set(cell_name + "->Cap->Y", y_cap); + Log::printLine(cell_name + "->Cap->A=" + (String) a_cap); + Log::printLine(cell_name + "->Cap->B=" + (String) b_cap); + Log::printLine(cell_name + "->Cap->Y=" + (String) y_cap); + // -------------------------------------------------------------------- + + // -------------------------------------------------------------------- + // Build Internal Delay Model + // -------------------------------------------------------------------- + double y_ron = getDriver("NAND_RonZN")->getOutputRes(); + double a_to_y_delay = getDriver("NAND_RonZN")->calculateDelay(); + double b_to_y_delay = getDriver("NAND_RonZN")->calculateDelay(); + + cache->set(cell_name + "->DriveRes->Y", y_ron); + cache->set(cell_name + "->Delay->A_to_Y", a_to_y_delay); + cache->set(cell_name + "->Delay->B_to_Y", b_to_y_delay); + Log::printLine(cell_name + "->DriveRes->Y=" + (String) y_ron); + Log::printLine(cell_name + "->Delay->A_to_Y=" + (String) a_to_y_delay); + Log::printLine(cell_name + "->Delay->B_to_Y=" + (String) b_to_y_delay); + // -------------------------------------------------------------------- + + return; + + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/NOR2.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/NOR2.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_STD_CELLS_NOR2_H__ +#define __DSENT_MODEL_STD_CELLS_NOR2_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" + +namespace DSENT +{ + class NOR2 : public StdCell + { + public: + NOR2(const String& instance_name_, const TechModel* tech_model_); + virtual ~NOR2(); + + public: + // Set a list of properties' name needed to construct model + void initProperties(); + + // Cache the standard cell + void cacheStdCell(StdCellLib* cell_lib_, double drive_strength_); + + protected: + // Build the model + virtual void constructModel(); + virtual void updateModel(); + virtual void useModel(); + virtual void propagateTransitionInfo(); + + }; // class NOR2 +} // namespace DSENT + +#endif // __DSENT_MODEL_STD_CELLS_NOR2_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/NOR2.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/NOR2.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/NOR2.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/CellMacros.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriver.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalLoad.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDelay.hh" + +namespace DSENT +{ + using std::ceil; + using std::max; + + NOR2::NOR2(const String& instance_name_, const TechModel* tech_model_) + : StdCell(instance_name_, tech_model_) + { + initProperties(); + } + + NOR2::~NOR2() + {} + + void NOR2::initProperties() + { + return; + } + + void NOR2::constructModel() + { + // All constructModel should do is create Area/NDDPower/Energy Results as + // well as instantiate any sub-instances using only the hard parameters + + createInputPort("A"); + createInputPort("B"); + createOutputPort("Y"); + + createLoad("A_Cap"); + createLoad("B_Cap"); + createDelay("A_to_Y_delay"); + createDelay("B_to_Y_delay"); + createDriver("Y_Ron", true); + + ElectricalLoad* a_cap = getLoad("A_Cap"); + ElectricalLoad* b_cap = getLoad("A_Cap"); + ElectricalDelay* a_to_y_delay = getDelay("A_to_Y_delay"); + ElectricalDelay* b_to_y_delay = getDelay("B_to_Y_delay"); + ElectricalDriver* y_ron = getDriver("Y_Ron"); + + getNet("A")->addDownstreamNode(a_cap); + getNet("B")->addDownstreamNode(b_cap); + a_cap->addDownstreamNode(a_to_y_delay); + b_cap->addDownstreamNode(b_to_y_delay); + a_to_y_delay->addDownstreamNode(y_ron); + b_to_y_delay->addDownstreamNode(y_ron); + y_ron->addDownstreamNode(getNet("Y")); + + // Create Area result + // Create NDD Power result + createElectricalAtomicResults(); + // Create NOR Event Energy Result + createElectricalEventAtomicResult("NOR2"); + + getEventInfo("Idle")->setStaticTransitionInfos(); + + return; + } + + void NOR2::updateModel() + { + // All updateModel should do is calculate numbers for the Area/NDDPower/Energy + // Results as anything else that needs to be done using either soft or hard parameters + + // Get parameters + double drive_strength = getDrivingStrength(); + Map* cache = getTechModel()->getStdCellLib()->getStdCellCache(); + + // Standard cell cache string + String cell_name = "NOR2_X" + (String) drive_strength; + + // Get timing parameters + getLoad("A_Cap")->setLoadCap(cache->get(cell_name + "->Cap->A")); + getLoad("B_Cap")->setLoadCap(cache->get(cell_name + "->Cap->B")); + getDelay("A_to_Y_delay")->setDelay(cache->get(cell_name + "->Delay->A_to_Y")); + getDelay("B_to_Y_delay")->setDelay(cache->get(cell_name + "->Delay->B_to_Y")); + getDriver("Y_Ron")->setOutputRes(cache->get(cell_name + "->DriveRes->Y")); + + // Set the cell area + getAreaResult("Active")->setValue(cache->get(cell_name + "->ActiveArea")); + getAreaResult("Metal1Wire")->setValue(cache->get(cell_name + "->ActiveArea")); + + return; + } + + void NOR2::useModel() + { + // Get parameters + double drive_strength = getDrivingStrength(); + Map* cache = getTechModel()->getStdCellLib()->getStdCellCache(); + + // Standard cell cache string + String cell_name = "NOR2_X" + (String) drive_strength; + + // Propagate the transition info and get the 0->1 transtion count + propagateTransitionInfo(); + double P_A = getInputPort("A")->getTransitionInfo().getProbability1(); + double P_B = getInputPort("B")->getTransitionInfo().getProbability1(); + double Y_num_trans_01 = getOutputPort("Y")->getTransitionInfo().getNumberTransitions01(); + + // Calculate leakage + double leakage = 0; + leakage += cache->get(cell_name + "->Leakage->!A!B") * (1 - P_A) * (1 - P_B); + leakage += cache->get(cell_name + "->Leakage->!AB") * (1 - P_A) * P_B; + leakage += cache->get(cell_name + "->Leakage->A!B") * P_A * (1 - P_B); + leakage += cache->get(cell_name + "->Leakage->AB") * P_A * P_B; + getNddPowerResult("Leakage")->setValue(leakage); + + // Get VDD + double vdd = getTechModel()->get("Vdd"); + // Get capacitances + double y_cap = cache->get(cell_name + "->Cap->Y"); + double y_load_cap = getNet("Y")->getTotalDownstreamCap(); + + // Calculate NOR2Event energy + double energy_per_trans_01 = (y_cap + y_load_cap) * vdd * vdd; + getEventResult("NOR2")->setValue(energy_per_trans_01 * Y_num_trans_01); + + return; + } + + void NOR2::propagateTransitionInfo() + { + // Get input signal transition info + const TransitionInfo& trans_A = getInputPort("A")->getTransitionInfo(); + const TransitionInfo& trans_B = getInputPort("B")->getTransitionInfo(); + + double max_freq_mult = max(trans_A.getFrequencyMultiplier(), trans_B.getFrequencyMultiplier()); + const TransitionInfo& scaled_trans_A = trans_A.scaleFrequencyMultiplier(max_freq_mult); + const TransitionInfo& scaled_trans_B = trans_B.scaleFrequencyMultiplier(max_freq_mult); + + double A_prob_00 = scaled_trans_A.getNumberTransitions00() / max_freq_mult; + double A_prob_01 = scaled_trans_A.getNumberTransitions01() / max_freq_mult; + double A_prob_10 = A_prob_01; + double A_prob_11 = scaled_trans_A.getNumberTransitions11() / max_freq_mult; + double B_prob_00 = scaled_trans_B.getNumberTransitions00() / max_freq_mult; + double B_prob_01 = scaled_trans_B.getNumberTransitions01() / max_freq_mult; + double B_prob_10 = B_prob_01; + double B_prob_11 = scaled_trans_B.getNumberTransitions11() / max_freq_mult; + + // Set output transition info + double Y_prob_00 = A_prob_00 * B_prob_11 + + A_prob_01 * (B_prob_10 + B_prob_11) + + A_prob_10 * (B_prob_01 + B_prob_11) + + A_prob_11; + double Y_prob_01 = A_prob_00 * B_prob_10 + + A_prob_10 * (B_prob_00 + B_prob_10); + double Y_prob_11 = A_prob_00 * B_prob_00; + + // Check that probabilities add up to 1.0 with some finite tolerance + ASSERT(LibUtil::Math::isEqual((Y_prob_00 + Y_prob_01 + Y_prob_01 + Y_prob_11), 1.0), + "[Error] " + getInstanceName() + "Output transition probabilities must add up to 1 (" + + (String) Y_prob_00 + ", " + (String) Y_prob_01 + ", " + (String) Y_prob_11 + ")!"); + + // Turn probability of transitions per cycle into number of transitions per time unit + TransitionInfo trans_Y(Y_prob_00 * max_freq_mult, Y_prob_01 * max_freq_mult, Y_prob_11 * max_freq_mult); + getOutputPort("Y")->setTransitionInfo(trans_Y); + return; + } + + void NOR2::cacheStdCell(StdCellLib* cell_lib_, double drive_strength_) + { + // Standard cell cache string + String cell_name = "NOR2_X" + (String) drive_strength_; + + Log::printLine("=== " + cell_name + " ==="); + + // Get parameters + double gate_pitch = cell_lib_->getTechModel()->get("Gate->PitchContacted"); + Map* cache = cell_lib_->getStdCellCache(); + + // Now actually build the full standard cell model + // Create the two input ports + createInputPort("A"); + createInputPort("B"); + createOutputPort("Y"); + + // Adds macros + CellMacros::addNor2(this, "NOR", true, true, true, "A", "B", "Y"); + CellMacros::updateNor2(this, "NOR", drive_strength_); + + // Cache area result + double area = gate_pitch * getTotalHeight() * (1 + getGenProperties()->get("NOR_GatePitches").toDouble()); + cache->set(cell_name + "->ActiveArea", area); + Log::printLine(cell_name + "->ActiveArea=" + (String) area); + + // -------------------------------------------------------------------- + // Leakage Model Calculation + // -------------------------------------------------------------------- + double leakage_00 = getGenProperties()->get("NOR_LeakagePower_00").toDouble(); + double leakage_01 = getGenProperties()->get("NOR_LeakagePower_01").toDouble(); + double leakage_10 = getGenProperties()->get("NOR_LeakagePower_10").toDouble(); + double leakage_11 = getGenProperties()->get("NOR_LeakagePower_11").toDouble(); + cache->set(cell_name + "->Leakage->!A!B", leakage_00); + cache->set(cell_name + "->Leakage->!AB", leakage_01); + cache->set(cell_name + "->Leakage->A!B", leakage_10); + cache->set(cell_name + "->Leakage->AB", leakage_11); + Log::printLine(cell_name + "->Leakage->!A!B=" + (String) leakage_00); + Log::printLine(cell_name + "->Leakage->!AB=" + (String) leakage_01); + Log::printLine(cell_name + "->Leakage->A!B=" + (String) leakage_10); + Log::printLine(cell_name + "->Leakage->AB=" + (String) leakage_11); + // -------------------------------------------------------------------- + + /* + // Cache event energy results + double event_a_flip = getGenProperties()->get("NOR_A1_Flip").toDouble(); + double event_b_flip = getGenProperties()->get("NOR_A2_Flip").toDouble(); + double event_zn_flip = getGenProperties()->get("NOR_ZN_Flip").toDouble(); + + cache->set(cell_name + "->Event_A_Flip", event_a_flip); + cache->set(cell_name + "->Event_B_Flip", event_b_flip); + cache->set(cell_name + "->Event_ZN_Flip", event_zn_flip); + Log::printLine(cell_name + "->Event_A_Flip=" + (String) event_a_flip); + Log::printLine(cell_name + "->Event_B_Flip=" + (String) event_b_flip); + Log::printLine(cell_name + "->Event_ZN_Flip=" + (String) event_zn_flip); + */ + + // -------------------------------------------------------------------- + // Get Node Capacitances + // -------------------------------------------------------------------- + // Build abstracted timing model + double a_cap = getNet("A")->getTotalDownstreamCap(); + double b_cap = getNet("B")->getTotalDownstreamCap(); + double y_cap = getNet("Y")->getTotalDownstreamCap(); + + cache->set(cell_name + "->Cap->A", a_cap); + cache->set(cell_name + "->Cap->B", b_cap); + cache->set(cell_name + "->Cap->Y", y_cap); + Log::printLine(cell_name + "->Cap->A_Cap=" + (String) a_cap); + Log::printLine(cell_name + "->Cap->B_Cap=" + (String) b_cap); + Log::printLine(cell_name + "->Cap->Y_Cap=" + (String) y_cap); + // -------------------------------------------------------------------- + + // -------------------------------------------------------------------- + // Build Internal Delay Model + // -------------------------------------------------------------------- + double y_ron = getDriver("NOR_RonZN")->getOutputRes(); + double a_to_y_delay = getDriver("NOR_RonZN")->calculateDelay(); + double b_to_y_delay = getDriver("NOR_RonZN")->calculateDelay(); + + cache->set(cell_name + "->DriveRes->Y", y_ron); + cache->set(cell_name + "->Delay->A_to_Y", a_to_y_delay); + cache->set(cell_name + "->Delay->B_to_Y", b_to_y_delay); + Log::printLine(cell_name + "->DriveRes->Y=" + (String) y_ron); + Log::printLine(cell_name + "->Delay->A_to_Y=" + (String) a_to_y_delay); + Log::printLine(cell_name + "->Delay->B_to_Y=" + (String) b_to_y_delay); + // -------------------------------------------------------------------- + + return; + + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/OR2.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/OR2.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_STD_CELLS_OR2_H__ +#define __DSENT_MODEL_STD_CELLS_OR2_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" + +namespace DSENT +{ + class OR2 : public StdCell + { + public: + OR2(const String& instance_name_, const TechModel* tech_model_); + virtual ~OR2(); + + public: + // Set a list of properties' name needed to construct model + void initProperties(); + // Cache the standard cell + void cacheStdCell(StdCellLib* cell_lib_, double drive_strength_); + + protected: + // Build the model + virtual void constructModel(); + virtual void updateModel(); + virtual void evaluateModel(); + virtual void useModel(); + virtual void propagateTransitionInfo(); + + }; // class OR2 +} // namespace DSENT + +#endif // __DSENT_MODEL_STD_CELLS_OR2_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/OR2.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/OR2.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/OR2.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/CellMacros.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriver.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalLoad.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDelay.hh" + +namespace DSENT +{ + using std::max; + + OR2::OR2(const String& instance_name_, const TechModel* tech_model_) + : StdCell(instance_name_, tech_model_) + { + initProperties(); + } + + OR2::~OR2() + {} + + void OR2::initProperties() + { + return; + } + + void OR2::constructModel() + { + createInputPort("A"); + createInputPort("B"); + createOutputPort("Y"); + + createLoad("A_Cap"); + createLoad("B_Cap"); + createDelay("A_to_Y_delay"); + createDelay("B_to_Y_delay"); + createDriver("Y_Ron", true); + + ElectricalLoad* a_cap = getLoad("A_Cap"); + ElectricalLoad* b_cap = getLoad("B_Cap"); + ElectricalDelay* a_to_y_delay = getDelay("A_to_Y_delay"); + ElectricalDelay* b_to_y_delay = getDelay("B_to_Y_delay"); + ElectricalDriver* y_ron = getDriver("Y_Ron"); + + getNet("A")->addDownstreamNode(a_cap); + getNet("B")->addDownstreamNode(b_cap); + a_cap->addDownstreamNode(a_to_y_delay); + b_cap->addDownstreamNode(b_to_y_delay); + a_to_y_delay->addDownstreamNode(y_ron); + b_to_y_delay->addDownstreamNode(y_ron); + y_ron->addDownstreamNode(getNet("Y")); + + // Create Area result + // Create NDD Power result + createElectricalAtomicResults(); + // Create OR Event Energy Result + createElectricalEventAtomicResult("OR2"); + + getEventInfo("Idle")->setStaticTransitionInfos(); + + return; + } + + void OR2::updateModel() + { + // Get parameters + double drive_strength = getDrivingStrength(); + Map* cache = getTechModel()->getStdCellLib()->getStdCellCache(); + + // Standard cell cache string + const String& cell_name = "OR2_X" + (String) drive_strength; + + // Get timing parameters + getLoad("A_Cap")->setLoadCap(cache->get(cell_name + "->Cap->A")); + getLoad("B_Cap")->setLoadCap(cache->get(cell_name + "->Cap->B")); + getDelay("A_to_Y_delay")->setDelay(cache->get(cell_name + "->Delay->A_to_Y")); + getDelay("B_to_Y_delay")->setDelay(cache->get(cell_name + "->Delay->B_to_Y")); + getDriver("Y_Ron")->setOutputRes(cache->get(cell_name + "->DriveRes->Y")); + + // Set the cell area + getAreaResult("Active")->setValue(cache->get(cell_name + "->ActiveArea")); + getAreaResult("Metal1Wire")->setValue(cache->get(cell_name + "->ActiveArea")); + + return; + } + + void OR2::evaluateModel() + { + return; + } + + void OR2::useModel() + { + // Get parameters + double drive_strength = getDrivingStrength(); + Map* cache = getTechModel()->getStdCellLib()->getStdCellCache(); + + // Stadard cell cache string + const String& cell_name = "OR2_X" + (String) drive_strength; + + // Propagate the transition info and get the 0->1 transtion count + propagateTransitionInfo(); + double P_A = getInputPort("A")->getTransitionInfo().getProbability1(); + double P_B = getInputPort("B")->getTransitionInfo().getProbability1(); + double Y_num_trans_01 = getOutputPort("Y")->getTransitionInfo().getNumberTransitions01(); + + // Calculate leakage + double leakage = 0; + leakage += cache->get(cell_name + "->Leakage->!A!B") * (1 - P_A) * (1 - P_B); + leakage += cache->get(cell_name + "->Leakage->!AB") * (1 - P_A) * P_B; + leakage += cache->get(cell_name + "->Leakage->A!B") * P_A * (1 - P_B); + leakage += cache->get(cell_name + "->Leakage->AB") * P_A * P_B; + getNddPowerResult("Leakage")->setValue(leakage); + + // Get VDD + double vdd = getTechModel()->get("Vdd"); + + // Get capacitances + double y_b_cap = cache->get(cell_name + "->Cap->Y_b"); + double y_cap = cache->get(cell_name + "->Cap->Y"); + double y_load_cap = getNet("Y")->getTotalDownstreamCap(); + + // Calculate OR2Event energy + double energy_per_trans_01 = (y_b_cap + y_cap + y_load_cap) * vdd * vdd; + getEventResult("OR2")->setValue(energy_per_trans_01 * Y_num_trans_01); + + return; + } + + void OR2::propagateTransitionInfo() + { + // Get input signal transition info + const TransitionInfo& trans_A = getInputPort("A")->getTransitionInfo(); + const TransitionInfo& trans_B = getInputPort("B")->getTransitionInfo(); + + double max_freq_mult = max(trans_A.getFrequencyMultiplier(), trans_B.getFrequencyMultiplier()); + const TransitionInfo& scaled_trans_A = trans_A.scaleFrequencyMultiplier(max_freq_mult); + const TransitionInfo& scaled_trans_B = trans_B.scaleFrequencyMultiplier(max_freq_mult); + + double A_prob_00 = scaled_trans_A.getNumberTransitions00() / max_freq_mult; + double A_prob_01 = scaled_trans_A.getNumberTransitions01() / max_freq_mult; + double A_prob_10 = A_prob_01; + double A_prob_11 = scaled_trans_A.getNumberTransitions11() / max_freq_mult; + double B_prob_00 = scaled_trans_B.getNumberTransitions00() / max_freq_mult; + double B_prob_01 = scaled_trans_B.getNumberTransitions01() / max_freq_mult; + double B_prob_10 = B_prob_01; + double B_prob_11 = scaled_trans_B.getNumberTransitions11() / max_freq_mult; + + // Set output transition info + double Y_prob_00 = A_prob_00 * B_prob_00; + double Y_prob_01 = A_prob_00 * B_prob_01 + + A_prob_01 * (B_prob_00 + B_prob_01); + double Y_prob_11 = A_prob_00 * B_prob_11 + + A_prob_01 * (B_prob_10 + B_prob_11) + + A_prob_10 * (B_prob_01 + B_prob_11) + + A_prob_11; + + // Check that probabilities add up to 1.0 with some finite tolerance + ASSERT(LibUtil::Math::isEqual((Y_prob_00 + Y_prob_01 + Y_prob_01 + Y_prob_11), 1.0), "[Error] " + getInstanceName() + + "Output transition probabilities must add up to 1 (" + (String) Y_prob_00 + ", " + + (String) Y_prob_01 + ", " + (String) Y_prob_11 + ")!"); + + // Turn probability of transitions per cycle into number of transitions per time unit + TransitionInfo trans_Y(Y_prob_00 * max_freq_mult, Y_prob_01 * max_freq_mult, Y_prob_11 * max_freq_mult); + getOutputPort("Y")->setTransitionInfo(trans_Y); + return; + } + + // Creates the standard cell, characterizes and abstracts away the details + void OR2::cacheStdCell(StdCellLib* cell_lib_, double drive_strength_) + { + // Get parameters + double gate_pitch = cell_lib_->getTechModel()->get("Gate->PitchContacted"); + Map* cache = cell_lib_->getStdCellCache(); + + // Stadard cell cache string + const String& cell_name = "OR2_X" + (String) drive_strength_; + + Log::printLine("=== " + cell_name + " ==="); + + // Now actually build the full standard cell model + createInputPort("A"); + createInputPort("B"); + createOutputPort("Y"); + + createNet("Y_b"); + + // Adds macros + CellMacros::addNor2(this, "NOR2", false, true, true, "A", "B", "Y_b"); + CellMacros::addInverter(this, "INV", false, true, "Y_b", "Y"); + + // Update macros + CellMacros::updateNor2(this, "NOR2", drive_strength_ * 0.66); + CellMacros::updateInverter(this, "INV", drive_strength_ * 1.0); + + // Cache area result + double area = 0.0; + area += gate_pitch * getTotalHeight() * 1; + area += gate_pitch * getTotalHeight() * getGenProperties()->get("NOR2_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV_GatePitches").toDouble(); + cache->set(cell_name + "->ActiveArea", area); + Log::printLine(cell_name + "->ActiveArea=" + (String)area); + + // -------------------------------------------------------------------- + // Leakage Model Calculation + // -------------------------------------------------------------------- + // Cache leakage power results (for every single signal combination) + double leakage_00 = 0.0; // !A, !B + double leakage_01 = 0.0; // !A, B + double leakage_10 = 0.0; // A, !B + double leakage_11 = 0.0; // A, B + + leakage_00 += getGenProperties()->get("NOR2_LeakagePower_00").toDouble(); + leakage_00 += getGenProperties()->get("INV_LeakagePower_1").toDouble(); + + leakage_01 += getGenProperties()->get("NOR2_LeakagePower_01").toDouble(); + leakage_01 += getGenProperties()->get("INV_LeakagePower_0").toDouble(); + + leakage_10 += getGenProperties()->get("NOR2_LeakagePower_10").toDouble(); + leakage_10 += getGenProperties()->get("INV_LeakagePower_0").toDouble(); + + leakage_11 += getGenProperties()->get("NOR2_LeakagePower_11").toDouble(); + leakage_11 += getGenProperties()->get("INV_LeakagePower_0").toDouble(); + + cache->set(cell_name + "->Leakage->!A!B", leakage_00); + cache->set(cell_name + "->Leakage->!AB", leakage_01); + cache->set(cell_name + "->Leakage->A!B", leakage_10); + cache->set(cell_name + "->Leakage->AB", leakage_11); + Log::printLine(cell_name + "->Leakage->!A!B=" + (String) leakage_00); + Log::printLine(cell_name + "->Leakage->!AB=" + (String) leakage_01); + Log::printLine(cell_name + "->Leakage->A!B=" + (String) leakage_10); + Log::printLine(cell_name + "->Leakage->AB=" + (String) leakage_11); + // -------------------------------------------------------------------- + + // -------------------------------------------------------------------- + // Get Node Capacitances + // -------------------------------------------------------------------- + double a_cap = getNet("A")->getTotalDownstreamCap(); + double b_cap = getNet("B")->getTotalDownstreamCap(); + double y_b_cap = getNet("Y_b")->getTotalDownstreamCap(); + double y_cap = getNet("Y")->getTotalDownstreamCap(); + + cache->set(cell_name + "->Cap->A", a_cap); + cache->set(cell_name + "->Cap->B", b_cap); + cache->set(cell_name + "->Cap->Y_b", y_b_cap); + cache->set(cell_name + "->Cap->Y", y_cap); + Log::printLine(cell_name + "->Cap->A_Cap=" + (String) a_cap); + Log::printLine(cell_name + "->Cap->B_Cap=" + (String) b_cap); + Log::printLine(cell_name + "->Cap->Y_b_Cap=" + (String) y_b_cap); + Log::printLine(cell_name + "->Cap->Y_Cap=" + (String) y_cap); + // -------------------------------------------------------------------- + + // -------------------------------------------------------------------- + // Build Internal Delay Model + // -------------------------------------------------------------------- + double y_ron = getDriver("INV_RonZN")->getOutputRes(); + double a_to_y_delay = getDriver("NOR2_RonZN")->calculateDelay() + + getDriver("INV_RonZN")->calculateDelay(); + double b_to_y_delay = getDriver("NOR2_RonZN")->calculateDelay() + + getDriver("INV_RonZN")->calculateDelay(); + + cache->set(cell_name + "->DriveRes->Y", y_ron); + cache->set(cell_name + "->Delay->A_to_Y", a_to_y_delay); + cache->set(cell_name + "->Delay->B_to_Y", b_to_y_delay); + Log::printLine(cell_name + "->DriveRes->Y=" + (String) y_ron); + Log::printLine(cell_name + "->Delay->A_to_Y=" + (String) a_to_y_delay); + Log::printLine(cell_name + "->Delay->B_to_Y=" + (String) b_to_y_delay); + // -------------------------------------------------------------------- + + return; + } +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/SConscript --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/SConscript Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,47 @@ +# 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. +# +# Authors: Chia-Hsin Owen Chen + +Import('*') + +if env['PROTOCOL'] == 'None': + Return() + +Source('MUX2.cc') +Source('INV.cc') +Source('ADDF.cc') +Source('LATQ.cc') +Source('OR2.cc') +Source('NAND2.cc') +Source('BUF.cc') +Source('DFFQ.cc') +Source('NOR2.cc') +Source('StdCellLib.cc') +Source('CellMacros.cc') +Source('AND2.cc') +Source('StdCell.cc') +Source('XOR2.cc') + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_STD_CELLS_STDCELL_H__ +#define __DSENT_MODEL_STD_CELLS_STDCELL_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" + +namespace DSENT +{ + class StdCell : public ElectricalModel + { + public: + StdCell(const String& instance_name_, const TechModel* tech_model_); + virtual ~StdCell(); + + public: + // Set a list of parameters needed to construct model + virtual void initParameters(); + // Set a list of properties needed to update model + virtual void initProperties(); + + // Get PMOS to NMOS ratio + double getPToNRatio() const; + void setPToNRatio(double p_to_n_ratio_); + // Get height of the standard cell taken by active transistors + double getActiveHeight() const; + void setActiveHeight(double active_height_); + // Get total height of the standard cell including overheads + double getTotalHeight() const; + void setTotalHeight(double total_height_); + + // Construct the full model of the standard cell and cache + // its contents to use for future copies of the standard cell + virtual void cacheStdCell(StdCellLib* cell_lib_, double drive_strength_) = 0; + + protected: + // Build the model, note that this is only available if the + // standard cell has been cached (via cacheStdCellModel) + virtual void constructModel() = 0; + virtual void updateModel() = 0; + + private: + // The PMOS to NMOS ratio + double m_p_to_n_ratio_; + // The height of the standard cell taken by active transitors + double m_active_height_; + // The total height of the standard cell including overheads + double m_total_height_; + + }; // class StdCell +} // namespace DSENT + +#endif // __DSENT_MODEL_STD_CELLS_STDCELL_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" + +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriver.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalLoad.hh" + +#include +#include + +namespace DSENT +{ + StdCell::StdCell(const String& instance_name_, const TechModel* tech_model_) + : ElectricalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + StdCell::~StdCell() + { + + } + + + void StdCell::initParameters() + { + addParameterName("AvailableDrivingStrengths"); + return; + } + + void StdCell::initProperties() + { + addPropertyName("DrivingStrength"); + return; + } + + // Get PMOS to NMOS ratio + double StdCell::getPToNRatio() const + { + return m_p_to_n_ratio_; + } + + void StdCell::setPToNRatio(double p_to_n_ratio_) + { + m_p_to_n_ratio_ = p_to_n_ratio_; + } + + // Get height of the standard cell taken by active transistors + double StdCell::getActiveHeight() const + { + return m_active_height_; + } + + void StdCell::setActiveHeight(double active_height_) + { + m_active_height_ = active_height_; + } + + // Get total height of the standard cell including overheads + double StdCell::getTotalHeight() const + { + return m_total_height_; + } + + void StdCell::setTotalHeight(double total_height_) + { + m_total_height_ = total_height_; + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_STD_CELLS_STDCELLLIBS_H__ +#define __DSENT_MODEL_STD_CELLS_STDCELLLIBS_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" + +namespace DSENT +{ + class TechModel; + class StdCell; + class LibertyFile; + + class StdCellLib + { + public: + StdCellLib(TechModel* tech_model_); + ~StdCellLib(); + + public: + // Get the technology model pointer + const TechModel* getTechModel() const; + // Create a standard cell by name and instance name + StdCell* createStdCell(const String& std_cell_name_, const String& instance_name_) const; + + // Get PMOS to NMOS ratio + double getPToNRatio() const; + void setPToNRatio(double p_to_n_ratio_); + // Get height of the standard cell taken by active transistors + double getActiveHeight() const; + void setActiveHeight(double active_height_); + // Get total height of the standard cell including overheads + double getTotalHeight() const; + void setTotalHeight(double total_height_); + // Get the standard cell library cache of values + Map* getStdCellCache() const; + // Create a list of standard cells + void createLib(); + + // Return a copy of this instance + StdCellLib* clone() const; + + private: + // Disabled copy constructor. Use clone to perform copy operation + StdCellLib(const StdCellLib& std_cell_lib_); + // Generate driving strength string + const String genDrivingStrengthString(const vector& driving_strength_) const; + + private: + // Technology model pointer + TechModel* m_tech_model_; + // The PMOS to NMOS ratio + double m_p_to_n_ratio_; + // The height of the standard cell taken by active transitors + double m_active_height_; + // The total height of the standard cell including overheads + double m_total_height_; + // Std cell values cache + Map* m_std_cell_cache_; + + }; // class StdCellLib +} // namespace DSENT + +#endif // __DSENT_MODEL_STD_CELLS_STDCELLLIBS_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/INV.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ModelGen.hh" + +namespace DSENT +{ + using std::pow; + + StdCellLib::StdCellLib(TechModel* tech_model_) + : m_tech_model_(tech_model_) + { + m_std_cell_cache_ = new Map(); + ASSERT((m_tech_model_ != NULL), "[Error] StdCellLib -> tech_model is NULL"); + createLib(); + } + + StdCellLib::~StdCellLib() + { + delete m_std_cell_cache_; + } + + const TechModel* StdCellLib::getTechModel() const + { + return m_tech_model_; + } + + StdCell* StdCellLib::createStdCell(const String& std_cell_name_, const String& instance_name_) const + { + // Create the standard cell + StdCell* created_cell = ModelGen::createStdCell(std_cell_name_, instance_name_, getTechModel()); + // Grab the variants of each standard cell + String driving_strength_str = getTechModel()->get("StdCell->AvailableSizes"); + // Set library properties for the standard cell + created_cell->setPToNRatio(getPToNRatio()); + created_cell->setActiveHeight(getActiveHeight()); + created_cell->setTotalHeight(getTotalHeight()); + created_cell->setAvailableDrivingStrengths(driving_strength_str); + return created_cell; + } + + // Get PMOS to NMOS ratio + double StdCellLib::getPToNRatio() const + { + return m_p_to_n_ratio_; + } + + void StdCellLib::setPToNRatio(double p_to_n_ratio_) + { + m_p_to_n_ratio_ = p_to_n_ratio_; + } + + // Get height of the standard cell taken by active transistors + double StdCellLib::getActiveHeight() const + { + return m_active_height_; + } + + void StdCellLib::setActiveHeight(double active_height_) + { + m_active_height_ = active_height_; + } + + // Get total height of the standard cell including overheads + double StdCellLib::getTotalHeight() const + { + return m_total_height_; + } + + void StdCellLib::setTotalHeight(double total_height_) + { + m_total_height_ = total_height_; + } + + void StdCellLib::createLib() + { + Log::printLine("Standard cell library creation for tech model " + getTechModel()->get("Name")); + + // Get technology parameters + double nmos_eff_res = getTechModel()->get("Nmos->EffResWidth"); + double pmos_eff_res = getTechModel()->get("Pmos->EffResWidth"); + double gate_min_width = getTechModel()->get("Gate->MinWidth"); + + // Create standard cell common parameters + double pn_ratio = pmos_eff_res / nmos_eff_res; + double nmos_unit_width = gate_min_width; + double pmos_unit_width = gate_min_width * pn_ratio; + + // Derive the height of each cell in the standard cell library, as well as the max Nmos and Pmos widths + double std_cell_total_height = getTechModel()->get("StdCell->Tracks").toDouble() * + (getTechModel()->get("Wire->Metal1->MinWidth").toDouble() + getTechModel()->get("Wire->Metal1->MinSpacing").toDouble()); + double std_cell_active_height = std_cell_total_height / getTechModel()->get("StdCell->HeightOverheadFactor").toDouble(); + + Log::printLine("Standard cell P-to-N ratio (Beta) = " + (String) pn_ratio); + Log::printLine("Standard cell NMOS unit width = " + (String) nmos_unit_width); + Log::printLine("Standard cell PMOS unit width = " + (String) pmos_unit_width); + Log::printLine("Standard cell active height = " + (String) std_cell_active_height); + Log::printLine("Standard cell total height = " + (String) std_cell_total_height); + + setPToNRatio(pn_ratio); + setActiveHeight(std_cell_active_height); + setTotalHeight(std_cell_total_height); + + const vector& cell_sizes = getTechModel()->get("StdCell->AvailableSizes").split("[,]"); + // Create cached standard cells + for (unsigned int i = 0; i < cell_sizes.size(); ++i) + { + StdCell* inv = createStdCell("INV", "CachedINV"); + inv->cacheStdCell(this, cell_sizes[i].toDouble()); + delete inv; + + StdCell* nand2 = createStdCell("NAND2", "CachedNAND2"); + nand2->cacheStdCell(this, cell_sizes[i].toDouble()); + delete nand2; + + StdCell* nor2 = createStdCell("NOR2", "CachedNOR2"); + nor2->cacheStdCell(this, cell_sizes[i].toDouble()); + delete nor2; + + StdCell* mux2 = createStdCell("MUX2", "CachedMUX2"); + mux2->cacheStdCell(this, cell_sizes[i].toDouble()); + delete mux2; + + StdCell* xor2 = createStdCell("XOR2", "CachedXOR2"); + xor2->cacheStdCell(this, cell_sizes[i].toDouble()); + delete xor2; + + StdCell* addf = createStdCell("ADDF", "CachedADDF"); + addf->cacheStdCell(this, cell_sizes[i].toDouble()); + delete addf; + + StdCell* dffq = createStdCell("DFFQ", "CachedDFFQ"); + dffq->cacheStdCell(this, cell_sizes[i].toDouble()); + delete dffq; + + StdCell* latq = createStdCell("LATQ", "CachedLATQ"); + latq->cacheStdCell(this, cell_sizes[i].toDouble()); + delete latq; + + StdCell* or2 = createStdCell("OR2", "CachedOR2"); + or2->cacheStdCell(this, cell_sizes[i].toDouble()); + delete or2; + + StdCell* and2 = createStdCell("AND2", "CachedAND2"); + and2->cacheStdCell(this, cell_sizes[i].toDouble()); + delete and2; + } + + Log::printLine("Standard cell library creation - End"); + return; + } + + StdCellLib* StdCellLib::clone() const + { + StdCellLib* new_lib = new StdCellLib(m_tech_model_); + return new_lib; + } + + const String StdCellLib::genDrivingStrengthString(const vector& driving_strength_) const + { + String ret_str = "["; + for(int i = 0; i < (int)driving_strength_.size() - 1; ++i) + { + ret_str += String(driving_strength_[i]) + ", "; + } + ret_str += String(driving_strength_[driving_strength_.size() - 1]); + ret_str += "]"; + return ret_str; + } + + Map* StdCellLib::getStdCellCache() const + { + return m_std_cell_cache_; + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/XOR2.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/XOR2.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_STD_CELLS_XOR2_H__ +#define __DSENT_MODEL_STD_CELLS_XOR2_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" + +namespace DSENT +{ + class XOR2 : public StdCell + { + public: + XOR2(const String& instance_name_, const TechModel* tech_model_); + virtual ~XOR2(); + + public: + // Set a list of properties' name needed to construct model + void initProperties(); + + // Cache the standard cell + void cacheStdCell(StdCellLib* cell_lib_, double drive_strength_); + + protected: + // Build the model + virtual void constructModel(); + virtual void updateModel(); + virtual void evaluateModel(); + virtual void useModel(); + virtual void propagateTransitionInfo(); + + }; // class XOR2 +} // namespace DSENT + +#endif // __DSENT_MODEL_STD_CELLS_XOR2_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/std_cells/XOR2.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/std_cells/XOR2.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,376 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/XOR2.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/EventInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/TransitionInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/CellMacros.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriver.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalLoad.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDelay.hh" + +namespace DSENT +{ + using std::ceil; + using std::max; + + XOR2::XOR2(const String& instance_name_, const TechModel* tech_model_) + : StdCell(instance_name_, tech_model_) + { + initProperties(); + } + + XOR2::~XOR2() + {} + + void XOR2::initProperties() + { + return; + } + + void XOR2::constructModel() + { + // All constructModel should do is create Area/NDDPower/Energy Results as + // well as instantiate any sub-instances using only the hard parameters + + createInputPort("A"); + createInputPort("B"); + createOutputPort("Y"); + + createLoad("A_Cap"); + createLoad("B_Cap"); + createDelay("A_to_Y_delay"); + createDelay("B_to_Y_delay"); + createDriver("Y_Ron", true); + + ElectricalLoad* a_cap = getLoad("A_Cap"); + ElectricalLoad* b_cap = getLoad("B_Cap"); + ElectricalDelay* a_to_y_delay = getDelay("A_to_Y_delay"); + ElectricalDelay* b_to_y_delay = getDelay("B_to_Y_delay"); + ElectricalDriver* y_ron = getDriver("Y_Ron"); + + getNet("A")->addDownstreamNode(a_cap); + getNet("B")->addDownstreamNode(b_cap); + a_cap->addDownstreamNode(a_to_y_delay); + b_cap->addDownstreamNode(b_to_y_delay); + a_to_y_delay->addDownstreamNode(y_ron); + b_to_y_delay->addDownstreamNode(y_ron); + y_ron->addDownstreamNode(getNet("Y")); + + // Create Area result + // Create NDD Power result + createElectricalAtomicResults(); + // Create XOR2 Event Energy Result + createElectricalEventAtomicResult("XOR2"); + + getEventInfo("Idle")->setStaticTransitionInfos(); + + return; + } + + void XOR2::updateModel() + { + // Get parameters + double drive_strength = getDrivingStrength(); + Map* cache = getTechModel()->getStdCellLib()->getStdCellCache(); + + // Standard cell cache string + String cell_name = "XOR2_X" + (String) drive_strength; + + // Get timing parameters + getLoad("A_Cap")->setLoadCap(cache->get(cell_name + "->Cap->A")); + getLoad("B_Cap")->setLoadCap(cache->get(cell_name + "->Cap->B")); + + getDelay("A_to_Y_delay")->setDelay(cache->get(cell_name + "->Delay->A_to_Y")); + getDelay("B_to_Y_delay")->setDelay(cache->get(cell_name + "->Delay->B_to_Y")); + + getDriver("Y_Ron")->setOutputRes(cache->get(cell_name + "->DriveRes->Y")); + + // Set the cell area + getAreaResult("Active")->setValue(cache->get(cell_name + "->ActiveArea")); + getAreaResult("Metal1Wire")->setValue(cache->get(cell_name + "->ActiveArea")); + + return; + } + + void XOR2::evaluateModel() + { + return; + } + + void XOR2::useModel() + { + // Get parameters + double drive_strength = getDrivingStrength(); + Map* cache = getTechModel()->getStdCellLib()->getStdCellCache(); + + // Standard cell cache string + String cell_name = "XOR2_X" + (String) drive_strength; + + // Propagate the transition info and get the 0->1 transtion count + propagateTransitionInfo(); + double P_A = getInputPort("A")->getTransitionInfo().getProbability1(); + double P_B = getInputPort("B")->getTransitionInfo().getProbability1(); + double A_num_trans_01 = getInputPort("A")->getTransitionInfo().getNumberTransitions01(); + double B_num_trans_01 = getInputPort("B")->getTransitionInfo().getNumberTransitions01(); + double Y_num_trans_01 = getOutputPort("Y")->getTransitionInfo().getNumberTransitions01(); + + // Calculate leakage + double leakage = 0; + leakage += cache->get(cell_name + "->Leakage->!A!B") * (1 - P_A) * (1 - P_B); + leakage += cache->get(cell_name + "->Leakage->!AB") * (1 - P_A) * P_B; + leakage += cache->get(cell_name + "->Leakage->A!B") * P_A * (1 - P_B); + leakage += cache->get(cell_name + "->Leakage->AB") * P_A * P_B; + getNddPowerResult("Leakage")->setValue(leakage); + + // Get VDD + double vdd = getTechModel()->get("Vdd"); + + // Get capacitances + double a_b_cap = cache->get(cell_name + "->Cap->A_b"); + double b_b_cap = cache->get(cell_name + "->Cap->B_b"); + double y_cap = cache->get(cell_name + "->Cap->Y"); + double y_load_cap = getNet("Y")->getTotalDownstreamCap(); + + // Calculate XOR Event energy + double xor2_event_result = 0.0; + xor2_event_result += a_b_cap * A_num_trans_01; + xor2_event_result += b_b_cap * B_num_trans_01; + xor2_event_result += (y_cap + y_load_cap) * Y_num_trans_01; + xor2_event_result *= vdd * vdd; + getEventResult("XOR2")->setValue(xor2_event_result); + + return; + } + + void XOR2::propagateTransitionInfo() + { + // Get input signal transition info + const TransitionInfo& trans_A = getInputPort("A")->getTransitionInfo(); + const TransitionInfo& trans_B = getInputPort("B")->getTransitionInfo(); + + double max_freq_mult = max(trans_A.getFrequencyMultiplier(), trans_B.getFrequencyMultiplier()); + const TransitionInfo& scaled_trans_A = trans_A.scaleFrequencyMultiplier(max_freq_mult); + const TransitionInfo& scaled_trans_B = trans_B.scaleFrequencyMultiplier(max_freq_mult); + + + double A_prob_00 = scaled_trans_A.getNumberTransitions00() / max_freq_mult; + double A_prob_01 = scaled_trans_A.getNumberTransitions01() / max_freq_mult; + double A_prob_10 = A_prob_01; + double A_prob_11 = scaled_trans_A.getNumberTransitions11() / max_freq_mult; + double B_prob_00 = scaled_trans_B.getNumberTransitions00() / max_freq_mult; + double B_prob_01 = scaled_trans_B.getNumberTransitions01() / max_freq_mult; + double B_prob_10 = B_prob_01; + double B_prob_11 = scaled_trans_B.getNumberTransitions11() / max_freq_mult; + + // Set output transition info + double Y_prob_00 = A_prob_00 * B_prob_00 + + A_prob_01 * B_prob_01 + + A_prob_10 * B_prob_10 + + A_prob_11 * B_prob_11; + double Y_prob_01 = A_prob_00 * B_prob_01 + + A_prob_01 * B_prob_00 + + A_prob_10 * B_prob_11 + + A_prob_11 * B_prob_10; + double Y_prob_11 = A_prob_00 * B_prob_11 + + A_prob_01 * B_prob_10 + + A_prob_10 * B_prob_01 + + A_prob_11 * B_prob_00; + + // Check that probabilities add up to 1.0 with some finite tolerance + ASSERT(LibUtil::Math::isEqual((Y_prob_00 + Y_prob_01 + Y_prob_01 + Y_prob_11), 1.0), + "[Error] " + getInstanceName() + "Output transition probabilities must add up to 1 (" + + (String) Y_prob_00 + ", " + (String) Y_prob_01 + ", " + (String) Y_prob_11 + ")!"); + + // Turn probability of transitions per cycle into number of transitions per time unit + TransitionInfo trans_Y(Y_prob_00 * max_freq_mult, Y_prob_01 * max_freq_mult, Y_prob_11 * max_freq_mult); + getOutputPort("Y")->setTransitionInfo(trans_Y); + return; + } + + // Creates the standard cell, characterizes and abstracts away the details + void XOR2::cacheStdCell(StdCellLib* cell_lib_, double drive_strength_) + { + // Get parameters + double gate_pitch = cell_lib_->getTechModel()->get("Gate->PitchContacted"); + Map* cache = cell_lib_->getStdCellCache(); + + // Standard cell cache string + String cell_name = "XOR2_X" + (String) drive_strength_; + + Log::printLine("=== " + cell_name + " ==="); + + // Now actually build the full standard cell model + createInputPort("A"); + createInputPort("B"); + createOutputPort("Y"); + + createNet("A_b"); + createNet("B_b"); + + // Adds macros + CellMacros::addInverter(this, "INV1", false, true, "A", "A_b"); + CellMacros::addInverter(this, "INV2", false, true, "B", "B_b"); + CellMacros::addTristate(this, "INVZ1", true, true, true, true, "B", "A", "A_b", "Y"); + CellMacros::addTristate(this, "INVZ2", true, true, true, true, "B_b", "A_b", "A", "Y"); + + // I have no idea how to size each of the parts haha + CellMacros::updateInverter(this, "INV1", drive_strength_ * 0.500); + CellMacros::updateInverter(this, "INV2", drive_strength_ * 0.500); + CellMacros::updateTristate(this, "INVZ1", drive_strength_ * 1.000); + CellMacros::updateTristate(this, "INVZ2", drive_strength_ * 1.000); + + // Cache area result + double area = 0.0; + area += gate_pitch * getTotalHeight() * 1; + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV1_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV2_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INVZ1_GatePitches").toDouble(); + area += gate_pitch * getTotalHeight() * getGenProperties()->get("INVZ2_GatePitches").toDouble(); + cache->set(cell_name + "->ActiveArea", area); + Log::printLine(cell_name + "->ActiveArea=" + (String) area); + + // -------------------------------------------------------------------- + // Leakage Model Calculation + // -------------------------------------------------------------------- + // Cache leakage power results (for every single signal combination) + double leakage_00 = 0; //!A, !B + double leakage_01 = 0; //!A, B + double leakage_10 = 0; //A, !B + double leakage_11 = 0; //A, B + + //This is so painful... + leakage_00 += getGenProperties()->get("INV1_LeakagePower_0").toDouble(); + leakage_00 += getGenProperties()->get("INV2_LeakagePower_0").toDouble(); + leakage_00 += getGenProperties()->get("INVZ1_LeakagePower_010_0").toDouble(); + leakage_00 += getGenProperties()->get("INVZ2_LeakagePower_101_0").toDouble(); + + leakage_01 += getGenProperties()->get("INV1_LeakagePower_0").toDouble(); + leakage_01 += getGenProperties()->get("INV2_LeakagePower_1").toDouble(); + leakage_01 += getGenProperties()->get("INVZ1_LeakagePower_011_1").toDouble(); + leakage_01 += getGenProperties()->get("INVZ2_LeakagePower_100_1").toDouble(); + + leakage_10 += getGenProperties()->get("INV1_LeakagePower_1").toDouble(); + leakage_10 += getGenProperties()->get("INV2_LeakagePower_0").toDouble(); + leakage_10 += getGenProperties()->get("INVZ1_LeakagePower_100_1").toDouble(); + leakage_10 += getGenProperties()->get("INVZ2_LeakagePower_011_1").toDouble(); + + leakage_11 += getGenProperties()->get("INV1_LeakagePower_1").toDouble(); + leakage_11 += getGenProperties()->get("INV2_LeakagePower_1").toDouble(); + leakage_11 += getGenProperties()->get("INVZ1_LeakagePower_101_0").toDouble(); + leakage_11 += getGenProperties()->get("INVZ2_LeakagePower_010_0").toDouble(); + + cache->set(cell_name + "->Leakage->!A!B", leakage_00); + cache->set(cell_name + "->Leakage->!AB", leakage_01); + cache->set(cell_name + "->Leakage->A!B", leakage_10); + cache->set(cell_name + "->Leakage->AB", leakage_11); + Log::printLine(cell_name + "->Leakage->!A!B=" + (String) leakage_00); + Log::printLine(cell_name + "->Leakage->!AB=" + (String) leakage_01); + Log::printLine(cell_name + "->Leakage->A!B=" + (String) leakage_10); + Log::printLine(cell_name + "->Leakage->AB=" + (String) leakage_11); + // -------------------------------------------------------------------- + + // Cache event energy results + /* + double event_a_flip = 0.0; + event_a_flip += getGenProperties()->get("INV1_A_Flip").toDouble() + getGenProperties()->get("INV1_ZN_Flip").toDouble(); + event_a_flip += getGenProperties()->get("INVZ1_OE_Flip").toDouble() + getGenProperties()->get("INVZ1_OEN_Flip").toDouble(); + event_a_flip += getGenProperties()->get("INVZ2_OE_Flip").toDouble() + getGenProperties()->get("INVZ2_OEN_Flip").toDouble(); + cache->set(cell_name + "->Event_A_Flip", event_a_flip); + Log::printLine(cell_name + "->Event_A_Flip=" + (String) event_a_flip); + + double event_b_flip = 0.0; + event_b_flip += getGenProperties()->get("INV2_A_Flip").toDouble() + getGenProperties()->get("INV2_ZN_Flip").toDouble(); + event_b_flip += getGenProperties()->get("INVZ1_A_Flip").toDouble(); + event_b_flip += getGenProperties()->get("INVZ2_A_Flip").toDouble(); + cache->set(cell_name + "->Event_B_Flip", event_b_flip); + Log::printLine(cell_name + "->Event_B_Flip=" + (String) event_b_flip); + + double event_y_flip = 0.0; + event_y_flip += getGenProperties()->get("INVZ1_ZN_Flip").toDouble(); + event_y_flip += getGenProperties()->get("INVZ2_ZN_Flip").toDouble(); + cache->set(cell_name + "->Event_Y_Flip", event_y_flip); + Log::printLine(cell_name + "->Event_Y_Flip=" + (String) event_y_flip); + */ + + // -------------------------------------------------------------------- + // Get Node Capacitances + // -------------------------------------------------------------------- + // Build abstracted timing model + double a_cap = getNet("A")->getTotalDownstreamCap(); + double b_cap = getNet("B")->getTotalDownstreamCap(); + double a_b_cap = getNet("A_b")->getTotalDownstreamCap(); + double b_b_cap = getNet("B_b")->getTotalDownstreamCap(); + double y_cap = getNet("Y")->getTotalDownstreamCap(); + + cache->set(cell_name + "->Cap->A", a_cap); + cache->set(cell_name + "->Cap->B", b_cap); + cache->set(cell_name + "->Cap->A_b", a_b_cap); + cache->set(cell_name + "->Cap->B_b", b_b_cap); + cache->set(cell_name + "->Cap->Y", y_cap); + Log::printLine(cell_name + "->Cap->A=" + (String) a_cap); + Log::printLine(cell_name + "->Cap->B=" + (String) b_cap); + Log::printLine(cell_name + "->Cap->A=" + (String) a_b_cap); + Log::printLine(cell_name + "->Cap->B=" + (String) b_b_cap); + Log::printLine(cell_name + "->Cap->Y=" + (String) y_cap); + // -------------------------------------------------------------------- + + // -------------------------------------------------------------------- + // Build Internal Delay Model + // -------------------------------------------------------------------- + double y_ron = (getDriver("INVZ1_RonZN")->getOutputRes() + getDriver("INVZ2_RonZN")->getOutputRes()) / 2; + + double a_to_y_delay = 0.0; + a_to_y_delay += getDriver("INV1_RonZN")->calculateDelay(); + a_to_y_delay += max(getDriver("INVZ1_RonZN")->calculateDelay(), getDriver("INVZ2_RonZN")->calculateDelay()); + + double b_to_y_delay = 0.0; + b_to_y_delay += max(getDriver("INVZ1_RonZN")->calculateDelay(), getDriver("INV2_RonZN")->calculateDelay() + getDriver("INVZ2_RonZN")->calculateDelay()); + + cache->set(cell_name + "->DriveRes->Y", y_ron); + cache->set(cell_name + "->Delay->A_to_Y", a_to_y_delay); + cache->set(cell_name + "->Delay->B_to_Y", b_to_y_delay); + Log::printLine(cell_name + "->DriveRes->Y=" + (String) y_ron); + Log::printLine(cell_name + "->Delay->A_to_Y=" + (String) a_to_y_delay); + Log::printLine(cell_name + "->Delay->B_to_Y=" + (String) b_to_y_delay); + // -------------------------------------------------------------------- + + return; + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDelay.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDelay.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_ELECTRICAL_DELAY_H__ +#define __DSENT_MODEL_ELECTRICAL_DELAY_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingNode.hh" + +namespace DSENT +{ + class ElectricalLoad; + + class ElectricalDelay : public ElectricalTimingNode + { + public: + ElectricalDelay(const String& instance_name_, ElectricalModel* model_); + virtual ~ElectricalDelay(); + + public: + // Specify an ideal delay + void setDelay(double delay_); + // Get the ideal delay + double getDelay() const; + // Calculate delay + double calculateDelay() const; + // Calculate transition + double calculateTransition() const; + // get maximum of upstream drive resistance + double getMaxUpstreamRes() const; + // get total amount of downstream load capacitance + double getTotalDownstreamCap() const; + + private: + // Disable copy constructor + ElectricalDelay(const ElectricalDelay& net_); + + private: + // The amount of ideal delay + double m_delay_; + }; + +} // namespace DSENT + +#endif // __DSENT_MODEL_ELECTRICAL_DELAY_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDelay.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDelay.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + + +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDelay.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalLoad.hh" + +namespace DSENT +{ + //------------------------------------------------------------------------- + // Electrical Delay + //------------------------------------------------------------------------- + + ElectricalDelay::ElectricalDelay(const String& instance_name_, ElectricalModel* model_) + : ElectricalTimingNode(instance_name_, model_), m_delay_(0.0) + { + + } + + ElectricalDelay::~ElectricalDelay() + { + + } + + void ElectricalDelay::setDelay(double delay_) + { + m_delay_ = delay_; + return; + } + + double ElectricalDelay::getDelay() const + { + return m_delay_; + } + + double ElectricalDelay::calculateDelay() const + { + return m_delay_; + } + + double ElectricalDelay::calculateTransition() const + { + return 1.386 * getMaxUpstreamRes() * getTotalDownstreamCap(); + } + + double ElectricalDelay::getMaxUpstreamRes() const + { + return ElectricalTimingNode::getMaxUpstreamRes(); + } + + double ElectricalDelay::getTotalDownstreamCap() const + { + return ElectricalTimingNode::getTotalDownstreamCap(); + } + +} // namespace DSENT + + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriver.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriver.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_ELECTRICAL_DRIVER_H__ +#define __DSENT_MODEL_ELECTRICAL_DRIVER_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingNode.hh" + +namespace DSENT +{ + class ElectricalModel; + + class ElectricalDriver : public ElectricalTimingNode + { + public: + ElectricalDriver(const String& instance_name_, ElectricalModel* model_, bool sizable_); + virtual ~ElectricalDriver(); + + public: + // Set the output resistance of this driver + void setOutputRes(double output_res_); + // Get the output resistance of this driver + double getOutputRes() const; + // Calculate delay due to total load capacitance + double calculateDelay() const; + // Calculate transition + double calculateTransition() const; + // get maximum of upstream drive resistance + double getMaxUpstreamRes() const; + + // Get whether the driver is sizable + bool isSizable() const; + // Return true if the instance has minimum driving strength + bool hasMinDrivingStrength() const; + // Return true if the instance has maximum driving strength + bool hasMaxDrivingStrength() const; + // Increase driving strength index by 1 + void increaseDrivingStrength(); + // Decrease driving strength index by 1 + void decreaseDrivingStrength(); + + bool isDriver() const; + + private: + // Disable copy constructor + ElectricalDriver(const ElectricalDriver& port_); + + private: + // Name of this instance + String m_instance_name_; + // Output resistance + double m_output_res_; + // Sizable flag + bool m_sizable_; + }; +} // namespace DSENT + +#endif // __DSENT_MODEL_ELECTRICAL_DRIVER_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriver.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriver.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + + +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriver.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" + +namespace DSENT +{ + ElectricalDriver::ElectricalDriver(const String& instance_name_, ElectricalModel* model_, bool sizable_) + : ElectricalTimingNode(instance_name_, model_), m_output_res_(0.0), m_sizable_(sizable_) + { + + } + + ElectricalDriver::~ElectricalDriver() + { + + } + + void ElectricalDriver::setOutputRes(double output_res_) + { + m_output_res_ = output_res_; + return; + } + + double ElectricalDriver::getOutputRes() const + { + return m_output_res_; + } + + double ElectricalDriver::calculateDelay() const + { + return 0.693 * m_output_res_ * getTotalDownstreamCap(); + } + + double ElectricalDriver::calculateTransition() const + { + return 1.386 * getMaxUpstreamRes() * getTotalDownstreamCap(); + } + + double ElectricalDriver::getMaxUpstreamRes() const + { + return m_output_res_; + } + + bool ElectricalDriver::isSizable() const + { + return m_sizable_; + } + + bool ElectricalDriver::hasMaxDrivingStrength() const + { + if (!isSizable()) + { + return true; + } + return (getModel() == NULL) || (getModel()->hasMaxDrivingStrength()); + } + + bool ElectricalDriver::hasMinDrivingStrength() const + { + if (!isSizable()) + { + return true; + } + return (getModel() == NULL) || (getModel()->hasMinDrivingStrength()); + } + + void ElectricalDriver::increaseDrivingStrength() + { + ASSERT(isSizable(), "[Error] " + getInstanceName() + + " -> Attempted to size up unsizable driver!"); + if(!hasMaxDrivingStrength()) + { + getModel()->increaseDrivingStrength(); + } + return; + } + + void ElectricalDriver::decreaseDrivingStrength() + { + ASSERT(isSizable(), "[Error] " + getInstanceName() + + " -> Attempted to size down unsizable driver!"); + if(!hasMinDrivingStrength()) + { + getModel()->decreaseDrivingStrength(); + } + return; + } + + bool ElectricalDriver::isDriver() const + { + return true; + } +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriverMultiplier.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriverMultiplier.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_ELECTRICAL_DRIVER_MULTIPLIER_H__ +#define __DSENT_MODEL_ELECTRICAL_DRIVER_MULTIPLIER_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingNode.hh" + +namespace DSENT +{ + // Simple class that can be used to mimic the presence of multiple drivers + // output drivers (each driving one of the downstream loads) when only one + // such driver has been instantiated (such as models that take advantage of + // bit duplicattion). When the downsream loads differ in load cap, it + // just returns the largest of the caps + class ElectricalDriverMultiplier : public ElectricalTimingNode + { + public: + ElectricalDriverMultiplier(const String& instance_name_, ElectricalModel* model_); + virtual ~ElectricalDriverMultiplier(); + + public: + // Calculate drive resistance of this node; + double calculateDriveRes(double input_drive_res_) const; + // Calculate wiring delay (or net delay) + double calculateDelay() const; + // Calculate transition + double calculateTransition() const; + // get total amount of downstream load capacitance + double getTotalDownstreamCap() const; + + private: + // Disable copy constructor + ElectricalDriverMultiplier(const ElectricalDriverMultiplier& net_); + + private: + // Name of this instance + String m_instance_name_; + }; + +} // namespace DSENT + +#endif // __DSENT_MODEL_ELECTRICAL_DRIVER_MULTIPLIER_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriverMultiplier.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriverMultiplier.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + + +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriverMultiplier.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalLoad.hh" + +namespace DSENT +{ + //------------------------------------------------------------------------- + // Electrical Net + //------------------------------------------------------------------------- + + ElectricalDriverMultiplier::ElectricalDriverMultiplier(const String& instance_name_, ElectricalModel* model_) + : ElectricalTimingNode(instance_name_, model_) + { + + } + + ElectricalDriverMultiplier::~ElectricalDriverMultiplier() + { + + } + + double ElectricalDriverMultiplier::calculateDriveRes( double input_drive_res_) const + { + return input_drive_res_; + } + + double ElectricalDriverMultiplier::calculateDelay() const + { + // This is just a model helper element, it does not contribute delay + return 0; + } + + double ElectricalDriverMultiplier::calculateTransition() const + { + return getMaxUpstreamRes() * getTotalDownstreamCap(); + } + + double ElectricalDriverMultiplier::getTotalDownstreamCap() const + { + // Finds the max of the load caps (as opposed to summing) + double max_cap = 0; + vector* downstream_nodes = ElectricalTimingNode::getDownstreamNodes(); + for (unsigned int i = 0; i < downstream_nodes->size(); ++i) + { + max_cap = std::max(max_cap, downstream_nodes->at(i)->getTotalDownstreamCap()); + } + + return max_cap; + } + +} // namespace DSENT + + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalLoad.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalLoad.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_ELECTRICAL_LOAD_H__ +#define __DSENT_MODEL_ELECTRICAL_LOAD_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingNode.hh" + +namespace DSENT +{ + class ElectricalModel; + class ElectricalDriver; + + class ElectricalLoad : public ElectricalTimingNode + { + public: + ElectricalLoad(const String& instance_name_, ElectricalModel* model_); + virtual ~ElectricalLoad(); + + public: + // Set the input capacitance of this input port + void setLoadCap(double load_cap_); + // Get the load capacitance + double getLoadCap() const; + // Get total load capacitance + double getTotalDownstreamCap() const; + // Calculate delay due to total load capacitance + double calculateDelay() const; + // Calculate transition + double calculateTransition() const; + + bool isLoad() const; + + private: + // Disable copy constructor + ElectricalLoad(const ElectricalLoad& load_); + + private: + // Load capacitance + double m_load_cap_; + }; +} // namespace DSENT + +#endif // __DSENT_MODEL_ELECTRICAL_LOAD_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalLoad.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalLoad.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + + +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalLoad.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriver.hh" + +namespace DSENT +{ + ElectricalLoad::ElectricalLoad(const String& instance_name_, ElectricalModel* model_) + : ElectricalTimingNode(instance_name_, model_), m_load_cap_(0.0) + { + } + + ElectricalLoad::~ElectricalLoad() + { + } + + void ElectricalLoad::setLoadCap(double load_cap_) + { + m_load_cap_ = load_cap_; + return; + } + + double ElectricalLoad::getLoadCap() const + { + return m_load_cap_; + } + + bool ElectricalLoad::isLoad() const + { + return true; + } + + double ElectricalLoad::calculateDelay() const + { + return 0; + } + + double ElectricalLoad::calculateTransition() const + { + return 1.386 * getMaxUpstreamRes() * getTotalDownstreamCap(); + } + + double ElectricalLoad::getTotalDownstreamCap() const + { + return m_load_cap_; + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_ELECTRICAL_NET_H__ +#define __DSENT_MODEL_ELECTRICAL_NET_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingNode.hh" + +namespace DSENT +{ + class ElectricalLoad; + + class ElectricalNet : public ElectricalTimingNode + { + public: + ElectricalNet(const String& instance_name_, ElectricalModel* model_); + virtual ~ElectricalNet(); + + public: + // Set distributed res/cap + void setDistributedRes(double distributed_res_); + void setDistributedCap(double distributed_cap_); + // Get distributed res/cap + double getDistributedRes() const; + double getDistributedCap() const; + // Calculate wiring delay (or net delay) + double calculateDelay() const; + // Calculate transition + double calculateTransition() const; + // get maximum of upstream drive resistance + double getMaxUpstreamRes() const; + // get total amount of downstream load capacitance + double getTotalDownstreamCap() const; + + virtual bool isNet() const; + + private: + // Disable copy constructor + ElectricalNet(const ElectricalNet& net_); + + private: + // Name of this instance + String m_instance_name_; + // Distributed capacitance and resistance of the net + double m_distributed_res_; + double m_distributed_cap_; + }; + +} // namespace DSENT + +#endif // __DSENT_MODEL_ELECTRICAL_NET_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + + +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalLoad.hh" + +namespace DSENT +{ + //------------------------------------------------------------------------- + // Electrical Net + //------------------------------------------------------------------------- + + ElectricalNet::ElectricalNet(const String& instance_name_, ElectricalModel* model_) + : ElectricalTimingNode(instance_name_, model_), m_distributed_res_(0), m_distributed_cap_(0) + { + + } + + ElectricalNet::~ElectricalNet() + { + + } + + double ElectricalNet::calculateDelay() const + { + // Remember that this is a pi model, delay is distributed cap * distributed_res / 2 + + // distributed res * (other downstream caps) + return 0.693 * (getTotalDownstreamCap() - m_distributed_cap_ / 2) * m_distributed_res_; + } + + double ElectricalNet::calculateTransition() const + { + return 1.386 * getMaxUpstreamRes() * (m_distributed_cap_ * 0.2 + ElectricalTimingNode::getTotalDownstreamCap()); + } + + double ElectricalNet::getMaxUpstreamRes() const + { + return m_distributed_res_ + ElectricalTimingNode::getMaxUpstreamRes(); + } + + double ElectricalNet::getTotalDownstreamCap() const + { + return m_distributed_cap_ + ElectricalTimingNode::getTotalDownstreamCap(); + } + + void ElectricalNet::setDistributedCap(double distributed_cap_) + { + m_distributed_cap_ = distributed_cap_; + return; + } + + void ElectricalNet::setDistributedRes(double distributed_res_) + { + m_distributed_res_ = distributed_res_; + return; + } + + double ElectricalNet::getDistributedCap() const + { + return m_distributed_cap_; + } + + double ElectricalNet::getDistributedRes() const + { + return m_distributed_res_; + } + + bool ElectricalNet::isNet() const + { + return true; + } + +} // namespace DSENT + + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingNode.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingNode.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_ELECTRICAL_TIMING_NODE_H__ +#define __DSENT_MODEL_ELECTRICAL_TIMING_NODE_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" + +namespace DSENT +{ + class ElectricalModel; + + class ElectricalTimingNode + { + public: + // The starting visited number flag of all timing nodes + static const int TIMING_NODE_INIT_VISITED_NUM; + + public: + ElectricalTimingNode(const String& instance_name_, ElectricalModel* model_); + virtual ~ElectricalTimingNode(); + + public: + + // Calculate the delay this node contributes + virtual double calculateDelay() const = 0; + // Calculate the transition at this node + virtual double calculateTransition() const = 0; + // get maximum of upstream drive resistance + virtual double getMaxUpstreamRes() const; + // get total amount of downstream load capacitance + virtual double getTotalDownstreamCap() const; + // Return instance name + const String& getInstanceName() const; + // get upstream timing nodes + vector* getUpstreamNodes() const; + // get downstream timing nodes + vector* getDownstreamNodes() const; + // Connect a downstream timing node + void addDownstreamNode(ElectricalTimingNode* node_); + // Return the node's parent model + ElectricalModel* getModel(); + const ElectricalModel* getModel() const; + // Set/get false path marker + void setFalsePath(bool false_path_); + bool getFalsePath() const; + + virtual bool isDriver() const; + virtual bool isNet() const; + virtual bool isLoad() const; + + + //----------------------------------------------------------------- + // Functions for delay optimization + //----------------------------------------------------------------- + // Return true if the instance has minimum driving strength + virtual bool hasMinDrivingStrength() const; + // Return true if the instance has maximum driving strength + virtual bool hasMaxDrivingStrength() const; + // Increase driving strength index by 1 + virtual void increaseDrivingStrength(); + // Decrease driving strength index by 1 + virtual void decreaseDrivingStrength(); + //----------------------------------------------------------------- + + //----------------------------------------------------------------- + // Node variables for critical path delay calculations + //----------------------------------------------------------------- + // Critical path marker + void setCritPath(int crit_path_); + int getCritPath() const; + // Visited parity marker + void setVisitedNum(int visited_parity_); + int getVisitedNum() const; + // Delay left in this path + void setDelayLeft(double delay_left_); + double getDelayLeft() const; + //----------------------------------------------------------------- + + + private: + // Disable copy constructor + ElectricalTimingNode(const ElectricalTimingNode& node_); + + private: + // Name of this instance + String m_instance_name_; + // A pointer to the model that contains this node + ElectricalModel* m_model_; + // Upstream electrical nets + vector* m_upstream_nodes_; + // Downstream electrical nets + vector* m_downstream_nodes_; + // False path marker + bool m_false_path_; + // Critical path index (to next downstream node) + int m_crit_path_; + // Odd / even path visited (so that you don't have to clear it) + int m_visited_num_; + // The amount of delay left to the end of the timing path + double m_delay_left_; + }; + +} // namespace DSENT + +#endif // __DSENT_MODEL_ELECTRICAL_TIMING_NODE_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingNode.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingNode.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + + +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingNode.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalLoad.hh" + +namespace DSENT +{ + // Set the optical node initial visited num + const int ElectricalTimingNode::TIMING_NODE_INIT_VISITED_NUM = 0; + + ElectricalTimingNode::ElectricalTimingNode(const String& instance_name_, ElectricalModel* model_) + : m_instance_name_(instance_name_), m_model_(model_), m_false_path_(false), m_crit_path_(-1), + m_visited_num_(ElectricalTimingNode::TIMING_NODE_INIT_VISITED_NUM), m_delay_left_(0.0) + { + m_upstream_nodes_ = new vector(); + m_downstream_nodes_ = new vector(); + } + + ElectricalTimingNode::~ElectricalTimingNode() + { + delete m_upstream_nodes_; + delete m_downstream_nodes_; + } + + double ElectricalTimingNode::getMaxUpstreamRes() const + { + double max_res = 0.0; + + for(unsigned int i = 0; i < m_upstream_nodes_->size(); ++i) + { + double res = m_upstream_nodes_->at(i)->getMaxUpstreamRes(); + if(max_res < res) + { + max_res = res; + } + } + return max_res; + } + + double ElectricalTimingNode::getTotalDownstreamCap() const + { + double cap_sum = 0; + + for(unsigned int i = 0; i < m_downstream_nodes_->size(); ++i) + { + cap_sum += m_downstream_nodes_->at(i)->getTotalDownstreamCap(); + } + + return cap_sum; + } + + vector* ElectricalTimingNode::getUpstreamNodes() const + { + return m_upstream_nodes_; + } + + vector* ElectricalTimingNode::getDownstreamNodes() const + { + return m_downstream_nodes_; + } + + const String& ElectricalTimingNode::getInstanceName() const + { + return m_instance_name_; + } + + ElectricalModel* ElectricalTimingNode::getModel() + { + return m_model_; + } + + bool ElectricalTimingNode::isDriver() const + { + return false; + } + + bool ElectricalTimingNode::isNet() const + { + return false; + } + + bool ElectricalTimingNode::isLoad() const + { + return false; + } + + + const ElectricalModel* ElectricalTimingNode::getModel() const + { + return (const ElectricalModel*) m_model_; + } + + void ElectricalTimingNode::addDownstreamNode(ElectricalTimingNode* node_) + { + m_downstream_nodes_->push_back(node_); + node_->m_upstream_nodes_->push_back(this); + return; + } + + void ElectricalTimingNode::setFalsePath(bool false_path_) + { + m_false_path_ = false_path_; + return; + } + + bool ElectricalTimingNode::getFalsePath() const + { + return m_false_path_; + } + + + //------------------------------------------------------------------------- + // Functions for delay optimization + //------------------------------------------------------------------------- + // By default, electrical timing nodes cannot be sized up/down + bool ElectricalTimingNode::hasMaxDrivingStrength() const + { + return true; + } + + bool ElectricalTimingNode::hasMinDrivingStrength() const + { + return true; + } + + void ElectricalTimingNode::increaseDrivingStrength() + { + return; + } + + void ElectricalTimingNode::decreaseDrivingStrength() + { + return; + } + //------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + // Node variables for critical path delay calculations + //------------------------------------------------------------------------- + void ElectricalTimingNode::setCritPath(int crit_path_) + { + m_crit_path_ = crit_path_; + return; + } + + int ElectricalTimingNode::getCritPath() const + { + return m_crit_path_; + } + + void ElectricalTimingNode::setVisitedNum(int visited_num_) + { + m_visited_num_ = visited_num_; + return; + } + + int ElectricalTimingNode::getVisitedNum() const + { + return m_visited_num_; + } + + void ElectricalTimingNode::setDelayLeft(double delay_left_) + { + m_delay_left_ = delay_left_; + } + + double ElectricalTimingNode::getDelayLeft() const + { + return m_delay_left_; + } + //------------------------------------------------------------------------- + +} // namespace DSENT + + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingOptimizer.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingOptimizer.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_TIMING_GRAPH_ELECTRICAL_TIMING_OPTIMIZER_H__ +#define __DSENT_MODEL_TIMING_GRAPH_ELECTRICAL_TIMING_OPTIMIZER_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" + +namespace DSENT +{ + // This model is only used to optimize the timing + class ElectricalTimingOptimizer : public ElectricalModel + { + public: + ElectricalTimingOptimizer(const String& instance_name_, const TechModel* tech_model_); + virtual ~ElectricalTimingOptimizer(); + + public: + void setModel(ElectricalModel* model_); + ElectricalModel* getModel(); + + protected: + // Build the optimizer + virtual void constructModel(); + + private: + ElectricalModel* m_model_; + }; // class ElectricalTimingOptimizer +} // namespace + +#endif // __DSENT_MODEL_TIMING_GRAPH_ELECTRICAL_TIMING_OPTIMIZER_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingOptimizer.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingOptimizer.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingOptimizer.hh" + +#include "mem/ruby/network/dsent/dsent-core/model/PortInfo.hh" +#include "mem/ruby/network/dsent/dsent-core/model/ModelGen.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCell.hh" +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingTree.hh" + +namespace DSENT +{ + ElectricalTimingOptimizer::ElectricalTimingOptimizer(const String& instance_name_, const TechModel* tech_model_) + : ElectricalModel(instance_name_, tech_model_), m_model_(NULL) + {} + + ElectricalTimingOptimizer::~ElectricalTimingOptimizer() + {} + + void ElectricalTimingOptimizer::setModel(ElectricalModel* model_) + { + m_model_ = model_; + return; + } + + ElectricalModel* ElectricalTimingOptimizer::getModel() + { + return m_model_; + } + + void ElectricalTimingOptimizer::constructModel() + { + if(getModel() == NULL) + { + return; + } + + const Map* port_info = getModel()->getInputs(); + Map::ConstIterator it_begin = port_info->begin(); + Map::ConstIterator it_end = port_info->end(); + Map::ConstIterator it; + + for(it = it_begin; it != it_end; ++it) + { + const String& port_name = it->first; + const PortInfo* port_info = it->second; + StdCell* inv0 = getTechModel()->getStdCellLib()->createStdCell("INV", port_name + "Driver0"); + inv0->construct(); + StdCell* inv1 = getTechModel()->getStdCellLib()->createStdCell("INV", port_name + "Driver1"); + inv1->construct(); + + addSubInstances(inv0, 1.0); + addSubInstances(inv1, 1.0); + + createInputPort(port_name, port_info->getNetIndex()); + createNet(port_name + "Driver0In"); + createNet(port_name + "Driver0Out"); + createNet(port_name + "Driver1Out"); + assignVirtualFanin(port_name + "Driver0In", port_name); + portConnect(inv0, "A", port_name + "Driver0In"); + portConnect(inv0, "Y", port_name + "Driver0Out"); + portConnect(inv1, "A", port_name + "Driver0Out"); + portConnect(inv1, "Y", port_name + "Driver1Out"); + + createNet(port_name + "In", port_info->getNetIndex()); + assignVirtualFanout(port_name + "In", port_name + "Driver1Out"); + + portConnect(getModel(), port_name, port_name + "In"); + } + + return; + } +}// namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingTree.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingTree.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_MODEL_ELECTRICAL_TIMING_TREE_H__ +#define __DSENT_MODEL_ELECTRICAL_TIMING_TREE_H__ + +#include + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingNode.hh" + +namespace DSENT +{ + using std::vector; + + class ElectricalDriver; + + class ElectricalTimingTree + { + public: + // The visited number for the next timing run. This needs to be + // global because several timing trees may be created to evaluate + // a single timing path, causing problems + static int msTreeNum; + + public: + // Construct timing tree that watches over model_ + ElectricalTimingTree(const String& instance_name_, ElectricalModel* model_); + ~ElectricalTimingTree(); + + public: + // Get tree name + const String& getInstanceName() const; + + // A wrapper for extractCritPathDelay + // Update the tree num before do extract critical path delay recursively + double performCritPathExtract(ElectricalTimingNode* node_); + // Calculate the delay of the marked critical path from a starting node + double calculateCritPathDelay(ElectricalTimingNode* node_) const; + // Calculate the transition at a node + double calculateNodeTransition(ElectricalTimingNode* node_) const; + // Returns the optimal node to optimize timing (by sizing up) in the critical + // path to reduce critical path delay + ElectricalTimingNode* findNodeForTimingOpt(ElectricalTimingNode* node_) const; + // Perform incremental timing optimization to guarantee that all timing paths from a + // starting node meets a required delay + // Return false if the timing optimization fails to meet the required delay + bool performTimingOpt(ElectricalTimingNode* node_, double required_delay_); + + // Return the model + ElectricalModel* getModel(); + + private: + // Disable the use of copy constructor + ElectricalTimingTree(const ElectricalTimingTree& graph_); + + // Recursively calculate delay from a starting node, finding and marking the + // critical path along the way and returns the delay of the critical path + double extractCritPathDelay(ElectricalTimingNode* node_); + + public: + // Set the sequence number of the timing tree + static void setTreeNum(int tree_num_); + static int getTreeNum(); + + private: + // Name of the timing tree + const String m_instance_name_; + // A pointer to the model that contains this node + ElectricalModel* m_model_; + + }; // class ElectricalTimingTree +} // namespace DSENT + +#endif // __DSENT_MODEL_ELECTRICAL_TIMING_TREE_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingTree.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingTree.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + + +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingTree.hh" + +#include "mem/ruby/network/dsent/dsent-core/model/ElectricalModel.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalTimingNode.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalDriver.hh" +#include "mem/ruby/network/dsent/dsent-core/model/timing_graph/ElectricalNet.hh" + +namespace DSENT +{ + // Initialize the next visited number to be one above the initial number + // used by ElectricalTimingNode + int ElectricalTimingTree::msTreeNum = ElectricalTimingNode::TIMING_NODE_INIT_VISITED_NUM + 1; + + ElectricalTimingTree::ElectricalTimingTree(const String& instance_name_, ElectricalModel* model_) + : m_instance_name_(instance_name_), m_model_(model_) + { + //setTreeNum(1); + } + + ElectricalTimingTree::~ElectricalTimingTree() + { + + } + + const String& ElectricalTimingTree::getInstanceName() const + { + return m_instance_name_; + } + + bool ElectricalTimingTree::performTimingOpt(ElectricalTimingNode* node_, double required_delay_) + { + // Extract the critical path from all timing paths branching out from the starting node + double delay = performCritPathExtract(node_); + double min_delay = delay; + + unsigned int iteration = 0; + unsigned int crit_path_iteration = 0; + unsigned int max_iterations = 8000; //TODO: make this not hard-coded + unsigned int max_iterations_single_crit_path = 400; //TODO: make this not hard-coded + + Log::printLine(getInstanceName() + " -> Beginning Incremental Timing Optimization"); + + // Size up the nodes if timing is not met + while(required_delay_ < delay) + { + Log::printLine(getInstanceName() + " -> Timing Optimization Iteration " + (String) iteration + + ": Required delay = " + (String) required_delay_ + ", Delay = " + + (String) delay + ", Slack = " + (String) (required_delay_ - delay)); + + ElectricalTimingNode* node_for_timing_opt = NULL; + // Go into the less expensive critical path delay calculation + // While the timing is not met for this critical path + while (required_delay_ < delay) + { + // Find the node to optimize timing for, it would return a node to size up + node_for_timing_opt = findNodeForTimingOpt(node_); + // Give up if there are no appropriate nodes to size up or + // max number of iterations has been reached + // Size up the chosen node if there is an appropriate node to size up + if(node_for_timing_opt == NULL || iteration > max_iterations || crit_path_iteration > max_iterations_single_crit_path) + break; + else + node_for_timing_opt->increaseDrivingStrength(); + + // Re-evaluate the delay of the critical path + delay = calculateCritPathDelay(node_); + iteration++; + crit_path_iteration++; + Log::printLine(getInstanceName() + " -> Critical Path Slack: " + (String) (required_delay_ - delay)); + } + // Give up if there are no appropriate nodes to size up or + // max number of iterations has been reached + if (node_for_timing_opt == NULL || iteration > max_iterations || crit_path_iteration > max_iterations_single_crit_path) + break; + + crit_path_iteration = 0; + // Once the critical path timing is met, extract a new critical path from + // all timing paths branching out from the starting node + delay = performCritPathExtract(node_); + min_delay = (min_delay > delay) ? delay : min_delay; + } + Log::printLine(getInstanceName() + " -> Timing Optimization Ended after Iteration: " + (String) iteration + + ": Required delay = " + (String) required_delay_ + ", Delay = " + + (String) delay + ", Slack = " + (String) (required_delay_ - delay)); + + min_delay = (min_delay > delay) ? delay : min_delay; + + // Check if the timing meets the required delay + if(required_delay_ < delay) + { + // Timing not met. Return false and print out a warning message + const String& warning_msg = "[Warning] " + getInstanceName() + " -> Timing not met: Required delay = " + + (String) required_delay_ + ", Minimum Delay = " + (String) min_delay + ", Slack = " + + (String) (required_delay_ - delay); + Log::printLine(std::cerr, warning_msg); + return false; + } + return true; + } + //------------------------------------------------------------------------- + // Extract Crit Path Delay (and marks the crit path) + //------------------------------------------------------------------------- + double ElectricalTimingTree::performCritPathExtract(ElectricalTimingNode* node_) + { + setTreeNum(getTreeNum() + 1); + return extractCritPathDelay(node_); + } + + double ElectricalTimingTree::extractCritPathDelay(ElectricalTimingNode* node_) + { + //TODO: Replace with a stack data structure instead of recursion to prevent + //stack overflow problems with long chains of logic (4000+ nodes) and/or better + //performance. Nvm, stack data structure version seems to run much slower + + // If the node has already been visited, return the delay! + if (node_->getVisitedNum() == getTreeNum()) + return node_->getDelayLeft(); + // If the node has been marked as a false path, return 0.0 + else if (node_->getFalsePath()) + return 0.0; + + // Set the new parity for this node + node_->setVisitedNum(getTreeNum()); + node_->setDelayLeft(0.0); + + double max_delay = 0; + double current_delay = 0; + + // Traverse downstream nodes to calculate the delay through each downstream path + vector* d_nodes = node_->getDownstreamNodes(); + for (unsigned int i = 0; i < d_nodes->size(); ++i) + { + current_delay = extractCritPathDelay(d_nodes->at(i)); + // Update the critical path + if (current_delay > max_delay) + { + node_->setCritPath(i); + max_delay = current_delay; + } + } + // Calculate the delay left from this node + double delay_left = node_->calculateDelay() + max_delay; + node_->setDelayLeft(delay_left); + + return delay_left; + + } + + double ElectricalTimingTree::calculateCritPathDelay(ElectricalTimingNode* node_) const + { + // Simplest case where theres nothing to optimize + if (node_ == NULL) + return 0.0; + + double delay = 0.0; + int crit_path = 0; + + // Traverse the critical path and sum up delays + while (crit_path >= 0) + { + delay += node_->calculateDelay(); + //Move on to the next node in the critical path + crit_path = node_->getCritPath(); + if (crit_path >= 0) + node_ = node_->getDownstreamNodes()->at(crit_path); + } + return delay; + } + //------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + // Find Worst Slew Helpers + //------------------------------------------------------------------------- + ElectricalTimingNode* ElectricalTimingTree::findNodeForTimingOpt(ElectricalTimingNode* node_) const + { + // Simplest case where theres nothing to optimize + if (node_ == NULL) + return NULL; + + double max_transition_ratio = -10.0; + double current_transition_ratio = 0.0; + double previous_transition = 1e3 * node_->getTotalDownstreamCap(); + double current_transition = 0.0; + ElectricalTimingNode* worst = NULL; + int crit_path = 0; + + // Find the node with the highest max_transition_ratio to return + while (crit_path >= 0) + { + current_transition = node_->calculateDelay(); + + //If the node is not yet at max size, it is a potential choice for size up + if (!node_->hasMaxDrivingStrength()) + { + current_transition_ratio = current_transition / previous_transition; + + if (current_transition_ratio > max_transition_ratio) + { + worst = node_; + max_transition_ratio = current_transition_ratio; + } + } + + if (node_->isDriver()) + previous_transition = 0.0; + previous_transition += current_transition; + + //Move on to the next node in the critical path + crit_path = node_->getCritPath(); + + if (crit_path >= 0) + node_ = node_->getDownstreamNodes()->at(crit_path); + } + + return worst; + } + //------------------------------------------------------------------------- + + double ElectricalTimingTree::calculateNodeTransition(ElectricalTimingNode* node_) const + { + return node_->calculateTransition(); + } + + ElectricalTimingTree::ElectricalTimingTree(const ElectricalTimingTree& /* graph_ */) + { + // Disabled + } + + ElectricalModel* ElectricalTimingTree::getModel() + { + return m_model_; + } + + void ElectricalTimingTree::setTreeNum(int tree_num_) + { + msTreeNum = tree_num_; + return; + } + + int ElectricalTimingTree::getTreeNum() + { + return msTreeNum; + } + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/model/timing_graph/SConscript --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/model/timing_graph/SConscript Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,41 @@ +# 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. +# +# Authors: Chia-Hsin Owen Chen + +Import('*') + +if env['PROTOCOL'] == 'None': + Return() + +Source('ElectricalTimingTree.cc') +Source('ElectricalLoad.cc') +Source('ElectricalNet.cc') +Source('ElectricalTimingOptimizer.cc') +Source('ElectricalDriver.cc') +Source('ElectricalTimingNode.cc') +Source('ElectricalDelay.cc') +Source('ElectricalDriverMultiplier.cc') + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/tech/SConscript --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/tech/SConscript Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,34 @@ +# 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. +# +# Authors: Chia-Hsin Owen Chen + +Import('*') + +if env['PROTOCOL'] == 'None': + Return() + +Source('TechModel.cc') + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/tech/TechModel.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/tech/TechModel.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_TECH_TECH_MODEL_H__ +#define __DSENT_TECH_TECH_MODEL_H__ + +#include +#include + +#include "mem/ruby/network/dsent/dsent-core/libutil/Config.hh" +#include "mem/ruby/network/dsent/dsent-core/libutil/String.hh" + +namespace DSENT +{ + class StdCellLib; + + using std::set; + using std::vector; + using LibUtil::String; + + class TechModel : public LibUtil::Config + { + public: + typedef std::set::const_iterator ConstWireLayerIterator; + + public: + TechModel(); + virtual ~TechModel(); + + public: + // Set the pointer to a standard cell library + void setStdCellLib(const StdCellLib* std_cell_lib_); + // Get the pointer to the standard cell library + const StdCellLib* getStdCellLib() const; + + // Return a cloned copy of this instance + virtual TechModel* clone() const; + // Override readFile function to include multiple technology files + virtual void readFile(const String& filename_); + + // Transistor + // Returns the leakage current of NMOS transistors, given the transistor stakcing, transistor widths, and input combination + double calculateNmosLeakageCurrent(unsigned int num_stacks_, double uni_stacked_mos_width_, unsigned int input_vector_) const; + double calculateNmosLeakageCurrent(unsigned int num_stacks_, const vector& stacked_mos_widths_, unsigned int input_vector_) const; + // Returns the leakage current of PMOS transistors, given the transistor stakcing, transistor widths, and input combination + double calculatePmosLeakageCurrent(unsigned int num_stacks_, double uni_stacked_mos_width_, unsigned int input_vector_) const; + double calculatePmosLeakageCurrent(unsigned int num_stacks_, const vector& stacked_mos_widths_, unsigned int input_vector_) const; + // Returns the leakage current, given the transistor stakcing, transistor widths, input combination, + // and technology information (vdd, subthreshold swing, subthreshold dibl swing) + double calculateLeakageCurrentFactor(unsigned int num_stacks_, const vector& stacked_mos_widths_, unsigned int input_vector_, double vdd_, double subthreshold_swing_, double dibl_swing_) const; + + // Wire + // Check if the wire layer exist + bool isWireLayerExist(const String& layer_name_) const; + const std::set* getAvailableWireLayers() const; + // Return wire capacitance for given wire layer, wire width, wire spacing, and wire length + double calculateWireCapacitance(const String& layer_name_, double width_, double spacing_, double length_) const; + // Return wire resistance for given wire layer, wire width, and wire length + double calculateWireResistance(const String& layer_name_, double width_, double length_) const; + + private: + // Private copy constructor. Use clone to perform copy operation + TechModel(const TechModel& tech_model_); + + private: + // A pointer to a standard cell library + const StdCellLib* m_std_cell_lib_; + // A set of available wire layers + std::set* m_available_wire_layers_; + }; // class TechModel +} // namespace DSENT + +#endif // __DSENT_TECH_TECH_MODEL_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/tech/TechModel.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/tech/TechModel.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,351 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/tech/TechModel.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" + +namespace DSENT +{ + TechModel::TechModel() + : Config(), m_std_cell_lib_(NULL), m_available_wire_layers_(NULL) + {} + + TechModel::~TechModel() + {} + + void TechModel::setStdCellLib(const StdCellLib* std_cell_lib_) + { + m_std_cell_lib_ = std_cell_lib_; + return; + } + + const StdCellLib* TechModel::getStdCellLib() const + { + return m_std_cell_lib_; + } + + TechModel* TechModel::clone() const + { + return new TechModel(*this); + } + + void TechModel::readFile(const String& filename_) + { + // Read the main technology file + LibUtil::Config::readFile(filename_); + + // Search for "INCLUDE" to include more technology files + StringMap::ConstIterator it; + for(it = begin(); it != end(); ++it) + { + const String& key = it->first; + if(key.compare(0, 8, "INCLUDE_") == 0) + { + const String& include_filename = it->second; + LibUtil::Config::readFile(include_filename); + } + } + + // Set the available wire layers + const vector& available_wire_layer_vector = get("Wire->AvailableLayers").split("[,]"); + m_available_wire_layers_ = new std::set; + for(unsigned int i = 0; i < available_wire_layer_vector.size(); ++i) + { + m_available_wire_layers_->insert(available_wire_layer_vector[i]); + } + return; + } + + //------------------------------------------------------------------------- + // Transistor Related Functions + //------------------------------------------------------------------------- + //Returns the leakage current of NMOS transistors, given the transistor stakcing, transistor widths, and input combination + double TechModel::calculateNmosLeakageCurrent(unsigned int num_stacks_, double uni_stacked_mos_width_, unsigned int input_vector_) const + { + vector stacked_mos_widths_(num_stacks_, uni_stacked_mos_width_); + return calculateNmosLeakageCurrent(num_stacks_, stacked_mos_widths_, input_vector_); + } + + //Returns the leakage current of NMOS transistors, given the transistor stakcing, transistor widths, and input combination + double TechModel::calculateNmosLeakageCurrent(unsigned int num_stacks_, const vector& stacked_mos_widths_, unsigned int input_vector_) const + { + // Get technology parameters + double vdd = get("Vdd"); + double temp = get("Temperature"); + double char_temp = get("Nmos->CharacterizedTemperature"); + double min_off_current = get("Nmos->MinOffCurrent"); + double off_current = get("Nmos->OffCurrent"); + double subthreshold_swing = get("Nmos->SubthresholdSwing"); + double dibl = get("Nmos->DIBL"); + double temp_swing = get("Nmos->SubthresholdTempSwing"); + + // Map dibl to a swing value for easier calculation + double dibl_swing = subthreshold_swing / dibl; + + //Calculate the leakage current factor + double leakage_current_factor = calculateLeakageCurrentFactor(num_stacks_, stacked_mos_widths_, input_vector_, vdd, subthreshold_swing, dibl_swing); + + // Calcualte actual leakage current at characterized temperature + double leakage_current_char_tmp = stacked_mos_widths_[0] * off_current * std::pow(10.0, leakage_current_factor); + leakage_current_char_tmp = std::max(min_off_current, leakage_current_char_tmp); + + // Calculate actual leakage current at temp + double leakage_current = leakage_current_char_tmp * std::pow(10.0, (temp - char_temp) / temp_swing); + + return leakage_current; + } + + double TechModel::calculatePmosLeakageCurrent(unsigned int num_stacks_, double uni_stacked_mos_width_, unsigned int input_vector_) const + { + vector stacked_mos_widths_(num_stacks_, uni_stacked_mos_width_); + return calculatePmosLeakageCurrent(num_stacks_, stacked_mos_widths_, input_vector_); + } + + //Returns the leakage current of PMOS transistors, given the transistor stakcing, transistor widths, and input combination + double TechModel::calculatePmosLeakageCurrent(unsigned int num_stacks_, const vector& stacked_mos_widths_, unsigned int input_vector_) const + { + // Get technology parameters + double vdd = get("Vdd"); + double temp = get("Temperature"); + double char_temp = get("Pmos->CharacterizedTemperature"); + double min_off_current = get("Pmos->MinOffCurrent"); + double off_current = get("Pmos->OffCurrent"); + double dibl = get("Pmos->DIBL"); + double subthreshold_swing = get("Pmos->SubthresholdSwing"); + double temp_swing = get("Nmos->SubthresholdTempSwing"); + + // Map dibl to a swing value for easier calculation + double dibl_swing = subthreshold_swing / dibl; + + //Calculate the leakage current factor + double leakage_current_factor = calculateLeakageCurrentFactor(num_stacks_, stacked_mos_widths_, input_vector_, vdd, subthreshold_swing, dibl_swing); + + // Calcualte actual leakage current at characterized temperature + double leakage_current_char_tmp = stacked_mos_widths_[0] * off_current * std::pow(10.0, leakage_current_factor); + leakage_current_char_tmp = std::max(min_off_current, leakage_current_char_tmp); + + // Calculate actual leakage current at temp + double leakage_current = leakage_current_char_tmp * std::pow(10.0, (temp - char_temp) / temp_swing); + + return leakage_current; + } + + //Returns the leakage current, given the transistor stakcing, transistor widths, input combination, + //and technology information (vdd, subthreshold swing, subthreshold dibl swing) + double TechModel::calculateLeakageCurrentFactor(unsigned int num_stacks_, const vector& stacked_mos_widths_, unsigned int input_vector_, double vdd_, double subthreshold_swing_, double dibl_swing_) const + { + // check everything is valid + ASSERT(num_stacks_ >= 1, "[Error] Number of stacks must be >= 1!"); + ASSERT(stacked_mos_widths_.size() == num_stacks_, "[Error] Mismatch in number of stacks and the widths specified!"); + + //Use short name in this method + const double s1 = subthreshold_swing_; + const double s2 = dibl_swing_; + + // Decode input combinations from input_vector_ + std::vector vs(num_stacks_, 0.0); + for(int i = 0; i < (int)num_stacks_; ++i) + { + double current_input = (double(input_vector_ & 0x1))*vdd_; + vs[i] = (current_input); + input_vector_ >>= 1; + } + // If the widths pointer is NULL, width is set to 1 by default + vector ws = stacked_mos_widths_; + + //Solve voltages at internal nodes of stacked transistors + // v[0] = 0 + // v[num_stacks_] = vdd_ + // v[i] = (1.0/(2*s1 + s2))*((s1 + s2)*v[i - 1] + s1*v[i + 1] + // + s2*(vs[i + 1] - vs[i]) + s1*s2*log10(ws[i + 1]/ws[i])) + //Use tri-matrix solver to solve the above linear system + + double A = -(s1 + s2); + double B = 2*s1 + s2; + double C = -s1; + std::vector a(num_stacks_ - 1, 0); + std::vector b(num_stacks_ - 1, 0); + std::vector c(num_stacks_ - 1, 0); + std::vector d(num_stacks_ - 1, 0); + std::vector v(num_stacks_ + 1, 0); + unsigned int eff_num_stacks = num_stacks_; + bool is_found_valid_v = false; + do + { + //Set boundary condition + v[0] = 0; + v[eff_num_stacks] = vdd_; + + //If the effective number of stacks is 1, no matrix needs to be solved + if(eff_num_stacks == 1) + { + break; + } + + //---------------------------------------------------------------------- + //Setup the tri-matrix + //---------------------------------------------------------------------- + for(int i = 0; i < (int)eff_num_stacks-2; ++i) + { + a[i + 1] = A; + c[i] = C; + } + for(int i = 0; i < (int)eff_num_stacks-1; ++i) + { + b[i] = B; + d[i] = s2*(vs[i + 1] - vs[i]) + s1*s2*std::log10(ws[i + 1]/ws[i]); + if(i == ((int)eff_num_stacks - 2)) + { + d[i] -= C*vdd_; + } + } + //---------------------------------------------------------------------- + + //---------------------------------------------------------------------- + //Solve the tri-matrix + //---------------------------------------------------------------------- + for(int i = 1; i < (int)eff_num_stacks-1; ++i) + { + double m = a[i]/b[i - 1]; + b[i] -= m*c[i - 1]; + d[i] -= m*d[i - 1]; + } + + v[eff_num_stacks - 1] = d[eff_num_stacks - 2]/b[eff_num_stacks - 2]; + for(int i = eff_num_stacks - 3; i >= 0; --i) + { + v[i + 1] = (d[i] - c[i]*v[i + 2])/b[i]; + } + //---------------------------------------------------------------------- + + //Check if the internal voltages are in increasing order + is_found_valid_v = true; + for(int i = 1; i <= (int)eff_num_stacks; ++i) + { + //If the ith internal voltage is not in increasing order + //(i-1)th transistor is in triode region + //Remove the transistors in triode region as it does not exist + if(v[i] < v[i - 1]) + { + is_found_valid_v = false; + eff_num_stacks--; + vs.erase(vs.begin() + i - 1); + ws.erase(ws.begin() + i - 1); + break; + } + } + } while(!is_found_valid_v); + + //Calculate the leakage current of the bottom transistor (first not in triode region) + double vgs = vs[0] - v[0]; + double vds = v[1] - v[0]; + double leakage_current_factor = vgs/s1 + (vds - vdd_)/s2; + //TODO - Check if the leakage current calculate for other transistors is identical + + return leakage_current_factor; + } + //------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + // Wire Related Functions + //------------------------------------------------------------------------- + bool TechModel::isWireLayerExist(const String& layer_name_) const + { + std::set::const_iterator it; + it = m_available_wire_layers_->find(layer_name_); + return (it != m_available_wire_layers_->end()); + } + + const std::set* TechModel::getAvailableWireLayers() const + { + return m_available_wire_layers_; + } + + double TechModel::calculateWireCapacitance(const String& layer_name_, double width_, double spacing_, double length_) const + { + // Get technology parameter + double min_width = get("Wire->" + layer_name_ + "->MinWidth").toDouble(); + double min_spacing = get("Wire->" + layer_name_ + "->MinSpacing").toDouble(); + double metal_thickness = get("Wire->" + layer_name_ + "->MetalThickness").toDouble(); + double dielec_thickness = get("Wire->" + layer_name_ + "->DielectricThickness").toDouble(); + double dielec_const = get("Wire->" + layer_name_ + "->DielectricConstant").toDouble(); + + ASSERT(width_ >= min_width, "[Error] Wire width must be >= " + (String) min_width + "!"); + ASSERT(spacing_ >= min_spacing, "[Error] Wire spacing must be >= " + (String) min_spacing + "!"); + ASSERT(length_ >= 0, "[Error] Wire length must be >= 0!"); + + double A, B, C; + // Calculate ground capacitance + A = width_ / dielec_thickness; + B = 2.04*std::pow((spacing_ / (spacing_ + 0.54 * dielec_thickness)), 1.77); + C = std::pow((metal_thickness / (metal_thickness + 4.53 * dielec_thickness)), 0.07); + double unit_gnd_cap = dielec_const * 8.85e-12 * (A + B * C); + + A = 1.14 * (metal_thickness / spacing_) * std::exp(-4.0 * spacing_ / (spacing_ + 8.01 * dielec_thickness)); + B = 2.37 * std::pow((width_ / (width_ + 0.31 * spacing_)), 0.28); + C = std::pow((dielec_thickness / (dielec_thickness + 8.96 * spacing_)), 0.76) * + std::exp(-2.0 * spacing_ / (spacing_ + 6.0 * dielec_thickness)); + double unit_coupling_cap = dielec_const * 8.85e-12 * (A + B * C); + + double total_cap = 2 * (unit_gnd_cap + unit_coupling_cap) * length_; + return total_cap; + } + + double TechModel::calculateWireResistance(const String& layer_name_, double width_, double length_) const + { + // Get technology parameter + double min_width = get("Wire->" + layer_name_ + "->MinWidth"); + //double barrier_thickness = get("Wire->" + layer_name_ + "->BarrierThickness"); + double resistivity = get("Wire->" + layer_name_ + "->Resistivity"); + double metal_thickness = get("Wire->" + layer_name_ + "->MetalThickness"); + + ASSERT(width_ >= min_width, "[Error] Wire width must be >= " + (String) min_width + "!"); + ASSERT(length_ >= 0, "[Error] Wire length must be >= 0!"); + + // Calculate Rho + // double rho = 2.202e-8 + (1.030e-15 / (width_ - 2.0 * barrier_thickness)); + + double unit_res = resistivity / (width_ * metal_thickness); + //double unit_res = rho / ((width_ - 2.0 * barrier_thickness) * (metal_thickness - barrier_thickness)); + + double total_res = unit_res * length_; + return total_res; + } + //------------------------------------------------------------------------- + + TechModel::TechModel(const TechModel& tech_model_) + : Config(tech_model_), m_std_cell_lib_(tech_model_.m_std_cell_lib_) + {} +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/tech/tech_models/Bulk22LVT.model --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/tech/tech_models/Bulk22LVT.model Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,179 @@ +# WARNING: Most commercial fabs will not be happy if you release their exact +# process information! If you derive these numbers through SPICE models, +# the process design kit, or any other confidential material, please round-off +# the values and leave the process name unidentifiable by fab (i.e. call it +# Bulk90LVT instead of TSMC90LVT) if you release parameters publicly. This +# rule may not apply for open processes, but you may want to check. + +# All units are in SI, (volts, meters, kelvin, farads, ohms, amps, etc.) + +# This file contains the model for a bulk 22nm LVT process +Name = Bulk22LVT + +# Supply voltage used in the circuit and for characterizations (V) +Vdd = 0.8 +# Temperature (K) +Temperature = 340 + +# ============================================================================= +# Parameters for transistors +# ============================================================================= + +# Contacted gate pitch (m) +Gate->PitchContacted = 0.120e-6 + +# Min gate width (m) +Gate->MinWidth = 0.100e-6 + +# Gate cap per unit width (F/m) +Gate->CapPerWidth = 0.900e-9 +# Source/Drain cap per unit width (F/m) +Drain->CapPerWidth = 0.620e-9 + +# Parameters characterization temperature (K) +Nmos->CharacterizedTemperature = 300.0 +Pmos->CharacterizedTemperature = 300.0 + +#------------------------------------------------------------------------------ +# I_Eff definition in Na, IEDM 2002 +# I_EFF = (I(VG = 0.5, VD = 1.0) + I(VG = 1.0, VD = 0.5))/2 +# R_EFF = VDD / I_EFF * 1 / (2 ln(2)) +# This is generally accurate for when input and output transition times +# are similar, which is a reasonable case after timing optimization +#------------------------------------------------------------------------------ +# Effective resistance (Ohm-m) +Nmos->EffResWidth = 0.700e-3 +Pmos->EffResWidth = 0.930e-3 + +#------------------------------------------------------------------------------ +# The ratio of extra effective resistance with each additional stacked +# transistor +# EffResStackRatio = (R_EFF_NAND2 - R_EFF_INV) / R_EFF_INV) +# For example, inverter has an normalized effective drive resistance of 1.0. +# A NAND2 (2-stack) will have an effective drive of 1.0 + 0.7, a NAND3 (3-stack) +# will have an effective drive of 1.0 + 2 * 0.7. Use NORs for Pmos. This fit +# works relatively well up to 4 stacks. This value will change depending on the +# VDD used. +#------------------------------------------------------------------------------ +# Effective resistance stack ratio +Nmos->EffResStackRatio = 0.800 +Pmos->EffResStackRatio = 0.680 + +#------------------------------------------------------------------------------ +# I_OFF defined as |I_DS| for |V_DS| = V_DD and |V_GS| = 0.0 +# Minimum off current is used in technologies where I_OFF stops scaling +# with transistor width below some threshold +#------------------------------------------------------------------------------ +# Off current per width (A/m) +Nmos->OffCurrent = 100.0e-3 +Pmos->OffCurrent = 100.0e-3 +# Minimum off current (A) +Nmos->MinOffCurrent = 60e-9 +Pmos->MinOffCurrent = 60e-9 + +# Subthreshold swing (V/dec) +Nmos->SubthresholdSwing = 0.100 +Pmos->SubthresholdSwing = 0.100 +# DIBL factor (V/V) +Nmos->DIBL = 0.150 +Pmos->DIBL = 0.150 +# Subthreshold temperature swing (K/dec) +Nmos->SubthresholdTempSwing = 100.0 +Pmos->SubthresholdTempSwing = 100.0 +#------------------------------------------------------------------------------ + +# ============================================================================= +# Parameters for interconnect +# ============================================================================= + +Wire->AvailableLayers = [Metal1,Local,Intermediate,Semiglobal,Global] + +# Metal 1 Wire (used for std cell routing only) +# Min width (m) +Wire->Metal1->MinWidth = 32e-9 +# Min spacing (m) +Wire->Metal1->MinSpacing = 32e-9 +# Resistivity (Ohm-m) +Wire->Metal1->Resistivity = 5.00e-8 +# Metal thickness (m) +Wire->Metal1->MetalThickness = 60.0e-9 +# Dielectric thickness (m) +Wire->Metal1->DielectricThickness = 60.0e-9 +# Dielectric constant +Wire->Metal1->DielectricConstant = 3.00 + +# Local wire, 1.0X of the M1 pitch +# Min width (m) +Wire->Local->MinWidth = 32e-9 +# Min spacing (m) +Wire->Local->MinSpacing = 32e-9 +# Resistivity (Ohm-m) +Wire->Local->Resistivity = 5.00e-8 +# Metal thickness (m) +Wire->Local->MetalThickness = 60.0e-9 +# Dielectric thickness (m) +Wire->Local->DielectricThickness = 60.0e-9 +# Dielectric constant +Wire->Local->DielectricConstant = 3.00 + +# Intermediate wire, 2.0X the M1 pitch +# Min width (m) +Wire->Intermediate->MinWidth = 55e-9 +# Min spacing (m) +Wire->Intermediate->MinSpacing = 55e-9 +# Resistivity (Ohm-m) +Wire->Intermediate->Resistivity = 4.00e-8 +# Metal thickness (m) +Wire->Intermediate->MetalThickness = 100.0e-9 +# Dielectric thickness (m) +Wire->Intermediate->DielectricThickness = 100.0e-9 +# Dielectric constant +Wire->Intermediate->DielectricConstant = 2.8 + +# Semiglobal wire, 4.0X the M1 pitch +# Min width (m) +Wire->Semiglobal->MinWidth = 110e-9 +# Min spacing (m) +Wire->Semiglobal->MinSpacing = 110e-9 +# Resistivity (Ohm-m) +Wire->Semiglobal->Resistivity = 2.60e-8 +# Metal thickness (m) +Wire->Semiglobal->MetalThickness = 200e-9 +# Dielectric thickness (m) +Wire->Semiglobal->DielectricThickness = 170e-9 +# Dielectric constant +Wire->Semiglobal->DielectricConstant = 2.80 + +# Global wire, 6.0X the M1 pitch +# Min width (m) +Wire->Global->MinWidth = 160e-9 +# Min spacing (m) +Wire->Global->MinSpacing = 160e-9 +# Resistivity (Ohm-m) +Wire->Global->Resistivity = 2.30e-8 +# Metal thickness (m) +Wire->Global->MetalThickness = 280e-9 +# Dielectric thickness (m) +Wire->Global->DielectricThickness = 250e-9 +# Dielectric constant +Wire->Global->DielectricConstant = 2.60 + +# ============================================================================= +# Parameters for Standard Cells +# ============================================================================= + +# The height of the standard cell is usually a multiple of the vertical +# M1 pitch (tracks). By definition, an X1 size cell has transistors +# that fit exactly in the given cell height without folding, or leaving +# any wasted vertical area + +# Reasonable values for the number of M1 tracks that we have seen are 8-14 +StdCell->Tracks = 11 +# Height overhead due to supply rails, well spacing, etc. Note that this will grow +# if the height of the standard cell decreases! +StdCell->HeightOverheadFactor = 1.400 + +# Sets the available sizes of each standard cell. Keep in mind that +# 1.0 is the biggest cell without any transistor folding +StdCell->AvailableSizes = [1.0, 1.4, 2.0, 3.0, 4.0, 6.0, 8.0, 10.0, 12.0, 16.0] + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/tech/tech_models/Bulk32LVT.model --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/tech/tech_models/Bulk32LVT.model Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,168 @@ +# WARNING: Most commercial fabs will not be happy if you release their exact +# process information! If you derive these numbers through SPICE models, +# the process design kit, or any other confidential material, please round-off +# the values and leave the process name unidentifiable by fab (i.e. call it +# Bulk90LVT instead of TSMC90LVT) if you release parameters publicly. This +# rule may not apply for open processes, but you may want to check. + +# All units are in SI, (volts, meters, kelvin, farads, ohms, amps, etc.) + +# This file contains the model for a bulk 32nm LVT process +Name = Bulk32LVT + +# Supply voltage used in the circuit and for characterizations (V) +Vdd = 0.9 +# Temperature (K) +Temperature = 340 + +# ============================================================================= +# Parameters for transistors +# ============================================================================= + +# Contacted gate pitch (m) +Gate->PitchContacted = 0.160e-6 + +# Min gate width (m) +Gate->MinWidth = 0.120e-6 + +# Gate cap per unit width (F/m) +Gate->CapPerWidth = 0.950e-9 +# Source/Drain cap per unit width (F/m) +Drain->CapPerWidth = 0.640e-9 + +# Parameters characterization temperature (K) +Nmos->CharacterizedTemperature = 300.0 +Pmos->CharacterizedTemperature = 300.0 + +#------------------------------------------------------------------------------ +# I_Eff definition in Na, IEDM 2002 +# I_EFF = (I(VG = 0.5, VD = 1.0) + I(VG = 1.0, VD = 0.5))/2 +# R_EFF = VDD / I_EFF * 1 / (2 ln(2)) +# This is generally accurate for when input and output transition times +# are similar, which is a reasonable case after timing optimization +#------------------------------------------------------------------------------ +# Effective resistance (Ohm-m) +Nmos->EffResWidth = 0.890e-3 +Pmos->EffResWidth = 1.270e-3 + +#------------------------------------------------------------------------------ +# The ratio of extra effective resistance with each additional stacked +# transistor +# EffResStackRatio = (R_EFF_NAND2 - R_EFF_INV) / R_EFF_INV) +# For example, inverter has an normalized effective drive resistance of 1.0. +# A NAND2 (2-stack) will have an effective drive of 1.0 + 0.7, a NAND3 (3-stack) +# will have an effective drive of 1.0 + 2 * 0.7. Use NORs for Pmos. This fit +# works relatively well up to 4 stacks. This value will change depending on the +# VDD used. +#------------------------------------------------------------------------------ +# Effective resistance stack ratio +Nmos->EffResStackRatio = 0.78 +Pmos->EffResStackRatio = 0.66 + +#------------------------------------------------------------------------------ +# I_OFF defined as |I_DS| for |V_DS| = V_DD and |V_GS| = 0.0 +# Minimum off current is used as a second fit point, since I_OFF often +# stops scaling with transistor width below some threshold +#------------------------------------------------------------------------------ +# Off current per width (A/m) +Nmos->OffCurrent = 100e-3 +Pmos->OffCurrent = 100e-3 + +# Minimum off current (A) +Nmos->MinOffCurrent = 100e-9 +Pmos->MinOffCurrent = 20e-9 + +# Subthreshold swing (V/dec) +Nmos->SubthresholdSwing = 0.100 +Pmos->SubthresholdSwing = 0.100 + +# DIBL factor (V/V) +Nmos->DIBL = 0.150 +Pmos->DIBL = 0.150 + +# Subthreshold leakage temperature swing (K/dec) +Nmos->SubthresholdTempSwing = 100 +Pmos->SubthresholdTempSwing = 100 +#------------------------------------------------------------------------------ + +# ============================================================================= +# Parameters for interconnect +# ============================================================================= + +Wire->AvailableLayers = [Metal1,Local,Intermediate,Global] + +# Metal 1 Wire (used for std cell routing only) +# Min width (m) +Wire->Metal1->MinWidth = 55e-9 +# Min spacing (m) +Wire->Metal1->MinSpacing = 55e-9 +# Resistivity (Ohm-m) +Wire->Metal1->Resistivity = 4.00e-8 +# Metal thickness (m) +Wire->Metal1->MetalThickness = 100.0e-9 +# Dielectric thickness (m) +Wire->Metal1->DielectricThickness = 100.0e-9 +# Dielectric constant +Wire->Metal1->DielectricConstant = 3.2 + +# Local wire, 1.0X of the M1 pitch +# Min width (m) +Wire->Local->MinWidth = 55e-9 +# Min spacing (m) +Wire->Local->MinSpacing = 55e-9 +# Resistivity (Ohm-m) +Wire->Local->Resistivity = 4.00e-8 +# Metal thickness (m) +Wire->Local->MetalThickness = 100.0e-9 +# Dielectric thickness (m) +Wire->Local->DielectricThickness = 100.0e-9 +# Dielectric constant +Wire->Local->DielectricConstant = 3.2 + +# Intermediate wire, 2.0X the M1 pitch +# Min width (m) +Wire->Intermediate->MinWidth = 110e-9 +# Min spacing (m) +Wire->Intermediate->MinSpacing = 110e-9 +# Resistivity (Ohm-m) +Wire->Intermediate->Resistivity = 2.60e-8 +# Metal thickness (m) +Wire->Intermediate->MetalThickness = 200e-9 +# Dielectric thickness (m) +Wire->Intermediate->DielectricThickness = 170e-9 +# Dielectric constant +Wire->Intermediate->DielectricConstant = 3.00 + +# Global wire, 3.0X the M1 pitch +# Min width (m) +Wire->Global->MinWidth = 160e-9 +# Min spacing (m) +Wire->Global->MinSpacing = 160e-9 +# Resistivity (Ohm-m) +Wire->Global->Resistivity = 2.30e-8 +# Metal thickness (m) +Wire->Global->MetalThickness = 280e-9 +# Dielectric thickness (m) +Wire->Global->DielectricThickness = 250e-9 +# Dielectric constant +Wire->Global->DielectricConstant = 2.80 + +# ============================================================================= +# Parameters for Standard Cells +# ============================================================================= + +# The height of the standard cell is usually a multiple of the vertical +# M1 pitch (tracks). By definition, an X1 size cell has transistors +# that fit exactly in the given cell height without folding, or leaving +# any wasted vertical area + +# Reasonable values for the number of M1 tracks that we have seen are 8-14 +StdCell->Tracks = 11 +# Height overhead due to supply rails, well spacing, etc. Note that this will grow +# if the height of the standard cell decreases! +StdCell->HeightOverheadFactor = 1.400 + +# Sets the available sizes of each standard cell. Keep in mind that +# 1.0 is the biggest cell without any transistor folding +StdCell->AvailableSizes = [1.0, 1.4, 2.0, 3.0, 4.0, 6.0, 8.0, 10.0, 12.0, 16.0] + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/tech/tech_models/Bulk45LVT.model --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/tech/tech_models/Bulk45LVT.model Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,168 @@ +# WARNING: Most commercial fabs will not be happy if you release their exact +# process information! If you derive these numbers through SPICE models, +# the process design kit, or any other confidential material, please round-off +# the values and leave the process name unidentifiable by fab (i.e. call it +# Bulk90LVT instead of TSMC90LVT) if you release parameters publicly. This +# rule may not apply for open processes, but you may want to check. + +# All units are in SI, (volts, meters, kelvin, farads, ohms, amps, etc.) + +# This file contains the model for a bulk 45nm LVT process +Name = Bulk45LVT + +# Supply voltage used in the circuit and for characterizations (V) +Vdd = 1.0 +# Temperature (K) +Temperature = 340 + +# ============================================================================= +# Parameters for transistors +# ============================================================================= + +# Contacted gate pitch (m) +Gate->PitchContacted = 0.200e-6 + +# Min gate width (m) +Gate->MinWidth = 0.160e-6 + +# Gate cap per unit width (F/m) +Gate->CapPerWidth = 1.000e-9 +# Source/Drain cap per unit width (F/m) +Drain->CapPerWidth = 0.600e-9 + +# Parameters characterization temperature (K) +Nmos->CharacterizedTemperature = 300.0 +Pmos->CharacterizedTemperature = 300.0 + +#------------------------------------------------------------------------------ +# I_Eff definition in Na, IEDM 2002 +# I_EFF = (I(VG = 0.5, VD = 1.0) + I(VG = 1.0, VD = 0.5))/2 +# R_EFF = VDD / I_EFF * 1 / (2 ln(2)) +# This is generally accurate for when input and output transition times +# are similar, which is a reasonable case after timing optimization +#------------------------------------------------------------------------------ +# Effective resistance (Ohm-m) +Nmos->EffResWidth = 1.100e-3 +Pmos->EffResWidth = 1.500e-3 + +#------------------------------------------------------------------------------ +# The ratio of extra effective resistance with each additional stacked +# transistor +# EffResStackRatio = (R_EFF_NAND2 - R_EFF_INV) / R_EFF_INV) +# For example, inverter has an normalized effective drive resistance of 1.0. +# A NAND2 (2-stack) will have an effective drive of 1.0 + 0.7, a NAND3 (3-stack) +# will have an effective drive of 1.0 + 2 * 0.7. Use NORs for Pmos. This fit +# works relatively well up to 4 stacks. This value will change depending on the +# VDD used. +#------------------------------------------------------------------------------ +# Effective resistance stack ratio +Nmos->EffResStackRatio = 0.7 +Pmos->EffResStackRatio = 0.6 + +#------------------------------------------------------------------------------ +# I_OFF defined as |I_DS| for |V_DS| = V_DD and |V_GS| = 0.0 +# Minimum off current is used as a second fit point, since I_OFF often +# stops scaling with transistor width below some threshold +#------------------------------------------------------------------------------ +# Off current per width (A/m) +Nmos->OffCurrent = 100e-3 +Pmos->OffCurrent = 100e-3 + +# Minimum off current (A) +Nmos->MinOffCurrent = 100e-9 +Pmos->MinOffCurrent = 20e-9 + +# Subthreshold swing (V/dec) +Nmos->SubthresholdSwing = 0.100 +Pmos->SubthresholdSwing = 0.100 + +# DIBL factor (V/V) +Nmos->DIBL = 0.150 +Pmos->DIBL = 0.150 + +# Subthreshold leakage temperature swing (K/dec) +Nmos->SubthresholdTempSwing = 100 +Pmos->SubthresholdTempSwing = 100 +#------------------------------------------------------------------------------ + +# ============================================================================= +# Parameters for interconnect +# ============================================================================= + +Wire->AvailableLayers = [Metal1,Local,Intermediate,Global] + +# Metal 1 Wire (used for std cell routing only) +# Min width (m) +Wire->Metal1->MinWidth = 80e-9 +# Min spacing (m) +Wire->Metal1->MinSpacing = 80e-9 +# Resistivity (Ohm-m) +Wire->Metal1->Resistivity = 3.00e-8 +# Metal thickness (m) +Wire->Metal1->MetalThickness = 140.0e-9 +# Dielectric thickness (m) +Wire->Metal1->DielectricThickness = 130.0e-9 +# Dielectric constant +Wire->Metal1->DielectricConstant = 3.2 + +# Local wire, 1.0X of the M1 pitch +# Min width (m) +Wire->Local->MinWidth = 80e-9 +# Min spacing (m) +Wire->Local->MinSpacing = 80e-9 +# Resistivity (Ohm-m) +Wire->Local->Resistivity = 3.00e-8 +# Metal thickness (m) +Wire->Local->MetalThickness = 140.0e-9 +# Dielectric thickness (m) +Wire->Local->DielectricThickness = 130.0e-9 +# Dielectric constant +Wire->Local->DielectricConstant = 3.2 + +# Intermediate wire, 1.4X the M1 pitch +# Min width (m) +Wire->Intermediate->MinWidth = 110e-9 +# Min spacing (m) +Wire->Intermediate->MinSpacing = 110e-9 +# Resistivity (Ohm-m) +Wire->Intermediate->Resistivity = 2.60e-8 +# Metal thickness (m) +Wire->Intermediate->MetalThickness = 200e-9 +# Dielectric thickness (m) +Wire->Intermediate->DielectricThickness = 170e-9 +# Dielectric constant +Wire->Intermediate->DielectricConstant = 3.00 + +# Global wire, 2.0X the M1 pitch +# Min width (m) +Wire->Global->MinWidth = 160e-9 +# Min spacing (m) +Wire->Global->MinSpacing = 160e-9 +# Resistivity (Ohm-m) +Wire->Global->Resistivity = 2.30e-8 +# Metal thickness (m) +Wire->Global->MetalThickness = 280e-9 +# Dielectric thickness (m) +Wire->Global->DielectricThickness = 250e-9 +# Dielectric constant +Wire->Global->DielectricConstant = 2.80 + +# ============================================================================= +# Parameters for Standard Cells +# ============================================================================= + +# The height of the standard cell is usually a multiple of the vertical +# M1 pitch (tracks). By definition, an X1 size cell has transistors +# that fit exactly in the given cell height without folding, or leaving +# any wasted vertical area + +# Reasonable values for the number of M1 tracks that we have seen are 8-14 +StdCell->Tracks = 11 +# Height overhead due to supply rails, well spacing, etc. Note that this will grow +# if the height of the standard cell decreases! +StdCell->HeightOverheadFactor = 1.400 + +# Sets the available sizes of each standard cell. Keep in mind that +# 1.0 is the biggest cell without any transistor folding +StdCell->AvailableSizes = [1.0, 1.4, 2.0, 3.0, 4.0, 6.0, 8.0, 10.0, 12.0, 16.0] + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/tech/tech_models/Photonics.model --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/tech/tech_models/Photonics.model Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,89 @@ +# This file contains the model for photonic devices/circuits +PhotonicsName = Photonics + +# ALL PARAMETERS IN SI UNITS!!! (J, W, m, F, dB, A) + +# ----------------------------------------------------------------------------- +# Waveguide +# ----------------------------------------------------------------------------- +Waveguide->LossPerMeter = 100 # dB/m +Waveguide->Pitch = 4e-6 # m +Splitter->Loss = 1.00 # dB +Coupler->Loss = 1.00 # dB + +# ----------------------------------------------------------------------------- +# Laser +# ----------------------------------------------------------------------------- + +# Continuous wave off-chip (always on) laser +Laser->CW->Efficiency = 0.25 # P_Laser/P_Electrical +Laser->CW->LaserDiodeLoss = 1.00 # Laser diode loss +Laser->CW->Area = 0 + +# Gated on-chip (data-dependent) laser +Laser->GatedCW->Efficiency = 0.25 # P_Laser/P_Electrical +Laser->GatedCW->LaserDiodeLoss = 1.00 # Laser diode loss +Laser->GatedCW->Area = 200e-12 + +# ----------------------------------------------------------------------------- +# Modulators +# ----------------------------------------------------------------------------- +# Ring Modulator +Modulator->Ring->SupplyBoostRatio = 1.2 # Boost the supply voltage above required reverse bias voltage by this ratio +Modulator->Ring->ParasiticRes = 100 # ohm +Modulator->Ring->ParasiticCap = 5e-15 # F +Modulator->Ring->FCPDEffect = 3e-27 # Free carrier plasma dispersion effect, delta_n/delta_c (m^-3) +Modulator->Ring->Tn = 0.01 # Transmisivity at the bottom of the notch +Modulator->Ring->NA = 3e24 # m^3, p doping +Modulator->Ring->ND = 1e24 # m^3, n doping +Modulator->Ring->ni = 1e16 # m^3, intrinsic free carriers +Modulator->Ring->JunctionRatio = 0.8 # Junction ratio to total optical length +Modulator->Ring->Height = 500e-9 # Height of the junction (m) +Modulator->Ring->Width = 500e-9 # Modulator width (m) +Modulator->Ring->ConfinementFactor = 0.3 # Modulator confinement factor + +# ----------------------------------------------------------------------------- +# Ring Resonator +# ----------------------------------------------------------------------------- +Ring->Area = 100e-12 # m2 +Ring->Lambda = 1300e-9 # Resonant wavelength range +Ring->GroupIndex = 4 # Group index +Ring->Radius = 3e-6 # Bend radius of the ring +Ring->ConfinementFactor = 0.3 # Confinement factor +Ring->ThroughLoss = 0.01 # [dB] +Ring->DropLoss = 1.0 # [dB] +Ring->MaxQualityFactor = 150e3 # Maximum quality factor +Ring->HeatingEfficiency = 100000 # Ring heating efficiency [K/W] +Ring->TuningEfficiency = 10e9 # Ring tuning efficiency [Hz/K] +Ring->LocalVariationSigma = 40e9 # Ring resonance frequency local mismatch sigma [Hz] +Ring->SystematicVariationSigma = 200e9 # Ring resonance frequency systematic mismatch sigma [Hz] +Ring->TemperatureMax = 380 # Maximum temperature that the tuning mechanism must still be able to work at [K] +Ring->TemperatureMin = 280 # Minimum temperature that the tuning mechanism must still be able to work at [K] +Ring->MaxElectricallyTunableFreq = 50e9 # Maximum electrically tunable range when allowing for electrically assisted tuning [Hz] + +# ----------------------------------------------------------------------------- +# Photodetector +# ----------------------------------------------------------------------------- +Photodetector->Responsivity = 1.1 #(A/W) +Photodetector->Area = 10e-12 # m2 +Photodetector->Cap = 0 # F +Photodetector->ParasiticCap = 5e-15 # F +Photodetector->Loss = 1.00 # dB +Photodetector->MinExtinctionRatio = 3 # dB +Photodetector->AvalancheGain = 1 # avalanche gain + +# ----------------------------------------------------------------------------- +# Receivers +# ----------------------------------------------------------------------------- + +# Sense amplifier (common to all receivers) +SenseAmp->BER = 1e-15 # Target bit error rate +SenseAmp->CMRR = 5 # Common-mode rejection ratio +SenseAmp->OffsetCompensationBits = 5 # Number of bits used for fine-tuning offset compensation +SenseAmp->OffsetRatio = 0.04 # Offset mismatch (as a fraction of VDD) +SenseAmp->SupplyNoiseRandRatio = 0.01 # Random supply noise (as a fraction VDD) +SenseAmp->SupplyNoiseDetRatio = 0.05 # Deterministic supply noise (as a fraction VDD) +SenseAmp->NoiseMargin = 0.02 # Extra noise margin +SenseAmp->JitterRatio = 0.01 # Jitter (as a fraction of Tbit) + +Receiver->Int->IntegrationTimeRatio = 0.7 # Integration time (as a fraction of Tbit) diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/tech/tech_models/SConscript --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/tech/tech_models/SConscript Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,33 @@ +# 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. +# +# Authors: Chia-Hsin Owen Chen + +Import('*') + +if env['PROTOCOL'] == 'None': + Return() + + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/tech/tech_models/TG11LVT.model --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/tech/tech_models/TG11LVT.model Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,181 @@ +# WARNING: Most commercial fabs will not be happy if you release their exact +# process information! If you derive these numbers through SPICE models, +# the process design kit, or any other confidential material, please round-off +# the values and leave the process name unidentifiable by fab (i.e. call it +# Bulk90LVT instead of TSMC90LVT) if you release parameters publicly. This +# rule may not apply for open processes, but you may want to check. + +# All units are in SI, (volts, meters, kelvin, farads, ohms, amps, etc.) + +# This file contains the model for a Tri-Gate (Multi-Gate) 11nm LVT process +Name = TG11LVT + +# Supply voltage used in the circuit and for characterizations (V) +Vdd = 0.6 +# Temperature (K) +Temperature = 340 + +# ============================================================================= +# Parameters for transistors +# ============================================================================= + +# Contacted gate pitch (m) +Gate->PitchContacted = 0.080e-6 + +# Min gate width (m) +Gate->MinWidth = 0.080e-6 + +# Gate cap per unit width (F/m) +Gate->CapPerWidth = 0.61e-9 +# Source/Drain cap per unit width (F/m) +Drain->CapPerWidth = 0.56e-9 + +# Parameters characterization temperature (K) +Nmos->CharacterizedTemperature = 300.0 +Pmos->CharacterizedTemperature = 300.0 + +#------------------------------------------------------------------------------ +# I_Eff definition in Na, IEDM 2002 +# I_EFF = (I(VG = 0.5, VD = 1.0) + I(VG = 1.0, VD = 0.5))/2 +# R_EFF = VDD / I_EFF * 1 / (2 ln(2)) +# This is generally more accurate for when the delay is input transition time +# limited +#------------------------------------------------------------------------------ +# Effective resistance (Ohm-m) +Nmos->EffResWidth = 1.16e-3 +Pmos->EffResWidth = 1.28e-3 + +#------------------------------------------------------------------------------ +# The ratio of extra effective resistance with each additional stacked +# transistor +# EffResStackRatio = (R_EFF_NAND2 - R_EFF_INV) / R_EFF_INV) +# For example, inverter has an normalized effective drive resistance of 1.0. +# A NAND2 (2-stack) will have an effective drive of 1.0 + 0.7, a NAND3 (3-stack) +# will have an effective drive of 1.0 + 2 * 0.7. Use NORs for Pmos. This fit +# works relatively well up to 4 stacks. This value will change depending on the +# VDD used. +#------------------------------------------------------------------------------ +# Effective resistance stack ratio +Nmos->EffResStackRatio = 0.89 +Pmos->EffResStackRatio = 0.86 + +#------------------------------------------------------------------------------ +# I_OFF defined as |I_DS| for |V_DS| = V_DD and |V_GS| = 0.0 +# Minimum off current is used in technologies where I_OFF stops scaling +# with transistor width below some threshold +#------------------------------------------------------------------------------ +# Off current per width (A/m) +Nmos->OffCurrent = 100.0e-3 +Pmos->OffCurrent = 100.0e-3 +# Minimum off current (A) +Nmos->MinOffCurrent = 40e-9 +Pmos->MinOffCurrent = 4e-9 + +# Subthreshold swing (V/dec) +Nmos->SubthresholdSwing = 0.080 +Pmos->SubthresholdSwing = 0.080 +# DIBL factor (V/V) +Nmos->DIBL = 0.125 +Pmos->DIBL = 0.125 +# Subthreshold temperature swing (K/dec) +Nmos->SubthresholdTempSwing = 100.0 +Pmos->SubthresholdTempSwing = 100.0 +#------------------------------------------------------------------------------ + +# ============================================================================= +# Parameters for interconnect +# ============================================================================= + +Wire->AvailableLayers = [Metal1,Local,Intermediate,Semiglobal,Global] + +# Metal 1 Wire (used for std cell routing only) +# Min width (m) +Wire->Metal1->MinWidth = 20e-9 +# Min spacing (m) +Wire->Metal1->MinSpacing = 20e-9 +# Resistivity (Ohm-m) +Wire->Metal1->Resistivity = 6.8e-8 +# Metal thickness (m) +Wire->Metal1->MetalThickness = 35.0e-9 +# Dielectric thickness (m) +Wire->Metal1->DielectricThickness = 35.0e-9 +# Dielectric constant +Wire->Metal1->DielectricConstant = 3.00 + +# Local wire, 1.0X of the M1 pitch +# Min width (m) +Wire->Local->MinWidth = 20e-9 +# Min spacing (m) +Wire->Local->MinSpacing = 20e-9 +# Resistivity (Ohm-m) +Wire->Local->Resistivity = 6.8e-8 +# Metal thickness (m) +Wire->Local->MetalThickness = 35.0e-9 +# Dielectric thickness (m) +Wire->Local->DielectricThickness = 35.0e-9 +# Dielectric constant +Wire->Local->DielectricConstant = 3.00 + +# Intermediate wire, 2.0X the M1 pitch +# Min width (m) +Wire->Intermediate->MinWidth = 40e-9 +# Min spacing (m) +Wire->Intermediate->MinSpacing = 40e-9 +# Resistivity (Ohm-m) +Wire->Intermediate->Resistivity = 4.50e-8 +# Metal thickness (m) +Wire->Intermediate->MetalThickness = 70.0e-9 +# Dielectric thickness (m) +Wire->Intermediate->DielectricThickness = 70.0e-9 +# Dielectric constant +Wire->Intermediate->DielectricConstant = 2.80 + +# Semiglobal wire, 4.0X the M1 pitch +# Min width (m) +Wire->Semiglobal->MinWidth = 80e-9 +# Min spacing (m) +Wire->Semiglobal->MinSpacing = 80e-9 +# Resistivity (Ohm-m) +Wire->Semiglobal->Resistivity = 2.80e-8 +# Metal thickness (m) +Wire->Semiglobal->MetalThickness = 150.0e-9 +# Dielectric thickness (m) +Wire->Semiglobal->DielectricThickness = 150.0e-9 +# Dielectric constant +Wire->Semiglobal->DielectricConstant = 2.60 + +# Global wire, 8.0X the M1 pitch +# Min width (m) +Wire->Global->MinWidth = 160e-9 +# Min spacing (m) +Wire->Global->MinSpacing = 160e-9 +# Resistivity (Ohm-m) +Wire->Global->Resistivity = 2.30e-8 +# Metal thickness (m) +Wire->Global->MetalThickness = 280e-9 +# Dielectric thickness (m) +Wire->Global->DielectricThickness = 250e-9 +# Dielectric constant +Wire->Global->DielectricConstant = 2.60 + +# ============================================================================= +# Parameters for Standard Cells +# ============================================================================= + +# The height of the standard cell is usually a multiple of the vertical +# M1 pitch (tracks). By definition, an X1 size cell has transistors +# that fit exactly in the given cell height without folding, or leaving +# any wasted vertical area + +# Reasonable values for the number of M1 tracks that we have seen are 8-14 +StdCell->Tracks = 11 +# Height overhead due to supply rails, well spacing, etc. Note that this will grow +# if the height of the standard cell decreases! +StdCell->HeightOverheadFactor = 1.400 + +# Sets the available sizes of each standard cell. Keep in mind that +# 1.0 is the biggest cell without any transistor folding +StdCell->AvailableSizes = [1.0, 1.4, 2.0, 3.0, 4.0, 6.0, 8.0, 10.0, 12.0, 16.0] + + + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/util/CommonType.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/util/CommonType.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_UTIL_COMMON_TYPE_H__ +#define __DSENT_UTIL_COMMON_TYPE_H__ + +#include + +#include "mem/ruby/network/dsent/dsent-core/libutil/LibUtil.hh" + +#include "mem/ruby/network/dsent/dsent-core/util/Result.hh" + +#include "mem/ruby/network/dsent/dsent-core/tech/TechModel.hh" + +namespace DSENT +{ + using std::cout; + using std::endl; + + // Enable functions + using LibUtil::deletePtrMap; + using LibUtil::clearPtrMap; + using LibUtil::deletePtrVector; + using LibUtil::clearPtrVector; + + // Enable classes + using LibUtil::Exception; + using LibUtil::Log; + using LibUtil::String; + using LibUtil::Map; + using LibUtil::StringMap; + + typedef StringMap ParameterMap; + typedef StringMap PropertyMap; + +} // namespace DSENT + +#endif // __DSENT_UTIL_COMMON_TYPE_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/util/Config.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/util/Config.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_UTIL_CONFIG_H__ +#define __DSENT_UTIL_CONFIG_H__ + +#include "mem/ruby/network/dsent/dsent-core/util/CommonType.hh" + +namespace DSENT +{ + class TechModel; + class StdCellLib; + + class Config : public LibUtil::Config + { + public: + static void allocate(const String& cfg_file_name_); + static void release(); + static Config* getSingleton(); + + protected: + static Config* ms_singleton_; + + public: + Config(); + ~Config(); + + public: + void setTechModel(const TechModel* tech_model_); + const TechModel* getTechModel() const; + + void constructTechModel(const String& overwrite_str_); + + protected: + void readFile(const String& file_name_); + + protected: + const TechModel* m_tech_model_; + }; // class Config +} // namespace DSENT + +#endif // __DSENT_UTIL_CONFIG_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/util/Config.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/util/Config.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/util/Config.hh" + +#include "mem/ruby/network/dsent/dsent-core/model/std_cells/StdCellLib.hh" + +namespace DSENT +{ + + Config* Config::ms_singleton_ = NULL; + + void Config::allocate(const String& cfg_file_name_) + { + Log::printLine("Config::allocate"); + + // Allocate static Config instance + ASSERT(!ms_singleton_, "Config singleton is allocated"); + ms_singleton_ = new Config(); + + // If the filename is an empty string, no file is read into Config + if(cfg_file_name_.size() != 0) + { + ms_singleton_->readFile(cfg_file_name_); + } + + Log::printLine("Config::allocate - End"); + return; + } + + void Config::release() + { + Log::printLine("Config::release"); + + // Release static Config instance + ASSERT(ms_singleton_, "Config singleton is not allocated"); + delete ms_singleton_; + ms_singleton_ = NULL; + + Log::printLine("Config::release - End"); + return; + } + + Config* Config::getSingleton() + { + ASSERT(ms_singleton_, "Config singleton is not allocated"); + return ms_singleton_; + } + + Config::Config() + : m_tech_model_(NULL) + {} + + Config::~Config() + { + delete m_tech_model_; + } + + void Config::setTechModel(const TechModel* tech_model_) + { + ASSERT((tech_model_ != NULL), "tech_model_ is null"); + + m_tech_model_ = tech_model_; + return; + } + + const TechModel* Config::getTechModel() const + { + ASSERT((m_tech_model_ != NULL), "m_tech_model_ is null"); + + return m_tech_model_; + } + + void Config::readFile(const String& file_name_) + { + Log::printLine("Config::readFile"); + + LibUtil::Config::readFile(file_name_); + + Log::printLine("Config::readFile - End"); + return; + } + + void Config::constructTechModel(const String& overwrite_str_) + { + Log::printLine("Config::constructTechModel"); + + // Allocate static TechModel instance + const String& electrical_tech_model_filename = get("ElectricalTechModelFilename"); + + TechModel* tech_model = new TechModel(); + tech_model->readFile(electrical_tech_model_filename); + if(keyExist("PhotonicTechModelFilename")) + { + const String& photonic_tech_model_filename = get("PhotonicTechModelFilename"); + tech_model->readFile(photonic_tech_model_filename); + } + + // Overwrite the settings at runtime + tech_model->readString(overwrite_str_); + + // Allocate static StdCellLib instance + StdCellLib* std_cell_lib = new StdCellLib(tech_model); + + // Set the StdCellLib pointer in static TechModel instance + tech_model->setStdCellLib(std_cell_lib); + + m_tech_model_ = tech_model; + Log::printLine("Config::constructTechModel - End"); + return; + } +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/util/Constants.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/util/Constants.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_UTIL_CONSTANTS_H__ +#define __DSENT_UTIL_CONSTANTS_H__ + +namespace DSENT +{ + class Constants + { + public: + // Physical constants + static const double pi; + static const double k; + static const double c; + static const double q; + static const double e0; + static const double es; + }; + +} // namespace DSENT + +#endif // __DSENT_UTIL_CONSTANTS_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/util/Constants.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/util/Constants.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + + +#include "mem/ruby/network/dsent/dsent-core/util/Constants.hh" + +namespace DSENT +{ + // PI + const double Constants::pi = 3.14159; //PI + // Boltzman's + const double Constants::k = 1.3806503e-23; // m^2 * kg / (s^2 * K); + // Speed of light + const double Constants::c = 2.9979246e8; // m/s + // Charge of electron + const double Constants::q = 1.602e-19; // C + // Permitivity of free space + const double Constants::e0 = 8.85e-12; + // Permitivity ratio of silicon + const double Constants::es = 11.7; + +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/util/Result.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/util/Result.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENT_UTIL_RESULT_H__ +#define __DSENT_UTIL_RESULT_H__ + +#include +#include + +#include "mem/ruby/network/dsent/dsent-core/libutil/String.hh" +#include "mem/ruby/network/dsent/dsent-core/libutil/Map.hh" + +namespace DSENT +{ + using std::ostream; + using std::vector; + using LibUtil::Map; + using LibUtil::String; + + class Result + { + public: + class SubResult + { + public: + SubResult(const Result* result_, const String& producer_, double num_results_); + ~SubResult(); + + public: + const Result* getResult() const; + const String& getProducer() const; + double getNumResults() const; + + SubResult* clone() const; + + protected: + SubResult(const SubResult& sub_result_); + + private: + // Pointer to the actual result + const Result* m_result_; + // Name of the instance that produces this result + String m_producer_; + // Number of the times this result should be produce + double m_num_results_; + }; // class SubResult + + public: + Result(); + Result(const String& result_name_); + virtual ~Result(); + + public: + // Get the name of result + const String& getName() const; + // Add a sub result + void addSubResult(const Result* sub_result_, const String& result_producer_, double num_results_); + // Remove all sub results + void removeAllSubResults(); + // Set the value of a result, not available except for AtomicResult + virtual void setValue(double value_); + // Set the value of a result, not available except for AtomicResult + virtual void addValue(double value_); + // Get the value of a result, not available except for AtomicResult + virtual double getValue() const; + // Loop through all sub results and calculate the sum + virtual double calculateSum() const; + // Print the result with hierarchy if detail_level_ > 0. Print the sum when detail_level_ <= 0 + void print(const String& prepend_str_, int detail_level_, ostream& ost_) const; + // Print the tree of the results + void printHierarchy(const String& prepend_str_, int detail_level_, ostream& ost_) const; + + Result* clone() const; + + protected: + Result(const Result& result_); + virtual void print(const String& prepend_str_, double num_results_, int detail_level_, ostream& ost_) const; + + private: + String m_result_name_; + vector m_sub_results_; + }; // class Result + + class AtomicResult : public Result + { + public: + AtomicResult(const String& result_name_, double value_ = 0.0); + ~AtomicResult(); + + public: + void setValue(double value_); + void addValue(double value_); + double getValue() const; + virtual double calculateSum() const; + AtomicResult* clone() const; + + protected: + AtomicResult(const AtomicResult& atomic_result_); + virtual void print(const String& prepend_str_, double num_results_, int detail_level_, ostream& ost_) const; + + private: + // Actual value of the result + double m_value_; + }; // class AtomicResult +} // namespace DSENT + +#endif // __DSENT_UTIL_RESULT_H__ + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/util/Result.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/util/Result.cc Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#include "mem/ruby/network/dsent/dsent-core/util/Result.hh" + +#include + +#include "mem/ruby/network/dsent/dsent-core/libutil/Log.hh" +#include "mem/ruby/network/dsent/dsent-core/libutil/Assert.hh" + +namespace DSENT +{ + using std::ostream; + using std::endl; + + Result::SubResult::SubResult(const Result* sub_result_, const String& producer_, double num_results_) + : m_result_(sub_result_), m_producer_(producer_), m_num_results_(num_results_) + { + // Check if the result is not a null pointer + ASSERT((sub_result_ != NULL), "Internal error: sub_result_ is null"); + + // Check if the number of results greater than 0 + ASSERT((num_results_ >= 0), "Internal error: num_results_ (" + String(num_results_) + ") is less than 0"); + } + + Result::SubResult::~SubResult() + {} + + const Result* Result::SubResult::getResult() const + { + return m_result_; + } + + const String& Result::SubResult::getProducer() const + { + return m_producer_; + } + + double Result::SubResult::getNumResults() const + { + return m_num_results_; + } + + Result::SubResult* Result::SubResult::clone() const + { + return new SubResult(*this); + } + + Result::SubResult::SubResult(const SubResult& sub_result_) + : m_result_(sub_result_.m_result_), m_producer_(sub_result_.m_producer_), m_num_results_(sub_result_.m_num_results_) + {} + + Result::Result() + {} + + Result::Result(const String& result_name_) + : m_result_name_(result_name_) + {} + + Result::~Result() + { + // Clear all sub results + for(vector::iterator it = m_sub_results_.begin(); + it != m_sub_results_.end(); ++it) + { + SubResult* sub_result = (*it); + delete sub_result; + } + } + + const String& Result::getName() const + { + return m_result_name_; + } + + void Result::setValue(double /* value_ */) + { + throw LibUtil::Exception("[Error] " + getName() + " -> Cannot set the value of a non-atomic result!"); + return; + } + + void Result::addValue(double /* value_ */) + { + throw LibUtil::Exception("[Error] " + getName() + + " -> Cannot add the value of a non-atomic result"); + return; + } + + double Result::getValue() const + { + throw LibUtil::Exception("[Error] " + getName() + " -> Cannot get the value of a non-atomic result!"); + return 0.0; + } + + void Result::addSubResult(const Result* sub_result_, const String& result_producer_, double num_results_) + { + SubResult* new_sub_result = new SubResult(sub_result_, result_producer_, num_results_); + m_sub_results_.push_back(new_sub_result); + return; + } + + void Result::removeAllSubResults() + { + // Clear all sub results + for(vector::iterator it = m_sub_results_.begin(); + it != m_sub_results_.end(); ++it) + { + SubResult* sub_result = (*it); + delete sub_result; + } + m_sub_results_.clear(); + return; + } + + double Result::calculateSum() const + { + double sum = 0.0; + + // Loop through all sub results and calculate the sum + for(vector::const_iterator it = m_sub_results_.begin(); + it != m_sub_results_.end(); ++it) + { + const SubResult* temp_sub_result = (*it); + const Result* temp_result = temp_sub_result->getResult(); + double num_results = temp_sub_result->getNumResults(); + sum += temp_result->calculateSum()*num_results; + } + return sum; + } + + void Result::print(const String& prepend_str_, int detail_level_, ostream& ost_) const + { + print(prepend_str_, 1.0, detail_level_, ost_); + return; + } + + Result* Result::clone() const + { + return new Result(*this); + } + + Result::Result(const Result& result_) + { + // Copy the result name + m_result_name_ = result_.m_result_name_; + + // Clone all sub results + for(vector::const_iterator it = m_sub_results_.begin(); + it != m_sub_results_.end(); ++it) + { + const SubResult* temp_sub_result = (*it); + SubResult* new_sub_result = temp_sub_result->clone(); + m_sub_results_.push_back(new_sub_result); + } + } + + void Result::print(const String& prepend_str_, double num_results_, int detail_level_, ostream& ost_) const + { + // Go down to lower level if detail_level_ > 0, else print the sthe sthe sthe sum + if(detail_level_ > 0) + { + for(vector::const_iterator it = m_sub_results_.begin(); + it != m_sub_results_.end(); ++it) + { + const SubResult* temp_sub_result = (*it); + const Result* temp_result = temp_sub_result->getResult(); + const String& temp_producer = temp_sub_result->getProducer(); + const String& temp_result_name = temp_result->getName(); + double temp_num_results = temp_sub_result->getNumResults(); + String temp_prepend_str = prepend_str_ + "->" + temp_producer; + + if(!temp_result_name.empty()) + { + temp_prepend_str += ":" + temp_result_name; + } + temp_result->print(temp_prepend_str, num_results_*temp_num_results, detail_level_ - 1, ost_); + } + } + else + { + ost_ << prepend_str_ << " = " << calculateSum()*num_results_; + ost_ << " (" << calculateSum() << " * " << num_results_ << ")" << endl; + } + return; + } + + void Result::printHierarchy(const String& prepend_str_, int detail_level_, ostream& ost_) const + { + if(detail_level_ > 0) + { + for(vector::const_iterator it = m_sub_results_.begin(); it != m_sub_results_.end(); ++it) + { + const SubResult* temp_sub_result = (*it); + const Result* temp_result = temp_sub_result->getResult(); + const String& temp_producer = temp_sub_result->getProducer(); + const String& temp_result_name = temp_result->getName(); + String temp_prepend_str = prepend_str_ + " "; + + ost_ << prepend_str_ << " |--" << temp_producer << "->" << temp_result_name << endl; + + temp_result->printHierarchy(temp_prepend_str, detail_level_ - 1, ost_); + } + } + return; + } + + AtomicResult::AtomicResult(const String& result_name_, double value_) + : Result(result_name_), m_value_(value_) + {} + + AtomicResult::~AtomicResult() + {} + + void AtomicResult::setValue(double value_) + { + m_value_ = value_; + return; + } + + void AtomicResult::addValue(double value_) + { + m_value_ += value_; + return; + } + + double AtomicResult::getValue() const + { + return m_value_; + } + + double AtomicResult::calculateSum() const + { + return m_value_; + } + + AtomicResult* AtomicResult::clone() const + { + return new AtomicResult(*this); + } + + AtomicResult::AtomicResult(const AtomicResult& atomic_result_) + : Result(atomic_result_), m_value_(atomic_result_.m_value_) + {} + + void AtomicResult::print(const String& prepend_str_, double num_results_, int /* detail_level_ */, ostream& ost_) const + { + ost_ << prepend_str_ << " = " << m_value_*num_results_; + ost_ << " (" << m_value_ << " * " << num_results_ << ")" << endl; + return; + } +} // namespace DSENT + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent-core/util/SConscript --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent-core/util/SConscript Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,36 @@ +# 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. +# +# Authors: Chia-Hsin Owen Chen + +Import('*') + +if env['PROTOCOL'] == 'None': + Return() + +Source('Constants.cc') +Source('Result.cc') +Source('Config.cc') + diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/dsent/dsent_contrib.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/network/dsent/dsent_contrib.hh Wed Dec 05 02:30:52 2012 -0500 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2012 Massachusetts Institute of Technology + * 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. + * + * Authors: Chen Sun + * Chia-Hsin Owen Chen + */ + +#ifndef __DSENTCONTRIB_H__ +#define __DSENTCONTRIB_H__ + +#include "mem/ruby/network/dsent/DSENTInterface.hh" +#include "mem/ruby/network/dsent/DSENTElectricalLink.hh" +// #include "mem/ruby/network/dsent/DSENTOpticalLink.hh" +#include "mem/ruby/network/dsent/DSENTRouter.hh" + +#endif diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.py --- a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.py Mon Nov 19 11:21:09 2012 -0500 +++ b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetLink_d.py Wed Dec 05 02:30:52 2012 -0500 @@ -44,6 +44,7 @@ "number of virtual networks") channel_width = Param.Int(Parent.bandwidth_factor, "channel width == bw factor") + link_length = Param.Float(Parent.length, "link length") class CreditLink_d(NetworkLink_d): type = 'CreditLink_d' diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.hh --- a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.hh Mon Nov 19 11:21:09 2012 -0500 +++ b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.hh Wed Dec 05 02:30:52 2012 -0500 @@ -48,6 +48,11 @@ class NetworkLink_d; class CreditLink_d; +// DSENT class forwarding +namespace dsent_contrib { + class DSENTInterface; +} + class GarnetNetwork_d : public BaseGarnetNetwork { public: @@ -106,6 +111,9 @@ int m_buffers_per_data_vc; int m_buffers_per_ctrl_vc; + + // DSENT + dsent_contrib::DSENTInterface* m_dsent_interface_; }; inline std::ostream& diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc --- a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc Mon Nov 19 11:21:09 2012 -0500 +++ b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc Wed Dec 05 02:30:52 2012 -0500 @@ -30,6 +30,8 @@ #include +#include + #include "base/cast.hh" #include "base/stl_helpers.hh" #include "mem/protocol/MachineType.hh" @@ -44,9 +46,15 @@ #include "mem/ruby/network/garnet/fixed-pipeline/Router_d.hh" #include "mem/ruby/network/Topology.hh" +// DSENT include files +#include "mem/ruby/network/dsent/DSENTInterface.hh" + using namespace std; using m5::stl_helpers::deletePointers; +// DSENT using +using dsent_contrib::DSENTInterface; + GarnetNetwork_d::GarnetNetwork_d(const Params *p) : BaseGarnetNetwork(p) { @@ -65,6 +73,9 @@ Router_d* router = safe_cast(*i); m_router_ptr_vector.push_back(router); } + + // Set DSENT interface pointer + m_dsent_interface_ = p->dsent_interface; } void @@ -129,6 +140,7 @@ deletePointers(m_link_ptr_vector); deletePointers(m_creditlink_ptr_vector); delete m_topology_ptr; + delete m_dsent_interface_; } void @@ -302,8 +314,16 @@ void GarnetNetwork_d::printPowerStats(ostream& out) const { - out << "Network Power" << endl; - out << "-------------" << endl; + // Initialize DSENT link and router model + for(int i = 0; i < m_link_ptr_vector.size(); i++) { + m_link_ptr_vector[i]->init_dsent_model(m_dsent_interface_); + } + + for(int i = 0; i < m_router_ptr_vector.size(); i++) { + m_router_ptr_vector[i]->init_dsent_model(m_dsent_interface_); + } + + // Calculate power stats double m_total_link_power = 0.0; double m_dynamic_link_power = 0.0; double m_static_link_power = 0.0; @@ -313,24 +333,43 @@ double m_clk_power = 0.0; for (int i = 0; i < m_link_ptr_vector.size(); i++) { - m_total_link_power += m_link_ptr_vector[i]->calculate_power(); + // Link performance number is always updated m_dynamic_link_power += m_link_ptr_vector[i]->get_dynamic_power(); m_static_link_power += m_link_ptr_vector[i]->get_static_power(); } + m_total_link_power = m_dynamic_link_power + m_static_link_power; for (int i = 0; i < m_router_ptr_vector.size(); i++) { - m_total_router_power += m_router_ptr_vector[i]->calculate_power(); + // Update router performance numbers + m_router_ptr_vector[i]->update_performance_numbers(); + m_dynamic_router_power += m_router_ptr_vector[i]->get_dynamic_power(); m_static_router_power += m_router_ptr_vector[i]->get_static_power(); m_clk_power += m_router_ptr_vector[i]->get_clk_power(); } - out << "Link Dynamic Power = " << m_dynamic_link_power << " W" << endl; - out << "Link Static Power = " << m_static_link_power << " W" << endl; - out << "Total Link Power = " << m_total_link_power << " W " << endl; - out << "Router Dynamic Power = " << m_dynamic_router_power << " W" << endl; - out << "Router Clock Power = " << m_clk_power << " W" << endl; - out << "Router Static Power = " << m_static_router_power << " W" << endl; - out << "Total Router Power = " << m_total_router_power << " W " <release_dsent_model(); + } + + for (int i = 0; i < m_router_ptr_vector.size(); i++) { + m_router_ptr_vector[i]->release_dsent_model(); + } + + // Print power stats + out << "Network Power" << endl; + out << "-------------" << endl; + + out << "Link Dynamic Power = " << scientific << m_dynamic_link_power << " W" << endl; + out << "Link Static Power = " << scientific << m_static_link_power << " W" << endl; + out << "Total Link Power = " << scientific << m_total_link_power << " W " << endl; + out << "Router Dynamic Power = " << scientific << m_dynamic_router_power << " W" << endl; + out << "Router Clock Power = " << scientific << m_clk_power << " W" << endl; + out << "Router Static Power = " << scientific << m_static_router_power << " W" << endl; + out << "Total Router Power = " << scientific << m_total_router_power << " W " << endl; + out << "Total Network Power = " << scientific << m_total_link_power + m_total_router_power << " W" << endl; out << "-------------" << endl; out << endl; } diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh --- a/src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh Mon Nov 19 11:21:09 2012 -0500 +++ b/src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh Wed Dec 05 02:30:52 2012 -0500 @@ -37,12 +37,17 @@ #include "mem/ruby/common/Consumer.hh" #include "mem/ruby/network/garnet/fixed-pipeline/flitBuffer_d.hh" #include "mem/ruby/network/garnet/NetworkHeader.hh" -#include "mem/ruby/network/orion/NetworkPower.hh" #include "params/NetworkLink_d.hh" #include "sim/sim_object.hh" class GarnetNetwork_d; +// DSENT forward declaration +namespace dsent_contrib { + class DSENTInterface; + class DSENTElectricalLink; +} + class NetworkLink_d : public SimObject, public Consumer { public: @@ -56,26 +61,29 @@ int getLinkUtilization(); std::vector getVcLoad(); int get_id(){return m_id;} - double get_dynamic_power(){return m_power_dyn;} - double get_static_power(){return m_power_sta;} void wakeup(); - double calculate_power(); + // DSENT related functions + void init_dsent_model(const dsent_contrib::DSENTInterface* dsent_interface); + void release_dsent_model(); + double get_dynamic_power(); + double get_static_power(); inline bool isReady() { return linkBuffer->isReady(); } inline flit_d* peekLink() { return linkBuffer->peekTopFlit(); } inline flit_d* consumeLink() { return linkBuffer->getTopFlit(); } void init_net_ptr(GarnetNetwork_d* net_ptr) { - m_net_ptr = net_ptr; + m_network_ptr = net_ptr; } protected: int m_id; int m_latency; + double m_length; int channel_width; - GarnetNetwork_d *m_net_ptr; + GarnetNetwork_d *m_network_ptr; flitBuffer_d *linkBuffer; Consumer *link_consumer; flitBuffer_d *link_srcQueue; @@ -83,8 +91,8 @@ std::vector m_vc_load; int m_flit_width; - double m_power_dyn; - double m_power_sta; + // DSENT variables + dsent_contrib::DSENTElectricalLink* m_dsent_link; }; #endif // __MEM_RUBY_NETWORK_GARNET_FIXED_PIPELINE_NETWORK_LINK_D_HH__ diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.cc --- a/src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.cc Mon Nov 19 11:21:09 2012 -0500 +++ b/src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.cc Wed Dec 05 02:30:52 2012 -0500 @@ -28,13 +28,22 @@ * Authors: Niket Agarwal */ +#include "mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.hh" #include "mem/ruby/network/garnet/fixed-pipeline/CreditLink_d.hh" #include "mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh" +// DSENT include files +#include "mem/ruby/network/dsent/DSENTElectricalLink.hh" + +// DSENT using +using dsent_contrib::DSENTInterface; +using dsent_contrib::DSENTElectricalLink; + NetworkLink_d::NetworkLink_d(const Params *p) : SimObject(p), Consumer(this) { m_latency = p->link_latency; + m_length = p->link_length; channel_width = p->channel_width; m_id = p->link_id; linkBuffer = new flitBuffer_d(); @@ -44,6 +53,8 @@ for (int i = 0; i < (p->vcs_per_vnet * p->virt_nets); i++) { m_vc_load[i] = 0; } + + m_dsent_link = NULL; } NetworkLink_d::~NetworkLink_d() @@ -88,6 +99,42 @@ return m_link_utilized; } +void +NetworkLink_d::init_dsent_model(const DSENTInterface* dsent_interface) +{ + m_dsent_link = new DSENTElectricalLink( + m_length, + channel_width, + dsent_interface + ); +} + +double +NetworkLink_d::get_dynamic_power() +{ + // Calculate the total simulation time + double sim_cycles = (double)(g_system_ptr->getTime() - m_network_ptr->getRubyStartTime()); + double sim_time = sim_cycles * (1.0 / m_dsent_link->get_frequency()); + + double dynamic_energy = m_dsent_link->calc_dynamic_energy(m_link_utilized); + + return (dynamic_energy / sim_time); +} + +double +NetworkLink_d::get_static_power() +{ + return m_dsent_link->get_static_power(); +} + +void +NetworkLink_d::release_dsent_model() +{ + if (m_dsent_link != NULL) + delete m_dsent_link; + m_dsent_link = NULL; +} + NetworkLink_d * NetworkLink_dParams::create() { diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/garnet/fixed-pipeline/Router_d.hh --- a/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.hh Mon Nov 19 11:21:09 2012 -0500 +++ b/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.hh Wed Dec 05 02:30:52 2012 -0500 @@ -36,9 +36,9 @@ #include "mem/ruby/common/NetDest.hh" #include "mem/ruby/network/BasicRouter.hh" +#include "mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.hh" #include "mem/ruby/network/garnet/fixed-pipeline/flit_d.hh" #include "mem/ruby/network/garnet/NetworkHeader.hh" -#include "mem/ruby/network/orion/NetworkPower.hh" #include "params/GarnetRouter_d.hh" class GarnetNetwork_d; @@ -52,6 +52,12 @@ class Switch_d; class FaultModel; +// DSENT forward declaration +namespace dsent_contrib { + class DSENTInterface; + class DSENTRouter; +} + class Router_d : public BasicRouter { public: @@ -89,12 +95,15 @@ void printFaultVector(std::ostream& out); void printAggregateFaultProbability(std::ostream& out); - double calculate_power(); - void calculate_performance_numbers(); + void update_performance_numbers(); - double get_dynamic_power(){return m_power_dyn;} - double get_static_power(){return m_power_sta;} - double get_clk_power(){return m_clk_power;} + // DSENT related functions + void init_dsent_model(const dsent_contrib::DSENTInterface* dsent_interface); + void release_dsent_model(); + double get_dynamic_power(); + double get_static_power(); + double get_clk_power(); + bool get_fault_vector(int temperature, float fault_vector[]){ return m_network_ptr->fault_model->fault_vector(m_id, temperature, fault_vector); @@ -123,9 +132,8 @@ SWallocator_d *m_sw_alloc; Switch_d *m_switch; - double m_power_dyn; - double m_power_sta; - double m_clk_power; + // DSENT variables + dsent_contrib::DSENTRouter* m_dsent_router; }; #endif // __MEM_RUBY_NETWORK_GARNET_FIXED_PIPELINE_ROUTER_D_HH__ diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/garnet/fixed-pipeline/Router_d.cc --- a/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.cc Mon Nov 19 11:21:09 2012 -0500 +++ b/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.cc Wed Dec 05 02:30:52 2012 -0500 @@ -40,9 +40,16 @@ #include "mem/ruby/network/garnet/fixed-pipeline/Switch_d.hh" #include "mem/ruby/network/garnet/fixed-pipeline/VCallocator_d.hh" +// DSENT include files +#include "mem/ruby/network/dsent/DSENTRouter.hh" + using namespace std; using m5::stl_helpers::deletePointers; +// DSENT using +using dsent_contrib::DSENTInterface; +using dsent_contrib::DSENTRouter; + Router_d::Router_d(const Params *p) : BasicRouter(p) { @@ -71,6 +78,8 @@ vc_local_arbit_count[i] = 0; vc_global_arbit_count[i] = 0; } + + m_dsent_router = NULL; } Router_d::~Router_d() @@ -158,7 +167,7 @@ } void -Router_d::calculate_performance_numbers() +Router_d::update_performance_numbers() { for (int j = 0; j < m_virtual_networks; j++) { for (int i = 0; i < m_input_unit.size(); i++) { @@ -176,6 +185,135 @@ } void +Router_d::init_dsent_model(const DSENTInterface* dsent_interface) +{ + // Determine the correct #VNs + unsigned int num_vns = 0; + vector num_vcs_vec; + vector num_bufs_vec; + + for (int i = 0; i < m_virtual_networks; i++) { + // Only consider valid virtual networks while calculating the power/area + if (m_network_ptr->validVirtualNetwork(i) == true) { + num_vns++; + + // Since the number of virtual channels per virtual network is the same across all + // virtual networks, we can use 'vc_id' to find out the types of each virtual network. + int vc_id = i * m_vc_per_vnet; + VNET_type vnet_type = m_network_ptr->get_vnet_type(vc_id); + + // All virtual networks are assumed to have the same number of virtual channels + // Currently only two types of virtual networks are assumed: DATA_VNET_ and CTRL_VNET_ + // The number of buffers per virtual channel can be different in the DATA_VNET_ and CTRL_VNET_ + unsigned int num_vcs = (unsigned int)m_vc_per_vnet; + unsigned int num_bufs = (unsigned int)((vnet_type == DATA_VNET_)? m_network_ptr->getBuffersPerDataVC() : m_network_ptr->getBuffersPerCtrlVC()); + + num_vcs_vec.push_back(num_vcs); + num_bufs_vec.push_back(num_bufs); + } + } + + // Calculate flit width (convert from byte to bit) + int flit_width_bits = m_network_ptr->getNiFlitSize() * 8; + + // Initiate a DSENT router + m_dsent_router = new DSENTRouter( + m_input_unit.size(), + m_output_unit.size(), + num_vns, + num_vcs_vec, + num_bufs_vec, + flit_width_bits, + dsent_interface + ); +} + +void +Router_d::release_dsent_model() +{ + if(m_dsent_router != NULL) + delete m_dsent_router; + m_dsent_router = NULL; +} + +double +Router_d::get_dynamic_power() +{ + // Calculate the total simulation time + double sim_cycles = (double)(g_system_ptr->getTime() - m_network_ptr->getRubyStartTime()); + double sim_time = sim_cycles * (1.0 / m_dsent_router->get_frequency()); + + // Calculate energy consumed by each event + // Only valid virtual network is considered + double energy_buf_write = 0.0; + double energy_buf_read = 0.0; + double energy_sa_local = 0.0; + double energy_sa_global = 0.0; + double energy_xbar = 0.0; + + for (int i = 0; i < m_virtual_networks; i++) { + if (m_network_ptr->validVirtualNetwork(i) == true) { + // Buffer write + energy_buf_write += m_dsent_router->calc_dynamic_energy_buf_write(buf_write_count[i]); + + // Buffer read + energy_buf_read += m_dsent_router->calc_dynamic_energy_buf_read(buf_read_count[i]); + + // VC allocation + // Currently no energy is considered for VC allocation + } + } + + // Switch allocation local + energy_sa_local = m_dsent_router->calc_dynamic_energy_sa_local(sw_local_arbit_count); + + // Switch allocation global + energy_sa_global = m_dsent_router->calc_dynamic_energy_sa_global(sw_global_arbit_count); + + // Crossbar traversal ('1' means unicast) + // Currently does not account for multicasts because no performance counter that + // keeps this information + energy_xbar = m_dsent_router->calc_dynamic_energy_xbar(crossbar_count, 1); + + double dynamic_energy = energy_buf_write + energy_buf_read + + energy_sa_local + energy_sa_global + + energy_xbar; + + return (dynamic_energy / sim_time); +} + +double +Router_d::get_static_power() +{ + // Get static power for each component + // VC allocation is not considered + double power_buf = m_dsent_router->get_static_power_buf(); + double power_sa = m_dsent_router->get_static_power_sa(); + double power_xbar = m_dsent_router->get_static_power_xbar(); + + double static_power = power_buf + power_sa + power_xbar; + + return static_power; +} + +double +Router_d::get_clk_power() +{ + // Calculate the total simulation time + double sim_cycles = (double)(g_system_ptr->getTime() - m_network_ptr->getRubyStartTime()); + double sim_time = sim_cycles * (1.0 / m_dsent_router->get_frequency()); + + // Get dynamic energy + // Assumed always clocking + double dynamic_energy = m_dsent_router->calc_dynamic_energy_clock(sim_cycles); + + // Get static power + double static_power = m_dsent_router->get_static_power_clock(); + + return ((dynamic_energy / sim_time) + static_power); +} + +void Router_d::printFaultVector(ostream& out) { int temperature_celcius = BASELINE_TEMPERATURE_CELCIUS; diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Allocator/Arbiter.hh --- a/src/mem/ruby/network/orion/Allocator/Arbiter.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#ifndef __ARBITER_H__ -#define __ARBITER_H__ - -#include "mem/ruby/network/orion/Type.hh" - -class TechParameter; -class FlipFlop; - -class Arbiter -{ - public: - enum ArbiterModel - { - NO_MODEL = 0, - RR_ARBITER, - MATRIX_ARBITER - }; - - public: - Arbiter(const ArbiterModel arb_model_, - const uint32_t req_width_, - const double len_in_wire_, - const TechParameter* tech_param_ptr_); - virtual ~Arbiter() = 0; - - public: - virtual double calc_dynamic_energy(double num_req_, bool is_max_) const = 0; - double get_static_power() const; - - protected: - ArbiterModel m_arb_model; - uint32_t m_req_width; - double m_len_in_wire; - const TechParameter* m_tech_param_ptr; - - FlipFlop* m_ff_ptr; - - double m_e_chg_req; - double m_e_chg_grant; - - double m_i_static; - - public: - static Arbiter* create_arbiter(const string& arb_model_str_, - const string& ff_model_str_, - uint32_t req_width_, - double len_in_wire_, - const TechParameter* tech_param_ptr_); -}; - -#endif - diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Allocator/Arbiter.cc --- a/src/mem/ruby/network/orion/Allocator/Arbiter.cc Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#include -#include - -#include "mem/ruby/network/orion/Allocator/Arbiter.hh" -#include "mem/ruby/network/orion/Allocator/MatrixArbiter.hh" -#include "mem/ruby/network/orion/Allocator/RRArbiter.hh" -#include "mem/ruby/network/orion/TechParameter.hh" - -using namespace std; - -Arbiter::Arbiter(const ArbiterModel arb_model_, - const uint32_t req_width_, - const double len_in_wire_, - const TechParameter* tech_param_ptr_) -{ - assert(req_width_ == req_width_); - assert(len_in_wire_ == len_in_wire_); - - m_arb_model = arb_model_; - m_req_width = req_width_; - m_len_in_wire = len_in_wire_; - m_tech_param_ptr = tech_param_ptr_; -} - -Arbiter::~Arbiter() -{} - -double -Arbiter::get_static_power() const -{ - double vdd = m_tech_param_ptr->get_vdd(); - double SCALE_S = m_tech_param_ptr->get_SCALE_S(); - - return m_i_static*vdd*SCALE_S; -} - -Arbiter* -Arbiter::create_arbiter(const string& arb_model_str_, - const string& ff_model_str_, - uint32_t req_width_, - double len_in_wire_, - const TechParameter* tech_param_ptr_) -{ - if (arb_model_str_ == string("RR_ARBITER")) { - - return new RRArbiter(ff_model_str_, req_width_, - len_in_wire_, tech_param_ptr_); - - } else if (arb_model_str_ == string("MATRIX_ARBITER")) { - - return new MatrixArbiter(ff_model_str_, req_width_, - len_in_wire_, tech_param_ptr_); - - } else { - cerr << "WARNING: No Arbiter model" << endl; - return (Arbiter*)NULL; - } -} diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Allocator/MatrixArbiter.hh --- a/src/mem/ruby/network/orion/Allocator/MatrixArbiter.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#ifndef __MATRIXARBITER_H__ -#define __MATRIXARBITER_H__ - -#include "mem/ruby/network/orion/Allocator/Arbiter.hh" -#include "mem/ruby/network/orion/Type.hh" - -class TechParameter; - -class MatrixArbiter : public Arbiter -{ - public: - MatrixArbiter( - const string& ff_model_str_, - uint32_t req_width_, - double len_in_wire_, - const TechParameter* tech_param_ptr_ - ); - ~MatrixArbiter(); - - public: - double calc_dynamic_energy(double num_req_, bool is_max_) const; - - private: - void init(const string& ff_model_str_); - double calc_req_cap(); - double calc_pri_cap(); - double calc_grant_cap(); - double calc_int_cap(); - double calc_i_static(); - - private: - double m_e_chg_int; -}; - -#endif diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Allocator/MatrixArbiter.cc --- a/src/mem/ruby/network/orion/Allocator/MatrixArbiter.cc Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,251 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#include -#include -#include - -#include "mem/ruby/network/orion/Allocator/MatrixArbiter.hh" -#include "mem/ruby/network/orion/FlipFlop.hh" -#include "mem/ruby/network/orion/TechParameter.hh" - -using namespace std; - -MatrixArbiter::MatrixArbiter(const string& ff_model_str_, - uint32_t req_width_, - double len_in_wire_, - const TechParameter* tech_param_ptr_) - : Arbiter(RR_ARBITER, req_width_, len_in_wire_, tech_param_ptr_) -{ - init(ff_model_str_); -} - -MatrixArbiter::~MatrixArbiter() -{ - delete m_ff_ptr; -} - -double -MatrixArbiter::calc_dynamic_energy(double num_req_, bool is_max_) const -{ - assert(num_req_ < m_req_width); - - double num_grant; - if (num_req_ >= 1) num_grant = 1; - else if (num_req_) num_grant = 1.0 / ceil(1.0 / num_req_); - else num_grant = 0; - - uint32_t total_pri = m_req_width * (m_req_width - 1) / 2; - double num_chg_pri = (m_req_width - 1) * (is_max_? 1 : 0.5); - - double e_atomic; - double e_arb = 0; - - //FIXME: we may overestimate request switch - e_atomic = m_e_chg_req * num_req_; - e_arb += e_atomic; - - e_atomic = m_e_chg_grant * num_grant; - e_arb += e_atomic; - - // priority register - e_atomic = m_ff_ptr->get_e_switch() * num_chg_pri * num_grant; - e_arb += e_atomic; - - // assume 1 and 0 are uniformly distributed - if ((m_ff_ptr->get_e_keep_0() >= m_ff_ptr->get_e_keep_1()) || (!is_max_)) - { - e_atomic = m_ff_ptr->get_e_keep_0(); - e_atomic *= (total_pri - num_chg_pri * num_grant) * (is_max_? 1 : 0.5); - e_arb += e_atomic; - } - if ((m_ff_ptr->get_e_keep_0() < m_ff_ptr->get_e_keep_1()) || (!is_max_)) - { - e_atomic = m_ff_ptr->get_e_keep_1(); - e_atomic *= (total_pri - num_chg_pri * num_grant) * (is_max_? 1 : 0.5); - e_arb += e_atomic; - } - - e_atomic = m_ff_ptr->get_e_clock()*total_pri; - e_arb += e_atomic; - - // based on above assumptions - if (is_max_) - { - e_atomic = m_e_chg_int; - e_atomic *= (min(num_req_, m_req_width * 0.5) + 2) * (m_req_width - 1); - } - else - { - e_atomic = m_e_chg_int * (num_req_ + 1) * (m_req_width - 1) * 0.5; - } - e_arb += e_atomic; - - return e_arb; -} - -void MatrixArbiter::init(const string& ff_model_str_) -{ - double e_factor = m_tech_param_ptr->get_EnergyFactor(); - - m_e_chg_req = calc_req_cap() / 2 * e_factor; - // two grant signals switch together, so no 1/2 - m_e_chg_grant = calc_grant_cap() * e_factor; - m_e_chg_int = calc_int_cap() / 2 * e_factor; - - double ff_load = calc_pri_cap(); - m_ff_ptr = new FlipFlop(ff_model_str_, ff_load, m_tech_param_ptr); - - m_i_static = calc_i_static(); - return; -} - -// the "huge" NOR gate in matrix arbiter model is an approximation -// switch cap of request signal -double MatrixArbiter::calc_req_cap() -{ - double total_cap = 0; - - // part 1: gate cap of NOR gates - // FIXME: need actual size - double WdecNORn = m_tech_param_ptr->get_WdecNORn(); - double WdecNORp = m_tech_param_ptr->get_WdecNORp(); - double gatecap = m_tech_param_ptr->calc_gatecap(WdecNORn+WdecNORp, 0); - total_cap += (m_req_width - 1) * gatecap; - - // part 2: inverter - // FIXME: need actual size - double Wdecinvn = m_tech_param_ptr->get_Wdecinvn(); - double Wdecinvp = m_tech_param_ptr->get_Wdecinvp(); - total_cap += m_tech_param_ptr->calc_draincap(Wdecinvn, - TechParameter::NCH, 1) - + m_tech_param_ptr->calc_draincap(Wdecinvp, TechParameter::PCH, 1) - + m_tech_param_ptr->calc_gatecap(Wdecinvn+Wdecinvp, 0); - - // part 3: gate cap of the "huge" NOR gate - // FIXME: need actual size - total_cap += m_tech_param_ptr->calc_gatecap(WdecNORn + WdecNORp, 0); - - // part 4: wire cap - double Cmetal = m_tech_param_ptr->get_Cmetal(); - total_cap += m_len_in_wire * Cmetal; - - return total_cap; -} - -// switch cap of priority signal -double MatrixArbiter::calc_pri_cap() -{ - double total_cap = 0; - - // part 1: gate cap of NOR gate - // FIXME: need actual size - double WdecNORn = m_tech_param_ptr->get_WdecNORn(); - double WdecNORp = m_tech_param_ptr->get_WdecNORp(); - total_cap += 2 * m_tech_param_ptr->calc_gatecap(WdecNORn+WdecNORp, 0); - - return total_cap; -} - -// switch cap of grant signa -double MatrixArbiter::calc_grant_cap() -{ - double total_cap = 0; - - // part 1: drain cap of NOR gate - // FIXME: need actual size - double WdecNORn = m_tech_param_ptr->get_WdecNORn(); - double WdecNORp = m_tech_param_ptr->get_WdecNORp(); - double draincap1 = m_tech_param_ptr->calc_draincap(WdecNORn, - TechParameter::NCH, 1); - - double draincap2 = m_tech_param_ptr->calc_draincap(WdecNORp, - TechParameter::PCH, - m_req_width); - - total_cap += m_req_width * (draincap1 + draincap2); - - return total_cap; -} - -// switch cap of internal node -double MatrixArbiter::calc_int_cap() -{ - double total_cap = 0; - - double WdecNORn = m_tech_param_ptr->get_WdecNORn(); - double WdecNORp = m_tech_param_ptr->get_WdecNORp(); - // part 1: drain cap of NOR gate (this bloc) - // FIXME: need actual size - total_cap += 2 * m_tech_param_ptr->calc_draincap(WdecNORn, - TechParameter::NCH, 1) - + m_tech_param_ptr->calc_draincap(WdecNORp, TechParameter::PCH, 2); - - // part 2: gate cap of NOR gate (next block) - // FIXME: need actual size - total_cap += m_tech_param_ptr->calc_gatecap(WdecNORn + WdecNORp, 0); - - return total_cap; -} - -double MatrixArbiter::calc_i_static() -{ - double i_static = 0; - - double WdecNORn = m_tech_param_ptr->get_WdecNORn(); - double WdecNORp = m_tech_param_ptr->get_WdecNORp(); - double Wdecinvn = m_tech_param_ptr->get_Wdecinvn(); - double Wdecinvp = m_tech_param_ptr->get_Wdecinvp(); - double Wdff = m_tech_param_ptr->get_Wdff(); - double NOR2_TAB_0 = m_tech_param_ptr->get_NOR2_TAB(0); - double NOR2_TAB_1 = m_tech_param_ptr->get_NOR2_TAB(1); - double NOR2_TAB_2 = m_tech_param_ptr->get_NOR2_TAB(2); - double NOR2_TAB_3 = m_tech_param_ptr->get_NOR2_TAB(3); - double NMOS_TAB_0 = m_tech_param_ptr->get_NMOS_TAB(0); - double PMOS_TAB_0 = m_tech_param_ptr->get_PMOS_TAB(0); - double DFF_TAB_0 = m_tech_param_ptr->get_DFF_TAB(0); - - // NOR - i_static += ((2 * m_req_width - 1) * m_req_width * - ((WdecNORp * NOR2_TAB_0 + WdecNORn * - (NOR2_TAB_1 + NOR2_TAB_2 + NOR2_TAB_3)) / 4)); - // inverter - i_static += m_req_width * - ((Wdecinvn * NMOS_TAB_0 + Wdecinvp * PMOS_TAB_0) / 2); - // dff - i_static += (m_req_width * (m_req_width - 1) / 2) * Wdff * DFF_TAB_0; - - return i_static; -} diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Allocator/RRArbiter.hh --- a/src/mem/ruby/network/orion/Allocator/RRArbiter.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#ifndef __RRARBITER_H__ -#define __RRARBITER_H__ - -#include "mem/ruby/network/orion/Allocator/Arbiter.hh" -#include "mem/ruby/network/orion/Type.hh" - -class TechParameter; - -class RRArbiter : public Arbiter -{ - public: - RRArbiter( - const string& ff_model_str_, - uint32_t req_width_, - double len_in_wire_, - const TechParameter* tech_param_ptr_ - ); - ~RRArbiter(); - - public: - double calc_dynamic_energy(double num_req_, bool is_max_) const; - - private: - void init(const string& ff_model_str_); - double calc_req_cap(); - double calc_pri_cap(); - double calc_grant_cap(); - double calc_carry_cap(); - double calc_carry_in_cap(); - double calc_i_static(); - - private: - double m_e_chg_carry; - double m_e_chg_carry_in; -}; - -#endif diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Allocator/RRArbiter.cc --- a/src/mem/ruby/network/orion/Allocator/RRArbiter.cc Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,238 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#include -#include - -#include "mem/ruby/network/orion/Allocator/RRArbiter.hh" -#include "mem/ruby/network/orion/FlipFlop.hh" -#include "mem/ruby/network/orion/TechParameter.hh" - -using namespace std; - -RRArbiter::RRArbiter( - const string& ff_model_str_, - uint32_t req_width_, - double len_in_wire_, - const TechParameter* tech_param_ptr_ - ) : Arbiter(RR_ARBITER, req_width_, len_in_wire_, tech_param_ptr_) -{ - init(ff_model_str_); -} - -RRArbiter::~RRArbiter() -{ - delete m_ff_ptr; -} - -double RRArbiter::calc_dynamic_energy(double num_req_, bool is_max_) const -{ - if (num_req_ > m_req_width) - { - cerr << "WARNING: (num_req_ > m_req_width). Set num_req_ = m_req_width" << endl; - num_req_ = m_req_width; - } - - double num_grant; - if (num_req_ >= 1) num_grant = 1; - else if (num_req_) num_grant = 1.0 / ceil(1.0/num_req_); - else num_grant = 0; - - double e_atomic; - double e_arb = 0; - - e_atomic = m_e_chg_req*num_req_; - e_arb += e_atomic; - - e_atomic = m_e_chg_grant*num_grant; - e_arb += e_atomic; - - // assume carry signal propagates half length in average case */ - // carry does not propagate in maximum case, i.e. all carrys go down */ - e_atomic = m_e_chg_carry*m_req_width*(is_max_? 1:0.5)*num_grant; - e_arb += e_atomic; - - e_atomic = m_e_chg_carry_in*(m_req_width*(is_max_? 1:0.5)-1)*num_grant; - e_arb += e_atomic; - - // priority register - e_atomic = m_ff_ptr->get_e_switch()*2*num_grant; - e_arb += e_atomic; - - e_atomic = m_ff_ptr->get_e_keep_0()*(m_req_width-2*num_grant); - e_arb += e_atomic; - - e_atomic = m_ff_ptr->get_e_clock()*m_req_width; - e_arb += e_atomic; - - return e_arb; -} - -void RRArbiter::init(const string& ff_model_str_) -{ - double e_factor = m_tech_param_ptr->get_EnergyFactor(); - - m_e_chg_req = calc_req_cap()/2*e_factor; - // two grant signals switch together, so no 1/2 - m_e_chg_grant = calc_grant_cap()*e_factor; - m_e_chg_carry = calc_carry_cap()/2*e_factor; - m_e_chg_carry_in = calc_carry_in_cap()/2*e_factor; - - double ff_load = calc_pri_cap(); - m_ff_ptr = new FlipFlop(ff_model_str_, ff_load, m_tech_param_ptr); - - m_i_static = calc_i_static(); - return; -} - -// switch cap of request signal (round robin arbiter) -double RRArbiter::calc_req_cap() -{ - double total_cap = 0; - - // part 1: gate cap of 2 NOR gates - // FIXME: need actual size - double WdecNORn = m_tech_param_ptr->get_WdecNORn(); - double WdecNORp = m_tech_param_ptr->get_WdecNORp(); - total_cap += 2*m_tech_param_ptr->calc_gatecap(WdecNORn+WdecNORp, 0); - - // part 2: inverter - // FIXME: need actual size - double Wdecinvn = m_tech_param_ptr->get_Wdecinvn(); - double Wdecinvp = m_tech_param_ptr->get_Wdecinvp(); - total_cap += m_tech_param_ptr->calc_draincap(Wdecinvn, TechParameter::NCH, 1) - + m_tech_param_ptr->calc_draincap(Wdecinvp, TechParameter::PCH, 1) - + m_tech_param_ptr->calc_gatecap(Wdecinvn+Wdecinvp, 0); - - // part 3: wire cap - double Cmetal = m_tech_param_ptr->get_Cmetal(); - total_cap += m_len_in_wire*Cmetal; - - return total_cap; -} - -// switch cap of priority signal -double RRArbiter::calc_pri_cap() -{ - double total_cap = 0; - - // part 1: gate cap of NOR gate - // FIXME: need actual size - double WdecNORn = m_tech_param_ptr->get_WdecNORn(); - double WdecNORp = m_tech_param_ptr->get_WdecNORp(); - total_cap += m_tech_param_ptr->calc_gatecap(WdecNORn+WdecNORp, 0); - - return total_cap; -} - -// switch cap of grant signa -double RRArbiter::calc_grant_cap() -{ - double total_cap = 0; - - // part 1: drain cap of NOR gate - // FIXME: need actual size - double WdecNORn = m_tech_param_ptr->get_WdecNORn(); - double WdecNORp = m_tech_param_ptr->get_WdecNORp(); - total_cap += 2*m_tech_param_ptr->calc_draincap(WdecNORn, TechParameter::NCH, 1) - + m_tech_param_ptr->calc_draincap(WdecNORp, TechParameter::PCH, 2); - - return total_cap; -} - -// switch cap of carry signal -double RRArbiter::calc_carry_cap() -{ - double total_cap = 0; - - double WdecNORn = m_tech_param_ptr->get_WdecNORn(); - double WdecNORp = m_tech_param_ptr->get_WdecNORp(); - // part 1: drain cap of NOR gate (this bloc) - // FIXME: need actual size - total_cap += 2*m_tech_param_ptr->calc_draincap(WdecNORn, TechParameter::NCH, 1) - + m_tech_param_ptr->calc_draincap(WdecNORp, TechParameter::PCH, 2); - - // part 2: gate cap of NOR gate (next block) - // FIXME: need actual size - total_cap += m_tech_param_ptr->calc_gatecap(WdecNORn+WdecNORp, 0); - - return total_cap; -} - -// switch cap of internal carry node -double RRArbiter::calc_carry_in_cap() -{ - double total_cap = 0; - - double WdecNORn = m_tech_param_ptr->get_WdecNORn(); - double WdecNORp = m_tech_param_ptr->get_WdecNORp(); - // part 1: gate cap of 2 NOR gate - // FIXME: need actual size - total_cap += 2*m_tech_param_ptr->calc_gatecap(WdecNORn+WdecNORp, 0); - - // part 2: drain cap of NOR gate (this bloc) - // FIXME: need actual size - total_cap += 2*m_tech_param_ptr->calc_draincap(WdecNORn, TechParameter::NCH, 1) - + m_tech_param_ptr->calc_draincap(WdecNORp, TechParameter::PCH, 2); - - return total_cap; -} - -double RRArbiter::calc_i_static() -{ - double i_static = 0; - - double WdecNORn = m_tech_param_ptr->get_WdecNORn(); - double WdecNORp = m_tech_param_ptr->get_WdecNORp(); - double Wdecinvn = m_tech_param_ptr->get_Wdecinvn(); - double Wdecinvp = m_tech_param_ptr->get_Wdecinvp(); - double Wdff = m_tech_param_ptr->get_Wdff(); - double NOR2_TAB_0 = m_tech_param_ptr->get_NOR2_TAB(0); - double NOR2_TAB_1 = m_tech_param_ptr->get_NOR2_TAB(1); - double NOR2_TAB_2 = m_tech_param_ptr->get_NOR2_TAB(2); - double NOR2_TAB_3 = m_tech_param_ptr->get_NOR2_TAB(3); - double NMOS_TAB_0 = m_tech_param_ptr->get_NMOS_TAB(0); - double PMOS_TAB_0 = m_tech_param_ptr->get_PMOS_TAB(0); - double DFF_TAB_0 = m_tech_param_ptr->get_DFF_TAB(0); - - // NOR - i_static += (6*m_req_width*((WdecNORp*NOR2_TAB_0+WdecNORn*(NOR2_TAB_1+NOR2_TAB_2+NOR2_TAB_3))/4)); - // inverter - i_static += 2*m_req_width*((Wdecinvn*NMOS_TAB_0+Wdecinvp*PMOS_TAB_0)/2); - // dff - i_static += m_req_width*Wdff*DFF_TAB_0; - - return i_static; -} diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Allocator/SConscript --- a/src/mem/ruby/network/orion/Allocator/SConscript Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -# Copyright (c) 2010 Massachusetts Institute of Technology -# 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. -# -# Authors: Tushar Krishna - -Import('*') - -if env['PROTOCOL'] == 'None': - Return() - -Source('Arbiter.cc') -Source('MatrixArbiter.cc') -Source('RRArbiter.cc') -Source('SWAllocator.cc') -Source('VCAllocator.cc') diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Allocator/SWAllocator.hh --- a/src/mem/ruby/network/orion/Allocator/SWAllocator.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#ifndef __SWALLOCATOR_H__ -#define __SWALLOCATOR_H__ - -#include "mem/ruby/network/orion/Type.hh" - -class TechParameter; -class OrionConfig; -class Arbiter; -class Crossbar; - -class SWAllocator -{ - protected: - SWAllocator( - uint32_t num_in_port_, - uint32_t num_out_port_, - uint32_t num_vclass_, - uint32_t num_vchannel_, - double len_in_wire_, - const string& local_arb_model_str_, - const string& local_arb_ff_model_str_, - const string& global_arb_model_str_, - const string& global_arb_ff_model_str_, - const TechParameter* tech_param_ptr_ - ); - - public: - ~SWAllocator(); - - public: - double get_dynamic_energy_local_sw_arb(double num_req_, bool is_max_) const; - double get_dynamic_energy_global_sw_arb(double num_req_, bool is_max_) const; - double get_static_power() const; - - void print_all() const; - - protected: - void init(); - - protected: - uint32_t m_num_in_port; - uint32_t m_num_out_port; - uint32_t m_num_vclass; - uint32_t m_num_vchannel; - - Arbiter* m_local_arb_ptr; - Arbiter* m_global_arb_ptr; - - public: - static SWAllocator* create_swallocator( - uint32_t num_in_port_, - uint32_t num_out_port_, - uint32_t num_vclass_, - uint32_t num_vchannel_, - const Crossbar* xbar_ptr_, - const OrionConfig* orion_cfg_ptr_ - ); -}; - -#endif diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Allocator/SWAllocator.cc --- a/src/mem/ruby/network/orion/Allocator/SWAllocator.cc Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#include -#include - -#include "mem/ruby/network/orion/Allocator/Arbiter.hh" -#include "mem/ruby/network/orion/Allocator/SWAllocator.hh" -#include "mem/ruby/network/orion/Crossbar/Crossbar.hh" -#include "mem/ruby/network/orion/OrionConfig.hh" - -using namespace std; - -SWAllocator::SWAllocator( - uint32_t num_in_port_, - uint32_t num_out_port_, - uint32_t num_vclass_, - uint32_t num_vchannel_, - double len_in_wire_, - const string& local_arb_model_str_, - const string& local_arb_ff_model_str_, - const string& global_arb_model_str_, - const string& global_arb_ff_model_str_, - const TechParameter* tech_param_ptr_ - ) -{ - assert(num_in_port_ == num_in_port_); - assert(num_out_port_ == num_out_port_); - assert(num_vclass_ == num_vclass_); - assert(num_vchannel_ == num_vchannel_); - assert(len_in_wire_ == len_in_wire_); - - m_num_in_port = num_in_port_; - m_num_out_port = num_out_port_; - m_num_vclass = num_vclass_; - m_num_vchannel = num_vchannel_; - - if ((m_num_vclass*m_num_vchannel) > 1) - { - m_local_arb_ptr = Arbiter::create_arbiter( - local_arb_model_str_, local_arb_ff_model_str_, - m_num_vclass*m_num_vchannel, 0, tech_param_ptr_); - } - else - { - m_local_arb_ptr = NULL; - } - - if (m_num_in_port > 2) - { - m_global_arb_ptr = Arbiter::create_arbiter( - global_arb_model_str_, global_arb_ff_model_str_, - m_num_in_port-1, len_in_wire_, tech_param_ptr_); - } - else - { - m_global_arb_ptr = NULL; - } -} - -SWAllocator::~SWAllocator() -{} - -double SWAllocator::get_dynamic_energy_local_sw_arb(double num_req_, bool is_max_) const -{ - double e_local_arb = 0; - - if (m_local_arb_ptr) - { - e_local_arb = m_local_arb_ptr->calc_dynamic_energy(num_req_, is_max_); - } - return e_local_arb; -} - -double SWAllocator::get_dynamic_energy_global_sw_arb(double num_req_, bool is_max_) const -{ - double e_global_arb = 0; - - if (m_global_arb_ptr) - { - e_global_arb = m_global_arb_ptr->calc_dynamic_energy(num_req_, is_max_); - } - return e_global_arb; -} - -double SWAllocator::get_static_power() const -{ - double p_va = 0; - - if (m_local_arb_ptr) - { - // FIXME: might not be m_num_in_port; - p_va += m_local_arb_ptr->get_static_power()*m_num_in_port; - } - if (m_global_arb_ptr) - { - p_va += m_global_arb_ptr->get_static_power()*m_num_out_port; - } - return p_va; -} - -void SWAllocator::print_all() const -{ - cout << "SWAllocator:" << endl; - if (m_local_arb_ptr) - { - for (uint32_t i = 0; i < m_num_vclass*m_num_vchannel; i++) - { - cout << "\t" << "Local arb (" << i << ") = " << get_dynamic_energy_local_sw_arb(i, false) << endl; - } - } - - if (m_global_arb_ptr) - { - for (uint32_t i = 0; i < m_num_in_port-1; i++) - { - cout << "\t" << "Global arb (" << i << ") = " << get_dynamic_energy_global_sw_arb(i, false) << endl; - } - } - - cout << "\t" << "Static power = " << get_static_power() << endl; - return; -} - -SWAllocator* SWAllocator::create_swallocator( - uint32_t num_in_port_, - uint32_t num_out_port_, - uint32_t num_vclass_, - uint32_t num_vchannel_, - const Crossbar* xbar_ptr_, - const OrionConfig* orion_cfg_ptr_ - ) -{ - double len_in_wire = xbar_ptr_->get_len_req_wire(); - const string& local_arb_model_str = orion_cfg_ptr_->get("SA_IN_ARB_MODEL"); - const string& local_arb_ff_model_str = orion_cfg_ptr_->get("SA_IN_ARB_FF_MODEL"); - const string& global_arb_model_str = orion_cfg_ptr_->get("SA_OUT_ARB_MODEL"); - const string& global_arb_ff_model_str = orion_cfg_ptr_->get("SA_OUT_ARB_FF_MODEL"); - const TechParameter* tech_param_ptr = orion_cfg_ptr_->get_tech_param_ptr(); - return new SWAllocator(num_in_port_, num_out_port_, num_vclass_, num_vchannel_, - len_in_wire, local_arb_model_str, local_arb_ff_model_str, - global_arb_model_str, global_arb_ff_model_str,tech_param_ptr); -} diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Allocator/VCAllocator.hh --- a/src/mem/ruby/network/orion/Allocator/VCAllocator.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#ifndef __VCALLOCATOR_H__ -#define __VCALLOCATOR_H__ - -#include "mem/ruby/network/orion/Type.hh" - -class TechParameter; -class OrionConfig; -class Arbiter; -class Buffer; - -class VCAllocator -{ - public: - enum VAModel - { - NO_MODEL = 0, - ONE_STAGE_ARB, - TWO_STAGE_ARB, - VC_SELECT - }; - - public: - ~VCAllocator(); - - protected: - // for ONE_STAGE_ARB - VCAllocator( - uint32_t num_in_port_, - uint32_t num_out_port_, - uint32_t num_vclass_, - uint32_t num_vchannel_, - const string& arb_model_str_, - const string& arb_ff_model_str_, - const TechParameter* tech_param_ptr_ - ); - // for TWO_STAGE_ARB - VCAllocator( - uint32_t num_in_port_, - uint32_t num_out_port_, - uint32_t num_vclass_, - uint32_t num_vchannel_, - const string& local_arb_model_str_, - const string& local_arb_ff_model_str_, - const string& global_arb_model_str_, - const string& global_arb_ff_model_str_, - const TechParameter* tech_param_ptr_ - ); - // for VC_SELECT - VCAllocator( - uint32_t num_in_port_, - uint32_t num_out_port_, - uint32_t num_vclass_, - uint32_t num_vchannel_, - const string& vc_select_buf_model_str_, - const OrionConfig* orion_cfg_ptr_ - ); - - public: - double get_dynamic_energy_local_vc_arb(double num_req_, bool is_max_) const; - double get_dynamic_energy_global_vc_arb(double num_req_, bool is_max_) const; - double get_dynamic_energy_vc_select(bool is_read_, bool is_max_) const; - double get_static_power() const; - - void print_all() const; - - protected: - VAModel m_va_model; - uint32_t m_num_in_port; - uint32_t m_num_out_port; - uint32_t m_num_vclass; - uint32_t m_num_vchannel; - - Arbiter* m_local_arb_ptr; - Arbiter* m_global_arb_ptr; - Buffer* m_vc_select_ptr; - - public: - static VCAllocator* create_vcallocator( - const string& vcalloc_model_str_, - uint32_t num_in_port_, - uint32_t num_out_port_, - uint32_t num_vclass_, - uint32_t num_vchannel_, - const OrionConfig* orion_cfg_ptr_ - ); -}; - -#endif diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Allocator/VCAllocator.cc --- a/src/mem/ruby/network/orion/Allocator/VCAllocator.cc Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,302 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#include -#include -#include -#include - -#include "mem/ruby/network/orion/Allocator/Arbiter.hh" -#include "mem/ruby/network/orion/Allocator/VCAllocator.hh" -#include "mem/ruby/network/orion/Buffer/Buffer.hh" -#include "mem/ruby/network/orion/OrionConfig.hh" - -using namespace std; - -VCAllocator::VCAllocator( - uint32_t num_in_port_, - uint32_t num_out_port_, - uint32_t num_vclass_, - uint32_t num_vchannel_, - const string& arb_model_str_, - const string& arb_ff_model_str_, - const TechParameter* tech_param_ptr_ - ) -{ - assert(num_in_port_ == num_in_port_); - assert(num_out_port_ == num_out_port_); - assert(num_vclass_ == num_vclass_); - assert(num_vchannel_ == num_vchannel_); - - m_va_model = ONE_STAGE_ARB; - m_num_in_port = num_in_port_; - m_num_out_port = num_out_port_; - m_num_vclass = num_vclass_; - m_num_vchannel = num_vchannel_; - - m_local_arb_ptr = NULL; - - m_global_arb_ptr = Arbiter::create_arbiter( - arb_model_str_, arb_ff_model_str_, - (m_num_in_port-1)*m_num_vchannel, 0, tech_param_ptr_); - - m_vc_select_ptr = NULL; -} - -VCAllocator::VCAllocator( - uint32_t num_in_port_, - uint32_t num_out_port_, - uint32_t num_vclass_, - uint32_t num_vchannel_, - const string& local_arb_model_str_, - const string& local_arb_ff_model_str_, - const string& global_arb_model_str_, - const string& global_arb_ff_model_str_, - const TechParameter* tech_param_ptr_ - ) -{ - assert(num_in_port_ == num_in_port_); - assert(num_out_port_ == num_out_port_); - assert(num_vclass_ == num_vclass_); - assert(num_vchannel_ == num_vchannel_); - - m_va_model = TWO_STAGE_ARB; - m_num_in_port = num_in_port_; - m_num_out_port = num_out_port_; - m_num_vclass = num_vclass_; - m_num_vchannel = num_vchannel_; - - // first stage - m_local_arb_ptr = Arbiter::create_arbiter( - local_arb_model_str_, local_arb_ff_model_str_, - m_num_vchannel, 0, tech_param_ptr_); - - // second stage - m_global_arb_ptr = Arbiter::create_arbiter( - global_arb_model_str_, global_arb_ff_model_str_, - (m_num_in_port-1)*m_num_vchannel, 0, tech_param_ptr_); - - m_vc_select_ptr = NULL; -} - -VCAllocator::VCAllocator( - uint32_t num_in_port_, - uint32_t num_out_port_, - uint32_t num_vclass_, - uint32_t num_vchannel_, - const string& vc_select_buf_model_str_, - const OrionConfig* orion_cfg_ptr_ - ) -{ - assert(num_in_port_ == num_in_port_); - assert(num_out_port_ == num_out_port_); - assert(num_vclass_ == num_vclass_); - assert(num_vchannel_ == num_vchannel_); - - m_va_model = VC_SELECT; - m_num_in_port = num_in_port_; - m_num_out_port = num_out_port_; - m_num_vclass = num_vclass_; - m_num_vchannel = num_vchannel_; - - m_local_arb_ptr = NULL; - m_global_arb_ptr = NULL; - - uint32_t vc_select_buf_num_set = m_num_vchannel; - uint32_t vc_select_buf_line_width = (uint32_t)ceil(log2(m_num_vchannel)); - m_vc_select_ptr = new Buffer(vc_select_buf_model_str_, true, false, - vc_select_buf_num_set, vc_select_buf_line_width, 1, 1, orion_cfg_ptr_); -} - -VCAllocator::~VCAllocator() -{ - delete m_local_arb_ptr; - delete m_global_arb_ptr; - delete m_vc_select_ptr; -} - -double VCAllocator::get_dynamic_energy_local_vc_arb(double num_req_, bool is_max_) const -{ - double e_local_arb = 0; - switch(m_va_model) - { - case TWO_STAGE_ARB: - e_local_arb = m_local_arb_ptr->calc_dynamic_energy(num_req_, is_max_); - break; - case ONE_STAGE_ARB: - case VC_SELECT: - default: - e_local_arb = 0; - } - return e_local_arb; -} - -double VCAllocator::get_dynamic_energy_global_vc_arb(double num_req_, bool is_max_) const -{ - double e_global_arb = 0; - switch(m_va_model) - { - case ONE_STAGE_ARB: - case TWO_STAGE_ARB: - e_global_arb = m_global_arb_ptr->calc_dynamic_energy(num_req_, is_max_); - break; - case VC_SELECT: - default: - e_global_arb = 0; - } - return e_global_arb; -} - -double VCAllocator::get_dynamic_energy_vc_select(bool is_read_, bool is_max_) const -{ - double e_vc_select = 0; - switch(m_va_model) - { - case VC_SELECT: - e_vc_select = m_vc_select_ptr->get_dynamic_energy(is_read_, is_max_); - break; - case ONE_STAGE_ARB: - case TWO_STAGE_ARB: - default: - e_vc_select = 0; - } - return e_vc_select; -} - -double VCAllocator::get_static_power() const -{ - double p_va = 0; - switch(m_va_model) - { - case ONE_STAGE_ARB: - p_va = m_global_arb_ptr->get_static_power()*m_num_out_port*m_num_vclass*m_num_vchannel; - break; - case TWO_STAGE_ARB: - p_va += m_local_arb_ptr->get_static_power()*m_num_in_port*m_num_vclass*m_num_vchannel; - p_va += m_global_arb_ptr->get_static_power()*m_num_out_port*m_num_vclass*m_num_vchannel; - break; - case VC_SELECT: - p_va = m_vc_select_ptr->get_static_power()*m_num_out_port*m_num_vclass; - break; - default: - cerr << "ERROR: Invalid VA model" << endl; - exit(1); - } - return p_va; -} - -void VCAllocator::print_all() const -{ - switch(m_va_model) - { - case ONE_STAGE_ARB: - cout << "VCAllocator: ONE_STAGE_ARB" << endl; - for (uint32_t i = 0; i < (m_num_in_port-1)*m_num_vchannel; i++) - { - cout << "\t" << "Global arb (" << i << ") = " << get_dynamic_energy_global_vc_arb(i, false) << endl; - } - break; - case TWO_STAGE_ARB: - cout << "VCAllocator: TWO_STAGE_ARB" << endl; - for (uint32_t i = 0; i < m_num_vchannel; i++) - { - cout << "\t" << "Local arb (" << i << ") = " << get_dynamic_energy_local_vc_arb(i, false) << endl; - } - for (uint32_t i = 0; i < (m_num_in_port-1)*m_num_vchannel; i++) - { - cout << "\t" << "Global arb (" << i << ") = " << get_dynamic_energy_global_vc_arb(i, false) << endl; - } - break; - case VC_SELECT: - cout << "VCAllocator: VC_SELECT" << endl; - cout << "\t" << "Read = " << get_dynamic_energy_vc_select(true, false) << endl; - cout << "\t" << "Write = " << get_dynamic_energy_vc_select(false, false) << endl; - break; - default: - ; - } - cout << "\t" << "Static power = " << get_static_power() << endl; - return; -} - -VCAllocator* VCAllocator::create_vcallocator( - const string& vcalloc_model_str_, - uint32_t num_in_port_, - uint32_t num_out_port_, - uint32_t num_vclass_, - uint32_t num_vchannel_, - const OrionConfig* orion_cfg_ptr_ - ) -{ - if (num_vchannel_ > 1) - { - if (vcalloc_model_str_ == string("ONE_STAGE_ARB")) - { - const string& arb_model_str = orion_cfg_ptr_->get("VA_OUT_ARB_MODEL"); - const string& arb_ff_model_str = orion_cfg_ptr_->get("VA_OUT_ARB_FF_MODEL"); - const TechParameter* tech_param_ptr = orion_cfg_ptr_->get_tech_param_ptr(); - return new VCAllocator(num_in_port_, num_out_port_, num_vclass_, num_vchannel_, - arb_model_str, arb_ff_model_str, tech_param_ptr); - } - else if (vcalloc_model_str_ == string("TWO_STAGE_ARB")) - { - const string& local_arb_model_str = orion_cfg_ptr_->get("VA_IN_ARB_MODEL"); - const string& local_arb_ff_model_str = orion_cfg_ptr_->get("VA_IN_ARB_FF_MODEL"); - const string& global_arb_model_str = orion_cfg_ptr_->get("VA_OUT_ARB_MODEL"); - const string& global_arb_ff_model_str = orion_cfg_ptr_->get("VA_OUT_ARB_FF_MODEL"); - const TechParameter* tech_param_ptr = orion_cfg_ptr_->get_tech_param_ptr(); - return new VCAllocator(num_in_port_, num_out_port_, num_vclass_, num_vchannel_, - local_arb_model_str, local_arb_ff_model_str, - global_arb_model_str, global_arb_ff_model_str,tech_param_ptr); - } - else if (vcalloc_model_str_ == string("VC_SELECT")) - { - const string& vc_select_buf_model_str = orion_cfg_ptr_->get("VA_BUF_MODEL"); - return new VCAllocator(num_in_port_, num_out_port_, num_vclass_, num_vchannel_, - vc_select_buf_model_str, orion_cfg_ptr_); - } - else - { - cerr << "WARNING: No VC allocator model" << endl; - return (VCAllocator*)NULL; - } - } - else - { - // reduce to a register - return new VCAllocator(num_in_port_, num_out_port_, num_vclass_, 1, - "REGISTER", orion_cfg_ptr_); - } -} diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Buffer/AmpUnit.hh --- a/src/mem/ruby/network/orion/Buffer/AmpUnit.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#ifndef __AMPUNIT_H__ -#define __AMPUNIT_H__ - -#include "mem/ruby/network/orion/Type.hh" - -class TechParameter; - -class AmpUnit -{ - public: - enum AmpModel - { - NO_MODEL = 0, - GENERIC_AMP - }; - - public: - AmpUnit( - const string& amp_model_str_, - const TechParameter* tech_param_ptr_ - ); - ~AmpUnit(); - - public: - double get_e_access() const { return m_e_access; } - - private: - void init(); - - private: - AmpModel m_amp_model; - const TechParameter* m_tech_param_ptr; - - double m_e_access; -}; - -#endif - diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Buffer/AmpUnit.cc --- a/src/mem/ruby/network/orion/Buffer/AmpUnit.cc Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#include "mem/ruby/network/orion/Buffer/AmpUnit.hh" -#include "mem/ruby/network/orion/TechParameter.hh" - -AmpUnit::AmpUnit( - const string& amp_model_str_, - const TechParameter* tech_param_ptr_ - ) -{ - if (amp_model_str_.compare("GENERIC_AMP") == 0) - { - m_amp_model = GENERIC_AMP; - } - else - { - m_amp_model = NO_MODEL; - } - - if (m_amp_model != NO_MODEL) - { - m_tech_param_ptr = tech_param_ptr_; - - init(); - } -} - -AmpUnit::~AmpUnit() -{} - -void AmpUnit::init() -{ - double vdd = m_tech_param_ptr->get_vdd(); - double period = m_tech_param_ptr->get_period(); - double amp_Idsat = m_tech_param_ptr->get_amp_idsat(); - - m_e_access = (vdd / 8.0 * period * amp_Idsat); - return; -} diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Buffer/BitlineUnit.hh --- a/src/mem/ruby/network/orion/Buffer/BitlineUnit.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#ifndef __BITLINEUNIT_H__ -#define __BITLINEUNIT_H__ - -#include "mem/ruby/network/orion/Type.hh" - -class SRAM; -class TechParameter; - -class BitlineUnit -{ - public: - enum BitlineModel - { - NO_MODEL = 0, - RW_BITLINE, - WO_BITLINE - }; - - public: - BitlineUnit( - const string bl_model_str_, - const SRAM* sram_ptr_, - const TechParameter* tech_param_ptr_ - ); - ~BitlineUnit(); - - public: - double get_pre_unit_load() const { return m_pre_unit_load; } - - double get_e_col_read() const { return m_e_col_read; } - double get_e_col_wrtie() const { return m_e_col_write; } - double get_i_static() const { return m_i_static; } - - private: - void init(); - double calc_col_select_cap(); - double calc_col_read_cap(); - double calc_col_write_cap(); - double calc_i_static(); - - private: - BitlineModel m_bl_model; - const SRAM* m_sram_ptr; - const TechParameter* m_tech_param_ptr; - - double m_bl_len; - double m_bl_wire_cap; - double m_pre_unit_load; - - double m_e_col_sel; - double m_e_col_read; - double m_e_col_write; - - double m_i_static; -}; - -#endif - diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Buffer/BitlineUnit.cc --- a/src/mem/ruby/network/orion/Buffer/BitlineUnit.cc Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,200 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#include "base/misc.hh" -#include "mem/ruby/network/orion/Buffer/BitlineUnit.hh" -#include "mem/ruby/network/orion/Buffer/SRAM.hh" -#include "mem/ruby/network/orion/TechParameter.hh" - -BitlineUnit::BitlineUnit( - const string bl_model_str_, - const SRAM* sram_ptr_, - const TechParameter* tech_param_ptr_ - ) -{ - if (bl_model_str_ == "RW_BITLINE") - { - m_bl_model = RW_BITLINE; - } - else if (bl_model_str_ == "WO_BITLINE") - { - m_bl_model = WO_BITLINE; - } - else - { - m_bl_model = NO_MODEL; - } - - if (m_bl_model != NO_MODEL) - { - m_sram_ptr = sram_ptr_; - m_tech_param_ptr = tech_param_ptr_; - - init(); - } -} - -BitlineUnit::~BitlineUnit() -{} - -void BitlineUnit::init() -{ - uint32_t num_port = m_sram_ptr->get_num_port(); - uint32_t num_data_end = m_sram_ptr->get_num_data_end(); - double bl_cmetal; - if ((num_port > 1) || (num_data_end == 2)) - { - bl_cmetal = m_tech_param_ptr->get_CC3M2metal(); - } - else - { - bl_cmetal = m_tech_param_ptr->get_CM2metal(); - } - uint32_t num_row = m_sram_ptr->get_num_row(); - double RegCellHeight = m_tech_param_ptr->get_RegCellHeight(); - double WordlineSpacing = m_tech_param_ptr->get_WordlineSpacing(); - m_bl_len = num_row*(RegCellHeight + num_port*WordlineSpacing); - m_bl_wire_cap = m_bl_len * bl_cmetal; - - double e_factor = m_tech_param_ptr->get_EnergyFactor(); - double sense_e_factor = m_tech_param_ptr->get_SenseEnergyFactor(); - switch(m_bl_model) - { - case RW_BITLINE: - if (num_data_end == 2) - { - m_e_col_sel = calc_col_select_cap() * e_factor; - m_e_col_read = calc_col_read_cap() * sense_e_factor; - } - else - { - m_e_col_sel = 0; - m_e_col_read = calc_col_read_cap() * e_factor; - } - m_e_col_write = calc_col_write_cap() * e_factor; - - m_i_static = calc_i_static(); - break; - case WO_BITLINE: - m_e_col_sel = m_e_col_read = 0; - m_e_col_write = calc_col_write_cap() * e_factor; - //FIXME - no static power? - break; - default: - fatal("Error in BITLINE model.\n"); - } - return; -} - -double BitlineUnit::calc_col_select_cap() -{ - double Wbitmuxn = m_tech_param_ptr->get_Wbitmuxn(); - return m_tech_param_ptr->calc_gatecap(Wbitmuxn, 1); -} - -double BitlineUnit::calc_col_read_cap() -{ - double total_cap = 0; - - // part 1: drain cap of precharge tx's - //total_cap = m_num_bl_pre * Util::calc_draincap(m_pre_size, Util::PCH, 1); - - // part 2: drain cap of pass tx's - double Wmemcellr = m_tech_param_ptr->get_Wmemcellr(); - uint32_t num_row = m_sram_ptr->get_num_row(); - total_cap = num_row * m_tech_param_ptr->calc_draincap(Wmemcellr, TechParameter::NCH, 1); - - // part 3: metal cap - total_cap += m_bl_wire_cap; - m_pre_unit_load = total_cap; - - // part 4: bitline inverter - uint32_t num_data_end = m_sram_ptr->get_num_data_end(); - if (num_data_end == 1) - { - // FIXME: magic numbers - double MSCALE = m_tech_param_ptr->get_MSCALE(); - total_cap += m_tech_param_ptr->calc_gatecap(MSCALE * (29.9 + 7.8), 0) + m_tech_param_ptr->calc_gatecap(MSCALE * (47.0 + 12.0), 0); - } - - // part 5: gate cap of sense amplifier or output driver - bool is_outdrv = m_sram_ptr->get_is_outdrv(); - if (num_data_end == 2) - { // sense amplifier - double WsenseQ1to4 = m_tech_param_ptr->get_WsenseQ1to4(); - total_cap += 2 * m_tech_param_ptr->calc_gatecap(WsenseQ1to4, 10); - } - else if (is_outdrv) - { - double Woutdrvnandn = m_tech_param_ptr->get_Woutdrvnandn(); - double Woutdrvnandp = m_tech_param_ptr->get_Woutdrvnandp(); - double Woutdrvnorn = m_tech_param_ptr->get_Woutdrvnorn(); - double Woutdrvnorp = m_tech_param_ptr->get_Woutdrvnorp(); - - total_cap += m_tech_param_ptr->calc_gatecap(Woutdrvnandn, 1) + m_tech_param_ptr->calc_gatecap(Woutdrvnandp, 1) + m_tech_param_ptr->calc_gatecap(Woutdrvnorn, 1) + m_tech_param_ptr->calc_gatecap(Woutdrvnorp, 1); - } - - return total_cap; -} - -double BitlineUnit::calc_col_write_cap() -{ - double total_cap, psize, nsize; - - // part 1: line cap, including drain cap of pass tx's and metal cap - uint32_t num_row = m_sram_ptr->get_num_row(); - double Wmemcellw = m_tech_param_ptr->get_Wmemcellw(); - total_cap = num_row * m_tech_param_ptr->calc_draincap(Wmemcellw, TechParameter::NCH, 1) + m_bl_wire_cap; - - // part 2: write driver - double period = m_tech_param_ptr->get_period(); - psize = m_tech_param_ptr->calc_driver_psize(total_cap, period / 8.0); - double Wdecinvn = m_tech_param_ptr->get_Wdecinvn(); - double Wdecinvp = m_tech_param_ptr->get_Wdecinvp(); - nsize = psize * Wdecinvn / Wdecinvp; - total_cap += m_tech_param_ptr->calc_draincap(psize, TechParameter::PCH, 1) + m_tech_param_ptr->calc_draincap(nsize, TechParameter::NCH, 1) + m_tech_param_ptr->calc_gatecap(psize + nsize, 1); - - return total_cap; -} - -double BitlineUnit::calc_i_static() -{ - double Wdecinvn = m_tech_param_ptr->get_Wdecinvn(); - double Wdecinvp = m_tech_param_ptr->get_Wdecinvp(); - double NMOS_TAB_0 = m_tech_param_ptr->get_NMOS_TAB(0); - double PMOS_TAB_0 = m_tech_param_ptr->get_PMOS_TAB(0); - - return (2*(Wdecinvn*NMOS_TAB_0+Wdecinvp*PMOS_TAB_0)); -} diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Buffer/Buffer.hh --- a/src/mem/ruby/network/orion/Buffer/Buffer.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#ifndef __BUFFER_H__ -#define __BUFFER_H__ - -#include "mem/ruby/network/orion/Type.hh" - -class OrionConfig; -class TechParameter; - -class SRAM; -class Register; - -class Buffer -{ - public: - enum BufferModel - { - NO_MODEL = 0, - BUF_SRAM, - BUF_REG - }; - - public: - Buffer( - const string& buffer_model_str_, - bool is_fifo_, - bool is_outdrv_, - uint32_t num_entry_, - uint32_t line_width_, - uint32_t num_read_port_, - uint32_t num_write_port_, - const OrionConfig* orion_cfg_ptr_ - ); - ~Buffer(); - - public: - double get_dynamic_energy(bool is_read_, bool is_max_) const; - double get_static_power() const; - - void print_all() const; - - private: - void init(); - - private: - BufferModel m_buffer_model; - uint32_t m_num_entry; - uint32_t m_line_width; - - bool m_is_fifo; - bool m_is_outdrv; - uint32_t m_num_read_port; - uint32_t m_num_write_port; - const OrionConfig* m_orion_cfg_ptr; - const TechParameter* m_tech_param_ptr; - - SRAM* m_sram_ptr; - Register* m_reg_ptr; -}; - -#endif - diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Buffer/Buffer.cc --- a/src/mem/ruby/network/orion/Buffer/Buffer.cc Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,187 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#include -#include - -#include "mem/ruby/network/orion/Buffer/Buffer.hh" -#include "mem/ruby/network/orion/Buffer/Register.hh" -#include "mem/ruby/network/orion/Buffer/SRAM.hh" -#include "mem/ruby/network/orion/OrionConfig.hh" -#include "mem/ruby/network/orion/TechParameter.hh" - -using namespace std; - -Buffer::Buffer( - const string& buffer_model_str_, - bool is_fifo_, - bool is_outdrv_, - uint32_t num_entry_, - uint32_t line_width_, - uint32_t num_read_port_, - uint32_t num_write_port_, - const OrionConfig* orion_cfg_ptr_ - ) -{ - if (buffer_model_str_ == string("SRAM")) - { - m_buffer_model = BUF_SRAM; - } - else if(buffer_model_str_ == string("REGISTER")) - { - m_buffer_model = BUF_REG; - } - else - { - m_buffer_model = NO_MODEL; - } - - if (m_buffer_model != NO_MODEL) - { - assert(num_entry_ == num_entry_); - assert(line_width_ == line_width_); - assert(num_read_port_ == num_read_port_); - assert(num_write_port_ == num_write_port_); - - m_num_entry = num_entry_; - m_line_width = line_width_; - m_is_fifo = is_fifo_; - m_is_outdrv = is_outdrv_; - m_num_read_port = num_read_port_; - m_num_write_port = num_write_port_; - - m_orion_cfg_ptr = orion_cfg_ptr_; - m_tech_param_ptr = m_orion_cfg_ptr->get_tech_param_ptr(); - - init(); - } -} - -Buffer::~Buffer() -{ - delete m_sram_ptr; -} - -double Buffer::get_dynamic_energy( - bool is_read_, - bool is_max_ - ) const -{ - if (m_buffer_model == BUF_SRAM) - { - if (is_read_) - { - return m_sram_ptr->calc_e_read(is_max_); - } - else - { - return m_sram_ptr->calc_e_write(is_max_); - } - } - else if (m_buffer_model == BUF_REG) - { - if (is_read_) - { - return m_reg_ptr->calc_e_read(); - } - else - { - return m_reg_ptr->calc_e_write(); - } - } - else - { - return 0; - } -} - -double Buffer::get_static_power() const -{ - double vdd = m_tech_param_ptr->get_vdd(); - double SCALE_S = m_tech_param_ptr->get_SCALE_S(); - if (m_buffer_model == BUF_SRAM) - { - return m_sram_ptr->calc_i_static()*vdd*SCALE_S; - } - else if (m_buffer_model == BUF_REG) - { - return m_reg_ptr->calc_i_static()*vdd*SCALE_S; - } - else - { - return 0; - } -} - -void Buffer::print_all() const -{ - cout << "Buffer" << endl; - cout << "\t" << "Read = " << get_dynamic_energy(true, false) << endl; - cout << "\t" << "Write = " << get_dynamic_energy(false, false) << endl; - cout << "\t" << "Static power = " << get_static_power() << endl; - return; -} - -void Buffer::init() -{ - if(m_buffer_model == BUF_SRAM) - { - uint32_t num_data_end = m_orion_cfg_ptr->get("SRAM_NUM_DATA_END"); - const string& rowdec_model_str = m_orion_cfg_ptr->get("SRAM_ROWDEC_MODEL"); - const string& wl_model_str = m_orion_cfg_ptr->get("SRAM_WORDLINE_MODEL"); - const string& bl_pre_model_str = m_orion_cfg_ptr->get("SRAM_BITLINE_PRE_MODEL"); - const string& mem_model_str = "NORMAL_MEM"; - const string& bl_model_str = m_orion_cfg_ptr->get("SRAM_BITLINE_MODEL"); - const string& amp_model_str = m_orion_cfg_ptr->get("SRAM_AMP_MODEL"); - const string& outdrv_model_str = m_orion_cfg_ptr->get("SRAM_OUTDRV_MODEL"); - m_sram_ptr = new SRAM( - m_num_entry, m_line_width, m_is_fifo, m_is_outdrv, - m_num_read_port, m_num_write_port, num_data_end, - rowdec_model_str, wl_model_str, bl_pre_model_str, mem_model_str, - bl_model_str, amp_model_str, outdrv_model_str, m_tech_param_ptr); - } - else if (m_buffer_model == BUF_REG) - { - m_sram_ptr = NULL; - m_reg_ptr = new Register(m_num_entry, m_line_width, m_tech_param_ptr); - } - else - { - m_sram_ptr = NULL; - m_reg_ptr = NULL; - } - return; -} - diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Buffer/DecoderUnit.hh --- a/src/mem/ruby/network/orion/Buffer/DecoderUnit.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#ifndef __DECODERUNIT_H__ -#define __DECODERUNIT_H__ - -#include "mem/ruby/network/orion/TechParameter.hh" -#include "mem/ruby/network/orion/Type.hh" - -class DecoderUnit -{ - public: - enum DecModel - { - NO_MODEL = 0, - GENERIC_DEC - }; - - public: - DecoderUnit( - const string& dec_model_str_, - uint32_t dec_width_, - const TechParameter* tech_param_ptr_ - ); - ~DecoderUnit(); - - public: - uint32_t get_dec_width() const { return m_dec_width; } - uint32_t get_num_in_2nd() const { return m_num_in_2nd; } - double get_e_chg_addr() const { return m_e_chg_addr; } - double get_e_chg_output() const { return m_e_chg_output; } - double get_e_chg_l1() const { return m_e_chg_l1; } - - private: - void init(); - double calc_chgl1_cap(); - double calc_select_cap(); - double calc_chgaddr_cap(); - - private: - DecModel m_dec_model; - uint32_t m_dec_width; - const TechParameter* m_tech_param_ptr; - - uint32_t m_num_in_1st; - uint32_t m_num_in_2nd; - uint32_t m_num_out_0th; - uint32_t m_num_out_1st; - - double m_e_chg_l1; - double m_e_chg_output; - double m_e_chg_addr; -}; - -#endif - diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Buffer/DecoderUnit.cc --- a/src/mem/ruby/network/orion/Buffer/DecoderUnit.cc Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,171 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#include - -#include "mem/ruby/network/orion/Buffer/DecoderUnit.hh" -#include "mem/ruby/network/orion/TechParameter.hh" - -using namespace std; - -DecoderUnit::DecoderUnit( - const string& dec_model_str_, - uint32_t dec_width_, - const TechParameter* tech_param_ptr_ - ) -{ - if (dec_model_str_.compare("GENERIC_DEC") == 0) - { - m_dec_model = GENERIC_DEC; - } - else - { - m_dec_model = NO_MODEL; - } - - if (m_dec_model != NO_MODEL) - { - m_dec_width = dec_width_; - m_tech_param_ptr = tech_param_ptr_; - - init(); - } -} - -DecoderUnit::~DecoderUnit() -{ -} - -void DecoderUnit::init() -{ - if (m_dec_width >= 4) - { // 2-level decoder - m_num_in_1st = (m_dec_width == 4)? 2:3; - m_num_out_0th = 1 << (m_num_in_1st - 1); - m_num_in_2nd = (uint32_t)ceil((double)m_dec_width/(double)m_num_in_1st); - m_num_out_1st = 1 << (m_dec_width - m_num_in_1st); - } - else if (m_dec_width >= 2) - { // 1-level decoder - m_num_in_1st = m_dec_width; - m_num_out_0th = 1 << (m_num_in_1st - 1); - m_num_in_2nd = m_num_out_1st = 0; - } - else - { - m_num_in_1st = m_num_out_0th = m_num_in_2nd = m_num_out_1st = 0; - } - - // compute energy constants - double e_factor = m_tech_param_ptr->get_vdd() * m_tech_param_ptr->get_vdd(); - if (m_dec_width >= 4) - { - m_e_chg_l1 = calc_chgl1_cap() * e_factor; - m_e_chg_output = calc_select_cap() * e_factor; - } - else if (m_dec_width >= 2) - { - m_e_chg_l1 = calc_chgl1_cap() * e_factor; - m_e_chg_output = 0; - } - else - { - m_e_chg_l1 = m_e_chg_output = 0; - } - m_e_chg_addr = calc_chgaddr_cap() * e_factor; - - return; -} - -double DecoderUnit::calc_chgl1_cap() -{ - double total_cap; - - // part 1: drain cap of level-1 decoder - double Wdec3to8p = m_tech_param_ptr->get_Wdec3to8p(); - double Wdec3to8n = m_tech_param_ptr->get_Wdec3to8n(); - total_cap = m_num_in_1st * m_tech_param_ptr->calc_draincap(Wdec3to8p, TechParameter::PCH, 1) + m_tech_param_ptr->calc_draincap(Wdec3to8n, TechParameter::NCH, m_num_in_1st); - - /* part 2: gate cap of level-2 decoder */ - /* WHS: 40 and 20 should go to PARM */ - double WdecNORn = m_tech_param_ptr->get_WdecNORn(); - double WdecNORp = m_tech_param_ptr->get_WdecNORp(); - total_cap += m_num_out_0th*m_tech_param_ptr->calc_gatecap((WdecNORn+WdecNORp), m_num_in_2nd*40 + 20); - - return total_cap; -} - -double DecoderUnit::calc_select_cap() -{ - double total_cap; - - // part 1: drain cap of last level decoders - double WdecNORp = m_tech_param_ptr->get_WdecNORp(); - double WdecNORn = m_tech_param_ptr->get_WdecNORn(); - total_cap = m_num_in_2nd * m_tech_param_ptr->calc_draincap(WdecNORn, TechParameter::NCH, 1) + m_tech_param_ptr->calc_draincap(WdecNORp, TechParameter::PCH, m_num_in_2nd); - - // part 2: output inverter - // WHS: 20 should go to PARM - double Wdecinvp = m_tech_param_ptr->get_Wdecinvp(); - double Wdecinvn = m_tech_param_ptr->get_Wdecinvn(); - total_cap += m_tech_param_ptr->calc_draincap(Wdecinvn, TechParameter::NCH, 1) + m_tech_param_ptr->calc_draincap(Wdecinvp, TechParameter::PCH, 1) + m_tech_param_ptr->calc_gatecap(Wdecinvn + Wdecinvp, 20); - - return total_cap; -} - -double DecoderUnit::calc_chgaddr_cap() -{ - double total_cap; - - // stage 1: input driver - double Wdecdrivep = m_tech_param_ptr->get_Wdecdrivep(); - double Wdecdriven = m_tech_param_ptr->get_Wdecdriven(); - total_cap = m_tech_param_ptr->calc_draincap(Wdecdrivep, TechParameter::PCH, 1) + m_tech_param_ptr->calc_draincap(Wdecdriven, TechParameter::NCH, 1) + m_tech_param_ptr->calc_gatecap(Wdecdriven, 1); - - /* inverter to produce complement addr, this needs 1/2 */ - /* WHS: assume Wdecinv(np) for this inverter */ - double Wdecinvp = m_tech_param_ptr->get_Wdecinvp(); - double Wdecinvn = m_tech_param_ptr->get_Wdecinvn(); - total_cap += (m_tech_param_ptr->calc_draincap(Wdecinvp, TechParameter::PCH, 1) + m_tech_param_ptr->calc_draincap(Wdecinvn, TechParameter::NCH, 1) + m_tech_param_ptr->calc_gatecap(Wdecinvp, 1) + m_tech_param_ptr->calc_gatecap(Wdecinvn, 1)) / 2; - - /* stage 2: gate cap of level-1 decoder */ - /* WHS: 10 should go to PARM */ - double Wdec3to8p = m_tech_param_ptr->get_Wdec3to8p(); - double Wdec3to8n = m_tech_param_ptr->get_Wdec3to8n(); - total_cap += m_num_out_0th*m_tech_param_ptr->calc_gatecap( Wdec3to8n + Wdec3to8p, 10 ); - - return total_cap; -} - diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Buffer/MemUnit.hh --- a/src/mem/ruby/network/orion/Buffer/MemUnit.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#ifndef __MEMUNIT_H__ -#define __MEMUNIT_H__ - -#include "mem/ruby/network/orion/Type.hh" - -class SRAM; -class TechParameter; - -class MemUnit -{ - public: - enum MemModel - { - NO_MODEL = 0, - NORMAL_MEM - }; - - public: - MemUnit( - const string& mem_model_str_, - const SRAM* sram_ptr_, - const TechParameter* tech_param_ptr_ - ); - ~MemUnit(); - - public: - double get_e_switch() const { return m_e_switch; } - double get_i_static() const { return m_i_static; } - - private: - void init(); - double calc_mem_cap(); - double calc_i_static(); - - private: - MemModel m_mem_model; - const SRAM* m_sram_ptr; - const TechParameter* m_tech_param_ptr; - - double m_e_switch; - double m_i_static; -}; - -#endif - diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Buffer/MemUnit.cc --- a/src/mem/ruby/network/orion/Buffer/MemUnit.cc Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#include - -#include "mem/ruby/network/orion/Buffer/MemUnit.hh" -#include "mem/ruby/network/orion/Buffer/SRAM.hh" -#include "mem/ruby/network/orion/TechParameter.hh" - -using namespace std; - -MemUnit::MemUnit( - const string& mem_model_str_, - const SRAM* sram_ptr_, - const TechParameter* tech_param_ptr_ - ) -{ - if (mem_model_str_.compare("NORMAL_MEM") == 0) - { - m_mem_model = NORMAL_MEM; - } - else - { - m_mem_model = NO_MODEL; - } - - if (m_mem_model != NO_MODEL) - { - m_sram_ptr = sram_ptr_; - m_tech_param_ptr = tech_param_ptr_; - - init(); - } -} - -MemUnit::~MemUnit() -{} - -void MemUnit::init() -{ - double e_factor = m_tech_param_ptr->get_EnergyFactor(); - - m_e_switch = calc_mem_cap() * e_factor; - - m_i_static = calc_i_static(); -} - -double MemUnit::calc_mem_cap() -{ - double Wmemcella = m_tech_param_ptr->get_Wmemcella(); - double Wmemcellbscale = m_tech_param_ptr->get_Wmemcellbscale(); - double Wmemcellr = m_tech_param_ptr->get_Wmemcellr(); - double Wmemcellw = m_tech_param_ptr->get_Wmemcellw(); - uint32_t num_data_end = m_sram_ptr->get_num_data_end(); - uint32_t num_read_port = m_sram_ptr->get_num_read_port(); - uint32_t num_write_port = m_sram_ptr->get_num_write_port(); - - const TechParameter* tp = m_tech_param_ptr; - - double total_cap = 0; - // part 1: drain capacitance of pass transistors - total_cap += tp->calc_draincap(Wmemcellr, TechParameter::NCH, 1)*num_read_port*num_data_end/2.0; - total_cap += tp->calc_draincap(Wmemcellw, TechParameter::NCH, 1)*num_write_port; - - // has coefficient (1/2 * 2) - // part 2: drain capacitance of memory cell - total_cap += tp->calc_draincap(Wmemcella, TechParameter::NCH, 1) + tp->calc_draincap(Wmemcella*Wmemcellbscale, TechParameter::PCH, 1 - ); - - // has coefficient (1/2 * 2) - // part 3: gate capacitance of memory cell - total_cap += tp->calc_gatecap(Wmemcella, 1) + tp->calc_gatecap(Wmemcella*Wmemcellbscale, 1); - - return total_cap; -} - -double MemUnit::calc_i_static() -{ - double Wmemcella = m_tech_param_ptr->get_Wmemcella(); - double Wmemcellbscale = m_tech_param_ptr->get_Wmemcellbscale(); - double Wmemcellr = m_tech_param_ptr->get_Wmemcellr(); - double Wmemcellw = m_tech_param_ptr->get_Wmemcellw(); - uint32_t num_data_end = m_sram_ptr->get_num_data_end(); - uint32_t num_read_port = m_sram_ptr->get_num_read_port(); - uint32_t num_write_port = m_sram_ptr->get_num_write_port(); - - const TechParameter* tp = m_tech_param_ptr; - - double ret = 0; - // memory cell - //FIXME - why - ret += (Wmemcella*tp->get_NMOS_TAB(0) + Wmemcella*Wmemcellbscale*tp->get_PMOS_TAB(0))*2; - // read port pass tx - ret += (Wmemcellr*tp->get_NMOS_TAB(0)*num_data_end*num_read_port); - // write port pass tx - ret += (Wmemcellw*tp->get_NMOS_TAB(0)*2*num_write_port); - - return ret; -} - diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Buffer/OutdrvUnit.hh --- a/src/mem/ruby/network/orion/Buffer/OutdrvUnit.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#ifndef __OUTDRVUNIT_H__ -#define __OUTDRVUNIT_H__ - -#include "mem/ruby/network/orion/Type.hh" - -class SRAM; -class TechParameter; - -class OutdrvUnit -{ - public: - enum OutdrvModel - { - NO_MODEL = 0, - CACHE_OUTDRV, - REG_OUTDRV - }; - - public: - OutdrvUnit( - const string& outdrv_model_str_, - const SRAM* sram_ptr_, - const TechParameter* tech_param_ptr_ - ); - ~OutdrvUnit(); - - public: - double get_e_select() const { return m_e_select; } - double get_e_chg_data() const { return m_e_chg_data; } - double get_e_out_0() const { return m_e_out_0; } - double get_e_out_1() const { return m_e_out_1; } - - private: - void init(); - double calc_select_cap(); - double calc_chgdata_cap(); - double calc_outdata_cap(bool value_); - double calc_i_static(); - - private: - OutdrvModel m_outdrv_model; - const SRAM* m_sram_ptr; - const TechParameter* m_tech_param_ptr; - - double m_e_select; - double m_e_out_1; - double m_e_out_0; - double m_e_chg_data; - - double m_i_static; -}; - -#endif - diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Buffer/OutdrvUnit.cc --- a/src/mem/ruby/network/orion/Buffer/OutdrvUnit.cc Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,176 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#include "base/misc.hh" -#include "mem/ruby/network/orion/Buffer/OutdrvUnit.hh" -#include "mem/ruby/network/orion/Buffer/SRAM.hh" -#include "mem/ruby/network/orion/TechParameter.hh" - -OutdrvUnit::OutdrvUnit( - const string& outdrv_model_str_, - const SRAM* sram_ptr_, - const TechParameter* tech_param_ptr_ - ) -{ - if (outdrv_model_str_ == string("CACHE_OUTDRV")) - { - m_outdrv_model = CACHE_OUTDRV; - } - else if (outdrv_model_str_ == string("REG_OUTDRV")) - { - m_outdrv_model = REG_OUTDRV; - } - else - { - m_outdrv_model = NO_MODEL; - } - - if (m_outdrv_model != NO_MODEL) - { - m_sram_ptr = sram_ptr_; - m_tech_param_ptr = tech_param_ptr_; - init(); - } - else - { - m_e_select = 0; - m_e_out_1 = 0; - m_e_out_0 = 0; - m_e_chg_data = 0; - } -} - -OutdrvUnit::~OutdrvUnit() -{} - -void OutdrvUnit::init() -{ - double e_factor = m_tech_param_ptr->get_EnergyFactor(); - - m_e_select = calc_select_cap() * e_factor; - m_e_out_1 = calc_outdata_cap(1) * e_factor; - m_e_out_0 = calc_outdata_cap(0) * e_factor; - - switch(m_outdrv_model) - { - case CACHE_OUTDRV: - m_e_chg_data = calc_chgdata_cap() * e_factor; - break; - case REG_OUTDRV: - m_e_chg_data = 0; - break; - default: - fatal("Incorrect OUTDRIVE model.\n"); - } - - m_i_static = calc_i_static(); - return; -} - -double OutdrvUnit::calc_select_cap() -{ - double total_cap; - - // stage 1: inverter - double Woutdrvseln = m_tech_param_ptr->get_Woutdrvseln(); - double Woutdrvselp = m_tech_param_ptr->get_Woutdrvselp(); - total_cap = m_tech_param_ptr->calc_gatecap(Woutdrvseln, 1) + m_tech_param_ptr->calc_gatecap(Woutdrvselp, 1) + m_tech_param_ptr->calc_draincap(Woutdrvseln, TechParameter::NCH, 1) + m_tech_param_ptr->calc_draincap(Woutdrvselp, TechParameter::PCH, 1); - - // stage 2: gate cap of nand gate and nor gate - // only consider 1 gate cap because another and drain cap switch depends on data value - uint32_t line_width = m_sram_ptr->get_line_width(); - double Woutdrvnandn = m_tech_param_ptr->get_Woutdrvnandn(); - double Woutdrvnandp = m_tech_param_ptr->get_Woutdrvnandp(); - double Woutdrvnorn = m_tech_param_ptr->get_Woutdrvnorn(); - double Woutdrvnorp = m_tech_param_ptr->get_Woutdrvnorp(); - total_cap += line_width * (m_tech_param_ptr->calc_gatecap(Woutdrvnandn, 1) + m_tech_param_ptr->calc_gatecap(Woutdrvnandp, 1) + m_tech_param_ptr->calc_gatecap(Woutdrvnorn, 1) + m_tech_param_ptr->calc_gatecap(Woutdrvnorp, 1)); - return total_cap; -} - -double OutdrvUnit::calc_chgdata_cap() -{ - double total_cap; - double Woutdrvnandn = m_tech_param_ptr->get_Woutdrvnandn(); - double Woutdrvnandp = m_tech_param_ptr->get_Woutdrvnandp(); - double Woutdrvnorn = m_tech_param_ptr->get_Woutdrvnorn(); - double Woutdrvnorp = m_tech_param_ptr->get_Woutdrvnorp(); - - total_cap = (m_tech_param_ptr->calc_gatecap(Woutdrvnandn, 1) + m_tech_param_ptr->calc_gatecap(Woutdrvnandp, 1) + m_tech_param_ptr->calc_gatecap(Woutdrvnorn, 1) + m_tech_param_ptr->calc_gatecap(Woutdrvnorp, 1)) / 2.0; - return total_cap; -} - -double OutdrvUnit::calc_outdata_cap(bool value_) -{ - double total_cap = 0; - - // stage 1: drain cap of nand gate or nor gate - if (value_) - { - //drain cap of nand gate - double Woutdrvnandn = m_tech_param_ptr->get_Woutdrvnandn(); - double Woutdrvnandp = m_tech_param_ptr->get_Woutdrvnandp(); - total_cap = m_tech_param_ptr->calc_draincap(Woutdrvnandn, TechParameter::NCH, 2) + 2 * m_tech_param_ptr->calc_draincap(Woutdrvnandp, TechParameter::PCH, 1); - } - else - { - //drain cap of nor gate - double Woutdrvnorn = m_tech_param_ptr->get_Woutdrvnorn(); - double Woutdrvnorp = m_tech_param_ptr->get_Woutdrvnorp(); - total_cap = 2 * m_tech_param_ptr->calc_draincap(Woutdrvnorn, TechParameter::NCH, 1) + m_tech_param_ptr->calc_draincap(Woutdrvnorp, TechParameter::PCH, 2); - } - - // stage 2: gate cap of output inverter - if (value_) - { - double Woutdriverp = m_tech_param_ptr->get_Woutdriverp(); - total_cap += m_tech_param_ptr->calc_gatecap(Woutdriverp, 1); - } - else - { - double Woutdrivern = m_tech_param_ptr->get_Woutdrivern(); - total_cap += m_tech_param_ptr->calc_gatecap(Woutdrivern, 1); - } - - //drian cap of output inverter should be included into bus cap - //TODO - return total_cap; -} - -double OutdrvUnit::calc_i_static() -{ - //FIXME - add static power - return 0; -} - diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Buffer/PrechargeUnit.hh --- a/src/mem/ruby/network/orion/Buffer/PrechargeUnit.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#ifndef __PRECHARGEUNIT_H__ -#define __PRECHARGEUNIT_H__ - -#include "mem/ruby/network/orion/Type.hh" - -class SRAM; -class TechParameter; - -class PrechargeUnit -{ - public: - enum PrechargeModel - { - NO_MODEL = 0, - SINGLE_BITLINE, - EQU_BITLINE, - SINGLE_OTHER - }; - - public: - PrechargeUnit( - const string& pre_model_str_, - double pre_load_, - const SRAM* sram_ptr_, - const TechParameter* tech_param_ptr_ - ); - ~PrechargeUnit(); - - public: - double get_e_charge_gate() const { return m_e_charge_gate; } - double get_e_charge_drain() const { return m_e_charge_drain; } - double get_i_static() const { return m_i_static; } - - private: - void init(); - uint32_t calc_num_pre_gate(); - uint32_t calc_num_pre_drain(); - double calc_pre_cap(double width_, double length_); - - private: - PrechargeModel m_pre_model; - double m_pre_load; - const SRAM* m_sram_ptr; - const TechParameter* m_tech_param_ptr; - - double m_pre_size; - - double m_e_charge_gate; - double m_e_charge_drain; - - double m_i_static; -}; - -#endif - diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Buffer/PrechargeUnit.cc --- a/src/mem/ruby/network/orion/Buffer/PrechargeUnit.cc Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#include "base/misc.hh" -#include "mem/ruby/network/orion/Buffer/PrechargeUnit.hh" -#include "mem/ruby/network/orion/Buffer/SRAM.hh" -#include "mem/ruby/network/orion/TechParameter.hh" - -PrechargeUnit::PrechargeUnit( - const string& pre_model_str_, - double pre_load_, - const SRAM* sram_ptr_, - const TechParameter* tech_param_ptr_ - ) -{ - if (pre_model_str_ == "SINGLE_BITLINE") - { - m_pre_model = SINGLE_BITLINE; - } - else if (pre_model_str_ == "EQU_BITLINE") - { - m_pre_model = EQU_BITLINE; - } - else if (pre_model_str_ == "SINGLE_OTHER") - { - m_pre_model = SINGLE_OTHER; - } - else - { - m_pre_model = NO_MODEL; - } - - if (m_pre_model != NO_MODEL) - { - m_pre_load = pre_load_; - m_sram_ptr = sram_ptr_; - m_tech_param_ptr = tech_param_ptr_; - - init(); - } -} - -PrechargeUnit::~PrechargeUnit() -{ -} - -void PrechargeUnit::init() -{ - double period = m_tech_param_ptr->get_period(); - m_pre_size = m_tech_param_ptr->calc_driver_psize(m_pre_load, period/8.0); - //FIXME - shouldn't be added - double Wdecinvn = m_tech_param_ptr->get_Wdecinvn(); - double Wdecinvp = m_tech_param_ptr->get_Wdecinvp(); - m_pre_size += m_pre_size*Wdecinvn/Wdecinvp; - - uint32_t num_gate = calc_num_pre_gate(); - - // WHS: 10 should go to PARM - double e_factor = m_tech_param_ptr->get_EnergyFactor(); - m_e_charge_gate = calc_pre_cap(m_pre_size, 10) * num_gate * e_factor; - - uint32_t num_data_end = m_sram_ptr->get_num_data_end(); - if (num_data_end == 2) - { - e_factor = m_tech_param_ptr->get_SenseEnergyFactor(); - } - else - { - e_factor = m_tech_param_ptr->get_EnergyFactor(); - } - uint32_t num_drain = calc_num_pre_drain(); - m_e_charge_drain = m_tech_param_ptr->calc_draincap(m_pre_size, TechParameter::PCH, 1)*num_drain*e_factor; - - // static power - double PMOS_TAB_0 = m_tech_param_ptr->get_PMOS_TAB(0); - m_i_static = num_gate*m_pre_size*PMOS_TAB_0; -} - -uint32_t PrechargeUnit::calc_num_pre_gate() -{ - switch(m_pre_model) - { - case SINGLE_BITLINE: return 2; - case EQU_BITLINE: return 3; - case SINGLE_OTHER: return 1; - default: fatal("Incorrect Precharge Unit model.\n"); - } -} - -uint32_t PrechargeUnit::calc_num_pre_drain() -{ - switch(m_pre_model) - { - case SINGLE_BITLINE: return 1; - case EQU_BITLINE: return 2; - case SINGLE_OTHER: return 1; - default: fatal("Incorrect Precharge Unit model.\n"); - } -} - -double PrechargeUnit::calc_pre_cap(double width_, double length_) -{ - return m_tech_param_ptr->calc_gatecap(width_, length_); -} - diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Buffer/Register.hh --- a/src/mem/ruby/network/orion/Buffer/Register.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#ifndef __REGISTER_H__ -#define __REGISTER_H__ - -#include "mem/ruby/network/orion/Type.hh" - -class TechParameter; -class FlipFlop; - -class Register -{ - public: - Register( - uint32_t num_entry_, - uint32_t line_width_, - const TechParameter* tech_param_ptr_ - ); - ~Register(); - - public: - double calc_e_read() const; - double calc_e_write() const; - double calc_i_static() const; - - private: - void init(); - - private: - uint32_t m_num_entry; - uint32_t m_line_width; - const TechParameter* m_tech_param_ptr; - - FlipFlop* m_ff_ptr; - - double m_avg_read; - double m_avg_write; -}; - -#endif diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Buffer/Register.cc --- a/src/mem/ruby/network/orion/Buffer/Register.cc Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#include -#include - -#include "mem/ruby/network/orion/Buffer/Register.hh" -#include "mem/ruby/network/orion/FlipFlop.hh" -#include "mem/ruby/network/orion/TechParameter.hh" - -using namespace std; - -Register::Register( - uint32_t num_entry_, - uint32_t line_width_, - const TechParameter *tech_param_ptr_ - ) -{ - assert(num_entry_ == num_entry_); - assert(line_width_ == line_width_); - - m_num_entry = num_entry_; - m_line_width = line_width_; - m_tech_param_ptr = tech_param_ptr_; - - init(); -} - -Register::~Register() -{ - delete m_ff_ptr; -} - -double Register::calc_e_read() const -{ - // average read energy for one buffer entry - double e_read = 0; - - - // for each read operation, the energy consists of one read operation and n write - // operateion. n means there is n flits in the buffer before read operation. - // assume n is info->n_entry * 0.25. - // - if (m_num_entry > 1) - { - e_read = (m_avg_read + m_num_entry*0.25*m_avg_write); - } - else - { - e_read = m_avg_read; - } - return e_read; -} - -double Register::calc_e_write() const -{ - // average write energy for one buffer entry - double e_write = 0; - - e_write = m_avg_write; - return e_write; -} - -double Register::calc_i_static() const -{ - double i_static = m_ff_ptr->get_i_static()*m_line_width*m_num_entry; - - return i_static; -} - -void Register::init() -{ - m_ff_ptr = new FlipFlop("NEG_DFF", 0, m_tech_param_ptr); - - uint32_t num_clock = m_line_width; - m_avg_read = m_ff_ptr->get_e_clock()*((double)num_clock)/2.0; - - double num_switch = m_line_width/2.0; - m_avg_write = m_ff_ptr->get_e_switch()*num_switch+m_ff_ptr->get_e_clock()*num_clock; - return; -} diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Buffer/SConscript --- a/src/mem/ruby/network/orion/Buffer/SConscript Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -# Copyright (c) 2010 Massachusetts Institute of Technology -# 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. -# -# Authors: Tushar Krishna - -Import('*') - -if env['PROTOCOL'] == 'None': - Return() - -Source('AmpUnit.cc') -Source('BitlineUnit.cc') -Source('Buffer.cc') -Source('DecoderUnit.cc') -Source('MemUnit.cc') -Source('OutdrvUnit.cc') -Source('PrechargeUnit.cc') -Source('Register.cc') -Source('SRAM.cc') -Source('WordlineUnit.cc') diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Buffer/SRAM.hh --- a/src/mem/ruby/network/orion/Buffer/SRAM.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#ifndef __SRAM_H__ -#define __SRAM_H__ - -#include "mem/ruby/network/orion/OrionConfig.hh" -#include "mem/ruby/network/orion/TechParameter.hh" -#include "mem/ruby/network/orion/Type.hh" - -class OutdrvUnit; -class AmpUnit; -class BitlineUnit; -class MemUnit; -class PrechargeUnit; -class WordlineUnit; -class DecoderUnit; - -class SRAM -{ - public: - SRAM( - uint32_t num_entry_, - uint32_t line_width_, - bool is_fifo_, - bool is_outdrv_, - uint32_t num_read_port_, - uint32_t num_write_port_, - uint32_t num_data_end_, - const string& rowdec_model_str_, - const string& wl_model_str_, - const string& bl_pre_model_str_, - const string& mem_model_str_, - const string& bl_model_str_, - const string& amp_model_str_, - const string& outdrv_model_str_, - const TechParameter* tech_param_ptr_ - ); - ~SRAM(); - - public: - uint32_t get_line_width() const { return m_line_width; } - uint32_t get_num_data_end() const { return m_num_data_end; } - uint32_t get_num_read_port() const { return m_num_read_port; } - uint32_t get_num_write_port() const { return m_num_write_port; } - uint32_t get_num_port() const { return (m_num_read_port+m_num_write_port); } - bool get_is_outdrv() const { return m_is_outdrv; } - uint32_t get_num_row() const { return m_num_entry; } - uint32_t get_num_col() const { return m_line_width; } - - double calc_e_read(bool is_max_) const; - double calc_e_write(bool is_max_) const; - double calc_i_static() const; - - private: - void init(); - - private: - uint32_t m_num_entry; - uint32_t m_line_width; - bool m_is_fifo; - bool m_is_outdrv; - string m_rowdec_model_str; - string m_wl_model_str; - string m_bl_pre_model_str; - string m_mem_model_str; - string m_bl_model_str; - string m_amp_model_str; - string m_outdrv_model_str; - const TechParameter* m_tech_param_ptr; - - OutdrvUnit* m_outdrv_unit_ptr; - AmpUnit* m_amp_unit_ptr; - BitlineUnit* m_bl_unit_ptr; - MemUnit* m_mem_unit_ptr; - PrechargeUnit* m_bl_pre_unit_ptr; - WordlineUnit* m_wl_unit_ptr; - DecoderUnit* m_rowdec_unit_ptr; - - uint32_t m_num_read_port; - uint32_t m_num_write_port; - uint32_t m_num_data_end; - - uint32_t m_rowdec_width; -}; - -#endif - diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Buffer/SRAM.cc --- a/src/mem/ruby/network/orion/Buffer/SRAM.cc Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,271 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#include -#include -#include - -#include "mem/ruby/network/orion/Buffer/AmpUnit.hh" -#include "mem/ruby/network/orion/Buffer/BitlineUnit.hh" -#include "mem/ruby/network/orion/Buffer/DecoderUnit.hh" -#include "mem/ruby/network/orion/Buffer/MemUnit.hh" -#include "mem/ruby/network/orion/Buffer/OutdrvUnit.hh" -#include "mem/ruby/network/orion/Buffer/PrechargeUnit.hh" -#include "mem/ruby/network/orion/Buffer/SRAM.hh" -#include "mem/ruby/network/orion/Buffer/WordlineUnit.hh" - -using namespace std; - -SRAM::SRAM( - uint32_t num_entry_, - uint32_t line_width_, - bool is_fifo_, - bool is_outdrv_, - uint32_t num_read_port_, - uint32_t num_write_port_, - uint32_t num_data_end_, - const string& rowdec_model_str_, - const string& wl_model_str_, - const string& bl_pre_model_str_, - const string& mem_model_str_, - const string& bl_model_str_, - const string& amp_model_str_, - const string& outdrv_model_str_, - const TechParameter* tech_param_ptr_ - ) -{ - assert(num_entry_ == num_entry_); - assert(line_width_ == line_width_); - assert(num_read_port_ == num_read_port_); - assert(num_write_port_ == num_write_port_); - assert(num_data_end_ == num_data_end_); - - m_num_entry = num_entry_; - m_line_width = line_width_; - m_is_fifo = is_fifo_; - m_is_outdrv = is_outdrv_; - - m_num_read_port = num_read_port_; - m_num_write_port = num_write_port_; - m_num_data_end = num_data_end_; - - m_rowdec_model_str = rowdec_model_str_; - m_wl_model_str = wl_model_str_; - m_bl_pre_model_str = bl_pre_model_str_; - m_mem_model_str = mem_model_str_; - m_bl_model_str = bl_model_str_; - m_amp_model_str = amp_model_str_; - m_outdrv_model_str = outdrv_model_str_; - m_tech_param_ptr = tech_param_ptr_; - - init(); -} - -SRAM::~SRAM() -{ - delete m_outdrv_unit_ptr; - delete m_amp_unit_ptr; - delete m_bl_unit_ptr; - delete m_mem_unit_ptr; - delete m_bl_pre_unit_ptr; - delete m_wl_unit_ptr; - delete m_rowdec_unit_ptr; -} - -double SRAM::calc_e_read( - bool is_max_ - ) const -{ - double e_atomic; - double e_read = 0; - - // decoder - if (m_rowdec_unit_ptr != NULL) - { - e_atomic = m_rowdec_unit_ptr->get_e_chg_addr()*m_rowdec_unit_ptr->get_dec_width()*(is_max_? 1:0.5); - e_atomic += m_rowdec_unit_ptr->get_e_chg_output(); - // assume all 1st-level decoders change output - e_atomic += m_rowdec_unit_ptr->get_e_chg_l1()*m_rowdec_unit_ptr->get_num_in_2nd(); - e_read += e_atomic; - } - - //wordline - e_atomic = m_wl_unit_ptr->get_e_read(); - e_read += e_atomic; - - //bitline pre - e_atomic = m_bl_pre_unit_ptr->get_e_charge_gate()*m_line_width; - if (m_num_data_end == 2) - { - e_atomic += m_bl_pre_unit_ptr->get_e_charge_drain()*m_line_width; - } - else - { - e_atomic += m_bl_pre_unit_ptr->get_e_charge_drain()*m_line_width*(is_max_? 1:0.5); - } - e_read += e_atomic; - - //bitline - if (m_num_data_end == 2) - { - e_atomic = m_bl_unit_ptr->get_e_col_read()*m_line_width; - } - else - { - e_atomic = m_bl_unit_ptr->get_e_col_read()*m_line_width*(is_max_? 1:0.5); - } - e_read += e_atomic; - - if (m_num_data_end == 2) - { - e_atomic = m_amp_unit_ptr->get_e_access()*m_line_width; - e_read += e_atomic; - } - - if (m_outdrv_unit_ptr != NULL) - { - e_atomic = m_outdrv_unit_ptr->get_e_select(); - - e_atomic += m_outdrv_unit_ptr->get_e_chg_data()*m_line_width*(is_max_? 1:0.5); - - //assume 1 and 0 are uniformly distributed - if ((m_outdrv_unit_ptr->get_e_out_1() >= m_outdrv_unit_ptr->get_e_out_0()) || (!is_max_)) - { - e_atomic += m_outdrv_unit_ptr->get_e_out_1()*m_line_width*(is_max_? 1:0.5); - } - if ((m_outdrv_unit_ptr->get_e_out_1() < m_outdrv_unit_ptr->get_e_out_0()) || (!is_max_)) - { - e_atomic += m_outdrv_unit_ptr->get_e_out_0()*m_line_width*(is_max_? 1:0.5); - } - - e_read += e_atomic; - } - - return e_read; -} - -double SRAM::calc_e_write( - bool is_max_ - ) const -{ - double e_atomic; - double e_write = 0; - - // decoder - if (m_rowdec_unit_ptr != NULL) - { - e_atomic = m_rowdec_unit_ptr->get_e_chg_addr()*m_rowdec_unit_ptr->get_dec_width()*(is_max_? 1:0.5); - e_atomic += m_rowdec_unit_ptr->get_e_chg_output(); - // assume all 1st-level decoders change output - e_atomic += m_rowdec_unit_ptr->get_e_chg_l1()*m_rowdec_unit_ptr->get_num_in_2nd(); - e_write += e_atomic; - } - - //wordline - e_atomic = m_wl_unit_ptr->get_e_write(); - e_write += e_atomic; - - //bitline - e_atomic = m_bl_unit_ptr->get_e_col_wrtie()*m_line_width*(is_max_? 1:0.5); - e_write += e_atomic; - - //mem cell - e_atomic = m_mem_unit_ptr->get_e_switch()*m_line_width*(is_max_? 1:0.5); - e_write += e_atomic; - - return e_write; -} - -double SRAM::calc_i_static() const -{ - double i_static = 0; - - i_static += m_bl_unit_ptr->get_i_static()*m_line_width*m_num_write_port; - i_static += m_mem_unit_ptr->get_i_static()*m_num_entry*m_line_width; - i_static += m_bl_pre_unit_ptr->get_i_static()*m_line_width*m_num_read_port; - i_static += m_wl_unit_ptr->get_i_static()*m_num_entry*(m_num_read_port+m_num_write_port); - - return i_static; -} - -void SRAM::init() -{ - // output driver unit - if (m_is_outdrv) - { - m_outdrv_unit_ptr = new OutdrvUnit(m_outdrv_model_str, this, m_tech_param_ptr); - } - else - { - m_outdrv_unit_ptr = NULL; - } - - // sense amplifier unit - if (m_num_data_end == 2) - { - m_amp_unit_ptr = new AmpUnit(m_amp_model_str, m_tech_param_ptr); - } - else - { - m_amp_unit_ptr = NULL; - } - - // bitline unit - m_bl_unit_ptr = new BitlineUnit(m_bl_model_str, this, m_tech_param_ptr); - - // mem unit - m_mem_unit_ptr = new MemUnit(m_mem_model_str, this, m_tech_param_ptr); - - // precharge unit - double bl_pre_unit_load = m_bl_unit_ptr->get_pre_unit_load(); - m_bl_pre_unit_ptr = new PrechargeUnit(m_bl_pre_model_str, bl_pre_unit_load, this, m_tech_param_ptr); - - // wordline unit - m_wl_unit_ptr = new WordlineUnit(m_wl_model_str, this, m_tech_param_ptr); - - // decode unit - if (!m_is_fifo) - { - m_rowdec_width = (uint32_t)log2((double)m_num_entry); - m_rowdec_unit_ptr = new DecoderUnit(m_rowdec_model_str, m_rowdec_width, m_tech_param_ptr); - } - else - { - m_rowdec_unit_ptr = NULL; - } - return; -} - - diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Buffer/WordlineUnit.hh --- a/src/mem/ruby/network/orion/Buffer/WordlineUnit.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#ifndef __WORDLINEUNIT_H__ -#define __WORDLINEUNIT_H__ - -#include "mem/ruby/network/orion/Type.hh" - -class SRAM; -class TechParameter; - -class WordlineUnit -{ - public: - enum WordlineModel - { - NO_MODEL = 0, - RW_WORDLINE, - WO_WORDLINE - }; - - public: - WordlineUnit( - const string& wl_model_str_, - const SRAM* sram_ptr_, - const TechParameter* tech_param_ptr_ - ); - ~WordlineUnit(); - - public: - double get_e_read() const { return m_e_read; } - double get_e_write() const { return m_e_write; } - double get_i_static() const { return m_i_static; } - - private: - void init(); - double calc_wordline_cap(uint32_t num_mos_, double mos_width_) const; - double calc_i_static(); - - private: - WordlineModel m_wl_model; - const SRAM* m_sram_ptr; - const TechParameter* m_tech_param_ptr; - - double m_wl_len; - double m_wl_wire_cap; - - double m_e_read; - double m_e_write; - - double m_i_static; -}; - -#endif - diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Buffer/WordlineUnit.cc --- a/src/mem/ruby/network/orion/Buffer/WordlineUnit.cc Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#include "base/misc.hh" -#include "mem/ruby/network/orion/Buffer/SRAM.hh" -#include "mem/ruby/network/orion/Buffer/WordlineUnit.hh" -#include "mem/ruby/network/orion/TechParameter.hh" - -WordlineUnit::WordlineUnit( - const string& wl_model_str_, - const SRAM* sram_ptr_, - const TechParameter* tech_param_ptr_ - ) -{ - if (wl_model_str_ == string("RW_WORDLINE")) - { - m_wl_model = RW_WORDLINE; - } - else if (wl_model_str_ == string("WO_WORDLINE")) - { - m_wl_model = WO_WORDLINE; - } - else - { - m_wl_model = NO_MODEL; - } - - if (m_wl_model != NO_MODEL) - { - m_sram_ptr = sram_ptr_; - m_tech_param_ptr = tech_param_ptr_; - - init(); - } -} - -WordlineUnit::~WordlineUnit() -{} - -void WordlineUnit::init() -{ - uint32_t num_port = m_sram_ptr->get_num_port(); - uint32_t num_read_port = m_sram_ptr->get_num_read_port(); - uint32_t num_col = m_sram_ptr->get_num_col(); - uint32_t num_data_end = m_sram_ptr->get_num_data_end(); - double RegCellWidth = m_tech_param_ptr->get_RegCellWidth(); - double BitlineSpacing = m_tech_param_ptr->get_BitlineSpacing(); - - if (num_data_end == 2) - { - m_wl_len = num_col*(RegCellWidth + 2*num_port*BitlineSpacing); - } - else - { - m_wl_len = num_col*(RegCellWidth + (2*num_port-num_read_port)*BitlineSpacing); - } - - double wl_cmetal; - if (num_port > 1) - { - wl_cmetal = m_tech_param_ptr->get_CC3M3metal(); - } - else - { - wl_cmetal = m_tech_param_ptr->get_CM3metal(); - } - - m_wl_wire_cap = m_wl_len*wl_cmetal; - - double e_factor = m_tech_param_ptr->get_EnergyFactor(); - double Wmemcellr = m_tech_param_ptr->get_Wmemcellr(); - double Wmemcellw = m_tech_param_ptr->get_Wmemcellw(); - double Woutdrivern = m_tech_param_ptr->get_Woutdrivern(); - double Woutdriverp = m_tech_param_ptr->get_Woutdriverp(); - double NMOS_TAB_0 = m_tech_param_ptr->get_NMOS_TAB(0); - double PMOS_TAB_0 = m_tech_param_ptr->get_PMOS_TAB(0); - switch(m_wl_model) - { - case RW_WORDLINE: - m_e_read = calc_wordline_cap(num_col*num_data_end, Wmemcellr) * e_factor; - m_e_write = calc_wordline_cap(num_col*2, Wmemcellw) * e_factor; - m_i_static = (Woutdrivern*NMOS_TAB_0 + Woutdriverp*PMOS_TAB_0); - break; - case WO_WORDLINE: - m_e_read = 0; - m_e_write = calc_wordline_cap(num_col*2, Wmemcellw)*e_factor; - m_i_static = 0; - break; - default: - fatal("Incorrect Wordline model.\n"); - } - return; -} - -double WordlineUnit::calc_wordline_cap( - uint32_t num_mos_, - double mos_width_ - ) const -{ - double total_cap; - - // part 1: line cap, including gate cap of pass tx's and metal cap - double BitWidth = m_tech_param_ptr->get_BitWidth(); - total_cap = m_tech_param_ptr->calc_gatecappass(mos_width_, BitWidth/2.0-mos_width_)*num_mos_ + m_wl_wire_cap; - - // part 2: input driver - double period = m_tech_param_ptr->get_period(); - double psize, nsize; - psize = m_tech_param_ptr->calc_driver_psize(total_cap, period/16.0); - double Wdecinvn = m_tech_param_ptr->get_Wdecinvn(); - double Wdecinvp = m_tech_param_ptr->get_Wdecinvp(); - nsize = psize*Wdecinvn/Wdecinvp; - - // WHS: 20 should go to PARM - total_cap += m_tech_param_ptr->calc_draincap(nsize, TechParameter::NCH, 1) + m_tech_param_ptr->calc_draincap(psize, TechParameter::PCH, 1) + m_tech_param_ptr->calc_gatecap(psize+nsize, 20); - - return total_cap; -} - diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Clock.hh --- a/src/mem/ruby/network/orion/Clock.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#ifndef __CLOCK_H__ -#define __CLOCK_H__ - -#include "mem/ruby/network/orion/Type.hh" - -class TechParameter; -class OrionConfig; - -class Clock -{ - public: - Clock( - bool is_in_buf_, - bool is_in_shared_switch_, - bool is_out_buf_, - bool is_out_shared_switch_, - const OrionConfig* orion_cfg_ptr_ - ); - ~Clock(); - - public: - double get_dynamic_energy() const; - double get_static_power() const; - - private: - void init(); - double calc_cap_pipe_reg(); - - private: - bool m_is_in_buf; - bool m_is_in_shared_switch; - bool m_is_out_buf; - bool m_is_out_shared_switch; - const OrionConfig* m_orion_cfg_ptr; - const TechParameter* m_tech_param_ptr; - - double m_e_pipe_reg; - double m_e_htree; - double m_i_static; -}; - -#endif diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Clock.cc --- a/src/mem/ruby/network/orion/Clock.cc Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,176 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#include "mem/ruby/network/orion/Clock.hh" -#include "mem/ruby/network/orion/OrionConfig.hh" -#include "mem/ruby/network/orion/TechParameter.hh" -#include "mem/ruby/network/orion/Wire.hh" - -Clock::Clock( - bool is_in_buf_, - bool is_in_shared_switch_, - bool is_out_buf_, - bool is_out_shared_switch_, - const OrionConfig* orion_cfg_ptr_ - ) -{ - m_is_in_buf = is_in_buf_; - m_is_in_shared_switch = is_in_shared_switch_; - m_is_out_buf = is_out_buf_; - m_is_out_shared_switch = is_out_shared_switch_; - m_orion_cfg_ptr = orion_cfg_ptr_; - - init(); -} - -Clock::~Clock() -{} - -double Clock::get_dynamic_energy() const -{ - return (m_e_pipe_reg + m_e_htree); -} - -double Clock::get_static_power() const -{ - double vdd = m_tech_param_ptr->get_vdd(); - return (m_i_static*vdd); -} - -void Clock::init() -{ - m_tech_param_ptr = m_orion_cfg_ptr->get_tech_param_ptr(); - - double e_factor = m_tech_param_ptr->get_EnergyFactor(); - - // Pipeline registers capacitive load on clock network - uint32_t num_in_port = m_orion_cfg_ptr->get_num_in_port(); - uint32_t num_out_port = m_orion_cfg_ptr->get_num_out_port(); - uint32_t num_vclass = m_orion_cfg_ptr->get_num_vclass(); - uint32_t num_vchannel = m_orion_cfg_ptr->get_num_vchannel(); - uint32_t flit_width = m_orion_cfg_ptr->get_flit_width(); - - uint32_t num_pipe_reg = 0; - - // pipeline registers after the link traversal stage - num_pipe_reg += num_in_port*flit_width; - - // pipeline registers for input buffer - if (m_is_in_buf) - { - if (m_is_in_shared_switch) - { - num_pipe_reg += num_in_port*flit_width; - } - else - { - num_pipe_reg += num_in_port*num_vclass*num_vchannel*flit_width; - } - } - - // pipeline registers for crossbar - if (m_is_out_shared_switch) - { - num_pipe_reg += num_out_port*flit_width; - } - else - { - num_pipe_reg += num_out_port*num_vclass*num_vchannel*flit_width; - } - - // pipeline registers for output buffer - if (m_is_out_buf) // assume output buffers share links - { - num_pipe_reg += num_out_port*flit_width; - } - - double cap_clock = m_tech_param_ptr->get_ClockCap(); - m_e_pipe_reg = num_pipe_reg*cap_clock*e_factor; - - //========================H_tree wiring load ========================*/ - // The 1e-6 factor is to convert the "router_diagonal" back to meters. - // To be consistent we use micro-meters unit for our inputs, but - // the functions, internally, use meters. */ - - double i_static_nmos = 0; - double i_static_pmos = 0; - - bool is_htree = m_orion_cfg_ptr->get("IS_HTREE_CLOCK"); - if(is_htree) - { - const string& width_spacing_model_str = m_orion_cfg_ptr->get("WIRE_WIDTH_SPACING"); - const string& buf_scheme_str = m_orion_cfg_ptr->get("WIRE_BUFFERING_MODEL"); - bool is_shielding = m_orion_cfg_ptr->get("WIRE_IS_SHIELDING"); - Wire wire(width_spacing_model_str, buf_scheme_str, is_shielding, m_tech_param_ptr); - - double router_diagonal = m_orion_cfg_ptr->get("ROUTER_DIAGONAL"); - double Clockwire = m_tech_param_ptr->get_ClockCap(); - - double htree_clockcap; - int k; - double h; - - double BufferNMOSOffCurrent = m_tech_param_ptr->get_BufferNMOSOffCurrent(); - double BufferPMOSOffCurrent = m_tech_param_ptr->get_BufferPMOSOffCurrent(); - - if (m_tech_param_ptr->is_trans_type_hvt() || m_tech_param_ptr->is_trans_type_nvt()) - { - htree_clockcap = (4+4+2+2)*(router_diagonal*1e-6)*Clockwire; - - wire.calc_opt_buffering(&k, &h, ((4+4+2+2)*router_diagonal*1e-6)); - i_static_nmos = BufferNMOSOffCurrent*h*k*15; - i_static_pmos = BufferPMOSOffCurrent*h*k*15; - } - else - { - htree_clockcap = (8+4+4+4+4)*(router_diagonal*1e-6)*Clockwire; - - wire.calc_opt_buffering(&k, &h, ((4+4+2+2)*router_diagonal*1e-6)); - i_static_nmos = BufferNMOSOffCurrent*h*k*29; - i_static_pmos = BufferPMOSOffCurrent*h*k*15; - } - - m_e_htree = (htree_clockcap+cap_clock)*e_factor; - } - else - { - m_e_htree = 0; - } - - double SCALE_S = m_tech_param_ptr->get_SCALE_S(); - double DFF_TAB_0 = m_tech_param_ptr->get_DFF_TAB(0); - double Wdff = m_tech_param_ptr->get_Wdff(); - m_i_static = (((i_static_nmos+i_static_pmos)/2)/SCALE_S + (num_pipe_reg*DFF_TAB_0*Wdff)); -} diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/ConfigFile.hh --- a/src/mem/ruby/network/orion/ConfigFile.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,252 +0,0 @@ -// Class for reading named values from configuration files -// Richard J. Wagner v2.1 24 May 2004 wagnerr@umich.edu - -// Copyright (c) 2004 Richard J. Wagner -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. - -// Typical usage -// ------------- -// -// Given a configuration file "settings.inp": -// atoms = 25 -// length = 8.0 # nanometers -// name = Reece Surcher -// -// Named values are read in various ways, with or without default values: -// ConfigFile config( "settings.inp" ); -// int atoms = config.read( "atoms" ); -// double length = config.read( "length", 10.0 ); -// string author, title; -// config.readInto( author, "name" ); -// config.readInto( title, "title", string("Untitled") ); -// -// See file example.cpp for more examples. - -#ifndef CONFIGFILE_H -#define CONFIGFILE_H - -#include -#include -#include -#include -#include - -using std::string; - -class ConfigFile { - // Data - protected: - string myDelimiter; // separator between key and value - string myComment; // separator between value and comments - string mySentry; // optional string to signal end of file - std::map myContents; // extracted keys and values - - typedef std::map::iterator mapi; - typedef std::map::const_iterator mapci; - - // Methods - public: - ConfigFile( string filename, - string delimiter = "=", - string comment = "#", - string sentry = "EndConfigFile" ); - ConfigFile(); - - // Search for key and read value or optional default value - template T read( const string& key ) const; // call as read - template T read( const string& key, const T& value ) const; - template bool readInto( T& var, const string& key ) const; - template - bool readInto( T& var, const string& key, const T& value ) const; - - // Modify keys and values - template void add( string key, const T& value ); - void remove( const string& key ); - - // Check whether key exists in configuration - bool keyExists( const string& key ) const; - - // Check or change configuration syntax - string getDelimiter() const { return myDelimiter; } - string getComment() const { return myComment; } - string getSentry() const { return mySentry; } - string setDelimiter( const string& s ) - { string old = myDelimiter; myDelimiter = s; return old; } - string setComment( const string& s ) - { string old = myComment; myComment = s; return old; } - - // Write or read configuration - friend std::ostream& operator<<( std::ostream& os, const ConfigFile& cf ); - friend std::istream& operator>>( std::istream& is, ConfigFile& cf ); - - protected: - template static string T_as_string( const T& t ); - template static T string_as_T( const string& s ); - static void trim( string& s ); - - - // Exception types - public: - struct file_not_found { - string filename; - file_not_found( const string& filename_ = string() ) - : filename(filename_) {} }; - struct key_not_found { // thrown only by T read(key) variant of read() - string key; - key_not_found( const string& key_ = string() ) - : key(key_) {} }; -}; - - -/* static */ -template -string ConfigFile::T_as_string( const T& t ) -{ - // Convert from a T to a string - // Type T must support << operator - std::ostringstream ost; - ost << t; - return ost.str(); -} - - -/* static */ -template -T ConfigFile::string_as_T( const string& s ) -{ - // Convert from a string to a T - // Type T must support >> operator - T t; - std::istringstream ist(s); - ist >> t; - return t; -} - - -/* static */ -template<> -inline string ConfigFile::string_as_T( const string& s ) -{ - // Convert from a string to a string - // In other words, do nothing - return s; -} - - -/* static */ -template<> -inline bool ConfigFile::string_as_T( const string& s ) -{ - // Convert from a string to a bool - // Interpret "false", "F", "no", "n", "0" as false - // Interpret "true", "T", "yes", "y", "1", "-1", or anything else as true - bool b = true; - string sup = s; - for( string::iterator p = sup.begin(); p != sup.end(); ++p ) - *p = toupper(*p); // make string all caps - if( sup==string("FALSE") || sup==string("F") || - sup==string("NO") || sup==string("N") || - sup==string("0") || sup==string("NONE") ) - b = false; - return b; -} - - -template -T ConfigFile::read( const string& key ) const -{ - // Read the value corresponding to key - mapci p = myContents.find(key); - if( p == myContents.end() ) throw key_not_found(key); - return string_as_T( p->second ); -} - - -template -T ConfigFile::read( const string& key, const T& value ) const -{ - // Return the value corresponding to key or given default value - // if key is not found - mapci p = myContents.find(key); - if( p == myContents.end() ) return value; - return string_as_T( p->second ); -} - - -template -bool ConfigFile::readInto( T& var, const string& key ) const -{ - // Get the value corresponding to key and store in var - // Return true if key is found - // Otherwise leave var untouched - mapci p = myContents.find(key); - bool found = ( p != myContents.end() ); - if( found ) var = string_as_T( p->second ); - return found; -} - - -template -bool ConfigFile::readInto( T& var, const string& key, const T& value ) const -{ - // Get the value corresponding to key and store in var - // Return true if key is found - // Otherwise set var to given default - mapci p = myContents.find(key); - bool found = ( p != myContents.end() ); - if( found ) - var = string_as_T( p->second ); - else - var = value; - return found; -} - - -template -void ConfigFile::add( string key, const T& value ) -{ - // Add a key with given value - string v = T_as_string( value ); - trim(key); - trim(v); - myContents[key] = v; - return; -} - -#endif // CONFIGFILE_H - -// Release notes: -// v1.0 21 May 1999 -// + First release -// + Template read() access only through non-member readConfigFile() -// + ConfigurationFileBool is only built-in helper class -// -// v2.0 3 May 2002 -// + Shortened name from ConfigurationFile to ConfigFile -// + Implemented template member functions -// + Changed default comment separator from % to # -// + Enabled reading of multiple-line values -// -// v2.1 24 May 2004 -// + Made template specializations inline to avoid compiler-dependent linkage -// + Allowed comments within multiple-line values -// + Enabled blank line termination for multiple-line values -// + Added optional sentry to detect end of configuration file -// + Rewrote messy trimWhitespace() function as elegant trim() diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/ConfigFile.cc --- a/src/mem/ruby/network/orion/ConfigFile.cc Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,170 +0,0 @@ -/* - * Copyright (c) 2010 Massachusetts Institute of Technology - * 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. - * - * Authors: Chia-Hsin Owen Chen - */ - -#include "mem/ruby/network/orion/ConfigFile.hh" - -using std::string; - -ConfigFile::ConfigFile( string filename, string delimiter, - string comment, string sentry ) - : myDelimiter(delimiter), myComment(comment), mySentry(sentry) -{ - // Construct a ConfigFile, getting keys and values from given file - - std::ifstream in( filename.c_str() ); - - if( !in ) throw file_not_found( filename ); - - in >> (*this); -} - - -ConfigFile::ConfigFile() - : myDelimiter( string(1,'=') ), myComment( string(1,'#') ) -{ - // Construct a ConfigFile without a file; empty -} - - -void ConfigFile::remove( const string& key ) -{ - // Remove key and its value - myContents.erase( myContents.find( key ) ); - return; -} - - -bool ConfigFile::keyExists( const string& key ) const -{ - // Indicate whether key is found - mapci p = myContents.find( key ); - return ( p != myContents.end() ); -} - - -/* static */ -void ConfigFile::trim( string& s ) -{ - // Remove leading and trailing whitespace - static const char whitespace[] = " \n\t\v\r\f"; - s.erase( 0, s.find_first_not_of(whitespace) ); - s.erase( s.find_last_not_of(whitespace) + 1U ); -} - - -std::ostream& operator<<( std::ostream& os, const ConfigFile& cf ) -{ - // Save a ConfigFile to os - for( ConfigFile::mapci p = cf.myContents.begin(); - p != cf.myContents.end(); - ++p ) - { - os << p->first << " " << cf.myDelimiter << " "; - os << p->second << std::endl; - } - return os; -} - - -std::istream& operator>>( std::istream& is, ConfigFile& cf ) -{ - // Load a ConfigFile from is - // Read in keys and values, keeping internal whitespace - typedef string::size_type pos; - const string& delim = cf.myDelimiter; // separator - const string& comm = cf.myComment; // comment - const string& sentry = cf.mySentry; // end of file sentry - const pos skip = delim.length(); // length of separator - - string nextline = ""; // might need to read ahead to see where value ends - - while( is || nextline.length() > 0 ) - { - // Read an entire line at a time - string line; - if( nextline.length() > 0 ) - { - line = nextline; // we read ahead; use it now - nextline = ""; - } - else - { - std::getline( is, line ); - } - - // Ignore comments - line = line.substr( 0, line.find(comm) ); - - // Check for end of file sentry - if( sentry != "" && line.find(sentry) != string::npos ) return is; - - // Parse the line if it contains a delimiter - pos delimPos = line.find( delim ); - if( delimPos < string::npos ) - { - // Extract the key - string key = line.substr( 0, delimPos ); - line.replace( 0, delimPos+skip, "" ); - - // See if value continues on the next line - // Stop at blank line, next line with a key, end of stream, - // or end of file sentry - bool terminate = false; - while( !terminate && is ) - { - std::getline( is, nextline ); - terminate = true; - - string nlcopy = nextline; - ConfigFile::trim(nlcopy); - if( nlcopy == "" ) continue; - - nextline = nextline.substr( 0, nextline.find(comm) ); - if( nextline.find(delim) != string::npos ) - continue; - if( sentry != "" && nextline.find(sentry) != string::npos ) - continue; - - nlcopy = nextline; - ConfigFile::trim(nlcopy); - if( nlcopy != "" ) line += "\n"; - line += nextline; - terminate = false; - } - - // Store key and value - ConfigFile::trim(key); - ConfigFile::trim(line); - cf.myContents[key] = line; // overwrites if key is repeated - } - } - - return is; -} diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Crossbar/Crossbar.hh --- a/src/mem/ruby/network/orion/Crossbar/Crossbar.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#ifndef __CROSSBAR_H__ -#define __CROSSBAR_H__ - -#include "mem/ruby/network/orion/Type.hh" - -class TechParameter; -class OrionConfig; - -class Crossbar -{ - public: - enum CrossbarModel - { - NO_MODEL = 0, - MATRIX_CROSSBAR, - MULTREE_CROSSBAR - }; - enum ConnectType - { - TRANS_GATE, - TRISTATE_GATE - }; - enum TransType - { - N_GATE, - NP_GATE - }; - - public: - Crossbar( - CrossbarModel xbar_model_, - const string& conn_type_str_, - const string& trans_type_str_, - uint32_t num_in_, - uint32_t num_out_, - uint32_t data_width_, - uint32_t num_in_seg_, - uint32_t num_out_seg_, - uint32_t degree_, - const TechParameter* tech_param_ptr_ - ); - virtual ~Crossbar() = 0; - - public: - double get_len_req_wire() const { return m_len_req_wire; } - - virtual double get_dynamic_energy(bool is_max_) const = 0; - double get_static_power() const; - - void print_all() const; - - protected: - void set_conn_type(const string& conn_type_str_); - void set_trans_type(const string& trans_type_str_); - double calc_in_cap(); - double calc_out_cap(uint32_t num_in_); - double calc_int_cap(); - double calc_ctr_cap(double cap_wire_, bool prev_ctr_, bool next_ctr_); - virtual double calc_i_static() = 0; - - protected: - CrossbarModel m_xbar_model; - ConnectType m_conn_type; - TransType m_trans_type; - uint32_t m_num_in; - uint32_t m_num_out; - uint32_t m_data_width; - uint32_t m_num_in_seg; - uint32_t m_num_out_seg; - uint32_t m_degree; - const TechParameter* m_tech_param_ptr; - - double m_cap_in_wire; - double m_cap_out_wire; - double m_cap_ctr_wire; - double m_len_req_wire; - - double m_e_chg_in; - double m_e_chg_out; - double m_e_chg_ctr; - double m_e_chg_int; - - double m_i_static; - - public: - static Crossbar* create_crossbar( - const string& xbar_model_str_, - uint32_t num_in_, - uint32_t num_out_, - uint32_t data_width_, - const OrionConfig* orion_cfg_ptr_ - ); -}; - -#endif diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Crossbar/Crossbar.cc --- a/src/mem/ruby/network/orion/Crossbar/Crossbar.cc Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,393 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#include -#include - -#include "mem/ruby/network/orion/Crossbar/Crossbar.hh" -#include "mem/ruby/network/orion/Crossbar/MatrixCrossbar.hh" -#include "mem/ruby/network/orion/Crossbar/MultreeCrossbar.hh" -#include "mem/ruby/network/orion/OrionConfig.hh" -#include "mem/ruby/network/orion/TechParameter.hh" - -using namespace std; - -Crossbar::Crossbar( - CrossbarModel xbar_model_, - const string& conn_type_str_, - const string& trans_type_str_, - uint32_t num_in_, - uint32_t num_out_, - uint32_t data_width_, - uint32_t num_in_seg_, - uint32_t num_out_seg_, - uint32_t degree_, - const TechParameter* tech_param_ptr_ - ) -{ - m_xbar_model = xbar_model_; - if (m_xbar_model != NO_MODEL) - { - assert((num_in_ == num_in_) && (num_in_ != 0)); - assert((num_out_ == num_out_) && (num_out_ != 0)); - assert((data_width_ == data_width_) && (data_width_ != 0)); - assert(num_in_seg_ == num_in_seg_); - assert(num_out_seg_ == num_out_seg_); - - set_conn_type(conn_type_str_); - set_trans_type(trans_type_str_); - m_num_in = num_in_; - m_num_out = num_out_; - m_num_in_seg = num_in_seg_; - m_num_out_seg = num_out_seg_; - m_data_width = data_width_; - m_degree = degree_; - m_tech_param_ptr = tech_param_ptr_; - } - else - { - cerr << "ERROR at " << __FILE__ << " " << __LINE__ << endl; - } -} - -Crossbar::~Crossbar() -{} - -double Crossbar::get_static_power() const -{ - double vdd = m_tech_param_ptr->get_vdd(); - double SCALE_S = m_tech_param_ptr->get_SCALE_S(); - return (m_i_static*vdd*SCALE_S); -} - -void Crossbar::print_all() const -{ - cout << "Crossbar" << endl; - cout << "\t" << "Traversal = " << get_dynamic_energy(false) << endl; - cout << "\t" << "Static power = " << get_static_power() << endl; - return; -} - -void Crossbar::set_conn_type(const string& conn_type_str_) -{ - if (conn_type_str_ == string("TRANS_GATE")) - { - m_conn_type = TRANS_GATE; - } - else if (conn_type_str_ == string("TRISTATE_GATE")) - { - m_conn_type = TRISTATE_GATE; - } - else - { - cerr << "Invalid connect type: '" << conn_type_str_ << "'. Use TRANS_GATE as default." << endl; - m_conn_type = TRANS_GATE; - } - return; -} - -void Crossbar::set_trans_type(const string& trans_type_str_) -{ - if (trans_type_str_ == string("NP_GATE")) - { - m_trans_type = NP_GATE; - } - else if (trans_type_str_ == string("N_GATE")) - { - m_trans_type = N_GATE; - } - else - { - cerr << "Invalid trans type: '" << trans_type_str_ << "'. Use N_GATE as default." << endl; - m_trans_type = N_GATE; - } -} - -double Crossbar::calc_in_cap() -{ - double total_cap = 0; - - // part 1: wire cap - total_cap += m_cap_in_wire; - - double trans_cap = 0; - // part 2: drain cap of transmission gate or gate cap of tri-state gate - if (m_conn_type == TRANS_GATE) - { - //FIXME: resizing strategy - double Wmemcellr = m_tech_param_ptr->get_Wmemcellr(); - double nsize = Wmemcellr; - double Wdecinvn = m_tech_param_ptr->get_Wdecinvn(); - double Wdecinvp = m_tech_param_ptr->get_Wdecinvp(); - double psize = nsize*Wdecinvp/Wdecinvn; - trans_cap = m_tech_param_ptr->calc_draincap(nsize, TechParameter::NCH, 1); - if (m_trans_type == NP_GATE) - { - trans_cap += m_tech_param_ptr->calc_draincap(psize, TechParameter::PCH, 1); - } - } - else if (m_conn_type == TRISTATE_GATE) - { - double Woutdrvnandn = m_tech_param_ptr->get_Woutdrvnandn(); - double Woutdrvnandp = m_tech_param_ptr->get_Woutdrvnandp(); - double Woutdrvnorn = m_tech_param_ptr->get_Woutdrvnorn(); - double Woutdrvnorp = m_tech_param_ptr->get_Woutdrvnorp(); - trans_cap = m_tech_param_ptr->calc_gatecap(Woutdrvnandn+Woutdrvnandp, 0) - + m_tech_param_ptr->calc_gatecap(Woutdrvnorn+Woutdrvnorp, 0); - } - total_cap += trans_cap*m_num_out; - - // segmented crossbar - if (m_num_in_seg > 1) - { - total_cap *= (m_num_in_seg+1)/(m_num_in_seg*2); - // input capacitance of tri-state buffer - double Woutdrvnandn = m_tech_param_ptr->get_Woutdrvnandn(); - double Woutdrvnandp = m_tech_param_ptr->get_Woutdrvnandp(); - double Woutdrvnorn = m_tech_param_ptr->get_Woutdrvnorn(); - double Woutdrvnorp = m_tech_param_ptr->get_Woutdrvnorp(); - total_cap += (m_num_in_seg+2)*(m_num_in_seg-1)/(m_num_in_seg*2)*(m_tech_param_ptr->calc_gatecap(Woutdrvnandn+Woutdrvnandp, 0)+m_tech_param_ptr->calc_gatecap(Woutdrvnorn+Woutdrvnorp, 0)); - // output capacitance of tri-state buffer - double Woutdrivern = m_tech_param_ptr->get_Woutdrivern(); - double Woutdriverp = m_tech_param_ptr->get_Woutdriverp(); - total_cap += (m_num_in_seg-1)/2*(m_tech_param_ptr->calc_draincap(Woutdrivern, TechParameter::NCH, 1)+m_tech_param_ptr->calc_draincap(Woutdriverp, TechParameter::PCH, 1)); - } - - // part 3: input driver - //FIXME: how to specify timing - double period = m_tech_param_ptr->get_period(); - double psize = m_tech_param_ptr->calc_driver_psize(total_cap, period/3.0); - double Wdecinvn = m_tech_param_ptr->get_Wdecinvn(); - double Wdecinvp = m_tech_param_ptr->get_Wdecinvp(); - double nsize = psize*Wdecinvn/Wdecinvp; - total_cap += m_tech_param_ptr->calc_draincap(nsize, TechParameter::NCH, 1)+m_tech_param_ptr->calc_draincap(psize, TechParameter::PCH, 1)+m_tech_param_ptr->calc_gatecap(nsize+psize, 0); - - return total_cap/2.0; -} - -double Crossbar::calc_out_cap(uint32_t num_in_) -{ - double total_cap = 0; - - // part 1: wire cap - total_cap += m_cap_out_wire; - - double trans_cap = 0; - // part 2: drain cap of transmission gate or tri-state gate - if (m_conn_type == TRANS_GATE) - { - // FIXME: resizing strategy - double Wmemcellr = m_tech_param_ptr->get_Wmemcellr(); - double nsize = Wmemcellr; - double Wdecinvn = m_tech_param_ptr->get_Wdecinvn(); - double Wdecinvp = m_tech_param_ptr->get_Wdecinvp(); - double psize = nsize*Wdecinvp/Wdecinvn; - - trans_cap = m_tech_param_ptr->calc_draincap(nsize, TechParameter::NCH, 1); - if (m_trans_type == NP_GATE) - { - trans_cap += m_tech_param_ptr->calc_draincap(psize, TechParameter::PCH, 1); - } - } - else if (m_conn_type == TRISTATE_GATE) - { - double Woutdrivern = m_tech_param_ptr->get_Woutdrivern(); - double Woutdriverp = m_tech_param_ptr->get_Woutdriverp(); - trans_cap = m_tech_param_ptr->calc_draincap(Woutdrivern, TechParameter::NCH, 1)+m_tech_param_ptr->calc_draincap(Woutdriverp, TechParameter::PCH, 1); - } - total_cap += trans_cap*num_in_; - - // segmented crossbar - if (m_num_out_seg > 1) - { - total_cap *= (m_num_out_seg+1)/(m_num_out_seg*2); - // input capacitance of tri-state buffer - double Woutdrvnandn = m_tech_param_ptr->get_Woutdrvnandn(); - double Woutdrvnandp = m_tech_param_ptr->get_Woutdrvnandp(); - double Woutdrvnorn = m_tech_param_ptr->get_Woutdrvnorn(); - double Woutdrvnorp = m_tech_param_ptr->get_Woutdrvnorp(); - total_cap += (m_num_out_seg+2)*(m_num_out_seg-1)/(m_num_out_seg*2)*(m_tech_param_ptr->calc_gatecap(Woutdrvnandn+Woutdrvnandp, 0)+m_tech_param_ptr->calc_gatecap(Woutdrvnorn+Woutdrvnorp, 0)); - // output capacitance of tri-state buffer - double Woutdrivern = m_tech_param_ptr->get_Woutdrivern(); - double Woutdriverp = m_tech_param_ptr->get_Woutdriverp(); - total_cap += (m_num_out_seg-1)/2*(m_tech_param_ptr->calc_draincap(Woutdrivern, TechParameter::NCH, 1)+m_tech_param_ptr->calc_draincap(Woutdriverp, TechParameter::PCH, 1)); - } - - // part 3: output driver - double Woutdrivern = m_tech_param_ptr->get_Woutdrivern(); - double Woutdriverp = m_tech_param_ptr->get_Woutdriverp(); - total_cap += m_tech_param_ptr->calc_draincap(Woutdrivern, TechParameter::NCH, 1)+m_tech_param_ptr->calc_draincap(Woutdriverp, TechParameter::PCH, 1)+m_tech_param_ptr->calc_gatecap(Woutdrivern+Woutdriverp, 0); - - return total_cap/2.0; -} - -double Crossbar::calc_int_cap() -{ - double total_cap = 0; - - if (m_conn_type == TRANS_GATE) - { - // part 1: drain cap of transmission gate - //FIXME: Wmemcellr and resize - double Wmemcellr = m_tech_param_ptr->get_Wmemcellr(); - double nsize = Wmemcellr; - double trans_cap = m_tech_param_ptr->calc_draincap(nsize, TechParameter::NCH, 1); - if (m_trans_type == NP_GATE) - { - double Wdecinvn = m_tech_param_ptr->get_Wdecinvn(); - double Wdecinvp = m_tech_param_ptr->get_Wdecinvp(); - double psize = nsize*Wdecinvp/Wdecinvn; - trans_cap += m_tech_param_ptr->calc_draincap(psize, TechParameter::PCH, 1); - } - total_cap += trans_cap*(m_degree+1); - } - else if (m_conn_type == TRISTATE_GATE) - { - // part 1: drain cap of tri-state gate - double Woutdrivern = m_tech_param_ptr->get_Woutdrivern(); - double Woutdriverp = m_tech_param_ptr->get_Woutdriverp(); - - double trans_cap = (m_tech_param_ptr->calc_draincap(Woutdrivern, TechParameter::NCH, 1)+m_tech_param_ptr->calc_draincap(Woutdriverp, TechParameter::PCH, 1))*m_degree; - // part 2: gate cap of tri-state gate - double Woutdrvnandn = m_tech_param_ptr->get_Woutdrvnandn(); - double Woutdrvnandp = m_tech_param_ptr->get_Woutdrvnandp(); - double Woutdrvnorn = m_tech_param_ptr->get_Woutdrvnorn(); - double Woutdrvnorp = m_tech_param_ptr->get_Woutdrvnorp(); - trans_cap += m_tech_param_ptr->calc_gatecap(Woutdrvnandn+Woutdrvnandp, 0)+m_tech_param_ptr->calc_gatecap(Woutdrvnorn+Woutdrvnorp, 0); - total_cap += trans_cap; - } - - return total_cap/2.0; -} - -double Crossbar::calc_ctr_cap(double cap_wire_, bool prev_ctr_, bool next_ctr_) -{ - double total_cap = 0; - - // part 1: wire cap - total_cap += cap_wire_; - - double trans_cap = 0; - // part 2: gate cap of transmission gate or tri-state gate - if (m_conn_type == TRANS_GATE) - { - //FIXME Wmemcellr and resize - double Wmemcellr = m_tech_param_ptr->get_Wmemcellr(); - double nsize = Wmemcellr; - double trans_cap = m_tech_param_ptr->calc_gatecap(nsize, 0); - if (m_trans_type == NP_GATE) - { - double Wdecinvn = m_tech_param_ptr->get_Wdecinvn(); - double Wdecinvp = m_tech_param_ptr->get_Wdecinvp(); - double psize = nsize*Wdecinvp/Wdecinvn; - trans_cap += m_tech_param_ptr->calc_gatecap(psize, 0); - } - } - else if (m_conn_type == TRISTATE_GATE) - { - double Woutdrvnandn = m_tech_param_ptr->get_Woutdrvnandn(); - double Woutdrvnandp = m_tech_param_ptr->get_Woutdrvnandp(); - double Woutdrvnorn = m_tech_param_ptr->get_Woutdrvnorn(); - double Woutdrvnorp = m_tech_param_ptr->get_Woutdrvnorp(); - trans_cap = m_tech_param_ptr->calc_gatecap(Woutdrvnandn+Woutdrvnandp, 0) - + m_tech_param_ptr->calc_gatecap(Woutdrvnorn+Woutdrvnorp, 0); - } - total_cap += trans_cap*m_data_width; - - // part 3: inverter - if (!((m_conn_type == TRANS_GATE) && (m_trans_type == N_GATE) && (!prev_ctr_))) - { - double Wdecinvn = m_tech_param_ptr->get_Wdecinvn(); - double Wdecinvp = m_tech_param_ptr->get_Wdecinvp(); - total_cap += m_tech_param_ptr->calc_draincap(Wdecinvn, TechParameter::NCH, 1)+m_tech_param_ptr->calc_draincap(Wdecinvp, TechParameter::PCH, 1) - + m_tech_param_ptr->calc_gatecap(Wdecinvn+Wdecinvp, 0); - } - - double WdecNORn = m_tech_param_ptr->get_WdecNORn(); - double WdecNORp = m_tech_param_ptr->get_WdecNORp(); - // part 4: drain cap of previous level control signal - if (prev_ctr_) - { - // FIXME: need actual size, use decoder data for now - total_cap += m_degree*m_tech_param_ptr->calc_draincap(WdecNORn, TechParameter::NCH, 1) - +m_tech_param_ptr->calc_draincap(WdecNORp, TechParameter::PCH, m_degree); - } - - // part 5: gate cap of next level control signal - if (next_ctr_) - { - // FIXME: need actual size, use decoder data for now - total_cap += m_tech_param_ptr->calc_gatecap(WdecNORn+WdecNORp, m_degree*40+20); - } - - return total_cap; -} - -Crossbar* Crossbar::create_crossbar( - const string& xbar_model_str_, - uint32_t num_in_, - uint32_t num_out_, - uint32_t data_width_, - const OrionConfig* orion_cfg_ptr_ - ) -{ - if (xbar_model_str_ == string("MATRIX_CROSSBAR")) - { - const string& conn_type_str = orion_cfg_ptr_->get("CROSSBAR_CONNECT_TYPE"); - const string& trans_type_str = orion_cfg_ptr_->get("CROSSBAR_TRANS_GATE_TYPE"); - uint32_t num_in_seg = orion_cfg_ptr_->get("CROSSBAR_NUM_IN_SEG"); - uint32_t num_out_seg = orion_cfg_ptr_->get("CROSSBAR_NUM_OUT_SEG"); - double len_in_wire = orion_cfg_ptr_->get("CROSSBAR_LEN_IN_WIRE"); - double len_out_wire = orion_cfg_ptr_->get("CROSSBAR_LEN_OUT_WIRE"); - const TechParameter* tech_param_ptr = orion_cfg_ptr_->get_tech_param_ptr(); - return new MatrixCrossbar(conn_type_str, trans_type_str, - num_in_, num_out_, data_width_, num_in_seg, num_out_seg, - len_in_wire, len_out_wire, tech_param_ptr); - } - else if (xbar_model_str_ == string("MULTREE_CROSSBAR")) - { - const string& conn_type_str = orion_cfg_ptr_->get("CROSSBAR_CONNECT_TYPE"); - const string& trans_type_str = orion_cfg_ptr_->get("CROSSBAR_TRANS_GATE_TYPE"); - uint32_t degree = orion_cfg_ptr_->get("CROSSBAR_MUX_DEGREE"); - const TechParameter* tech_param_ptr = orion_cfg_ptr_->get_tech_param_ptr(); - return new MultreeCrossbar(conn_type_str, trans_type_str, - num_in_, num_out_, data_width_, degree, tech_param_ptr); - } - else - { - cerr << "WARNING: No Crossbar model" << endl; - return (Crossbar*)NULL; - } -} diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Crossbar/MatrixCrossbar.hh --- a/src/mem/ruby/network/orion/Crossbar/MatrixCrossbar.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#ifndef __MATRIXCROSSBAR_H__ -#define __MATRIXCROSSBAR_H__ - -#include "mem/ruby/network/orion/Crossbar/Crossbar.hh" -#include "mem/ruby/network/orion/Type.hh" - -class TechParameter; - -class MatrixCrossbar : public Crossbar -{ - public: - MatrixCrossbar( - const string& conn_type_str_, - const string& trans_type_str_, - uint32_t num_in_, - uint32_t num_out_, - uint32_t data_width_, - uint32_t num_in_seg_, - uint32_t num_out_seg_, - double len_in_wire_, - double len_out_wire_, - const TechParameter* tech_param_ptr_ - ); - ~MatrixCrossbar(); - - public: - double get_dynamic_energy(bool is_max_) const; - - private: - void init(); - double calc_i_static(); - - private: - double m_len_in_wire; - double m_len_out_wire; -}; - -#endif diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Crossbar/MatrixCrossbar.cc --- a/src/mem/ruby/network/orion/Crossbar/MatrixCrossbar.cc Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#include -#include - -#include "mem/ruby/network/orion/Crossbar/MatrixCrossbar.hh" -#include "mem/ruby/network/orion/TechParameter.hh" - -using namespace std; - -MatrixCrossbar::MatrixCrossbar( - const string& conn_type_str_, - const string& trans_type_str_, - uint32_t num_in_, - uint32_t num_out_, - uint32_t data_width_, - uint32_t num_in_seg_, - uint32_t num_out_seg_, - double len_in_wire_, - double len_out_wire_, - const TechParameter* tech_param_ptr_ - ) : Crossbar( - MATRIX_CROSSBAR, conn_type_str_, trans_type_str_, - num_in_, num_out_, data_width_, num_in_seg_, num_out_seg_, - 0, tech_param_ptr_) -{ - assert(len_in_wire_ == len_in_wire_); - assert(len_out_wire_ == len_out_wire_); - - m_len_in_wire = len_in_wire_; - m_len_out_wire = len_out_wire_; - init(); -} - -MatrixCrossbar::~MatrixCrossbar() -{} - -double MatrixCrossbar::get_dynamic_energy(bool is_max_) const -{ - double e_atomic; - double e_access = 0; - - e_atomic = m_e_chg_in*m_data_width*(is_max_? 1:0.5); - e_access += e_atomic; - - e_atomic = m_e_chg_out*m_data_width*(is_max_? 1:0.5); - e_access += e_atomic; - - e_atomic = m_e_chg_ctr; - e_access += e_atomic; - - return e_access; -} - -void MatrixCrossbar::init() -{ - // FIXME: need accurate spacing - double CrsbarCellWidth = m_tech_param_ptr->get_CrsbarCellWidth(); - double CrsbarCellHeight = m_tech_param_ptr->get_CrsbarCellHeight(); - double len_in = m_num_out*m_data_width*CrsbarCellWidth; - double len_out = m_num_in*m_data_width*CrsbarCellHeight; - if(len_in > m_len_in_wire) m_len_in_wire = len_in; - if(len_out > m_len_out_wire) m_len_out_wire = len_out; - double CC3metal = m_tech_param_ptr->get_CC3metal(); - m_cap_in_wire = CC3metal*m_len_in_wire; - m_cap_out_wire = CC3metal*m_len_out_wire; - double Cmetal = m_tech_param_ptr->get_Cmetal(); - m_cap_ctr_wire = Cmetal*m_len_in_wire/2.0; - m_len_req_wire = m_len_in_wire; - - double e_factor = m_tech_param_ptr->get_EnergyFactor(); - m_e_chg_in = calc_in_cap()*e_factor; - m_e_chg_out = calc_out_cap(m_num_out)*e_factor; - //FIXME: wire length estimation, really reset? - //control signal should reset after transmission is done, so no 1/2 - m_e_chg_ctr = calc_ctr_cap(m_cap_ctr_wire, 0, 0)*e_factor; - m_e_chg_int = 0; - - m_i_static = calc_i_static(); - return; -} - -double MatrixCrossbar::calc_i_static() -{ - double Woutdrvnandn = m_tech_param_ptr->get_Woutdrvnandn(); - double Woutdrvnandp = m_tech_param_ptr->get_Woutdrvnandp(); - double Woutdrvnorn = m_tech_param_ptr->get_Woutdrvnorn(); - double Woutdrvnorp = m_tech_param_ptr->get_Woutdrvnorp(); - double Wdecinvn = m_tech_param_ptr->get_Wdecinvn(); - double Wdecinvp = m_tech_param_ptr->get_Wdecinvp(); - double Woutdrivern = m_tech_param_ptr->get_Woutdrivern(); - double Woutdriverp = m_tech_param_ptr->get_Woutdriverp(); - double NAND2_TAB_0 = m_tech_param_ptr->get_NAND2_TAB(0); - double NAND2_TAB_1 = m_tech_param_ptr->get_NAND2_TAB(1); - double NAND2_TAB_2 = m_tech_param_ptr->get_NAND2_TAB(2); - double NAND2_TAB_3 = m_tech_param_ptr->get_NAND2_TAB(3); - double NOR2_TAB_0 = m_tech_param_ptr->get_NOR2_TAB(0); - double NOR2_TAB_1 = m_tech_param_ptr->get_NOR2_TAB(1); - double NOR2_TAB_2 = m_tech_param_ptr->get_NOR2_TAB(2); - double NOR2_TAB_3 = m_tech_param_ptr->get_NOR2_TAB(3); - double NMOS_TAB_0 = m_tech_param_ptr->get_NMOS_TAB(0); - double PMOS_TAB_0 = m_tech_param_ptr->get_PMOS_TAB(0); - - double i_static = 0; - // tri-state buffers - i_static += ((Woutdrvnandp*(NAND2_TAB_0+NAND2_TAB_1+NAND2_TAB_2)+Woutdrvnandn*NAND2_TAB_3)/4 - + (Woutdrvnorp*NOR2_TAB_0+Woutdrvnorn*(NOR2_TAB_1+NOR2_TAB_2+NOR2_TAB_3))/4 - + Woutdrivern*NMOS_TAB_0+Woutdriverp*PMOS_TAB_0)*m_num_in*m_num_out*m_data_width; - - // input driver - i_static += (Wdecinvn*NMOS_TAB_0+Wdecinvp*PMOS_TAB_0)*m_num_in*m_data_width; - - // output driver - i_static += (Woutdrivern*NMOS_TAB_0+Woutdriverp*PMOS_TAB_0)*m_num_out*m_data_width; - - // control siganl inverter - i_static += (Wdecinvn*NMOS_TAB_0+Wdecinvp*PMOS_TAB_0)*m_num_in*m_num_out; - return i_static; -} diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Crossbar/MultreeCrossbar.hh --- a/src/mem/ruby/network/orion/Crossbar/MultreeCrossbar.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#ifndef __MULTREECROSSBAR_H__ -#define __MULTREECROSSBAR_H__ - -#include "mem/ruby/network/orion/Crossbar/Crossbar.hh" -#include "mem/ruby/network/orion/Type.hh" - -class TechParameter; - -class MultreeCrossbar : public Crossbar -{ - public: - MultreeCrossbar( - const string& conn_type_str_, - const string& trans_type_str_, - uint32_t num_in_, - uint32_t num_out_, - uint32_t data_width_, - uint32_t degree_, - const TechParameter* tech_param_ptr_ - ); - ~MultreeCrossbar(); - - public: - double get_dynamic_energy(bool is_max_) const; - - private: - void init(); - double calc_i_static(); - - private: - uint32_t m_depth; -}; - -#endif diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Crossbar/MultreeCrossbar.cc --- a/src/mem/ruby/network/orion/Crossbar/MultreeCrossbar.cc Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#include -#include - -#include "mem/ruby/network/orion/Crossbar/MultreeCrossbar.hh" -#include "mem/ruby/network/orion/TechParameter.hh" - -using namespace std; - -MultreeCrossbar::MultreeCrossbar( - const string& conn_type_str_, - const string& trans_type_str_, - uint32_t num_in_, - uint32_t num_out_, - uint32_t data_width_, - uint32_t degree_, - const TechParameter *tech_param_ptr_ - ) : Crossbar( - MULTREE_CROSSBAR, conn_type_str_, trans_type_str_, - num_in_, num_out_, data_width_, 0, 0, degree_, tech_param_ptr_) -{ - m_len_req_wire = 0; - init(); -} - -MultreeCrossbar::~MultreeCrossbar() -{} - -double MultreeCrossbar::get_dynamic_energy(bool is_max_) const -{ - double e_atomic; - double e_access = 0; - - e_atomic = m_e_chg_in*m_data_width*(is_max_? 1:0.5); - e_access += e_atomic; - - e_atomic = m_e_chg_out*m_data_width*(is_max_? 1:0.5); - e_access += e_atomic; - - e_atomic = m_e_chg_ctr; - e_access += e_atomic; - - if (m_depth > 1) - { - e_atomic = m_e_chg_int*m_data_width*(m_depth-1)*(is_max_? 1:0.5); - e_access += e_atomic; - } - - return e_access; -} - -void MultreeCrossbar::init() -{ - double CrsbarCellWidth = m_tech_param_ptr->get_CrsbarCellWidth(); - double CCmetal = m_tech_param_ptr->get_CCmetal(); - double Lamda = m_tech_param_ptr->get_Lamda(); - double CC3metal = m_tech_param_ptr->get_CC3metal(); - - double len_in_wire; - // input wire horizontal segment length - len_in_wire = m_num_in*m_data_width*CrsbarCellWidth*(m_num_out/2); - m_cap_in_wire = len_in_wire*CCmetal; - // input wire vertical segment length - len_in_wire = m_num_in*m_data_width*(5*Lamda)*(m_num_out/2); - m_cap_in_wire += len_in_wire*CC3metal; - m_cap_out_wire = 0; - - double Cmetal = m_tech_param_ptr->get_Cmetal(); - double len_ctr_wire = m_num_in*m_data_width*CrsbarCellWidth*(m_num_out/2)/2; - m_cap_ctr_wire = Cmetal*len_ctr_wire; - - double e_factor = m_tech_param_ptr->get_EnergyFactor(); - m_e_chg_in = calc_in_cap()*e_factor; - m_e_chg_out = calc_out_cap(m_degree)*e_factor; - m_e_chg_int = calc_int_cap()*e_factor; - - m_depth = (uint32_t)ceil(log((double)m_num_in)/log((double)m_degree)); - - // control signal should reset after transmission is done - if (m_depth == 1) - { - // only one level of control sigal - m_e_chg_ctr = calc_ctr_cap(m_cap_ctr_wire, 0, 0)*e_factor; - } - else - { - // first level and last level control signals - m_e_chg_ctr = calc_ctr_cap(m_cap_ctr_wire, 0, 1)*e_factor + calc_ctr_cap(0, 1, 0)*e_factor; - // intermediate control signals - if (m_depth > 2) - { - m_e_chg_ctr += (m_depth-2)*calc_ctr_cap(0, 1, 1)*e_factor; - } - } - - m_i_static = calc_i_static(); -} - -double MultreeCrossbar::calc_i_static() -{ - double Wdecinvn = m_tech_param_ptr->get_Wdecinvn(); - double Wdecinvp = m_tech_param_ptr->get_Wdecinvp(); - double Woutdrivern = m_tech_param_ptr->get_Woutdrivern(); - double Woutdriverp = m_tech_param_ptr->get_Woutdriverp(); - double WdecNORn = m_tech_param_ptr->get_WdecNORn(); - double WdecNORp = m_tech_param_ptr->get_WdecNORp(); - double NOR2_TAB_0 = m_tech_param_ptr->get_NOR2_TAB(0); - double NOR2_TAB_1 = m_tech_param_ptr->get_NOR2_TAB(1); - double NOR2_TAB_2 = m_tech_param_ptr->get_NOR2_TAB(2); - double NOR2_TAB_3 = m_tech_param_ptr->get_NOR2_TAB(3); - double NMOS_TAB_0 = m_tech_param_ptr->get_NMOS_TAB(0); - double PMOS_TAB_0 = m_tech_param_ptr->get_PMOS_TAB(0); - - double i_static = 0; - - // input driver - i_static += (Wdecinvn*NMOS_TAB_0+Wdecinvp*PMOS_TAB_0)*m_num_in*m_data_width; - - // output driver - i_static += (Woutdrivern*NMOS_TAB_0+Woutdriverp*PMOS_TAB_0)*m_num_out*m_data_width; - - // mux - i_static += (WdecNORp*NOR2_TAB_0+WdecNORn*(NOR2_TAB_1+NOR2_TAB_2+NOR2_TAB_3))/4*(2*m_num_in-1)*m_num_out*m_data_width; - - // control signal inverter - i_static += (Wdecinvn*NMOS_TAB_0+Wdecinvp*PMOS_TAB_0)*m_num_in*m_num_out; - return i_static; -} diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Crossbar/SConscript --- a/src/mem/ruby/network/orion/Crossbar/SConscript Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -# Copyright (c) 2010 Massachusetts Institute of Technology -# 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. -# -# Authors: Tushar Krishna - -Import('*') - -if env['PROTOCOL'] == 'None': - Return() - -Source('Crossbar.cc') -Source('MatrixCrossbar.cc') -Source('MultreeCrossbar.cc') diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/FlipFlop.hh --- a/src/mem/ruby/network/orion/FlipFlop.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#ifndef __FLIPFLOP_H__ -#define __FLIPFLOP_H__ - -#include "mem/ruby/network/orion/Type.hh" - -class TechParameter; - -class FlipFlop -{ - public: - enum FFModel - { - NO_MODEL = 0, - NEG_DFF - }; - - public: - FlipFlop( - const string& ff_model_str_, - double load_, - const TechParameter* tech_param_ptr_ - ); - ~FlipFlop(); - - public: - double get_e_switch() const { return m_e_switch; } - double get_e_keep_1() const { return m_e_keep_1; } - double get_e_keep_0() const { return m_e_keep_0; } - double get_e_clock() const { return m_e_clock; } - double get_i_static() const { return m_i_static; } - - private: - void init(); - double calc_node_cap(uint32_t num_fanin_, uint32_t num_fanout_); - double calc_clock_cap(); - double calc_i_static(); - - private: - FFModel m_ff_model; - const TechParameter* m_tech_param_ptr; - - double m_load; - - double m_e_switch; - double m_e_keep_1; - double m_e_keep_0; - double m_e_clock; - - double m_i_static; -}; - -#endif diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/FlipFlop.cc --- a/src/mem/ruby/network/orion/FlipFlop.cc Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#include -#include - -#include "mem/ruby/network/orion/FlipFlop.hh" -#include "mem/ruby/network/orion/TechParameter.hh" - -using namespace std; - -FlipFlop::FlipFlop( - const string& ff_model_str_, - double load_, - const TechParameter* tech_param_ptr_ -) -{ - if (ff_model_str_ == string("NEG_DFF")) - { - m_ff_model = NEG_DFF; - } - else - { - m_ff_model = NO_MODEL; - } - - if (m_ff_model != NO_MODEL) - { - assert(load_ == load_); - - m_load = load_; - m_tech_param_ptr = tech_param_ptr_; - - init(); - } -} - -FlipFlop::~FlipFlop() -{} - -void FlipFlop::init() -{ - double c1, c2, c3, c4, c5, c6; - - double e_factor = m_tech_param_ptr->get_EnergyFactor(); - switch(m_ff_model) - { - case NEG_DFF: - c1 = c5 = c6 = calc_node_cap(2, 1); - c2 = calc_node_cap(2, 3); - c3 = calc_node_cap(3, 2); - c4 = calc_node_cap(2, 3); - - m_e_switch = (c1+c2+c3+c4+c5+c6+m_load)*e_factor/2.0; - // no 1/2 for e_keep and e_clock because clock signal switches twice in one cycle - m_e_keep_1 = c3*e_factor; - m_e_keep_0 = c2*e_factor; - m_e_clock = calc_clock_cap()*e_factor; - - m_i_static = calc_i_static(); - break; - default: - cerr << "error" << endl; - } - return; -} - - -//this model is based on the gate-level design given by Randy H. Katz "Contemporary Logic Design" -//Figure 6.24, node numbers (1-6) are assigned to all gate outputs, left to right, top to bottom -// -//We should have pure cap functions and leave the decision of whether or not to have coefficient -//1/2 in init function. -double FlipFlop::calc_node_cap(uint32_t num_fanin_, uint32_t num_fanout_) -{ - double total_cap = 0; - - //FIXME: all need actual size - //part 1: drain cap of NOR gate - double WdecNORn = m_tech_param_ptr->get_WdecNORn(); - double WdecNORp = m_tech_param_ptr->get_WdecNORp(); - total_cap += num_fanin_*m_tech_param_ptr->calc_draincap(WdecNORn, TechParameter::NCH, 1) + m_tech_param_ptr->calc_draincap(WdecNORp, TechParameter::PCH, num_fanin_); - - //part 2: gate cap of NOR gate - total_cap += num_fanout_*m_tech_param_ptr->calc_gatecap(WdecNORn+WdecNORp, 0); - return total_cap; -} - -double FlipFlop::calc_clock_cap() -{ - double WdecNORn = m_tech_param_ptr->get_WdecNORn(); - double WdecNORp = m_tech_param_ptr->get_WdecNORp(); - return (2*m_tech_param_ptr->calc_gatecap(WdecNORn+WdecNORp, 0)); -} - -double FlipFlop::calc_i_static() -{ - double WdecNORn = m_tech_param_ptr->get_WdecNORn(); - double WdecNORp = m_tech_param_ptr->get_WdecNORp(); - double NOR2_TAB_0 = m_tech_param_ptr->get_NOR2_TAB(0); - double NOR2_TAB_1 = m_tech_param_ptr->get_NOR2_TAB(1); - double NOR2_TAB_2 = m_tech_param_ptr->get_NOR2_TAB(2); - double NOR2_TAB_3 = m_tech_param_ptr->get_NOR2_TAB(3); - - return (WdecNORp*NOR2_TAB_0 + WdecNORn*(NOR2_TAB_1+NOR2_TAB_2+NOR2_TAB_3))/4*6; -} diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/NetworkPower.hh --- a/src/mem/ruby/network/orion/NetworkPower.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2010 Massachusetts Institute of Technology - * 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. - * - * Authors: Chia-Hsin Owen Chen - * Tushar Krishna - */ - -#ifndef POWER_TRACE_H -#define POWER_TRACE_H - -#include -#include -#include - -#include "mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.hh" -#include "mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh" -#include "mem/ruby/network/garnet/fixed-pipeline/Router_d.hh" - -//int RW : -#define READ_MODE 0 -#define WRITE_MODE 1 - -#endif diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/NetworkPower.cc --- a/src/mem/ruby/network/orion/NetworkPower.cc Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,271 +0,0 @@ -/* - * Copyright (c) 2010 Massachusetts Institute of Technology - * 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. - * - * Authors: Chia-Hsin Owen Chen - * Tushar Krishna - */ - -#include "mem/ruby/network/orion/NetworkPower.hh" -#include "mem/ruby/network/orion/OrionConfig.hh" -#include "mem/ruby/network/orion/OrionLink.hh" -#include "mem/ruby/network/orion/OrionRouter.hh" - -double -Router_d::calculate_power() -{ - //Network Activities from garnet - calculate_performance_numbers(); - double sim_cycles; - sim_cycles = - g_system_ptr->getTime() - m_network_ptr->getRubyStartTime(); - - // Number of virtual networks/message classes declared in Ruby - // maybe greater than active virtual networks. - // Estimate active virtual networks for correct power estimates - int num_active_vclass = 0; - std::vector active_vclass_ary; - active_vclass_ary.resize(m_virtual_networks); - - std::vector vc_local_arbit_count_active; - std::vector vc_global_arbit_count_active; - std::vector buf_read_count_active; - std::vector buf_write_count_active; - - for (int i =0; i < m_virtual_networks; i++) { - - active_vclass_ary[i] = (get_net_ptr())->validVirtualNetwork(i); - if (active_vclass_ary[i]) { - num_active_vclass++; - vc_local_arbit_count_active.push_back(vc_local_arbit_count[i]); - vc_global_arbit_count_active.push_back(vc_global_arbit_count[i]); - buf_read_count_active.push_back(buf_read_count[i]); - buf_write_count_active.push_back(buf_write_count[i]); - } - else { - // Inactive vclass - assert(vc_global_arbit_count[i] == 0); - assert(vc_local_arbit_count[i] == 0); - } - } - - // Orion Initialization - OrionConfig* orion_cfg_ptr; - OrionRouter* orion_rtr_ptr; - static double freq_Hz; - - const string cfg_fn = "src/mem/ruby/network/orion/router.cfg"; - orion_cfg_ptr = new OrionConfig(cfg_fn); - freq_Hz = orion_cfg_ptr->get("FREQUENCY"); - - uint32_t num_in_port = m_input_unit.size(); - uint32_t num_out_port = m_output_unit.size(); - uint32_t num_vclass = num_active_vclass; - std::vector vclass_type_ary; - - for (int i = 0; i < m_virtual_networks; i++) { - if (active_vclass_ary[i]) { - int temp_vc = i*m_vc_per_vnet; - vclass_type_ary.push_back((uint32_t) - m_network_ptr->get_vnet_type(temp_vc)); - } - } - assert(vclass_type_ary.size() == num_active_vclass); - - uint32_t num_vc_per_vclass = m_vc_per_vnet; - uint32_t in_buf_per_data_vc = m_network_ptr->getBuffersPerDataVC(); - uint32_t in_buf_per_ctrl_vc = m_network_ptr->getBuffersPerCtrlVC(); - //flit width in bits - uint32_t flit_width_bits = m_network_ptr->getNiFlitSize() * 8; - - orion_rtr_ptr = new OrionRouter( - num_in_port, - num_out_port, - num_vclass, - vclass_type_ary, - num_vc_per_vclass, - in_buf_per_data_vc, - in_buf_per_ctrl_vc, - flit_width_bits, - orion_cfg_ptr - ); - - - //Power Calculation - double Pbuf_wr_dyn = 0.0; - double Pbuf_rd_dyn = 0.0; - double Pvc_arb_local_dyn = 0.0; - double Pvc_arb_global_dyn = 0.0; - double Psw_arb_local_dyn = 0.0; - double Psw_arb_global_dyn = 0.0; - double Pxbar_dyn = 0.0; - double Ptotal_dyn = 0.0; - - double Pbuf_sta = 0.0; - double Pvc_arb_sta = 0.0; - double Psw_arb_sta = 0.0; - double Pxbar_sta = 0.0; - double Ptotal_sta = 0.0; - - double Ptotal = 0.0; - - - //Dynamic Power - - // Note: For each active arbiter in vc_arb or sw_arb of size T:1, - // assuming half the requests (T/2) are high on average. - // TODO: estimate expected value of requests from simulation. - - for (int i = 0; i < num_vclass; i++) { - // Buffer Write - Pbuf_wr_dyn += - orion_rtr_ptr->calc_dynamic_energy_buf(i, WRITE_MODE, false)* - (buf_write_count_active[i]/sim_cycles)*freq_Hz; - - // Buffer Read - Pbuf_rd_dyn += - orion_rtr_ptr->calc_dynamic_energy_buf(i, READ_MODE, false)* - (buf_read_count_active[i]/sim_cycles)*freq_Hz; - - // VC arbitration local - // Each input VC arbitrates for one output VC (in its vclass) - // at its output port. - // Arbiter size: num_vc_per_vclass:1 - Pvc_arb_local_dyn += - orion_rtr_ptr->calc_dynamic_energy_local_vc_arb(i, - num_vc_per_vclass/2, false)* - (vc_local_arbit_count_active[i]/sim_cycles)* - freq_Hz; - - // VC arbitration global - // Each output VC chooses one input VC out of all possible requesting - // VCs (within vclass) at all input ports - // Arbiter size: num_in_port*num_vc_per_vclass:1 - // Round-robin at each input VC for outvcs in the local stage will - // try to keep outvc conflicts to the minimum. - // Assuming conflicts due to request for same outvc from - // num_in_port/2 requests. - // TODO: use garnet to estimate this - Pvc_arb_global_dyn += - orion_rtr_ptr->calc_dynamic_energy_global_vc_arb(i, - num_in_port/2, false)* - (vc_global_arbit_count_active[i]/sim_cycles)* - freq_Hz; - } - - // Switch Allocation Local - // Each input port chooses one input VC as requestor - // Arbiter size: num_vclass*num_vc_per_vclass:1 - Psw_arb_local_dyn = - orion_rtr_ptr->calc_dynamic_energy_local_sw_arb( - num_vclass*num_vc_per_vclass/2, false)* - (sw_local_arbit_count/sim_cycles)* - freq_Hz; - - // Switch Allocation Global - // Each output port chooses one input port as winner - // Arbiter size: num_in_port:1 - Psw_arb_global_dyn = - orion_rtr_ptr->calc_dynamic_energy_global_sw_arb( - num_in_port/2, false)* - (sw_global_arbit_count/sim_cycles)* - freq_Hz; - - // Crossbar - Pxbar_dyn = - orion_rtr_ptr->calc_dynamic_energy_xbar(false)* - (crossbar_count/sim_cycles)*freq_Hz; - - // Total - Ptotal_dyn = Pbuf_wr_dyn + Pbuf_rd_dyn + - Pvc_arb_local_dyn + Pvc_arb_global_dyn + - Psw_arb_local_dyn + Psw_arb_global_dyn + - Pxbar_dyn; - - m_power_dyn = Ptotal_dyn; - - // Clock Power - m_clk_power = orion_rtr_ptr->calc_dynamic_energy_clock()*freq_Hz; - - // Static Power - Pbuf_sta = orion_rtr_ptr->get_static_power_buf(); - Pvc_arb_sta = orion_rtr_ptr->get_static_power_va(); - Psw_arb_sta = orion_rtr_ptr->get_static_power_sa(); - Pxbar_sta = orion_rtr_ptr->get_static_power_xbar(); - - Ptotal_sta += Pbuf_sta + Pvc_arb_sta + Psw_arb_sta + Pxbar_sta; - - m_power_sta = Ptotal_sta; - - Ptotal = m_power_dyn + m_power_sta + m_clk_power; - - return Ptotal; -} - -double -NetworkLink_d::calculate_power() -{ - OrionConfig* orion_cfg_ptr; - OrionLink* orion_link_ptr; - static double freq_Hz; - double link_length; - - // Initialization - const string cfg_fn = "src/mem/ruby/network/orion/router.cfg"; - orion_cfg_ptr = new OrionConfig(cfg_fn); - freq_Hz = orion_cfg_ptr->get("FREQUENCY"); - - link_length = orion_cfg_ptr->get("LINK_LENGTH"); - - int channel_width_bits = channel_width*8; - - orion_link_ptr = new OrionLink( - link_length, - channel_width_bits, - orion_cfg_ptr); - - double sim_cycles = - (double)(g_system_ptr->getTime() - m_net_ptr->getRubyStartTime()); - - // Dynamic Power - // Assume half the bits flipped on every link activity - double Plink_dyn = - orion_link_ptr->calc_dynamic_energy(channel_width_bits/2)* - (m_link_utilized/ sim_cycles)*freq_Hz; - - m_power_dyn = Plink_dyn; - - // Static Power - // Calculates number of repeaters needed in link, and their static power - // For short links, like 1mm, no repeaters are needed so static power is 0 - double Plink_sta = orion_link_ptr->get_static_power(); - - m_power_sta = Plink_sta; - - double Ptotal = m_power_dyn + m_power_sta; - - return Ptotal; -} diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/OrionConfig.hh --- a/src/mem/ruby/network/orion/OrionConfig.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2010 Massachusetts Institute of Technology - * 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. - * - * Authors: Chia-Hsin Owen Chen - */ - -#ifndef __ORIONCONFIG_H__ -#define __ORIONCONFIG_H__ - -#include -#include -#include - -#include "mem/ruby/network/orion/Type.hh" - -class TechParameter; - -class OrionConfig -{ - public: - OrionConfig(const string& cfg_fn_); - OrionConfig(const OrionConfig& orion_cfg_); - ~OrionConfig(); - - public: - void set_num_in_port(uint32_t num_in_port_); - void set_num_out_port(uint32_t num_out_port_); - void set_num_vclass(uint32_t num_vclass_); - void set_num_vchannel(uint32_t num_vchannel_); - void set_in_buf_num_set(uint32_t in_buf_num_set_); - void set_flit_width(uint32_t flit_width_); - - void read_file(const std::string& filename_); - void print_config(std::ostream& out_); - - public: - template - T get(const std::string& key_) const; - const TechParameter* get_tech_param_ptr() const { return m_tech_param_ptr; } - uint32_t get_num_in_port() const { return m_num_in_port; } - uint32_t get_num_out_port() const { return m_num_out_port; } - uint32_t get_num_vclass() const { return m_num_vclass; } - uint32_t get_num_vchannel() const { return m_num_vchannel; } - uint32_t get_in_buf_num_set() const { return m_in_buf_num_set; } - uint32_t get_flit_width() const { return m_flit_width; } - - private: - std::map m_params_map; - - TechParameter* m_tech_param_ptr; - uint32_t m_num_in_port; - uint32_t m_num_out_port; - uint32_t m_num_vclass; - uint32_t m_num_vchannel; - uint32_t m_in_buf_num_set; - uint32_t m_flit_width; - - protected: - struct key_not_found - { - std::string m_key; - key_not_found(const std::string& key_ = string()) : m_key(key_) - {} - }; - template - static T string_as_T(const std::string& str_); - template - static std::string T_as_string(const T& t_); - - private: - static std::string ms_param_name[]; -}; - -template -T OrionConfig::get(const string& key_) const -{ - std::map::const_iterator it; - - it = m_params_map.find(key_); - if (it == m_params_map.end()) - { - std::cerr << key_ << " NOT FOUND!" << std::endl; - throw key_not_found(key_); - } - return string_as_T(it->second); -} - - template -T OrionConfig::string_as_T(const string& str_) -{ - T ret; - std::istringstream ist(str_); - ist >> ret; - return ret; -} - -template<> -inline string OrionConfig::string_as_T(const string& str_) -{ - return str_; -} - -template<> -inline bool OrionConfig::string_as_T(const string& str_) -{ - bool ret; - if (str_ == string("TRUE")) - { - ret = true; - } - else if (str_ == string("FALSE")) - { - ret = false; - } - else - { - std::cerr << "Invalid bool value: '" << str_ << - "'. Treated as FALSE." << std::endl; - ret = false; - } - return ret; -} - -template -string OrionConfig::T_as_string(const T& t) -{ - std::ostringstream ost; - ost << t; - return ost.str(); -} - -#endif - diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/OrionConfig.cc --- a/src/mem/ruby/network/orion/OrionConfig.cc Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,201 +0,0 @@ -/* - * Copyright (c) 2010 Massachusetts Institute of Technology - * 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. - * - * Authors: Chia-Hsin Owen Chen - */ - -#include -#include - -#include "mem/ruby/network/orion/ConfigFile.hh" -#include "mem/ruby/network/orion/OrionConfig.hh" -#include "mem/ruby/network/orion/TechParameter.hh" - -using namespace std; - -string OrionConfig::ms_param_name[] = { - "TECH_NODE", - "TRANSISTOR_TYPE", - "VDD", - "FREQUENCY", - "NUM_INPUT_PORT", - "NUM_OUTPUT_PORT", - "FLIT_WIDTH", - "NUM_VIRTUAL_CLASS", - "NUM_VIRTUAL_CHANNEL", - "IS_IN_SHARED_BUFFER", - "IS_OUT_SHARED_BUFFER", - "IS_IN_SHARED_SWITCH", - "IS_OUT_SHARED_SWITCH", - "IS_INPUT_BUFFER", - "IN_BUF_MODEL", - "IN_BUF_NUM_SET", - "IN_BUF_NUM_READ_PORT", - "IS_OUTPUT_BUFFER", - "OUT_BUF_MODEL", - "OUT_BUF_NUM_SET", - "OUT_BUF_NUM_WRITE_PORT", - "SRAM_NUM_DATA_END", - "SRAM_ROWDEC_MODEL", - "SRAM_ROWDEC_PRE_MODEL", - "SRAM_WORDLINE_MODEL", - "SRAM_BITLINE_PRE_MODEL", - "SRAM_BITLINE_MODEL", - "SRAM_AMP_MODEL", - "SRAM_OUTDRV_MODEL", - "CROSSBAR_MODEL", - "CROSSBAR_CONNECT_TYPE", - "CROSSBAR_TRANS_GATE_TYPE", - "CROSSBAR_MUX_DEGREE", - "CROSSBAR_NUM_IN_SEG", - "CROSSBAR_NUM_OUT_SEG", - "CROSSBAR_LEN_IN_WIRE", - "CROSSBAR_LEN_OUT_WIRE", - "VA_MODEL", - "VA_IN_ARB_MODEL", - "VA_IN_ARB_FF_MODEL", - "VA_OUT_ARB_MODEL", - "VA_OUT_ARB_FF_MODEL", - "VA_BUF_MODEL", - "SA_IN_ARB_MODEL", - "SA_IN_ARB_FF_MODEL", - "SA_OUT_ARB_MODEL", - "SA_OUT_ARB_FF_MODEL", - "LINK_LENGTH", - "WIRE_LAYER_TYPE", - "WIRE_WIDTH_SPACING", - "WIRE_BUFFERING_MODEL", - "WIRE_IS_SHIELDING", - "IS_HTREE_CLOCK", - "ROUTER_DIAGONAL" -}; - -OrionConfig::OrionConfig(const string& cfg_fn_) -{ - uint32_t num_param = sizeof(ms_param_name)/sizeof(string); - - for(uint32_t i = 0; i < num_param; i++) - { - m_params_map[ms_param_name[i]] = "NOT_SET"; - } - - read_file(cfg_fn_); - m_tech_param_ptr = new TechParameter(this); -} - -OrionConfig::OrionConfig(const OrionConfig& orion_cfg_) -{ - m_params_map = orion_cfg_.m_params_map; - m_num_in_port = orion_cfg_.m_num_in_port; - m_num_out_port = orion_cfg_.m_num_out_port; - m_num_vclass = orion_cfg_.m_num_vclass; - m_num_vchannel = orion_cfg_.m_num_vchannel; - m_in_buf_num_set = orion_cfg_.m_in_buf_num_set; - m_flit_width = orion_cfg_.m_flit_width; - - m_tech_param_ptr = new TechParameter(this); -} - -OrionConfig::~OrionConfig() -{ - delete m_tech_param_ptr; -} - -void OrionConfig::set_num_in_port(uint32_t num_in_port_) -{ - m_params_map[string("NUM_INPUT_PORT")] = T_as_string(num_in_port_); - m_num_in_port = num_in_port_; - return; -} - -void OrionConfig::set_num_out_port(uint32_t num_out_port_) -{ - m_params_map[string("NUM_OUTPUT_PORT")] = T_as_string(num_out_port_); - m_num_out_port = num_out_port_; - return; -} - -void OrionConfig::set_num_vclass(uint32_t num_vclass_) -{ - m_params_map[string("NUM_VIRTUAL_CLASS")] = T_as_string(num_vclass_); - m_num_vclass = num_vclass_; - return; -} - -void OrionConfig::set_num_vchannel(uint32_t num_vchannel_) -{ - m_params_map[string("NUM_VIRTUAL_CHANNEL")] = T_as_string(num_vchannel_); - m_num_vchannel = num_vchannel_; - return; -} - -void OrionConfig::set_in_buf_num_set(uint32_t in_buf_num_set_) -{ - m_params_map[string("IN_BUF_NUM_SET")] = T_as_string(in_buf_num_set_); - m_in_buf_num_set = in_buf_num_set_; - return; -} - -void OrionConfig::set_flit_width(uint32_t flit_width_) -{ - m_params_map[string("FLIT_WIDTH")] = T_as_string(flit_width_); - m_flit_width = flit_width_; - return; -} - -void OrionConfig::read_file( - const string& filename_ - ) -{ - ConfigFile cfg_file(filename_); - - uint32_t num_param = sizeof(ms_param_name)/sizeof(string); - for(uint32_t i = 0; i < num_param; i++) - { - cfg_file.readInto(m_params_map[ms_param_name[i]], ms_param_name[i]); - } - - m_num_in_port = get("NUM_INPUT_PORT"); - m_num_out_port = get("NUM_OUTPUT_PORT"); - m_num_vclass = get("NUM_VIRTUAL_CLASS"); - m_num_vchannel = get("NUM_VIRTUAL_CHANNEL"); - m_in_buf_num_set = get("IN_BUF_NUM_SET"); - m_flit_width = get("FLIT_WIDTH"); - return; -} - -void OrionConfig::print_config(ostream& out_) -{ - uint32_t num_param = sizeof(ms_param_name)/sizeof(string); - - for(uint32_t i = 0; i < num_param; i++) - { - out_ << ms_param_name[i] << " = " << m_params_map[ms_param_name[i]] << endl; - } - return; -} - diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/OrionLink.hh --- a/src/mem/ruby/network/orion/OrionLink.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#ifndef __ORIONLINK_H__ -#define __ORIONLINK_H__ - -#include "mem/ruby/network/orion/Type.hh" - -class TechParameter; -class OrionConfig; - -class OrionLink -{ - public: - OrionLink( - double len_, - uint32_t line_width_, - const OrionConfig* orion_cfg_ptr_ - ); - ~OrionLink(); - - public: - double calc_dynamic_energy(uint32_t num_bit_flip_) const; - double get_static_power() const; - - void print() const; - - private: - void init(); - - private: - double m_len; - uint32_t m_line_width; - const OrionConfig* m_orion_cfg_ptr; - - double m_dynamic_energy_per_bit; - double m_static_power_per_bit; -}; - -#endif diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/OrionLink.cc --- a/src/mem/ruby/network/orion/OrionLink.cc Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#include -#include - -#include "mem/ruby/network/orion/OrionConfig.hh" -#include "mem/ruby/network/orion/OrionLink.hh" -#include "mem/ruby/network/orion/Wire.hh" - -using namespace std; - -OrionLink::OrionLink( - double len_, - uint32_t line_width_, - const OrionConfig* orion_cfg_ptr_ -) -{ - assert(len_ == len_); - assert(line_width_ == line_width_); - - m_len = len_; - m_line_width = line_width_; - m_orion_cfg_ptr = orion_cfg_ptr_; - - init(); -} - -OrionLink::~OrionLink() -{} - -double OrionLink::calc_dynamic_energy(uint32_t num_bit_flip_) const -{ - assert(num_bit_flip_ <= m_line_width); - return (num_bit_flip_*(m_dynamic_energy_per_bit/2)); -} - -double OrionLink::get_static_power() const -{ - return (m_line_width*m_static_power_per_bit); -} - -void OrionLink::init() -{ - const TechParameter* tech_param_ptr = m_orion_cfg_ptr->get_tech_param_ptr(); - - const string& width_spacing_model_str = m_orion_cfg_ptr->get("WIRE_WIDTH_SPACING"); - const string& buf_scheme_str = m_orion_cfg_ptr->get("WIRE_BUFFERING_MODEL"); - bool is_shielding = m_orion_cfg_ptr->get("WIRE_IS_SHIELDING"); - Wire wire(width_spacing_model_str, buf_scheme_str, is_shielding, tech_param_ptr); - - m_dynamic_energy_per_bit = wire.calc_dynamic_energy(m_len); - m_static_power_per_bit = wire.calc_static_power(m_len); - return; -} - -void OrionLink::print() const -{ - cout << "Link - Dynamic Energy" << endl; - cout << "\t" << "One Bit = " << calc_dynamic_energy(1) << endl; - cout << endl; - cout << "Link - Static Power" << endl; - cout << "\t" << "One Bit = " << get_static_power() << endl; - cout << endl; - return; -} diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/OrionRouter.hh --- a/src/mem/ruby/network/orion/OrionRouter.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#ifndef __ORIONROUTER_H__ -#define __ORIONROUTER_H__ - -#include - -#include "mem/ruby/network/orion/Type.hh" - -class OrionConfig; -class Buffer; -class Crossbar; -class VCAllocator; -class SWAllocator; -class Clock; - -class OrionRouter -{ - public: - OrionRouter( - const OrionConfig* orion_cfg_ptr_ - ); - - //values in cfg file will be modified - OrionRouter( - uint32_t num_in_port_, - uint32_t num_out_port_, - uint32_t num_vclass_, - std::vector vclass_type_, - uint32_t num_vc_per_vclass_, - uint32_t in_buf_per_data_vc_, - uint32_t in_buf_per_ctrl_vc_, - uint32_t flit_width_, - OrionConfig* orion_cfg_ptr_ - ); - ~OrionRouter(); - - public: - //double calc_dynamic_energy(double e_fin_, bool is_max_ = false) const; - //double calc_dynamic_energy_in_buf(bool is_read_, bool is_max_ = false) const; - //double calc_dynamic_energy_out_buf(bool is_read_, bool is_max_ = false) const; - double calc_dynamic_energy_buf(uint32_t vclass_id_, bool is_read_, bool is_max_ = false) const; - double calc_dynamic_energy_xbar(bool is_max_ = false) const; - double calc_dynamic_energy_local_vc_arb(uint32_t vclass_id_, double num_req_, bool is_max_ = false) const; - double calc_dynamic_energy_global_vc_arb(uint32_t vclass_id_, double num_req_, bool is_max_ = false) const; - //double calc_dynamic_energy_vc_select(uint32_t vclass_id_, bool is_read_, bool is_max_ = false) const; - double calc_dynamic_energy_local_sw_arb(double num_req_, bool is_max_ = false) const; - double calc_dynamic_energy_global_sw_arb(double num_req_, bool is_max_ = false) const; - double calc_dynamic_energy_clock() const; - - double get_static_power_buf() const; - double get_static_power_xbar() const; - double get_static_power_va() const; - double get_static_power_sa() const; - double get_static_power_clock() const; - - void print() const; - - void init(); - - private: - const OrionConfig* m_orion_cfg_ptr; - - uint32_t m_num_in_port; - uint32_t m_num_out_port; - uint32_t m_flit_width; - uint32_t m_num_vclass; - uint32_t num_vc_per_vclass_; - uint32_t m_total_num_vc; - uint32_t* m_num_vc_per_vclass_ary; - uint32_t* m_in_buf_num_set_ary; - bool m_is_in_shared_buf; - bool m_is_out_shared_buf; - bool m_is_in_shared_switch; - bool m_is_out_shared_switch; - - Buffer** m_in_buf_ary_ptr; - Crossbar* m_xbar_ptr; - VCAllocator** m_va_ary_ptr; - //VCAllocator** m_vc_select_ary_ptr; - SWAllocator* m_sa_ptr; - Clock* m_clk_ptr; -}; - -#endif - diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/OrionRouter.cc --- a/src/mem/ruby/network/orion/OrionRouter.cc Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,497 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#include - -#include "mem/ruby/network/orion/Allocator/SWAllocator.hh" -#include "mem/ruby/network/orion/Allocator/VCAllocator.hh" -#include "mem/ruby/network/orion/Buffer/Buffer.hh" -#include "mem/ruby/network/orion/Crossbar/Crossbar.hh" -#include "mem/ruby/network/orion/Clock.hh" -#include "mem/ruby/network/orion/OrionConfig.hh" -#include "OrionRouter.hh" - -using namespace std; - -OrionRouter::OrionRouter( - uint32_t num_in_port_, - uint32_t num_out_port_, - uint32_t num_vclass_, - std::vector vclass_type_ary_, - uint32_t num_vc_per_vclass_, - uint32_t in_buf_per_data_vc_, - uint32_t in_buf_per_ctrl_vc_, - uint32_t flit_width_, - OrionConfig* orion_cfg_ptr_ -) -{ - assert((num_in_port_ == num_in_port_) && (num_in_port_ != 0)); - assert((num_out_port_ == num_out_port_) && (num_out_port_ != 0)); - assert((num_vclass_ == num_vclass_) && (num_vclass_ != 0)); - assert((num_vc_per_vclass_ == num_vc_per_vclass_) && (num_vc_per_vclass_ != 0)); - assert(in_buf_per_data_vc_ != 0); - assert(in_buf_per_ctrl_vc_ != 0); - assert((flit_width_ == flit_width_) && (flit_width_ != 0)); - - orion_cfg_ptr_->set_num_in_port(num_in_port_); - orion_cfg_ptr_->set_num_out_port(num_out_port_); - orion_cfg_ptr_->set_num_vclass(num_vclass_); - orion_cfg_ptr_->set_flit_width(flit_width_); - m_orion_cfg_ptr = orion_cfg_ptr_; - - m_num_in_port = m_orion_cfg_ptr->get("NUM_INPUT_PORT"); - m_num_out_port = m_orion_cfg_ptr->get("NUM_OUTPUT_PORT"); - m_flit_width = m_orion_cfg_ptr->get("FLIT_WIDTH"); - m_num_vclass = m_orion_cfg_ptr->get("NUM_VIRTUAL_CLASS"); - - m_num_vc_per_vclass_ary = new uint32_t [m_num_vclass]; - m_in_buf_num_set_ary = new uint32_t [m_num_vclass]; - for (int i = 0; i < m_num_vclass; i++) - { - // can also suppport different vcs per vclass - m_num_vc_per_vclass_ary[i] = num_vc_per_vclass_; - - if (vclass_type_ary_[i] == 0) // ctrl - m_in_buf_num_set_ary[i] = in_buf_per_ctrl_vc_; - else if (vclass_type_ary_[i] == 1) // data - m_in_buf_num_set_ary[i] = in_buf_per_data_vc_; - else - assert(0); - } - - init(); -} - -OrionRouter::~OrionRouter() -{ - delete[] m_num_vc_per_vclass_ary; - delete[] m_in_buf_num_set_ary; - - if (m_in_buf_ary_ptr) - { - for (uint32_t i = 0; i < m_num_vclass; i++) - { - delete m_in_buf_ary_ptr[i]; - } - delete[] m_in_buf_ary_ptr; - } - - if (m_va_ary_ptr) - { - for (uint32_t i = 0; i < m_num_vclass; i++) - { - delete m_va_ary_ptr[i]; - } - delete[] m_va_ary_ptr; - } - - delete m_xbar_ptr; - delete m_sa_ptr; - delete m_clk_ptr; -} - -double OrionRouter::calc_dynamic_energy_buf(uint32_t vclass_id_, bool is_read_, bool is_max_) const -{ - assert(vclass_id_ < m_num_vclass); - if (m_in_buf_ary_ptr) - { - if (m_in_buf_ary_ptr[vclass_id_]) - { - return m_in_buf_ary_ptr[vclass_id_]->get_dynamic_energy(is_read_, is_max_); - } - else - { - return 0; - } - } - else - { - return 0; - } -} - -double OrionRouter::calc_dynamic_energy_xbar(bool is_max_) const -{ - if (m_xbar_ptr) - { - return m_xbar_ptr->get_dynamic_energy(is_max_); - } - else - { - return 0; - } -} - -double OrionRouter::calc_dynamic_energy_local_vc_arb(uint32_t vclass_id_, double num_req_, bool is_max_) const -{ - assert(vclass_id_ < m_num_vclass); - - if (m_va_ary_ptr) - { - if (m_va_ary_ptr[vclass_id_]) - { - return m_va_ary_ptr[vclass_id_]->get_dynamic_energy_local_vc_arb(num_req_, is_max_); - } - else - { - return 0; - } - } - else - { - return 0; - } -} - -double OrionRouter::calc_dynamic_energy_global_vc_arb(uint32_t vclass_id_, double num_req_, bool is_max_) const -{ - assert(vclass_id_ < m_num_vclass); - - if (m_va_ary_ptr) - { - if (m_va_ary_ptr[vclass_id_]) - { - return m_va_ary_ptr[vclass_id_]->get_dynamic_energy_global_vc_arb(num_req_, is_max_); - } - else - { - return 0; - } - } - else - { - return 0; - } -} - -//double OrionRouter::calc_dynamic_energy_vc_select(bool is_read_, bool is_max_) const -//{ -// if (m_vc_select_ptr) -// { -// return m_vc_select_ptr->get_dynamic_energy_vc_select(is_read_, is_max_); -// } -// else -// { -// return 0; -// } -//} - -double OrionRouter::calc_dynamic_energy_local_sw_arb(double num_req_, bool is_max_) const -{ - if (m_sa_ptr) - { - return m_sa_ptr->get_dynamic_energy_local_sw_arb(num_req_, is_max_); - } - else - { - return 0; - } -} - -double OrionRouter::calc_dynamic_energy_global_sw_arb(double num_req_, bool is_max_) const -{ - if (m_sa_ptr) - { - return m_sa_ptr->get_dynamic_energy_global_sw_arb(num_req_, is_max_); - } - else - { - return 0; - } -} - -double OrionRouter::calc_dynamic_energy_clock() const -{ - if (m_clk_ptr) - { - return m_clk_ptr->get_dynamic_energy(); - } - else - { - return 0; - } -} - -double OrionRouter::get_static_power_buf() const -{ - if (m_in_buf_ary_ptr) - { - double total_static_power = 0; - - for (uint32_t i = 0; i < m_num_vclass; i++) - { - uint32_t num_in_buf; - if (m_is_in_shared_buf) - { - num_in_buf = m_num_in_port; - } - else - { - num_in_buf = m_num_vc_per_vclass_ary[i]*m_num_in_port; - } - total_static_power += m_in_buf_ary_ptr[i]->get_static_power()*(double)num_in_buf; - } - return total_static_power; - } - else - { - return 0; - } -} - -double OrionRouter::get_static_power_xbar() const -{ - if (m_xbar_ptr) - { - return m_xbar_ptr->get_static_power(); - } - else - { - return 0; - } -} - -double OrionRouter::get_static_power_va() const -{ - if (m_va_ary_ptr) - { - double total_static_power = 0; - - for (uint32_t i = 0; i < m_num_vclass; i++) - { - total_static_power += m_va_ary_ptr[i]->get_static_power(); - } - return total_static_power; - } - else - { - return 0; - } -} - -//double OrionRouter::get_static_power_vc_select() const -//{ -// if (m_vc_select_ptr) -// { -// return m_vc_select_ptr->get_static_power(); -// } -// else -// { -// return 0; -// } -//} - -double OrionRouter::get_static_power_sa() const -{ - if (m_sa_ptr) - { - return m_sa_ptr->get_static_power(); - } - else - { - return 0; - } -} - -double OrionRouter::get_static_power_clock() const -{ - if (m_clk_ptr) - { - return m_clk_ptr->get_static_power(); - } - else - { - return 0; - } -} - -void OrionRouter::init() -{ - m_total_num_vc = 0; - for (uint32_t i = 0; i < m_num_vclass; i++) - { - m_total_num_vc += m_num_vc_per_vclass_ary[i]; - } - - if (m_total_num_vc > 1) - { - m_is_in_shared_buf = m_orion_cfg_ptr->get("IS_IN_SHARED_BUFFER"); - m_is_out_shared_buf = m_orion_cfg_ptr->get("IS_OUT_SHARED_BUFFER"); - m_is_in_shared_switch = m_orion_cfg_ptr->get("IS_IN_SHARED_SWITCH"); - m_is_out_shared_switch = m_orion_cfg_ptr->get("IS_OUT_SHARED_SWITCH"); - } - else - { - m_is_in_shared_buf = false; - m_is_out_shared_buf = false; - m_is_in_shared_switch = false; - m_is_out_shared_switch = false; - } - - //input buffer - bool is_in_buf = m_orion_cfg_ptr->get("IS_INPUT_BUFFER"); - if (is_in_buf) - { - bool is_fifo = true; - bool is_outdrv = (!m_is_in_shared_buf) && (m_is_in_shared_switch); - const string& in_buf_model_str = m_orion_cfg_ptr->get("IN_BUF_MODEL"); - m_in_buf_ary_ptr = new Buffer* [m_num_vclass]; - for (uint32_t i = 0; i < m_num_vclass; i++) - { - uint32_t in_buf_num_read_port = m_orion_cfg_ptr->get("IN_BUF_NUM_READ_PORT"); - uint32_t in_buf_num_set = m_in_buf_num_set_ary[i]; - m_in_buf_ary_ptr[i] = new Buffer(in_buf_model_str, is_fifo, is_outdrv, - in_buf_num_set, m_flit_width, in_buf_num_read_port, 1, m_orion_cfg_ptr); - } - } - else - { - m_in_buf_ary_ptr = NULL; - } - - bool is_out_buf = m_orion_cfg_ptr->get("IS_OUTPUT_BUFFER"); - - //crossbar - uint32_t num_switch_in; - if (is_in_buf) - { - if (m_is_in_shared_buf) - { - uint32_t in_buf_num_read_port = m_orion_cfg_ptr->get("IN_BUF_NUM_READ_PORT"); - num_switch_in = in_buf_num_read_port*m_num_in_port; - } - else if (m_is_in_shared_switch) - { - num_switch_in = 1*m_num_in_port; - } - else - { - num_switch_in = m_total_num_vc*m_num_in_port; - } - } - else - { - num_switch_in = 1*m_num_in_port; - } - uint32_t num_switch_out; - if (is_out_buf) - { - if (m_is_out_shared_buf) - { - uint32_t out_buf_num_write_port = m_orion_cfg_ptr->get("OUT_BUF_NUM_WRITE_PORT"); - num_switch_out = out_buf_num_write_port*m_num_out_port; - } - else if (m_is_out_shared_switch) - { - num_switch_out = 1*m_num_out_port; - } - else - { - num_switch_out = m_total_num_vc*m_num_out_port; - } - } - else - { - num_switch_out = 1*m_num_out_port; - } - const string& xbar_model_str = m_orion_cfg_ptr->get("CROSSBAR_MODEL"); - m_xbar_ptr = Crossbar::create_crossbar(xbar_model_str, - num_switch_in, num_switch_out, m_flit_width, m_orion_cfg_ptr); - - //vc allocator - const string& va_model_str = m_orion_cfg_ptr->get("VA_MODEL"); - m_va_ary_ptr = new VCAllocator* [m_num_vclass]; - //m_vc_select_ary_ptr = new VCAllocator* [m_num_vclass]; - for (uint32_t i = 0; i < m_num_vclass; i++) - { - m_va_ary_ptr[i] = VCAllocator::create_vcallocator(va_model_str, - m_num_in_port, m_num_out_port, 1, m_num_vc_per_vclass_ary[i], - m_orion_cfg_ptr); - //m_vc_select_ary_ptr[i] = VCAllocator::create_vcallocator("VC_SELECT", - // m_num_in_port, m_num_out_port, 1, m_num_vc_per_vclass_ary[i], m_orion_cfg_ptr); - } - - //sw allocator - m_sa_ptr = SWAllocator::create_swallocator( - m_num_in_port, m_num_out_port, 1, m_total_num_vc, - m_xbar_ptr, m_orion_cfg_ptr); - - //cloc - m_clk_ptr = new Clock(is_in_buf, m_is_in_shared_switch, is_out_buf, m_is_out_shared_switch, m_orion_cfg_ptr); - - return; -} - -void OrionRouter::print() const -{ - if (m_in_buf_ary_ptr) - { - for (uint32_t i = 0; i < m_num_vclass; i++) - { - cout << "VClass " << i << endl; - if (m_in_buf_ary_ptr[i]) m_in_buf_ary_ptr[i]->print_all(); - } - } - m_xbar_ptr->print_all(); - for (uint32_t i = 0; i < m_num_vclass; i++) - { - cout << "VClass " << i << endl; - m_va_ary_ptr[i]->print_all(); - //m_vc_select_ary_ptr[i]->print_all(); - } - m_sa_ptr->print_all(); - - //cout << "Router - Dynamic Energy" << endl; - //cout << "\t" << "Buffer Read = " << calc_dynamic_energy_buf(true) << endl; - //cout << "\t" << "Buffer Write = " << calc_dynamic_energy_buf(false) << endl; - //cout << "\t" << "Crossbar = " << calc_dynamic_energy_xbar() << endl; - //cout << "\t" << "Local VC Allocator(1) = " << calc_dynamic_energy_local_vc_arb(1) << endl; - //cout << "\t" << "Global VC Allocator(1) = " << calc_dynamic_energy_global_vc_arb(1) << endl; - //cout << "\t" << "VC Select Read = " << calc_dynamic_energy_vc_select(true) << endl; - //cout << "\t" << "VC Select Write = " << calc_dynamic_energy_vc_select(false) << endl; - //cout << "\t" << "Local SW Allocator(2) = " << calc_dynamic_energy_local_sw_arb(1) << endl; - //cout << "\t" << "Global SW Allocator(2) = " << calc_dynamic_energy_global_sw_arb(1) << endl; - //cout << "\t" << "Clock = " << calc_dynamic_energy_clock() << endl; - //cout << endl; - //cout << "Router - Static Power" << endl; - //cout << "\t" << "Buffer = " << get_static_power_buf() << endl; - //cout << "\t" << "Crossbar = " << get_static_power_xbar() << endl; - //cout << "\t" << "VC Allocator = " << get_static_power_va() << endl; - //cout << "\t" << "SW Allocator = " << get_static_power_sa() << endl; - //cout << "\t" << "Clock = " << get_static_power_clock() << endl; - //cout << endl; - return; -} - diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/SConscript --- a/src/mem/ruby/network/orion/SConscript Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -# 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. -# -# Authors: Tushar Krishna - -Import('*') - -if env['PROTOCOL'] == 'None': - Return() - -Source('NetworkPower.cc') -Source('Clock.cc') -Source('ConfigFile.cc') -Source('FlipFlop.cc') -Source('OrionConfig.cc') -Source('OrionLink.cc') -Source('OrionRouter.cc') -Source('TechParameter.cc') -Source('Wire.cc') diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/TechParameter.hh --- a/src/mem/ruby/network/orion/TechParameter.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,412 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#ifndef __TECHPARAMETER_H__ -#define __TECHPARAMETER_H__ - -#include - -#include "mem/ruby/network/orion/Type.hh" - -class OrionConfig; - -class TechParameter -{ - public: - enum TransistorType - { - LVT = 0, - NVT, - HVT, - NUM_TRANSISTOR_TYPE - }; - enum WireLayerType - { - LOCAL = 0, - INTERMEDIATE, - GLOBAL, - NUM_WIRE_LAYER_TYPE - }; - enum ChannelType - { - NCH, - PCH - }; - - public: - TechParameter(const OrionConfig* orion_cfg_ptr_); - ~TechParameter(); - - public: - double calc_gatecap(double width_, double wirelength_) const; - double calc_gatecappass(double width_, double wirelength_) const; - double calc_draincap(double width_, ChannelType ch_, uint32_t num_stack_) const; - double calc_restowidth(double res_, ChannelType ch_) const; - double calc_driver_psize(double cap_, double rise_time_) const; - - public: - bool is_trans_type_hvt() const { return (m_transistor_type == HVT); } - bool is_trans_type_nvt() const { return (m_transistor_type == NVT); } - bool is_trans_type_lvt() const { return (m_transistor_type == LVT); } - double get_tech_node() const { return m_tech_node; } - double get_vdd() const { return m_vdd; } - double get_freq() const { return m_freq; } - double get_period() const { return m_period; } - double get_amp_idsat() const { return m_amp_idsat; } - - double get_SCALE_S() const { return m_SCALE_S; } - double get_MSCALE() const { return m_MSCALE; } - - double get_Lamda() const { return m_Lamda; } - - double get_Cmetal() const { return m_Cmetal; } - double get_CM2metal() const { return m_CM2metal; } - double get_CM3metal() const { return m_CM3metal; } - double get_CCmetal() const { return m_CCmetal; } - double get_CCM2metal() const { return m_CCM2metal; } - double get_CCM3metal() const { return m_CCM3metal; } - double get_CC2metal() const { return m_CC2metal; } - double get_CC2M2metal() const { return m_CC2M2metal; } - double get_CC2M3metal() const { return m_CC2M3metal; } - double get_CC3metal() const { return m_CC3metal; } - double get_CC3M2metal() const { return m_CC3M2metal; } - double get_CC3M3metal() const { return m_CC3M3metal; } - - double get_EnergyFactor() const { return m_EnergyFactor; } - double get_SenseEnergyFactor() const { return m_SenseEnergyFactor; } - - double get_Woutdrvseln() const { return m_Woutdrvseln; } - double get_Woutdrvselp() const { return m_Woutdrvselp; } - double get_Woutdrvnandn() const { return m_Woutdrvnandn; } - double get_Woutdrvnandp() const { return m_Woutdrvnandp; } - double get_Woutdrvnorn() const { return m_Woutdrvnorn; } - double get_Woutdrvnorp() const { return m_Woutdrvnorp; } - double get_Woutdrivern() const { return m_Woutdrivern; } - double get_Woutdriverp() const { return m_Woutdriverp; } - - double get_WsenseQ1to4() const { return m_WsenseQ1to4; } - double get_Wbitmuxn() const { return m_Wbitmuxn; } - double get_Wmemcellr() const { return m_Wmemcellr; } - double get_Wmemcellw() const { return m_Wmemcellw; } - double get_Wmemcella() const { return m_Wmemcella; } - double get_Wmemcellbscale() const { return m_Wmemcellbscale; } - - double get_RegCellHeight() const { return m_RegCellHeight; } - double get_RegCellWidth() const { return m_RegCellWidth; } - double get_WordlineSpacing() const { return m_WordlineSpacing; } - double get_BitlineSpacing() const { return m_BitlineSpacing; } - double get_BitWidth() const { return m_BitWidth; } - - double get_Wdecinvn() const { return m_Wdecinvn; } - double get_Wdecinvp() const { return m_Wdecinvp; } - double get_Wdec3to8n() const { return m_Wdec3to8n; } - double get_Wdec3to8p() const { return m_Wdec3to8p; } - double get_WdecNORn() const { return m_WdecNORn; } - double get_WdecNORp() const { return m_WdecNORp; } - double get_Wdecdriven() const { return m_Wdecdriven; } - double get_Wdecdrivep() const { return m_Wdecdrivep; } - - double get_CrsbarCellWidth() const { return m_CrsbarCellWidth; } - double get_CrsbarCellHeight() const { return m_CrsbarCellHeight; } - - double get_Wdff() const { return m_Wdff; } - - double get_WireMinWidth() const { return m_WireMinWidth; } - double get_WireMinSpacing() const { return m_WireMinSpacing; } - double get_WireBarrierThickness() const { return m_WireBarrierThickness; } - double get_WireMetalThickness() const { return m_WireMetalThickness; } - double get_WireDielectricThickness() const { return m_WireDielectricThickness; } - double get_WireDielectricConstant() const { return m_WireDielectricConstant; } - double get_BufferDriveResistance() const { return m_BufferDriveResistance; } - double get_BufferInputCapacitance() const { return m_BufferInputCapacitance; } - double get_BufferNMOSOffCurrent() const { return m_BufferNMOSOffCurrent; } - double get_BufferPMOSOffCurrent() const { return m_BufferPMOSOffCurrent; } - double get_ClockCap() const { return m_ClockCap; } - double get_Clockwire() const { return m_Clockwire; } - double get_Reswire() const { return m_Reswire; } - - double get_NMOS_TAB(uint32_t idx) const { return m_NMOS_TAB[idx]; } - double get_PMOS_TAB(uint32_t idx) const { return m_PMOS_TAB[idx]; } - double get_NAND2_TAB(uint32_t idx) const { return m_NAND2_TAB[idx]; } - double get_NOR2_TAB(uint32_t idx) const { return m_NOR2_TAB[idx]; } - double get_DFF_TAB(uint32_t idx) const { return m_DFF_TAB[idx]; } - - private: - void init(); - void init_tech_110_800(); - void init_tech_32_90(); - void init_tech_90(); - - private: - const OrionConfig* m_orion_cfg_ptr; - unsigned int m_tech_node; - TransistorType m_transistor_type; - double m_vdd; - double m_freq; - double m_period; - WireLayerType m_wire_layer_type; - - double m_af; - uint32_t m_max_n; - uint32_t m_max_subarrays; - uint32_t m_max_spd; - double m_vth_outdr_nor; - double m_vth_comp_inv; - uint32_t m_bit_out; - uint32_t m_ruu_issue_width; - double m_amp_idsat; - double m_vs_inv; - double m_gen_power_factor; - double m_vth_nand_60x90; - double m_fudge_factor; - double m_vth_outdrive; - double m_vth_muxdrv1; - double m_vth_muxdrv2; - double m_normalize_scale; - double m_vth_muxdrv3; - uint32_t m_address_bits; - uint32_t m_ruu_size; - double m_vth_nor_12x4x1; - double m_vth_nor_12x4x2; - double m_vth_outdr_inv; - double m_vth_nor_12x4x3; - double m_vth_eval_inv; - double m_vth_nor_12x4x4; - uint32_t m_res_ialu; - double m_vth_outdr_nand; - double m_vth_inv_100x60; - - double m_Cpdiffarea; - double m_Cpdiffside; - double m_Cpoverlap; - double m_Cndiffarea; - double m_Cndiffside; - double m_Cnoverlap; - double m_Cgatepass; - double m_Cgate; - double m_Cpdiffovlp; - double m_Cndiffovlp; - double m_Cpoxideovlp; - double m_Cnoxideovlp; - - double m_Vbitpre; - double m_Vbitsense; - double m_EnergyFactor; - double m_SenseEnergyFactor; - double m_SenseEnergyFactor3; - double m_SenseEnergyFactor2; - - double m_SCALE_T; - double m_SCALE_M; - double m_SCALE_S; - double m_SCALE_W; - double m_SCALE_H; - double m_SCALE_BW; - double m_SCALE_Crs; - - double m_LSCALE; - double m_MSCALE; - - double m_BitWidth; - double m_BitHeight; - double m_BitlineSpacing; - double m_WordlineSpacing; - - double m_RegCellWidth; - double m_RegCellHeight; - - double m_Cout; - - double m_Cwordmetal; - double m_Cbitmetal; - - double m_Cmetal; - double m_CM2metal; - double m_CM3metal; - - double m_CCmetal; - double m_CCM2metal; - double m_CCM3metal; - - double m_CC2metal; - double m_CC2M2metal; - double m_CC2M3metal; - - double m_CC3metal; - double m_CC3M2metal; - double m_CC3M3metal; - - double m_Clockwire; - double m_Reswire; - double m_invCap; - double m_Resout; - - double m_Leff; - double m_Lamda; - - double m_Cpolywire; - - double m_Rnchannelstatic; - double m_Rpchannelstatic; - - double m_Rnchannelon; - double m_Rpchannelon; - - double m_Rbitmetal; - double m_Rwordmetal; - - double m_Vt; - - double m_Wdecdrivep; - double m_Wdecdriven; - double m_Wdec3to8n; - double m_Wdec3to8p; - double m_WdecNORn; - double m_WdecNORp; - double m_Wdecinvn; - double m_Wdecinvp; - double m_Wdff; - - double m_Wworddrivemax; - double m_Wmemcella; - double m_Wmemcellr; - double m_Wmemcellw; - double m_Wmemcellbscale; - double m_Wbitpreequ; - - double m_Wbitmuxn; - double m_WsenseQ1to4; - double m_Wcompinvp1; - double m_Wcompinvn1; - double m_Wcompinvp2; - double m_Wcompinvn2; - double m_Wcompinvp3; - double m_Wcompinvn3; - double m_Wevalinvp; - double m_Wevalinvn; - - double m_Wcompn; - double m_Wcompp; - double m_Wcomppreequ; - double m_Wmuxdrv12n; - double m_Wmuxdrv12p; - double m_WmuxdrvNANDn; - double m_WmuxdrvNANDp; - double m_WmuxdrvNORn; - double m_WmuxdrvNORp; - double m_Wmuxdrv3n; - double m_Wmuxdrv3p; - double m_Woutdrvseln; - double m_Woutdrvselp; - double m_Woutdrvnandn; - double m_Woutdrvnandp; - double m_Woutdrvnorn; - double m_Woutdrvnorp; - double m_Woutdrivern; - double m_Woutdriverp; - double m_Wbusdrvn; - double m_Wbusdrvp; - - double m_Wcompcellpd2; - double m_Wcompdrivern; - double m_Wcompdriverp; - double m_Wcomparen2; - double m_Wcomparen1; - double m_Wmatchpchg; - double m_Wmatchinvn; - double m_Wmatchinvp; - double m_Wmatchnandn; - double m_Wmatchnandp; - double m_Wmatchnorn; - double m_Wmatchnorp; - - double m_WSelORn; - double m_WSelORprequ; - double m_WSelPn; - double m_WSelPp; - double m_WSelEnn; - double m_WSelEnp; - - double m_Wsenseextdrv1p; - double m_Wsenseextdrv1n; - double m_Wsenseextdrv2p; - double m_Wsenseextdrv2n; - - double m_CamCellHeight;/*derived from Cacti 5.3 */ - double m_CamCellWidth;/*derived from Cacti 5.3 */ - - double m_MatchlineSpacing; - double m_TaglineSpacing; - - double m_CrsbarCellHeight; - double m_CrsbarCellWidth; - - double m_krise; - double m_tsensedata; - double m_tsensetag; - double m_tfalldata; - double m_tfalltag; - - double m_WireMinWidth; - double m_WireMinSpacing; - double m_WireMetalThickness; - double m_WireBarrierThickness; - double m_WireDielectricThickness; - double m_WireDielectricConstant; - - double m_BufferDriveResistance; - double m_BufferIntrinsicDelay; - double m_BufferInputCapacitance; - double m_BufferPMOSOffCurrent; - double m_BufferNMOSOffCurrent; - double m_ClockCap; - - double m_AreaNOR; - double m_AreaINV; - double m_AreaAND; - double m_AreaDFF; - double m_AreaMUX2; - double m_AreaMUX3; - double m_AreaMUX4; - - double m_NMOS_TAB[1]; - double m_PMOS_TAB[1]; - double m_NAND2_TAB[4]; - double m_NOR2_TAB[4]; - double m_DFF_TAB[1]; -}; - -#endif - diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/TechParameter.cc --- a/src/mem/ruby/network/orion/TechParameter.cc Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1476 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#include -#include -#include -#include - -#include "mem/ruby/network/orion/OrionConfig.hh" -#include "mem/ruby/network/orion/TechParameter.hh" - -using namespace std; - -TechParameter::TechParameter( - const OrionConfig* orion_cfg_ptr_ -) -{ - m_orion_cfg_ptr = orion_cfg_ptr_; - uint32_t tech_node = m_orion_cfg_ptr->get("TECH_NODE"); - switch(tech_node) - { - case 800: - case 400: - case 350: - case 250: - case 180: - case 110: - case 90: - case 65: - case 45: - case 32: - m_tech_node = tech_node; - break; - default: - cerr << "Invalid technology node (" << tech_node << ")" << endl; - exit(1); - } - - const string& transistor_type_str = m_orion_cfg_ptr->get("TRANSISTOR_TYPE"); - if(transistor_type_str == "LVT") - { - m_transistor_type = LVT; - } - else if(transistor_type_str == "NVT") - { - m_transistor_type = NVT; - } - else if(transistor_type_str == "HVT") - { - m_transistor_type = HVT; - } - else - { - cerr << "Invalid transistor type (" << transistor_type_str << ")" << endl; - exit(1); - } - - m_vdd = m_orion_cfg_ptr->get("VDD"); - m_freq = m_orion_cfg_ptr->get("FREQUENCY"); - m_period = 1 / m_freq; - - const string& wire_layer_type_str = m_orion_cfg_ptr->get("WIRE_LAYER_TYPE"); - if (wire_layer_type_str == "LOCAL") - { - m_wire_layer_type = LOCAL; - } - else if (wire_layer_type_str == "INTERMEDIATE") - { - m_wire_layer_type = INTERMEDIATE; - } - else if (wire_layer_type_str == "GLOBAL") - { - m_wire_layer_type = GLOBAL; - } - else - { - cerr << "Invalid wire layer type (" << wire_layer_type_str << ")" << endl; - exit(1); - } - - init(); -} - -TechParameter::~TechParameter() -{} - -void TechParameter::init() -{ - m_af = 5.000000e-01; - m_max_n = 8; - m_max_subarrays = 8; - m_max_spd = 8; - m_vth_outdr_nor = 4.310000e-01; - m_vth_comp_inv = 4.370000e-01; - m_bit_out = 64; - m_ruu_issue_width = 4; - m_amp_idsat = 5.000000e-04; - m_vs_inv = 4.560000e-01; - m_gen_power_factor = 1.310000e+00; - m_vth_nand_60x90 = 5.610000e-01; - m_fudge_factor = 1.000000e+00; - m_vth_outdrive = 4.250000e-01; - m_vth_muxdrv1 = 4.370000e-01; - m_vth_muxdrv2 = 4.860000e-01; - m_normalize_scale = 6.488730e-10; - m_vth_muxdrv3 = 4.370000e-01; - m_address_bits = 64; - m_ruu_size = 16; - m_vth_nor_12x4x1 = 5.030000e-01; - m_vth_nor_12x4x2 = 4.520000e-01; - m_vth_outdr_inv = 4.370000e-01; - m_vth_nor_12x4x3 = 4.170000e-01; - m_vth_eval_inv = 2.670000e-01; - m_vth_nor_12x4x4 = 3.900000e-01; - m_res_ialu = 4; - m_vth_outdr_nand = 4.410000e-01; - m_vth_inv_100x60 = 4.380000e-01; - - if((m_tech_node >= 110)) - { - init_tech_110_800(); - } - else - { - init_tech_32_90(); - } - return; -} - -void TechParameter::init_tech_110_800() -{ - m_Cgatepass = 1.450000e-15; - m_Cpdiffarea = 6.060000e-16; - m_Cpdiffside = 2.400000e-16; - m_Cndiffside = 2.400000e-16; - m_Cndiffarea = 6.600000e-16; - m_Cnoverlap = 1.320000e-16; - m_Cpoverlap = 1.210000e-16; - m_Cgate = 9.040000e-15; - m_Cpdiffovlp = 1.380000e-16; - m_Cndiffovlp = 1.380000e-16; - m_Cnoxideovlp = 2.230000e-16; - m_Cpoxideovlp = 3.380000e-16; - - //TODO -- data not imported - return; -} - -void TechParameter::init_tech_32_90() -{ - switch(m_transistor_type) - { - case LVT: - m_Cgatepass = 1.5225000e-14; - m_Cpdiffarea = 6.05520000e-15; - m_Cpdiffside = 2.38380000e-15; - m_Cndiffside = 2.8500000e-16; - m_Cndiffarea = 5.7420000e-15; - m_Cnoverlap = 1.320000e-16; - m_Cpoverlap = 1.210000e-16; - m_Cgate = 7.8648000e-14; - m_Cpdiffovlp = 1.420000e-16; - m_Cndiffovlp = 1.420000e-16; - m_Cnoxideovlp = 2.580000e-16; - m_Cpoxideovlp = 3.460000e-16; - break; - case NVT: - m_Cgatepass = 8.32500e-15; - m_Cpdiffarea = 3.330600e-15; - m_Cpdiffside = 1.29940000e-15; - m_Cndiffside = 2.5500000e-16; - m_Cndiffarea = 2.9535000e-15; - m_Cnoverlap = 1.270000e-16; - m_Cpoverlap = 1.210000e-16; - m_Cgate = 3.9664000e-14; - m_Cpdiffovlp = 1.31000e-16; - m_Cndiffovlp = 1.310000e-16; - m_Cnoxideovlp = 2.410000e-16; - m_Cpoxideovlp = 3.170000e-16; - break; - case HVT: - m_Cgatepass = 1.45000e-15; - m_Cpdiffarea = 6.06000e-16; - m_Cpdiffside = 2.150000e-16; - m_Cndiffside = 2.25000e-16; - m_Cndiffarea = 1.650000e-16; - m_Cnoverlap = 1.220000e-16; - m_Cpoverlap = 1.210000e-16; - m_Cgate = 6.8000e-16; - m_Cpdiffovlp = 1.20000e-16; - m_Cndiffovlp = 1.20000e-16; - m_Cnoxideovlp = 2.230000e-16; - m_Cpoxideovlp = 2.880000e-16; - break; - default: - cerr << "Invalid transistor type (" << m_transistor_type << ")" << endl; - exit(1); - } - - m_Vbitpre = m_vdd; - m_Vbitsense = 0.08; - m_EnergyFactor = m_vdd*m_vdd; - m_SenseEnergyFactor = m_vdd*m_vdd/2; - m_SenseEnergyFactor2 = (m_Vbitpre-m_Vbitsense)*(m_Vbitpre-m_Vbitsense); - m_SenseEnergyFactor3 = m_Vbitsense*m_Vbitsense; - - if((m_tech_node == 90) || (m_tech_node == 65)) - { - m_SCALE_T = 1; - m_SCALE_M = 1; - m_SCALE_S = 1; - m_SCALE_W = 1; - m_SCALE_H = 1; - m_SCALE_BW = 1; - m_SCALE_Crs = 1; - } - else if(m_tech_node == 45) - { - switch(m_transistor_type) - { - case LVT: - m_SCALE_T = 0.9123404; - m_SCALE_M = 0.6442105; - m_SCALE_S = 2.3352694; - m_SCALE_W = 0.51; - m_SCALE_H = 0.88; - m_SCALE_BW = 0.73; - m_SCALE_Crs = 0.7; - break; - case NVT: - m_SCALE_T = 0.8233582; - m_SCALE_M = 0.6442105; - m_SCALE_S = 2.1860558; - m_SCALE_W = 0.51; - m_SCALE_H = 0.88; - m_SCALE_BW = 0.73; - m_SCALE_Crs = 0.7; - break; - case HVT: - m_SCALE_T = 0.73437604; - m_SCALE_M = 0.6442105; - m_SCALE_S = 2.036842; - m_SCALE_W = 0.51; - m_SCALE_H = 0.88; - m_SCALE_BW = 0.73; - m_SCALE_Crs = 0.7; - break; - default: - cerr << "Invalid transistor type (" << m_transistor_type << ")" << endl; - exit(1); - } - } - else if(m_tech_node == 32) - { - switch(m_transistor_type) - { - case LVT: - m_SCALE_T = 0.7542128; - m_SCALE_M = 0.4863158; - m_SCALE_S = 2.9692334; - m_SCALE_W = 0.26; - m_SCALE_H = 0.77; - m_SCALE_BW = 0.53; - m_SCALE_Crs = 0.49; - break; - case NVT: - m_SCALE_T = 0.6352095; - m_SCALE_M = 0.4863158; - m_SCALE_S = 3.1319851; - m_SCALE_W = 0.26; - m_SCALE_H = 0.77; - m_SCALE_BW = 0.53; - m_SCALE_Crs = 0.49; - break; - case HVT: - m_SCALE_T = 0.5162063; - m_SCALE_M = 0.4863158; - m_SCALE_S = 3.294737; - m_SCALE_W = 0.26; - m_SCALE_H = 0.77; - m_SCALE_BW = 0.53; - m_SCALE_Crs = 0.49; - break; - default: - cerr << "Invalid transistor type (" << m_transistor_type << ")" << endl; - exit(1); - } - } - else - { - cerr << "Invalid technology node (" << m_tech_node << ")" << endl; - exit(1); - } - - if(m_tech_node == 90) - { - m_LSCALE = 0.125; - m_MSCALE = (m_LSCALE * .624 / .2250); - - /* bit width of RAM cell in um */ - m_BitWidth = 2.0; - - /* bit height of RAM cell in um */ - m_BitHeight = 2.0; - - m_Cout = 6.25e-14; - - m_BitlineSpacing = 1.1; - m_WordlineSpacing = 1.1; - - m_RegCellHeight = 2.8; - m_RegCellWidth = 1.9; - - m_Cwordmetal = 1.936e-15; - m_Cbitmetal = 3.872e-15; - - m_Cmetal = m_Cbitmetal/16; - m_CM2metal = m_Cbitmetal/16; - m_CM3metal = m_Cbitmetal/16; - - /* minimal spacing metal cap per unit length */ - m_CCmetal = 0.18608e-15; - m_CCM2metal = 0.18608e-15; - m_CCM3metal = 0.18608e-15; - /* 2x minimal spacing metal cap per unit length */ - m_CC2metal = 0.12529e-15; - m_CC2M2metal = 0.12529e-15; - m_CC2M3metal = 0.12529e-15; - /* 3x minimal spacing metal cap per unit length */ - m_CC3metal = 0.11059e-15; - m_CC3M2metal = 0.11059e-15; - m_CC3M3metal = 0.11059e-15; - - /* corresponds to clock network*/ - m_Clockwire = 404.8e-12; - m_Reswire = 36.66e3; - m_invCap = 3.816e-14; - m_Resout = 213.6; - - /* um */ - m_Leff = 0.1; - /* length unit in um */ - m_Lamda = m_Leff * 0.5; - - /* fF/um */ - m_Cpolywire = 2.6317875e-15; - - /* ohms*um of channel width */ - m_Rnchannelstatic = 3225; - - /* ohms*um of channel width */ - m_Rpchannelstatic = 7650; - - //derived from Cacti 5.3 - switch(m_transistor_type) - { - case LVT: - m_Rnchannelon = 1716; - m_Rpchannelon = 4202; - break; - case NVT: - m_Rnchannelon = 4120; - m_Rpchannelon = 10464; - break; - case HVT: - m_Rnchannelon = 4956; - m_Rpchannelon = 12092; - break; - default: - cerr << "Invalid transistor type (" << m_transistor_type << ")" << endl; - exit(1); - } - - - m_Rbitmetal = 1.38048; - m_Rwordmetal = 0.945536; - - switch(m_transistor_type) - { - case LVT: - m_Vt = 0.237; - break; - case NVT: - m_Vt = 0.307; - break; - case HVT: - m_Vt = 0.482; - break; - default: - cerr << "Invalid transistor type (" << m_transistor_type << ")" << endl; - exit(1); - } - - /* transistor widths in um = as described in Cacti 1.0 tech report, appendix 1;*/ - switch(m_transistor_type) - { - case LVT: - m_Wdecdrivep = 12.50; - m_Wdecdriven = 6.25; - m_Wdec3to8n = 11.25; - m_Wdec3to8p = 7.5; - m_WdecNORn = 0.30; - m_WdecNORp = 1.5; - m_Wdecinvn = 0.63; - m_Wdecinvp = 1.25; - m_Wdff = 12.29; - - m_Wworddrivemax = 12.50; - m_Wmemcella = 0.35; - m_Wmemcellr = 0.50; - m_Wmemcellw = 0.26; - m_Wmemcellbscale = 2; - m_Wbitpreequ = 1.25; - - m_Wbitmuxn = 1.25; - m_WsenseQ1to4 = 0.55; - m_Wcompinvp1 = 1.25; - m_Wcompinvn1 = 0.75; - m_Wcompinvp2 = 2.50; - m_Wcompinvn2 = 1.50; - m_Wcompinvp3 = 5.15; - m_Wcompinvn3 = 3.25; - m_Wevalinvp = 2.50; - m_Wevalinvn = 9.45; - - m_Wcompn = 1.25; - m_Wcompp = 3.75; - m_Wcomppreequ = 5.15; - m_Wmuxdrv12n = 3.75; - m_Wmuxdrv12p = 6.25; - m_WmuxdrvNANDn = 2.50; - m_WmuxdrvNANDp = 10.33; - m_WmuxdrvNORn = 7.33; - m_WmuxdrvNORp = 10.66; - m_Wmuxdrv3n = 24.85; - m_Wmuxdrv3p = 60.25; - m_Woutdrvseln = 1.55; - m_Woutdrvselp = 2.33; - m_Woutdrvnandn = 3.27; - m_Woutdrvnandp = 1.25; - m_Woutdrvnorn = 0.75; - m_Woutdrvnorp = 5.33; - m_Woutdrivern = 6.16; - m_Woutdriverp = 9.77; - m_Wbusdrvn = 6.16; - m_Wbusdrvp = 10.57; - - m_Wcompcellpd2 = 0.33; - m_Wcompdrivern = 50.95; - m_Wcompdriverp = 102.67; - m_Wcomparen2 = 5.13; - m_Wcomparen1 = 2.5; - m_Wmatchpchg = 1.25; - m_Wmatchinvn = 1.33; - m_Wmatchinvp = 2.77; - m_Wmatchnandn = 2.33; - m_Wmatchnandp = 1.76; - m_Wmatchnorn = 2.66; - m_Wmatchnorp = 1.15; - - m_WSelORn = 1.25; - m_WSelORprequ = 5.15; - m_WSelPn = 1.86; - m_WSelPp = 1.86; - m_WSelEnn = 0.63; - m_WSelEnp = 1.25; - - m_Wsenseextdrv1p = 5.15; - m_Wsenseextdrv1n = 3.05; - m_Wsenseextdrv2p = 25.20; - m_Wsenseextdrv2n = 15.65; - break; - case NVT: - m_Wdecdrivep = 11.57; - m_Wdecdriven = 5.74; - m_Wdec3to8n = 10.31; - m_Wdec3to8p = 6.87; - m_WdecNORn = 0.28; - m_WdecNORp = 1.38; - m_Wdecinvn = 0.58; - m_Wdecinvp = 1.15; - m_Wdff = 6.57; - - m_Wworddrivemax = 11.57; - m_Wmemcella = 0.33; - m_Wmemcellr = 0.46; - m_Wmemcellw = 0.24; - m_Wmemcellbscale = 2; - m_Wbitpreequ = 1.15; - - m_Wbitmuxn = 1.15; - m_WsenseQ1to4 = 0.49; - m_Wcompinvp1 = 1.17; - m_Wcompinvn1 = 0.69; - m_Wcompinvp2 = 2.29; - m_Wcompinvn2 = 1.38; - m_Wcompinvp3 = 4.66; - m_Wcompinvn3 = 2.88; - m_Wevalinvp = 2.29; - m_Wevalinvn = 8.89; - - m_Wcompn = 1.15; - m_Wcompp = 3.44; - m_Wcomppreequ = 4.66; - m_Wmuxdrv12n = 3.44; - m_Wmuxdrv12p = 5.74; - m_WmuxdrvNANDn = 2.29; - m_WmuxdrvNANDp = 9.33; - m_WmuxdrvNORn = 6.79; - m_WmuxdrvNORp = 9.49; - m_Wmuxdrv3n = 22.83; - m_Wmuxdrv3p = 55.09; - m_Woutdrvseln = 1.40; - m_Woutdrvselp = 2.21; - m_Woutdrvnandn = 2.89; - m_Woutdrvnandp = 1.15; - m_Woutdrvnorn = 0.69; - m_Woutdrvnorp = 4.75; - m_Woutdrivern = 5.58; - m_Woutdriverp = 9.05; - m_Wbusdrvn = 5.58; - m_Wbusdrvp = 9.45; - - m_Wcompcellpd2 = 0.29; - m_Wcompdrivern = 46.28; - m_Wcompdriverp = 92.94; - m_Wcomparen2 = 4.65; - m_Wcomparen1 = 2.29; - m_Wmatchpchg = 1.15; - m_Wmatchinvn = 1.19; - m_Wmatchinvp = 2.43; - m_Wmatchnandn = 2.21; - m_Wmatchnandp = 1.42; - m_Wmatchnorn = 2.37; - m_Wmatchnorp = 1.10; - - m_WSelORn = 1.15; - m_WSelORprequ = 4.66; - m_WSelPn = 1.45; - m_WSelPp = 1.71; - m_WSelEnn = 0.58; - m_WSelEnp = 1.15; - - m_Wsenseextdrv1p = 4.66; - m_Wsenseextdrv1n = 2.78; - m_Wsenseextdrv2p = 23.02; - m_Wsenseextdrv2n = 14.07; - break; - case HVT: - m_Wdecdrivep = 10.64; - m_Wdecdriven = 5.23; - m_Wdec3to8n = 9.36; - m_Wdec3to8p = 6.24; - m_WdecNORn = 0.25; - m_WdecNORp = 1.25; - m_Wdecinvn = 0.52; - m_Wdecinvp = 1.04; - m_Wdff = 5.43; - - m_Wworddrivemax = 10.64; - m_Wmemcella = 0.25; - m_Wmemcellr = 0.42; - m_Wmemcellw = 0.22; - m_Wmemcellbscale = 2; - m_Wbitpreequ = 1.04; - - m_Wbitmuxn = 1.04; - m_WsenseQ1to4 = 0.42; - m_Wcompinvp1 = 1.08; - m_Wcompinvn1 = 0.62; - m_Wcompinvp2 = 2.08; - m_Wcompinvn2 = 1.25; - m_Wcompinvp3 = 4.16; - m_Wcompinvn3 = 2.50; - m_Wevalinvp = 2.08; - m_Wevalinvn = 8.32; - - m_Wcompn = 1.04; - m_Wcompp = 3.12; - m_Wcomppreequ = 4.16; - m_Wmuxdrv12n = 3.12; - m_Wmuxdrv12p = 5.23; - m_WmuxdrvNANDn = 2.08; - m_WmuxdrvNANDp = 8.32; - m_WmuxdrvNORn = 6.24; - m_WmuxdrvNORp = 8.32; - m_Wmuxdrv3n = 20.80; - m_Wmuxdrv3p = 49.92; - m_Woutdrvseln = 1.25; - m_Woutdrvselp = 2.08; - m_Woutdrvnandn = 2.50; - m_Woutdrvnandp = 1.04; - m_Woutdrvnorn = 0.62; - m_Woutdrvnorp = 4.16; - m_Woutdrivern = 4.99; - m_Woutdriverp = 8.32; - m_Wbusdrvn = 4.99; - m_Wbusdrvp = 8.32; - - m_Wcompcellpd2 = 0.25; - m_Wcompdrivern = 41.60; - m_Wcompdriverp = 83.20; - m_Wcomparen2 = 4.16; - m_Wcomparen1 = 2.08; - m_Wmatchpchg = 1.04; - m_Wmatchinvn = 1.04; - m_Wmatchinvp = 2.08; - m_Wmatchnandn = 2.08; - m_Wmatchnandp = 1.08; - m_Wmatchnorn = 2.08; - m_Wmatchnorp = 1.04; - - m_WSelORn = 1.04; - m_WSelORprequ = 4.16; - m_WSelPn = 1.04; - m_WSelPp = 1.56; - m_WSelEnn = 0.52; - m_WSelEnp = 1.04; - - m_Wsenseextdrv1p = 4.16; - m_Wsenseextdrv1n = 2.50; - m_Wsenseextdrv2p = 20.83; - m_Wsenseextdrv2n = 12.48; - break; - default: - cerr << "Invalid transistor type (" << m_transistor_type << ")" << endl; - exit(1); - } - - m_CamCellHeight = 4.095;/*derived from Cacti 5.3 */ - m_CamCellWidth = 3.51;/*derived from Cacti 5.3 */ - - m_MatchlineSpacing = 0.75; - m_TaglineSpacing = 0.75; - - m_CrsbarCellHeight = 2.94; - m_CrsbarCellWidth = 2.94; - - m_krise = 0.5e-10; - m_tsensedata = 0.725e-10; - m_tsensetag = 0.325e-10; - m_tfalldata = 0.875e-10; - m_tfalltag = 0.875e-10; - /*=============Above are the parameters for 90nm ========================*/ - } - else if(m_tech_node <= 65) - { - /*=============Below are the parameters for 65nm ========================*/ - - m_LSCALE = 0.087; - m_MSCALE = m_LSCALE * .624 / .2250; - - /* bit width of RAM cell in um */ - m_BitWidth = 1.4; - - /* bit height of RAM cell in um */ - m_BitHeight = 1.4; - - m_Cout = 4.35e-14; - - /* Sizing of cells and spacings */ - m_BitlineSpacing = 0.8 * m_SCALE_BW; - m_WordlineSpacing = 0.8 * m_SCALE_BW; - - m_RegCellHeight = 2.1 * m_SCALE_H; - m_RegCellWidth = 1.4 * m_SCALE_W; - - m_Cwordmetal = 1.63e-15 * m_SCALE_M; - m_Cbitmetal = 3.27e-15 * m_SCALE_M; - - m_Cmetal = m_Cbitmetal/16; - m_CM2metal = m_Cbitmetal/16; - m_CM3metal = m_Cbitmetal/16; - - // minimum spacing - m_CCmetal = 0.146206e-15; - m_CCM2metal = 0.146206e-15; - m_CCM3metal = 0.146206e-15; - // 2x minimum spacing - m_CC2metal = 0.09844e-15; - m_CC2M2metal = 0.09844e-15; - m_CC2M3metal = 0.09844e-15; - // 3x minimum spacing - m_CC3metal = 0.08689e-15; - m_CC3M2metal = 0.08689e-15; - m_CC3M3metal = 0.08689e-15; - - - /* corresponds to clock network*/ - m_Clockwire = 323.4e-12 * m_SCALE_M; - m_Reswire = 61.11e3 * 1.0/m_SCALE_M; - m_invCap = 3.12e-14; - m_Resout = 361.00; - - /* um */ - m_Leff = 0.0696; - /* length unit in um */ - m_Lamda = m_Leff * 0.5; - - /* fF/um */ - m_Cpolywire = 1.832e-15; - /* ohms*um of channel width */ - m_Rnchannelstatic = 2244.6; - - /* ohms*um of channel width */ - m_Rpchannelstatic = 5324.4; - - switch(m_transistor_type) - { - case LVT: - m_Rnchannelon = 1370; - m_Rpchannelon = 3301; - break; - case NVT: - m_Rnchannelon = 2540; - m_Rpchannelon = 5791; - break; - case HVT: - m_Rnchannelon = 4530; - m_Rpchannelon = 10101; - break; - default: - cerr << "Invalid transistor type (" << m_transistor_type << ")" << endl; - exit(1); - } - - m_Rbitmetal = 1.92644;/* derived from Cacti 5.3 */ - m_Rwordmetal = 1.31948;/* derived from Cacti 5.3 */ - - switch(m_transistor_type) - { - case LVT: - m_Vt = 0.195; - break; - case NVT: - m_Vt = 0.285; - break; - case HVT: - m_Vt = 0.524; - break; - default: - cerr << "Invalid transistor type (" << m_transistor_type << ")" << endl; - exit(1); - } - - /* transistor widths in um for 65nm. = as described in Cacti 1.0 tech report, appendix 1;*/ - switch(m_transistor_type) - { - case LVT: - m_Wdecdrivep = 8.27; - m_Wdecdriven = 6.70; - m_Wdec3to8n = 2.33; - m_Wdec3to8p = 2.33; - m_WdecNORn = 1.50; - m_WdecNORp = 3.82; - m_Wdecinvn = 8.46; - m_Wdecinvp = 10.93; - m_Wdff = 8.6; - - m_Wworddrivemax = 9.27; - m_Wmemcella = 0.2225; - m_Wmemcellr = 0.3708; - m_Wmemcellw = 0.1947; - m_Wmemcellbscale = 1.87; - m_Wbitpreequ = 0.927; - - m_Wbitmuxn = 0.927; - m_WsenseQ1to4 = 0.371; - m_Wcompinvp1 = 0.927; - m_Wcompinvn1 = 0.5562; - m_Wcompinvp2 = 1.854; - m_Wcompinvn2 = 1.1124; - m_Wcompinvp3 = 3.708; - m_Wcompinvn3 = 2.2248; - m_Wevalinvp = 1.854; - m_Wevalinvn = 7.416; - - - m_Wcompn = 1.854; - m_Wcompp = 2.781; - m_Wcomppreequ = 3.712; - m_Wmuxdrv12n = 2.785; - m_Wmuxdrv12p = 4.635; - m_WmuxdrvNANDn = 1.860; - m_WmuxdrvNANDp = 7.416; - m_WmuxdrvNORn = 5.562; - m_WmuxdrvNORp = 7.416; - m_Wmuxdrv3n = 18.54; - m_Wmuxdrv3p = 44.496; - m_Woutdrvseln = 1.112; - m_Woutdrvselp = 1.854; - m_Woutdrvnandn = 2.225; - m_Woutdrvnandp = 0.927; - m_Woutdrvnorn = 0.5562; - m_Woutdrvnorp = 3.708; - m_Woutdrivern = 4.450; - m_Woutdriverp = 7.416; - m_Wbusdrvn = 4.450; - m_Wbusdrvp = 7.416; - - m_Wcompcellpd2 = 0.222; - m_Wcompdrivern = 37.08; - m_Wcompdriverp = 74.20; - m_Wcomparen2 = 3.708; - m_Wcomparen1 = 1.854; - m_Wmatchpchg = 0.927; - m_Wmatchinvn = 0.930; - m_Wmatchinvp = 1.854; - m_Wmatchnandn = 1.854; - m_Wmatchnandp = 0.927; - m_Wmatchnorn = 1.860; - m_Wmatchnorp = 0.930; - - m_WSelORn = 0.930; - m_WSelORprequ = 3.708; - m_WSelPn = 0.927; - m_WSelPp = 1.391; - m_WSelEnn = 0.434; - m_WSelEnp = 0.930; - - m_Wsenseextdrv1p = 3.708; - m_Wsenseextdrv1n = 2.225; - m_Wsenseextdrv2p = 18.54; - m_Wsenseextdrv2n = 11.124; - break; - case NVT: - m_Wdecdrivep = 6.7; - m_Wdecdriven = 4.7; - m_Wdec3to8n = 1.33; - m_Wdec3to8p = 1.33; - m_WdecNORn = 1.20; - m_WdecNORp = 2.62; - m_Wdecinvn = 1.46; - m_Wdecinvp = 3.93; - m_Wdff = 4.6; - - m_Wworddrivemax = 9.225; - m_Wmemcella = 0.221; - m_Wmemcellr = 0.369; - m_Wmemcellw = 0.194; - m_Wmemcellbscale = 1.87; - m_Wbitpreequ = 0.923; - - m_Wbitmuxn = 0.923; - m_WsenseQ1to4 = 0.369; - m_Wcompinvp1 = 0.924; - m_Wcompinvn1 = 0.554; - m_Wcompinvp2 = 1.845; - m_Wcompinvn2 = 1.107; - m_Wcompinvp3 = 3.69; - m_Wcompinvn3 = 2.214; - m_Wevalinvp = 1.842; - m_Wevalinvn = 7.368; - - m_Wcompn = 1.845; - m_Wcompp = 2.768; - m_Wcomppreequ = 3.692; - m_Wmuxdrv12n = 2.773; - m_Wmuxdrv12p = 4.618; - m_WmuxdrvNANDn = 1.848; - m_WmuxdrvNANDp = 7.38; - m_WmuxdrvNORn = 5.535; - m_WmuxdrvNORp = 7.380; - m_Wmuxdrv3n = 18.45; - m_Wmuxdrv3p = 44.28; - m_Woutdrvseln = 1.105; - m_Woutdrvselp = 1.842; - m_Woutdrvnandn = 2.214; - m_Woutdrvnandp = 0.923; - m_Woutdrvnorn = 0.554; - m_Woutdrvnorp = 3.69; - m_Woutdrivern = 4.428; - m_Woutdriverp = 7.380; - m_Wbusdrvn = 4.421; - m_Wbusdrvp = 7.368; - - m_Wcompcellpd2 = 0.221; - m_Wcompdrivern = 36.84; - m_Wcompdriverp = 73.77; - m_Wcomparen2 = 3.684; - m_Wcomparen1 = 1.842; - m_Wmatchpchg = 0.921; - m_Wmatchinvn = 0.923; - m_Wmatchinvp = 1.852; - m_Wmatchnandn = 1.852; - m_Wmatchnandp = 0.921; - m_Wmatchnorn = 1.845; - m_Wmatchnorp = 0.923; - - m_WSelORn = 0.923; - m_WSelORprequ = 3.684; - m_WSelPn = 0.921; - m_WSelPp = 1.382; - m_WSelEnn = 0.446; - m_WSelEnp = 0.923; - - m_Wsenseextdrv1p = 3.684; - m_Wsenseextdrv1n = 2.211; - m_Wsenseextdrv2p = 18.42; - m_Wsenseextdrv2n = 11.052; - break; - case HVT: - m_Wdecdrivep = 3.11; - m_Wdecdriven = 1.90; - m_Wdec3to8n = 1.33; - m_Wdec3to8p = 1.33; - m_WdecNORn = 0.90; - m_WdecNORp = 1.82; - m_Wdecinvn = 0.46; - m_Wdecinvp = 0.93; - m_Wdff = 3.8; - - m_Wworddrivemax = 9.18; - m_Wmemcella = 0.220; - m_Wmemcellr = 0.367; - m_Wmemcellw = 0.193; - m_Wmemcellbscale = 1.87; - m_Wbitpreequ = 0.918; - - m_Wbitmuxn = 0.918; - m_WsenseQ1to4 = 0.366; - m_Wcompinvp1 = 0.920; - m_Wcompinvn1 = 0.551; - m_Wcompinvp2 = 1.836; - m_Wcompinvn2 = 1.102; - m_Wcompinvp3 = 3.672; - m_Wcompinvn3 = 2.203; - m_Wevalinvp = 1.83; - m_Wevalinvn = 7.32; - - m_Wcompn = 1.836; - m_Wcompp = 2.754; - m_Wcomppreequ = 3.672; - m_Wmuxdrv12n = 2.760; - m_Wmuxdrv12p = 4.60; - m_WmuxdrvNANDn = 1.836; - m_WmuxdrvNANDp = 7.344; - m_WmuxdrvNORn = 5.508; - m_WmuxdrvNORp = 7.344; - m_Wmuxdrv3n = 18.36; - m_Wmuxdrv3p = 44.064; - m_Woutdrvseln = 1.098; - m_Woutdrvselp = 1.83; - m_Woutdrvnandn = 2.203; - m_Woutdrvnandp = 0.918; - m_Woutdrvnorn = 0.551; - m_Woutdrvnorp = 3.672; - m_Woutdrivern = 4.406; - m_Woutdriverp = 7.344; - m_Wbusdrvn = 4.392; - m_Wbusdrvp = 7.32; - - m_Wcompcellpd2 = 0.220; - m_Wcompdrivern = 36.6; - m_Wcompdriverp = 73.33; - m_Wcomparen2 = 3.66; - m_Wcomparen1 = 1.83; - m_Wmatchpchg = 0.915; - m_Wmatchinvn = 0.915; - m_Wmatchinvp = 1.85; - m_Wmatchnandn = 1.85; - m_Wmatchnandp = 0.915; - m_Wmatchnorn = 1.83; - m_Wmatchnorp = 0.915; - - m_WSelORn = 0.915; - m_WSelORprequ = 3.66; - m_WSelPn = 0.915; - m_WSelPp = 1.373; - m_WSelEnn = 0.458; - m_WSelEnp = 0.915; - - m_Wsenseextdrv1p = 3.66; - m_Wsenseextdrv1n = 2.196; - m_Wsenseextdrv2p = 18.3; - m_Wsenseextdrv2n = 10.98; - break; - default: - cerr << "Invalid transistor type (" << m_transistor_type << ")" << endl; - exit(1); - } - - m_CamCellHeight = 2.9575;/* derived from Cacti 5.3 */ - m_CamCellWidth = 2.535;/* derived from Cacti 5.3 */ - - m_MatchlineSpacing = 0.522; - m_TaglineSpacing = 0.522; - - m_CrsbarCellHeight = 2.06 * m_SCALE_Crs; - m_CrsbarCellWidth = 2.06 * m_SCALE_Crs; - - m_krise = 0.348e-10; - m_tsensedata = 0.5046e-10; - m_tsensetag = 0.2262e-10; - m_tfalldata = 0.609e-10; - m_tfalltag = 0.6609e-10; - } - - /*=======================PARAMETERS for Link===========================*/ - - if(m_tech_node == 90) - { - if(m_wire_layer_type == LOCAL) - { - m_WireMinWidth = 214e-9; - m_WireMinSpacing = 214e-9; - m_WireMetalThickness = 363.8e-9; - m_WireBarrierThickness = 10e-9; - m_WireDielectricThickness = 363.8e-9; - m_WireDielectricConstant = 3.3; - } - else if(m_wire_layer_type == INTERMEDIATE) - { - m_WireMinWidth = 275e-9; - m_WireMinSpacing = 275e-9; - m_WireMetalThickness = 467.5e-9; - m_WireBarrierThickness = 10e-9; - m_WireDielectricThickness = 412.5e-9; - m_WireDielectricConstant = 3.3; - } - else if(m_wire_layer_type == GLOBAL) - { - m_WireMinWidth = 410e-9; - m_WireMinSpacing = 410e-9; - m_WireMetalThickness = 861e-9; - m_WireBarrierThickness = 10e-9; - m_WireDielectricThickness = 779e-9; - m_WireDielectricConstant = 3.3; - } - } - else if(m_tech_node == 65) - { - if(m_wire_layer_type == LOCAL) - { - m_WireMinWidth = 136e-9; - m_WireMinSpacing = 136e-9; - m_WireMetalThickness = 231.2e-9; - m_WireBarrierThickness = 4.8e-9; - m_WireDielectricThickness = 231.2e-9; - m_WireDielectricConstant = 2.85; - } - else if(m_wire_layer_type == INTERMEDIATE) - { - m_WireMinWidth = 140e-9; - m_WireMinSpacing = 140e-9; - m_WireMetalThickness = 252e-9; - m_WireBarrierThickness = 5.2e-9; - m_WireDielectricThickness = 224e-9; - m_WireDielectricConstant = 2.85; - } - else if(m_wire_layer_type == GLOBAL) - { - m_WireMinWidth = 400e-9; - m_WireMinSpacing = 400e-9; - m_WireMetalThickness = 400e-9; - m_WireBarrierThickness = 5.2e-9; - m_WireDielectricThickness = 790e-9; - m_WireDielectricConstant = 2.9; - } - } - else if(m_tech_node == 45) - { - if(m_wire_layer_type == LOCAL) - { - m_WireMinWidth = 45e-9; - m_WireMinSpacing = 45e-9; - m_WireMetalThickness = 129.6e-9; - m_WireBarrierThickness = 3.3e-9; - m_WireDielectricThickness = 162e-9; - m_WireDielectricConstant = 2.0; - } - else if(m_wire_layer_type == INTERMEDIATE) - { - m_WireMinWidth = 45e-9; - m_WireMinSpacing = 45e-9; - m_WireMetalThickness = 129.6e-9; - m_WireBarrierThickness = 3.3e-9; - m_WireDielectricThickness = 72e-9; - m_WireDielectricConstant = 2.0; - } - else if(m_wire_layer_type == GLOBAL) - { - m_WireMinWidth = 67.5e-9; - m_WireMinSpacing = 67.5e-9; - m_WireMetalThickness = 155.25e-9; - m_WireBarrierThickness = 3.3e-9; - m_WireDielectricThickness = 141.75e-9; - m_WireDielectricConstant = 2.0; - } - } - else if(m_tech_node == 32) - { - if(m_wire_layer_type == LOCAL) - { - m_WireMinWidth = 32e-9; - m_WireMinSpacing = 32e-9; - m_WireMetalThickness = 60.8e-9; - m_WireBarrierThickness = 2.4e-9; - m_WireDielectricThickness = 60.8e-9; - m_WireDielectricConstant = 1.9; - } - else if(m_wire_layer_type == INTERMEDIATE) - { - m_WireMinWidth = 32e-9; - m_WireMinSpacing = 32e-9; - m_WireMetalThickness = 60.8e-9; - m_WireBarrierThickness = 2.4e-9; - m_WireDielectricThickness = 54.4e-9; - m_WireDielectricConstant = 1.9; - } - else if(m_wire_layer_type == GLOBAL) - { - m_WireMinWidth = 48e-9; - m_WireMinSpacing = 48e-9; - m_WireMetalThickness = 120e-9; - m_WireBarrierThickness = 2.4e-9; - m_WireDielectricThickness = 110.4e-9; - m_WireDielectricConstant = 1.9; - } - } - - /*===================================================================*/ - /*parameters for insertion buffer for links at 90nm*/ - if(m_tech_node == 90) - { - m_BufferDriveResistance = 5.12594e+03; - m_BufferIntrinsicDelay = 4.13985e-11; - if(m_transistor_type == LVT) - { - m_BufferInputCapacitance = 1.59e-15; - m_BufferPMOSOffCurrent = 116.2e-09; - m_BufferNMOSOffCurrent = 52.1e-09; - m_ClockCap = 2.7e-14; - } - else if(m_transistor_type == NVT) - { - m_BufferInputCapacitance = 4.7e-15; - m_BufferPMOSOffCurrent = 67.6e-09; - m_BufferNMOSOffCurrent = 31.1e-09; - m_ClockCap = 1.0e-14; - } - else if(m_transistor_type == HVT) - { - m_BufferInputCapacitance = 15.0e-15;//9.5e-15 - m_BufferPMOSOffCurrent = 19.2e-09; - m_BufferNMOSOffCurrent = 10.1e-09; - m_ClockCap = 0.3e-15; - } - } - /*parameters for insertion buffer for links at 65nm*/ - else if(m_tech_node == 65) - { - m_BufferDriveResistance = 6.77182e+03; - m_BufferIntrinsicDelay = 3.31822e-11; - if(m_transistor_type == LVT) - { - m_BufferPMOSOffCurrent = 317.2e-09; - m_BufferNMOSOffCurrent = 109.7e-09; - m_BufferInputCapacitance = 1.3e-15; - m_ClockCap = 2.6e-14; - } - else if(m_transistor_type == NVT) - { - m_BufferPMOSOffCurrent = 113.1e-09; - m_BufferNMOSOffCurrent = 67.3e-09; - m_BufferInputCapacitance = 2.6e-15; - m_ClockCap = 1.56e-14; - } - else if(m_transistor_type == HVT) - { - m_BufferPMOSOffCurrent = 35.2e-09; - m_BufferNMOSOffCurrent = 18.4e-09; - m_BufferInputCapacitance = 7.8e-15; - m_ClockCap = 0.9e-15; - } - } - /*parameters for insertion buffer for links at 45nm*/ - else if(m_tech_node == 45) - { - m_BufferDriveResistance = 7.3228e+03; - m_BufferIntrinsicDelay = 4.6e-11; - if(m_transistor_type == LVT) - { - m_BufferInputCapacitance = 1.25e-15; - m_BufferPMOSOffCurrent = 1086.75e-09; - m_BufferNMOSOffCurrent = 375.84e-09; - m_ClockCap = 2.5e-14; - } - else if(m_transistor_type == NVT) - { - m_BufferInputCapacitance = 2.5e-15; - m_BufferPMOSOffCurrent = 382.3e-09; - m_BufferNMOSOffCurrent = 195.5e-09; - m_ClockCap = 1.5e-14; - } - else if(m_transistor_type == HVT) - { - m_BufferInputCapacitance = 7.5e-15; - m_BufferPMOSOffCurrent = 76.4e-09; - m_BufferNMOSOffCurrent = 39.1e-09; - m_ClockCap = 0.84e-15; - } - } - /*parameters for insertion buffer for links at 32nm*/ - else if(m_tech_node == 32) - { - m_BufferDriveResistance = 10.4611e+03; - m_BufferIntrinsicDelay = 4.0e-11; - if(m_transistor_type == LVT) - { - m_BufferPMOSOffCurrent = 1630.08e-09; - m_BufferNMOSOffCurrent = 563.74e-09; - m_BufferInputCapacitance = 1.2e-15; - m_ClockCap = 2.2e-14; - } - else if(m_transistor_type == NVT) - { - m_BufferPMOSOffCurrent = 792.4e-09; - m_BufferNMOSOffCurrent = 405.1e-09; - m_BufferInputCapacitance = 2.4e-15; - m_ClockCap = 1.44e-14; - } - else if(m_transistor_type == HVT) - { - m_BufferPMOSOffCurrent = 129.9e-09; - m_BufferNMOSOffCurrent = 66.4e-09; - m_BufferInputCapacitance = 7.2e-15; - m_ClockCap = 0.53e-15; - } - } - - /*======================Parameters for Area===========================*/ - if(m_tech_node == 90) - { - m_AreaNOR = 4.23; - m_AreaINV = 2.82; - m_AreaAND = 4.23; - m_AreaDFF = 16.23; - m_AreaMUX2 = 7.06; - m_AreaMUX3 = 11.29; - m_AreaMUX4 = 16.93; - } - else if(m_tech_node <= 65) - { - m_AreaNOR = 2.52 * m_SCALE_T; - m_AreaINV = 1.44 * m_SCALE_T; - m_AreaDFF = 8.28 * m_SCALE_T; - m_AreaAND = 2.52 * m_SCALE_T; - m_AreaMUX2 = 6.12 * m_SCALE_T; - m_AreaMUX3 = 9.36 * m_SCALE_T; - m_AreaMUX4 = 12.6 * m_SCALE_T; - } - - if (m_tech_node == 90) - { - if (m_transistor_type == LVT) - { - m_NMOS_TAB[0] = 19.9e-9; - m_PMOS_TAB[0] = 16.6e-9; - m_NAND2_TAB[0] = 7.8e-9; - m_NAND2_TAB[1] = 24.6e-9; - m_NAND2_TAB[2] = 14.1e-9; - m_NAND2_TAB[3] = 34.3e-9; - m_NOR2_TAB[0] = 51.2e-9; - m_NOR2_TAB[1] = 23.9e-9; - m_NOR2_TAB[2] = 19.5e-9; - m_NOR2_TAB[3] = 8.4e-9; - m_DFF_TAB[0] = 219.7e-9; - } - else if (m_transistor_type == NVT) - { - m_NMOS_TAB[0] = 15.6e-9; - m_PMOS_TAB[0] = 11.3e-9; - m_NAND2_TAB[0] = 2.8e-9; - m_NAND2_TAB[1] = 19.6e-9; - m_NAND2_TAB[2] = 10.4e-9; - m_NAND2_TAB[3] = 29.3e-9; - m_NOR2_TAB[0] = 41.5e-9; - m_NOR2_TAB[1] = 13.1e-9; - m_NOR2_TAB[2] = 14.5e-9; - m_NOR2_TAB[3] = 1.4e-9; - m_DFF_TAB[0] = 194.7e-9; - } - else - { - m_NMOS_TAB[0] = 12.2e-9; - m_PMOS_TAB[0] = 9.3e-9; - m_NAND2_TAB[0] = 1.8e-9; - m_NAND2_TAB[1] = 12.4e-9; - m_NAND2_TAB[2] = 8.9e-9; - m_NAND2_TAB[3] = 19.3e-9; - m_NOR2_TAB[0] = 29.5e-9; - m_NOR2_TAB[1] = 8.3e-9; - m_NOR2_TAB[2] = 11.1e-9; - m_NOR2_TAB[3] = 0.9e-9; - m_DFF_TAB[0] = 194.7e-9; //FIXME-the same as NVT? - } - } - else if (m_tech_node <= 65) - { - if (m_transistor_type == LVT) - { - m_NMOS_TAB[0] = 311.7e-9; - m_PMOS_TAB[0] = 674.3e-9; - m_NAND2_TAB[0] = 303.0e-9; - m_NAND2_TAB[1] = 423.0e-9; - m_NAND2_TAB[2] = 498.3e-9; - m_NAND2_TAB[3] = 626.3e-9; - m_NOR2_TAB[0] = 556.0e-9; - m_NOR2_TAB[1] = 393.7e-9; - m_NOR2_TAB[2] = 506.7e-9; - m_NOR2_TAB[3] = 369.7e-9; - m_DFF_TAB[0] = 970.4e-9; - } - else if (m_transistor_type == NVT) - { - m_NMOS_TAB[0] = 115.1e-9; - m_PMOS_TAB[0] = 304.8e-9; - m_NAND2_TAB[0] = 111.4e-9; - m_NAND2_TAB[1] = 187.2e-9; - m_NAND2_TAB[2] = 230.7e-9; - m_NAND2_TAB[3] = 306.9e-9; - m_NOR2_TAB[0] = 289.7e-9; - m_NOR2_TAB[1] = 165.7e-9; - m_NOR2_TAB[2] = 236.9e-9; - m_NOR2_TAB[3] = 141.4e-9; - m_DFF_TAB[0] = 400.3e-9; - } - else - { - m_NMOS_TAB[0] = 18.4e-9; - m_PMOS_TAB[0] = 35.2e-9; - m_NAND2_TAB[0] = 19.7e-9; - m_NAND2_TAB[1] = 51.3e-9; - m_NAND2_TAB[2] = 63.0e-9; - m_NAND2_TAB[3] = 87.6e-9; - m_NOR2_TAB[0] = 23.4e-9; - m_NOR2_TAB[1] = 37.6e-9; - m_NOR2_TAB[2] = 67.9e-9; - m_NOR2_TAB[3] = 12.3e-9; - m_DFF_TAB[0] = 231.3e-9; - } - } - return; -} - -// -// width - gate width in um (length is Leff) -// wirelength - poly wire length going to gate in lambda -// return gate capacitance in Farads -double TechParameter::calc_gatecap( - double width_, - double wirelength_ - ) const -{ - return ((width_*m_Leff*m_Cgate + wirelength_*m_Cpolywire*m_Leff)*m_SCALE_T); -} - -double TechParameter::calc_gatecappass( - double width_, - double wirelength_ - ) const -{ - return calc_gatecap(width_, wirelength_); -} - -// Routine for calculating drain capacitances. The draincap routine -// folds transistors larger than 10um */ -// -// width - um -// nchannel - whether n or p-channel (boolean) -// stack - number of transistors in series that are on -// -// return drain cap in Farads -double TechParameter::calc_draincap( - double width_, - ChannelType ch_, - uint32_t num_stack_ - ) const -{ - double Cdiffside, Cdiffarea, Coverlap, total_cap; - - if (ch_ == NCH) - { - Cdiffside = m_Cndiffside; - Cdiffarea = m_Cndiffarea; - Coverlap = m_Cnoverlap; - } - else - { - Cdiffside = m_Cpdiffside; - Cdiffarea = m_Cpdiffarea; - Coverlap = m_Cpoverlap; - } - - if (width_ >= 10) - { - total_cap = (3.0*m_Leff*width_/2.0)*Cdiffarea + 6.0*m_Leff*Cdiffside + width_*Coverlap; - total_cap += (double)(num_stack_ - 1)*(m_Leff*width_*Cdiffarea + 4.0*m_Leff*Cdiffside + 2.0*width_*Coverlap); - } - else - { - total_cap = (3.0*m_Leff*width_)*Cdiffarea + (6.0*m_Leff + width_)*Cdiffside + width_*Coverlap; - total_cap += (double)(num_stack_ - 1)*(m_Leff*width_*Cdiffarea + 2.0*m_Leff*Cdiffside + 2.0*width_*Coverlap); - } - - return (total_cap*m_SCALE_T); -} - -double TechParameter::calc_restowidth( - double res_, - ChannelType ch_ - ) const -{ - double restrans; - - restrans = (ch_ == NCH)? m_Rnchannelon : m_Rpchannelon; - - return (restrans / res_); -} - -double TechParameter::calc_driver_psize( - double cap_, - double rise_time_ - ) const -{ - double psize; - double Rpdrive; - - Rpdrive = rise_time_ / (cap_ * log(m_vs_inv) * (-1.0)); - psize = calc_restowidth(Rpdrive, PCH); - - if (psize > m_Wworddrivemax) - { - psize = m_Wworddrivemax; - } - if (psize < 4.0 * m_LSCALE) - { - psize = 4.0 * m_LSCALE; - } - - return psize; -} - diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Type.hh --- a/src/mem/ruby/network/orion/Type.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#ifndef __TYPE_H__ -#define __TYPE_H__ - -typedef unsigned int uint32_t; - -#include -using std::string; - -#endif - diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Wire.hh --- a/src/mem/ruby/network/orion/Wire.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#ifndef __WIRE_H__ -#define __WIRE_H__ - -#include "mem/ruby/network/orion/Type.hh" - -class TechParameter; - -class Wire -{ - public: - enum WidthSpacingModel - { - SWIDTH_SSPACE, - SWIDTH_DSPACE, - DWIDTH_SSPACE, - DWIDTH_DSPACE - }; - enum BufferScheme - { - MIN_DELAY, - STAGGERED - }; - - public: - Wire( - const string& wire_spacing_model_str_, - const string& buf_scheme_str_, - bool is_shielding_, - const TechParameter* tech_param_ptr_ - ); - ~Wire(); - - public: - void calc_opt_buffering(int* k_, double* h_, double len_) const; - double calc_dynamic_energy(double len_) const; - double calc_static_power(double len_) const; - - private: - void init(); - void set_width_spacing_model(const string& wire_spacing_model_str_); - void set_buf_scheme(const string& buf_scheme_str_); - double calc_res_unit_len(); - double calc_gnd_cap_unit_len(); - double calc_couple_cap_unit_len(); - - private: - const TechParameter* m_tech_param_ptr; - WidthSpacingModel m_width_spacing_model; - BufferScheme m_buf_scheme; - bool m_is_shielding; - - double m_res_unit_len; - double m_gnd_cap_unit_len; - double m_couple_cap_unit_len; -}; - -#endif diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/Wire.cc --- a/src/mem/ruby/network/orion/Wire.cc Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,383 +0,0 @@ -/* - * Copyright (c) 2009 Princeton University - * Copyright (c) 2009 The Regents of the University of California - * 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. - * - * Authors: Hangsheng Wang (Orion 1.0, Princeton) - * Xinping Zhu (Orion 1.0, Princeton) - * Xuning Chen (Orion 1.0, Princeton) - * Bin Li (Orion 2.0, Princeton) - * Kambiz Samadi (Orion 2.0, UC San Diego) - */ - -#include -#include -#include - -#include "base/misc.hh" -#include "mem/ruby/network/orion/TechParameter.hh" -#include "mem/ruby/network/orion/Wire.hh" - -using namespace std; - -Wire::Wire( - const string& wire_spacing_model_str_, - const string& buf_scheme_str_, - bool is_shielding_, - const TechParameter* tech_param_ptr_ -) -{ - set_width_spacing_model(wire_spacing_model_str_); - set_buf_scheme(buf_scheme_str_); - - m_is_shielding = is_shielding_; - - m_tech_param_ptr = tech_param_ptr_; - - if (m_tech_param_ptr->get_tech_node() > 90) - { - cerr << "ERROR: Wire model only support tech node <= 90" << endl; - exit(1); - } - - init(); -} - -Wire::~Wire() -{} - -// OPTIMUM K and H CALCULATION -// Computes the optimum number and size of repeaters for the link -void Wire::calc_opt_buffering( - int* k_, - double* h_, - double len_ - ) const -{ - double BufferDriveResistance = m_tech_param_ptr->get_BufferDriveResistance(); - double BufferInputCapacitance = m_tech_param_ptr->get_BufferInputCapacitance(); - switch(m_buf_scheme) - { - case MIN_DELAY: - { - if (m_is_shielding) - { - double r = m_res_unit_len*len_; - double c_g = 2*m_gnd_cap_unit_len*len_; - double c_c = 2*m_couple_cap_unit_len*len_; - *k_ = (int) sqrt(((0.4*r*c_g)+(0.57*r*c_c))/ - (0.7*BufferDriveResistance*BufferInputCapacitance)); //k is the number of buffers to be inserted - *h_ = sqrt(((0.7*BufferDriveResistance*c_g)+ - (1.4*1.5*BufferDriveResistance*c_c))/(0.7*r*BufferInputCapacitance)); //the size of the buffers to be inserted - break; - } - else - { - double r = m_res_unit_len*len_; - double c_g = 2*m_gnd_cap_unit_len*len_; - double c_c = 2*m_couple_cap_unit_len*len_; - *k_ = (int) sqrt(((0.4*r*c_g)+(1.51*r*c_c))/ - (0.7*BufferDriveResistance*BufferInputCapacitance)); - *h_ = sqrt(((0.7*BufferDriveResistance*c_g)+ - (1.4*2.2*BufferDriveResistance*c_c))/(0.7*r*BufferInputCapacitance)); - break; - } - } - case STAGGERED: - { - double r = m_res_unit_len*len_; - double c_g = 2*m_gnd_cap_unit_len*len_; - double c_c = 2*m_couple_cap_unit_len*len_; - - *k_ = (int) sqrt(((0.4*r*c_g)+(0.57*r*c_c))/ - (0.7*BufferDriveResistance*BufferInputCapacitance)); - *h_ = sqrt(((0.7*BufferDriveResistance*c_g)+ - (1.4*1.5*BufferDriveResistance*c_c))/(0.7*r*BufferInputCapacitance)); - break; - } - } - return; -} - -double Wire::calc_dynamic_energy(double len_) const -{ - - double c_g = 2*m_gnd_cap_unit_len*len_; - double c_c = 2*m_couple_cap_unit_len*len_; - double cap_wire = c_g + c_c; - - int k; - double h; - - calc_opt_buffering(&k, &h, len_); - - double BufferInputCapacitance = m_tech_param_ptr->get_BufferInputCapacitance(); - double cap_buf = ((double)k)*BufferInputCapacitance*h; - - double e_factor = m_tech_param_ptr->get_EnergyFactor(); - return ((cap_wire+cap_buf)*e_factor); -} - -double Wire::calc_static_power(double len_) const -{ - int k; - double h; - calc_opt_buffering(&k, &h, len_); - - double BufferNMOSOffCurrent = m_tech_param_ptr->get_BufferNMOSOffCurrent(); - double BufferPMOSOffCurrent = m_tech_param_ptr->get_BufferPMOSOffCurrent(); - double i_static_nmos = BufferNMOSOffCurrent*h*k; - double i_static_pmos = BufferPMOSOffCurrent*h*k; - - double vdd = m_tech_param_ptr->get_vdd(); - return (vdd*(i_static_pmos+i_static_nmos)/2); -} - -void Wire::init() -{ - m_res_unit_len = calc_res_unit_len(); - m_gnd_cap_unit_len = calc_gnd_cap_unit_len(); - m_couple_cap_unit_len = calc_couple_cap_unit_len(); - return; -} - -void Wire::set_width_spacing_model( - const string& wire_spacing_model_str_ - ) -{ - if (wire_spacing_model_str_ == string("SWIDTH_SSPACE")) - { - m_width_spacing_model = SWIDTH_SSPACE; - } - else if (wire_spacing_model_str_ == string("SWIDTH_DSPACE")) - { - m_width_spacing_model = SWIDTH_DSPACE; - } - else if (wire_spacing_model_str_ == string("DWIDTH_SSPACE")) - { - m_width_spacing_model = DWIDTH_SSPACE; - } - else if (wire_spacing_model_str_ == string("DWIDTH_DSPACE")) - { - m_width_spacing_model = DWIDTH_DSPACE; - } - else - { - cerr << "ERROR: Invalid wire width/spacing model" << endl; - exit(1); - } - return; -} - -void Wire::set_buf_scheme( - const string& buf_scheme_str_ - ) -{ - if (buf_scheme_str_ == string("MIN_DELAY")) - { - m_buf_scheme = MIN_DELAY; - } - else if (buf_scheme_str_ == string("STAGGERED")) - { - m_buf_scheme = STAGGERED; - } - else - { - cerr << "ERROR: Invalid wire buf scheme" << endl; - exit(1); - } - return; -} - -// The following function computes the wire resistance considering -// width-spacing combination and a width-dependent resistivity model -double Wire::calc_res_unit_len() -{ - double r = -1.0; - double rho; - // r, rho is in ohm.m - - double WireMinWidth = m_tech_param_ptr->get_WireMinWidth(); - double WireBarrierThickness = m_tech_param_ptr->get_WireBarrierThickness(); - double WireMetalThickness = m_tech_param_ptr->get_WireMetalThickness(); - - switch(m_width_spacing_model) - { - case SWIDTH_SSPACE: - case SWIDTH_DSPACE: - rho = 2.202e-8 + (1.030e-15 / (WireMinWidth - 2*WireBarrierThickness)); - r = ((rho) / ((WireMinWidth - 2*WireBarrierThickness) * - (WireMetalThickness - WireBarrierThickness))); - break; - case DWIDTH_SSPACE: - case DWIDTH_DSPACE: - rho = 2.202e-8 + (1.030e-15 / (2*WireMinWidth - 2*WireBarrierThickness)); - r = ((rho) / ((2*WireMinWidth - 2*WireBarrierThickness) * - (WireMetalThickness - WireBarrierThickness))); - break; - default: - warn("Orion: Width spacing model not found: %s\n", m_width_spacing_model); - r = 1.0; - } - return r; -} - -// COMPUTE WIRE CAPACITANCE using PTM models -double Wire::calc_gnd_cap_unit_len() -{ - // c_g is in F - double c_g = -1.0; - - double WireMinWidth = m_tech_param_ptr->get_WireMinWidth(); - double WireMinSpacing = m_tech_param_ptr->get_WireMinSpacing(); - double WireMetalThickness = m_tech_param_ptr->get_WireMetalThickness(); - double WireDielectricThickness = m_tech_param_ptr->get_WireDielectricThickness(); - double WireDielectricConstant = m_tech_param_ptr->get_WireDielectricConstant(); - - switch(m_width_spacing_model) - { - case SWIDTH_SSPACE: - { - double A = (WireMinWidth/WireDielectricThickness); - double B = 2.04*pow((WireMinSpacing/(WireMinSpacing + - 0.54*WireDielectricThickness)), 1.77); - double C = pow((WireMetalThickness/(WireMetalThickness + - 4.53*WireDielectricThickness)), 0.07); - c_g = WireDielectricConstant*8.85e-12*(A+(B*C)); - break; - } - case SWIDTH_DSPACE: - { - double minSpacingNew = 2*WireMinSpacing + WireMinWidth; - double A = (WireMinWidth/WireDielectricThickness); - double B = 2.04*pow((minSpacingNew/(minSpacingNew + - 0.54*WireDielectricThickness)), 1.77); - double C = pow((WireMetalThickness/(WireMetalThickness + - 4.53*WireDielectricThickness)), 0.07); - c_g = WireDielectricConstant*8.85e-12*(A+(B*C)); - break; - } - case DWIDTH_SSPACE: - { - double minWidthNew = 2*WireMinWidth; - double A = (minWidthNew/WireDielectricThickness); - double B = 2.04*pow((WireMinSpacing/(WireMinSpacing + - 0.54*WireDielectricThickness)), 1.77); - double C = pow((WireMetalThickness/(WireMetalThickness + - 4.53*WireDielectricThickness)), 0.07); - c_g = WireDielectricConstant*8.85e-12*(A+(B*C)); - break; - } - case DWIDTH_DSPACE: - { - double minWidthNew = 2*WireMinWidth; - double minSpacingNew = 2*WireMinSpacing; - double A = (minWidthNew/WireDielectricThickness); - double B = 2.04*pow((minSpacingNew/(minSpacingNew+ - 0.54*WireDielectricThickness)), 1.77); - double C = pow((WireMetalThickness/(WireMetalThickness + - 4.53*WireDielectricThickness)), 0.07); - c_g = WireDielectricConstant*8.85e-12*(A+(B*C)); - break; - } - default: - warn("Orion: Width spacing model not found: %s\n", m_width_spacing_model); - c_g = 1.0; - } - - return c_g; -} - -// Computes the coupling capacitance considering cross-talk -double Wire::calc_couple_cap_unit_len() -{ - //c_c is in F - double c_c = -1.0; - - double WireMinWidth = m_tech_param_ptr->get_WireMinWidth(); - double WireMinSpacing = m_tech_param_ptr->get_WireMinSpacing(); - double WireMetalThickness = m_tech_param_ptr->get_WireMetalThickness(); - double WireDielectricThickness = m_tech_param_ptr->get_WireDielectricThickness(); - double WireDielectricConstant = m_tech_param_ptr->get_WireDielectricConstant(); - - switch(m_width_spacing_model) - { - case SWIDTH_SSPACE: - { - double A = 1.14*(WireMetalThickness/WireMinSpacing) * - exp(-4*WireMinSpacing/(WireMinSpacing + 8.01*WireDielectricThickness)); - double B = 2.37*pow((WireMinWidth/(WireMinWidth + 0.31*WireMinSpacing)), 0.28); - double C = pow((WireDielectricThickness/(WireDielectricThickness + - 8.96*WireMinSpacing)), 0.76) * - exp(-2*WireMinSpacing/(WireMinSpacing + 6*WireDielectricThickness)); - c_c = WireDielectricConstant*8.85e-12*(A + (B*C)); - break; - } - case SWIDTH_DSPACE: - { - double minSpacingNew = 2*WireMinSpacing + WireMinWidth; - double A = 1.14*(WireMetalThickness/minSpacingNew) * - exp(-4*minSpacingNew/(minSpacingNew + 8.01*WireDielectricThickness)); - double B = 2.37*pow((WireMinWidth/(WireMinWidth + 0.31*minSpacingNew)), 0.28); - double C = pow((WireDielectricThickness/(WireDielectricThickness + - 8.96*minSpacingNew)), 0.76) * - exp(-2*minSpacingNew/(minSpacingNew + 6*WireDielectricThickness)); - c_c = WireDielectricConstant*8.85e-12*(A + (B*C)); - break; - } - case DWIDTH_SSPACE: - { - double minWidthNew = 2*WireMinWidth; - double A = 1.14*(WireMetalThickness/WireMinSpacing) * - exp(-4*WireMinSpacing/(WireMinSpacing + 8.01*WireDielectricThickness)); - double B = 2.37*pow((2*minWidthNew/(2*minWidthNew + 0.31*WireMinSpacing)), 0.28); - double C = pow((WireDielectricThickness/(WireDielectricThickness + - 8.96*WireMinSpacing)), 0.76) * - exp(-2*WireMinSpacing/(WireMinSpacing + 6*WireDielectricThickness)); - c_c = WireDielectricConstant*8.85e-12*(A + (B*C)); - break; - } - case DWIDTH_DSPACE: - { - double minWidthNew = 2*WireMinWidth; - double minSpacingNew = 2*WireMinSpacing; - double A = 1.14*(WireMetalThickness/minSpacingNew) * - exp(-4*minSpacingNew/(minSpacingNew + 8.01*WireDielectricThickness)); - double B = 2.37*pow((minWidthNew/(minWidthNew + 0.31*minSpacingNew)), 0.28); - double C = pow((WireDielectricThickness/(WireDielectricThickness + - 8.96*minSpacingNew)), 0.76) * - exp(-2*minSpacingNew/(minSpacingNew + 6*WireDielectricThickness)); - c_c = WireDielectricConstant*8.85e-12*(A + (B*C)); - break; - } - default: - warn("Orion: Width spacing model not found: %s\n", m_width_spacing_model); - c_c = 1.0; - } - - return c_c; -} - diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/orion.hh --- a/src/mem/ruby/network/orion/orion.hh Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2010 Massachusetts Institute of Technology - * 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. - * - * Authors: Chia-Hsin Owen Chen - */ - -#ifndef __ORION_H__ -#define __ORION_H__ - -#include "mem/ruby/network/orion/OrionConfig.hh" -#include "mem/ruby/network/orion/OrionLink.hh" -#include "mem/ruby/network/orion/OrionRouter.hh" - -#endif - diff -r 94383c5124d2 -r 9126cd4e98b0 src/mem/ruby/network/orion/router.cfg --- a/src/mem/ruby/network/orion/router.cfg Mon Nov 19 11:21:09 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,146 +0,0 @@ -# Copyright (c) 2010 Massachusetts Institute of Technology -# 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. -# -# Authors: Chia-Hsin Owen Chen - -# Technology related parameters -# technology node in nm (90, 65, 45, 32) -TECH_NODE = 65 -# transistor type (HVT, NVT, LVT) -TRANSISTOR_TYPE = NVT -# operating voltage supply in volt -VDD = 1.0 -# operating frequency in Hz -FREQUENCY = 1.0e9 - -# router module parameters -# general parameters -# number of router input ports -NUM_INPUT_PORT = 0 -# number of router output ports -NUM_OUTPUT_PORT = 0 -# flit width in bit -FLIT_WIDTH = 0 - -# virtual channel parameters -# number of message classes per port -NUM_VIRTUAL_CLASS = 0 -# number of virtual channels per message class -NUM_VIRTUAL_CHANNEL = 0 -# Are input virtual channels managed in a shared buffer? (Private buffer otherwise) -IS_IN_SHARED_BUFFER = FALSE -# Are output virtual channels managed in a shared buffer? (Private buffer otherwise) -IS_OUT_SHARED_BUFFER = FALSE -# Are input virtual channels sharing the same crossbar input ports? -IS_IN_SHARED_SWITCH = TRUE -# Are output virtual channels sharing the same crossbar output ports? -IS_OUT_SHARED_SWITCH = TRUE - -# crossbar parameters -# crossbar model -CROSSBAR_MODEL = MULTREE_CROSSBAR - -CROSSBAR_CONNECT_TYPE = TRISTATE_GATE -CROSSBAR_TRANS_GATE_TYPE = NP_GATE -CROSSBAR_MUX_DEGREE = 4 -CROSSBAR_NUM_IN_SEG = 1 -CROSSBAR_NUM_OUT_SEG = 1 -# crossbar input line length -CROSSBAR_LEN_IN_WIRE = 0 -# crossbar output line length -CROSSBAR_LEN_OUT_WIRE = 0 - -# input buffer parameters -IS_INPUT_BUFFER = TRUE -# input buffer model (SRAM, REGISTER) -IN_BUF_MODEL = REGISTER -IN_BUF_NUM_SET = 0 -IN_BUF_NUM_READ_PORT = 1 - -# output buffer parameters */ -IS_OUTPUT_BUFFER = FALSE -# output buffer model (SRAM, REGISTER) -OUT_BUF_MODEL = SRAM -OUT_BUF_NUM_SET = 0 -OUT_BUF_NUM_WRITE_PORT = 0 - -# array parameters shared by various sram buffers -SRAM_ROWDEC_MODEL = GENERIC_DEC -SRAM_ROWDEC_PRE_MODEL = SINGLE_OTHER -SRAM_WORDLINE_MODEL = RW_WORDLINE -SRAM_BITLINE_MODEL = RW_BITLINE -SRAM_OUTDRV_MODEL = REG_OUTDRV -# these 3 should be changed together -# use double-ended bitline because the array is too large -SRAM_NUM_DATA_END = 2 -SRAM_AMP_MODEL = GENERIC_AMP -SRAM_BITLINE_PRE_MODEL = EQU_BITLINE -# SRAM_NUM_DATA_END = 1 -# SRAM_AMP_MODEL = NO_MODEL -# SRAM_BITLINE_PRE_MODEL = SINGLE_OTHER - -# switch allocator arbiter parameters -# arbiter mode (MATRIX_ARBITER, RR_ARBITER) -SA_IN_ARB_MODEL = RR_ARBITER -# flip-flop model -SA_IN_ARB_FF_MODEL = NEG_DFF -# arbiter mode (MATRIX_ARBITER, RR_ARBITER) -SA_OUT_ARB_MODEL = MATRIX_ARBITER -# flip-flop model -SA_OUT_ARB_FF_MODEL = NEG_DFF - -# virtual channel allocator arbiter parameters -# allocator model (ONE_STAGE_ARB, TWO_STAGE_ARB, VC_SELECT) -VA_MODEL = TWO_STAGE_ARB -# arbiter mode (MATRIX_ARBITER, RR_ARBITER) -VA_IN_ARB_MODEL = RR_ARBITER -# flip-flop model -VA_IN_ARB_FF_MODEL = NEG_DFF -# arbiter mode (MATRIX_ARBITER, RR_ARBITER) -VA_OUT_ARB_MODEL = MATRIX_ARBITER -# flip-flop model -VA_OUT_ARB_FF_MODEL = NEG_DFF -# buffer model if VC_SELECT is used (SRAM, REGISTER) -VA_BUF_MODEL = REGISTER - -# link wire parameters -#link length in metres -LINK_LENGTH = 1e-3 -# wire layer model (INTERMEDIATE, GLOBAL) -WIRE_LAYER_TYPE = GLOBAL -# wire width spacing (SWIDTH_SSPACE, SWIDTH_DSPACE, DWIDTH_SSPACE, DWIDTH_DSPACE) -WIRE_WIDTH_SPACING = DWIDTH_DSPACE -# buffering model (MIN_DELAY, STAGGERED) -WIRE_BUFFERING_MODEL = MIN_DELAY -# is shielding -WIRE_IS_SHIELDING = FALSE - -# clock power parameters -NUM_PIPELINE_STAGE = 3 -IS_HTREE_CLOCK = FALSE -# router diagonal in um -ROUTER_DIAGONAL = 442 -