summaryrefslogtreecommitdiff
path: root/src/mem/ruby/network/orion
diff options
context:
space:
mode:
authorNathan Binkert <nate@binkert.org>2009-05-11 10:38:43 -0700
committerNathan Binkert <nate@binkert.org>2009-05-11 10:38:43 -0700
commit2f30950143cc70bc42a3c8a4111d7cf8198ec881 (patch)
tree708f6c22edb3c6feb31dd82866c26623a5329580 /src/mem/ruby/network/orion
parentc70241810d4e4f523f173c1646b008dc40faad8e (diff)
downloadgem5-2f30950143cc70bc42a3c8a4111d7cf8198ec881.tar.xz
ruby: Import ruby and slicc from GEMS
We eventually plan to replace the m5 cache hierarchy with the GEMS hierarchy, but for now we will make both live alongside eachother.
Diffstat (limited to 'src/mem/ruby/network/orion')
-rw-r--r--src/mem/ruby/network/orion/NetworkPower.cc430
-rw-r--r--src/mem/ruby/network/orion/NetworkPower.hh32
-rw-r--r--src/mem/ruby/network/orion/SIM_port.hh172
-rw-r--r--src/mem/ruby/network/orion/SIM_power.hh384
-rw-r--r--src/mem/ruby/network/orion/SIM_power_test.hh285
-rw-r--r--src/mem/ruby/network/orion/parm_technology.hh474
-rw-r--r--src/mem/ruby/network/orion/power_arbiter.cc392
-rw-r--r--src/mem/ruby/network/orion/power_arbiter.hh90
-rw-r--r--src/mem/ruby/network/orion/power_array.cc2158
-rw-r--r--src/mem/ruby/network/orion/power_array.hh394
-rw-r--r--src/mem/ruby/network/orion/power_bus.cc215
-rw-r--r--src/mem/ruby/network/orion/power_bus.hh64
-rw-r--r--src/mem/ruby/network/orion/power_crossbar.cc365
-rw-r--r--src/mem/ruby/network/orion/power_crossbar.hh81
-rw-r--r--src/mem/ruby/network/orion/power_ll.cc270
-rw-r--r--src/mem/ruby/network/orion/power_ll.hh53
-rw-r--r--src/mem/ruby/network/orion/power_router_init.cc260
-rw-r--r--src/mem/ruby/network/orion/power_router_init.hh126
-rw-r--r--src/mem/ruby/network/orion/power_static.cc46
-rw-r--r--src/mem/ruby/network/orion/power_static.hh39
-rw-r--r--src/mem/ruby/network/orion/power_utils.cc157
-rw-r--r--src/mem/ruby/network/orion/power_utils.hh35
22 files changed, 6522 insertions, 0 deletions
diff --git a/src/mem/ruby/network/orion/NetworkPower.cc b/src/mem/ruby/network/orion/NetworkPower.cc
new file mode 100644
index 000000000..6e5994071
--- /dev/null
+++ b/src/mem/ruby/network/orion/NetworkPower.cc
@@ -0,0 +1,430 @@
+/*
+ * 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 "power_router_init.hh"
+#include "power_array.hh"
+#include "power_crossbar.hh"
+#include "power_arbiter.hh"
+#include "power_bus.hh"
+#include "NetworkPower.hh"
+#include "Router_d.hh"
+#include "NetworkLink_d.hh"
+#include "GarnetNetwork_d.hh"
+#include "SIM_port.hh"
+#include "parm_technology.hh"
+
+/* --------- Static energy calculation functions ------------ */
+
+//Input buffer
+double SIM_reg_stat_energy(power_array_info *info, power_array *arr, double n_read, double n_write)
+{
+ 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;
+ }
+ //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, Estatic;
+
+ 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;
+}
+
+//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;
+}
+
+double SIM_bus_stat_energy(power_bus *bus, double e_link)
+{
+ double Ebus;
+ Ebus = bus->e_switch * e_link * SWITCHING_FACTOR * bus->bit_width;
+
+ return (Ebus);
+}
+
+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;
+}
+
+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;
+}
+
+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;
+}
+
+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;
+
+}
+
+double Router_d::calculate_power()
+{
+ power_router router;
+ power_router_info router_info;
+ double total_energy, total_power;
+
+ power_router_initialize(&router, &router_info);
+ power_router_init(&router, &router_info);
+
+ total_energy = calculate_offline_power(&router, &router_info);
+ total_power = total_energy * PARM_Freq;
+ return total_power;
+}
diff --git a/src/mem/ruby/network/orion/NetworkPower.hh b/src/mem/ruby/network/orion/NetworkPower.hh
new file mode 100644
index 000000000..560d58376
--- /dev/null
+++ b/src/mem/ruby/network/orion/NetworkPower.hh
@@ -0,0 +1,32 @@
+/*
+ * 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 _NETWORK_POWER_H
+#define _NETWORK_POWER_H
+
+#endif
diff --git a/src/mem/ruby/network/orion/SIM_port.hh b/src/mem/ruby/network/orion/SIM_port.hh
new file mode 100644
index 000000000..96d26daad
--- /dev/null
+++ b/src/mem/ruby/network/orion/SIM_port.hh
@@ -0,0 +1,172 @@
+/*
+ * 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
new file mode 100644
index 000000000..1f0ddd36c
--- /dev/null
+++ b/src/mem/ruby/network/orion/SIM_power.hh
@@ -0,0 +1,384 @@
+/*
+ * 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 "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 unsigned int SIM_power_logtwo(LIB_Type_max_uint 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 unsigned int SIM_power_Hamming(LIB_Type_max_uint old_val, LIB_Type_max_uint new_val, LIB_Type_max_uint 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
new file mode 100644
index 000000000..95b304042
--- /dev/null
+++ b/src/mem/ruby/network/orion/SIM_power_test.hh
@@ -0,0 +1,285 @@
+/*
+ * 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/parm_technology.hh b/src/mem/ruby/network/orion/parm_technology.hh
new file mode 100644
index 000000000..87049d4cd
--- /dev/null
+++ b/src/mem/ruby/network/orion/parm_technology.hh
@@ -0,0 +1,474 @@
+/*
+ * 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
new file mode 100644
index 000000000..ba68fbe1c
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_arbiter.cc
@@ -0,0 +1,392 @@
+/*
+ * 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 "power_arbiter.hh"
+#include "power_array.hh"
+#include "power_ll.hh"
+#include "parm_technology.hh"
+#include "SIM_port.hh"
+#include "power_static.hh"
+#include "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
new file mode 100644
index 000000000..671608c2f
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_arbiter.hh
@@ -0,0 +1,90 @@
+/*
+ * 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 "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
new file mode 100644
index 000000000..225f45377
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_array.cc
@@ -0,0 +1,2158 @@
+/*
+ * 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 "power_array.hh"
+#include "power_ll.hh"
+#include "parm_technology.hh"
+#include "SIM_port.hh"
+#include "power_static.hh"
+#include "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
new file mode 100644
index 000000000..dbd2733c9
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_array.hh
@@ -0,0 +1,394 @@
+/*
+ * 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
new file mode 100644
index 000000000..032c3c519
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_bus.cc
@@ -0,0 +1,215 @@
+/*
+ * 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 "power_bus.hh"
+#include "power_ll.hh"
+#include "parm_technology.hh"
+#include "SIM_port.hh"
+#include "power_static.hh"
+#include "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_bus.hh b/src/mem/ruby/network/orion/power_bus.hh
new file mode 100644
index 000000000..e1c3ef565
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_bus.hh
@@ -0,0 +1,64 @@
+/*
+ * 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_BUS_H
+#define _POWER_BUS_H
+
+typedef enum {
+ RESULT_BUS = 1,
+ GENERIC_BUS,
+ BUS_MAX_MODEL
+} power_bus_model;
+
+typedef enum {
+ IDENT_ENC = 1, /* identity encoding */
+ TRANS_ENC, /* transition encoding */
+ BUSINV_ENC, /* bus inversion encoding */
+ BUS_MAX_ENC
+} power_bus_enc;
+
+
+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;
+
+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);
+
+extern int bus_record(power_bus *bus, unsigned long int old_state, unsigned long int new_state);
+
+extern double bus_report(power_bus *bus);
+
+#endif
diff --git a/src/mem/ruby/network/orion/power_crossbar.cc b/src/mem/ruby/network/orion/power_crossbar.cc
new file mode 100644
index 000000000..d3e2232ae
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_crossbar.cc
@@ -0,0 +1,365 @@
+/*
+ * 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 "power_ll.hh"
+#include "power_crossbar.hh"
+#include "parm_technology.hh"
+#include "SIM_port.hh"
+#include "power_static.hh"
+#include "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_crossbar.hh b/src/mem/ruby/network/orion/power_crossbar.hh
new file mode 100644
index 000000000..1dc0220e7
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_crossbar.hh
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+// Crossbar
+
+#ifndef _POWER_CROSSBAR_H
+#define _POWER_CROSSBAR_H
+
+typedef enum {
+ TRANS_GATE,
+ TRISTATE_GATE
+} power_connect_model;
+
+/* transmission gate type */
+typedef enum {
+ N_GATE,
+ NP_GATE
+} power_trans;
+
+typedef enum {
+ MATRIX_CROSSBAR =1,
+ MULTREE_CROSSBAR,
+ CUT_THRU_CROSSBAR,
+ CROSSBAR_MAX_MODEL
+} power_crossbar_model;
+
+
+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;
+
+
+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);
+
+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);
+
+#endif
diff --git a/src/mem/ruby/network/orion/power_ll.cc b/src/mem/ruby/network/orion/power_ll.cc
new file mode 100644
index 000000000..3628989d0
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_ll.cc
@@ -0,0 +1,270 @@
+/*
+ * 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 <math.h>
+#include <assert.h>
+
+#include "parm_technology.hh"
+#include "SIM_port.hh"
+#include "power_static.hh"
+#include "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_ll.hh b/src/mem/ruby/network/orion/power_ll.hh
new file mode 100644
index 000000000..4cae89dcc
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_ll.hh
@@ -0,0 +1,53 @@
+/*
+ * 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_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);
+
+
+
+
+
+
+
+
+
+
+
+
+#endif
diff --git a/src/mem/ruby/network/orion/power_router_init.cc b/src/mem/ruby/network/orion/power_router_init.cc
new file mode 100644
index 000000000..be58fbdbf
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_router_init.cc
@@ -0,0 +1,260 @@
+/*
+ * 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 "power_router_init.hh"
+#include "power_array.hh"
+#include "power_arbiter.hh"
+#include "power_crossbar.hh"
+#include "power_ll.hh"
+#include "parm_technology.hh"
+#include "SIM_port.hh"
+#include "power_static.hh"
+#include "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
new file mode 100644
index 000000000..2d95cea0b
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_router_init.hh
@@ -0,0 +1,126 @@
+/*
+ * 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 "power_array.hh"
+#include "power_arbiter.hh"
+#include "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_static.cc b/src/mem/ruby/network/orion/power_static.cc
new file mode 100644
index 000000000..c0ae394a6
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_static.cc
@@ -0,0 +1,46 @@
+/*
+ * 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 "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};
+#endif
diff --git a/src/mem/ruby/network/orion/power_static.hh b/src/mem/ruby/network/orion/power_static.hh
new file mode 100644
index 000000000..6bc58ca01
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_static.hh
@@ -0,0 +1,39 @@
+/*
+ * 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_STATIC_H
+#define _POWER_STATIC_H
+
+#include "parm_technology.hh"
+
+extern double NMOS_TAB[1];
+extern double PMOS_TAB[1];
+extern double NAND2_TAB[4];
+extern double NOR2_TAB[4];
+
+#endif
diff --git a/src/mem/ruby/network/orion/power_utils.cc b/src/mem/ruby/network/orion/power_utils.cc
new file mode 100644
index 000000000..1f592fff0
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_utils.cc
@@ -0,0 +1,157 @@
+/*
+ * 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 "parm_technology.hh"
+#include "power_utils.hh"
+#include <assert.h>
+#include <math.h>
+
+/* ----------- 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 unsigned SIM_power_Hamming_slow( unsigned long int old_val, unsigned long int new_val, unsigned long int mask )
+{
+ /* old slow code, I don't understand the new fast code though */
+ /* unsigned long int dist;
+ unsigned 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))
+ unsigned long int 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)
+{
+ unsigned i;
+
+ /* initialize Hamming distance table */
+ for (i = 0; i < 256; i++)
+ h_tab[i] = SIM_power_Hamming_slow(i, 0, 0xFF);
+
+ return 0;
+}
+
+
+/* assume unsigned long int is unsigned64_t */
+unsigned SIM_power_Hamming(unsigned long int old_val, unsigned long int new_val, unsigned long int mask)
+{
+ union {
+ unsigned long int x;
+ char id[8];
+ } u;
+ unsigned 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;
+}
+
+
+unsigned SIM_power_Hamming_group(unsigned long int d1_new, unsigned long int d1_old, unsigned long int d2_new, unsigned long int d2_old, unsigned width, unsigned n_grp)
+{
+ unsigned rval = 0;
+ unsigned long int 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);
+}
+
+unsigned SIM_power_logtwo(unsigned long int x)
+{
+ unsigned rval = 0;
+
+ while (x >> rval && rval < sizeof(unsigned long int) << 3) rval++;
+ if (x == (BIGONE << rval - 1)) rval--;
+
+ return rval;
+}
+
diff --git a/src/mem/ruby/network/orion/power_utils.hh b/src/mem/ruby/network/orion/power_utils.hh
new file mode 100644
index 000000000..59123c1f7
--- /dev/null
+++ b/src/mem/ruby/network/orion/power_utils.hh
@@ -0,0 +1,35 @@
+/*
+ * 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_UTILS_H
+#define _POWER_UTILS_H
+extern unsigned SIM_power_Hamming(unsigned long int old_val, unsigned long int new_val, unsigned long int mask);
+extern double logtwo(double x);
+extern unsigned SIM_power_logtwo(unsigned long int x);
+
+#endif