diff options
author | Tushar Krishna <tushar@csail.mit.edu> | 2011-02-06 22:14:17 -0800 |
---|---|---|
committer | Tushar Krishna <tushar@csail.mit.edu> | 2011-02-06 22:14:17 -0800 |
commit | a679e732cee821616c20cc13c22ad2877072ff14 (patch) | |
tree | d3225f0f3bc7f4f79fa3eeb7bf0fb40de19509aa /src/mem/ruby | |
parent | 59163f824c71e4290399be7c1c4b6e70b799a388 (diff) | |
download | gem5-a679e732cee821616c20cc13c22ad2877072ff14.tar.xz |
garnet: added orion2.0 for network power calculation
Diffstat (limited to 'src/mem/ruby')
82 files changed, 9845 insertions, 6312 deletions
diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/InputUnit_d.cc b/src/mem/ruby/network/garnet/fixed-pipeline/InputUnit_d.cc index 057b11fe9..b62a7d2c7 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/InputUnit_d.cc +++ b/src/mem/ruby/network/garnet/fixed-pipeline/InputUnit_d.cc @@ -40,9 +40,14 @@ InputUnit_d::InputUnit_d(int id, Router_d *router) m_id = id; m_router = router; m_num_vcs = m_router->get_num_vcs(); + m_vc_per_vnet = m_router->get_vc_per_vnet(); - m_num_buffer_reads = 0; - m_num_buffer_writes = 0; + m_num_buffer_reads.resize(m_num_vcs/m_vc_per_vnet); + m_num_buffer_writes.resize(m_num_vcs/m_vc_per_vnet); + for (int i = 0; i < m_num_buffer_reads.size(); i++) { + m_num_buffer_reads[i] = 0; + m_num_buffer_writes[i] = 0; + } creditQueue = new flitBuffer_d(); // Instantiating the virtual channels @@ -82,11 +87,11 @@ InputUnit_d::wakeup() // write flit into input buffer m_vcs[vc]->insertFlit(t_flit); - + int vnet = vc/m_vc_per_vnet; // number of writes same as reads // any flit that is written will be read only once - m_num_buffer_writes++; - m_num_buffer_reads++; + m_num_buffer_writes[vnet]++; + m_num_buffer_reads[vnet]++; } } diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/InputUnit_d.hh b/src/mem/ruby/network/garnet/fixed-pipeline/InputUnit_d.hh index bb2b7aa82..81c60f7e1 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/InputUnit_d.hh +++ b/src/mem/ruby/network/garnet/fixed-pipeline/InputUnit_d.hh @@ -162,21 +162,23 @@ class InputUnit_d : public Consumer } inline double - get_buf_read_count() + get_buf_read_count(int vnet) { - return m_num_buffer_reads; + return m_num_buffer_reads[vnet]; } inline double - get_buf_write_count() + get_buf_write_count(int vnet) { - return m_num_buffer_writes; + return m_num_buffer_writes[vnet]; } private: int m_id; int m_num_vcs; - double m_num_buffer_writes, m_num_buffer_reads; + int m_vc_per_vnet; + std::vector<double> m_num_buffer_writes; + std::vector<double> m_num_buffer_reads; Router_d *m_router; NetworkLink_d *m_in_link; diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh b/src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh index 8f64baa37..cc13f5b9e 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh +++ b/src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh @@ -37,7 +37,7 @@ #include "mem/ruby/network/garnet/NetworkHeader.hh" #include "mem/ruby/common/Consumer.hh" #include "mem/ruby/network/garnet/fixed-pipeline/flitBuffer_d.hh" -#include "mem/ruby/network/orion/power_bus.hh" +#include "mem/ruby/network/orion/NetworkPower.hh" class GarnetNetwork_d; @@ -56,7 +56,6 @@ class NetworkLink_d : public Consumer int get_id(){return m_id;} void wakeup(); - double calculate_offline_power(power_bus*); double calculate_power(); inline bool isReady() { return linkBuffer->isReady(); } diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.cc b/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.cc index 44c3a5d64..4ee176653 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.cc +++ b/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.cc @@ -60,13 +60,19 @@ Router_d::Router_d(int id, GarnetNetwork_d *network_ptr) m_input_unit.clear(); m_output_unit.clear(); - buf_read_count = 0; - buf_write_count = 0; crossbar_count = 0; - vc_local_arbit_count = 0; - vc_global_arbit_count = 0; sw_local_arbit_count = 0; sw_global_arbit_count = 0; + buf_read_count.resize(m_virtual_networks); + buf_write_count.resize(m_virtual_networks); + vc_local_arbit_count.resize(m_virtual_networks); + vc_global_arbit_count.resize(m_virtual_networks); + for (int i = 0; i < m_virtual_networks; i++) { + buf_read_count[i] = 0; + buf_write_count[i] = 0; + vc_local_arbit_count[i] = 0; + vc_global_arbit_count[i] = 0; + } } Router_d::~Router_d() @@ -154,15 +160,19 @@ Router_d::update_sw_winner(int inport, flit_d *t_flit) void Router_d::calculate_performance_numbers() { - for (int i = 0; i < m_input_unit.size(); i++) { - buf_read_count += m_input_unit[i]->get_buf_read_count(); - buf_write_count += m_input_unit[i]->get_buf_write_count(); + for (int j = 0; j < m_virtual_networks; j++) { + for (int i = 0; i < m_input_unit.size(); i++) { + buf_read_count[j] += m_input_unit[i]->get_buf_read_count(j); + buf_write_count[j] += m_input_unit[i]->get_buf_write_count(j); + } + + vc_local_arbit_count[j] = m_vc_alloc->get_local_arbit_count(j); + vc_global_arbit_count[j] = m_vc_alloc->get_global_arbit_count(j); } - crossbar_count = m_switch->get_crossbar_count(); - vc_local_arbit_count = m_vc_alloc->get_local_arbit_count(); - vc_global_arbit_count = m_vc_alloc->get_global_arbit_count(); + sw_local_arbit_count = m_sw_alloc->get_local_arbit_count(); sw_global_arbit_count = m_sw_alloc->get_global_arbit_count(); + crossbar_count = m_switch->get_crossbar_count(); } void diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.hh b/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.hh index 4af37cdbe..0c5d51fc3 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.hh +++ b/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.hh @@ -37,7 +37,7 @@ #include "mem/ruby/network/garnet/NetworkHeader.hh" #include "mem/ruby/network/garnet/fixed-pipeline/flit_d.hh" #include "mem/ruby/common/NetDest.hh" -#include "mem/ruby/network/orion/power_router_init.hh" +#include "mem/ruby/network/orion/NetworkPower.hh" class GarnetNetwork_d; class NetworkLink_d; @@ -78,10 +78,7 @@ class Router_d void swarb_req(); void printConfig(std::ostream& out); - void power_router_initialize(power_router *router, - power_router_info *info); double calculate_power(); - double calculate_offline_power(power_router*, power_router_info*); void calculate_performance_numbers(); private: @@ -90,10 +87,12 @@ class Router_d GarnetNetwork_d *m_network_ptr; int m_flit_width; - double buf_read_count, buf_write_count; - double crossbar_count; - double vc_local_arbit_count, vc_global_arbit_count; + std::vector<double> buf_read_count; + std::vector<double> buf_write_count; + std::vector<double> vc_local_arbit_count; + std::vector<double> vc_global_arbit_count; double sw_local_arbit_count, sw_global_arbit_count; + double crossbar_count; std::vector<InputUnit_d *> m_input_unit; std::vector<OutputUnit_d *> m_output_unit; diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/VCallocator_d.cc b/src/mem/ruby/network/garnet/fixed-pipeline/VCallocator_d.cc index 9148cdf9d..3cffda84c 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/VCallocator_d.cc +++ b/src/mem/ruby/network/garnet/fixed-pipeline/VCallocator_d.cc @@ -39,8 +39,13 @@ VCallocator_d::VCallocator_d(Router_d *router) m_router = router; m_num_vcs = m_router->get_num_vcs(); m_vc_per_vnet = m_router->get_vc_per_vnet(); - m_local_arbiter_activity = 0; - m_global_arbiter_activity = 0; + + m_local_arbiter_activity.resize(m_num_vcs/m_vc_per_vnet); + m_global_arbiter_activity.resize(m_num_vcs/m_vc_per_vnet); + for (int i = 0; i < m_local_arbiter_activity.size(); i++) { + m_local_arbiter_activity[i] = 0; + m_global_arbiter_activity[i] = 0; + } } void @@ -158,7 +163,7 @@ VCallocator_d::select_outvc(int inport_iter, int invc_iter) outvc_offset = 0; int outvc = outvc_base + outvc_offset; if (m_output_unit[outport]->is_vc_idle(outvc)) { - m_local_arbiter_activity++; + m_local_arbiter_activity[vnet]++; m_outvc_req[outport][outvc][inport_iter][invc_iter] = true; if (!m_outvc_is_req[outport][outvc]) m_outvc_is_req[outport][outvc] = true; @@ -220,7 +225,7 @@ VCallocator_d::arbitrate_outvcs() } int invc = invc_base + invc_offset; if (m_outvc_req[outport_iter][outvc_iter][inport][invc]) { - m_global_arbiter_activity++; + m_global_arbiter_activity[vnet]++; m_input_unit[inport]->grant_vc(invc, outvc_iter); m_output_unit[outport_iter]->update_vc( outvc_iter, inport, invc); diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/VCallocator_d.hh b/src/mem/ruby/network/garnet/fixed-pipeline/VCallocator_d.hh index 3d3e9a4e6..789338244 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/VCallocator_d.hh +++ b/src/mem/ruby/network/garnet/fixed-pipeline/VCallocator_d.hh @@ -58,15 +58,15 @@ class VCallocator_d : public Consumer void select_outvc(int inport_iter, int invc_iter); inline double - get_local_arbit_count() + get_local_arbit_count(int vnet) { - return m_local_arbiter_activity; + return m_local_arbiter_activity[vnet]; } inline double - get_global_arbit_count() + get_global_arbit_count(int vnet) { - return m_global_arbiter_activity; + return m_global_arbiter_activity[vnet]; } private: @@ -74,7 +74,8 @@ class VCallocator_d : public Consumer int m_num_inports; int m_num_outports; - double m_local_arbiter_activity, m_global_arbiter_activity; + std::vector<double > m_local_arbiter_activity; + std::vector<double > m_global_arbiter_activity; Router_d *m_router; diff --git a/src/mem/ruby/network/orion/Allocator/Arbiter.cc b/src/mem/ruby/network/orion/Allocator/Arbiter.cc new file mode 100644 index 000000000..2f6c60301 --- /dev/null +++ b/src/mem/ruby/network/orion/Allocator/Arbiter.cc @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 <iostream> +#include <cassert> + +#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 --git a/src/mem/ruby/network/orion/Allocator/Arbiter.hh b/src/mem/ruby/network/orion/Allocator/Arbiter.hh new file mode 100644 index 000000000..cdd4678ec --- /dev/null +++ b/src/mem/ruby/network/orion/Allocator/Arbiter.hh @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 --git a/src/mem/ruby/network/orion/Allocator/MatrixArbiter.cc b/src/mem/ruby/network/orion/Allocator/MatrixArbiter.cc new file mode 100644 index 000000000..13beedb2d --- /dev/null +++ b/src/mem/ruby/network/orion/Allocator/MatrixArbiter.cc @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 <cassert> +#include <cmath> +#include <iostream> + +#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 --git a/src/mem/ruby/network/orion/Allocator/MatrixArbiter.hh b/src/mem/ruby/network/orion/Allocator/MatrixArbiter.hh new file mode 100644 index 000000000..7cb277a50 --- /dev/null +++ b/src/mem/ruby/network/orion/Allocator/MatrixArbiter.hh @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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/Type.hh" + +#include "mem/ruby/network/orion/Allocator/Arbiter.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 --git a/src/mem/ruby/network/orion/Allocator/RRArbiter.cc b/src/mem/ruby/network/orion/Allocator/RRArbiter.cc new file mode 100644 index 000000000..0dad2c5b7 --- /dev/null +++ b/src/mem/ruby/network/orion/Allocator/RRArbiter.cc @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 <iostream> +#include <cmath> + +#include "mem/ruby/network/orion/Allocator/RRArbiter.hh" +#include "mem/ruby/network/orion/TechParameter.hh" +#include "mem/ruby/network/orion/FlipFlop.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 --git a/src/mem/ruby/network/orion/Allocator/RRArbiter.hh b/src/mem/ruby/network/orion/Allocator/RRArbiter.hh new file mode 100644 index 000000000..24b4d38b8 --- /dev/null +++ b/src/mem/ruby/network/orion/Allocator/RRArbiter.hh @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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/Type.hh" +#include "mem/ruby/network/orion/Allocator/Arbiter.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 --git a/src/mem/ruby/network/orion/Allocator/SConscript b/src/mem/ruby/network/orion/Allocator/SConscript new file mode 100644 index 000000000..eede26a79 --- /dev/null +++ b/src/mem/ruby/network/orion/Allocator/SConscript @@ -0,0 +1,38 @@ +# 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 not env['RUBY']: + Return() + +Source('Arbiter.cc') +Source('MatrixArbiter.cc') +Source('RRArbiter.cc') +Source('SWAllocator.cc') +Source('VCAllocator.cc') diff --git a/src/mem/ruby/network/orion/Allocator/SWAllocator.cc b/src/mem/ruby/network/orion/Allocator/SWAllocator.cc new file mode 100644 index 000000000..366779e45 --- /dev/null +++ b/src/mem/ruby/network/orion/Allocator/SWAllocator.cc @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 <iostream> +#include <cassert> + +#include "mem/ruby/network/orion/Allocator/SWAllocator.hh" +#include "mem/ruby/network/orion/OrionConfig.hh" +#include "mem/ruby/network/orion/Allocator/Arbiter.hh" +#include "mem/ruby/network/orion/Crossbar/Crossbar.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<string>("SA_IN_ARB_MODEL"); + const string& local_arb_ff_model_str = orion_cfg_ptr_->get<string>("SA_IN_ARB_FF_MODEL"); + const string& global_arb_model_str = orion_cfg_ptr_->get<string>("SA_OUT_ARB_MODEL"); + const string& global_arb_ff_model_str = orion_cfg_ptr_->get<string>("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 --git a/src/mem/ruby/network/orion/Allocator/SWAllocator.hh b/src/mem/ruby/network/orion/Allocator/SWAllocator.hh new file mode 100644 index 000000000..e2982ddf3 --- /dev/null +++ b/src/mem/ruby/network/orion/Allocator/SWAllocator.hh @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 --git a/src/mem/ruby/network/orion/Allocator/VCAllocator.cc b/src/mem/ruby/network/orion/Allocator/VCAllocator.cc new file mode 100644 index 000000000..38ac985f3 --- /dev/null +++ b/src/mem/ruby/network/orion/Allocator/VCAllocator.cc @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 <iostream> +#include <cassert> +#include <cstdlib> +#include <cmath> + +#include "mem/ruby/network/orion/Allocator/VCAllocator.hh" +#include "mem/ruby/network/orion/OrionConfig.hh" +#include "mem/ruby/network/orion/Allocator/Arbiter.hh" +#include "mem/ruby/network/orion/Buffer/Buffer.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<string>("VA_OUT_ARB_MODEL"); + const string& arb_ff_model_str = orion_cfg_ptr_->get<string>("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<string>("VA_IN_ARB_MODEL"); + const string& local_arb_ff_model_str = orion_cfg_ptr_->get<string>("VA_IN_ARB_FF_MODEL"); + const string& global_arb_model_str = orion_cfg_ptr_->get<string>("VA_OUT_ARB_MODEL"); + const string& global_arb_ff_model_str = orion_cfg_ptr_->get<string>("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<string>("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 --git a/src/mem/ruby/network/orion/Allocator/VCAllocator.hh b/src/mem/ruby/network/orion/Allocator/VCAllocator.hh new file mode 100644 index 000000000..c989089fb --- /dev/null +++ b/src/mem/ruby/network/orion/Allocator/VCAllocator.hh @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 --git a/src/mem/ruby/network/orion/Buffer/AmpUnit.cc b/src/mem/ruby/network/orion/Buffer/AmpUnit.cc new file mode 100644 index 000000000..f6be2fe52 --- /dev/null +++ b/src/mem/ruby/network/orion/Buffer/AmpUnit.cc @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 --git a/src/mem/ruby/network/orion/power_ll.hh b/src/mem/ruby/network/orion/Buffer/AmpUnit.hh index 4cae89dcc..30c4cd0ec 100644 --- a/src/mem/ruby/network/orion/power_ll.hh +++ b/src/mem/ruby/network/orion/Buffer/AmpUnit.hh @@ -1,5 +1,6 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2009 Princeton University, and + * Regents of the University of California * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,30 +25,49 @@ * 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 POWER_LL_H_ -#define POWER_LL_H_ - -extern double SIM_power_driver_size(double driving_cap, double desiredrisetime); -extern int SIM_power_init(void); -extern double SIM_power_gatecap(double width, double wirelength) ; -extern double SIM_power_gatecappass(double width, double wirelength); -extern double SIM_power_draincap(double width, int nchannel, int stack); -extern double SIM_power_transresswitch(double width, int nchannel, int stack); -extern double SIM_power_transreson(double width,int nchannel,int stack); -extern double SIM_power_restowidth(double res,int nchannel); -extern double SIM_power_horowitz(double inputramptime,double tf,double vs1,double vs2,int rise); - - - +#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 --git a/src/mem/ruby/network/orion/Buffer/BitlineUnit.cc b/src/mem/ruby/network/orion/Buffer/BitlineUnit.cc new file mode 100644 index 000000000..05d0ae382 --- /dev/null +++ b/src/mem/ruby/network/orion/Buffer/BitlineUnit.cc @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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/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: + printf("error\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 --git a/src/mem/ruby/network/orion/Buffer/BitlineUnit.hh b/src/mem/ruby/network/orion/Buffer/BitlineUnit.hh new file mode 100644 index 000000000..ffdb33727 --- /dev/null +++ b/src/mem/ruby/network/orion/Buffer/BitlineUnit.hh @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 --git a/src/mem/ruby/network/orion/Buffer/Buffer.cc b/src/mem/ruby/network/orion/Buffer/Buffer.cc new file mode 100644 index 000000000..11c92094f --- /dev/null +++ b/src/mem/ruby/network/orion/Buffer/Buffer.cc @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 <iostream> +#include <cassert> + +#include "mem/ruby/network/orion/Buffer/Buffer.hh" +#include "mem/ruby/network/orion/TechParameter.hh" +#include "mem/ruby/network/orion/OrionConfig.hh" +#include "mem/ruby/network/orion/Buffer/SRAM.hh" +#include "mem/ruby/network/orion/Buffer/Register.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<uint32_t>("SRAM_NUM_DATA_END"); + const string& rowdec_model_str = m_orion_cfg_ptr->get<string>("SRAM_ROWDEC_MODEL"); + const string& wl_model_str = m_orion_cfg_ptr->get<string>("SRAM_WORDLINE_MODEL"); + const string& bl_pre_model_str = m_orion_cfg_ptr->get<string>("SRAM_BITLINE_PRE_MODEL"); + const string& mem_model_str = "NORMAL_MEM"; + const string& bl_model_str = m_orion_cfg_ptr->get<string>("SRAM_BITLINE_MODEL"); + const string& amp_model_str = m_orion_cfg_ptr->get<string>("SRAM_AMP_MODEL"); + const string& outdrv_model_str = m_orion_cfg_ptr->get<string>("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 --git a/src/mem/ruby/network/orion/Buffer/Buffer.hh b/src/mem/ruby/network/orion/Buffer/Buffer.hh new file mode 100644 index 000000000..cf61bee2b --- /dev/null +++ b/src/mem/ruby/network/orion/Buffer/Buffer.hh @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 --git a/src/mem/ruby/network/orion/Buffer/DecoderUnit.cc b/src/mem/ruby/network/orion/Buffer/DecoderUnit.cc new file mode 100644 index 000000000..101efdf5e --- /dev/null +++ b/src/mem/ruby/network/orion/Buffer/DecoderUnit.cc @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 <cmath> + +#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 --git a/src/mem/ruby/network/orion/power_crossbar.hh b/src/mem/ruby/network/orion/Buffer/DecoderUnit.hh index 1dc0220e7..93bee26ae 100644 --- a/src/mem/ruby/network/orion/power_crossbar.hh +++ b/src/mem/ruby/network/orion/Buffer/DecoderUnit.hh @@ -1,5 +1,6 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2009 Princeton University, and + * Regents of the University of California * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,58 +25,64 @@ * 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) */ -// Crossbar - -#ifndef _POWER_CROSSBAR_H -#define _POWER_CROSSBAR_H +#ifndef __DECODERUNIT_H__ +#define __DECODERUNIT_H__ -typedef enum { - TRANS_GATE, - TRISTATE_GATE -} power_connect_model; +#include "mem/ruby/network/orion/Type.hh" +#include "mem/ruby/network/orion/TechParameter.hh" -/* transmission gate type */ -typedef enum { - N_GATE, - NP_GATE -} power_trans; +class DecoderUnit +{ + public: + enum DecModel + { + NO_MODEL = 0, + GENERIC_DEC + }; -typedef enum { - MATRIX_CROSSBAR =1, - MULTREE_CROSSBAR, - CUT_THRU_CROSSBAR, - CROSSBAR_MAX_MODEL -} power_crossbar_model; + 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; } -typedef struct { - int model; - unsigned n_in; - unsigned n_out; - unsigned data_width; - unsigned degree; //used only for multree xbar - unsigned connect_type; - unsigned trans_type; - unsigned long int n_chg_in; - unsigned long int n_chg_int; - unsigned long int n_chg_out; - unsigned long int n_chg_ctr; - unsigned long int mask; - double e_chg_in; - double e_chg_int; - double e_chg_out; - double e_chg_ctr; - unsigned depth; //used only for multree xbar - double i_leakage; -} power_crossbar; + 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; -extern int crossbar_record(power_crossbar *xb, int io, unsigned long int new_data, unsigned long int old_data, unsigned new_port, unsigned old_port); + uint32_t m_num_in_1st; + uint32_t m_num_in_2nd; + uint32_t m_num_out_0th; + uint32_t m_num_out_1st; -extern int power_crossbar_init(power_crossbar *crsbar, int model, unsigned n_in, unsigned n_out, unsigned data_width, unsigned degree, int connect_type, int trans_type, double in_len, double out_len, double *req_len); - -extern double crossbar_report(power_crossbar *crsbar); + double m_e_chg_l1; + double m_e_chg_output; + double m_e_chg_addr; +}; #endif + diff --git a/src/mem/ruby/network/orion/Buffer/MemUnit.cc b/src/mem/ruby/network/orion/Buffer/MemUnit.cc new file mode 100644 index 000000000..159bd87fc --- /dev/null +++ b/src/mem/ruby/network/orion/Buffer/MemUnit.cc @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 <iostream> + +#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 --git a/src/mem/ruby/network/orion/Buffer/MemUnit.hh b/src/mem/ruby/network/orion/Buffer/MemUnit.hh new file mode 100644 index 000000000..e2858437e --- /dev/null +++ b/src/mem/ruby/network/orion/Buffer/MemUnit.hh @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 --git a/src/mem/ruby/network/orion/Buffer/OutdrvUnit.cc b/src/mem/ruby/network/orion/Buffer/OutdrvUnit.cc new file mode 100644 index 000000000..716fc18ee --- /dev/null +++ b/src/mem/ruby/network/orion/Buffer/OutdrvUnit.cc @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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/OutdrvUnit.hh" +#include "mem/ruby/network/orion/TechParameter.hh" +#include "mem/ruby/network/orion/Buffer/SRAM.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: + printf("error\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 --git a/src/mem/ruby/network/orion/Buffer/OutdrvUnit.hh b/src/mem/ruby/network/orion/Buffer/OutdrvUnit.hh new file mode 100644 index 000000000..5d01e2c8a --- /dev/null +++ b/src/mem/ruby/network/orion/Buffer/OutdrvUnit.hh @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 --git a/src/mem/ruby/network/orion/Buffer/PrechargeUnit.cc b/src/mem/ruby/network/orion/Buffer/PrechargeUnit.cc new file mode 100644 index 000000000..ac91edb43 --- /dev/null +++ b/src/mem/ruby/network/orion/Buffer/PrechargeUnit.cc @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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/PrechargeUnit.hh" +#include "mem/ruby/network/orion/TechParameter.hh" +#include "mem/ruby/network/orion/Buffer/SRAM.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: printf("error\n"); return 0; + } +} + +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: printf("error\n"); return 0; + } +} + +double PrechargeUnit::calc_pre_cap(double width_, double length_) +{ + return m_tech_param_ptr->calc_gatecap(width_, length_); +} + diff --git a/src/mem/ruby/network/orion/Buffer/PrechargeUnit.hh b/src/mem/ruby/network/orion/Buffer/PrechargeUnit.hh new file mode 100644 index 000000000..e6f56eb3a --- /dev/null +++ b/src/mem/ruby/network/orion/Buffer/PrechargeUnit.hh @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 --git a/src/mem/ruby/network/orion/Buffer/Register.cc b/src/mem/ruby/network/orion/Buffer/Register.cc new file mode 100644 index 000000000..364e5a833 --- /dev/null +++ b/src/mem/ruby/network/orion/Buffer/Register.cc @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 <iostream> +#include <cassert> + +#include "mem/ruby/network/orion/Buffer/Register.hh" +#include "mem/ruby/network/orion/TechParameter.hh" +#include "mem/ruby/network/orion/FlipFlop.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 --git a/src/mem/ruby/network/orion/power_static.cc b/src/mem/ruby/network/orion/Buffer/Register.hh index ded399000..30e8b80f3 100644 --- a/src/mem/ruby/network/orion/power_static.cc +++ b/src/mem/ruby/network/orion/Buffer/Register.hh @@ -1,5 +1,6 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2009 Princeton University, and + * Regents of the University of California * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,23 +25,49 @@ * 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/power_static.hh" - -#if (PARM_TECH_POINT == 18) -double NMOS_TAB[1] = {20.5e-9}; -double PMOS_TAB[1] = {9.2e-9}; -double NAND2_TAB[4] = {6.4e-10, 20.4e-9, 12.6e-9, 18.4e-9}; -double NOR2_TAB[4] ={40.9e-9, 8.32e-9, 9.2e-9, 2.3e-10}; -#elif (PARM_TECH_POINT == 10) -double NMOS_TAB[1] = {22.7e-9}; -double PMOS_TAB[1] = {18.0e-9}; -double NAND2_TAB[4] = {1.2e-9, 22.6e-9, 11.4e-9, 35.9e-9}; -double NOR2_TAB[4] ={45.1e-9, 11.5e-9, 17.9e-9, 1.8e-9}; -#elif (PARM_TECH_POINT == 7) -double NMOS_TAB[1] = {118.1e-9}; -double PMOS_TAB[1] = {135.2e-9}; -double NAND2_TAB[4] = {19.7e-9, 115.3e-9, 83.0e-9, 267.6e-9}; -double NOR2_TAB[4] ={232.4e-9, 79.6e-9, 127.9e-9, 12.3e-9}; +#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 --git a/src/mem/ruby/network/orion/Buffer/SConscript b/src/mem/ruby/network/orion/Buffer/SConscript new file mode 100644 index 000000000..3db8c4a01 --- /dev/null +++ b/src/mem/ruby/network/orion/Buffer/SConscript @@ -0,0 +1,43 @@ +# 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 not env['RUBY']: + 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 --git a/src/mem/ruby/network/orion/Buffer/SRAM.cc b/src/mem/ruby/network/orion/Buffer/SRAM.cc new file mode 100644 index 000000000..d8f500de5 --- /dev/null +++ b/src/mem/ruby/network/orion/Buffer/SRAM.cc @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 <iostream> +#include <cmath> +#include <cassert> + +#include "mem/ruby/network/orion/Buffer/SRAM.hh" +#include "mem/ruby/network/orion/Buffer/OutdrvUnit.hh" +#include "mem/ruby/network/orion/Buffer/AmpUnit.hh" +#include "mem/ruby/network/orion/Buffer/BitlineUnit.hh" +#include "mem/ruby/network/orion/Buffer/MemUnit.hh" +#include "mem/ruby/network/orion/Buffer/PrechargeUnit.hh" +#include "mem/ruby/network/orion/Buffer/WordlineUnit.hh" +#include "mem/ruby/network/orion/Buffer/DecoderUnit.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 --git a/src/mem/ruby/network/orion/Buffer/SRAM.hh b/src/mem/ruby/network/orion/Buffer/SRAM.hh new file mode 100644 index 000000000..7b3f46698 --- /dev/null +++ b/src/mem/ruby/network/orion/Buffer/SRAM.hh @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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/Type.hh" +#include "mem/ruby/network/orion/OrionConfig.hh" +#include "mem/ruby/network/orion/TechParameter.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 --git a/src/mem/ruby/network/orion/Buffer/WordlineUnit.cc b/src/mem/ruby/network/orion/Buffer/WordlineUnit.cc new file mode 100644 index 000000000..bc28444e2 --- /dev/null +++ b/src/mem/ruby/network/orion/Buffer/WordlineUnit.cc @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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/WordlineUnit.hh" +#include "mem/ruby/network/orion/Buffer/SRAM.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: + printf("error\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 --git a/src/mem/ruby/network/orion/Buffer/WordlineUnit.hh b/src/mem/ruby/network/orion/Buffer/WordlineUnit.hh new file mode 100644 index 000000000..4083f5dcf --- /dev/null +++ b/src/mem/ruby/network/orion/Buffer/WordlineUnit.hh @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 --git a/src/mem/ruby/network/orion/Clock.cc b/src/mem/ruby/network/orion/Clock.cc new file mode 100644 index 000000000..27c6e2332 --- /dev/null +++ b/src/mem/ruby/network/orion/Clock.cc @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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/TechParameter.hh" +#include "mem/ruby/network/orion/OrionConfig.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<bool>("IS_HTREE_CLOCK"); + if(is_htree) + { + const string& width_spacing_model_str = m_orion_cfg_ptr->get<string>("WIRE_WIDTH_SPACING"); + const string& buf_scheme_str = m_orion_cfg_ptr->get<string>("WIRE_BUFFERING_MODEL"); + bool is_shielding = m_orion_cfg_ptr->get<bool>("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<double>("ROUTER_DIAGONAL"); + double Clockwire = m_tech_param_ptr->get_ClockCap(); + double Reswire = m_tech_param_ptr->get_Reswire(); + + double htree_clockcap; + double htree_res; + int k; + double h; + double cap_clock_buf = 0; + + 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; + htree_res = (4+4+2+2)*(router_diagonal*1e-6)*Reswire; + + 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; + htree_res = (8+4+4+4+4)*(router_diagonal*1e-6)*Reswire; + + 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; + } + + cap_clock_buf = ((double)k)*cap_clock*h; + + 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 --git a/src/mem/ruby/network/orion/Clock.hh b/src/mem/ruby/network/orion/Clock.hh new file mode 100644 index 000000000..82a73212d --- /dev/null +++ b/src/mem/ruby/network/orion/Clock.hh @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 --git a/src/mem/ruby/network/orion/ConfigFile.cc b/src/mem/ruby/network/orion/ConfigFile.cc new file mode 100644 index 000000000..33566acf4 --- /dev/null +++ b/src/mem/ruby/network/orion/ConfigFile.cc @@ -0,0 +1,170 @@ +/* + * 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 --git a/src/mem/ruby/network/orion/ConfigFile.hh b/src/mem/ruby/network/orion/ConfigFile.hh new file mode 100644 index 000000000..65cf50069 --- /dev/null +++ b/src/mem/ruby/network/orion/ConfigFile.hh @@ -0,0 +1,252 @@ +// 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<int>( "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 <string> +#include <map> +#include <iostream> +#include <fstream> +#include <sstream> + +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<string,string> myContents; // extracted keys and values + + typedef std::map<string,string>::iterator mapi; + typedef std::map<string,string>::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<class T> T read( const string& key ) const; // call as read<T> + template<class T> T read( const string& key, const T& value ) const; + template<class T> bool readInto( T& var, const string& key ) const; + template<class T> + bool readInto( T& var, const string& key, const T& value ) const; + + // Modify keys and values + template<class T> 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<class T> static string T_as_string( const T& t ); + template<class T> 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<class T> +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<class T> +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<string>( 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<bool>( 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<class T> +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<T>( p->second ); +} + + +template<class T> +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<T>( p->second ); +} + + +template<class T> +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<T>( p->second ); + return found; +} + + +template<class T> +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<T>( p->second ); + else + var = value; + return found; +} + + +template<class T> +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 --git a/src/mem/ruby/network/orion/Crossbar/Crossbar.cc b/src/mem/ruby/network/orion/Crossbar/Crossbar.cc new file mode 100644 index 000000000..65f1c20f9 --- /dev/null +++ b/src/mem/ruby/network/orion/Crossbar/Crossbar.cc @@ -0,0 +1,393 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 <iostream> +#include <cassert> + +#include "mem/ruby/network/orion/Crossbar/Crossbar.hh" +#include "mem/ruby/network/orion/TechParameter.hh" +#include "mem/ruby/network/orion/OrionConfig.hh" +#include "mem/ruby/network/orion/Crossbar/MatrixCrossbar.hh" +#include "mem/ruby/network/orion/Crossbar/MultreeCrossbar.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<string>("CROSSBAR_CONNECT_TYPE"); + const string& trans_type_str = orion_cfg_ptr_->get<string>("CROSSBAR_TRANS_GATE_TYPE"); + uint32_t num_in_seg = orion_cfg_ptr_->get<uint32_t>("CROSSBAR_NUM_IN_SEG"); + uint32_t num_out_seg = orion_cfg_ptr_->get<uint32_t>("CROSSBAR_NUM_OUT_SEG"); + double len_in_wire = orion_cfg_ptr_->get<double>("CROSSBAR_LEN_IN_WIRE"); + double len_out_wire = orion_cfg_ptr_->get<double>("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<string>("CROSSBAR_CONNECT_TYPE"); + const string& trans_type_str = orion_cfg_ptr_->get<string>("CROSSBAR_TRANS_GATE_TYPE"); + uint32_t degree = orion_cfg_ptr_->get<uint32_t>("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 --git a/src/mem/ruby/network/orion/Crossbar/Crossbar.hh b/src/mem/ruby/network/orion/Crossbar/Crossbar.hh new file mode 100644 index 000000000..dc695880d --- /dev/null +++ b/src/mem/ruby/network/orion/Crossbar/Crossbar.hh @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 --git a/src/mem/ruby/network/orion/Crossbar/MatrixCrossbar.cc b/src/mem/ruby/network/orion/Crossbar/MatrixCrossbar.cc new file mode 100644 index 000000000..f283f6176 --- /dev/null +++ b/src/mem/ruby/network/orion/Crossbar/MatrixCrossbar.cc @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 <iostream> +#include <cassert> + +#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 --git a/src/mem/ruby/network/orion/Crossbar/MatrixCrossbar.hh b/src/mem/ruby/network/orion/Crossbar/MatrixCrossbar.hh new file mode 100644 index 000000000..cbfcf9fc7 --- /dev/null +++ b/src/mem/ruby/network/orion/Crossbar/MatrixCrossbar.hh @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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/Type.hh" +#include "mem/ruby/network/orion/Crossbar/Crossbar.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 --git a/src/mem/ruby/network/orion/Crossbar/MultreeCrossbar.cc b/src/mem/ruby/network/orion/Crossbar/MultreeCrossbar.cc new file mode 100644 index 000000000..44fa43cac --- /dev/null +++ b/src/mem/ruby/network/orion/Crossbar/MultreeCrossbar.cc @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 <iostream> +#include <cmath> + +#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 --git a/src/mem/ruby/network/orion/power_bus.hh b/src/mem/ruby/network/orion/Crossbar/MultreeCrossbar.hh index e1c3ef565..bac8b22cd 100644 --- a/src/mem/ruby/network/orion/power_bus.hh +++ b/src/mem/ruby/network/orion/Crossbar/MultreeCrossbar.hh @@ -1,5 +1,6 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2009 Princeton University, and + * Regents of the University of California * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,41 +25,45 @@ * 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 _POWER_BUS_H -#define _POWER_BUS_H - -typedef enum { - RESULT_BUS = 1, - GENERIC_BUS, - BUS_MAX_MODEL -} power_bus_model; +#ifndef __MULTREECROSSBAR_H__ +#define __MULTREECROSSBAR_H__ -typedef enum { - IDENT_ENC = 1, /* identity encoding */ - TRANS_ENC, /* transition encoding */ - BUSINV_ENC, /* bus inversion encoding */ - BUS_MAX_ENC -} power_bus_enc; +#include "mem/ruby/network/orion/Type.hh" +#include "mem/ruby/network/orion/Crossbar/Crossbar.hh" +class TechParameter; -typedef struct { - int model; - int encoding; - unsigned data_width; - unsigned grp_width; - unsigned long int n_switch; - double e_switch; - /* redundant field */ - unsigned bit_width; - unsigned long int bus_mask; -} power_bus; +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(); -extern int power_bus_init(power_bus *bus, int model, int encoding, unsigned width, unsigned grp_width, unsigned n_snd, unsigned n_rcv, double length, double time); + public: + double get_dynamic_energy(bool is_max_) const; -extern int bus_record(power_bus *bus, unsigned long int old_state, unsigned long int new_state); + private: + void init(); + double calc_i_static(); -extern double bus_report(power_bus *bus); + private: + uint32_t m_depth; +}; #endif diff --git a/src/mem/ruby/network/orion/Crossbar/SConscript b/src/mem/ruby/network/orion/Crossbar/SConscript new file mode 100644 index 000000000..76774da1b --- /dev/null +++ b/src/mem/ruby/network/orion/Crossbar/SConscript @@ -0,0 +1,36 @@ +# 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 not env['RUBY']: + Return() + +Source('Crossbar.cc') +Source('MatrixCrossbar.cc') +Source('MultreeCrossbar.cc') diff --git a/src/mem/ruby/network/orion/FlipFlop.cc b/src/mem/ruby/network/orion/FlipFlop.cc new file mode 100644 index 000000000..5b76d0a23 --- /dev/null +++ b/src/mem/ruby/network/orion/FlipFlop.cc @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 <iostream> +#include <cassert> + +#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 --git a/src/mem/ruby/network/orion/FlipFlop.hh b/src/mem/ruby/network/orion/FlipFlop.hh new file mode 100644 index 000000000..a34e6d987 --- /dev/null +++ b/src/mem/ruby/network/orion/FlipFlop.hh @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 --git a/src/mem/ruby/network/orion/NetworkPower.cc b/src/mem/ruby/network/orion/NetworkPower.cc index 2c0561438..7d4aae3ed 100644 --- a/src/mem/ruby/network/orion/NetworkPower.cc +++ b/src/mem/ruby/network/orion/NetworkPower.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2010 Massachusetts Institute of Technology * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,407 +24,236 @@ * 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 <stdio.h> -#include <math.h> - -#include "mem/ruby/network/orion/power_router_init.hh" -#include "mem/ruby/network/orion/power_array.hh" -#include "mem/ruby/network/orion/power_crossbar.hh" -#include "mem/ruby/network/orion/power_arbiter.hh" -#include "mem/ruby/network/orion/power_bus.hh" #include "mem/ruby/network/orion/NetworkPower.hh" -#include "mem/ruby/network/garnet/fixed-pipeline/Router_d.hh" -#include "mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh" -#include "mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.hh" -#include "mem/ruby/network/orion/SIM_port.hh" -#include "mem/ruby/network/orion/parm_technology.hh" - -/* --------- Static energy calculation functions ------------ */ +#include "mem/ruby/network/orion/OrionConfig.hh" +#include "mem/ruby/network/orion/OrionRouter.hh" +#include "mem/ruby/network/orion/OrionLink.hh" -//Input buffer -double SIM_reg_stat_energy(power_array_info *info, power_array *arr, double n_read, double n_write) +double +Router_d::calculate_power() { - double Eavg = 0, Eatomic, Estruct, Estatic; - - - /* decoder */ - if (info->row_dec_model) { - //row decoder - Estruct = 0; - /* assume switch probability 0.5 for address bits */ - //input - Eatomic = arr->row_dec.e_chg_addr * arr->row_dec.n_bits * SWITCHING_FACTOR * (n_read + n_write); - Estruct += Eatomic; - - //output - Eatomic = arr->row_dec.e_chg_output * (n_read + n_write); - Estruct += Eatomic; - - /* assume all 1st-level decoders change output */ - //internal node - Eatomic = arr->row_dec.e_chg_l1 * arr->row_dec.n_in_2nd * (n_read + n_write); - Estruct += Eatomic; - - Eavg += Estruct; - } - - /* wordline */ - Estruct = 0; - //read - Eatomic = arr->data_wordline.e_read * n_read; - Estruct += Eatomic; - //write - Eatomic = arr->data_wordline.e_write * n_write; - Estruct += Eatomic; - - Eavg += Estruct; - - /* bitlines */ - Estruct = 0; - //read - if (arr->data_bitline.end == 2) { - Eatomic = arr->data_bitline.e_col_read * info->eff_data_cols * n_read; - } - else { - /* assume switch probability 0.5 for single-ended bitlines */ - Eatomic = arr->data_bitline.e_col_read * info->eff_data_cols * SWITCHING_FACTOR * n_read; - } - - Estruct += Eatomic; - //write - /* assume switch probability 0.5 for write bitlines */ - Eatomic = arr->data_bitline.e_col_write * info->data_width * SWITCHING_FACTOR * n_write; - Estruct += Eatomic; - //precharge - Eatomic = arr->data_bitline_pre.e_charge * info->eff_data_cols * n_read; - Estruct += Eatomic; - - Eavg += Estruct; - - /* memory cells */ - Estruct = 0; - - /* assume switch probability 0.5 for memory cells */ - Eatomic = arr->data_mem.e_switch * info->data_width * SWITCHING_FACTOR * n_write; - Estruct += Eatomic; - - Eavg += Estruct; - - /* sense amplifier */ - if (info->data_end == 2) { - Estruct = 0; - - Eatomic = arr->data_amp.e_access * info->eff_data_cols * n_read; - Estruct += Eatomic; - - Eavg += Estruct; - } - - /* output driver */ - if (info->outdrv_model) { - Estruct = 0; - //enable - Eatomic = arr->outdrv.e_select * n_read; - Estruct += Eatomic; - //data - /* same switch probability as bitlines */ - Eatomic = arr->outdrv.e_chg_data * arr->outdrv.item_width * SWITCHING_FACTOR * info->n_item * info->assoc * n_read; - Estruct += Eatomic; - //output 1 - /* assume 1 and 0 are uniformly distributed */ - if (arr->outdrv.e_out_1 >= arr->outdrv.e_out_0 ) { - Eatomic = arr->outdrv.e_out_1 * arr->outdrv.item_width * SWITCHING_FACTOR * n_read; - Estruct += Eatomic; + //Network Activities from garnet + calculate_performance_numbers(); + double sim_cycles; + sim_cycles = g_eventQueue_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<bool > active_vclass_ary; + active_vclass_ary.resize(m_virtual_networks); + + std::vector<double > vc_local_arbit_count_active; + std::vector<double > vc_global_arbit_count_active; + std::vector<double > buf_read_count_active; + std::vector<double > buf_write_count_active; + + for (int i =0; i < m_virtual_networks; i++) { + if (vc_local_arbit_count[i] > 0) { + num_active_vclass++; + active_vclass_ary[i] = true; + 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); + active_vclass_ary[i] = false; + } } - //output 0 - if (arr->outdrv.e_out_1 < arr->outdrv.e_out_0) { - Eatomic = arr->outdrv.e_out_0 * arr->outdrv.item_width * SWITCHING_FACTOR * n_read; - Estruct += Eatomic; - } - - Eavg += Estruct; - } - - /* static power */ - Estatic = arr->i_leakage * Vdd * Period * SCALE_S; - - //static energy - Eavg += Estatic; - - return Eavg; -} - -//crossbar -double SIM_crossbar_stat_energy(power_crossbar *crsbar, double n_data) -{ - double Eavg = 0, Eatomic; - - if (n_data > crsbar->n_out) { - n_data = crsbar->n_out; - } - - - switch (crsbar->model) { - case MATRIX_CROSSBAR: - case CUT_THRU_CROSSBAR: - case MULTREE_CROSSBAR: - /* assume 0.5 data switch probability */ - //input - Eatomic = crsbar->e_chg_in * crsbar->data_width * SWITCHING_FACTOR * n_data; - Eavg += Eatomic; - - //output - Eatomic = crsbar->e_chg_out * crsbar->data_width * SWITCHING_FACTOR * n_data; - Eavg += Eatomic; - - //control - Eatomic = crsbar->e_chg_ctr * n_data; - Eavg += Eatomic; - - if (crsbar->model == MULTREE_CROSSBAR && crsbar->depth > 1) { - //internal node - Eatomic = crsbar->e_chg_int * crsbar->data_width * (crsbar->depth - 1) * SWITCHING_FACTOR * n_data; - Eavg += Eatomic; - } - break; - default: break;/* some error handler */ - } - - return Eavg; -} + // 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<double>("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<uint32_t > 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(); + uint32_t flit_width = m_flit_width * 8; //flit width in bits + + 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, + 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 Pclk_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; + } -//arbiter -/* stat over one cycle */ -/* info is only used by queuing arbiter */ -double SIM_arbiter_stat_energy(power_arbiter *arb, power_array_info *info, double n_req) -{ - double Eavg = 0, Estruct, Eatomic; - double total_pri, n_chg_pri, n_grant; - - /* energy cycle distribution */ - if (n_req > arb->req_width) { - n_req = arb->req_width; - } - if (n_req >= 1) n_grant = 1; - else n_grant = 1.0 / ceil(1.0 / n_req); - - switch (arb->model) { - case RR_ARBITER: - /* FIXME: we may overestimate request switch */ - //request - Eatomic = arb->e_chg_req * n_req; - Eavg += Eatomic; - - //grant - Eatomic = arb->e_chg_grant * n_grant; - Eavg += Eatomic; - - /* assume carry signal propagates half length in average case */ - /* carry does not propagate in maximum case, i.e. all carrys go down */ - //carry - Eatomic = arb->e_chg_carry * arb->req_width * SWITCHING_FACTOR * n_grant; - Eavg += Eatomic; - - //internal carry - Eatomic = arb->e_chg_carry_in * (arb->req_width * SWITCHING_FACTOR - 1) * n_grant; - Eavg += Eatomic; - - /* priority registers */ - Estruct = 0; - //priority - - //switch - Eatomic = arb->pri_ff.e_switch * 2 * n_grant; - Estruct += Eatomic; - - //keep 0 - Eatomic = arb->pri_ff.e_keep_0 * (arb->req_width - 2 * n_grant); - Estruct += Eatomic; - - //clock - Eatomic = arb->pri_ff.e_clock * arb->req_width; - Estruct += Eatomic; - - Eavg += Estruct; - break; - - case MATRIX_ARBITER: - total_pri = arb->req_width * (arb->req_width - 1) * 0.5; - /* assume switch probability 0.5 for priorities */ - n_chg_pri = (arb->req_width - 1) * SWITCHING_FACTOR; - - /* FIXME: we may overestimate request switch */ - //request - Eatomic = arb->e_chg_req * n_req; - Eavg += Eatomic; - - //grant - Eatomic = arb->e_chg_grant * n_grant; - Eavg += Eatomic; - - /* priority registers */ - Estruct = 0; - //priority - - //switch - Eatomic = arb->pri_ff.e_switch * n_chg_pri * n_grant; - Estruct += Eatomic; - - /* assume 1 and 0 are uniformly distributed */ - //keep 0 - if (arb->pri_ff.e_keep_0 >= arb->pri_ff.e_keep_1) { - Eatomic = arb->pri_ff.e_keep_0 * (total_pri - n_chg_pri * n_grant) * SWITCHING_FACTOR; - Estruct += Eatomic; - } - - //keep 1 - if (arb->pri_ff.e_keep_0 < arb->pri_ff.e_keep_1) { - Eatomic = arb->pri_ff.e_keep_1 * (total_pri - n_chg_pri * n_grant) * SWITCHING_FACTOR; - Estruct += Eatomic; - } - - //clock - Eatomic = arb->pri_ff.e_clock * total_pri; - Estruct += Eatomic; - - Eavg += Estruct; - - /* based on above assumptions */ - //internal node - /* p(n-1)/2 + (n-1)/2 */ - Eatomic = arb->e_chg_mint * (n_req + 1) * (arb->req_width - 1) * 0.5; - Eavg += Eatomic; - break; - - case QUEUE_ARBITER: - /* FIXME: what if n_req > 1? */ - Eavg = SIM_reg_stat_energy(info, &arb->queue, n_req, n_grant); - break; - - default: break;/* some error handler */ - } - - - return Eavg; + // 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; + + // Clock + Pclk_dyn += orion_rtr_ptr->calc_dynamic_energy_clock()*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 + + Pclk_dyn; + + + // 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; + + Ptotal = Ptotal_dyn + Ptotal_sta; + + return Ptotal; } -double SIM_bus_stat_energy(power_bus *bus, double e_link) +double +NetworkLink_d::calculate_power() { - double Ebus; - Ebus = bus->e_switch * e_link * SWITCHING_FACTOR * bus->bit_width; - - return (Ebus); -} + OrionConfig* orion_cfg_ptr; + OrionLink* orion_link_ptr; + static double freq_Hz; + double link_length; + int channel_width; -double Router_d::calculate_offline_power(power_router *router, power_router_info *info) -{ - double Eavg = 0; - double P_in_buf, P_xbar, P_vc_in_arb, P_vc_out_arb, P_sw_in_arb, P_sw_out_arb, P_leakage, P_total; - - double E_in_buf, E_xbar, E_vc_in_arb, E_vc_out_arb, E_sw_in_arb, E_sw_out_arb, E_leakage; - double e_in_buf_read, e_in_buf_write, e_crossbar, e_vc_local_arb, e_vc_global_arb, e_sw_local_arb, e_sw_global_arb; - double sim_cycles; - - sim_cycles = g_eventQueue_ptr->getTime() - m_network_ptr->getRubyStartTime(); - - calculate_performance_numbers(); - //counts obtained from perf. simulator - e_in_buf_read = (double )(buf_read_count/sim_cycles); - e_in_buf_write = (double )(buf_write_count/sim_cycles); - e_crossbar = (double )(crossbar_count/sim_cycles); - e_vc_local_arb = (double)(vc_local_arbit_count/sim_cycles); - e_vc_global_arb = (double)(vc_global_arbit_count/sim_cycles); - e_sw_local_arb = (double )(sw_local_arbit_count/sim_cycles); - e_sw_global_arb = (double )(sw_global_arbit_count/sim_cycles); - // e_link = (double )(link_traversal_count/sim_cycles); - - /* input buffers */ - if (info->in_buf) - E_in_buf = SIM_reg_stat_energy(&info->in_buf_info, &router->in_buf, e_in_buf_read, e_in_buf_write); - P_in_buf = E_in_buf * PARM_Freq; - Eavg += E_in_buf; - - /* main crossbar */ - if (info->crossbar_model) - E_xbar= SIM_crossbar_stat_energy(&router->crossbar, e_crossbar); - P_xbar = E_xbar * PARM_Freq; - Eavg += E_xbar; - - /* vc input (local) arbiter */ - if (info->vc_in_arb_model) - E_vc_in_arb = SIM_arbiter_stat_energy(&router->vc_in_arb, &info->vc_in_arb_queue_info, e_sw_local_arb); - P_vc_in_arb = E_vc_in_arb * PARM_Freq; - Eavg += E_vc_in_arb; - - /* vc output (global) arbiter */ - if (info->vc_out_arb_model) - E_vc_out_arb = SIM_arbiter_stat_energy(&router->vc_out_arb, &info->vc_out_arb_queue_info, e_sw_global_arb); - P_vc_out_arb = E_vc_out_arb * PARM_Freq; - Eavg += E_vc_out_arb; - - /* sw input (local) arbiter */ - if (info->sw_in_arb_model) - E_sw_in_arb = SIM_arbiter_stat_energy(&router->sw_in_arb, &info->sw_in_arb_queue_info, e_sw_local_arb); - P_sw_in_arb = E_sw_in_arb * PARM_Freq; - Eavg += E_sw_in_arb; - - /* sw output (global) arbiter */ - if (info->sw_out_arb_model) - E_sw_out_arb = SIM_arbiter_stat_energy(&router->sw_out_arb, &info->sw_out_arb_queue_info, e_sw_global_arb); - P_sw_out_arb = E_sw_out_arb * PARM_Freq; - Eavg += E_sw_out_arb; - - /* static power */ - E_leakage = router->i_leakage * Vdd * Period * SCALE_S; - P_leakage = E_leakage * PARM_Freq; - Eavg += E_leakage; - - P_total = Eavg * PARM_Freq; - - return Eavg; -} + // 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<double>("FREQUENCY"); -double NetworkLink_d::calculate_offline_power(power_bus* bus) -{ - double sim_cycles = (double) (g_eventQueue_ptr->getTime() - m_net_ptr->getRubyStartTime()); - double e_link = (double) (m_link_utilized)/ sim_cycles; - double E_link = SIM_bus_stat_energy(bus, e_link); - double P_link = E_link * PARM_Freq; - return P_link; -} + link_length = orion_cfg_ptr->get<double>("LINK_LENGTH"); + channel_width = m_net_ptr->getFlitSize(); -double NetworkLink_d::calculate_power() -{ - power_bus bus; - power_bus_init(&bus, GENERIC_BUS, IDENT_ENC, PARM_flit_width, 0, 1, 1, PARM_link_length, 0); - double total_power = calculate_offline_power(&bus); - return total_power; -} + orion_link_ptr = new OrionLink( + link_length, + channel_width /* channel width */, + orion_cfg_ptr); -void Router_d::power_router_initialize(power_router *router, power_router_info *info) -{ - info->n_in = m_input_unit.size(); - info->n_out = m_output_unit.size(); - info->flit_width = PARM_flit_width; - info->n_v_channel = m_num_vcs; - info->n_v_class = m_virtual_networks; + // Dynamic Power + double sim_cycles = + (double)(g_eventQueue_ptr->getTime() - m_net_ptr->getRubyStartTime()); -} + double Plink_dyn = orion_link_ptr->calc_dynamic_energy(channel_width/2)* + (m_link_utilized/ sim_cycles)*freq_Hz; -double Router_d::calculate_power() -{ - power_router router; - power_router_info router_info; - double total_energy, total_power; + // Static Power + double Plink_sta = orion_link_ptr->get_static_power(); - power_router_initialize(&router, &router_info); - power_router_init(&router, &router_info); + double Ptotal = Plink_dyn + Plink_sta; - total_energy = calculate_offline_power(&router, &router_info); - total_power = total_energy * PARM_Freq; - return total_power; + return Ptotal; } diff --git a/src/mem/ruby/network/orion/NetworkPower.hh b/src/mem/ruby/network/orion/NetworkPower.hh index 560d58376..591f45362 100644 --- a/src/mem/ruby/network/orion/NetworkPower.hh +++ b/src/mem/ruby/network/orion/NetworkPower.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2010 Massachusetts Institute of Technology * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,9 +24,24 @@ * 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 _NETWORK_POWER_H -#define _NETWORK_POWER_H +#ifndef POWER_TRACE_H +#define POWER_TRACE_H + +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> + +#include "mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh" +#include "mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.hh" +#include "mem/ruby/network/garnet/fixed-pipeline/Router_d.hh" + +//int RW : +#define READ_MODE 0 +#define WRITE_MODE 1 #endif diff --git a/src/mem/ruby/network/orion/OrionConfig.cc b/src/mem/ruby/network/orion/OrionConfig.cc new file mode 100644 index 000000000..a4ac55a36 --- /dev/null +++ b/src/mem/ruby/network/orion/OrionConfig.cc @@ -0,0 +1,201 @@ +/* + * 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 <iostream> +#include <string> + +#include "mem/ruby/network/orion/OrionConfig.hh" +#include "mem/ruby/network/orion/ConfigFile.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<uint32_t>(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<uint32_t>(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<uint32_t>(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<uint32_t>(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<uint32_t>(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<uint32_t>(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<uint32_t>("NUM_INPUT_PORT"); + m_num_out_port = get<uint32_t>("NUM_OUTPUT_PORT"); + m_num_vclass = get<uint32_t>("NUM_VIRTUAL_CLASS"); + m_num_vchannel = get<uint32_t>("NUM_VIRTUAL_CHANNEL"); + m_in_buf_num_set = get<uint32_t>("IN_BUF_NUM_SET"); + m_flit_width = get<uint32_t>("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 --git a/src/mem/ruby/network/orion/OrionConfig.hh b/src/mem/ruby/network/orion/OrionConfig.hh new file mode 100644 index 000000000..78131e3c5 --- /dev/null +++ b/src/mem/ruby/network/orion/OrionConfig.hh @@ -0,0 +1,158 @@ +/* + * 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 <iostream> +#include <sstream> +#include <map> + +#include "mem/ruby/network/orion/Type.hh" + +using namespace std; + +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 string& filename_); + void print_config(ostream& out_); + + public: + template<class T> + T get(const 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: + map<string, string> 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 + { + string m_key; + key_not_found(const string& key_ = string()) : m_key(key_) + {} + }; + template<class T> + static T string_as_T(const string& str_); + template<class T> + static string T_as_string(const T& t_); + + private: + static string ms_param_name[]; +}; + +template<class T> +T OrionConfig::get(const string& key_) const +{ + map<string, string>::const_iterator it; + + it = m_params_map.find(key_); + if (it == m_params_map.end()) + { + cerr << key_ << " NOT FOUND!" << endl; + throw key_not_found(key_); + } + return string_as_T<T>(it->second); +} + + template<class T> +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<string>(const string& str_) +{ + return str_; +} + +template<> +inline bool OrionConfig::string_as_T<bool>(const string& str_) +{ + bool ret; + if (str_ == string("TRUE")) + { + ret = true; + } + else if (str_ == string("FALSE")) + { + ret = false; + } + else + { + cerr << "Invalid bool value: '" << str_ << "'. Treated as FALSE." << endl; + ret = false; + } + return ret; +} + +template<class T> +string OrionConfig::T_as_string(const T& t) +{ + std::ostringstream ost; + ost << t; + return ost.str(); +} + +#endif + diff --git a/src/mem/ruby/network/orion/OrionLink.cc b/src/mem/ruby/network/orion/OrionLink.cc new file mode 100644 index 000000000..38ddd0459 --- /dev/null +++ b/src/mem/ruby/network/orion/OrionLink.cc @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 <iostream> +#include <cassert> + +#include "mem/ruby/network/orion/OrionLink.hh" +#include "mem/ruby/network/orion/OrionConfig.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<string>("WIRE_WIDTH_SPACING"); + const string& buf_scheme_str = m_orion_cfg_ptr->get<string>("WIRE_BUFFERING_MODEL"); + bool is_shielding = m_orion_cfg_ptr->get<bool>("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 --git a/src/mem/ruby/network/orion/OrionLink.hh b/src/mem/ruby/network/orion/OrionLink.hh new file mode 100644 index 000000000..8cdcc945d --- /dev/null +++ b/src/mem/ruby/network/orion/OrionLink.hh @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 --git a/src/mem/ruby/network/orion/OrionRouter.cc b/src/mem/ruby/network/orion/OrionRouter.cc new file mode 100644 index 000000000..1dd92d885 --- /dev/null +++ b/src/mem/ruby/network/orion/OrionRouter.cc @@ -0,0 +1,495 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 <cassert> + +#include "OrionRouter.hh" +#include "mem/ruby/network/orion/OrionConfig.hh" +#include "mem/ruby/network/orion/Buffer/Buffer.hh" +#include "mem/ruby/network/orion/Crossbar/Crossbar.hh" +#include "mem/ruby/network/orion/Allocator/VCAllocator.hh" +#include "mem/ruby/network/orion/Allocator/SWAllocator.hh" +#include "mem/ruby/network/orion/Clock.hh" + +OrionRouter::OrionRouter( + uint32_t num_in_port_, + uint32_t num_out_port_, + uint32_t num_vclass_, + std::vector<uint32_t > 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<uint32_t>("NUM_INPUT_PORT"); + m_num_out_port = m_orion_cfg_ptr->get<uint32_t>("NUM_OUTPUT_PORT"); + m_flit_width = m_orion_cfg_ptr->get<uint32_t>("FLIT_WIDTH"); + m_num_vclass = m_orion_cfg_ptr->get<uint32_t>("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<bool>("IS_IN_SHARED_BUFFER"); + m_is_out_shared_buf = m_orion_cfg_ptr->get<bool>("IS_OUT_SHARED_BUFFER"); + m_is_in_shared_switch = m_orion_cfg_ptr->get<bool>("IS_IN_SHARED_SWITCH"); + m_is_out_shared_switch = m_orion_cfg_ptr->get<bool>("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<bool>("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<string>("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<uint32_t>("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<bool>("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<uint32_t>("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<uint32_t>("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<string>("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<string>("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 --git a/src/mem/ruby/network/orion/OrionRouter.hh b/src/mem/ruby/network/orion/OrionRouter.hh new file mode 100644 index 000000000..f2a8ce52d --- /dev/null +++ b/src/mem/ruby/network/orion/OrionRouter.hh @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 <vector> + +#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<uint32_t > 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 --git a/src/mem/ruby/network/orion/SConscript b/src/mem/ruby/network/orion/SConscript index 99b38bc22..8a6383bfb 100644 --- a/src/mem/ruby/network/orion/SConscript +++ b/src/mem/ruby/network/orion/SConscript @@ -1,6 +1,3 @@ -# -*- mode:python -*- - -# Copyright (c) 2009 The Hewlett-Packard Development Company # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -26,19 +23,19 @@ # (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: Nathan Binkert +# Authors: Tushar Krishna Import('*') if not env['RUBY']: Return() -Source('NetworkPower.cc', Werror=False) -Source('power_arbiter.cc') -Source('power_array.cc', Werror=False) -Source('power_bus.cc', Werror=False) -Source('power_crossbar.cc', Werror=False) -Source('power_ll.cc', Werror=False) -Source('power_router_init.cc') -Source('power_static.cc') -Source('power_utils.cc', Werror=False) +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 --git a/src/mem/ruby/network/orion/SIM_port.hh b/src/mem/ruby/network/orion/SIM_port.hh deleted file mode 100644 index 96d26daad..000000000 --- a/src/mem/ruby/network/orion/SIM_port.hh +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _SIM_PORT_H -#define _SIM_PORT_H - -#define PARM_POWER_STATS 1 - -/* RF module parameters */ -#define PARM_read_port 1 -#define PARM_write_port 1 -#define PARM_n_regs 64 -#define PARM_reg_width 32 - -#define PARM_ndwl 1 -#define PARM_ndbl 1 -#define PARM_nspd 1 - -//Niket - -#define PARM_vc_in_arb_model QUEUE_ARBITER -#define PARM_vc_out_arb_model QUEUE_ARBITER -#define PARM_vc_in_arb_ff_model NEG_DFF -#define PARM_vc_out_arb_ff_model NEG_DFF -#define PARM_sw_in_arb_model QUEUE_ARBITER -#define PARM_sw_out_arb_model QUEUE_ARBITER -#define PARM_sw_in_arb_ff_model NEG_DFF -#define PARM_sw_out_arb_ff_model NEG_DFF -#define PARM_VC_per_MC 4 - -//Niket - -//#define PARM_wordline_model CACHE_RW_WORDLINE -//#define PARM_bitline_model RW_BITLINE -//#define PARM_mem_model NORMAL_MEM -//#define PARM_row_dec_model SIM_NO_MODEL -//#define PARM_row_dec_pre_model SIM_NO_MODEL -//#define PARM_col_dec_model SIM_NO_MODEL -//#define PARM_col_dec_pre_model SIM_NO_MODEL -//#define PARM_mux_model SIM_NO_MODEL -//#define PARM_outdrv_model SIM_NO_MODEL - -/* these 3 should be changed together */ -//#define PARM_data_end 2 -//#define PARM_amp_model GENERIC_AMP -//#define PARM_bitline_pre_model EQU_BITLINE -//#define PARM_data_end 1 -//#define PARM_amp_model SIM_NO_MODEL -//#define PARM_bitline_pre_model SINGLE_OTHER - - -/* router module parameters */ -/* general parameters */ -#define PARM_in_port 9 -#define PARM_cache_in_port 0 /* # of cache input ports */ -#define PARM_mc_in_port 0 /* # of memory controller input ports */ -#define PARM_io_in_port 0 /* # of I/O device input ports */ -#define PARM_out_port 9 -#define PARM_cache_out_port 0 /* # of cache output ports */ -#define PARM_mc_out_port 0 /* # of memory controller output ports */ -#define PARM_io_out_port 0 /* # of I/O device output ports */ -#define PARM_flit_width 128 /* flit width in bits */ - -/* virtual channel parameters */ -#define PARM_v_channel 1 /* # of network port virtual channels */ -#define PARM_v_class 0 /* # of total virtual classes */ -#define PARM_cache_class 0 /* # of cache port virtual classes */ -#define PARM_mc_class 0 /* # of memory controller port virtual classes */ -#define PARM_io_class 0 /* # of I/O device port virtual classes */ -/* ?? */ -#define PARM_in_share_buf 0 /* do input virtual channels physically share buffers? */ -#define PARM_out_share_buf 0 /* do output virtual channels physically share buffers? */ -/* ?? */ -#define PARM_in_share_switch 1 /* do input virtual channels share crossbar input ports? */ -#define PARM_out_share_switch 1 /* do output virtual channels share crossbar output ports? */ - -/* crossbar parameters */ -#define PARM_crossbar_model MATRIX_CROSSBAR /* crossbar model type */ -#define PARM_crsbar_degree 4 /* crossbar mux degree */ -#define PARM_connect_type TRISTATE_GATE /* crossbar connector type */ -#define PARM_trans_type NP_GATE /* crossbar transmission gate type */ -#define PARM_crossbar_in_len 0 /* crossbar input line length, if known */ -#define PARM_crossbar_out_len 0 /* crossbar output line length, if known */ -#define PARM_xb_in_seg 0 -#define PARM_xb_out_seg 0 -/* HACK HACK HACK */ -#define PARM_exp_xb_model MATRIX_CROSSBAR -#define PARM_exp_in_seg 2 -#define PARM_exp_out_seg 2 - -/* input buffer parameters */ -#define PARM_in_buf 1 /* have input buffer? */ -#define PARM_in_buf_set 4 -#define PARM_in_buf_rport 1 /* # of read ports */ - -#define PARM_cache_in_buf 0 -#define PARM_cache_in_buf_set 0 -#define PARM_cache_in_buf_rport 0 - -#define PARM_mc_in_buf 0 -#define PARM_mc_in_buf_set 0 -#define PARM_mc_in_buf_rport 0 - -#define PARM_io_in_buf 0 -#define PARM_io_in_buf_set 0 -#define PARM_io_in_buf_rport 0 - -/* output buffer parameters */ -#define PARM_out_buf 0 -#define PARM_out_buf_set 4 -#define PARM_out_buf_wport 1 - -/* central buffer parameters */ -#define PARM_central_buf 0 /* have central buffer? */ -#define PARM_cbuf_set 2560 /* # of rows */ -#define PARM_cbuf_rport 2 /* # of read ports */ -#define PARM_cbuf_wport 2 /* # of write ports */ -#define PARM_cbuf_width 4 /* # of flits in one row */ -#define PARM_pipe_depth 4 /* # of banks */ - -/* array parameters shared by various buffers */ -#define PARM_wordline_model CACHE_RW_WORDLINE -#define PARM_bitline_model RW_BITLINE -#define PARM_mem_model NORMAL_MEM -#define PARM_row_dec_model GENERIC_DEC -#define PARM_row_dec_pre_model SINGLE_OTHER -#define PARM_col_dec_model SIM_NO_MODEL -#define PARM_col_dec_pre_model SIM_NO_MODEL -#define PARM_mux_model SIM_NO_MODEL -#define PARM_outdrv_model REG_OUTDRV - -/* these 3 should be changed together */ -/* use double-ended bitline because the array is too large */ -#define PARM_data_end 2 -#define PARM_amp_model GENERIC_AMP -#define PARM_bitline_pre_model EQU_BITLINE -//#define PARM_data_end 1 -//#define PARM_amp_model SIM_NO_MODEL -//#define PARM_bitline_pre_model SINGLE_OTHER - -/* arbiter parameters */ -#define PARM_in_arb_model MATRIX_ARBITER /* input side arbiter model type */ -#define PARM_in_arb_ff_model NEG_DFF /* input side arbiter flip-flop model type */ -#define PARM_out_arb_model MATRIX_ARBITER /* output side arbiter model type */ -#define PARM_out_arb_ff_model NEG_DFF /* output side arbiter flip-flop model type */ - -#endif /* _SIM_PORT_H */ diff --git a/src/mem/ruby/network/orion/SIM_power.hh b/src/mem/ruby/network/orion/SIM_power.hh deleted file mode 100644 index aa8448436..000000000 --- a/src/mem/ruby/network/orion/SIM_power.hh +++ /dev/null @@ -1,385 +0,0 @@ -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _SIM_POWER_H -#define _SIM_POWER_H - -#include <sys/types.h> -#include "mem/ruby/network/orion/SIM_power_test.hh" - -#define SIM_NO_MODEL 0 - -#define MAX_ENERGY 1 -#define AVG_ENERGY 0 -#ifndef MAX -#define MAX(a,b) (((a)>(b))?(a):(b)) -#endif -#ifndef MIN -#define MIN(a,b) (((a)>(b))?(b):(a)) -#endif - -#define NEXT_DEPTH(d) ((d) > 0 ? (d) - 1 : (d)) - -#define BIGNUM 1e30 -#define BIGONE ((LIB_Type_max_uint)1) -#define BIGNONE ((LIB_Type_max_uint)-1) -#define HAMM_MASK(w) ((unsigned int)w < (sizeof(LIB_Type_max_uint) << 3) ? (BIGONE << w) - 1 : BIGNONE) - -/* Used to communicate with the horowitz model */ -#define RISE 1 -#define FALL 0 -#define NCH 1 -#define PCH 0 - -/* - * Cache layout parameters and process parameters - * Thanks to Glenn Reinman for the technology scaling factors - */ -#if ( PARM(TECH_POINT) == 10 ) -#define CSCALE (84.2172) /* wire capacitance scaling factor */ - /* linear: 51.7172, predicted: 84.2172 */ -#define RSCALE (80.0000) /* wire resistance scaling factor */ -#define LSCALE 0.1250 /* length (feature) scaling factor */ -#define ASCALE (LSCALE*LSCALE) /* area scaling factor */ -#define VSCALE 0.38 /* voltage scaling factor */ -#define VTSCALE 0.49 /* threshold voltage scaling factor */ -#define SSCALE 0.80 /* sense voltage scaling factor */ -/* FIXME: borrowed from 0.11u technology */ -#define MCSCALE 5.2277 /* metal coupling capacitance scaling factor */ -#define MCSCALE2 3 /* metal coupling capacitance scaling factor (2X) */ -#define MCSCALE3 1.5 /* metal coupling capacitance scaling factor (3X) */ -#define GEN_POWER_SCALE (1/PARM(GEN_POWER_FACTOR)) -/* copied from TECH_POINT 10 except LSCALE */ -#elif ( PARM(TECH_POINT) == 11 ) -#define CSCALE (84.2172) /* wire capacitance scaling factor */ -#define RSCALE (80.0000) /* wire resistance scaling factor */ -#define LSCALE 0.1375 /* length (feature) scaling factor */ -#define ASCALE (LSCALE*LSCALE) /* area scaling factor */ -#define VSCALE 0.38 /* voltage scaling factor */ -#define VTSCALE 0.49 /* threshold voltage scaling factor */ -#define SSCALE 0.80 /* sense voltage scaling factor */ -#define MCSCALE 5.2277 /* metal coupling capacitance scaling factor */ -#define MCSCALE2 3 /* metal coupling capacitance scaling factor (2X) */ -#define MCSCALE3 1.5 /* metal coupling capacitance scaling factor (3X) */ -#define GEN_POWER_SCALE (1/PARM(GEN_POWER_FACTOR)) -#elif ( PARM(TECH_POINT) == 18 ) -#define CSCALE (19.7172) /* wire capacitance scaling factor */ -#define RSCALE (20.0000) /* wire resistance scaling factor */ -#define LSCALE 0.2250 /* length (feature) scaling factor */ -#define ASCALE (LSCALE*LSCALE) /* area scaling factor */ -#define VSCALE 0.4 /* voltage scaling factor */ -#define VTSCALE 0.5046 /* threshold voltage scaling factor */ -#define SSCALE 0.85 /* sense voltage scaling factor */ -#define MCSCALE 4.1250 /* metal coupling capacitance scaling factor */ -#define MCSCALE2 2.4444 /* metal coupling capacitance scaling factor (2X) */ -#define MCSCALE3 1.2 /* metal coupling capacitance scaling factor (3X) */ -#define GEN_POWER_SCALE 1 -#elif ( PARM(TECH_POINT) == 25 ) -#define CSCALE (10.2197) /* wire capacitance scaling factor */ -#define RSCALE (10.2571) /* wire resistance scaling factor */ -#define LSCALE 0.3571 /* length (feature) scaling factor */ -#define ASCALE (LSCALE*LSCALE) /* area scaling factor */ -#define VSCALE 0.45 /* voltage scaling factor */ -#define VTSCALE 0.5596 /* threshold voltage scaling factor */ -#define SSCALE 0.90 /* sense voltage scaling factor */ -#define MCSCALE 1.0 /* metal coupling capacitance scaling factor */ -#define MCSCALE2 1.0 /* metal coupling capacitance scaling factor (2X) */ -#define MCSCALE3 1.0 /* metal coupling capacitance scaling factor (3X) */ -#define GEN_POWER_SCALE PARM(GEN_POWER_FACTOR) -#elif ( PARM(TECH_POINT) == 35 ) -#define CSCALE (5.2197) /* wire capacitance scaling factor */ -#define RSCALE (5.2571) /* wire resistance scaling factor */ -#define LSCALE 0.4375 /* length (feature) scaling factor */ -#define ASCALE (LSCALE*LSCALE) /* area scaling factor */ -#define VSCALE 0.5 /* voltage scaling factor */ -#define VTSCALE 0.6147 /* threshold voltage scaling factor */ -#define SSCALE 0.95 /* sense voltage scaling factor */ -#define MCSCALE 1.0 /* metal coupling capacitance scaling factor */ -#define MCSCALE2 1.0 /* metal coupling capacitance scaling factor (2X) */ -#define MCSCALE3 1.0 /* metal coupling capacitance scaling factor (3X) */ -#define GEN_POWER_SCALE (PARM(GEN_POWER_FACTOR)*PARM(GEN_POWER_FACTOR)) -#elif ( PARM(TECH_POINT) == 40 ) -#define CSCALE 1.0 /* wire capacitance scaling factor */ -#define RSCALE 1.0 /* wire resistance scaling factor */ -#define LSCALE 0.5 /* length (feature) scaling factor */ -#define ASCALE (LSCALE*LSCALE) /* area scaling factor */ -#define VSCALE 1.0 /* voltage scaling factor */ -#define VTSCALE 1.0 /* threshold voltage scaling factor */ -#define SSCALE 1.0 /* sense voltage scaling factor */ -#define MCSCALE 1.0 /* metal coupling capacitance scaling factor */ -#define MCSCALE2 1.0 /* metal coupling capacitance scaling factor (2X) */ -#define MCSCALE3 1.0 /* metal coupling capacitance scaling factor (3X) */ -#define GEN_POWER_SCALE (PARM(GEN_POWER_FACTOR)*PARM(GEN_POWER_FACTOR)*PARM(GEN_POWER_FACTOR)) -#else /* ( PARM(TECH_POINT) == 80 ) */ -#define CSCALE 1.0 /* wire capacitance scaling factor */ -#define RSCALE 1.0 /* wire resistance scaling factor */ -#define LSCALE 1.0 /* length (feature) scaling factor */ -#define ASCALE (LSCALE*LSCALE) /* area scaling factor */ -#define VSCALE 1.0 /* voltage scaling factor */ -#define VTSCALE 1.0 /* threshold voltage scaling factor */ -#define SSCALE 1.0 /* sense voltage scaling factor */ -#define MCSCALE 1.0 /* metal coupling capacitance scaling factor */ -#define MCSCALE2 1.0 /* metal coupling capacitance scaling factor (2X) */ -#define MCSCALE3 1.0 /* metal coupling capacitance scaling factor (3X) */ -#define GEN_POWER_SCALE (PARM(GEN_POWER_FACTOR)*PARM(GEN_POWER_FACTOR)*PARM(GEN_POWER_FACTOR)*PARM(GEN_POWER_FACTOR)) -#endif - -#define MSCALE (LSCALE * .624 / .2250) - -/* - * CMOS 0.8um model parameters - * - from Appendix II of Cacti tech report - */ -/* corresponds to 8um of m3 @ 225ff/um */ -#define Cwordmetal (1.8e-15 * (CSCALE * ASCALE) * SCALE_M) - -/* corresponds to 16um of m2 @ 275ff/um */ -#define Cbitmetal (4.4e-15 * (CSCALE * ASCALE) * SCALE_M) - -/* corresponds to 1um of m2 @ 275ff/um */ -#define Cmetal (Cbitmetal/16) -#define CM2metal (Cbitmetal/16) -#define CM3metal (Cbitmetal/16) - -/* minimal spacing metal cap per unit length */ -#define CCmetal (Cmetal * MCSCALE) -#define CCM2metal (CM2metal * MCSCALE) -#define CCM3metal (CM3metal * MCSCALE) -/* 2x minimal spacing metal cap per unit length */ -#define CC2metal (Cmetal * MCSCALE2) -#define CC2M2metal (CM2metal * MCSCALE2) -#define CC2M3metal (CM3metal * MCSCALE2) -/* 3x minimal spacing metal cap per unit length */ -#define CC3metal (Cmetal * MCSCALE3) -#define CC3M2metal (CM2metal * MCSCALE3) -#define CC3M3metal (CM3metal * MCSCALE3) - -/* um */ -#define Leff (0.8 * LSCALE) -/* length unit in um */ -#define Lamda (Leff * 0.5) - -/* fF/um */ -#define Cpolywire (0.25e-15 * CSCALE * LSCALE) - -/* ohms*um of channel width */ -#define Rnchannelstatic (25800 * LSCALE) - -/* ohms*um of channel width */ -#define Rpchannelstatic (61200 * LSCALE) - -#define Rnchannelon (9723 * LSCALE) - -#define Rpchannelon (22400 * LSCALE) - -/* corresponds to 16um of m2 @ 48mO/sq */ -#define Rbitmetal (0.320 * (RSCALE * ASCALE)) - -/* corresponds to 8um of m3 @ 24mO/sq */ -#define Rwordmetal (0.080 * (RSCALE * ASCALE)) - -#ifndef Vdd -#define Vdd (5 * VSCALE) -#endif /* Vdd */ - -/* other stuff (from tech report, appendix 1) */ -#define Period ((double)1/(double)PARM(Freq)) - -#define krise (0.4e-9 * LSCALE) -#define tsensedata (5.8e-10 * LSCALE) -#define tsensetag (2.6e-10 * LSCALE) -#define tfalldata (7e-10 * LSCALE) -#define tfalltag (7e-10 * LSCALE) -#define Vbitpre (3.3 * SSCALE) -#define Vt (1.09 * VTSCALE) -#define Vbitsense (0.10 * SSCALE) - -#define Powerfactor (PARM(Freq))*Vdd*Vdd -#define EnergyFactor (Vdd*Vdd) - -#define SensePowerfactor3 (PARM(Freq))*(Vbitsense)*(Vbitsense) -#define SensePowerfactor2 (PARM(Freq))*(Vbitpre-Vbitsense)*(Vbitpre-Vbitsense) -#define SensePowerfactor (PARM(Freq))*Vdd*(Vdd/2) -#define SenseEnergyFactor (Vdd*Vdd/2) - -/* transistor widths in um (as described in tech report, appendix 1) */ -#define Wdecdrivep (57.0 * LSCALE) -#define Wdecdriven (40.0 * LSCALE) -#define Wdec3to8n (14.4 * LSCALE) -#define Wdec3to8p (14.4 * LSCALE) -#define WdecNORn (5.4 * LSCALE) -#define WdecNORp (30.5 * LSCALE) -#define Wdecinvn (5.0 * LSCALE) -#define Wdecinvp (10.0 * LSCALE) - -#define Wworddrivemax (100.0 * LSCALE) -#define Wmemcella (2.4 * LSCALE) -#define Wmemcellr (4.0 * LSCALE) -#define Wmemcellw (2.1 * LSCALE) -#define Wmemcellbscale 2 /* means 2x bigger than Wmemcella */ -#define Wbitpreequ (10.0 * LSCALE) - -#define Wbitmuxn (10.0 * LSCALE) -#define WsenseQ1to4 (4.0 * LSCALE) -#define Wcompinvp1 (10.0 * LSCALE) -#define Wcompinvn1 (6.0 * LSCALE) -#define Wcompinvp2 (20.0 * LSCALE) -#define Wcompinvn2 (12.0 * LSCALE) -#define Wcompinvp3 (40.0 * LSCALE) -#define Wcompinvn3 (24.0 * LSCALE) -#define Wevalinvp (20.0 * LSCALE) -#define Wevalinvn (80.0 * LSCALE) - -#define Wcompn (20.0 * LSCALE) -#define Wcompp (30.0 * LSCALE) -#define Wcomppreequ (40.0 * LSCALE) -#define Wmuxdrv12n (30.0 * LSCALE) -#define Wmuxdrv12p (50.0 * LSCALE) -#define WmuxdrvNANDn (20.0 * LSCALE) -#define WmuxdrvNANDp (80.0 * LSCALE) -#define WmuxdrvNORn (60.0 * LSCALE) -#define WmuxdrvNORp (80.0 * LSCALE) -#define Wmuxdrv3n (200.0 * LSCALE) -#define Wmuxdrv3p (480.0 * LSCALE) -#define Woutdrvseln (12.0 * LSCALE) -#define Woutdrvselp (20.0 * LSCALE) -#define Woutdrvnandn (24.0 * LSCALE) -#define Woutdrvnandp (10.0 * LSCALE) -#define Woutdrvnorn (6.0 * LSCALE) -#define Woutdrvnorp (40.0 * LSCALE) -#define Woutdrivern (48.0 * LSCALE) -#define Woutdriverp (80.0 * LSCALE) -#define Wbusdrvn (48.0 * LSCALE) -#define Wbusdrvp (80.0 * LSCALE) - -#define Wcompcellpd2 (2.4 * LSCALE) -#define Wcompdrivern (400.0 * LSCALE) -#define Wcompdriverp (800.0 * LSCALE) -#define Wcomparen2 (40.0 * LSCALE) -#define Wcomparen1 (20.0 * LSCALE) -#define Wmatchpchg (10.0 * LSCALE) -#define Wmatchinvn (10.0 * LSCALE) -#define Wmatchinvp (20.0 * LSCALE) -#define Wmatchnandn (20.0 * LSCALE) -#define Wmatchnandp (10.0 * LSCALE) -#define Wmatchnorn (20.0 * LSCALE) -#define Wmatchnorp (10.0 * LSCALE) - -#define WSelORn (10.0 * LSCALE) -#define WSelORprequ (40.0 * LSCALE) -#define WSelPn (10.0 * LSCALE) -#define WSelPp (15.0 * LSCALE) -#define WSelEnn (5.0 * LSCALE) -#define WSelEnp (10.0 * LSCALE) - -#define Wsenseextdrv1p (40.0*LSCALE) -#define Wsenseextdrv1n (24.0*LSCALE) -#define Wsenseextdrv2p (200.0*LSCALE) -#define Wsenseextdrv2n (120.0*LSCALE) - -/* bit width of RAM cell in um */ -#define BitWidth (16.0 * LSCALE) - -/* bit height of RAM cell in um */ -#define BitHeight (16.0 * LSCALE) - -#define Cout (0.5e-12 * LSCALE) - -/* Sizing of cells and spacings */ -#define RatCellHeight (40.0 * LSCALE) -#define RatCellWidth (70.0 * LSCALE) -#define RatShiftRegWidth (120.0 * LSCALE) -#define RatNumShift 4 -#define BitlineSpacing (6.0 * LSCALE) -#define WordlineSpacing (6.0 * LSCALE) - -#define RegCellHeight (16.0 * LSCALE) -#define RegCellWidth (8.0 * LSCALE) - -#define CamCellHeight (40.0 * LSCALE) -#define CamCellWidth (25.0 * LSCALE) -#define MatchlineSpacing (6.0 * LSCALE) -#define TaglineSpacing (6.0 * LSCALE) - -#define CrsbarCellHeight (6.0 * LSCALE) -#define CrsbarCellWidth (6.0 * LSCALE) - -/*===================================================================*/ - -/* ALU POWER NUMBERS for .18um 733Mhz */ -/* normalize .18um cap to other gen's cap, then xPowerfactor */ -#define POWER_SCALE (GEN_POWER_SCALE * PARM(NORMALIZE_SCALE) * Powerfactor) -#define I_ADD ((.37 - .091)*POWER_SCALE) -#define I_ADD32 (((.37 - .091)/2)*POWER_SCALE) -#define I_MULT16 ((.31-.095)*POWER_SCALE) -#define I_SHIFT ((.21-.089)*POWER_SCALE) -#define I_LOGIC ((.04-.015)*POWER_SCALE) -#define F_ADD ((1.307-.452)*POWER_SCALE) -#define F_MULT ((1.307-.452)*POWER_SCALE) - -#define I_ADD_CLOCK (.091*POWER_SCALE) -#define I_MULT_CLOCK (.095*POWER_SCALE) -#define I_SHIFT_CLOCK (.089*POWER_SCALE) -#define I_LOGIC_CLOCK (.015*POWER_SCALE) -#define F_ADD_CLOCK (.452*POWER_SCALE) -#define F_MULT_CLOCK (.452*POWER_SCALE) - -/* - - transmission gate type -typedef enum { - N_GATE, - NP_GATE -} SIM_power_trans_t; - -*/ -/* some utility routines */ -extern uint32_t SIM_power_logtwo(uint64_t x); -//extern int SIM_power_squarify(int rows, int cols); -extern double SIM_power_driver_size(double driving_cap, double desiredrisetime); - -/* functions from cacti */ -extern double SIM_power_gatecap(double width, double wirelength); -extern double SIM_power_gatecappass(double width, double wirelength); -extern double SIM_power_draincap(double width, int nchannel, int stack); -extern double SIM_power_restowidth(double res, int nchannel); - -extern int SIM_power_init(void); - -extern uint32_t SIM_power_Hamming(uint64_t old_val, uint64_t new_val, - uint64_t mask); -extern unsigned int SIM_power_Hamming_group(LIB_Type_max_uint d1_new, LIB_Type_max_uint d1_old, LIB_Type_max_uint d2_new, LIB_Type_max_uint d2_old, u_int width, u_int n_grp); - -/* statistical functions */ -//extern int SIM_print_stat_energy(char *path, double Energy, int print_flag); -//extern u_int SIM_power_strlen(char *s); -//extern char *SIM_power_strcat(char *dest, char *src); -//extern int SIM_power_res_path(char *path, u_int id); -//extern int SIM_power_dump_tech_para(void); - -#endif /* _SIM_POWER_H */ diff --git a/src/mem/ruby/network/orion/SIM_power_test.hh b/src/mem/ruby/network/orion/SIM_power_test.hh deleted file mode 100644 index 95b304042..000000000 --- a/src/mem/ruby/network/orion/SIM_power_test.hh +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * 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. - */ - -/* all needed to perform computation out of Liberty */ -#ifndef _SIM_POWER_TEST_H -#define _SIM_POWER_TEST_H - -#include <unistd.h> -#include <sys/types.h> - -#define LIB_Type_max_uint unsigned long int -#define LIB_Type_max_int long int - -#define __INSTANCE__ mainpe__power -#define GLOBDEF(t,n) t mainpe__power___ ## n -#define GLOB(n) mainpe__power___ ## n -#define FUNC(n, args...) mainpe__power___ ## n (args) -#define FUNCPTR(n) mainpe__power___ ## n -#define PARM(x) PARM_ ## x - -#undef PARM_AF -#undef PARM_MAXN -#undef PARM_MAXSUBARRAYS -#undef PARM_MAXSPD -#undef PARM_VTHSENSEEXTDRV -#undef PARM_VTHOUTDRNOR -#undef PARM_res_fpalu -#undef PARM_VTHCOMPINV -#undef PARM_MD_NUM_IREGS -#undef PARM_die_length -#undef PARM_BITOUT -#undef PARM_Cndiffside -#undef PARM_ruu_decode_width -#undef PARM_ruu_issue_width -#undef PARM_amp_Idsat -#undef PARM_AF_TYPE -#undef PARM_VSINV -#undef PARM_Cpdiffovlp -#undef PARM_data_width -#undef PARM_Cgatepass -#undef PARM_Cpdiffarea -#undef PARM_GEN_POWER_FACTOR -#undef PARM_res_memport -#undef PARM_VTHNAND60x90 -#undef PARM_Cpdiffside -#undef PARM_Cpoxideovlp -#undef PARM_opcode_length -#undef PARM_MD_NUM_FREGS -#undef PARM_FUDGEFACTOR -#undef PARM_ruu_commit_width -#undef PARM_Cndiffovlp -#undef PARM_VTHOUTDRIVE -#undef PARM_Cndiffarea -#undef PARM_VTHMUXDRV1 -#undef PARM_inst_length -#undef PARM_VTHMUXDRV2 -#undef PARM_NORMALIZE_SCALE -#undef PARM_ras_size -#undef PARM_VTHMUXDRV3 -#undef PARM_ADDRESS_BITS -#undef PARM_RUU_size -#undef PARM_Cgate -#undef PARM_VTHNOR12x4x1 -#undef PARM_VTHNOR12x4x2 -#undef PARM_VTHOUTDRINV -#undef PARM_VTHNOR12x4x3 -#undef PARM_VTHEVALINV -#undef PARM_crossover_scaling -#undef PARM_VTHNOR12x4x4 -#undef PARM_turnoff_factor -#undef PARM_res_ialu -#undef PARM_Cnoxideovlp -#undef PARM_VTHOUTDRNAND -#undef PARM_VTHINV100x60 -#undef PARM_LSQ_size - -#ifndef PARM_AF -#define PARM_AF (5.000000e-01) -#endif /* PARM_AF */ -#ifndef PARM_MAXN -#define PARM_MAXN (8) -#endif /* PARM_MAXN */ -#ifndef PARM_MAXSUBARRAYS -#define PARM_MAXSUBARRAYS (8) -#endif /* PARM_MAXSUBARRAYS */ -#ifndef PARM_MAXSPD -#define PARM_MAXSPD (8) -#endif /* PARM_MAXSPD */ -#ifndef PARM_VTHSENSEEXTDRV -#define PARM_VTHSENSEEXTDRV (4.370000e-01) -#endif /* PARM_VTHSENSEEXTDRV */ -#ifndef PARM_VTHOUTDRNOR -#define PARM_VTHOUTDRNOR (4.310000e-01) -#endif /* PARM_VTHOUTDRNOR */ -#ifndef PARM_res_fpalu -#define PARM_res_fpalu (4) -#endif /* PARM_res_fpalu */ -#ifndef PARM_VTHCOMPINV -#define PARM_VTHCOMPINV (4.370000e-01) -#endif /* PARM_VTHCOMPINV */ -#ifndef PARM_MD_NUM_IREGS -#define PARM_MD_NUM_IREGS (32) -#endif /* PARM_MD_NUM_IREGS */ -#ifndef PARM_die_length -#define PARM_die_length (1.800000e-02) -#endif /* PARM_die_length */ -#ifndef PARM_BITOUT -#define PARM_BITOUT (64) -#endif /* PARM_BITOUT */ -#ifndef PARM_Cndiffside -#define PARM_Cndiffside (2.750000e-16) -#endif /* PARM_Cndiffside */ -#ifndef PARM_ruu_decode_width -#define PARM_ruu_decode_width (4) -#endif /* PARM_ruu_decode_width */ -#ifndef PARM_ruu_issue_width -#define PARM_ruu_issue_width (4) -#endif /* PARM_ruu_issue_width */ -#ifndef PARM_amp_Idsat -#define PARM_amp_Idsat (5.000000e-04) -#endif /* PARM_amp_Idsat */ -#ifndef PARM_AF_TYPE -#define PARM_AF_TYPE (1) -#endif /* PARM_AF_TYPE */ -#ifndef PARM_VSINV -#define PARM_VSINV (4.560000e-01) -#endif /* PARM_VSINV */ -#ifndef PARM_Cpdiffovlp -#define PARM_Cpdiffovlp (1.380000e-16) -#endif /* PARM_Cpdiffovlp */ -#ifndef PARM_Cgatepass -#define PARM_Cgatepass (1.450000e-15) -#endif /* PARM_Cgatepass */ -#ifndef PARM_Cpdiffarea -#define PARM_Cpdiffarea (3.430000e-16) -#endif /* PARM_Cpdiffarea */ -#ifndef PARM_GEN_POWER_FACTOR -#define PARM_GEN_POWER_FACTOR (1.310000e+00) -#endif /* PARM_GEN_POWER_FACTOR */ -#ifndef PARM_res_memport -#define PARM_res_memport (2) -#endif /* PARM_res_memport */ -#ifndef PARM_VTHNAND60x90 -#define PARM_VTHNAND60x90 (5.610000e-01) -#endif /* PARM_VTHNAND60x90 */ -#ifndef PARM_Cpdiffside -#define PARM_Cpdiffside (2.750000e-16) -#endif /* PARM_Cpdiffside */ -#ifndef PARM_Cpoxideovlp -#define PARM_Cpoxideovlp (3.380000e-16) -#endif /* PARM_Cpoxideovlp */ -#ifndef PARM_opcode_length -#define PARM_opcode_length (8) -#endif /* PARM_opcode_length */ -#ifndef PARM_MD_NUM_FREGS -#define PARM_MD_NUM_FREGS (32) -#endif /* PARM_MD_NUM_FREGS */ -#ifndef PARM_FUDGEFACTOR -#define PARM_FUDGEFACTOR (1.000000e+00) -#endif /* PARM_FUDGEFACTOR */ -#ifndef PARM_ruu_commit_width -#define PARM_ruu_commit_width (4) -#endif /* PARM_ruu_commit_width */ -#ifndef PARM_Cndiffovlp -#define PARM_Cndiffovlp (1.380000e-16) -#endif /* PARM_Cndiffovlp */ -#ifndef PARM_VTHOUTDRIVE -#define PARM_VTHOUTDRIVE (4.250000e-01) -#endif /* PARM_VTHOUTDRIVE */ -#ifndef PARM_Cndiffarea -#define PARM_Cndiffarea (1.370000e-16) -#endif /* PARM_Cndiffarea */ -#ifndef PARM_VTHMUXDRV1 -#define PARM_VTHMUXDRV1 (4.370000e-01) -#endif /* PARM_VTHMUXDRV1 */ -#ifndef PARM_inst_length -#define PARM_inst_length (32) -#endif /* PARM_inst_length */ -#ifndef PARM_VTHMUXDRV2 -#define PARM_VTHMUXDRV2 (4.860000e-01) -#endif /* PARM_VTHMUXDRV2 */ -#ifndef PARM_NORMALIZE_SCALE -#define PARM_NORMALIZE_SCALE (6.488730e-10) -#endif /* PARM_NORMALIZE_SCALE */ -#ifndef PARM_ras_size -#define PARM_ras_size (8) -#endif /* PARM_ras_size */ -#ifndef PARM_VTHMUXDRV3 -#define PARM_VTHMUXDRV3 (4.370000e-01) -#endif /* PARM_VTHMUXDRV3 */ -#ifndef PARM_ADDRESS_BITS -#define PARM_ADDRESS_BITS (64) -#endif /* PARM_ADDRESS_BITS */ -#ifndef PARM_RUU_size -#define PARM_RUU_size (16) -#endif /* PARM_RUU_size */ -#ifndef PARM_Cgate -#define PARM_Cgate (1.950000e-15) -#endif /* PARM_Cgate */ -#ifndef PARM_VTHNOR12x4x1 -#define PARM_VTHNOR12x4x1 (5.030000e-01) -#endif /* PARM_VTHNOR12x4x1 */ -#ifndef PARM_VTHNOR12x4x2 -#define PARM_VTHNOR12x4x2 (4.520000e-01) -#endif /* PARM_VTHNOR12x4x2 */ -#ifndef PARM_VTHOUTDRINV -#define PARM_VTHOUTDRINV (4.370000e-01) -#endif /* PARM_VTHOUTDRINV */ -#ifndef PARM_VTHNOR12x4x3 -#define PARM_VTHNOR12x4x3 (4.170000e-01) -#endif /* PARM_VTHNOR12x4x3 */ -#ifndef PARM_VTHEVALINV -#define PARM_VTHEVALINV (2.670000e-01) -#endif /* PARM_VTHEVALINV */ -#ifndef PARM_crossover_scaling -#define PARM_crossover_scaling (1.200000e+00) -#endif /* PARM_crossover_scaling */ -#ifndef PARM_VTHNOR12x4x4 -#define PARM_VTHNOR12x4x4 (3.900000e-01) -#endif /* PARM_VTHNOR12x4x4 */ -#ifndef PARM_turnoff_factor -#define PARM_turnoff_factor (1.000000e-01) -#endif /* PARM_turnoff_factor */ -#ifndef PARM_res_ialu -#define PARM_res_ialu (4) -#endif /* PARM_res_ialu */ -#ifndef PARM_Cnoxideovlp -#define PARM_Cnoxideovlp (2.630000e-16) -#endif /* PARM_Cnoxideovlp */ -#ifndef PARM_VTHOUTDRNAND -#define PARM_VTHOUTDRNAND (4.410000e-01) -#endif /* PARM_VTHOUTDRNAND */ -#ifndef PARM_VTHINV100x60 -#define PARM_VTHINV100x60 (4.380000e-01) -#endif /* PARM_VTHINV100x60 */ -#ifndef PARM_LSQ_size -#define PARM_LSQ_size (8) -#endif /* PARM_LSQ_size */ - -#define TEST_LENGTH (100) -/* scaling factors from 0.1u to 0.07u, 0.05u and 0.035u */ -#if (TEST_LENGTH == 70) -#define SCALE_T (0.5489156157) -#define SCALE_M (0.6566502462) -#define SCALE_S (1.4088071075) -#elif (TEST_LENGTH == 50) -#define SCALE_T (0.3251012552) -#define SCALE_M (0.4426460239) -#define SCALE_S (2.8667111607) -#elif (TEST_LENGTH == 35) -#define SCALE_T (0.2016627474) -#define SCALE_M (0.2489788586) -#define SCALE_S (8.7726826878) -#else -#define SCALE_T (1) -#define SCALE_M (1) -#define SCALE_S (1) -#endif /* TEST_LENGTH */ - -#endif /* _SIM_POWER_TEST_H */ diff --git a/src/mem/ruby/network/orion/TechParameter.cc b/src/mem/ruby/network/orion/TechParameter.cc new file mode 100644 index 000000000..d1a107e18 --- /dev/null +++ b/src/mem/ruby/network/orion/TechParameter.cc @@ -0,0 +1,1476 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 <iostream> +#include <string> +#include <cmath> +#include <cstdlib> + +#include "mem/ruby/network/orion/TechParameter.hh" +#include "mem/ruby/network/orion/OrionConfig.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<uint32_t>("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<string>("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<double>("VDD"); + m_freq = m_orion_cfg_ptr->get<double>("FREQUENCY"); + m_period = 1 / m_freq; + + const string& wire_layer_type_str = m_orion_cfg_ptr->get<string>("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 --git a/src/mem/ruby/network/orion/TechParameter.hh b/src/mem/ruby/network/orion/TechParameter.hh new file mode 100644 index 000000000..bdebe74bc --- /dev/null +++ b/src/mem/ruby/network/orion/TechParameter.hh @@ -0,0 +1,414 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 <string> + +#include "mem/ruby/network/orion/Type.hh" + +using namespace std; + +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 --git a/src/mem/ruby/network/orion/power_utils.hh b/src/mem/ruby/network/orion/Type.hh index 8f0343989..04fb9cc29 100644 --- a/src/mem/ruby/network/orion/power_utils.hh +++ b/src/mem/ruby/network/orion/Type.hh @@ -1,5 +1,6 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2009 Princeton University, and + * Regents of the University of California * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,16 +25,21 @@ * 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 _POWER_UTILS_H -#define _POWER_UTILS_H +#ifndef __TYPE_H__ +#define __TYPE_H__ -#include "base/types.hh" +typedef unsigned int uint32_t; -extern uint32_t SIM_power_Hamming(uint64_t old_val, uint64_t new_val, - uint64_t mask); -extern double logtwo(double x); -extern uint32_t SIM_power_logtwo(uint64_t x); +#include <string> +using std::string; #endif + diff --git a/src/mem/ruby/network/orion/Wire.cc b/src/mem/ruby/network/orion/Wire.cc new file mode 100644 index 000000000..c704fa8da --- /dev/null +++ b/src/mem/ruby/network/orion/Wire.cc @@ -0,0 +1,383 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 <iostream> +#include <cmath> +#include <cstdlib> + +#include "base/misc.hh" +#include "mem/ruby/network/orion/Wire.hh" +#include "mem/ruby/network/orion/TechParameter.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 --git a/src/mem/ruby/network/orion/Wire.hh b/src/mem/ruby/network/orion/Wire.hh new file mode 100644 index 000000000..b16be0d47 --- /dev/null +++ b/src/mem/ruby/network/orion/Wire.hh @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2009 Princeton University, and + * 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 --git a/src/mem/ruby/network/orion/power_static.hh b/src/mem/ruby/network/orion/orion.hh index 09f989aa2..a9cc2a5b6 100644 --- a/src/mem/ruby/network/orion/power_static.hh +++ b/src/mem/ruby/network/orion/orion.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2010 Massachusetts Institute of Technology * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,16 +24,16 @@ * 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 _POWER_STATIC_H -#define _POWER_STATIC_H - -#include "mem/ruby/network/orion/parm_technology.hh" +#ifndef __ORION_H__ +#define __ORION_H__ -extern double NMOS_TAB[1]; -extern double PMOS_TAB[1]; -extern double NAND2_TAB[4]; -extern double NOR2_TAB[4]; +#include "mem/ruby/network/orion/OrionConfig.hh" +#include "mem/ruby/network/orion/OrionRouter.hh" +#include "mem/ruby/network/orion/OrionLink.hh" #endif + diff --git a/src/mem/ruby/network/orion/parm_technology.hh b/src/mem/ruby/network/orion/parm_technology.hh deleted file mode 100644 index 87049d4cd..000000000 --- a/src/mem/ruby/network/orion/parm_technology.hh +++ /dev/null @@ -1,474 +0,0 @@ -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _PARM_TECHNOLOGY_H -#define _PARM_TECHNOLOGY_H - -/******* LEAKAGE current values for different tech points are in power_static.c *******/ -/******* for LINKS: metal cap is assumed to be CC2metal and repeater size is assumed to be n_size=Lambda*10, p_size=n_size*2 *******/ - -#define SWITCHING_FACTOR 0.5 /*used for offline calculations*/ - -/********************* Technology point **********/ -#define PARM_TECH_POINT 10 /* 100nm */ -#define PARM_Freq 3e9 -/*************************************************/ - - -/*********** Transistor parasitics ******************/ -#define PARM_Cndiffside (2.750000e-16) -#define PARM_Cpdiffovlp (1.380000e-16) -#define PARM_Cgatepass (1.450000e-15) -#define PARM_Cpdiffarea (3.430000e-16) -#define PARM_Cpdiffside (2.750000e-16) -#define PARM_Cpoxideovlp (3.380000e-16) -#define PARM_Cndiffovlp (1.380000e-16) -#define PARM_Cndiffarea (1.370000e-16) -#define PARM_Cgate (1.950000e-15) -#define PARM_Cnoxideovlp (2.630000e-16) -/*************************************************/ - - - -/************* Scaling factors for different technology points ******************/ -#if ( PARM_TECH_POINT == 10 ) /* 100nm */ -#define CSCALE (84.2172) /* wire capacitance scaling factor */ - /* linear: 51.7172, predicted: 84.2172 */ -#define RSCALE (80.0000) /* wire resistance scaling factor */ -#define LSCALE 0.1250 /* length (feature) scaling factor */ -#define ASCALE (LSCALE*LSCALE) /* area scaling factor */ -#define VSCALE 0.38 /* voltage scaling factor */ -#define VTSCALE 0.49 /* threshold voltage scaling factor */ -#define SSCALE 0.80 /* sense voltage scaling factor */ -/* FIXME: borrowed from 0.11u technology */ -#define MCSCALE 5.2277 /* metal coupling capacitance scaling factor */ -#define MCSCALE2 3 /* metal coupling capacitance scaling factor (2X) */ -#define MCSCALE3 1.5 /* metal coupling capacitance scaling factor (3X) */ -#define GEN_POWER_SCALE (1/PARM_GEN_POWER_FACTOR) -/* copied from TECH_POINT 10 except LSCALE */ -#elif ( PARM_TECH_POINT == 11 ) /* 110nm */ -#define CSCALE (84.2172) /* wire capacitance scaling factor */ -#define RSCALE (80.0000) /* wire resistance scaling factor */ -#define LSCALE 0.1375 /* length (feature) scaling factor */ -#define ASCALE (LSCALE*LSCALE) /* area scaling factor */ -#define VSCALE 0.38 /* voltage scaling factor */ -#define VTSCALE 0.49 /* threshold voltage scaling factor */ -#define SSCALE 0.80 /* sense voltage scaling factor */ -#define MCSCALE 5.2277 /* metal coupling capacitance scaling factor */ -#define MCSCALE2 3 /* metal coupling capacitance scaling factor (2X) */ -#define MCSCALE3 1.5 /* metal coupling capacitance scaling factor (3X) */ -#define GEN_POWER_SCALE (1/PARM_GEN_POWER_FACTOR) -#elif ( PARM_TECH_POINT == 18 ) /* 180nm */ -#define CSCALE (19.7172) /* wire capacitance scaling factor */ -#define RSCALE (20.0000) /* wire resistance scaling factor */ -#define LSCALE 0.2250 /* length (feature) scaling factor */ -#define ASCALE (LSCALE*LSCALE) /* area scaling factor */ -#define VSCALE 0.4 /* voltage scaling factor */ -#define VTSCALE 0.5046 /* threshold voltage scaling factor */ -#define SSCALE 0.85 /* sense voltage scaling factor */ -#define MCSCALE 4.1250 /* metal coupling capacitance scaling factor */ -#define MCSCALE2 2.4444 /* metal coupling capacitance scaling factor (2X) */ -#define MCSCALE3 1.2 /* metal coupling capacitance scaling factor (3X) */ -#define GEN_POWER_SCALE 1 -#elif ( PARM_TECH_POINT == 25 ) /* 250nm */ -#define CSCALE (10.2197) /* wire capacitance scaling factor */ -#define RSCALE (10.2571) /* wire resistance scaling factor */ -#define LSCALE 0.3571 /* length (feature) scaling factor */ -#define ASCALE (LSCALE*LSCALE) /* area scaling factor */ -#define VSCALE 0.45 /* voltage scaling factor */ -#define VTSCALE 0.5596 /* threshold voltage scaling factor */ -#define SSCALE 0.90 /* sense voltage scaling factor */ -#define MCSCALE 1.0 /* metal coupling capacitance scaling factor */ -#define MCSCALE2 1.0 /* metal coupling capacitance scaling factor (2X) */ -#define MCSCALE3 1.0 /* metal coupling capacitance scaling factor (3X) */ -#define GEN_POWER_SCALE PARM_GEN_POWER_FACTOR -#elif ( PARM_TECH_POINT == 35 ) /* 350nm */ -#define CSCALE (5.2197) /* wire capacitance scaling factor */ -#define RSCALE (5.2571) /* wire resistance scaling factor */ -#define LSCALE 0.4375 /* length (feature) scaling factor */ -#define ASCALE (LSCALE*LSCALE) /* area scaling factor */ -#define VSCALE 0.5 /* voltage scaling factor */ -#define VTSCALE 0.6147 /* threshold voltage scaling factor */ -#define SSCALE 0.95 /* sense voltage scaling factor */ -#define MCSCALE 1.0 /* metal coupling capacitance scaling factor */ -#define MCSCALE2 1.0 /* metal coupling capacitance scaling factor (2X) */ -#define MCSCALE3 1.0 /* metal coupling capacitance scaling factor (3X) */ -#define GEN_POWER_SCALE (PARM_GEN_POWER_FACTOR*PARM_GEN_POWER_FACTOR) -#elif ( PARM_TECH_POINT == 40 ) /* 400nm */ -#define CSCALE 1.0 /* wire capacitance scaling factor */ -#define RSCALE 1.0 /* wire resistance scaling factor */ -#define LSCALE 0.5 /* length (feature) scaling factor */ -#define ASCALE (LSCALE*LSCALE) /* area scaling factor */ -#define VSCALE 1.0 /* voltage scaling factor */ -#define VTSCALE 1.0 /* threshold voltage scaling factor */ -#define SSCALE 1.0 /* sense voltage scaling factor */ -#define MCSCALE 1.0 /* metal coupling capacitance scaling factor */ -#define MCSCALE2 1.0 /* metal coupling capacitance scaling factor (2X) */ -#define MCSCALE3 1.0 /* metal coupling capacitance scaling factor (3X) */ -#define GEN_POWER_SCALE (PARM_GEN_POWER_FACTOR*PARM_GEN_POWER_FACTOR*PARM_GEN_POWER_FACTOR) -#else /* ( PARM_TECH_POINT == 80 ) */ /* 800nm */ -#define CSCALE 1.0 /* wire capacitance scaling factor */ -#define RSCALE 1.0 /* wire resistance scaling factor */ -#define LSCALE 1.0 /* length (feature) scaling factor */ -#define ASCALE (LSCALE*LSCALE) /* area scaling factor */ -#define VSCALE 1.0 /* voltage scaling factor */ -#define VTSCALE 1.0 /* threshold voltage scaling factor */ -#define SSCALE 1.0 /* sense voltage scaling factor */ -#define MCSCALE 1.0 /* metal coupling capacitance scaling factor */ -#define MCSCALE2 1.0 /* metal coupling capacitance scaling factor (2X) */ -#define MCSCALE3 1.0 /* metal coupling capacitance scaling factor (3X) */ -#define GEN_POWER_SCALE (PARM_GEN_POWER_FACTOR*PARM_GEN_POWER_FACTOR*PARM_GEN_POWER_FACTOR*PARM_GEN_POWER_FACTOR) -#endif - -#define MSCALE (LSCALE * .624 / .2250) -#define PARM_NORMALIZE_SCALE (6.488730e-10) - -/* scaling factors from 0.1u to 0.07u, 0.05u and 0.035u */ -/* if technology point is 0.07u, o.05u or 0.035u set PARM_TECH_POINT to 10 and - * set TEST_LENGTH to 70, 50 or 35 respectively(TEST_LENGTH =100 for all other technologies) */ -#define TEST_LENGTH (70) - -#if (TEST_LENGTH == 70) -#define SCALE_T (0.5489156157) -#define SCALE_M (0.6566502462) -#define SCALE_S (1.4088071075) -#elif (TEST_LENGTH == 50) -#define SCALE_T (0.3251012552) -#define SCALE_M (0.4426460239) -#define SCALE_S (2.8667111607) -#elif (TEST_LENGTH == 35) -#define SCALE_T (0.2016627474) -#define SCALE_M (0.2489788586) -#define SCALE_S (8.7726826878) -#else -#define SCALE_T (1) -#define SCALE_M (1) -#define SCALE_S (1) -#endif /* TEST_LENGTH */ -/*************************************************/ - - - -/********************** technology point related ***************************/ -/* um */ -#define Leff (0.8 * LSCALE) -/* length unit in um */ -#define Lamda (Leff * 0.5) - -#ifndef Vdd -#define Vdd (5 * VSCALE) -#endif /* Vdd */ - -#define Period ((double)1/(double)PARM_Freq) -/*************************************************/ - - -/**** for SRAM - decoder, mem cell, wordline, bitline, output driver ****/ -/* - * CMOS 0.8um model parameters - * - from Appendix II of Cacti tech report - */ -/* corresponds to 8um of m3 @ 225ff/um */ -#define Cwordmetal (1.8e-15 * (CSCALE * ASCALE) * SCALE_M) - -/* corresponds to 16um of m2 @ 275ff/um */ -#define Cbitmetal (4.4e-15 * (CSCALE * ASCALE) * SCALE_M) - -/* corresponds to 1um of m2 @ 275ff/um */ -#define Cmetal (Cbitmetal/16) -#define CM2metal (Cbitmetal/16) -#define CM3metal (Cbitmetal/16) - -/* minimal spacing metal cap per unit length */ -#define CCmetal (Cmetal * MCSCALE) -#define CCM2metal (CM2metal * MCSCALE) -#define CCM3metal (CM3metal * MCSCALE) -/* 2x minimal spacing metal cap per unit length */ -#define CC2metal (Cmetal * MCSCALE2) -#define CC2M2metal (CM2metal * MCSCALE2) -#define CC2M3metal (CM3metal * MCSCALE2) -/* 3x minimal spacing metal cap per unit length */ -#define CC3metal (Cmetal * MCSCALE3) -#define CC3M2metal (CM2metal * MCSCALE3) -#define CC3M3metal (CM3metal * MCSCALE3) - -/* fF/um */ -#define Cpolywire (0.25e-15 * CSCALE * LSCALE) - -/* ohms*um of channel width */ -#define Rnchannelstatic (25800 * LSCALE) - -/* ohms*um of channel width */ -#define Rpchannelstatic (61200 * LSCALE) - -#define Rnchannelon (9723 * LSCALE) - -#define Rpchannelon (22400 * LSCALE) - -/* corresponds to 16um of m2 @ 48mO/sq */ -#define Rbitmetal (0.320 * (RSCALE * ASCALE)) - -/* corresponds to 8um of m3 @ 24mO/sq */ -#define Rwordmetal (0.080 * (RSCALE * ASCALE)) - -#define Powerfactor (PARM_Freq)*Vdd*Vdd -#define EnergyFactor (Vdd*Vdd) - -#define SensePowerfactor3 (PARM_Freq)*(Vbitsense)*(Vbitsense) // -#define SensePowerfactor2 (PARM_Freq)*(Vbitpre-Vbitsense)*(Vbitpre-Vbitsense) // -#define SensePowerfactor (PARM_Freq)*Vdd*(Vdd/2) // -#define SenseEnergyFactor (Vdd*Vdd/2) - -/* transistor widths in um (as described in tech report, appendix 1) */ -#define Wdecdrivep (57.0 * LSCALE) -#define Wdecdriven (40.0 * LSCALE) -#define Wdec3to8n (14.4 * LSCALE) -#define Wdec3to8p (14.4 * LSCALE) -#define WdecNORn (5.4 * LSCALE) -#define WdecNORp (30.5 * LSCALE) -#define Wdecinvn (5.0 * LSCALE) -#define Wdecinvp (10.0 * LSCALE) - -#define Wworddrivemax (100.0 * LSCALE) -#define Wmemcella (2.4 * LSCALE) /* AMIT memory cell inverter PMOS transistor width */ -#define Wmemcellr (4.0 * LSCALE) /* AMIT memory cell read access transistor width */ -#define Wmemcellw (2.1 * LSCALE) /* AMIT memory cell write access transistor width */ -#define Wmemcellbscale 2 /* AMIT (mem cell inverter NMOS trans width = Wmemcella * Wmemcellbscale) means 2x bigger than Wmemcella */ -#define Wbitpreequ (10.0 * LSCALE) // - -#define Wbitmuxn (10.0 * LSCALE) -#define WsenseQ1to4 (4.0 * LSCALE) -#define Wcompinvp1 (10.0 * LSCALE) -#define Wcompinvn1 (6.0 * LSCALE) -#define Wcompinvp2 (20.0 * LSCALE) -#define Wcompinvn2 (12.0 * LSCALE) -#define Wcompinvp3 (40.0 * LSCALE) -#define Wcompinvn3 (24.0 * LSCALE) -#define Wevalinvp (20.0 * LSCALE) -#define Wevalinvn (80.0 * LSCALE) - -#define Wcompn (20.0 * LSCALE) -#define Wcompp (30.0 * LSCALE) -#define Wcomppreequ (40.0 * LSCALE) -#define Wmuxdrv12n (30.0 * LSCALE) -#define Wmuxdrv12p (50.0 * LSCALE) -#define WmuxdrvNANDn (20.0 * LSCALE) -#define WmuxdrvNANDp (80.0 * LSCALE) -#define WmuxdrvNORn (60.0 * LSCALE) -#define WmuxdrvNORp (80.0 * LSCALE) -#define Wmuxdrv3n (200.0 * LSCALE) -#define Wmuxdrv3p (480.0 * LSCALE) -#define Woutdrvseln (12.0 * LSCALE) -#define Woutdrvselp (20.0 * LSCALE) -#define Woutdrvnandn (24.0 * LSCALE) -#define Woutdrvnandp (10.0 * LSCALE) -#define Woutdrvnorn (6.0 * LSCALE) -#define Woutdrvnorp (40.0 * LSCALE) -#define Woutdrivern (48.0 * LSCALE) -#define Woutdriverp (80.0 * LSCALE) -#define Wbusdrvn (48.0 * LSCALE) -#define Wbusdrvp (80.0 * LSCALE) - -#define Wcompcellpd2 (2.4 * LSCALE) // -#define Wcompdrivern (400.0 * LSCALE) -#define Wcompdriverp (800.0 * LSCALE) -#define Wcomparen2 (40.0 * LSCALE) -#define Wcomparen1 (20.0 * LSCALE) -#define Wmatchpchg (10.0 * LSCALE) -#define Wmatchinvn (10.0 * LSCALE) -#define Wmatchinvp (20.0 * LSCALE) -#define Wmatchnandn (20.0 * LSCALE) -#define Wmatchnandp (10.0 * LSCALE) -#define Wmatchnorn (20.0 * LSCALE) -#define Wmatchnorp (10.0 * LSCALE) - -#define WSelORn (10.0 * LSCALE) // -#define WSelORprequ (40.0 * LSCALE) // -#define WSelPn (10.0 * LSCALE) // -#define WSelPp (15.0 * LSCALE) // -#define WSelEnn (5.0 * LSCALE) // -#define WSelEnp (10.0 * LSCALE) // - -#define Wsenseextdrv1p (40.0*LSCALE) // -#define Wsenseextdrv1n (24.0*LSCALE) // -#define Wsenseextdrv2p (200.0*LSCALE) // -#define Wsenseextdrv2n (120.0*LSCALE) // - -/* bit width of RAM cell in um */ -#define BitWidth (16.0 * LSCALE) - -/* bit height of RAM cell in um */ -#define BitHeight (16.0 * LSCALE) - -#define Cout (0.5e-12 * LSCALE) - -/* Sizing of cells and spacings */ -#define RatCellHeight (40.0 * LSCALE) // -#define RatCellWidth (70.0 * LSCALE) // -#define RatShiftRegWidth (120.0 * LSCALE) // -#define RatNumShift 4 // -#define BitlineSpacing (6.0 * LSCALE) -#define WordlineSpacing (6.0 * LSCALE) - -#define RegCellHeight (16.0 * LSCALE) /* AMIT memory cell height */ -#define RegCellWidth (8.0 * LSCALE) /* AMIT memory cell width */ - -#define CamCellHeight (40.0 * LSCALE) -#define CamCellWidth (25.0 * LSCALE) -#define MatchlineSpacing (6.0 * LSCALE) -#define TaglineSpacing (6.0 * LSCALE) - -#define CrsbarCellHeight (6.0 * LSCALE) -#define CrsbarCellWidth (6.0 * LSCALE) - -/* Link length in um */ -#define PARM_link_length 1000 - - -/*************************************************/ - -/******* LEAKAGE current values for different tech points are in power_static.c *******/ -/******* for LINKS: metal cap is assumed to be CC2metal and repeater size is assumed to be n_size=Lambda*10, p_size=n_size*2 *******/ - -/* -------------------------Miscellaneous---------------------------- */ - -#define SIM_NO_MODEL 0 - -#define MAX_ENERGY 1 -#define AVG_ENERGY 0 - -#ifndef MAX -#define MAX(a,b) (((a)>(b))?(a):(b)) -#endif -#ifndef MIN -#define MIN(a,b) (((a)>(b))?(b):(a)) -#endif - -#define NEXT_DEPTH(d) ((d) > 0 ? (d) - 1 : (d)) - -#define BIGNUM 1e30 -#define BIGONE ((unsigned long int)1) -#define BIGNONE ((unsigned long int)-1) -#define HAMM_MASK(w) ((unsigned)w < (sizeof(unsigned long int) << 3) ? (BIGONE << w) - 1 : BIGNONE) - -/* Used to communicate with the horowitz model */ -#define RISE 1 -#define FALL 0 -#define NCH 1 -#define PCH 0 -/* --------------------------------------------------- */ - - - -/* ---------------------- not used ------------------------------- */ - -#define krise (0.4e-9 * LSCALE) // -#define tsensedata (5.8e-10 * LSCALE) // -#define tsensetag (2.6e-10 * LSCALE) // -#define tfalldata (7e-10 * LSCALE) // -#define tfalltag (7e-10 * LSCALE) // -#define Vbitpre (3.3 * SSCALE) // -#define Vt (1.09 * VTSCALE) -#define Vbitsense (0.10 * SSCALE) // - - -#define PARM_AF (5.000000e-01) // -#define PARM_MAXN (8) // -#define PARM_MAXSUBARRAYS (8) // -#define PARM_MAXSPD (8) // -#define PARM_VTHSENSEEXTDRV (4.370000e-01) // -#define PARM_VTHOUTDRNOR (4.310000e-01) // -#define PARM_res_fpalu (4) // -#define PARM_VTHCOMPINV (4.370000e-01) // -#define PARM_MD_NUM_IREGS (32) // -#define PARM_die_length (1.800000e-02) // -#define PARM_BITOUT (64) // - -#define PARM_ruu_decode_width (4) // -#define PARM_ruu_issue_width (4) // AMIT used only for result bus -#define PARM_amp_Idsat (5.000000e-04) //used in amp_energy -#define PARM_AF_TYPE (1) // -#define PARM_VSINV (4.560000e-01) //used in driver size calculations - -#define PARM_GEN_POWER_FACTOR (1.310000e+00) // -#define PARM_res_memport (2) // -#define PARM_VTHNAND60x90 (5.610000e-01) // - -#define PARM_opcode_length (8) // -#define PARM_MD_NUM_FREGS (32) // -#define PARM_FUDGEFACTOR (1.000000e+00) // -#define PARM_ruu_commit_width (4) // - -#define PARM_VTHOUTDRIVE (4.250000e-01) // - -#define PARM_VTHMUXDRV1 (4.370000e-01) // -#define PARM_inst_length (32) // -#define PARM_VTHMUXDRV2 (4.860000e-01) // - -#define PARM_ras_size (8) // -#define PARM_VTHMUXDRV3 (4.370000e-01) // -#define PARM_ADDRESS_BITS (64) // -#define PARM_RUU_size (16) // - -#define PARM_VTHNOR12x4x1 (5.030000e-01) // -#define PARM_VTHNOR12x4x2 (4.520000e-01) // -#define PARM_VTHOUTDRINV (4.370000e-01) // -#define PARM_VTHNOR12x4x3 (4.170000e-01) // -#define PARM_VTHEVALINV (2.670000e-01) // -#define PARM_crossover_scaling (1.200000e+00) // -#define PARM_VTHNOR12x4x4 (3.900000e-01) // -#define PARM_turnoff_factor (1.000000e-01) // -#define PARM_res_ialu (4) // - -#define PARM_VTHOUTDRNAND (4.410000e-01) // -#define PARM_VTHINV100x60 (4.380000e-01) // -#define PARM_LSQ_size (8) // - -/* ALU POWER NUMBERS for .18um 733Mhz */ -/* normalize .18um cap to other gen's cap, then xPowerfactor */ -#define POWER_SCALE (GEN_POWER_SCALE * PARM_NORMALIZE_SCALE * Powerfactor) // -#define I_ADD ((.37 - .091)*POWER_SCALE) // -#define I_ADD32 (((.37 - .091)/2)*POWER_SCALE) // -#define I_MULT16 ((.31-.095)*POWER_SCALE) // -#define I_SHIFT ((.21-.089)*POWER_SCALE) // -#define I_LOGIC ((.04-.015)*POWER_SCALE) // -#define F_ADD ((1.307-.452)*POWER_SCALE) // -#define F_MULT ((1.307-.452)*POWER_SCALE) // - -#define I_ADD_CLOCK (.091*POWER_SCALE) // -#define I_MULT_CLOCK (.095*POWER_SCALE) // -#define I_SHIFT_CLOCK (.089*POWER_SCALE) // -#define I_LOGIC_CLOCK (.015*POWER_SCALE) // -#define F_ADD_CLOCK (.452*POWER_SCALE) // -#define F_MULT_CLOCK (.452*POWER_SCALE) // - - -/* ----------------------------------------------------- */ - - -#endif diff --git a/src/mem/ruby/network/orion/power_arbiter.cc b/src/mem/ruby/network/orion/power_arbiter.cc deleted file mode 100644 index d382ebfb2..000000000 --- a/src/mem/ruby/network/orion/power_arbiter.cc +++ /dev/null @@ -1,392 +0,0 @@ -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> - -#include "mem/ruby/network/orion/power_arbiter.hh" -#include "mem/ruby/network/orion/power_array.hh" -#include "mem/ruby/network/orion/power_ll.hh" -#include "mem/ruby/network/orion/parm_technology.hh" -#include "mem/ruby/network/orion/SIM_port.hh" -#include "mem/ruby/network/orion/power_static.hh" -#include "mem/ruby/network/orion/power_utils.hh" - - - - - -/******************************* Power model for flip flop *****************************/ - -/* ------- flip flop model ---------- */ - -/* 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. - */ -static double SIM_fpfp_node_cap(unsigned fan_in, unsigned fan_out) -{ - double Ctotal = 0; - - /* FIXME: all need actual sizes */ - /* part 1: drain cap of NOR gate */ - Ctotal += fan_in * SIM_power_draincap(WdecNORn, NCH, 1) + SIM_power_draincap(WdecNORp, PCH, fan_in); - - /* part 2: gate cap of NOR gates */ - Ctotal += fan_out * SIM_power_gatecap(WdecNORn + WdecNORp, 0); - - return Ctotal; -} - - -static double SIM_fpfp_clock_cap(void) -{ - /* gate cap of clock load */ - return (2 * SIM_power_gatecap(WdecNORn + WdecNORp, 0)); -} - - -int SIM_fpfp_clear_stat(power_ff *ff) -{ - ff->n_switch = ff->n_keep_1 = ff->n_keep_0 = ff->n_clock = 0; - - return 0; -} - - -int SIM_fpfp_init(power_ff *ff, int model, double load) -{ - double c1, c2, c3, c4, c5, c6; - - if ((ff->model = model) && model < FF_MAX_MODEL) { - switch (model) { - case NEG_DFF: - SIM_fpfp_clear_stat(ff); - - /* node 5 and node 6 are identical to node 1 in capacitance */ - c1 = c5 = c6 = SIM_fpfp_node_cap(2, 1); - c2 = SIM_fpfp_node_cap(2, 3); - c3 = SIM_fpfp_node_cap(3, 2); - c4 = SIM_fpfp_node_cap(2, 3); - - ff->e_switch = (c4 + c1 + c2 + c3 + c5 + c6 + load) / 2 * EnergyFactor; - /* no 1/2 for e_keep and e_clock because clock signal switches twice in one cycle */ - ff->e_keep_1 = c3 * EnergyFactor; - ff->e_keep_0 = c2 * EnergyFactor; - ff->e_clock = SIM_fpfp_clock_cap() * EnergyFactor; - - /* static power */ - ff->i_leakage = (WdecNORp * NOR2_TAB[0] + WdecNORn * (NOR2_TAB[1] + NOR2_TAB[2] + NOR2_TAB[3])) / 4 * 6 / PARM_TECH_POINT * 100; - break; - - default: break;/* some error handler */ - } - - return 0; - } - else - return -1; -} - - -double SIM_fpfp_report(power_ff *ff) -{ - return (ff->e_switch * ff->n_switch + ff->e_clock * ff->n_clock + - ff->e_keep_0 * ff->n_keep_0 + ff->e_keep_1 * ff->n_keep_1); -} - -/* ------- flip flop model ---------- */ - - - - - -/* -------- arbiter power model ------------- */ - -/* switch cap of request signal (round robin arbiter) */ -static double rr_arbiter_req_cap(double length) -{ - double Ctotal = 0; - - /* part 1: gate cap of 2 NOR gates */ - /* FIXME: need actual size */ - Ctotal += 2 * SIM_power_gatecap(WdecNORn + WdecNORp, 0); - - /* part 2: inverter */ - /* FIXME: need actual size */ - Ctotal += SIM_power_draincap(Wdecinvn, NCH, 1) + SIM_power_draincap(Wdecinvp, PCH, 1) + - SIM_power_gatecap(Wdecinvn + Wdecinvp, 0); - - /* part 3: wire cap */ - Ctotal += length * Cmetal; - - return Ctotal; -} - - -/* switch cap of priority signal (round robin arbiter) */ -static double rr_arbiter_pri_cap() -{ - double Ctotal = 0; - - /* part 1: gate cap of NOR gate */ - /* FIXME: need actual size */ - Ctotal += SIM_power_gatecap(WdecNORn + WdecNORp, 0); - - return Ctotal; -} - - -/* switch cap of grant signal (round robin arbiter) */ -static double rr_arbiter_grant_cap() -{ - double Ctotal = 0; - - /* part 1: drain cap of NOR gate */ - /* FIXME: need actual size */ - Ctotal += 2 * SIM_power_draincap(WdecNORn, NCH, 1) + SIM_power_draincap(WdecNORp, PCH, 2); - - return Ctotal; -} - - -/* switch cap of carry signal (round robin arbiter) */ -static double rr_arbiter_carry_cap() -{ - double Ctotal = 0; - - /* part 1: drain cap of NOR gate (this block) */ - /* FIXME: need actual size */ - Ctotal += 2 * SIM_power_draincap(WdecNORn, NCH, 1) + SIM_power_draincap(WdecNORp, PCH, 2); - - /* part 2: gate cap of NOR gate (next block) */ - /* FIXME: need actual size */ - Ctotal += SIM_power_gatecap(WdecNORn + WdecNORp, 0); - - return Ctotal; -} - - -/* switch cap of internal carry node (round robin arbiter) */ -static double rr_arbiter_carry_in_cap() -{ - double Ctotal = 0; - - /* part 1: gate cap of 2 NOR gates */ - /* FIXME: need actual size */ - Ctotal += 2 * SIM_power_gatecap(WdecNORn + WdecNORp, 0); - - /* part 2: drain cap of NOR gate */ - /* FIXME: need actual size */ - Ctotal += 2 * SIM_power_draincap(WdecNORn, NCH, 1) + SIM_power_draincap(WdecNORp, PCH, 2); - - return Ctotal; -} - - -/* the "huge" NOR gate in matrix arbiter model is an approximation */ -/* switch cap of request signal (matrix arbiter) */ -static double matrix_arbiter_req_cap(unsigned req_width, double length) -{ - double Ctotal = 0; - - /* FIXME: all need actual sizes */ - /* part 1: gate cap of NOR gates */ - Ctotal += (req_width - 1) * SIM_power_gatecap(WdecNORn + WdecNORp, 0); - - /* part 2: inverter */ - Ctotal += SIM_power_draincap(Wdecinvn, NCH, 1) + SIM_power_draincap(Wdecinvp, PCH, 1) + - SIM_power_gatecap(Wdecinvn + Wdecinvp, 0); - - /* part 3: gate cap of the "huge" NOR gate */ - Ctotal += SIM_power_gatecap(WdecNORn + WdecNORp, 0); - - /* part 4: wire cap */ - Ctotal += length * Cmetal; - - return Ctotal; -} - - -/* switch cap of priority signal (matrix arbiter) */ -static double matrix_arbiter_pri_cap(unsigned req_width) -{ - double Ctotal = 0; - - /* part 1: gate cap of NOR gates (2 groups) */ - Ctotal += 2 * SIM_power_gatecap(WdecNORn + WdecNORp, 0); - - /* no inverter because priority signal is kept by a flip flop */ - return Ctotal; -} - - -/* switch cap of grant signal (matrix arbiter) */ -static double matrix_arbiter_grant_cap(unsigned req_width) -{ - /* drain cap of the "huge" NOR gate */ - return (req_width * SIM_power_draincap(WdecNORn, NCH, 1) + SIM_power_draincap(WdecNORp, PCH, req_width)); -} - - -/* switch cap of internal node (matrix arbiter) */ -static double matrix_arbiter_int_cap() -{ - double Ctotal = 0; - - /* part 1: drain cap of NOR gate */ - Ctotal += 2 * SIM_power_draincap(WdecNORn, NCH, 1) + SIM_power_draincap(WdecNORp, PCH, 2); - - /* part 2: gate cap of the "huge" NOR gate */ - Ctotal += SIM_power_gatecap(WdecNORn + WdecNORp, 0); - - return Ctotal; -} - - -static int arbiter_clear_stat(power_arbiter *arb) -{ - arb->n_chg_req = arb->n_chg_grant = arb->n_chg_mint = 0; - arb->n_chg_carry = arb->n_chg_carry_in = 0; - - SIM_array_clear_stat(&arb->queue); - SIM_fpfp_clear_stat(&arb->pri_ff); - - return 0; -} - - -int power_arbiter_init(power_arbiter *arb, int arbiter_model, int ff_model, unsigned req_width, double length, power_array_info *info) -{ - if ((arb->model = arbiter_model) && arbiter_model < ARBITER_MAX_MODEL) { - arb->req_width = req_width; - arbiter_clear_stat(arb); - /* redundant field */ - arb->mask = HAMM_MASK(req_width); - - switch (arbiter_model) { - case RR_ARBITER: - arb->e_chg_req = rr_arbiter_req_cap(length) / 2 * EnergyFactor; - /* two grant signals switch together, so no 1/2 */ - arb->e_chg_grant = rr_arbiter_grant_cap() * EnergyFactor; - arb->e_chg_carry = rr_arbiter_carry_cap() / 2 * EnergyFactor; - arb->e_chg_carry_in = rr_arbiter_carry_in_cap() / 2 * EnergyFactor; - arb->e_chg_mint = 0; - - if (SIM_fpfp_init(&arb->pri_ff, ff_model, rr_arbiter_pri_cap())) - return -1; - break; - - case MATRIX_ARBITER: - arb->e_chg_req = matrix_arbiter_req_cap(req_width, length) / 2 * EnergyFactor; - /* 2 grant signals switch together, so no 1/2 */ - arb->e_chg_grant = matrix_arbiter_grant_cap(req_width) * EnergyFactor; - arb->e_chg_mint = matrix_arbiter_int_cap() / 2 * EnergyFactor; - arb->e_chg_carry = arb->e_chg_carry_in = 0; - - if (SIM_fpfp_init(&arb->pri_ff, ff_model, matrix_arbiter_pri_cap(req_width))) - return -1; - break; - - case QUEUE_ARBITER: - arb->e_chg_req = arb->e_chg_grant = arb->e_chg_mint = 0; - arb->e_chg_carry = arb->e_chg_carry_in = 0; - - return power_array_init(info, &arb->queue); - break; - - default: break;/* some error handler */ - } - - return 0; - } - else - return -1; -} - - -int arbiter_record(power_arbiter *arb, unsigned long int new_req, unsigned long int old_req, unsigned new_grant, unsigned old_grant) -{ - switch (arb->model) { - case MATRIX_ARBITER: - arb->n_chg_req += SIM_power_Hamming(new_req, old_req, arb->mask); - arb->n_chg_grant += new_grant != old_grant; - /* FIXME: approximation */ - arb->n_chg_mint += (arb->req_width - 1) * arb->req_width / 2; - /* priority registers */ - /* FIXME: use average instead */ - arb->pri_ff.n_switch += (arb->req_width - 1) / 2; - break; - - case RR_ARBITER: - arb->n_chg_req += SIM_power_Hamming(new_req, old_req, arb->mask); - arb->n_chg_grant += new_grant != old_grant; - /* FIXME: use average instead */ - arb->n_chg_carry += arb->req_width / 2; - arb->n_chg_carry_in += arb->req_width / 2 - 1; - /* priority registers */ - arb->pri_ff.n_switch += 2; - break; - - case QUEUE_ARBITER: - break; - - default: break;/* some error handler */ - } - - return 0; -} - - -double arbiter_report(power_arbiter *arb) -{ - switch (arb->model) { - case MATRIX_ARBITER: - return (arb->n_chg_req * arb->e_chg_req + arb->n_chg_grant * arb->e_chg_grant + - arb->n_chg_mint * arb->e_chg_mint + - arb->pri_ff.n_switch * arb->pri_ff.e_switch + - arb->pri_ff.n_keep_1 * arb->pri_ff.e_keep_1 + - arb->pri_ff.n_keep_0 * arb->pri_ff.e_keep_0 + - arb->pri_ff.n_clock * arb->pri_ff.e_clock); - - case RR_ARBITER: - return (arb->n_chg_req * arb->e_chg_req + arb->n_chg_grant * arb->e_chg_grant + - arb->n_chg_carry * arb->e_chg_carry + arb->n_chg_carry_in * arb->e_chg_carry_in + - arb->pri_ff.n_switch * arb->pri_ff.e_switch + - arb->pri_ff.n_keep_1 * arb->pri_ff.e_keep_1 + - arb->pri_ff.n_keep_0 * arb->pri_ff.e_keep_0 + - arb->pri_ff.n_clock * arb->pri_ff.e_clock); - - default: return -1; - } -} - -/* ---------- arbiter power model ----------- */ - - diff --git a/src/mem/ruby/network/orion/power_arbiter.hh b/src/mem/ruby/network/orion/power_arbiter.hh deleted file mode 100644 index f2c3a9eab..000000000 --- a/src/mem/ruby/network/orion/power_arbiter.hh +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * 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. - */ - -// Arbiter - - -#ifndef _POWER_ARBITER_H -#define _POWER_ARBITER_H - -#include "mem/ruby/network/orion/power_array.hh" - -typedef enum { - RR_ARBITER =1, - MATRIX_ARBITER, - QUEUE_ARBITER, - ARBITER_MAX_MODEL -} power_arbiter_model; - -typedef enum { - NEG_DFF = 1, /* negative egde-triggered D flip-flop */ - FF_MAX_MODEL -} power_ff_model; - -typedef struct { - int model; - unsigned long int n_switch; - unsigned long int n_keep_1; - unsigned long int n_keep_0; - unsigned long int n_clock; - double e_switch; - double e_keep_1; - double e_keep_0; - double e_clock; - double i_leakage; -} power_ff; - -typedef struct{ - int model; - unsigned req_width; - unsigned long int n_chg_req; - unsigned long int n_chg_grant; - unsigned long int n_chg_carry; //internal node of rr arbiter - unsigned long int n_chg_carry_in; //internal node of rr arbiter - unsigned long int n_chg_mint; //internal node of matrix arbiter - unsigned long int mask; - double e_chg_req; - double e_chg_grant; - double e_chg_carry; - double e_chg_carry_in; - double e_chg_mint; - power_ff pri_ff; //priority ff - power_array queue; //request queue - double i_leakage; -} power_arbiter; - -extern int arbiter_record(power_arbiter *arb, unsigned long int new_req, unsigned long int old_req, unsigned new_grant, unsigned old_grant); - -extern double arbiter_report(power_arbiter *arb); - -extern int power_arbiter_init(power_arbiter *arb, int arbiter_model, int ff_model, unsigned req_width, double length, power_array_info *info); - -#endif - - - diff --git a/src/mem/ruby/network/orion/power_array.cc b/src/mem/ruby/network/orion/power_array.cc deleted file mode 100644 index 9ac08ffb0..000000000 --- a/src/mem/ruby/network/orion/power_array.cc +++ /dev/null @@ -1,2158 +0,0 @@ -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> -#include <math.h> - -#include "mem/ruby/network/orion/power_array.hh" -#include "mem/ruby/network/orion/power_ll.hh" -#include "mem/ruby/network/orion/parm_technology.hh" -#include "mem/ruby/network/orion/SIM_port.hh" -#include "mem/ruby/network/orion/power_static.hh" -#include "mem/ruby/network/orion/power_utils.hh" - -/* local macros */ - -#define IS_DIRECT_MAP( info ) ((info)->assoc == 1) -#define IS_FULLY_ASSOC( info ) ((info)->n_set == 1 && (info)->assoc > 1) -#define IS_WRITE_THROUGH( info ) (! (info)->write_policy) -#define IS_WRITE_BACK( info ) ((info)->write_policy) - -/* sufficient (not necessary) condition */ -#define HAVE_TAG( info ) ((info)->tag_mem_model) -#define HAVE_USE_BIT( info ) ((info)->use_bit_width) -#define HAVE_COL_DEC( info ) ((info)->col_dec_model) -#define HAVE_COL_MUX( info ) ((info)->mux_model) - - -/* ----------------------------- CAM ---------------------------------- */ -/*============================== wordlines ==============================*/ - -/* each time one wordline 1->0, another wordline 0->1, so no 1/2 */ -double SIM_cam_wordline_cap( unsigned cols, double wire_cap, double tx_width ) -{ - double Ctotal, Cline, psize, nsize; - - /* part 1: line cap, including gate cap of pass tx's and metal cap */ - Ctotal = Cline = SIM_power_gatecappass( tx_width, 2 ) * cols + wire_cap; - - /* part 2: input driver */ - psize = SIM_power_driver_size( Cline, Period / 8 ); - nsize = psize * Wdecinvn / Wdecinvp; - /* WHS: 20 should go to PARM */ - Ctotal += SIM_power_draincap( nsize, NCH, 1 ) + SIM_power_draincap( psize, PCH, 1 ) + - SIM_power_gatecap( nsize + psize, 20 ); - - return Ctotal; -} - -/*============================== wordlines ==============================*/ - - - -/*============================== tag comparator ==============================*/ - -/* tag and tagbar switch simultaneously, so no 1/2 */ -double SIM_cam_comp_tagline_cap( unsigned rows, double taglinelength ) -{ - double Ctotal; - - /* part 1: line cap, including drain cap of pass tx's and metal cap */ - Ctotal = rows * SIM_power_gatecap( Wcomparen2, 2 ) + CC3M2metal * taglinelength; - - /* part 2: input driver */ - Ctotal += SIM_power_draincap( Wcompdrivern, NCH, 1 ) + SIM_power_draincap( Wcompdriverp, PCH, 1 ) + - SIM_power_gatecap( Wcompdrivern + Wcompdriverp, 1 ); - - return Ctotal; -} - - -/* upon mismatch, matchline 1->0, then 0->1 on next precharging, so no 1/2 */ -double SIM_cam_comp_mismatch_cap( unsigned n_bits, unsigned n_pre, double matchline_len ) -{ - double Ctotal; - - /* part 1: drain cap of precharge tx */ - Ctotal = n_pre * SIM_power_draincap( Wmatchpchg, PCH, 1 ); - - /* part 2: drain cap of comparator tx */ - Ctotal += n_bits * ( SIM_power_draincap( Wcomparen1, NCH, 1 ) + SIM_power_draincap( Wcomparen1, NCH, 2 )); - - /* part 3: metal cap of matchline */ - Ctotal += CC3M3metal * matchline_len; - - /* FIXME: I don't understand the Wattch code here */ - /* part 4: nor gate of valid output */ - Ctotal += SIM_power_gatecap( Wmatchnorn + Wmatchnorp, 10 ); - - return Ctotal; -} - - -/* WHS: subtle difference of valid output between cache and inst window: - * fully-associative cache: nor all matchlines of the same port - * instruction window: nor all matchlines of the same tag line */ -/* upon miss, valid output switches twice in one cycle, so no 1/2 */ -double SIM_cam_comp_miss_cap( unsigned assoc ) -{ - /* drain cap of valid output */ - return ( assoc * SIM_power_draincap( Wmatchnorn, NCH, 1 ) + SIM_power_draincap( Wmatchnorp, PCH, assoc )); -} - -/*============================== tag comparator ==============================*/ - - - -/*============================== memory cell ==============================*/ - -/* WHS: use Wmemcella and Wmemcellbscale to compute tx width of memory cell */ -double SIM_cam_tag_mem_cap( unsigned read_ports, unsigned write_ports, int share_rw, unsigned end, int only_write ) -{ - double Ctotal; - - /* part 1: drain capacitance of pass transistors */ - if ( only_write ) - Ctotal = SIM_power_draincap( Wmemcellw, NCH, 1 ) * write_ports; - else { - Ctotal = SIM_power_draincap( Wmemcellr, NCH, 1 ) * read_ports * end / 2; - if ( ! share_rw ) - Ctotal += SIM_power_draincap( Wmemcellw, NCH, 1 ) * write_ports; - } - - /* has coefficient ( 1/2 * 2 ) */ - /* part 2: drain capacitance of memory cell */ - Ctotal += SIM_power_draincap( Wmemcella, NCH, 1 ) + SIM_power_draincap( Wmemcella * Wmemcellbscale, PCH, 1 ); - - /* has coefficient ( 1/2 * 2 ) */ - /* part 3: gate capacitance of memory cell */ - Ctotal += SIM_power_gatecap( Wmemcella, 1 ) + SIM_power_gatecap( Wmemcella * Wmemcellbscale, 1 ); - - /* has coefficient ( 1/2 * 2 ) */ - /* part 4: gate capacitance of comparator */ - Ctotal += SIM_power_gatecap( Wcomparen1, 2 ) * read_ports; - - return Ctotal; -} - - -double SIM_cam_data_mem_cap( unsigned read_ports, unsigned write_ports ) -{ - double Ctotal; - - /* has coefficient ( 1/2 * 2 ) */ - /* part 1: drain capacitance of pass transistors */ - Ctotal = SIM_power_draincap( Wmemcellw, NCH, 1 ) * write_ports; - - /* has coefficient ( 1/2 * 2 ) */ - /* part 2: drain capacitance of memory cell */ - Ctotal += SIM_power_draincap( Wmemcella, NCH, 1 ) + SIM_power_draincap( Wmemcella * Wmemcellbscale, PCH, 1 ); - - /* has coefficient ( 1/2 * 2 ) */ - /* part 3: gate capacitance of memory cell */ - Ctotal += SIM_power_gatecap( Wmemcella, 1 ) + SIM_power_gatecap( Wmemcella * Wmemcellbscale, 1 ); - - /* part 4: gate capacitance of output driver */ - Ctotal += ( SIM_power_gatecap( Woutdrvnandn, 1 ) + SIM_power_gatecap( Woutdrvnandp, 1 ) + - SIM_power_gatecap( Woutdrvnorn, 1 ) + SIM_power_gatecap( Woutdrvnorp, 1 )) / 2 * read_ports; - - return Ctotal; -} - -/*============================== memory cell ==============================*/ - - - - - - - -/* ---------- buffer model ------------ */ - -// ------- Decoder begin - -/*# - * compute switching cap when decoder changes output (select signal) - * - * Parameters: - * n_input -- fanin of 1 gate of last level decoder - * - * Return value: switching cap - * - * NOTES: 2 select signals switch, so no 1/2 - */ -static double SIM_array_dec_select_cap( unsigned n_input ) -{ - double Ctotal = 0; - - /* FIXME: why? */ - // if ( numstack > 5 ) numstack = 5; - - /* part 1: drain cap of last level decoders */ - Ctotal = n_input * SIM_power_draincap( WdecNORn, NCH, 1 ) + SIM_power_draincap( WdecNORp, PCH, n_input ); - - /* part 2: output inverter */ - /* WHS: 20 should go to PARM */ - Ctotal += SIM_power_draincap( Wdecinvn, NCH, 1 ) + SIM_power_draincap( Wdecinvp, PCH, 1) + - SIM_power_gatecap( Wdecinvn + Wdecinvp, 20 ); - - return Ctotal; -} - - -/*# - * compute switching cap when 1 input bit of decoder changes - * - * Parameters: - * n_gates -- fanout of 1 addr signal - * - * Return value: switching cap - * - * NOTES: both addr and its complement change, so no 1/2 - */ -static double SIM_array_dec_chgaddr_cap( unsigned n_gates ) -{ - double Ctotal; - - /* stage 1: input driver */ - Ctotal = SIM_power_draincap( Wdecdrivep, PCH, 1 ) + SIM_power_draincap( Wdecdriven, NCH, 1 ) + - SIM_power_gatecap( Wdecdrivep, 1 ) + SIM_power_gatecap( Wdecdriven, 1 ); - /* inverter to produce complement addr, this needs 1/2 */ - /* WHS: assume Wdecinv(np) for this inverter */ - Ctotal += ( SIM_power_draincap( Wdecinvp, PCH, 1 ) + SIM_power_draincap( Wdecinvn, NCH, 1 ) + - SIM_power_gatecap( Wdecinvp, 1 ) + SIM_power_gatecap( Wdecinvn, 1 )) / 2; - - /* stage 2: gate cap of level-1 decoder */ - /* WHS: 10 should go to PARM */ - Ctotal += n_gates * SIM_power_gatecap( Wdec3to8n + Wdec3to8p, 10 ); - - return Ctotal; -} - - -/*# - * compute switching cap when 1st-level decoder changes output - * - * Parameters: - * n_in_1st -- fanin of 1 gate of 1st-level decoder - * n_in_2nd -- fanin of 1 gate of 2nd-level decoder - * n_gates -- # of gates of 2nd-level decoder, i.e. - * fanout of 1 gate of 1st-level decoder - * - * Return value: switching cap - * - * NOTES: 2 complementary signals switch, so no 1/2 - */ -static double SIM_array_dec_chgl1_cap( unsigned n_in_1st, unsigned n_in_2nd, unsigned n_gates ) -{ - double Ctotal; - - /* part 1: drain cap of level-1 decoder */ - Ctotal = n_in_1st * SIM_power_draincap( Wdec3to8p, PCH, 1 ) + SIM_power_draincap( Wdec3to8n, NCH, n_in_1st ); - - /* part 2: gate cap of level-2 decoder */ - /* WHS: 40 and 20 should go to PARM */ - Ctotal += n_gates * SIM_power_gatecap( WdecNORn + WdecNORp, n_in_2nd * 40 + 20 ); - - return Ctotal; -} - - -static int SIM_array_dec_clear_stat(power_decoder *dec) -{ - dec->n_chg_output = dec->n_chg_l1 = dec->n_chg_addr = 0; - - return 0; -} - - -/*# - * initialize decoder - * - * Parameters: - * dec -- decoder structure - * model -- decoder model type - * n_bits -- decoder width - * - * Side effects: - * initialize dec structure if model type is valid - * - * Return value: -1 if model type is invalid - * 0 otherwise - */ -static int SIM_array_dec_init(power_decoder *dec, int model, unsigned n_bits ) -{ - if ((dec->model = model) && model < DEC_MAX_MODEL) { - dec->n_bits = n_bits; - /* redundant field */ - dec->addr_mask = HAMM_MASK(n_bits); - - SIM_array_dec_clear_stat(dec); - dec->e_chg_output = dec->e_chg_l1 = dec->e_chg_addr = 0; - - /* compute geometry parameters */ - if ( n_bits >= 4 ) { /* 2-level decoder */ - /* WHS: inaccurate for some n_bits */ - dec->n_in_1st = ( n_bits == 4 ) ? 2:3; - dec->n_out_0th = BIGONE << ( dec->n_in_1st - 1 ); - dec->n_in_2nd = (unsigned)ceil((double)n_bits / dec->n_in_1st ); - dec->n_out_1st = BIGONE << ( n_bits - dec->n_in_1st ); - } - else if ( n_bits >= 2 ) { /* 1-level decoder */ - dec->n_in_1st = n_bits; - dec->n_out_0th = BIGONE << ( n_bits - 1 ); - dec->n_in_2nd = dec->n_out_1st = 0; - } - else { /* no decoder basically */ - dec->n_in_1st = dec->n_in_2nd = dec->n_out_0th = dec->n_out_1st = 0; - } - - /* compute energy constants */ - if ( n_bits >= 2 ) { - dec->e_chg_l1 = SIM_array_dec_chgl1_cap( dec->n_in_1st, dec->n_in_2nd, dec->n_out_1st ) * EnergyFactor; - if ( n_bits >= 4 ) - dec->e_chg_output = SIM_array_dec_select_cap( dec->n_in_2nd ) * EnergyFactor; - } - dec->e_chg_addr = SIM_array_dec_chgaddr_cap( dec->n_out_0th ) * EnergyFactor; - - return 0; - } - else - return -1; -} - - -/*# - * record decoder power stats - * - * Parameters: - * dec -- decoder structure - * prev_addr -- previous input - * curr_addr -- current input - * - * Side effects: - * update counters in dec structure - * - * Return value: 0 - */ -int SIM_array_dec_record(power_decoder *dec, unsigned long int prev_addr, unsigned long int curr_addr ) -{ - unsigned n_chg_bits, n_chg_l1 = 0, n_chg_output = 0; - unsigned i; - unsigned long int mask; - - /* compute Hamming distance */ - n_chg_bits = SIM_power_Hamming( prev_addr, curr_addr, dec->addr_mask ); - if ( n_chg_bits ) { - if ( dec->n_bits >= 4 ) { /* 2-level decoder */ - /* WHS: inaccurate for some n_bits */ - n_chg_output ++; - /* count addr group changes */ - mask = HAMM_MASK(dec->n_in_1st); - for ( i = 0; i < dec->n_in_2nd; i ++ ) { - if ( SIM_power_Hamming( prev_addr, curr_addr, mask )) - n_chg_l1 ++; - mask = mask << dec->n_in_1st; - } - } - else if ( dec->n_bits >= 2 ) { /* 1-level decoder */ - n_chg_l1 ++; - } - - dec->n_chg_addr += n_chg_bits; - dec->n_chg_l1 += n_chg_l1; - dec->n_chg_output += n_chg_output; - } - - return 0; -} - - -/*# - * report decoder power stats - * - * Parameters: - * dec -- decoder structure - * - * Return value: total energy consumption of this decoder - * - * TODO: add more report functionality, currently only total energy is reported - */ -double SIM_array_dec_report(power_decoder *dec ) -{ - double Etotal; - - Etotal = dec->n_chg_output * dec->e_chg_output + dec->n_chg_l1 * dec->e_chg_l1 + - dec->n_chg_addr * dec->e_chg_addr; - - /* bonus energy for dynamic decoder :) */ - //if ( is_dynamic_dec( dec->model )) Etotal += Etotal; - - return Etotal; -} - -// ------- Decoder end - - - -// ------- Wordlines begin - -/*# - * compute wordline switching cap - * - * Parameters: - * cols -- # of pass transistors, i.e. # of bitlines - * wordlinelength -- length of wordline - * tx_width -- width of pass transistor - * - * Return value: switching cap - * - * NOTES: upon address change, one wordline 1->0, another 0->1, so no 1/2 - */ -static double SIM_array_wordline_cap( unsigned cols, double wire_cap, double tx_width ) -{ - double Ctotal, Cline, psize, nsize; - - /* part 1: line cap, including gate cap of pass tx's and metal cap */ - Ctotal = Cline = SIM_power_gatecappass( tx_width, BitWidth / 2 - tx_width ) * cols + wire_cap; - - /* part 2: input driver */ - psize = SIM_power_driver_size( Cline, Period / 16 ); - nsize = psize * Wdecinvn / Wdecinvp; - /* WHS: 20 should go to PARM */ - Ctotal += SIM_power_draincap( nsize, NCH, 1 ) + SIM_power_draincap( psize, PCH, 1 ) + - SIM_power_gatecap( nsize + psize, 20 ); - - return Ctotal; -} - - -static int SIM_array_wordline_clear_stat(power_wordline *wordline) -{ - wordline->n_read = wordline->n_write = 0; - - return 0; -} - - -/*# - * initialize wordline - * - * Parameters: - * wordline -- wordline structure - * model -- wordline model type - * share_rw -- 1 if shared R/W wordlines, 0 if separate R/W wordlines - * cols -- # of array columns, NOT # of bitlines - * wire_cap -- wordline wire capacitance - * end -- end of bitlines - * - * Return value: -1 if invalid model type - * 0 otherwise - * - * Side effects: - * initialize wordline structure if model type is valid - * - * TODO: add error handler - */ -static int SIM_array_wordline_init(power_wordline *wordline, int model, int share_rw, unsigned cols, double wire_cap, unsigned end ) -{ - if ((wordline->model = model) && model < WORDLINE_MAX_MODEL) { - SIM_array_wordline_clear_stat(wordline); - - switch ( model ) { - case CAM_RW_WORDLINE: - wordline->e_read = SIM_cam_wordline_cap( cols * end, wire_cap, Wmemcellr ) * EnergyFactor; - if ( wordline->share_rw = share_rw ) - wordline->e_write = wordline->e_read; - else - /* write bitlines are always double-ended */ - wordline->e_write = SIM_cam_wordline_cap( cols * 2, wire_cap, Wmemcellw ) * EnergyFactor; - break; - - case CAM_WO_WORDLINE: /* only have write wordlines */ - wordline->share_rw = 0; - wordline->e_read = 0; - wordline->e_write = SIM_cam_wordline_cap( cols * 2, wire_cap, Wmemcellw ) * EnergyFactor; - break; - - case CACHE_WO_WORDLINE: /* only have write wordlines */ - wordline->share_rw = 0; - wordline->e_read = 0; - wordline->e_write = SIM_array_wordline_cap( cols * 2, wire_cap, Wmemcellw ) * EnergyFactor; - break; - - case CACHE_RW_WORDLINE: - wordline->e_read = SIM_array_wordline_cap( cols * end, wire_cap, Wmemcellr ) * EnergyFactor; - if ( wordline->share_rw = share_rw ) - wordline->e_write = wordline->e_read; - else - wordline->e_write = SIM_array_wordline_cap( cols * 2, wire_cap, Wmemcellw ) * EnergyFactor; - - /* static power */ - /* input driver */ - wordline->i_leakage = (Woutdrivern * NMOS_TAB[0] + Woutdriverp * PMOS_TAB[0]) / PARM_TECH_POINT * 100; - break; - - default: break;/* some error handler */ - } - - return 0; - } - else - return -1; -} - - -/*# - * record wordline power stats - * - * Parameters: - * wordline -- wordline structure - * rw -- 1 if write operation, 0 if read operation - * n_switch -- switching times - * - * Return value: 0 - * - * Side effects: - * update counters of wordline structure - */ -int SIM_array_wordline_record(power_wordline *wordline, int rw, unsigned long int n_switch ) -{ - if ( rw ) wordline->n_write += n_switch; - else wordline->n_read += n_switch; - - return 0; -} - - -/*# - * report wordline power stats - * - * Parameters: - * wordline -- wordline structure - * - * Return value: total energy consumption of all wordlines of this array - * - * TODO: add more report functionality, currently only total energy is reported - */ -double SIM_array_wordline_report(power_wordline *wordline ) -{ - return ( wordline->n_read * wordline->e_read + - wordline->n_write * wordline->e_write ); -} - -// ------- Wordlines end - - - -// ------- Bitlines begin - -/*# - * compute switching cap of reading 1 separate bitline column - * - * Parameters: - * rows -- # of array rows, i.e. # of wordlines - * wire_cap -- bitline wire capacitance - * end -- end of bitlines - * n_share_amp -- # of columns who share one sense amp - * n_bitline_pre -- # of precharge transistor drains for 1 bitline column - * n_colsel_pre -- # of precharge transistor drains for 1 column selector, if any - * pre_size -- width of precharge transistors - * outdrv_model -- output driver model type - * - * Return value: switching cap - * - * NOTES: one bitline 1->0, then 0->1 on next precharging, so no 1/2 - */ -static double SIM_array_column_read_cap(unsigned rows, double wire_cap, unsigned end, unsigned n_share_amp, unsigned n_bitline_pre, unsigned n_colsel_pre, double pre_size, int outdrv_model) -{ - double Ctotal=0, Cprecharge=0, Cpass=0, Cwire=0, Ccol_sel=0, Csense=0; - - /* part 1: drain cap of precharge tx's */ - Cprecharge = n_bitline_pre * SIM_power_draincap( pre_size, PCH, 1 ); -// printf("Precharge = %g\n", Cprecharge); - Ctotal = Cprecharge; - - /* part 2: drain cap of pass tx's */ - Cpass = rows * SIM_power_draincap( Wmemcellr, NCH, 1 ); -// printf("Pass = %g\n", Cpass); - Ctotal += Cpass; - - /* part 3: metal cap */ - Cwire = wire_cap; -// printf("Wire = %g\n", Cwire); - Ctotal += Cwire; - - /* part 4: column selector or bitline inverter */ - if ( end == 1 ) { /* bitline inverter */ - /* FIXME: magic numbers */ - Ccol_sel = SIM_power_gatecap( MSCALE * ( 29.9 + 7.8 ), 0 ) + - SIM_power_gatecap( MSCALE * ( 47.0 + 12.0), 0 ); - } - else if ( n_share_amp > 1 ) { /* column selector */ - /* drain cap of pass tx's */ - Ccol_sel = ( n_share_amp + 1 ) * SIM_power_draincap( Wbitmuxn, NCH, 1 ); - /* drain cap of column selector precharge tx's */ - Ccol_sel += n_colsel_pre * SIM_power_draincap( pre_size, PCH, 1 ); - /* FIXME: no way to count activity factor on gates of column selector */ - } -// printf("Col selector = %g\n", Ccol_sel); - - Ctotal += Ccol_sel; - - /* part 5: gate cap of sense amplifier or output driver */ - if (end == 2) /* sense amplifier */ - Csense = 2 * SIM_power_gatecap( WsenseQ1to4, 10 ); - else if (outdrv_model) /* end == 1, output driver */ - Csense = SIM_power_gatecap( Woutdrvnandn, 1 ) + SIM_power_gatecap( Woutdrvnandp, 1 ) + - SIM_power_gatecap( Woutdrvnorn, 1 ) + SIM_power_gatecap( Woutdrvnorp, 1 ); -// printf("Sense = %g\n", Csense); - Ctotal += Csense; - - return Ctotal; -} - - -/*# - * compute switching cap of selecting 1 column selector - * - * Parameters: - * - * Return value: switching cap - * - * NOTES: select one, deselect another, so no 1/2 - */ -static double SIM_array_column_select_cap( void ) -{ - return SIM_power_gatecap( Wbitmuxn, 1 ); -} - - -/*# - * compute switching cap of writing 1 separate bitline column - * - * Parameters: - * rows -- # of array rows, i.e. # of wordlines - * wire_cap -- bitline wire capacitance - * - * Return value: switching cap - * - * NOTES: bit and bitbar switch simultaneously, so no 1/2 - */ -static double SIM_array_column_write_cap( unsigned rows, double wire_cap ) -{ - double Ctotal=0, Cwire=0, Cpass=0, Cdriver=0, psize, nsize; - - Cwire = wire_cap; -// printf("WRITE wire cap = %g\n", Cwire); - Ctotal = Cwire; - - /* part 1: line cap, including drain cap of pass tx's and metal cap */ - Cpass = rows * SIM_power_draincap( Wmemcellw, NCH, 1 ); -// printf("WRITE pass tx cap = %g\n", Cpass); - Ctotal += Cpass; - - - /* part 2: write driver */ - psize = SIM_power_driver_size( Ctotal, Period / 8 ); - nsize = psize * Wdecinvn / Wdecinvp; - Cdriver = SIM_power_draincap( psize, PCH, 1 ) + SIM_power_draincap( nsize, NCH, 1 ) + - SIM_power_gatecap( psize + nsize, 1 ); -// printf("WRITE driver cap = %g\n", Cdriver); - Ctotal += Cdriver; - - return Ctotal; -} - - -/* one bitline switches twice in one cycle, so no 1/2 */ -static double SIM_array_share_column_write_cap( unsigned rows, double wire_cap, unsigned n_share_amp, unsigned n_bitline_pre, double pre_size ) -{ - double Ctotal, psize, nsize; - - /* part 1: drain cap of precharge tx's */ - Ctotal = n_bitline_pre * SIM_power_draincap( pre_size, PCH, 1 ); - - /* part 2: drain cap of pass tx's */ - Ctotal += rows * SIM_power_draincap( Wmemcellr, NCH, 1 ); - - /* part 3: metal cap */ - Ctotal += wire_cap; - - /* part 4: column selector or sense amplifier */ - if ( n_share_amp > 1 ) Ctotal += SIM_power_draincap( Wbitmuxn, NCH, 1 ); - else Ctotal += 2 * SIM_power_gatecap( WsenseQ1to4, 10 ); - - /* part 5: write driver */ - psize = SIM_power_driver_size( Ctotal, Period / 8 ); - nsize = psize * Wdecinvn / Wdecinvp; - /* WHS: omit gate cap of driver due to modeling difficulty */ - Ctotal += SIM_power_draincap( psize, PCH, 1 ) + SIM_power_draincap( nsize, NCH, 1 ); - - return Ctotal; -} - - -/* one bitline switches twice in one cycle, so no 1/2 */ -static double SIM_array_share_column_read_cap( unsigned rows, double wire_cap, unsigned n_share_amp, unsigned n_bitline_pre, unsigned n_colsel_pre, double pre_size ) -{ - double Ctotal; - - /* part 1: same portion as write */ - Ctotal = SIM_array_share_column_write_cap( rows, wire_cap, n_share_amp, n_bitline_pre, pre_size ); - - /* part 2: column selector and sense amplifier */ - if ( n_share_amp > 1 ) { - /* bottom part of drain cap of pass tx's */ - Ctotal += n_share_amp * SIM_power_draincap( Wbitmuxn, NCH, 1 ); - /* drain cap of column selector precharge tx's */ - Ctotal += n_colsel_pre * SIM_power_draincap( pre_size, PCH, 1 ); - - /* part 3: gate cap of sense amplifier */ - Ctotal += 2 * SIM_power_gatecap( WsenseQ1to4, 10 ); - } - - return Ctotal; -} - - -static int SIM_array_bitline_clear_stat(power_bitline *bitline) -{ - bitline->n_col_write = bitline->n_col_read = bitline->n_col_sel = 0; - - return 0; -} - - -static int SIM_array_bitline_init(power_bitline *bitline, int model, int share_rw, unsigned end, unsigned rows, double wire_cap, unsigned n_share_amp, unsigned n_bitline_pre, unsigned n_colsel_pre, double pre_size, int outdrv_model) -{ - if ((bitline->model = model) && model < BITLINE_MAX_MODEL) { - bitline->end = end; - SIM_array_bitline_clear_stat(bitline); - - switch ( model ) { - case RW_BITLINE: - if ( end == 2 ) - bitline->e_col_sel = SIM_array_column_select_cap() * EnergyFactor; - else /* end == 1 implies register file */ - bitline->e_col_sel = 0; -// printf("BUFFER INTERNAL bitline sel energy = %g\n", bitline->e_col_sel); - - if ( bitline->share_rw = share_rw ) { - /* shared bitlines are double-ended, so SenseEnergyFactor */ - bitline->e_col_read = SIM_array_share_column_read_cap( rows, wire_cap, n_share_amp, n_bitline_pre, n_colsel_pre, pre_size ) * SenseEnergyFactor; - bitline->e_col_write = SIM_array_share_column_write_cap( rows, wire_cap, n_share_amp, n_bitline_pre, pre_size ) * EnergyFactor; - } - else { - bitline->e_col_read = SIM_array_column_read_cap(rows, wire_cap, end, n_share_amp, n_bitline_pre, n_colsel_pre, pre_size, outdrv_model) * (end == 2 ? SenseEnergyFactor : EnergyFactor); -// printf("BUFFER INTERNAL bitline read energy = %g\n", bitline->e_col_read); - bitline->e_col_write = SIM_array_column_write_cap( rows, wire_cap ) * EnergyFactor; -// printf("BUFFER INTERNAL bitline write energy = %g\n", bitline->e_col_write); - - /* static power */ - bitline->i_leakage = 2 * (Wdecinvn * NMOS_TAB[0] + Wdecinvp * PMOS_TAB[0]) / PARM_TECH_POINT * 100; -// printf("BUFFER INTERNAL bitline leakage current = %g\n", bitline->i_leakage); - } - - break; - - case WO_BITLINE: /* only have write bitlines */ - bitline->share_rw = 0; - bitline->e_col_sel = bitline->e_col_read = 0; - bitline->e_col_write = SIM_array_column_write_cap( rows, wire_cap ) * EnergyFactor; - break; - - default: break;/* some error handler */ - } - - return 0; - } - else - return -1; -} - - -static int is_rw_bitline( int model ) -{ - return ( model == RW_BITLINE ); -} - - -/* WHS: no way to count activity factor on column selector gates */ -int SIM_array_bitline_record(power_bitline *bitline, int rw, unsigned cols, unsigned long int old_value, unsigned long int new_value ) -{ - /* FIXME: should use variable rather than computing each time */ - unsigned long int mask = HAMM_MASK(cols); - - if ( rw ) { /* write */ - if ( bitline->share_rw ) /* share R/W bitlines */ - bitline->n_col_write += cols; - else /* separate R/W bitlines */ - bitline->n_col_write += SIM_power_Hamming( old_value, new_value, mask ); - } - else { /* read */ - if ( bitline->end == 2 ) /* double-ended bitline */ - bitline->n_col_read += cols; - else /* single-ended bitline */ - /* WHS: read ~new_value due to the bitline inverter */ - bitline->n_col_read += SIM_power_Hamming( mask, ~new_value, mask ); - } - - return 0; -} - - -double SIM_array_bitline_report(power_bitline *bitline ) -{ - return ( bitline->n_col_write * bitline->e_col_write + - bitline->n_col_read * bitline->e_col_read + - bitline->n_col_sel * bitline->e_col_sel ); -} - -// ------- Bitlines end - - - -// ------- Sense amplifier begin - -/* estimate senseamp power dissipation in cache structures (Zyuban's method) */ -static double SIM_array_amp_energy( void ) -{ - return ( (double)Vdd / 8.0 * (double )(Period) * (double )(PARM_amp_Idsat)); -} - - -static int SIM_array_amp_clear_stat(power_amp *amp) -{ - amp->n_access = 0; - - return 0; -} - - -static int SIM_array_amp_init(power_amp *amp, int model ) -{ - if ((amp->model = model) && model < AMP_MAX_MODEL) { - SIM_array_amp_clear_stat(amp); - amp->e_access = SIM_array_amp_energy(); - - return 0; - } - else - return -1; -} - - -int SIM_array_amp_record(power_amp *amp, unsigned cols ) -{ - amp->n_access += cols; - - return 0; -} - - -double SIM_array_amp_report(power_amp *amp ) -{ - return ( amp->n_access * amp->e_access ); -} - -// ------- Sense amplifier end - - -// ------- Tag comparator begin - -/* eval switches twice per cycle, so no 1/2 */ -/* WHS: assume eval = 1 when no cache operation */ -static double SIM_array_comp_base_cap( void ) -{ - /* eval tx's: 4 inverters */ - return ( SIM_power_draincap( Wevalinvp, PCH, 1 ) + SIM_power_draincap( Wevalinvn, NCH, 1 ) + - SIM_power_gatecap( Wevalinvp, 1 ) + SIM_power_gatecap( Wevalinvn, 1 ) + - SIM_power_draincap( Wcompinvp1, PCH, 1 ) + SIM_power_draincap( Wcompinvn1, NCH, 1 ) + - SIM_power_gatecap( Wcompinvp1, 1 ) + SIM_power_gatecap( Wcompinvn1, 1 ) + - SIM_power_draincap( Wcompinvp2, PCH, 1 ) + SIM_power_draincap( Wcompinvn2, NCH, 1 ) + - SIM_power_gatecap( Wcompinvp2, 1 ) + SIM_power_gatecap( Wcompinvn2, 1 ) + - SIM_power_draincap( Wcompinvp3, PCH, 1 ) + SIM_power_draincap( Wcompinvn3, NCH, 1 ) + - SIM_power_gatecap( Wcompinvp3, 1 ) + SIM_power_gatecap( Wcompinvn3, 1 )); -} - - -/* no 1/2 for the same reason with SIM_array_comp_base_cap */ -static double SIM_array_comp_match_cap( unsigned n_bits ) -{ - return ( n_bits * ( SIM_power_draincap( Wcompn, NCH, 1 ) + SIM_power_draincap( Wcompn, NCH, 2 ))); -} - - -/* upon mismatch, select signal 1->0, then 0->1 on next precharging, so no 1/2 */ -static double SIM_array_comp_mismatch_cap( unsigned n_pre ) -{ - double Ctotal; - - /* part 1: drain cap of precharge tx */ - Ctotal = n_pre * SIM_power_draincap( Wcomppreequ, PCH, 1 ); - - /* part 2: nor gate of valid output */ - Ctotal += SIM_power_gatecap( WdecNORn, 1 ) + SIM_power_gatecap( WdecNORp, 3 ); - - return Ctotal; -} - - -/* upon miss, valid output switches twice in one cycle, so no 1/2 */ -static double SIM_array_comp_miss_cap( unsigned assoc ) -{ - /* drain cap of valid output */ - return ( assoc * SIM_power_draincap( WdecNORn, NCH, 1 ) + SIM_power_draincap( WdecNORp, PCH, assoc )); -} - - -/* no 1/2 for the same reason as base_cap */ -static double SIM_array_comp_bit_match_cap( void ) -{ - return ( 2 * ( SIM_power_draincap( Wcompn, NCH, 1 ) + SIM_power_draincap( Wcompn, NCH, 2 ))); -} - - -/* no 1/2 for the same reason as base_cap */ -static double SIM_array_comp_bit_mismatch_cap( void ) -{ - return ( 3 * SIM_power_draincap( Wcompn, NCH, 1 ) + SIM_power_draincap( Wcompn, NCH, 2 )); -} - - -/* each addr bit drives 2 nmos pass transistors, so no 1/2 */ -static double SIM_array_comp_chgaddr_cap( void ) -{ - return ( SIM_power_gatecap( Wcompn, 1 )); -} - - -static int SIM_array_comp_clear_stat(power_comp *comp) -{ - comp->n_access = comp->n_miss = comp->n_chg_addr = comp->n_match = 0; - comp->n_mismatch = comp->n_bit_match = comp->n_bit_mismatch = 0; - - return 0; -} - - -static int SIM_array_comp_init(power_comp *comp, int model, unsigned n_bits, unsigned assoc, unsigned n_pre, double matchline_len, double tagline_len ) -{ - if ((comp->model = model) && model < COMP_MAX_MODEL) { - comp->n_bits = n_bits; - comp->assoc = assoc; - /* redundant field */ - comp->comp_mask = HAMM_MASK(n_bits); - - SIM_array_comp_clear_stat(comp); - - switch ( model ) { - case CACHE_COMPONENT: - comp->e_access = SIM_array_comp_base_cap() * EnergyFactor; - comp->e_match = SIM_array_comp_match_cap( n_bits ) * EnergyFactor; - comp->e_mismatch = SIM_array_comp_mismatch_cap( n_pre ) * EnergyFactor; - comp->e_miss = SIM_array_comp_miss_cap( assoc ) * EnergyFactor; - comp->e_bit_match = SIM_array_comp_bit_match_cap() * EnergyFactor; - comp->e_bit_mismatch = SIM_array_comp_bit_mismatch_cap() * EnergyFactor; - comp->e_chg_addr = SIM_array_comp_chgaddr_cap() * EnergyFactor; - break; - - case CAM_COMP: - comp->e_access = comp->e_match = comp->e_chg_addr = 0; - comp->e_bit_match = comp->e_bit_mismatch = 0; - /* energy consumption of tagline */ - comp->e_chg_addr = SIM_cam_comp_tagline_cap( assoc, tagline_len ) * EnergyFactor; - comp->e_mismatch = SIM_cam_comp_mismatch_cap( n_bits, n_pre, matchline_len ) * EnergyFactor; - comp->e_miss = SIM_cam_comp_miss_cap( assoc ) * EnergyFactor; - break; - - default: break;/* some error handler */ - } - - return 0; - } - else - return -1; -} - - -int SIM_array_comp_global_record(power_comp *comp, unsigned long int prev_value, unsigned long int curr_value, int miss ) -{ - if ( miss ) comp->n_miss ++; - - switch ( comp->model ) { - case CACHE_COMPONENT: - comp->n_access ++; - comp->n_chg_addr += SIM_power_Hamming( prev_value, curr_value, comp->comp_mask ) * comp->assoc; - break; - - case CAM_COMP: - comp->n_chg_addr += SIM_power_Hamming( prev_value, curr_value, comp->comp_mask ); - break; - - default: break;/* some error handler */ - } - - return 0; -} - - -/* recover means prev_tag will recover on next cycle, e.g. driven by sense amplifier */ -/* return value: 1 if miss, 0 if hit */ -int SIM_array_comp_local_record(power_comp *comp, unsigned long int prev_tag, unsigned long int curr_tag, unsigned long int input, int recover ) -{ - unsigned H_dist; - int mismatch; - - if ( mismatch = ( curr_tag != input )) comp->n_mismatch ++; - - /* for cam, input changes are reflected in memory cells */ - if ( comp->model == CACHE_COMPONENT ) { - if ( recover ) - comp->n_chg_addr += 2 * SIM_power_Hamming( prev_tag, curr_tag, comp->comp_mask ); - else - comp->n_chg_addr += SIM_power_Hamming( prev_tag, curr_tag, comp->comp_mask ); - - if ( mismatch ) { - H_dist = SIM_power_Hamming( curr_tag, input, comp->comp_mask ); - comp->n_bit_mismatch += H_dist; - comp->n_bit_match += comp->n_bits - H_dist; - } - else comp->n_match ++; - } - - return mismatch; -} - - -double SIM_array_comp_report(power_comp *comp ) -{ - return ( comp->n_access * comp->e_access + comp->n_match * comp->e_match + - comp->n_mismatch * comp->e_mismatch + comp->n_miss * comp->e_miss + - comp->n_bit_match * comp->e_bit_match + comp->n_chg_addr * comp->e_chg_addr + - comp->n_bit_mismatch * comp->e_bit_mismatch ); -} - -// ------- Tag comparator end - - - -// ------- Multiplexor begin - -/* upon mismatch, 1 output of nor gates 1->0, then 0->1 on next cycle, so no 1/2 */ -static double SIM_array_mux_mismatch_cap( unsigned n_nor_gates ) -{ - double Cmul; - - /* stage 1: inverter */ - Cmul = SIM_power_draincap( Wmuxdrv12n, NCH, 1 ) + SIM_power_draincap( Wmuxdrv12p, PCH, 1 ) + - SIM_power_gatecap( Wmuxdrv12n, 1 ) + SIM_power_gatecap( Wmuxdrv12p, 1 ); - - /* stage 2: nor gates */ - /* gate cap of nor gates */ - Cmul += n_nor_gates * ( SIM_power_gatecap( WmuxdrvNORn, 1 ) + SIM_power_gatecap( WmuxdrvNORp, 1 )); - /* drain cap of nor gates, only count 1 */ - Cmul += SIM_power_draincap( WmuxdrvNORp, PCH, 2 ) + 2 * SIM_power_draincap( WmuxdrvNORn, NCH, 1 ); - - /* stage 3: output inverter */ - Cmul += SIM_power_gatecap( Wmuxdrv3n, 1 ) + SIM_power_gatecap( Wmuxdrv3p, 1 ) + - SIM_power_draincap( Wmuxdrv3n, NCH, 1 ) + SIM_power_draincap( Wmuxdrv3p, PCH, 1 ); - - return Cmul; -} - - -/* 2 nor gates switch gate signals, so no 1/2 */ -/* WHS: assume address changes won't propagate until matched or mismatched */ -static double SIM_array_mux_chgaddr_cap( void ) -{ - return ( SIM_power_gatecap( WmuxdrvNORn, 1 ) + SIM_power_gatecap( WmuxdrvNORp, 1 )); -} - - -static int SIM_array_mux_clear_stat(power_mux *mux) -{ - mux->n_mismatch = mux->n_chg_addr = 0; - - return 0; -} - - -static int SIM_array_mux_init(power_mux *mux, int model, unsigned n_gates, unsigned assoc ) -{ - if ((mux->model = model) && model < MUX_MAX_MODEL) { - mux->assoc = assoc; - - SIM_array_mux_clear_stat(mux); - - mux->e_mismatch = SIM_array_mux_mismatch_cap( n_gates ) * EnergyFactor; - mux->e_chg_addr = SIM_array_mux_chgaddr_cap() * EnergyFactor; - - return 0; - } - else - return -1; -} - - -int SIM_array_mux_record(power_mux *mux, unsigned long int prev_addr, unsigned long int curr_addr, int miss ) -{ - if ( prev_addr != curr_addr ) - mux->n_chg_addr += mux->assoc; - - if ( miss ) - mux->n_mismatch += mux->assoc; - else - mux->n_mismatch += mux->assoc - 1; - - return 0; -} - - -double SIM_array_mux_report(power_mux *mux ) -{ - return ( mux->n_mismatch * mux->e_mismatch + mux->n_chg_addr * mux->e_chg_addr ); -} - -// ------- Multiplexor end - - -// ------- Output driver begin - -/* output driver should be disabled somehow when no access occurs, so no 1/2 */ -static double SIM_array_outdrv_select_cap( unsigned data_width ) -{ - double Ctotal; - - /* stage 1: inverter */ - Ctotal = SIM_power_gatecap( Woutdrvseln, 1 ) + SIM_power_gatecap( Woutdrvselp, 1 ) + - SIM_power_draincap( Woutdrvseln, NCH, 1 ) + SIM_power_draincap( Woutdrvselp, 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 */ - Ctotal += data_width *( SIM_power_gatecap( Woutdrvnandn, 1 ) + SIM_power_gatecap( Woutdrvnandp, 1 ) + - SIM_power_gatecap( Woutdrvnorn, 1 ) + SIM_power_gatecap( Woutdrvnorp, 1 )); - - return Ctotal; -} - - -/* WHS: assume data changes won't propagate until enabled */ -static double SIM_array_outdrv_chgdata_cap( void ) -{ - return (( SIM_power_gatecap( Woutdrvnandn, 1 ) + SIM_power_gatecap( Woutdrvnandp, 1 ) + - SIM_power_gatecap( Woutdrvnorn, 1 ) + SIM_power_gatecap( Woutdrvnorp, 1 )) / 2 ); -} - - -/* no 1/2 for the same reason as outdrv_select_cap */ -static double SIM_array_outdrv_outdata_cap( unsigned value ) -{ - double Ctotal; - - /* stage 1: drain cap of nand gate or nor gate */ - if ( value ) - /* drain cap of nand gate */ - Ctotal = SIM_power_draincap( Woutdrvnandn, NCH, 2 ) + 2 * SIM_power_draincap( Woutdrvnandp, PCH, 1 ); - else - /* drain cap of nor gate */ - Ctotal = 2 * SIM_power_draincap( Woutdrvnorn, NCH, 1 ) + SIM_power_draincap( Woutdrvnorp, PCH, 2 ); - - /* stage 2: gate cap of output inverter */ - if ( value ) - Ctotal += SIM_power_gatecap( Woutdriverp, 1 ); - else - Ctotal += SIM_power_gatecap( Woutdrivern, 1 ); - - /* drain cap of output inverter should be included into bus cap */ - return Ctotal; -} - - -static int SIM_array_outdrv_clear_stat(power_out *outdrv) -{ - outdrv->n_select = outdrv->n_chg_data = 0; - outdrv->n_out_0 = outdrv->n_out_1 = 0; - - return 0; -} - - -static int SIM_array_outdrv_init(power_out *outdrv, int model, unsigned item_width ) -{ - if ((outdrv->model = model) && model < OUTDRV_MAX_MODEL) { - outdrv->item_width = item_width; - /* redundant field */ - outdrv->out_mask = HAMM_MASK(item_width); - - SIM_array_outdrv_clear_stat(outdrv); - - outdrv->e_select = SIM_array_outdrv_select_cap( item_width ) * EnergyFactor; - outdrv->e_out_1 = SIM_array_outdrv_outdata_cap( 1 ) * EnergyFactor; - outdrv->e_out_0 = SIM_array_outdrv_outdata_cap( 0 ) * EnergyFactor; - - switch ( model ) { - case CACHE_OUTDRV: - outdrv->e_chg_data = SIM_array_outdrv_chgdata_cap() * EnergyFactor; - break; - - case CAM_OUTDRV: - /* input changes are reflected in memory cells */ - case REG_OUTDRV: - /* input changes are reflected in bitlines */ - outdrv->e_chg_data = 0; - break; - - default: break;/* some error handler */ - } - - return 0; - } - else - return -1; -} - - -int SIM_array_outdrv_global_record(power_out *outdrv, unsigned long int data ) -{ - unsigned n_1; - - outdrv->n_select ++; - - n_1 = SIM_power_Hamming( data, 0, outdrv->out_mask ); - - outdrv->n_out_1 += n_1; - outdrv->n_out_0 += outdrv->item_width - n_1; - - return 0; -} - - -/* recover means prev_data will recover on next cycle, e.g. driven by sense amplifier */ -/* NOTE: this function SHOULD not be called by a fully-associative cache */ -int SIM_array_outdrv_local_record(power_out *outdrv, unsigned long int prev_data, unsigned long int curr_data, int recover ) -{ - if ( recover ) - outdrv->n_chg_data += 2 * SIM_power_Hamming( prev_data, curr_data, outdrv->out_mask ); - else - outdrv->n_chg_data += SIM_power_Hamming( prev_data, curr_data, outdrv->out_mask ); - - return 0; -} - - -double SIM_array_outdrv_report(power_out *outdrv ) -{ - return ( outdrv->n_select * outdrv->e_select + outdrv->n_chg_data * outdrv->e_chg_data + - outdrv->n_out_1 * outdrv->e_out_1 + outdrv->n_out_0 * outdrv->e_out_0 ); -} - -// ------- Output driver end - - - -// ------- Memcory cell begin - -/* WHS: use Wmemcella and Wmemcellbscale to compute tx width of memory cell */ -static double SIM_array_mem_cap( unsigned read_ports, unsigned write_ports, int share_rw, unsigned end ) -{ - double Ctotal; - - /* part 1: drain capacitance of pass transistors */ - Ctotal = SIM_power_draincap( Wmemcellr, NCH, 1 ) * read_ports * end / 2; - if ( ! share_rw ) - Ctotal += SIM_power_draincap( Wmemcellw, NCH, 1 ) * write_ports; - - /* has coefficient ( 1/2 * 2 ) */ - /* part 2: drain capacitance of memory cell */ - Ctotal += SIM_power_draincap( Wmemcella, NCH, 1 ) + SIM_power_draincap( Wmemcella * Wmemcellbscale, PCH, 1 ); - - /* has coefficient ( 1/2 * 2 ) */ - /* part 3: gate capacitance of memory cell */ - Ctotal += SIM_power_gatecap( Wmemcella, 1 ) + SIM_power_gatecap( Wmemcella * Wmemcellbscale, 1 ); - - return Ctotal; -} - - -static int SIM_array_mem_clear_stat(power_mem *mem) -{ - mem->n_switch = 0; - - return 0; -} - - -static int SIM_array_mem_init(power_mem *mem, int model, unsigned read_ports, unsigned write_ports, int share_rw, unsigned end ) -{ - double i_leakage; - - if ((mem->model = model) && model < MEM_MAX_MODEL) { - mem->end = end; - SIM_array_mem_clear_stat(mem); - - switch ( model ) { - case CAM_TAG_RW_MEM: - mem->e_switch = SIM_cam_tag_mem_cap( read_ports, write_ports, share_rw, end, SIM_ARRAY_RW ) * EnergyFactor; - break; - - /* FIXME: it's only an approximation using CAM_TAG_WO_MEM to emulate CAM_ATTACH_MEM */ - case CAM_ATTACH_MEM: - case CAM_TAG_WO_MEM: - mem->e_switch = SIM_cam_tag_mem_cap( read_ports, write_ports, share_rw, end, SIM_ARRAY_WO ) * EnergyFactor; - break; - - case CAM_DATA_MEM: - mem->e_switch = SIM_cam_data_mem_cap( read_ports, write_ports ) * EnergyFactor; - break; - - default: /* NORMAL_MEM */ - mem->e_switch = SIM_array_mem_cap( read_ports, write_ports, share_rw, end ) * EnergyFactor; - - /* static power */ - i_leakage = 0; - /* memory cell */ - i_leakage += (Wmemcella * NMOS_TAB[0] + Wmemcella * Wmemcellbscale * PMOS_TAB[0]) * 2; - /* read port pass tx */ - i_leakage += Wmemcellr * NMOS_TAB[0] * end * read_ports; - /* write port pass tx */ - if (! share_rw) - i_leakage += Wmemcellw * NMOS_TAB[0] * 2 * write_ports; - - mem->i_leakage = i_leakage / PARM_TECH_POINT * 100; - } - - return 0; - } - else - return -1; -} - - -int SIM_array_mem_record(power_mem *mem, unsigned long int prev_value, unsigned long int curr_value, unsigned width ) -{ - mem->n_switch += SIM_power_Hamming( prev_value, curr_value, HAMM_MASK(width)); - - return 0; -} - - -double SIM_array_mem_report(power_mem *mem ) -{ - return ( mem->n_switch * mem->e_switch ); -} - -// ------- Memcory cell end - - - -// ------- Precharge begin - -/* consider charge then discharge, so no 1/2 */ -static double SIM_array_pre_cap( double width, double length ) -{ - return SIM_power_gatecap( width, length ); -} - - -/* return # of precharging gates per column */ -static unsigned n_pre_gate( int model ) -{ - switch ( model ) { - case SINGLE_BITLINE: return 2; - case EQU_BITLINE: return 3; - case SINGLE_OTHER: return 1; - default: break;/* some error handler */ - } - - return 0; -} - - -/* return # of precharging drains per line */ -static unsigned n_pre_drain( int model ) -{ - switch ( model ) { - case SINGLE_BITLINE: return 1; - case EQU_BITLINE: return 2; - case SINGLE_OTHER: return 1; - default: break;/* some error handler */ - } - - return 0; -} - - -static int SIM_array_pre_clear_stat(power_arr_pre *pre) -{ - pre->n_charge = 0; - - return 0; -} - - -static int SIM_array_pre_init(power_arr_pre *pre, int model, double pre_size ) -{ - unsigned n_gate; - - n_gate = n_pre_gate(model); - - if ((pre->model = model) && model < PRE_MAX_MODEL) { - SIM_array_pre_clear_stat(pre); - - /* WHS: 10 should go to PARM */ - pre->e_charge = SIM_array_pre_cap( pre_size, 10 ) * n_gate * EnergyFactor; - - /* static power */ - pre->i_leakage = n_gate * pre_size * PMOS_TAB[0] / PARM_TECH_POINT * 100; - - return 0; - } - else - return -1; -} - - -int SIM_array_pre_record(power_arr_pre *pre, unsigned long int n_charge ) -{ - pre->n_charge += n_charge; - - return 0; -} - - -double SIM_array_pre_report(power_arr_pre *pre ) -{ - return ( pre->n_charge * pre->e_charge ); -} - -// ------- Precharge end - -/* ---------- buffer model end ------------ */ - - - - - - - - -/***** from SIM_array_internal_m.c *********/ - - -/* for now we simply initialize all fields to 0, which should not - * add too much error if the program runtime is long enough :) */ -int SIM_array_port_state_init(power_array_info *info, SIM_array_port_state_t *port ) -{ - //if ( IS_FULLY_ASSOC( info ) || !(info->share_rw)) - //bzero( port->data_line, port->data_line_size ); - - port->tag_line = 0; - port->row_addr = 0; - port->col_addr = 0; - port->tag_addr = 0; - - return 0; -} - - -int SIM_array_set_state_init( power_array_info *info, SIM_array_set_state_t *set ) -{ - set->entry = NULL; - set->entry_set = NULL; - - if ( IS_FULLY_ASSOC( info )) { - set->write_flag = 0; - set->write_back_flag = 0; - } - - /* no default value for other fields */ - return 0; -} - - -/* record row decoder and wordline activity */ -/* only used by non-fully-associative array, but we check it anyway */ -int SIM_power_array_dec( power_array_info *info, power_array *arr, SIM_array_port_state_t *port, unsigned long int row_addr, int rw ) -{ - if ( ! IS_FULLY_ASSOC( info )) { - /* record row decoder stats */ - if (info->row_dec_model) { - SIM_array_dec_record( &arr->row_dec, port->row_addr, row_addr ); - - /* update state */ - port->row_addr = row_addr; - } - - /* record wordline stats */ - SIM_array_wordline_record( &arr->data_wordline, rw, info->data_ndwl ); - if ( HAVE_TAG( info )) - SIM_array_wordline_record( &arr->tag_wordline, rw, info->tag_ndwl ); - - return 0; - } - else - return -1; -} - - -/* record read data activity (including bitline and sense amplifier) */ -/* only used by non-fully-associative array, but we check it anyway */ -/* data only used by RF array */ -int SIM_power_array_data_read( power_array_info *info, power_array *arr, unsigned long int data ) -{ - if (info->data_end == 1) { - SIM_array_bitline_record( &arr->data_bitline, SIM_ARRAY_READ, info->eff_data_cols, 0, data ); - - return 0; - } - else if ( ! IS_FULLY_ASSOC( info )) { - SIM_array_bitline_record( &arr->data_bitline, SIM_ARRAY_READ, info->eff_data_cols, 0, 0 ); - SIM_array_amp_record( &arr->data_amp, info->eff_data_cols ); - - return 0; - } - else - return -1; -} - - -/* record write data bitline and memory cell activity */ -/* assume no alignment restriction on write, so (char *) */ -/* set only used by fully-associative array */ -/* data_line only used by fully-associative or RF array */ -int SIM_power_array_data_write( power_array_info *info, power_array *arr, SIM_array_set_state_t *set, unsigned n_item, char *data_line, char *old_data, char *new_data ) -{ - unsigned i; - - /* record bitline stats */ - if ( IS_FULLY_ASSOC( info )) { - /* wordline should be driven only once */ - if ( ! set->write_flag ) { - SIM_array_wordline_record( &arr->data_wordline, SIM_ARRAY_WRITE, 1 ); - set->write_flag = 1; - } - - /* for fully-associative array, data bank has no read - * bitlines, so bitlines not written have no activity */ - for ( i = 0; i < n_item; i ++ ) { - SIM_array_bitline_record( &arr->data_bitline, SIM_ARRAY_WRITE, 8, data_line[i], new_data[i] ); - /* update state */ - data_line[i] = new_data[i]; - } - } - else if (info->share_rw) { - /* there is some subtlety here: write width may not be as wide as block size, - * bitlines not written are actually read, but column selector should be off, - * so read energy per bitline is the same as write energy per bitline */ - SIM_array_bitline_record( &arr->data_bitline, SIM_ARRAY_WRITE, info->eff_data_cols, 0, 0 ); - - /* write in all sub-arrays if direct-mapped, which implies 1 cycle write latency, - * in those sub-arrays wordlines are not driven, so only n items columns switch */ - if ( IS_DIRECT_MAP( info ) && info->data_ndbl > 1 ) - SIM_array_bitline_record( &arr->data_bitline, SIM_ARRAY_WRITE, n_item * 8 * ( info->data_ndbl - 1 ), 0, 0 ); - } - else { /* separate R/W bitlines */ - /* same arguments as in the previous case apply here, except that when we say - * read_energy = write_energy, we omit the energy of write driver gate cap */ - for ( i = 0; i < n_item; i ++ ) { - SIM_array_bitline_record( &arr->data_bitline, SIM_ARRAY_WRITE, 8, data_line[i], new_data[i] ); - /* update state */ - data_line[i] = new_data[i]; - } - } - - /* record memory cell stats */ - for ( i = 0; i < n_item; i ++ ) - SIM_array_mem_record( &arr->data_mem, old_data[i], new_data[i], 8 ); - - return 0; -} - - -/* record read tag activity (including bitline and sense amplifier) */ -/* only used by non-RF array */ -/* set only used by fully-associative array */ -int SIM_power_array_tag_read( power_array_info *info, power_array *arr, SIM_array_set_state_t *set ) -{ - if ( IS_FULLY_ASSOC( info )) { - /* the only reason to read a fully-associative array tag is writing back */ - SIM_array_wordline_record( &arr->tag_wordline, SIM_ARRAY_READ, 1 ); - set->write_back_flag = 1; - } - - SIM_array_bitline_record( &arr->tag_bitline, SIM_ARRAY_READ, info->eff_tag_cols, 0, 0 ); - SIM_array_amp_record( &arr->tag_amp, info->eff_tag_cols ); - - return 0; -} - - -/* record write tag bitline and memory cell activity */ -/* WHS: assume update of use bit, valid bit, dirty bit and tag will be coalesced */ -/* only used by non-RF array */ -/* port only used by fully-associative array */ -//int SIM_power_array_tag_update( power_array_info *info, power_array *arr, SIM_array_port_state_t *port, SIM_array_set_state_t *set ) -//{ - //unsigned i; - //unsigned long int curr_tag; - //power_mem *tag_attach_mem; - - /* get current tag */ - //if ( set->entry ) - //curr_tag = (*info->get_entry_tag)( set->entry ); - - // if ( IS_FULLY_ASSOC( info )) - // tag_attach_mem = &arr->tag_attach_mem; - //else - //tag_attach_mem = &arr->tag_mem; - - /* record tag bitline stats */ - //if ( IS_FULLY_ASSOC( info )) { - // if ( set->entry && curr_tag != set->tag_bak ) { - // /* shared wordline should be driven only once */ - // if ( ! set->write_back_flag ) - // SIM_array_wordline_record( &arr->tag_wordline, SIM_ARRAY_WRITE, 1 ); - - /* WHS: value of tag_line doesn't matter if not write_through */ - //SIM_array_bitline_record( &arr->tag_bitline, SIM_ARRAY_WRITE, info->eff_tag_cols, port->tag_line, curr_tag ); - /* update state */ - //if ( IS_WRITE_THROUGH( info )) - // port->tag_line = curr_tag; - //} - //} - //else { - /* tag update cannot occur at the 1st cycle, so no other sub-arrays */ - // SIM_array_bitline_record( &arr->tag_bitline, SIM_ARRAY_WRITE, info->eff_tag_cols, 0, 0 ); - //} - - /* record tag memory cell stats */ - //if ( HAVE_USE_BIT( info )) - // for ( i = 0; i < info->assoc; i ++ ) - // SIM_array_mem_record( tag_attach_mem, set->use_bak[i], (*info->get_set_use_bit)( set->entry_set, i ), info->use_bit_width ); - - //if ( set->entry ) { - // SIM_array_mem_record( tag_attach_mem, set->valid_bak, (*info->get_entry_valid_bit)( set->entry ), info->valid_bit_width ); - //SIM_array_mem_record( &arr->tag_mem, set->tag_bak, curr_tag, info->tag_addr_width ); - - //if ( IS_WRITE_BACK( info )) - // SIM_array_mem_record( tag_attach_mem, set->dirty_bak, (*info->get_entry_dirty_bit)( set->entry ), 1 ); - //} - - //return 0; -//} - - -/* record tag compare activity (including tag comparator, column decoder and multiplexor) */ -/* NOTE: this function may be called twice during ONE array operation, remember to update - * states at the end so that call to *_record won't add erroneous extra energy */ -/* only used by non-RF array */ -//int SIM_power_array_tag_compare( power_array_info *info, power_array *arr, SIM_array_port_state_t *port, unsigned long int tag_input, unsigned long int col_addr, SIM_array_set_state_t *set ) -//{ - //int miss = 0; - //unsigned i; - - /* record tag comparator stats */ - //for ( i = 0; i < info->assoc; i ++ ) { - /* WHS: sense amplifiers output 0 when idle */ - //if ( SIM_array_comp_local_record( &arr->comp, 0, (*info->get_set_tag)( set->entry_set, i ), tag_input, SIM_ARRAY_RECOVER )) - // miss = 1; - //} - - //SIM_array_comp_global_record( &arr->comp, port->tag_addr, tag_input, miss ); - - /* record column decoder stats */ - //if ( HAVE_COL_DEC( info )) - //SIM_array_dec_record( &arr->col_dec, port->col_addr, col_addr ); - - /* record multiplexor stats */ - //if ( HAVE_COL_MUX( info )) - //SIM_array_mux_record( &arr->mux, port->col_addr, col_addr, miss ); - - /* update state */ - //port->tag_addr = tag_input; - //if ( HAVE_COL_DEC( info )) - //port->col_addr = col_addr; - - //return 0; -//} - - -/* record output driver activity */ -/* assume alignment restriction on read, so specify data_size */ -/* WHS: it's really a mess to use data_size to specify data type */ -/* data_all only used by non-RF and non-fully-associative array */ -/* WHS: don't support 128-bit or wider integer */ -//int SIM_power_array_output( power_array_info *info, power_array *arr, unsigned data_size, unsigned length, void *data_out, void *data_all ) -//{ - // unsigned i, j; - - /* record output driver stats */ - //for ( i = 0; i < length; i ++ ) { - // switch ( data_size ) { - // case 1: SIM_array_outdrv_global_record( &arr->outdrv, ((unsigned8_t *)data_out)[i] ); - // break; - //case 2: SIM_array_outdrv_global_record( &arr->outdrv, ((unsigned16_t *)data_out)[i] ); - // break; - //case 4: SIM_array_outdrv_global_record( &arr->outdrv, ((unsigned32_t *)data_out)[i] ); - // break; - //case 8: SIM_array_outdrv_global_record( &arr->outdrv, ((unsigned64_t *)data_out)[i] ); - // break; - //default: /* some error handler */ - //} - //} - - //if ( ! IS_FULLY_ASSOC( info )) { - //for ( i = 0; i < info->assoc; i ++ ) - //for ( j = 0; j < info->n_item; j ++ ) - /* sense amplifiers output 0 when idle */ - //switch ( data_size ) { - //case 1: SIM_array_outdrv_local_record( &arr->outdrv, 0, ((unsigned8_t **)data_all)[i][j], SIM_ARRAY_RECOVER ); - //break; - //case 2: SIM_array_outdrv_local_record( &arr->outdrv, 0, ((unsigned16_t **)data_all)[i][j], SIM_ARRAY_RECOVER ); - //break; - //case 4: SIM_array_outdrv_local_record( &arr->outdrv, 0, ((unsigned32_t **)data_all)[i][j], SIM_ARRAY_RECOVER ); - //break; - //case 8: SIM_array_outdrv_local_record( &arr->outdrv, 0, ((unsigned64_t **)data_all)[i][j], SIM_ARRAY_RECOVER ); - //break; - //default: /* some error handler */ - //} - //} - - //return 0; -//} - - -/********* end from SIM_array_internal_m.c **********/ - - -// ------- Array init - - -int power_array_init(power_array_info *info, power_array *arr ) -{ - unsigned rows, cols, ports, dec_width, n_bitline_pre, n_colsel_pre; - double wordline_len, bitline_len, tagline_len, matchline_len; - double wordline_cmetal, bitline_cmetal; - double Cline, pre_size, comp_pre_size; - - arr->i_leakage = 0; - - /* sanity check */ - if ( info->read_ports == 0 ) info->share_rw = 0; - if ( info->share_rw ) { //AMIT are read and write ports shared? - info->data_end = 2; - info->tag_end = 2; - } - - if ( info->share_rw ) ports = info->read_ports; - else ports = info->read_ports + info->write_ports; - - /* data array unit length wire cap */ - if (ports > 1) { - /* 3x minimal spacing */ - wordline_cmetal = CC3M3metal; - bitline_cmetal = CC3M2metal; - } - else if (info->data_end == 2) { - /* wordline infinite spacing, bitline 3x minimal spacing */ - wordline_cmetal = CM3metal; - bitline_cmetal = CC3M2metal; - } - else { - /* both infinite spacing */ - wordline_cmetal = CM3metal; - bitline_cmetal = CM2metal; - } - - info->data_arr_width = 0; - info->tag_arr_width = 0; - info->data_arr_height = 0; - info->tag_arr_height = 0; - - /* BEGIN: data array power initialization */ - if (dec_width = SIM_power_logtwo(info->n_set)) { //AMIT: not fully associative, n->sets!=1 - /* row decoder power initialization */ - SIM_array_dec_init( &arr->row_dec, info->row_dec_model, dec_width ); - - /* row decoder precharging power initialization */ - //if ( is_dynamic_dec( info->row_dec_model )) - /* FIXME: need real pre_size */ - //SIM_array_pre_init( &arr->row_dec_pre, info->row_dec_pre_model, 0 ); - - rows = info->n_set / info->data_ndbl / info->data_nspd; //AMIT: n_set is the number of sets(fully associative n_sets=1) - cols = info->blk_bits * info->assoc * info->data_nspd / info->data_ndwl; //AMIT: blk_bits is the line size - - bitline_len = rows * ( RegCellHeight + ports * WordlineSpacing ); - if ( info->data_end == 2 ) - wordline_len = cols * ( RegCellWidth + 2 * ports * BitlineSpacing ); - else /* info->data_end == 1 */ - wordline_len = cols * ( RegCellWidth + ( 2 * ports - info->read_ports ) * BitlineSpacing ); - info->data_arr_width = wordline_len; - info->data_arr_height = bitline_len; - - /* compute precharging size */ - /* FIXME: should consider n_pre and pre_size simultaneously */ - Cline = rows * SIM_power_draincap( Wmemcellr, NCH, 1 ) + bitline_cmetal * bitline_len; - pre_size = SIM_power_driver_size( Cline, Period / 8 ); - /* WHS: ?? compensate for not having an nmos pre-charging */ - pre_size += pre_size * Wdecinvn / Wdecinvp; - - /* bitline power initialization */ - n_bitline_pre = n_pre_drain( info->data_bitline_pre_model ); - n_colsel_pre = ( info->data_n_share_amp > 1 ) ? n_pre_drain( info->data_colsel_pre_model ) : 0; - SIM_array_bitline_init(&arr->data_bitline, info->data_bitline_model, info->share_rw, info->data_end, rows, bitline_len * bitline_cmetal, info->data_n_share_amp, n_bitline_pre, n_colsel_pre, pre_size, info->outdrv_model); - /* static power */ - arr->i_leakage += arr->data_bitline.i_leakage * cols * info->write_ports; - - /* bitline precharging power initialization */ - SIM_array_pre_init( &arr->data_bitline_pre, info->data_bitline_pre_model, pre_size ); - /* static power */ - arr->i_leakage += arr->data_bitline_pre.i_leakage * cols * info->read_ports; - /* bitline column selector precharging power initialization */ - if ( info->data_n_share_amp > 1 ) - SIM_array_pre_init( &arr->data_colsel_pre, info->data_colsel_pre_model, pre_size ); - - /* sense amplifier power initialization */ - SIM_array_amp_init( &arr->data_amp, info->data_amp_model ); - } - else { - /* info->n_set == 1 means this array is fully-associative */ - rows = info->assoc; - cols = info->blk_bits; - - /* WHS: no read wordlines or bitlines */ - bitline_len = rows * ( RegCellHeight + info->write_ports * WordlineSpacing ); - wordline_len = cols * ( RegCellWidth + 2 * info->write_ports * BitlineSpacing ); - info->data_arr_width = wordline_len; - info->data_arr_height = bitline_len; - - /* bitline power initialization */ - SIM_array_bitline_init(&arr->data_bitline, info->data_bitline_model, 0, info->data_end, rows, bitline_len * bitline_cmetal, 1, 0, 0, 0, info->outdrv_model); - } - - /* wordline power initialization */ - SIM_array_wordline_init( &arr->data_wordline, info->data_wordline_model, info->share_rw, cols, wordline_len * wordline_cmetal, info->data_end ); - /* static power */ - arr->i_leakage += arr->data_wordline.i_leakage * rows * ports; - - if (dec_width = SIM_power_logtwo(info->n_item)) { - /* multiplexor power initialization */ - SIM_array_mux_init( &arr->mux, info->mux_model, info->n_item, info->assoc ); - - /* column decoder power initialization */ - SIM_array_dec_init( &arr->col_dec, info->col_dec_model, dec_width ); - - /* column decoder precharging power initialization */ - //if ( is_dynamic_dec( info->col_dec_model )) - /* FIXME: need real pre_size */ - //SIM_array_pre_init( &arr->col_dec_pre, info->col_dec_pre_model, 0 ); - } - - /* memory cell power initialization */ - SIM_array_mem_init( &arr->data_mem, info->data_mem_model, info->read_ports, info->write_ports, info->share_rw, info->data_end ); - /* static power */ - arr->i_leakage += arr->data_mem.i_leakage * rows * cols; - - /* output driver power initialization */ - SIM_array_outdrv_init( &arr->outdrv, info->outdrv_model, info->data_width ); - /* END: data array power initialization */ - - - /* BEGIN: tag array power initialization */ - /* assume a tag array must have memory cells */ - if ( info->tag_mem_model ) { - if ( info->n_set > 1 ) { - /* tag array unit length wire cap */ - if (ports > 1) { - /* 3x minimal spacing */ - wordline_cmetal = CC3M3metal; - bitline_cmetal = CC3M2metal; - } - else if (info->data_end == 2) { - /* wordline infinite spacing, bitline 3x minimal spacing */ - wordline_cmetal = CM3metal; - bitline_cmetal = CC3M2metal; - } - else { - /* both infinite spacing */ - wordline_cmetal = CM3metal; - bitline_cmetal = CM2metal; - } - - rows = info->n_set / info->tag_ndbl / info->tag_nspd; - cols = info->tag_line_width * info->assoc * info->tag_nspd / info->tag_ndwl; - - bitline_len = rows * ( RegCellHeight + ports * WordlineSpacing ); - if ( info->tag_end == 2 ) - wordline_len = cols * ( RegCellWidth + 2 * ports * BitlineSpacing ); - else /* info->tag_end == 1 */ - wordline_len = cols * ( RegCellWidth + ( 2 * ports - info->read_ports ) * BitlineSpacing ); - info->tag_arr_width = wordline_len; - info->tag_arr_height = bitline_len; - - /* compute precharging size */ - /* FIXME: should consider n_pre and pre_size simultaneously */ - Cline = rows * SIM_power_draincap( Wmemcellr, NCH, 1 ) + bitline_cmetal * bitline_len; - pre_size = SIM_power_driver_size( Cline, Period / 8 ); - /* WHS: ?? compensate for not having an nmos pre-charging */ - pre_size += pre_size * Wdecinvn / Wdecinvp; - - /* bitline power initialization */ - n_bitline_pre = n_pre_drain( info->tag_bitline_pre_model ); - n_colsel_pre = ( info->tag_n_share_amp > 1 ) ? n_pre_drain( info->tag_colsel_pre_model ) : 0; - SIM_array_bitline_init(&arr->tag_bitline, info->tag_bitline_model, info->share_rw, info->tag_end, rows, bitline_len * bitline_cmetal, info->tag_n_share_amp, n_bitline_pre, n_colsel_pre, pre_size, SIM_NO_MODEL); - - /* bitline precharging power initialization */ - SIM_array_pre_init( &arr->tag_bitline_pre, info->tag_bitline_pre_model, pre_size ); - /* bitline column selector precharging power initialization */ - if ( info->tag_n_share_amp > 1 ) - SIM_array_pre_init( &arr->tag_colsel_pre, info->tag_colsel_pre_model, pre_size ); - - /* sense amplifier power initialization */ - SIM_array_amp_init( &arr->tag_amp, info->tag_amp_model ); - - /* prepare for comparator initialization */ - tagline_len = matchline_len = 0; - comp_pre_size = Wcomppreequ; - } - else { /* info->n_set == 1 */ - /* cam cells are big enough, so infinite spacing */ - wordline_cmetal = CM3metal; - bitline_cmetal = CM2metal; - - rows = info->assoc; - /* FIXME: operations of valid bit, use bit and dirty bit are not modeled */ - cols = info->tag_addr_width; - - bitline_len = rows * ( CamCellHeight + ports * WordlineSpacing + info->read_ports * MatchlineSpacing ); - if ( info->tag_end == 2 ) - wordline_len = cols * ( CamCellWidth + 2 * ports * BitlineSpacing + 2 * info->read_ports * TaglineSpacing ); - else /* info->tag_end == 1 */ - wordline_len = cols * ( CamCellWidth + ( 2 * ports - info->read_ports ) * BitlineSpacing + 2 * info->read_ports * TaglineSpacing ); - info->tag_arr_width = wordline_len; - info->tag_arr_height = bitline_len; - - if ( is_rw_bitline ( info->tag_bitline_model )) { - /* compute precharging size */ - /* FIXME: should consider n_pre and pre_size simultaneously */ - Cline = rows * SIM_power_draincap( Wmemcellr, NCH, 1 ) + bitline_cmetal * bitline_len; - pre_size = SIM_power_driver_size( Cline, Period / 8 ); - /* WHS: ?? compensate for not having an nmos pre-charging */ - pre_size += pre_size * Wdecinvn / Wdecinvp; - - /* bitline power initialization */ - n_bitline_pre = n_pre_drain( info->tag_bitline_pre_model ); - SIM_array_bitline_init(&arr->tag_bitline, info->tag_bitline_model, info->share_rw, info->tag_end, rows, bitline_len * bitline_cmetal, 1, n_bitline_pre, 0, pre_size, SIM_NO_MODEL); - - /* bitline precharging power initialization */ - SIM_array_pre_init( &arr->tag_bitline_pre, info->tag_bitline_pre_model, pre_size ); - - /* sense amplifier power initialization */ - SIM_array_amp_init( &arr->tag_amp, info->tag_amp_model ); - } - else { - /* bitline power initialization */ - SIM_array_bitline_init(&arr->tag_bitline, info->tag_bitline_model, 0, info->tag_end, rows, bitline_len * bitline_cmetal, 1, 0, 0, 0, SIM_NO_MODEL); - } - - /* memory cell power initialization */ - SIM_array_mem_init( &arr->tag_attach_mem, info->tag_attach_mem_model, info->read_ports, info->write_ports, info->share_rw, info->tag_end ); - - /* prepare for comparator initialization */ - tagline_len = bitline_len; - matchline_len = wordline_len; - comp_pre_size = Wmatchpchg; - } - - /* wordline power initialization */ - SIM_array_wordline_init( &arr->tag_wordline, info->tag_wordline_model, info->share_rw, cols, wordline_len * wordline_cmetal, info->tag_end ); - - /* comparator power initialization */ - SIM_array_comp_init( &arr->comp, info->comp_model, info->tag_addr_width, info->assoc, n_pre_drain( info->comp_pre_model ), matchline_len, tagline_len ); - - /* comparator precharging power initialization */ - SIM_array_pre_init( &arr->comp_pre, info->comp_pre_model, comp_pre_size ); - - /* memory cell power initialization */ - SIM_array_mem_init( &arr->tag_mem, info->tag_mem_model, info->read_ports, info->write_ports, info->share_rw, info->tag_end ); - } - /* END: tag array power initialization */ - - return 0; -} - -double array_report(power_array_info *info, power_array *arr) -{ - double epart, etotal = 0; - - if (info->row_dec_model) { - epart = SIM_array_dec_report(&arr->row_dec); - //fprintf(stderr, "row decoder: %g\n", epart); - etotal += epart; - } - if (info->col_dec_model) { - epart = SIM_array_dec_report(&arr->col_dec); - //fprintf(stderr, "col decoder: %g\n", epart); - etotal += epart; - } - if (info->data_wordline_model) { - epart = SIM_array_wordline_report(&arr->data_wordline); - //fprintf(stderr, "data wordline: %g\n", epart); - etotal += epart; - } - if (info->tag_wordline_model) { - epart = SIM_array_wordline_report(&arr->tag_wordline); - //fprintf(stderr, "tag wordline: %g\n", epart); - etotal += epart; - } - if (info->data_bitline_model) { - epart = SIM_array_bitline_report(&arr->data_bitline); - //fprintf(stderr, "data bitline: %g\n", epart); - etotal += epart; - } - if (info->data_bitline_pre_model) { - epart = SIM_array_pre_report(&arr->data_bitline_pre); - //fprintf(stderr, "data bitline precharge: %g\n", epart); - etotal += epart; - } - if (info->tag_bitline_model) { - epart = SIM_array_bitline_report(&arr->tag_bitline); - //fprintf(stderr, "tag bitline: %g\n", epart); - etotal += epart; - } - if (info->data_mem_model) { - epart = SIM_array_mem_report(&arr->data_mem); - //fprintf(stderr, "data memory: %g\n", epart); - etotal += epart; - } - if (info->tag_mem_model) { - epart = SIM_array_mem_report(&arr->tag_mem); - //fprintf(stderr, "tag memory: %g\n", epart); - etotal += epart; - } - if (info->data_amp_model) { - epart = SIM_array_amp_report(&arr->data_amp); - //fprintf(stderr, "data amp: %g\n", epart); - etotal += epart; - } - if (info->tag_amp_model) { - epart = SIM_array_amp_report(&arr->tag_amp); - //fprintf(stderr, "tag amp: %g\n", epart); - etotal += epart; - } - if (info->comp_model) { - epart = SIM_array_comp_report(&arr->comp); - //fprintf(stderr, "comparator: %g\n", epart); - etotal += epart; - } - if (info->mux_model) { - epart = SIM_array_mux_report(&arr->mux); - //fprintf(stderr, "multiplexor: %g\n", epart); - etotal += epart; - } - if (info->outdrv_model) { - epart = SIM_array_outdrv_report(&arr->outdrv); - //fprintf(stderr, "output driver: %g\n", epart); - etotal += epart; - } - /* ignore other precharging for now */ - - //fprintf(stderr, "total energy: %g\n", etotal); - - return etotal; -} - -/* ==================== buffer (wrapper/record functions) ==================== */ - -/* record read data activity */ -int SIM_buf_power_data_read(power_array_info *info, power_array *arr, unsigned long int data) -{ - /* precharge */ - SIM_array_pre_record(&arr->data_bitline_pre, info->blk_bits); - /* drive the wordline */ - SIM_power_array_dec(info, arr, NULL, 0, SIM_ARRAY_READ); - /* read data */ - SIM_power_array_data_read(info, arr, data); - - return 0; -} - - -/* record write data bitline and memory cell activity */ -int SIM_buf_power_data_write(power_array_info *info, power_array *arr, char *data_line, char *old_data, char *new_data) -{ -#define N_ITEM (PARM_flit_width / 8 + (PARM_flit_width % 8 ? 1:0)) - /* drive the wordline */ - SIM_power_array_dec(info, arr, NULL, 0, SIM_ARRAY_WRITE); - /* write data */ - SIM_power_array_data_write(info, arr, NULL, N_ITEM, data_line, old_data, new_data); - - return 0; -} - -/* WHS: missing data output wrapper function */ - -/* ==================== buffer (wrapper/record functions) end ==================== */ - - - - - -int SIM_array_clear_stat(power_array *arr) -{ - SIM_array_dec_clear_stat(&arr->row_dec); - SIM_array_dec_clear_stat(&arr->col_dec); - SIM_array_wordline_clear_stat(&arr->data_wordline); - SIM_array_wordline_clear_stat(&arr->tag_wordline); - SIM_array_bitline_clear_stat(&arr->data_bitline); - SIM_array_bitline_clear_stat(&arr->tag_bitline); - SIM_array_mem_clear_stat(&arr->data_mem); - SIM_array_mem_clear_stat(&arr->tag_mem); - SIM_array_mem_clear_stat(&arr->tag_attach_mem); - SIM_array_amp_clear_stat(&arr->data_amp); - SIM_array_amp_clear_stat(&arr->tag_amp); - SIM_array_comp_clear_stat(&arr->comp); - SIM_array_mux_clear_stat(&arr->mux); - SIM_array_outdrv_clear_stat(&arr->outdrv); - SIM_array_pre_clear_stat(&arr->row_dec_pre); - SIM_array_pre_clear_stat(&arr->col_dec_pre); - SIM_array_pre_clear_stat(&arr->data_bitline_pre); - SIM_array_pre_clear_stat(&arr->tag_bitline_pre); - SIM_array_pre_clear_stat(&arr->data_colsel_pre); - SIM_array_pre_clear_stat(&arr->tag_colsel_pre); - SIM_array_pre_clear_stat(&arr->comp_pre); - - return 0; -} - - - - - diff --git a/src/mem/ruby/network/orion/power_array.hh b/src/mem/ruby/network/orion/power_array.hh deleted file mode 100644 index dbd2733c9..000000000 --- a/src/mem/ruby/network/orion/power_array.hh +++ /dev/null @@ -1,394 +0,0 @@ -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _POWER_ARRAY_H -#define _POWER_ARRAY_H - - -#define SIM_ARRAY_NO_MODEL 0 -#define SIM_ARRAY_READ 0 -#define SIM_ARRAY_WRITE 1 - -#define SIM_ARRAY_RECOVER 1 - -/* read/write */ -#define SIM_ARRAY_RW 0 -/* only write */ -#define SIM_ARRAY_WO 1 - -typedef enum { - GENERIC_DEC =1, - DEC_MAX_MODEL -} power_dec_model; - -typedef enum { - GENERIC_MUX =1, - MUX_MAX_MODEL -} power_mux_model; - -typedef enum { - GENERIC_AMP =1, - AMP_MAX_MODEL -} power_amp_model; - -typedef enum { - CACHE_RW_WORDLINE =1, - CACHE_WO_WORDLINE, - CAM_RW_WORDLINE, - CAM_WO_WORDLINE, - WORDLINE_MAX_MODEL -} power_wordline_model; - -typedef enum { - RW_BITLINE =1, - WO_BITLINE, - BITLINE_MAX_MODEL -} power_bitline_model; - -typedef enum { - SINGLE_BITLINE =1, - EQU_BITLINE, - SINGLE_OTHER, - PRE_MAX_MODEL -} power_pre_model; - -typedef enum { - NORMAL_MEM =1, - CAM_TAG_RW_MEM, - CAM_TAG_WO_MEM, - CAM_DATA_MEM, - CAM_ATTACH_MEM, - MEM_MAX_MODEL -} power_mem_model; - -typedef enum { - CACHE_COMPONENT =1, - CAM_COMP, - COMP_MAX_MODEL -} power_comp_model; - -typedef enum { - CACHE_OUTDRV =1, - CAM_OUTDRV, - REG_OUTDRV, - OUTDRV_MAX_MODEL -} power_outdrv_model; - - - -typedef struct { - int model; - unsigned n_bits; - unsigned long int n_chg_output; - unsigned long int n_chg_addr; - unsigned long int n_chg_l1; - double e_chg_output; - double e_chg_addr; - double e_chg_l1; - unsigned n_in_1st; - unsigned n_in_2nd; - unsigned n_out_0th; - unsigned n_out_1st; - unsigned long int addr_mask; -} power_decoder; - -typedef struct { - int model; - int share_rw; - unsigned long int n_read; - unsigned long int n_write; - double e_read; - double e_write; - double i_leakage; -} power_wordline; - -typedef struct { - int model; - int share_rw; - unsigned end; - unsigned long int n_col_write; - unsigned long int n_col_read; - unsigned long int n_col_sel; - double e_col_write; - double e_col_read; - double e_col_sel; - double i_leakage; -} power_bitline; - -typedef struct { - int model; - unsigned long int n_access; - double e_access; -} power_amp; - -typedef struct { - int model; - unsigned n_bits; - unsigned assoc; - unsigned long int n_access; - unsigned long int n_match; - unsigned long int n_mismatch; - unsigned long int n_miss; - unsigned long int n_bit_match; - unsigned long int n_bit_mismatch; - unsigned long int n_chg_addr; - double e_access; - double e_match; - double e_mismatch; - double e_miss; - double e_bit_match; - double e_bit_mismatch; - double e_chg_addr; - unsigned long int comp_mask; -} power_comp; - -typedef struct { - int model; - unsigned end; - unsigned long int n_switch; - double e_switch; - double i_leakage; -} power_mem; - -typedef struct { - int model; - unsigned assoc; - unsigned long int n_mismatch; - unsigned long int n_chg_addr; - double e_mismatch; - double e_chg_addr; -} power_mux; - -typedef struct { - int model; - unsigned item_width; - unsigned long int n_select; - unsigned long int n_chg_data; - unsigned long int n_out_1; - unsigned long int n_out_0; - double e_select; - double e_chg_data; - double e_out_1; - double e_out_0; - unsigned long int out_mask; -} power_out; - -typedef struct { - int model; - unsigned long int n_charge; - double e_charge; - double i_leakage; -} power_arr_pre; - - -/*@ - * data type: array port state - * - * - row_addr -- input to row decoder - * col_addr -- input to column decoder, if any - * tag_addr -- input to tag comparator - * $+ tag_line -- value of tag bitline - * # data_line_size -- size of data_line in char - * # data_line -- value of data bitline - * - * legend: - * -: only used by non-fully-associative array - * +: only used by fully-associative array - * #: only used by fully-associative array or RF array - * $: only used by write-through array - * - * NOTE: - * (1) *_addr may not necessarily be an address - * (2) data_line_size is the allocated size of data_line in simulator, - * which must be no less than the physical size of data line - * (3) each instance of module should define an instance-specific data - * type with non-zero-length data_line and cast it to this type - */ -typedef struct { - unsigned long int row_addr; - unsigned long int col_addr; - unsigned long int tag_addr; - unsigned long int tag_line; - unsigned data_line_size; - char data_line[0]; -} SIM_array_port_state_t; - -/*@ - * data type: array set state - * - * entry -- pointer to some entry structure if an entry is selected for - * r/w, NULL otherwise - * entry_set -- pointer to corresponding set structure - * + write_flag -- 1 if entry is already written once, 0 otherwise - * + write_back_flag -- 1 if entry is already written back, 0 otherwise - * valid_bak -- valid bit of selected entry before operation - * dirty_bak -- dirty bit of selected entry, if any, before operation - * tag_bak -- tag of selected entry before operation - * use_bak -- use bits of all entries before operation - * - * legend: - * +: only used by fully-associative array - * - * NOTE: - * (1) entry is interpreted by modules, if some module has no "entry structure", - * then make sure this field is non-zero if some entry is selected - * (2) tag_addr may not necessarily be an address - * (3) each instance of module should define an instance-specific data - * type with non-zero-length use_bit and cast it to this type - */ -typedef struct { - void *entry; - void *entry_set; - int write_flag; - int write_back_flag; - unsigned valid_bak; - unsigned dirty_bak; - unsigned long int tag_bak; - unsigned use_bak[0]; -} SIM_array_set_state_t; - - - - - -// Array - -typedef struct { - power_decoder row_dec; - power_decoder col_dec; - power_wordline data_wordline; - power_wordline tag_wordline; - power_bitline data_bitline; - power_bitline tag_bitline; - power_mem data_mem; - power_mem tag_mem; - power_mem tag_attach_mem; - power_amp data_amp; - power_amp tag_amp; - power_comp comp; - power_mux mux; - power_out outdrv; - power_arr_pre row_dec_pre; - power_arr_pre col_dec_pre; - power_arr_pre data_bitline_pre; - power_arr_pre tag_bitline_pre; - power_arr_pre data_colsel_pre; - power_arr_pre tag_colsel_pre; - power_arr_pre comp_pre; - double i_leakage; -} power_array; - -typedef struct { - //common for data and tag array - int share_rw; - unsigned read_ports; - unsigned write_ports; - unsigned n_set; - unsigned blk_bits; - unsigned assoc; - int row_dec_model; - //for data array - unsigned data_width; - int col_dec_model; - int mux_model; - int outdrv_model; - //for tag array - unsigned tag_addr_width; - unsigned tag_line_width; - int comp_model; - //data common - unsigned data_ndwl; - unsigned data_ndbl; - unsigned data_nspd; - unsigned data_n_share_amp; - unsigned data_end; - int data_wordline_model; - int data_bitline_model; - int data_amp_model; - int data_mem_model; - //tag common - unsigned tag_ndwl; - unsigned tag_ndbl; - unsigned tag_nspd; - unsigned tag_n_share_amp; - unsigned tag_end; - unsigned tag_wordline_model; - unsigned tag_bitline_model; - unsigned tag_amp_model; - unsigned tag_mem_model; - unsigned tag_attach_mem_model; - //precharging parameters - int row_dec_pre_model; - int col_dec_pre_model; - int data_bitline_pre_model; - int tag_bitline_pre_model; - int data_colsel_pre_model; - int tag_colsel_pre_model; - int comp_pre_model; - //derived - unsigned n_item; - unsigned eff_data_cols; - unsigned eff_tag_cols; - //flags used by prototype array model - unsigned use_bit_width; - unsigned valid_bit_width; - int write_policy; - //fields filled up during initialization - double data_arr_width; - double tag_arr_width; - double data_arr_height; - double tag_arr_height; -} power_array_info; - - -extern int power_array_init(power_array_info *info, power_array *arr ); - -extern double array_report(power_array_info *info, power_array *arr); - -extern int SIM_buf_power_data_read(power_array_info *info, power_array *arr, unsigned long int data); - -extern int SIM_buf_power_data_write(power_array_info *info, power_array *arr, char *data_line, char *old_data, char *new_data); - -extern int SIM_array_clear_stat(power_array *arr); - -extern int SIM_power_array_dec( power_array_info *info, power_array *arr, SIM_array_port_state_t *port, unsigned long int row_addr, int rw ); -extern int SIM_power_array_data_read( power_array_info *info, power_array *arr, unsigned long int data ); -extern int SIM_power_array_data_write( power_array_info *info, power_array *arr, SIM_array_set_state_t *set, unsigned n_item, char *data_line, char *old_data, char *new_data ); -extern int power_array_tag_read( power_array_info *info, power_array *arr, SIM_array_set_state_t *set ); -extern int power_array_tag_update( power_array_info *info, power_array *arr, SIM_array_port_state_t *port, SIM_array_set_state_t *set ); -extern int power_array_tag_compare( power_array_info *info, power_array *arr, SIM_array_port_state_t *port, unsigned long int tag_input, unsigned long int col_addr, SIM_array_set_state_t *set ); -extern int SIM_power_array_output( power_array_info *info, power_array *arr, unsigned data_size, unsigned length, void *data_out, void *data_all ); - -extern int SIM_array_port_state_init( power_array_info *info, SIM_array_port_state_t *port ); -extern int SIM_array_set_state_init( power_array_info *info, SIM_array_set_state_t *set ); - -#endif - - - - diff --git a/src/mem/ruby/network/orion/power_bus.cc b/src/mem/ruby/network/orion/power_bus.cc deleted file mode 100644 index 7060752a5..000000000 --- a/src/mem/ruby/network/orion/power_bus.cc +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> - -#include "mem/ruby/network/orion/power_bus.hh" -#include "mem/ruby/network/orion/power_ll.hh" -#include "mem/ruby/network/orion/parm_technology.hh" -#include "mem/ruby/network/orion/SIM_port.hh" -#include "mem/ruby/network/orion/power_static.hh" -#include "mem/ruby/network/orion/power_utils.hh" - -/* ------- bus(link) model ---------- */ - -static int SIM_bus_bitwidth(int encoding, unsigned data_width, unsigned grp_width) -{ - if (encoding && encoding < BUS_MAX_ENC) - switch (encoding) { - case IDENT_ENC: - case TRANS_ENC: return data_width; - case BUSINV_ENC: return data_width + data_width / grp_width + (data_width % grp_width ? 1:0); - default: return 0;/* some error handler */ - } - else - return -1; -} - - -/* - * this function is provided to upper layers to compute the exact binary bus representation - * only correct when grp_width divides data_width - */ -unsigned long int SIM_bus_state(power_bus *bus, unsigned long int old_data, unsigned long int old_state, unsigned long int new_data) -{ - unsigned long int mask_bus, mask_data; - unsigned long int new_state = 0; - unsigned done_width = 0; - - switch (bus->encoding) { - case IDENT_ENC: return new_data; - case TRANS_ENC: return new_data ^ old_data; - - case BUSINV_ENC: - /* FIXME: this function should be re-written for boundary checking */ - mask_data = (BIGONE << bus->grp_width) - 1; - mask_bus = (mask_data << 1) + 1; - - while (bus->data_width > done_width) { - if (SIM_power_Hamming(old_state & mask_bus, new_data & mask_data, mask_bus) > bus->grp_width / 2) - new_state += (~(new_data & mask_data) & mask_bus) << done_width + done_width / bus->grp_width; - else - new_state += (new_data & mask_data) << done_width + done_width / bus->grp_width; - - done_width += bus->grp_width; - old_state >>= bus->grp_width + 1; - new_data >>= bus->grp_width; - } - - return new_state; - - default: return 0;/* some error handler */ - } -} - - -static double SIM_resultbus_cap(void) -{ - double Cline, reg_height; - - /* compute size of result bus tags */ - reg_height = PARM_RUU_size * (RegCellHeight + WordlineSpacing * 3 * PARM_ruu_issue_width); - - /* assume num alu's = ialu */ - /* FIXME: generate a more detailed result bus network model */ - /* WHS: 3200 should go to PARM */ - /* WHS: use minimal pitch for buses */ - Cline = CCmetal * (reg_height + 0.5 * PARM_res_ialu * 3200 * LSCALE); - - /* or use result bus length measured from 21264 die photo */ - // Cline = CCmetal * 3.3 * 1000; - - return Cline; -} - - -static double SIM_generic_bus_cap(unsigned n_snd, unsigned n_rcv, double length, double time) -{ - double Ctotal = 0; - double n_size, p_size; - - /* part 1: wire cap */ - /* WHS: use minimal pitch for buses */ - Ctotal += CC2metal * length; - - if ((n_snd == 1) && (n_rcv == 1)) { - /* directed bus if only one sender and one receiver */ - - /* part 2: repeater cap */ - /* FIXME: ratio taken from Raw, does not scale now */ - n_size = Lamda * 10; - p_size = n_size * 2; - - Ctotal += SIM_power_gatecap(n_size + p_size, 0) + SIM_power_draincap(n_size, NCH, 1) + SIM_power_draincap(p_size, PCH, 1); - - n_size *= 2.5; - p_size *= 2.5; - - Ctotal += SIM_power_gatecap(n_size + p_size, 0) + SIM_power_draincap(n_size, NCH, 1) + SIM_power_draincap(p_size, PCH, 1); - } - else { - /* otherwise, broadcasting bus */ - - /* part 2: input cap */ - /* WHS: no idea how input interface is, use an inverter for now */ - Ctotal += n_rcv * SIM_power_gatecap(Wdecinvn + Wdecinvp, 0); - - /* part 3: output driver cap */ - if (time) { - p_size = SIM_power_driver_size(Ctotal, time); - n_size = p_size / 2; - } - else { - p_size = Wbusdrvp; - n_size = Wbusdrvn; - } - - Ctotal += n_snd * (SIM_power_draincap(Wdecinvn, NCH, 1) + SIM_power_draincap(Wdecinvp, PCH, 1)); - } - - return Ctotal; -} - - -/* - * n_snd -> # of senders - * n_rcv -> # of receivers - * time -> rise and fall time, 0 means using default transistor sizes - * grp_width only matters for BUSINV_ENC - */ -int power_bus_init(power_bus *bus, int model, int encoding, unsigned width, unsigned grp_width, unsigned n_snd, unsigned n_rcv, double length, double time) -{ - if ((bus->model = model) && model < BUS_MAX_MODEL) { - bus->data_width = width; - bus->grp_width = grp_width; - bus->n_switch = 0; - - switch (model) { - case RESULT_BUS: - /* assume result bus uses identity encoding */ - bus->encoding = IDENT_ENC; - bus->e_switch = SIM_resultbus_cap() / 2 * EnergyFactor; - break; - - case GENERIC_BUS: - if ((bus->encoding = encoding) && encoding < BUS_MAX_ENC) { - bus->e_switch = SIM_generic_bus_cap(n_snd, n_rcv, length, time) / 2 * EnergyFactor; - /* sanity check */ - if (!grp_width || grp_width > width) - bus->grp_width = width; - } - else return -1; - - default: break;/* some error handler */ - } - - bus->bit_width = SIM_bus_bitwidth(bus->encoding, width, bus->grp_width); - bus->bus_mask = HAMM_MASK(bus->bit_width); - - return 0; - } - else - return -1; -} - - -int bus_record(power_bus *bus, unsigned long int old_state, unsigned long int new_state) -{ - bus->n_switch += SIM_power_Hamming(new_state, old_state, bus->bus_mask); - return 0; -} - - -double bus_report(power_bus *bus) -{ - return (bus->n_switch * bus->e_switch); -} - -/* ------- bus(link) model ---------- */ - - diff --git a/src/mem/ruby/network/orion/power_crossbar.cc b/src/mem/ruby/network/orion/power_crossbar.cc deleted file mode 100644 index a9f3e2e39..000000000 --- a/src/mem/ruby/network/orion/power_crossbar.cc +++ /dev/null @@ -1,365 +0,0 @@ -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> -#include <math.h> - -#include "mem/ruby/network/orion/power_ll.hh" -#include "mem/ruby/network/orion/power_crossbar.hh" -#include "mem/ruby/network/orion/parm_technology.hh" -#include "mem/ruby/network/orion/SIM_port.hh" -#include "mem/ruby/network/orion/power_static.hh" -#include "mem/ruby/network/orion/power_utils.hh" - -/*-------------------- CROSSBAR power model -------------------*/ - -static double crossbar_in_cap(double wire_cap, unsigned n_out, int connect_type, int trans_type, double *Nsize) -{ - double Ctotal = 0, Ctrans = 0, psize, nsize, Cdriver = 0; - - /* part 1: wire cap */ - Ctotal += wire_cap; - //printf("CROSSBAR_INTERNAL: input wire cap = %g\n", wire_cap); - - /* part 2: drain cap of transmission gate or gate cap of tri-state gate */ - if (connect_type == TRANS_GATE) { - /* FIXME: resizing strategy */ - nsize = Nsize ? *Nsize : Wmemcellr; - psize = nsize * Wdecinvp / Wdecinvn; - Ctrans = SIM_power_draincap(nsize, NCH, 1); - if (trans_type == NP_GATE) - Ctrans += SIM_power_draincap(psize, PCH, 1); - } - else if (connect_type == TRISTATE_GATE) { - Ctrans = SIM_power_gatecap(Woutdrvnandn + Woutdrvnandp, 0) + - SIM_power_gatecap(Woutdrvnorn + Woutdrvnorp, 0); - } - else {/* some error handler */} - - //printf("CROSSBAR_INTERNAL: input connector cap = %g\n", (n_out * Ctrans)); - Ctotal += n_out * Ctrans; - - /* part 3: input driver */ - /* FIXME: how to specify timing? */ - psize = SIM_power_driver_size(Ctotal, Period / 3); - nsize = psize * Wdecinvn / Wdecinvp; - Cdriver = SIM_power_draincap(nsize, NCH, 1) + SIM_power_draincap(psize, PCH, 1) + - SIM_power_gatecap(nsize + psize, 0); - - //printf("CROSSBAR_INTERNAL: input driver cap = %g\n", Cdriver); - - Ctotal += Cdriver; - - return Ctotal / 2; -} - - -static double crossbar_out_cap(double length, unsigned n_in, int connect_type, int trans_type, double *Nsize) -{ - double Ctotal = 0, Cwire = 0, Ctrans = 0, Cdriver = 0, psize, nsize; - - /* part 1: wire cap */ - Cwire += CC3metal * length; - //printf("CROSSBAR_INTERNAL: output wire cap = %g\n", Cwire); - - Ctotal += Cwire; - - /* part 2: drain cap of transmission gate or tri-state gate */ - if (connect_type == TRANS_GATE) { - /* FIXME: resizing strategy */ - if (Nsize) { - /* FIXME: how to specify timing? */ - psize = SIM_power_driver_size(Ctotal, Period / 3); - *Nsize = nsize = psize * Wdecinvn / Wdecinvp; - } - else { - nsize = Wmemcellr; - psize = nsize * Wdecinvp / Wdecinvn; - } - Ctrans = SIM_power_draincap(nsize, NCH, 1); - if (trans_type == NP_GATE) - Ctrans += SIM_power_draincap(psize, PCH, 1); - } - else if (connect_type == TRISTATE_GATE) { - Ctrans = SIM_power_draincap(Woutdrivern, NCH, 1) + SIM_power_draincap(Woutdriverp, PCH, 1); - } - else {/* some error handler */} - - //printf("CROSSBAR_INTERNAL: output connector cap = %g\n", (n_in * Ctrans)); - Ctotal += n_in * Ctrans; - - /* part 3: output driver */ - Cdriver += SIM_power_draincap(Woutdrivern, NCH, 1) + SIM_power_draincap(Woutdriverp, PCH, 1) + - SIM_power_gatecap(Woutdrivern + Woutdriverp, 0); - - //printf("CROSSBAR_INTERNAL: output driver cap = %g\n", Cdriver); - - Ctotal += Cdriver; - - return Ctotal / 2; -} - - -/* cut-through crossbar only supports 4x4 now */ -static double crossbar_io_cap(double length) -{ - double Ctotal = 0, psize, nsize; - - /* part 1: wire cap */ - Ctotal += CC3metal * length; - - /* part 2: gate cap of tri-state gate */ - Ctotal += 2 * (SIM_power_gatecap(Woutdrvnandn + Woutdrvnandp, 0) + - SIM_power_gatecap(Woutdrvnorn + Woutdrvnorp, 0)); - - /* part 3: drain cap of tri-state gate */ - Ctotal += 2 * (SIM_power_draincap(Woutdrivern, NCH, 1) + SIM_power_draincap(Woutdriverp, PCH, 1)); - - /* part 4: input driver */ - /* FIXME: how to specify timing? */ - psize = SIM_power_driver_size(Ctotal, Period * 0.8); - nsize = psize * Wdecinvn / Wdecinvp; - Ctotal += SIM_power_draincap(nsize, NCH, 1) + SIM_power_draincap(psize, PCH, 1) + - SIM_power_gatecap(nsize + psize, 0); - - /* part 5: output driver */ - Ctotal += SIM_power_draincap(Woutdrivern, NCH, 1) + SIM_power_draincap(Woutdriverp, PCH, 1) + - SIM_power_gatecap(Woutdrivern + Woutdriverp, 0); - - /* HACK HACK HACK */ - /* this HACK is to count a 1:4 mux and a 4:1 mux, so we have a 5x5 crossbar */ - return Ctotal / 2 * 1.32; -} - - -static double crossbar_int_cap(unsigned degree, int connect_type, int trans_type) -{ - double Ctotal = 0, Ctrans; - - if (connect_type == TRANS_GATE) { - /* part 1: drain cap of transmission gate */ - /* FIXME: Wmemcellr and resize */ - Ctrans = SIM_power_draincap(Wmemcellr, NCH, 1); - if (trans_type == NP_GATE) - Ctrans += SIM_power_draincap(Wmemcellr * Wdecinvp / Wdecinvn, PCH, 1); - Ctotal += (degree + 1) * Ctrans; - } - else if (connect_type == TRISTATE_GATE) { - /* part 1: drain cap of tri-state gate */ - Ctotal += degree * (SIM_power_draincap(Woutdrivern, NCH, 1) + SIM_power_draincap(Woutdriverp, PCH, 1)); - - /* part 2: gate cap of tri-state gate */ - Ctotal += SIM_power_gatecap(Woutdrvnandn + Woutdrvnandp, 0) + - SIM_power_gatecap(Woutdrvnorn + Woutdrvnorp, 0); - } - else {/* some error handler */} - - return Ctotal / 2; -} - - -/* FIXME: segment control signals are not handled yet */ -static double crossbar_ctr_cap(double length, unsigned data_width, int prev_ctr, int next_ctr, unsigned degree, int connect_type, int trans_type) -{ - double Ctotal = 0, Cgate; - - /* part 1: wire cap */ - Ctotal = Cmetal * length; - - /* part 2: gate cap of transmission gate or tri-state gate */ - if (connect_type == TRANS_GATE) { - /* FIXME: Wmemcellr and resize */ - Cgate = SIM_power_gatecap(Wmemcellr, 0); - if (trans_type == NP_GATE) - Cgate += SIM_power_gatecap(Wmemcellr * Wdecinvp / Wdecinvn, 0); - } - else if (connect_type == TRISTATE_GATE) { - Cgate = SIM_power_gatecap(Woutdrvnandn + Woutdrvnandp, 0) + - SIM_power_gatecap(Woutdrvnorn + Woutdrvnorp, 0); - } - else {/* some error handler */} - - Ctotal += data_width * Cgate; - - /* part 3: inverter */ - if (!(connect_type == TRANS_GATE && trans_type == N_GATE && !prev_ctr)) - /* FIXME: need accurate size, use minimal size for now */ - Ctotal += SIM_power_draincap(Wdecinvn, NCH, 1) + SIM_power_draincap(Wdecinvp, PCH, 1) + - SIM_power_gatecap(Wdecinvn + Wdecinvp, 0); - - /* part 4: drain cap of previous level control signal */ - if (prev_ctr) - /* FIXME: need actual size, use decoder data for now */ - Ctotal += degree * SIM_power_draincap(WdecNORn, NCH, 1) + SIM_power_draincap(WdecNORp, PCH, degree); - - /* part 5: gate cap of next level control signal */ - if (next_ctr) - /* FIXME: need actual size, use decoder data for now */ - Ctotal += SIM_power_gatecap(WdecNORn + WdecNORp, degree * 40 + 20); - - return Ctotal; -} - - -int power_crossbar_init(power_crossbar *crsbar, int model, unsigned n_in, unsigned n_out, unsigned data_width, unsigned degree, int connect_type, int trans_type, double in_len, double out_len, double *req_len) -{ - double in_length, out_length, ctr_length, Nsize, in_wire_cap, i_leakage; - - if ((crsbar->model = model) && model < CROSSBAR_MAX_MODEL) { - crsbar->n_in = n_in; - crsbar->n_out = n_out; - crsbar->data_width = data_width; - crsbar->degree = degree; - crsbar->connect_type = connect_type; - crsbar->trans_type = trans_type; - /* redundant field */ - crsbar->mask = HAMM_MASK(data_width); - - crsbar->n_chg_in = crsbar->n_chg_int = crsbar->n_chg_out = crsbar->n_chg_ctr = 0; - - switch (model) { - case MATRIX_CROSSBAR: - - /* FIXME: need accurate spacing */ - in_length = n_out * data_width * CrsbarCellWidth; - out_length = n_in * data_width * CrsbarCellHeight; - if (in_length < in_len) in_length = in_len; - if (out_length < out_len) out_length = out_len; - ctr_length = in_length / 2; - if (req_len) *req_len = in_length; - - in_wire_cap = in_length * CC3metal; - - crsbar->e_chg_out = crossbar_out_cap(out_length, n_in, connect_type, trans_type, &Nsize) * EnergyFactor; - crsbar->e_chg_in = crossbar_in_cap(in_wire_cap, n_out, connect_type, trans_type, &Nsize) * EnergyFactor; - /* FIXME: wire length estimation, really reset? */ - /* control signal should reset after transmission is done, so no 1/2 */ - crsbar->e_chg_ctr = crossbar_ctr_cap(ctr_length, data_width, 0, 0, 0, connect_type, trans_type) * EnergyFactor; - crsbar->e_chg_int = 0; - - /* static power */ - i_leakage = 0; - /* tri-state buffers */ - i_leakage += ((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]) * n_in * n_out * data_width; - /* input driver */ - i_leakage += (Wdecinvn * NMOS_TAB[0] + Wdecinvp * PMOS_TAB[0]) * n_in * data_width; - /* output driver */ - i_leakage += (Woutdrivern * NMOS_TAB[0] + Woutdriverp * PMOS_TAB[0]) * n_out * data_width; - /* control signal inverter */ - i_leakage += (Wdecinvn * NMOS_TAB[0] + Wdecinvp * PMOS_TAB[0]) * n_in * n_out; - crsbar->i_leakage = i_leakage / PARM_TECH_POINT * 100; - break; - - case MULTREE_CROSSBAR: - /* input wire horizontal segment length */ - in_length = n_in * data_width * CrsbarCellWidth * (n_out / 2); - in_wire_cap = in_length * CCmetal; - /* input wire vertical segment length */ - in_length = n_in * data_width * (5 * Lamda) * (n_out / 2); - in_wire_cap += in_length * CC3metal; - - ctr_length = n_in * data_width * CrsbarCellWidth * (n_out / 2) / 2; - - crsbar->e_chg_out = crossbar_out_cap(0, degree, connect_type, trans_type, NULL) * EnergyFactor; - crsbar->e_chg_in = crossbar_in_cap(in_wire_cap, n_out, connect_type, trans_type, NULL) * EnergyFactor; - crsbar->e_chg_int = crossbar_int_cap(degree, connect_type, trans_type) * EnergyFactor; - - /* redundant field */ - crsbar->depth = (unsigned)ceil(log(n_in) / log(degree)); - - /* control signal should reset after transmission is done, so no 1/2 */ - if (crsbar->depth == 1) - /* only one level of control signal */ - crsbar->e_chg_ctr = crossbar_ctr_cap(ctr_length, data_width, 0, 0, degree, connect_type, trans_type) * EnergyFactor; - else { - /* first level and last level control signals */ - crsbar->e_chg_ctr = crossbar_ctr_cap(ctr_length, data_width, 0, 1, degree, connect_type, trans_type) * EnergyFactor + - crossbar_ctr_cap(0, data_width, 1, 0, degree, connect_type, trans_type) * EnergyFactor; - /* intermediate control signals */ - if (crsbar->depth > 2) - crsbar->e_chg_ctr += (crsbar->depth - 2) * crossbar_ctr_cap(0, data_width, 1, 1, degree, connect_type, trans_type) * EnergyFactor; - } - - /* static power */ - i_leakage = 0; - /* input driver */ - i_leakage += (Wdecinvn * NMOS_TAB[0] + Wdecinvp * PMOS_TAB[0]) * n_in * data_width; - /* output driver */ - i_leakage += (Woutdrivern * NMOS_TAB[0] + Woutdriverp * PMOS_TAB[0]) * n_out * data_width; - /* mux */ - i_leakage += (WdecNORp * NOR2_TAB[0] + WdecNORn * (NOR2_TAB[1] + NOR2_TAB[2] + NOR2_TAB[3])) / 4 * (2 * n_in - 1) * n_out * data_width; - /* control signal inverter */ - i_leakage += (Wdecinvn * NMOS_TAB[0] + Wdecinvp * PMOS_TAB[0]) * n_in * n_out; - crsbar->i_leakage = i_leakage / PARM_TECH_POINT * 100; - break; - - default: break;/* some error handler */ - } - - return 0; - } - else - return -1; -} - - -/* FIXME: MULTREE_CROSSBAR record missing */ -int crossbar_record(power_crossbar *xb, int io, unsigned long int new_data, unsigned long int old_data, unsigned new_port, unsigned old_port) -{ - switch (xb->model) { - case MATRIX_CROSSBAR: - if (io) /* input port */ - xb->n_chg_in += SIM_power_Hamming(new_data, old_data, xb->mask); - else { /* output port */ - xb->n_chg_out += SIM_power_Hamming(new_data, old_data, xb->mask); - xb->n_chg_ctr += new_port != old_port; - } - break; - - case MULTREE_CROSSBAR: - break; - - default: break;/* some error handler */ - } - - return 0; -} - - -double crossbar_report(power_crossbar *crsbar) -{ - return (crsbar->n_chg_in * crsbar->e_chg_in + crsbar->n_chg_out * crsbar->e_chg_out + - crsbar->n_chg_int * crsbar->e_chg_int + crsbar->n_chg_ctr * crsbar->e_chg_ctr); -} - -/* ---------- crossbar model ---------- */ - - - diff --git a/src/mem/ruby/network/orion/power_ll.cc b/src/mem/ruby/network/orion/power_ll.cc deleted file mode 100644 index 864336034..000000000 --- a/src/mem/ruby/network/orion/power_ll.cc +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * 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. - */ - -/*------------------------------------------------------------ - * Copyright 1994 Digital Equipment Corporation and Steve Wilton - * All Rights Reserved - * - * Permission to use, copy, and modify this software and its documentation is - * hereby granted only under the following terms and conditions. Both the - * above copyright notice and this permission notice must appear in all copies - * of the software, derivative works or modified versions, and any portions - * thereof, and both notices must appear in supporting documentation. - * - * Users of this software agree to the terms and conditions set forth herein, - * and hereby grant back to Digital a non-exclusive, unrestricted, royalty- - * free right and license under any changes, enhancements or extensions - * made to the core functions of the software, including but not limited to - * those affording compatibility with other hardware or software - * environments, but excluding applications which incorporate this software. - * Users further agree to use their best efforts to return to Digital any - * such changes, enhancements or extensions that they make and inform Digital - * of noteworthy uses of this software. Correspondence should be provided - * to Digital at: - * - * Director of Licensing - * Western Research Laboratory - * Digital Equipment Corporation - * 100 Hamilton Avenue - * Palo Alto, California 94301 - * - * This software may be distributed (but not offered for sale or transferred - * for compensation) to third parties, provided such third parties agree to - * abide by the terms and conditions of this notice. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - *------------------------------------------------------------*/ - -#include <cassert> -#include <cmath> - -#include "mem/ruby/network/orion/parm_technology.hh" -#include "mem/ruby/network/orion/SIM_port.hh" -#include "mem/ruby/network/orion/power_static.hh" -#include "mem/ruby/network/orion/power_ll.hh" - -/*----------------------------------------------------------------------*/ - -double SIM_power_gatecap(double width,double wirelength) /* returns gate capacitance in Farads */ -//double width; /* gate width in um (length is Leff) */ -//double wirelength; /* poly wire length going to gate in lambda */ -{ - - double overlapCap; - double gateCap; - double l = 0.1525; - -#if defined(Pdelta_w) - overlapCap = (width - 2*Pdelta_w) * PCov; - gateCap = ((width - 2*Pdelta_w) * (l * LSCALE - 2*Pdelta_l) * - PCg) + 2.0 * overlapCap; - - return gateCap; -#endif - return(width*Leff*PARM_Cgate+wirelength*Cpolywire*Leff * SCALE_T); - /* return(width*Leff*PARM_Cgate); */ - /* return(width*CgateLeff+wirelength*Cpolywire*Leff);*/ -} - - -double SIM_power_gatecappass(double width,double wirelength) /* returns gate capacitance in Farads */ -//double width; /* gate width in um (length is Leff) */ -//double wirelength; /* poly wire length going to gate in lambda */ -{ - return(SIM_power_gatecap(width,wirelength)); - /* return(width*Leff*PARM_Cgatepass+wirelength*Cpolywire*Leff); */ -} - - -/*----------------------------------------------------------------------*/ - -/* Routine for calculating drain capacitances. The draincap routine - * folds transistors larger than 10um */ -double SIM_power_draincap(double width,int nchannel,int stack) /* returns drain cap in Farads */ -//double width; /* um */ -//int nchannel; /* whether n or p-channel (boolean) */ -//int stack; /* number of transistors in series that are on */ -{ - double Cdiffside,Cdiffarea,Coverlap,cap; - - double overlapCap; - double swAreaUnderGate; - double area_peri; - double diffArea; - double diffPeri; - double l = 0.4 * LSCALE; - - - diffArea = l * width; - diffPeri = 2 * l + 2 * width; - -#if defined(Pdelta_w) - if(nchannel == 0) { - overlapCap = (width - 2 * Pdelta_w) * PCov; - swAreaUnderGate = (width - 2 * Pdelta_w) * PCjswA; - area_peri = ((diffArea * PCja) - + (diffPeri * PCjsw)); - - return(stack*(area_peri + overlapCap + swAreaUnderGate)); - } - else { - overlapCap = (width - 2 * Ndelta_w) * NCov; - swAreaUnderGate = (width - 2 * Ndelta_w) * NCjswA; - area_peri = ((diffArea * NCja * LSCALE) - + (diffPeri * NCjsw * LSCALE)); - - return(stack*(area_peri + overlapCap + swAreaUnderGate)); - } -#endif - - Cdiffside = (nchannel) ? PARM_Cndiffside : PARM_Cpdiffside; - Cdiffarea = (nchannel) ? PARM_Cndiffarea : PARM_Cpdiffarea; - Coverlap = (nchannel) ? (PARM_Cndiffovlp+PARM_Cnoxideovlp) : - (PARM_Cpdiffovlp+PARM_Cpoxideovlp); - /* calculate directly-connected (non-stacked) capacitance */ - /* then add in capacitance due to stacking */ - if (width >= 10) { - cap = 3.0*Leff*width/2.0*Cdiffarea + 6.0*Leff*Cdiffside + - width*Coverlap; - cap += (double)(stack-1)*(Leff*width*Cdiffarea + - 4.0*Leff*Cdiffside + 2.0*width*Coverlap); - } else { - cap = 3.0*Leff*width*Cdiffarea + (6.0*Leff+width)*Cdiffside + - width*Coverlap; - cap += (double)(stack-1)*(Leff*width*Cdiffarea + - 2.0*Leff*Cdiffside + 2.0*width*Coverlap); - } - return(cap * SCALE_T); -} - - -/*----------------------------------------------------------------------*/ - -/* The following routines estimate the effective resistance of an - on transistor as described in the tech report. The first routine - gives the "switching" resistance, and the second gives the - "full-on" resistance */ -double SIM_power_transresswitch(double width,int nchannel,int stack) /* returns resistance in ohms */ -//double width; /* um */ -//int nchannel; /* whether n or p-channel (boolean) */ -//int stack; /* number of transistors in series */ -{ - double restrans; - restrans = (nchannel) ? (Rnchannelstatic): - (Rpchannelstatic); - /* calculate resistance of stack - assume all but switching trans - have 0.8X the resistance since they are on throughout switching */ - return((1.0+((stack-1.0)*0.8))*restrans/width); -} - - -/*----------------------------------------------------------------------*/ - -double SIM_power_transreson(double width,int nchannel,int stack) /* returns resistance in ohms */ -//double width; /* um */ -//int nchannel; /* whether n or p-channel (boolean) */ -//int stack; /* number of transistors in series */ -{ - double restrans; - restrans = (nchannel) ? Rnchannelon : Rpchannelon; - - /* calculate resistance of stack. Unlike transres, we don't - multiply the stacked transistors by 0.8 */ - return(stack*restrans/width); -} - - -/*----------------------------------------------------------------------*/ - -/* This routine operates in reverse: given a resistance, it finds - * the transistor width that would have this R. It is used in the - * data wordline to estimate the wordline driver size. */ -double SIM_power_restowidth(double res,int nchannel) /* returns width in um */ -//double res; /* resistance in ohms */ -//int nchannel; /* whether N-channel or P-channel */ -{ - double restrans; - - restrans = (nchannel) ? Rnchannelon : Rpchannelon; - - return(restrans/res); -} - - -/*----------------------------------------------------------------------*/ - -double SIM_power_horowitz(double inputramptime,double tf,double vs1,double vs2,int rise) -//double inputramptime, /* input rise time */ - // tf, /* time constant of gate */ - // vs1,vs2; /* threshold voltages */ -//int rise; /* whether INPUT rise or fall (boolean) */ -{ - double a,b,td; - - a = inputramptime/tf; - if (rise==RISE) { - b = 0.5; - td = tf*sqrt(fabs( log(vs1)*log(vs1)+2*a*b*(1.0-vs1))) + - tf*(log(vs1)-log(vs2)); - } else { - b = 0.4; - td = tf*sqrt(fabs( log(1.0-vs1)*log(1.0-vs1)+2*a*b*(vs1))) + - tf*(log(1.0-vs1)-log(1.0-vs2)); - } - - return(td); -} - - - - -double SIM_power_driver_size(double driving_cap, double desiredrisetime) -{ - double nsize, psize; - double Rpdrive; - - Rpdrive = desiredrisetime/(driving_cap*log(PARM_VSINV)*-1.0); - psize = SIM_power_restowidth(Rpdrive,PCH); - nsize = SIM_power_restowidth(Rpdrive,NCH); - if (psize > Wworddrivemax) { - psize = Wworddrivemax; - } - if (psize < 4.0 * LSCALE) - psize = 4.0 * LSCALE; - - return (psize); -} - - diff --git a/src/mem/ruby/network/orion/power_router_init.cc b/src/mem/ruby/network/orion/power_router_init.cc deleted file mode 100644 index 9a8bc7f28..000000000 --- a/src/mem/ruby/network/orion/power_router_init.cc +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> - -#include "mem/ruby/network/orion/power_router_init.hh" -#include "mem/ruby/network/orion/power_array.hh" -#include "mem/ruby/network/orion/power_arbiter.hh" -#include "mem/ruby/network/orion/power_crossbar.hh" -#include "mem/ruby/network/orion/power_ll.hh" -#include "mem/ruby/network/orion/parm_technology.hh" -#include "mem/ruby/network/orion/SIM_port.hh" -#include "mem/ruby/network/orion/power_static.hh" -#include "mem/ruby/network/orion/power_utils.hh" - -/* -------------------------------------------------------------------------------------------- */ -// Set buffer parameters -int buf_set_para(power_array_info *info, int is_fifo, unsigned n_read_port, unsigned n_write_port, unsigned n_entry, unsigned line_width, int outdrv) -{ - //general parameters - info->share_rw = 0; - info->read_ports = n_read_port; - info->write_ports = n_write_port; - info->n_set = n_entry; - info->blk_bits = line_width; - info->assoc = 1; - info->data_width = line_width; - info->data_end = PARM_data_end; - - //no array subpartition - info->data_ndwl = 1; - info->data_ndbl = 1; - info->data_nspd = 1; - - info->data_n_share_amp =1; - - //MODEL parameters - if(is_fifo) { - info->row_dec_model = SIM_NO_MODEL; - info->row_dec_pre_model = SIM_NO_MODEL; - } - else { - info->row_dec_model = PARM_row_dec_model; - info->row_dec_pre_model = PARM_row_dec_pre_model; - } - - info->data_wordline_model = PARM_wordline_model; - info->data_bitline_model = PARM_bitline_model; - info->data_bitline_pre_model = PARM_bitline_pre_model; - info->data_mem_model = PARM_mem_model; - - if(PARM_data_end == 2) - info->data_amp_model = PARM_amp_model; - else - info->data_amp_model = SIM_NO_MODEL; - if(outdrv) - info->outdrv_model = PARM_outdrv_model; - else - info->outdrv_model = SIM_NO_MODEL; - - info->data_colsel_pre_model = SIM_NO_MODEL; - info->col_dec_model = SIM_NO_MODEL; - info->col_dec_pre_model = SIM_NO_MODEL; - info->mux_model = SIM_NO_MODEL; - - //no tag array - - info->tag_wordline_model = SIM_NO_MODEL; - info->tag_bitline_model = SIM_NO_MODEL; - info->tag_bitline_pre_model = SIM_NO_MODEL; - info->tag_mem_model = SIM_NO_MODEL; - info->tag_attach_mem_model = SIM_NO_MODEL; - info->tag_amp_model = SIM_NO_MODEL; - info->tag_colsel_pre_model = SIM_NO_MODEL; - info->comp_model = SIM_NO_MODEL; - info->comp_pre_model = SIM_NO_MODEL; - - info->write_policy = 0; //no dirty bit - - //derived - if(info->data_width != 0){ - info->n_item = info->blk_bits / info->data_width; - } - else{ - info->eff_data_cols = info->blk_bits * info->assoc * info->data_nspd; - } - - return 0; -} -/* -------------------------------------------------------------------------------------------- */ - - -/* --------------- Router init --------------------------------------*/ - - -int power_router_init(power_router *router, power_router_info *info) -{ - int outdrv; - double req_len = 0; - - //general -// info->n_in = PARM_in_port; - info->n_total_in = info->n_in; -// info->n_out = PARM_out_port; - info->n_total_out = info->n_out; -// info->flit_width = PARM_flit_width; - - //vc -// info->n_v_channel = MAX(PARM_v_channel, 1); -// info->n_v_class = MAX(info->n_v_channel, PARM_v_class); - - if(info->n_v_class > 1) { - info->in_share_buf = PARM_in_share_buf; - info->out_share_buf = PARM_out_share_buf; - info->in_share_switch = PARM_in_share_switch; - info->out_share_switch = PARM_out_share_switch; - } - else { - info->in_share_buf = 0; - info->out_share_buf = 0; - info->in_share_switch = 0; - info->out_share_switch = 0; - } - - //xbar - info->crossbar_model = PARM_crossbar_model; - info->degree = PARM_crsbar_degree; - info->connect_type = PARM_connect_type; - info->trans_type = PARM_trans_type; - info->crossbar_in_len = PARM_crossbar_in_len; - info->crossbar_out_len = PARM_crossbar_out_len; - - //input buffer - info->in_buf = PARM_in_buf; - outdrv = !info->in_share_buf && info->in_share_switch; - buf_set_para(&info->in_buf_info, 0, PARM_in_buf_rport, 1, PARM_in_buf_set, info->flit_width, outdrv); - - //vc arbiter - if(info->n_v_class > 1) { - info->vc_in_arb_model = PARM_vc_in_arb_model; - info->vc_out_arb_model = PARM_vc_out_arb_model; - if(info->vc_in_arb_model == QUEUE_ARBITER) { - buf_set_para(&info->vc_in_arb_queue_info, 1, 1, 1, info->n_v_class, SIM_power_logtwo(info->n_v_class), 0); - info->vc_in_arb_ff_model = SIM_NO_MODEL; - } - else - info->vc_in_arb_ff_model = PARM_vc_in_arb_ff_model; - - if(info->vc_out_arb_model == QUEUE_ARBITER) { - buf_set_para(&info->vc_out_arb_queue_info, 1, 1, 1, info->n_total_in - 1, SIM_power_logtwo(info->n_total_in - 1), 0); - info->vc_out_arb_ff_model = SIM_NO_MODEL; - } - else - info->vc_out_arb_ff_model = PARM_vc_out_arb_ff_model; - } - else { - info->vc_in_arb_model = SIM_NO_MODEL; - info->vc_in_arb_ff_model = SIM_NO_MODEL; - info->vc_out_arb_model = SIM_NO_MODEL; - info->vc_out_arb_ff_model = SIM_NO_MODEL; - } - - //switch arbiter - if (info->n_in > 2) { - info->sw_in_arb_model = PARM_sw_in_arb_model; - info->sw_out_arb_model = PARM_sw_out_arb_model; - if(info->sw_in_arb_model == QUEUE_ARBITER) { - buf_set_para(&info->sw_in_arb_queue_info, 1, 1, 1, info->n_v_class, SIM_power_logtwo(info->n_v_class), 0); - info->sw_in_arb_ff_model = SIM_NO_MODEL; - } - else - info->sw_in_arb_ff_model = PARM_sw_in_arb_ff_model; - - if(info->sw_out_arb_model == QUEUE_ARBITER) { - buf_set_para(&info->sw_out_arb_queue_info, 1, 1, 1, info->n_total_in - 1, SIM_power_logtwo(info->n_total_in - 1), 0); - info->sw_out_arb_ff_model = SIM_NO_MODEL; - } - else - info->sw_out_arb_ff_model = PARM_sw_out_arb_ff_model; - } - else { - info->sw_in_arb_model = SIM_NO_MODEL; - info->sw_in_arb_ff_model = SIM_NO_MODEL; - info->sw_out_arb_model = SIM_NO_MODEL; - info->sw_out_arb_ff_model = SIM_NO_MODEL; - } - - if(info->in_buf) { - if(info->in_share_buf) - info->in_n_switch = info->in_buf_info.read_ports; - else if(info->in_share_switch) - info->in_n_switch = 1; - else - info->in_n_switch = info->n_v_class; - } - else - info->in_n_switch = 1; - - info->n_switch_in = info->n_in * info->in_n_switch; - - info->n_switch_out = info->n_out; - - //-------- call initialize functions ----------- - - router->i_leakage = 0; - - //initialize crossbar - power_crossbar_init(&router->crossbar, info->crossbar_model, info->n_switch_in, info->n_switch_out, info->flit_width, info->degree, info->connect_type, info->trans_type, info->crossbar_in_len, info->crossbar_out_len, &req_len); - router->i_leakage += router->crossbar.i_leakage; -// printf("xbar_leak %g", router->crossbar.i_leakage); - - //initialize input buffer - if(info->in_buf) { - power_array_init(&info->in_buf_info, &router->in_buf); - router->i_leakage += router->in_buf.i_leakage * info->n_in; -// printf("buffer_leak %g", router->in_buf.i_leakage); - } -// printf("initialize in buffer over\n"); - - //initialize vc arbiter - if(info->vc_in_arb_model) - power_arbiter_init(&router->vc_in_arb, info->vc_in_arb_model, info->vc_in_arb_ff_model, PARM_VC_per_MC, 0, &info->vc_in_arb_queue_info); - - if(info->vc_out_arb_model) - power_arbiter_init(&router->vc_out_arb, info->vc_out_arb_model, info->vc_out_arb_ff_model, info->n_total_in - 1, req_len, &info->vc_out_arb_queue_info); - - //initialize switch arbiter - if(info->sw_in_arb_model) - power_arbiter_init(&router->sw_in_arb, info->sw_in_arb_model, info->sw_in_arb_ff_model, info->n_v_class, 0, &info->sw_in_arb_queue_info); - - if(info->sw_out_arb_model) - power_arbiter_init(&router->sw_out_arb, info->sw_out_arb_model, info->sw_out_arb_ff_model, info->n_total_in - 1, req_len, &info->sw_out_arb_queue_info); - - return 0; -} diff --git a/src/mem/ruby/network/orion/power_router_init.hh b/src/mem/ruby/network/orion/power_router_init.hh deleted file mode 100644 index df0b8fb18..000000000 --- a/src/mem/ruby/network/orion/power_router_init.hh +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _POWER_ROUTER_INIT_H -#define _POWER_ROUTER_INIT_H - -#include "mem/ruby/network/orion/power_array.hh" -#include "mem/ruby/network/orion/power_arbiter.hh" -#include "mem/ruby/network/orion/power_crossbar.hh" - -/* ------------ Models ------------------------ */ -/*typedef enum { - GENERIC_SEL = 1, - SEL_MAX_MODEL -} power_sel_model; -*/ - -/* ------------ Misc --------------------------- */ - -/*typedef struct { - int model; - unsigned width; - unsigned long long n_anyreq; - unsigned long long n_chgreq; - unsigned long long n_grant; - unsigned long long n_enc[MAX_SEL_LEVEL]; - double e_anyreq; - double e_chgreq; - double e_grant; - double e_enc[MAX_SEL_LEVEL]; -} power_sel; -*/ - -/* --------------- Loading --------------- */ -typedef enum { - ACTUAL_LOADING =1, - HALF_LOADING, - MAX_LOADING -}loading; - -/* ----------------- Router --------------- */ - -typedef struct { - power_crossbar crossbar; - power_array in_buf; - power_arbiter vc_in_arb; - power_arbiter vc_out_arb; - power_arbiter sw_in_arb; - power_arbiter sw_out_arb; - double i_leakage; -} power_router; - -typedef struct { - //general - unsigned n_in; - unsigned n_out; - unsigned flit_width; - //vc - unsigned n_v_channel; - unsigned n_v_class; - int in_share_buf; - int out_share_buf; - int in_share_switch; - int out_share_switch; - //xbar - int crossbar_model; - int degree; - int connect_type; - int trans_type; - double crossbar_in_len; - double crossbar_out_len; - - int in_buf; - - //buffer - power_array_info in_buf_info; - unsigned pipe_depth; - //arbiter - int vc_in_arb_model; - int vc_out_arb_model; - int vc_in_arb_ff_model; - int vc_out_arb_ff_model; - int sw_in_arb_model; - int sw_out_arb_model; - int sw_in_arb_ff_model; - int sw_out_arb_ff_model; - - power_array_info vc_in_arb_queue_info; - power_array_info vc_out_arb_queue_info; - power_array_info sw_in_arb_queue_info; - power_array_info sw_out_arb_queue_info; - //derived - unsigned n_total_in; - unsigned n_total_out; - unsigned in_n_switch; - unsigned n_switch_in; - unsigned n_switch_out; -} power_router_info; - -extern int power_router_init(power_router *router, power_router_info *info); -#endif diff --git a/src/mem/ruby/network/orion/power_utils.cc b/src/mem/ruby/network/orion/power_utils.cc deleted file mode 100644 index 358e13c6f..000000000 --- a/src/mem/ruby/network/orion/power_utils.cc +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <cassert> -#include <cmath> -#include <cstdio> - -#include "base/types.hh" -#include "mem/ruby/network/orion/parm_technology.hh" -#include "mem/ruby/network/orion/power_utils.hh" - -/* ----------- from SIM_power_util.c ------------ */ - -/* Hamming distance table */ -static char h_tab[256] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8}; - - -static uint32_t SIM_power_Hamming_slow( uint64_t old_val, uint64_t new_val, uint64_t mask ) -{ - /* old slow code, I don't understand the new fast code though */ - /* uint64_t dist; - uint32_t Hamming = 0; - - dist = ( old_val ^ new_val ) & mask; - mask = (mask >> 1) + 1; - - while ( mask ) { - if ( mask & dist ) Hamming ++; - mask = mask >> 1; - } - - return Hamming; */ - -#define TWO(k) (BIGONE << (k)) -#define CYCL(k) (BIGNONE/(1 + (TWO(TWO(k))))) -#define BSUM(x,k) ((x)+=(x) >> TWO(k), (x) &= CYCL(k)) - uint64_t x; - - x = (old_val ^ new_val) & mask; - x = (x & CYCL(0)) + ((x>>TWO(0)) & CYCL(0)); - x = (x & CYCL(1)) + ((x>>TWO(1)) & CYCL(1)); - BSUM(x,2); - BSUM(x,3); - BSUM(x,4); - BSUM(x,5); - - return x; -} - - -int SIM_power_init(void) -{ - uint32_t i; - - /* initialize Hamming distance table */ - for (i = 0; i < 256; i++) - h_tab[i] = SIM_power_Hamming_slow(i, 0, 0xFF); - - return 0; -} - - - -uint32_t -SIM_power_Hamming(uint64_t old_val, uint64_t new_val, uint64_t mask) -{ - union { - uint64_t x; - uint64_t id[8]; - } u; - - uint32_t rval; - - u.x = (old_val ^ new_val) & mask; - - rval = h_tab[u.id[0]]; - rval += h_tab[u.id[1]]; - rval += h_tab[u.id[2]]; - rval += h_tab[u.id[3]]; - rval += h_tab[u.id[4]]; - rval += h_tab[u.id[5]]; - rval += h_tab[u.id[6]]; - rval += h_tab[u.id[7]]; - - return rval; -} - - -uint32_t -SIM_power_Hamming_group(uint64_t d1_new, uint64_t d1_old, uint64_t d2_new, - uint64_t d2_old, uint32_t width, uint32_t n_grp) -{ - uint32_t rval = 0; - uint64_t g1_new, g1_old, g2_new, g2_old, mask; - - mask = HAMM_MASK(width); - - while (n_grp--) { - g1_new = d1_new & mask; - g1_old = d1_old & mask; - g2_new = d2_new & mask; - g2_old = d2_old & mask; - - if (g1_new != g1_old || g2_new != g2_old) - rval ++; - - d1_new >>= width; - d1_old >>= width; - d2_new >>= width; - d2_old >>= width; - } - - return rval; -} - -/* ---------------------------------------------- */ - -/* ----------------------------------------------- */ - - - - -double logtwo(double x) -{ - assert(x > 0); - return log10(x)/log10(2); -} - -uint32_t -SIM_power_logtwo(uint64_t x) -{ - uint32_t rval = 0; - - while (x >> rval && rval < sizeof(uint64_t) << 3) rval++; - if (x == (BIGONE << rval - 1)) rval--; - - return rval; -} - diff --git a/src/mem/ruby/network/orion/router.cfg b/src/mem/ruby/network/orion/router.cfg new file mode 100644 index 000000000..68f0cd149 --- /dev/null +++ b/src/mem/ruby/network/orion/router.cfg @@ -0,0 +1,146 @@ +# 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 + |