2014-04-01 18:44:30 +02:00
|
|
|
/*****************************************************************************
|
|
|
|
* McPAT/CACTI
|
|
|
|
* SOFTWARE LICENSE AGREEMENT
|
|
|
|
* Copyright 2012 Hewlett-Packard Development Company, L.P.
|
2014-06-03 22:32:59 +02:00
|
|
|
* Copyright (c) 2010-2013 Advanced Micro Devices, Inc.
|
2014-04-01 18:44:30 +02:00
|
|
|
* All Rights Reserved
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions are
|
|
|
|
* met: redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer;
|
|
|
|
* redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution;
|
|
|
|
* neither the name of the copyright holders nor the names of its
|
|
|
|
* contributors may be used to endorse or promote products derived from
|
|
|
|
* this software without specific prior written permission.
|
|
|
|
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
2014-06-03 22:32:59 +02:00
|
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
2014-04-01 18:44:30 +02:00
|
|
|
*
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <cmath>
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
#include "uca.h"
|
|
|
|
|
|
|
|
UCA::UCA(const DynamicParameter & dyn_p)
|
2014-06-03 22:32:59 +02:00
|
|
|
: dp(dyn_p), bank(dp), nbanks(g_ip->nbanks), refresh_power(0) {
|
|
|
|
int num_banks_ver_dir = 1 << ((bank.area.h > bank.area.w) ? _log2(nbanks)
|
|
|
|
/ 2 : (_log2(nbanks) - _log2(nbanks) / 2));
|
|
|
|
int num_banks_hor_dir = nbanks / num_banks_ver_dir;
|
|
|
|
|
|
|
|
if (dp.use_inp_params) {
|
|
|
|
RWP = dp.num_rw_ports;
|
|
|
|
ERP = dp.num_rd_ports;
|
|
|
|
EWP = dp.num_wr_ports;
|
|
|
|
SCHP = dp.num_search_ports;
|
|
|
|
} else {
|
|
|
|
RWP = g_ip->num_rw_ports;
|
|
|
|
ERP = g_ip->num_rd_ports;
|
|
|
|
EWP = g_ip->num_wr_ports;
|
|
|
|
SCHP = g_ip->num_search_ports;
|
|
|
|
}
|
|
|
|
|
|
|
|
num_addr_b_bank = (dp.number_addr_bits_mat + dp.number_subbanks_decode) *
|
|
|
|
(RWP + ERP + EWP);
|
|
|
|
num_di_b_bank = dp.num_di_b_bank_per_port * (RWP + EWP);
|
|
|
|
num_do_b_bank = dp.num_do_b_bank_per_port * (RWP + ERP);
|
|
|
|
num_si_b_bank = dp.num_si_b_bank_per_port * SCHP;
|
|
|
|
num_so_b_bank = dp.num_so_b_bank_per_port * SCHP;
|
|
|
|
|
|
|
|
if (!dp.fully_assoc && !dp.pure_cam) {
|
|
|
|
|
|
|
|
if (g_ip->fast_access && dp.is_tag == false) {
|
|
|
|
num_do_b_bank *= g_ip->data_assoc;
|
|
|
|
}
|
|
|
|
|
|
|
|
htree_in_add = new Htree2(g_ip->wt, bank.area.w, bank.area.h,
|
|
|
|
num_addr_b_bank, num_di_b_bank, 0,
|
|
|
|
num_do_b_bank, 0, num_banks_ver_dir * 2,
|
|
|
|
num_banks_hor_dir * 2, Add_htree, true);
|
|
|
|
htree_in_data = new Htree2(g_ip->wt, bank.area.w, bank.area.h,
|
|
|
|
num_addr_b_bank, num_di_b_bank, 0,
|
|
|
|
num_do_b_bank, 0, num_banks_ver_dir * 2,
|
|
|
|
num_banks_hor_dir * 2, Data_in_htree, true);
|
|
|
|
htree_out_data = new Htree2(g_ip->wt, bank.area.w, bank.area.h,
|
|
|
|
num_addr_b_bank, num_di_b_bank, 0,
|
|
|
|
num_do_b_bank, 0, num_banks_ver_dir * 2,
|
|
|
|
num_banks_hor_dir * 2, Data_out_htree, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
htree_in_add = new Htree2(g_ip->wt, bank.area.w, bank.area.h,
|
|
|
|
num_addr_b_bank, num_di_b_bank,
|
|
|
|
num_si_b_bank, num_do_b_bank, num_so_b_bank,
|
|
|
|
num_banks_ver_dir * 2, num_banks_hor_dir * 2,
|
|
|
|
Add_htree, true);
|
|
|
|
htree_in_data = new Htree2(g_ip->wt, bank.area.w, bank.area.h,
|
|
|
|
num_addr_b_bank, num_di_b_bank,
|
|
|
|
num_si_b_bank, num_do_b_bank, num_so_b_bank,
|
|
|
|
num_banks_ver_dir * 2, num_banks_hor_dir * 2,
|
|
|
|
Data_in_htree, true);
|
|
|
|
htree_out_data = new Htree2(g_ip->wt, bank.area.w, bank.area.h,
|
|
|
|
num_addr_b_bank, num_di_b_bank,
|
|
|
|
num_si_b_bank, num_do_b_bank,
|
|
|
|
num_so_b_bank, num_banks_ver_dir * 2,
|
|
|
|
num_banks_hor_dir * 2, Data_out_htree, true);
|
|
|
|
htree_in_search = new Htree2(g_ip->wt, bank.area.w, bank.area.h,
|
|
|
|
num_addr_b_bank, num_di_b_bank,
|
|
|
|
num_si_b_bank, num_do_b_bank,
|
|
|
|
num_so_b_bank, num_banks_ver_dir * 2,
|
|
|
|
num_banks_hor_dir * 2, Data_in_htree, true);
|
|
|
|
htree_out_search = new Htree2(g_ip->wt, bank.area.w, bank.area.h,
|
|
|
|
num_addr_b_bank, num_di_b_bank,
|
|
|
|
num_si_b_bank, num_do_b_bank,
|
|
|
|
num_so_b_bank, num_banks_ver_dir * 2,
|
|
|
|
num_banks_hor_dir * 2, Data_out_htree,
|
|
|
|
true);
|
|
|
|
}
|
|
|
|
|
|
|
|
area.w = htree_in_data->area.w;
|
|
|
|
area.h = htree_in_data->area.h;
|
|
|
|
|
|
|
|
area_all_dataramcells = bank.mat.subarray.get_total_cell_area() * dp.num_subarrays * g_ip->nbanks;
|
2014-04-01 18:44:30 +02:00
|
|
|
// cout<<"area cell"<<area_all_dataramcells<<endl;
|
|
|
|
// cout<<area.get_area()<<endl;
|
2014-06-03 22:32:59 +02:00
|
|
|
// delay calculation
|
|
|
|
double inrisetime = 0.0;
|
|
|
|
compute_delays(inrisetime);
|
|
|
|
compute_power_energy();
|
2014-04-01 18:44:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-06-03 22:32:59 +02:00
|
|
|
UCA::~UCA() {
|
|
|
|
delete htree_in_add;
|
|
|
|
delete htree_in_data;
|
|
|
|
delete htree_out_data;
|
2014-04-01 18:44:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-06-03 22:32:59 +02:00
|
|
|
double UCA::compute_delays(double inrisetime) {
|
|
|
|
double outrisetime = bank.compute_delays(inrisetime);
|
|
|
|
|
|
|
|
double delay_array_to_mat = htree_in_add->delay + bank.htree_in_add->delay;
|
|
|
|
double max_delay_before_row_decoder = delay_array_to_mat + bank.mat.r_predec->delay;
|
|
|
|
delay_array_to_sa_mux_lev_1_decoder = delay_array_to_mat +
|
|
|
|
bank.mat.sa_mux_lev_1_predec->delay +
|
|
|
|
bank.mat.sa_mux_lev_1_dec->delay;
|
|
|
|
delay_array_to_sa_mux_lev_2_decoder = delay_array_to_mat +
|
|
|
|
bank.mat.sa_mux_lev_2_predec->delay +
|
|
|
|
bank.mat.sa_mux_lev_2_dec->delay;
|
|
|
|
double delay_inside_mat = bank.mat.row_dec->delay + bank.mat.delay_bitline + bank.mat.delay_sa;
|
|
|
|
|
|
|
|
delay_before_subarray_output_driver =
|
|
|
|
MAX(MAX(max_delay_before_row_decoder + delay_inside_mat, // row_path
|
|
|
|
delay_array_to_mat + bank.mat.b_mux_predec->delay + bank.mat.bit_mux_dec->delay + bank.mat.delay_sa), // col_path
|
|
|
|
MAX(delay_array_to_sa_mux_lev_1_decoder, // sa_mux_lev_1_path
|
|
|
|
delay_array_to_sa_mux_lev_2_decoder)); // sa_mux_lev_2_path
|
|
|
|
delay_from_subarray_out_drv_to_out = bank.mat.delay_subarray_out_drv_htree +
|
|
|
|
bank.htree_out_data->delay + htree_out_data->delay;
|
|
|
|
access_time = bank.mat.delay_comparator;
|
|
|
|
|
|
|
|
double ram_delay_inside_mat;
|
|
|
|
if (dp.fully_assoc) {
|
|
|
|
//delay of FA contains both CAM tag and RAM data
|
|
|
|
{ //delay of CAM
|
|
|
|
ram_delay_inside_mat = bank.mat.delay_bitline + bank.mat.delay_matchchline;
|
|
|
|
access_time = htree_in_add->delay + bank.htree_in_add->delay;
|
|
|
|
//delay of fully-associative data array
|
|
|
|
access_time += ram_delay_inside_mat + delay_from_subarray_out_drv_to_out;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
access_time = delay_before_subarray_output_driver + delay_from_subarray_out_drv_to_out; //data_acc_path
|
2014-04-01 18:44:30 +02:00
|
|
|
}
|
2014-06-03 22:32:59 +02:00
|
|
|
|
|
|
|
if (dp.is_main_mem) {
|
|
|
|
double t_rcd = max_delay_before_row_decoder + delay_inside_mat;
|
|
|
|
double cas_latency = MAX(delay_array_to_sa_mux_lev_1_decoder, delay_array_to_sa_mux_lev_2_decoder) +
|
|
|
|
delay_from_subarray_out_drv_to_out;
|
|
|
|
access_time = t_rcd + cas_latency;
|
|
|
|
}
|
|
|
|
|
|
|
|
double temp;
|
|
|
|
|
|
|
|
if (!dp.fully_assoc) {
|
|
|
|
temp = delay_inside_mat + bank.mat.delay_wl_reset + bank.mat.delay_bl_restore;//TODO: Sheng: revisit
|
|
|
|
if (dp.is_dram) {
|
|
|
|
temp += bank.mat.delay_writeback; // temp stores random cycle time
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
temp = MAX(temp, bank.mat.r_predec->delay);
|
|
|
|
temp = MAX(temp, bank.mat.b_mux_predec->delay);
|
|
|
|
temp = MAX(temp, bank.mat.sa_mux_lev_1_predec->delay);
|
|
|
|
temp = MAX(temp, bank.mat.sa_mux_lev_2_predec->delay);
|
|
|
|
} else {
|
|
|
|
ram_delay_inside_mat = bank.mat.delay_bitline + bank.mat.delay_matchchline;
|
|
|
|
temp = ram_delay_inside_mat + bank.mat.delay_cam_sl_restore + bank.mat.delay_cam_ml_reset + bank.mat.delay_bl_restore
|
|
|
|
+ bank.mat.delay_hit_miss_reset + bank.mat.delay_wl_reset;
|
|
|
|
|
|
|
|
temp = MAX(temp, bank.mat.b_mux_predec->delay);//TODO: Sheng revisit whether distinguish cam and ram bitline etc.
|
|
|
|
temp = MAX(temp, bank.mat.sa_mux_lev_1_predec->delay);
|
|
|
|
temp = MAX(temp, bank.mat.sa_mux_lev_2_predec->delay);
|
|
|
|
}
|
|
|
|
|
|
|
|
// The following is true only if the input parameter "repeaters_in_htree" is set to false --Nav
|
|
|
|
if (g_ip->rpters_in_htree == false) {
|
|
|
|
temp = MAX(temp, bank.htree_in_add->max_unpipelined_link_delay);
|
|
|
|
}
|
|
|
|
cycle_time = temp;
|
|
|
|
|
|
|
|
double delay_req_network = max_delay_before_row_decoder;
|
|
|
|
double delay_rep_network = delay_from_subarray_out_drv_to_out;
|
|
|
|
multisubbank_interleave_cycle_time = MAX(delay_req_network, delay_rep_network);
|
|
|
|
|
|
|
|
if (dp.is_main_mem) {
|
|
|
|
multisubbank_interleave_cycle_time = htree_in_add->delay;
|
|
|
|
precharge_delay = htree_in_add->delay +
|
|
|
|
bank.htree_in_add->delay + bank.mat.delay_writeback +
|
|
|
|
bank.mat.delay_wl_reset + bank.mat.delay_bl_restore;
|
|
|
|
cycle_time = access_time + precharge_delay;
|
|
|
|
} else {
|
|
|
|
precharge_delay = 0;
|
2014-04-01 18:44:30 +02:00
|
|
|
}
|
|
|
|
|
2014-06-03 22:32:59 +02:00
|
|
|
double dram_array_availability = 0;
|
|
|
|
if (dp.is_dram) {
|
|
|
|
dram_array_availability = (1 - dp.num_r_subarray * cycle_time / dp.dram_refresh_period) * 100;
|
|
|
|
}
|
2014-04-01 18:44:30 +02:00
|
|
|
|
2014-06-03 22:32:59 +02:00
|
|
|
return outrisetime;
|
2014-04-01 18:44:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// note: currently, power numbers are for a bank of an array
|
2014-06-03 22:32:59 +02:00
|
|
|
void UCA::compute_power_energy() {
|
|
|
|
bank.compute_power_energy();
|
|
|
|
power = bank.power;
|
|
|
|
|
|
|
|
power_routing_to_bank.readOp.dynamic = htree_in_add->power.readOp.dynamic + htree_out_data->power.readOp.dynamic;
|
|
|
|
power_routing_to_bank.writeOp.dynamic = htree_in_add->power.readOp.dynamic + htree_in_data->power.readOp.dynamic;
|
|
|
|
if (dp.fully_assoc || dp.pure_cam)
|
|
|
|
power_routing_to_bank.searchOp.dynamic =
|
|
|
|
htree_in_search->power.searchOp.dynamic +
|
|
|
|
htree_out_search->power.searchOp.dynamic;
|
|
|
|
|
|
|
|
power_routing_to_bank.readOp.leakage +=
|
|
|
|
htree_in_add->power.readOp.leakage +
|
|
|
|
htree_in_data->power.readOp.leakage +
|
|
|
|
htree_out_data->power.readOp.leakage;
|
|
|
|
|
|
|
|
power_routing_to_bank.readOp.gate_leakage +=
|
|
|
|
htree_in_add->power.readOp.gate_leakage +
|
|
|
|
htree_in_data->power.readOp.gate_leakage +
|
|
|
|
htree_out_data->power.readOp.gate_leakage;
|
|
|
|
if (dp.fully_assoc || dp.pure_cam) {
|
2014-04-01 18:44:30 +02:00
|
|
|
power_routing_to_bank.readOp.leakage += htree_in_search->power.readOp.leakage + htree_out_search->power.readOp.leakage;
|
|
|
|
power_routing_to_bank.readOp.gate_leakage += htree_in_search->power.readOp.gate_leakage + htree_out_search->power.readOp.gate_leakage;
|
2014-06-03 22:32:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
power.searchOp.dynamic += power_routing_to_bank.searchOp.dynamic;
|
|
|
|
power.readOp.dynamic += power_routing_to_bank.readOp.dynamic;
|
|
|
|
power.readOp.leakage += power_routing_to_bank.readOp.leakage;
|
|
|
|
power.readOp.gate_leakage += power_routing_to_bank.readOp.gate_leakage;
|
|
|
|
|
|
|
|
// calculate total write energy per access
|
|
|
|
power.writeOp.dynamic = power.readOp.dynamic
|
|
|
|
- bank.mat.power_bitline.readOp.dynamic * dp.num_act_mats_hor_dir
|
|
|
|
+ bank.mat.power_bitline.writeOp.dynamic * dp.num_act_mats_hor_dir
|
|
|
|
- power_routing_to_bank.readOp.dynamic
|
|
|
|
+ power_routing_to_bank.writeOp.dynamic
|
|
|
|
+ bank.htree_in_data->power.readOp.dynamic
|
|
|
|
- bank.htree_out_data->power.readOp.dynamic;
|
|
|
|
|
|
|
|
if (dp.is_dram == false) {
|
|
|
|
power.writeOp.dynamic -= bank.mat.power_sa.readOp.dynamic * dp.num_act_mats_hor_dir;
|
|
|
|
}
|
|
|
|
|
|
|
|
dyn_read_energy_from_closed_page = power.readOp.dynamic;
|
|
|
|
dyn_read_energy_from_open_page = power.readOp.dynamic -
|
|
|
|
(bank.mat.r_predec->power.readOp.dynamic +
|
|
|
|
bank.mat.power_row_decoders.readOp.dynamic +
|
|
|
|
bank.mat.power_bl_precharge_eq_drv.readOp.dynamic +
|
|
|
|
bank.mat.power_sa.readOp.dynamic +
|
|
|
|
bank.mat.power_bitline.readOp.dynamic) * dp.num_act_mats_hor_dir;
|
|
|
|
|
|
|
|
dyn_read_energy_remaining_words_in_burst =
|
|
|
|
(MAX((g_ip->burst_len / g_ip->int_prefetch_w), 1) - 1) *
|
|
|
|
((bank.mat.sa_mux_lev_1_predec->power.readOp.dynamic +
|
|
|
|
bank.mat.sa_mux_lev_2_predec->power.readOp.dynamic +
|
|
|
|
bank.mat.power_sa_mux_lev_1_decoders.readOp.dynamic +
|
|
|
|
bank.mat.power_sa_mux_lev_2_decoders.readOp.dynamic +
|
|
|
|
bank.mat.power_subarray_out_drv.readOp.dynamic) * dp.num_act_mats_hor_dir +
|
|
|
|
bank.htree_out_data->power.readOp.dynamic +
|
|
|
|
power_routing_to_bank.readOp.dynamic);
|
|
|
|
dyn_read_energy_from_closed_page += dyn_read_energy_remaining_words_in_burst;
|
|
|
|
dyn_read_energy_from_open_page += dyn_read_energy_remaining_words_in_burst;
|
|
|
|
|
|
|
|
activate_energy = htree_in_add->power.readOp.dynamic +
|
|
|
|
bank.htree_in_add->power_bit.readOp.dynamic * bank.num_addr_b_routed_to_mat_for_act +
|
|
|
|
(bank.mat.r_predec->power.readOp.dynamic +
|
|
|
|
bank.mat.power_row_decoders.readOp.dynamic +
|
|
|
|
bank.mat.power_sa.readOp.dynamic) * dp.num_act_mats_hor_dir;
|
|
|
|
read_energy = (htree_in_add->power.readOp.dynamic +
|
|
|
|
bank.htree_in_add->power_bit.readOp.dynamic * bank.num_addr_b_routed_to_mat_for_rd_or_wr +
|
|
|
|
(bank.mat.sa_mux_lev_1_predec->power.readOp.dynamic +
|
|
|
|
bank.mat.sa_mux_lev_2_predec->power.readOp.dynamic +
|
|
|
|
bank.mat.power_sa_mux_lev_1_decoders.readOp.dynamic +
|
|
|
|
bank.mat.power_sa_mux_lev_2_decoders.readOp.dynamic +
|
|
|
|
bank.mat.power_subarray_out_drv.readOp.dynamic) * dp.num_act_mats_hor_dir +
|
|
|
|
bank.htree_out_data->power.readOp.dynamic +
|
|
|
|
htree_in_data->power.readOp.dynamic) * g_ip->burst_len;
|
|
|
|
write_energy = (htree_in_add->power.readOp.dynamic +
|
|
|
|
bank.htree_in_add->power_bit.readOp.dynamic * bank.num_addr_b_routed_to_mat_for_rd_or_wr +
|
|
|
|
htree_in_data->power.readOp.dynamic +
|
|
|
|
bank.htree_in_data->power.readOp.dynamic +
|
|
|
|
(bank.mat.sa_mux_lev_1_predec->power.readOp.dynamic +
|
|
|
|
bank.mat.sa_mux_lev_2_predec->power.readOp.dynamic +
|
|
|
|
bank.mat.power_sa_mux_lev_1_decoders.readOp.dynamic +
|
|
|
|
bank.mat.power_sa_mux_lev_2_decoders.readOp.dynamic) * dp.num_act_mats_hor_dir) * g_ip->burst_len;
|
|
|
|
precharge_energy = (bank.mat.power_bitline.readOp.dynamic +
|
|
|
|
bank.mat.power_bl_precharge_eq_drv.readOp.dynamic) * dp.num_act_mats_hor_dir;
|
|
|
|
|
|
|
|
leak_power_subbank_closed_page =
|
|
|
|
(bank.mat.r_predec->power.readOp.leakage +
|
|
|
|
bank.mat.b_mux_predec->power.readOp.leakage +
|
|
|
|
bank.mat.sa_mux_lev_1_predec->power.readOp.leakage +
|
|
|
|
bank.mat.sa_mux_lev_2_predec->power.readOp.leakage +
|
|
|
|
bank.mat.power_row_decoders.readOp.leakage +
|
|
|
|
bank.mat.power_bit_mux_decoders.readOp.leakage +
|
|
|
|
bank.mat.power_sa_mux_lev_1_decoders.readOp.leakage +
|
|
|
|
bank.mat.power_sa_mux_lev_2_decoders.readOp.leakage +
|
|
|
|
bank.mat.leak_power_sense_amps_closed_page_state) * dp.num_act_mats_hor_dir;
|
|
|
|
|
|
|
|
leak_power_subbank_closed_page +=
|
|
|
|
(bank.mat.r_predec->power.readOp.gate_leakage +
|
|
|
|
bank.mat.b_mux_predec->power.readOp.gate_leakage +
|
|
|
|
bank.mat.sa_mux_lev_1_predec->power.readOp.gate_leakage +
|
|
|
|
bank.mat.sa_mux_lev_2_predec->power.readOp.gate_leakage +
|
|
|
|
bank.mat.power_row_decoders.readOp.gate_leakage +
|
|
|
|
bank.mat.power_bit_mux_decoders.readOp.gate_leakage +
|
|
|
|
bank.mat.power_sa_mux_lev_1_decoders.readOp.gate_leakage +
|
|
|
|
bank.mat.power_sa_mux_lev_2_decoders.readOp.gate_leakage) * dp.num_act_mats_hor_dir; //+
|
|
|
|
//bank.mat.leak_power_sense_amps_closed_page_state) * dp.num_act_mats_hor_dir;
|
|
|
|
|
|
|
|
leak_power_subbank_open_page =
|
|
|
|
(bank.mat.r_predec->power.readOp.leakage +
|
|
|
|
bank.mat.b_mux_predec->power.readOp.leakage +
|
|
|
|
bank.mat.sa_mux_lev_1_predec->power.readOp.leakage +
|
|
|
|
bank.mat.sa_mux_lev_2_predec->power.readOp.leakage +
|
|
|
|
bank.mat.power_row_decoders.readOp.leakage +
|
|
|
|
bank.mat.power_bit_mux_decoders.readOp.leakage +
|
|
|
|
bank.mat.power_sa_mux_lev_1_decoders.readOp.leakage +
|
|
|
|
bank.mat.power_sa_mux_lev_2_decoders.readOp.leakage +
|
|
|
|
bank.mat.leak_power_sense_amps_open_page_state) * dp.num_act_mats_hor_dir;
|
|
|
|
|
|
|
|
leak_power_subbank_open_page +=
|
|
|
|
(bank.mat.r_predec->power.readOp.gate_leakage +
|
|
|
|
bank.mat.b_mux_predec->power.readOp.gate_leakage +
|
|
|
|
bank.mat.sa_mux_lev_1_predec->power.readOp.gate_leakage +
|
|
|
|
bank.mat.sa_mux_lev_2_predec->power.readOp.gate_leakage +
|
|
|
|
bank.mat.power_row_decoders.readOp.gate_leakage +
|
|
|
|
bank.mat.power_bit_mux_decoders.readOp.gate_leakage +
|
|
|
|
bank.mat.power_sa_mux_lev_1_decoders.readOp.gate_leakage +
|
|
|
|
bank.mat.power_sa_mux_lev_2_decoders.readOp.gate_leakage ) * dp.num_act_mats_hor_dir;
|
|
|
|
//bank.mat.leak_power_sense_amps_open_page_state) * dp.num_act_mats_hor_dir;
|
|
|
|
|
|
|
|
leak_power_request_and_reply_networks =
|
|
|
|
power_routing_to_bank.readOp.leakage +
|
|
|
|
bank.htree_in_add->power.readOp.leakage +
|
|
|
|
bank.htree_in_data->power.readOp.leakage +
|
|
|
|
bank.htree_out_data->power.readOp.leakage;
|
|
|
|
|
|
|
|
leak_power_request_and_reply_networks +=
|
|
|
|
power_routing_to_bank.readOp.gate_leakage +
|
|
|
|
bank.htree_in_add->power.readOp.gate_leakage +
|
|
|
|
bank.htree_in_data->power.readOp.gate_leakage +
|
|
|
|
bank.htree_out_data->power.readOp.gate_leakage;
|
|
|
|
|
|
|
|
if (dp.fully_assoc || dp.pure_cam) {
|
2014-04-01 18:44:30 +02:00
|
|
|
leak_power_request_and_reply_networks += htree_in_search->power.readOp.leakage + htree_out_search->power.readOp.leakage;
|
|
|
|
leak_power_request_and_reply_networks += htree_in_search->power.readOp.gate_leakage + htree_out_search->power.readOp.gate_leakage;
|
2014-06-03 22:32:59 +02:00
|
|
|
}
|
2014-04-01 18:44:30 +02:00
|
|
|
|
2014-06-03 22:32:59 +02:00
|
|
|
|
|
|
|
// if DRAM, add contribution of power spent in row predecoder drivers,
|
|
|
|
// blocks and decoders to refresh power
|
|
|
|
if (dp.is_dram) {
|
|
|
|
refresh_power = (bank.mat.r_predec->power.readOp.dynamic * dp.num_act_mats_hor_dir +
|
|
|
|
bank.mat.row_dec->power.readOp.dynamic) * dp.num_r_subarray * dp.num_subarrays;
|
|
|
|
refresh_power += bank.mat.per_bitline_read_energy * dp.num_c_subarray * dp.num_r_subarray * dp.num_subarrays;
|
|
|
|
refresh_power += bank.mat.power_bl_precharge_eq_drv.readOp.dynamic * dp.num_act_mats_hor_dir;
|
|
|
|
refresh_power += bank.mat.power_sa.readOp.dynamic * dp.num_act_mats_hor_dir;
|
|
|
|
refresh_power /= dp.dram_refresh_period;
|
2014-04-01 18:44:30 +02:00
|
|
|
}
|
2014-06-03 22:32:59 +02:00
|
|
|
|
|
|
|
|
|
|
|
if (dp.is_tag == false) {
|
|
|
|
power.readOp.dynamic = dyn_read_energy_from_closed_page;
|
|
|
|
power.writeOp.dynamic = dyn_read_energy_from_closed_page
|
|
|
|
- dyn_read_energy_remaining_words_in_burst
|
|
|
|
- bank.mat.power_bitline.readOp.dynamic * dp.num_act_mats_hor_dir
|
|
|
|
+ bank.mat.power_bitline.writeOp.dynamic * dp.num_act_mats_hor_dir
|
|
|
|
+ (power_routing_to_bank.writeOp.dynamic -
|
|
|
|
power_routing_to_bank.readOp.dynamic -
|
|
|
|
bank.htree_out_data->power.readOp.dynamic +
|
|
|
|
bank.htree_in_data->power.readOp.dynamic) *
|
|
|
|
(MAX((g_ip->burst_len / g_ip->int_prefetch_w), 1) - 1); //FIXME
|
|
|
|
|
|
|
|
if (dp.is_dram == false) {
|
|
|
|
power.writeOp.dynamic -= bank.mat.power_sa.readOp.dynamic * dp.num_act_mats_hor_dir;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// if DRAM, add refresh power to total leakage
|
|
|
|
if (dp.is_dram) {
|
|
|
|
power.readOp.leakage += refresh_power;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: below should be avoided.
|
|
|
|
/*if (dp.is_main_mem)
|
|
|
|
{
|
|
|
|
power.readOp.leakage += MAIN_MEM_PER_CHIP_STANDBY_CURRENT_mA * 1e-3 * g_tp.peri_global.Vdd / g_ip->nbanks;
|
|
|
|
}*/
|
|
|
|
|
|
|
|
assert(power.readOp.dynamic > 0);
|
|
|
|
assert(power.writeOp.dynamic > 0);
|
|
|
|
assert(power.readOp.leakage > 0);
|
2014-04-01 18:44:30 +02:00
|
|
|
}
|
|
|
|
|