From 2f30950143cc70bc42a3c8a4111d7cf8198ec881 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 11 May 2009 10:38:43 -0700 Subject: 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. --- src/mem/ruby/network/orion/NetworkPower.cc | 430 +++++ src/mem/ruby/network/orion/NetworkPower.hh | 32 + src/mem/ruby/network/orion/SIM_port.hh | 172 ++ src/mem/ruby/network/orion/SIM_power.hh | 384 ++++ src/mem/ruby/network/orion/SIM_power_test.hh | 285 +++ src/mem/ruby/network/orion/parm_technology.hh | 474 +++++ src/mem/ruby/network/orion/power_arbiter.cc | 392 ++++ src/mem/ruby/network/orion/power_arbiter.hh | 90 + src/mem/ruby/network/orion/power_array.cc | 2158 +++++++++++++++++++++++ src/mem/ruby/network/orion/power_array.hh | 394 +++++ src/mem/ruby/network/orion/power_bus.cc | 215 +++ src/mem/ruby/network/orion/power_bus.hh | 64 + src/mem/ruby/network/orion/power_crossbar.cc | 365 ++++ src/mem/ruby/network/orion/power_crossbar.hh | 81 + src/mem/ruby/network/orion/power_ll.cc | 270 +++ src/mem/ruby/network/orion/power_ll.hh | 53 + src/mem/ruby/network/orion/power_router_init.cc | 260 +++ src/mem/ruby/network/orion/power_router_init.hh | 126 ++ src/mem/ruby/network/orion/power_static.cc | 46 + src/mem/ruby/network/orion/power_static.hh | 39 + src/mem/ruby/network/orion/power_utils.cc | 157 ++ src/mem/ruby/network/orion/power_utils.hh | 35 + 22 files changed, 6522 insertions(+) create mode 100644 src/mem/ruby/network/orion/NetworkPower.cc create mode 100644 src/mem/ruby/network/orion/NetworkPower.hh create mode 100644 src/mem/ruby/network/orion/SIM_port.hh create mode 100644 src/mem/ruby/network/orion/SIM_power.hh create mode 100644 src/mem/ruby/network/orion/SIM_power_test.hh create mode 100644 src/mem/ruby/network/orion/parm_technology.hh create mode 100644 src/mem/ruby/network/orion/power_arbiter.cc create mode 100644 src/mem/ruby/network/orion/power_arbiter.hh create mode 100644 src/mem/ruby/network/orion/power_array.cc create mode 100644 src/mem/ruby/network/orion/power_array.hh create mode 100644 src/mem/ruby/network/orion/power_bus.cc create mode 100644 src/mem/ruby/network/orion/power_bus.hh create mode 100644 src/mem/ruby/network/orion/power_crossbar.cc create mode 100644 src/mem/ruby/network/orion/power_crossbar.hh create mode 100644 src/mem/ruby/network/orion/power_ll.cc create mode 100644 src/mem/ruby/network/orion/power_ll.hh create mode 100644 src/mem/ruby/network/orion/power_router_init.cc create mode 100644 src/mem/ruby/network/orion/power_router_init.hh create mode 100644 src/mem/ruby/network/orion/power_static.cc create mode 100644 src/mem/ruby/network/orion/power_static.hh create mode 100644 src/mem/ruby/network/orion/power_utils.cc create mode 100644 src/mem/ruby/network/orion/power_utils.hh (limited to 'src/mem/ruby/network/orion') 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 +#include + +#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 +#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 +#include + +#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 + +#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 +#include + +#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 + +#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 +#include + +#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 +#include + +#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 + +#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 +#include "parm_technology.hh" +#include "power_utils.hh" +#include +#include + +/* ----------- 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 -- cgit v1.2.3