/***************************************************************************** * McPAT/CACTI * SOFTWARE LICENSE AGREEMENT * Copyright 2012 Hewlett-Packard Development Company, L.P. * All Rights Reserved * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer; * redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution; * neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (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 #include #include "io.h" #include "area.h" #include "basic_circuit.h" #include "parameter.h" #include "Ucache.h" #include "nuca.h" #include "crossbar.h" #include "arbiter.h" #include "version_cacti.h" //#include "highradix.h" using namespace std; InputParameter::InputParameter() : array_power_gated(false), bitline_floating(false), wl_power_gated(false), cl_power_gated(false), interconect_power_gated(false), power_gating(false), perfloss(0.01), cl_vertical (true), long_channel_device(false) { dvs_voltage = std::vector(0); } /* Parses "cache.cfg" file */ void InputParameter::parse_cfg(const string & in_file) { FILE *fp = fopen(in_file.c_str(), "r"); char line[5000]; char jk[5000]; char temp_var[5000]; double temp_double; char *data = line; int offset= 0; if(!fp) { cout << in_file << " is missing!\n"; exit(-1); } while(fscanf(fp, "%[^\n]\n", line) != EOF) { if (!strncmp("-size", line, strlen("-size"))) { sscanf(line, "-size %[(:-~)*]%u", jk, &(cache_sz)); continue; } if (!strncmp("-page size", line, strlen("-page size"))) { sscanf(line, "-page size %[(:-~)*]%u", jk, &(page_sz_bits)); continue; } if (!strncmp("-burst length", line, strlen("-burst length"))) { sscanf(line, "-burst %[(:-~)*]%u", jk, &(burst_len)); continue; } if (!strncmp("-internal prefetch width", line, strlen("-internal prefetch width"))) { sscanf(line, "-internal prefetch %[(:-~)*]%u", jk, &(int_prefetch_w)); continue; } if (!strncmp("-block", line, strlen("-block"))) { sscanf(line, "-block size (bytes) %d", &(line_sz)); continue; } if (!strncmp("-associativity", line, strlen("-associativity"))) { sscanf(line, "-associativity %d", &(assoc)); continue; } if (!strncmp("-read-write", line, strlen("-read-write"))) { sscanf(line, "-read-write port %d", &(num_rw_ports)); continue; } if (!strncmp("-exclusive read", line, strlen("exclusive read"))) { sscanf(line, "-exclusive read port %d", &(num_rd_ports)); continue; } if(!strncmp("-exclusive write", line, strlen("-exclusive write"))) { sscanf(line, "-exclusive write port %d", &(num_wr_ports)); continue; } if (!strncmp("-single ended", line, strlen("-single ended"))) { sscanf(line, "-single %[(:-~)*]%d", jk, &(num_se_rd_ports)); continue; } if (!strncmp("-search", line, strlen("-search"))) { sscanf(line, "-search port %d", &(num_search_ports)); continue; } if (!strncmp("-UCA bank", line, strlen("-UCA bank"))) { sscanf(line, "-UCA bank%[((:-~)| )*]%d", jk, &(nbanks)); continue; } if (!strncmp("-technology", line, strlen("-technology"))) { sscanf(line, "-technology (u) %lf", &(F_sz_um)); F_sz_nm = F_sz_um*1000; continue; } if (!strncmp("-hp Vdd", line, strlen("-hp Vdd"))) { sscanf(line, "-hp Vdd%[^\"]\"%[^\"]\"", jk, temp_var); if (!strncmp("default", temp_var, sizeof("default"))) { specific_hp_vdd = false; hp_Vdd = 1.0; /* * if this is by default, then the vdd value in g_ip here does not matter */ } else { specific_hp_vdd = true; sscanf(line, "-hp Vdd (V) %lf", &(hp_Vdd)); } continue; } if (!strncmp("-lstp Vdd", line, strlen("-lstp Vdd"))) { sscanf(line, "-lstp Vdd%[^\"]\"%[^\"]\"", jk, temp_var); if (!strncmp("default", temp_var, sizeof("default"))) { specific_lstp_vdd = false; lstp_Vdd = 1.0; /* * if this is by default, then the vdd value in g_ip here does not matter */ } else { specific_lstp_vdd = true; sscanf(line, "-lstp Vdd (V) %lf", &(lstp_Vdd)); } continue; } if (!strncmp("-lop Vdd", line, strlen("-lop Vdd"))) { sscanf(line, "-lop Vdd%[^\"]\"%[^\"]\"", jk, temp_var); if (!strncmp("default", temp_var, sizeof("default"))) { specific_lop_vdd = false; lop_Vdd = 1.0; /* * if this is by default, then the vdd value in g_ip here does not matter */ } else { specific_lop_vdd = true; sscanf(line, "-lop Vdd (V) %lf", &(lop_Vdd)); } continue; } if (!strncmp("-DVS(V):", line, strlen("-DVS(V):"))) { memmove (line,line+9,strlen(line)); while (1 == sscanf(data, "%lf%n", &temp_double, &offset)) { data += offset; dvs_voltage.push_back(temp_double); } // dvs_levels = dvs_voltage.size(); continue; } if (!strncmp("-Powergating voltage", line, strlen("-Powergating voltage"))) { sscanf(line, "-Powergating voltage%[^\"]\"%[^\"]\"", jk, temp_var); if (!strncmp("default", temp_var, sizeof("default"))) { specific_vcc_min= false; user_defined_vcc_min = 1.0; /* * if this is by default, then the vdd value in g_ip here does not matter */ } else { specific_vcc_min = true; sscanf(line, "-Powergating voltage (V) %lf", &(user_defined_vcc_min)); } continue; } if (!strncmp("-output/input", line, strlen("-output/input"))) { sscanf(line, "-output/input bus %[(:-~)*]%d", jk, &(out_w)); continue; } if (!strncmp("-operating temperature", line, strlen("-operating temperature"))) { sscanf(line, "-operating temperature %[(:-~)*]%d", jk, &(temp)); continue; } if (!strncmp("-cache type", line, strlen("-cache type"))) { sscanf(line, "-cache type%[^\"]\"%[^\"]\"", jk, temp_var); if (!strncmp("cache", temp_var, sizeof("cache"))) { is_cache = true; } else { is_cache = false; } if (!strncmp("main memory", temp_var, sizeof("main memory"))) { is_main_mem = true; } else { is_main_mem = false; } if (!strncmp("cam", temp_var, sizeof("cam"))) { pure_cam = true; } else { pure_cam = false; } if (!strncmp("ram", temp_var, sizeof("ram"))) { pure_ram = true; } else { if (!is_main_mem) pure_ram = false; else pure_ram = true; } continue; } if (!strncmp("-tag size", line, strlen("-tag size"))) { sscanf(line, "-tag size%[^\"]\"%[^\"]\"", jk, temp_var); if (!strncmp("default", temp_var, sizeof("default"))) { specific_tag = false; tag_w = 42; /* the acutal value is calculated * later based on the cache size, bank count, and associativity */ } else { specific_tag = true; sscanf(line, "-tag size (b) %d", &(tag_w)); } continue; } if (!strncmp("-access mode", line, strlen("-access mode"))) { sscanf(line, "-access %[^\"]\"%[^\"]\"", jk, temp_var); if (!strncmp("fast", temp_var, strlen("fast"))) { access_mode = 2; } else if (!strncmp("sequential", temp_var, strlen("sequential"))) { access_mode = 1; } else if(!strncmp("normal", temp_var, strlen("normal"))) { access_mode = 0; } else { cout << "ERROR: Invalid access mode!\n"; exit(0); } continue; } if (!strncmp("-Data array cell type", line, strlen("-Data array cell type"))) { sscanf(line, "-Data array cell type %[^\"]\"%[^\"]\"", jk, temp_var); if(!strncmp("itrs-hp", temp_var, strlen("itrs-hp"))) { data_arr_ram_cell_tech_type = 0; } else if(!strncmp("itrs-lstp", temp_var, strlen("itrs-lstp"))) { data_arr_ram_cell_tech_type = 1; } else if(!strncmp("itrs-lop", temp_var, strlen("itrs-lop"))) { data_arr_ram_cell_tech_type = 2; } else if(!strncmp("lp-dram", temp_var, strlen("lp-dram"))) { data_arr_ram_cell_tech_type = 3; } else if(!strncmp("comm-dram", temp_var, strlen("comm-dram"))) { data_arr_ram_cell_tech_type = 4; } else { cout << "ERROR: Invalid type!\n"; exit(0); } continue; } if (!strncmp("-Data array peripheral type", line, strlen("-Data array peripheral type"))) { sscanf(line, "-Data array peripheral type %[^\"]\"%[^\"]\"", jk, temp_var); if(!strncmp("itrs-hp", temp_var, strlen("itrs-hp"))) { data_arr_peri_global_tech_type = 0; } else if(!strncmp("itrs-lstp", temp_var, strlen("itrs-lstp"))) { data_arr_peri_global_tech_type = 1; } else if(!strncmp("itrs-lop", temp_var, strlen("itrs-lop"))) { data_arr_peri_global_tech_type = 2; } else { cout << "ERROR: Invalid type!\n"; exit(0); } continue; } if (!strncmp("-Tag array cell type", line, strlen("-Tag array cell type"))) { sscanf(line, "-Tag array cell type %[^\"]\"%[^\"]\"", jk, temp_var); if(!strncmp("itrs-hp", temp_var, strlen("itrs-hp"))) { tag_arr_ram_cell_tech_type = 0; } else if(!strncmp("itrs-lstp", temp_var, strlen("itrs-lstp"))) { tag_arr_ram_cell_tech_type = 1; } else if(!strncmp("itrs-lop", temp_var, strlen("itrs-lop"))) { tag_arr_ram_cell_tech_type = 2; } else if(!strncmp("lp-dram", temp_var, strlen("lp-dram"))) { tag_arr_ram_cell_tech_type = 3; } else if(!strncmp("comm-dram", temp_var, strlen("comm-dram"))) { tag_arr_ram_cell_tech_type = 4; } else { cout << "ERROR: Invalid type!\n"; exit(0); } continue; } if (!strncmp("-Tag array peripheral type", line, strlen("-Tag array peripheral type"))) { sscanf(line, "-Tag array peripheral type %[^\"]\"%[^\"]\"", jk, temp_var); if(!strncmp("itrs-hp", temp_var, strlen("itrs-hp"))) { tag_arr_peri_global_tech_type = 0; } else if(!strncmp("itrs-lstp", temp_var, strlen("itrs-lstp"))) { tag_arr_peri_global_tech_type = 1; } else if(!strncmp("itrs-lop", temp_var, strlen("itrs-lop"))) { tag_arr_peri_global_tech_type = 2; } else { cout << "ERROR: Invalid type!\n"; exit(0); } continue; } if(!strncmp("-design", line, strlen("-design"))) { sscanf(line, "-%[((:-~)| |,)*]%d:%d:%d:%d:%d", jk, &(delay_wt), &(dynamic_power_wt), &(leakage_power_wt), &(cycle_time_wt), &(area_wt)); continue; } if(!strncmp("-deviate", line, strlen("-deviate"))) { sscanf(line, "-%[((:-~)| |,)*]%d:%d:%d:%d:%d", jk, &(delay_dev), &(dynamic_power_dev), &(leakage_power_dev), &(cycle_time_dev), &(area_dev)); continue; } if(!strncmp("-Optimize", line, strlen("-Optimize"))) { sscanf(line, "-Optimize %[^\"]\"%[^\"]\"", jk, temp_var); if(!strncmp("ED^2", temp_var, strlen("ED^2"))) { ed = 2; } else if(!strncmp("ED", temp_var, strlen("ED"))) { ed = 1; } else { ed = 0; } } if(!strncmp("-NUCAdesign", line, strlen("-NUCAdesign"))) { sscanf(line, "-%[((:-~)| |,)*]%d:%d:%d:%d:%d", jk, &(delay_wt_nuca), &(dynamic_power_wt_nuca), &(leakage_power_wt_nuca), &(cycle_time_wt_nuca), &(area_wt_nuca)); continue; } if(!strncmp("-NUCAdeviate", line, strlen("-NUCAdeviate"))) { sscanf(line, "-%[((:-~)| |,)*]%d:%d:%d:%d:%d", jk, &(delay_dev_nuca), &(dynamic_power_dev_nuca), &(leakage_power_dev_nuca), &(cycle_time_dev_nuca), &(area_dev_nuca)); continue; } if(!strncmp("-Cache model", line, strlen("-cache model"))) { sscanf(line, "-Cache model %[^\"]\"%[^\"]\"", jk, temp_var); if (!strncmp("UCA", temp_var, strlen("UCA"))) { nuca = 0; } else { nuca = 1; } continue; } if(!strncmp("-NUCA bank", line, strlen("-NUCA bank"))) { sscanf(line, "-NUCA bank count %d", &(nuca_bank_count)); if (nuca_bank_count != 0) { force_nuca_bank = 1; } continue; } if(!strncmp("-Wire inside mat", line, strlen("-Wire inside mat"))) { sscanf(line, "-Wire%[^\"]\"%[^\"]\"", jk, temp_var); if (!strncmp("global", temp_var, strlen("global"))) { wire_is_mat_type = 2; continue; } else if (!strncmp("local", temp_var, strlen("local"))) { wire_is_mat_type = 0; continue; } else { wire_is_mat_type = 1; continue; } } if(!strncmp("-Wire outside mat", line, strlen("-Wire outside mat"))) { sscanf(line, "-Wire%[^\"]\"%[^\"]\"", jk, temp_var); if (!strncmp("global", temp_var, strlen("global"))) { wire_os_mat_type = 2; } else { wire_os_mat_type = 1; } continue; } if(!strncmp("-Interconnect projection", line, strlen("-Interconnect projection"))) { sscanf(line, "-Interconnect projection%[^\"]\"%[^\"]\"", jk, temp_var); if (!strncmp("aggressive", temp_var, strlen("aggressive"))) { ic_proj_type = 0; } else { ic_proj_type = 1; } continue; } if(!strncmp("-Wire signalling", line, strlen("-wire signalling"))) { sscanf(line, "-Wire%[^\"]\"%[^\"]\"", jk, temp_var); if (!strncmp("default", temp_var, strlen("default"))) { force_wiretype = 0; wt = Global; } else if (!(strncmp("Global_10", temp_var, strlen("Global_10")))) { force_wiretype = 1; wt = Global_10; } else if (!(strncmp("Global_20", temp_var, strlen("Global_20")))) { force_wiretype = 1; wt = Global_20; } else if (!(strncmp("Global_30", temp_var, strlen("Global_30")))) { force_wiretype = 1; wt = Global_30; } else if (!(strncmp("Global_5", temp_var, strlen("Global_5")))) { force_wiretype = 1; wt = Global_5; } else if (!(strncmp("Global", temp_var, strlen("Global")))) { force_wiretype = 1; wt = Global; } else { wt = Low_swing; force_wiretype = 1; } continue; } if(!strncmp("-Core", line, strlen("-Core"))) { sscanf(line, "-Core count %d\n", &(cores)); if (cores > 16) { printf("No. of cores should be less than 16!\n"); } continue; } if(!strncmp("-Cache level", line, strlen("-Cache level"))) { sscanf(line, "-Cache l%[^\"]\"%[^\"]\"", jk, temp_var); if (!strncmp("L2", temp_var, strlen("L2"))) { cache_level = 0; } else { cache_level = 1; } } if(!strncmp("-Print level", line, strlen("-Print level"))) { sscanf(line, "-Print l%[^\"]\"%[^\"]\"", jk, temp_var); if (!strncmp("DETAILED", temp_var, strlen("DETAILED"))) { print_detail = 1; } else { print_detail = 0; } } if(!strncmp("-Add ECC", line, strlen("-Add ECC"))) { sscanf(line, "-Add ECC %[^\"]\"%[^\"]\"", jk, temp_var); if (!strncmp("true", temp_var, strlen("true"))) { add_ecc_b_ = true; } else { add_ecc_b_ = false; } } if(!strncmp("-CLDriver vertical", line, strlen("-CLDriver vertical"))) { sscanf(line, "-CLDriver vertical %[^\"]\"%[^\"]\"", jk, temp_var); if (!strncmp("true", temp_var, strlen("true"))) { cl_vertical = true; } else { cl_vertical = false; } } if(!strncmp("-Array Power Gating", line, strlen("-Array Power Gating"))) { sscanf(line, "-Array Power Gating %[^\"]\"%[^\"]\"", jk, temp_var); if (!strncmp("true", temp_var, strlen("true"))) { array_power_gated = true; } else { array_power_gated = false; } } if(!strncmp("-Bitline floating", line, strlen("-Bitline floating"))) { sscanf(line, "-Bitline floating %[^\"]\"%[^\"]\"", jk, temp_var); if (!strncmp("true", temp_var, strlen("true"))) { bitline_floating = true; } else { bitline_floating = false; } } if(!strncmp("-WL Power Gating", line, strlen("-WL Power Gating"))) { sscanf(line, "-WL Power Gating %[^\"]\"%[^\"]\"", jk, temp_var); if (!strncmp("true", temp_var, strlen("true"))) { wl_power_gated = true; } else { wl_power_gated = false; } } if(!strncmp("-CL Power Gating", line, strlen("-CL Power Gating"))) { sscanf(line, "-CL Power Gating %[^\"]\"%[^\"]\"", jk, temp_var); if (!strncmp("true", temp_var, strlen("true"))) { cl_power_gated = true; } else { cl_power_gated = false; } } if(!strncmp("-Interconnect Power Gating", line, strlen("-Interconnect Power Gating"))) { sscanf(line, "-Interconnect Power Gating %[^\"]\"%[^\"]\"", jk, temp_var); if (!strncmp("true", temp_var, strlen("true"))) { interconect_power_gated = true; } else { interconect_power_gated = false; } } if(!strncmp("-Power Gating Performance Loss", line, strlen("-Power Gating Performance Loss"))) { sscanf(line, "-Power Gating Performance Loss %lf", &(perfloss)); continue; } if(!strncmp("-Power Gating", line, strlen("-Power Gating"))) { sscanf(line, "-Power Gating %[^\"]\"%[^\"]\"", jk, temp_var); if (!strncmp("true", temp_var, strlen("true"))) { power_gating = true; } else { power_gating = false; } } if(!strncmp("-Long channel devices", line, strlen("-Long channel devices"))) { sscanf(line, "-Long channel devices %[^\"]\"%[^\"]\"", jk, temp_var); if (!strncmp("true", temp_var, strlen("true"))) { long_channel_device = true; } else { long_channel_device = false; } } if(!strncmp("-Print input parameters", line, strlen("-Print input parameters"))) { sscanf(line, "-Print input %[^\"]\"%[^\"]\"", jk, temp_var); if (!strncmp("true", temp_var, strlen("true"))) { print_input_args = true; } else { print_input_args = false; } } if(!strncmp("-Force cache config", line, strlen("-Force cache config"))) { sscanf(line, "-Force cache %[^\"]\"%[^\"]\"", jk, temp_var); if (!strncmp("true", temp_var, strlen("true"))) { force_cache_config = true; } else { force_cache_config = false; } } if(!strncmp("-Ndbl", line, strlen("-Ndbl"))) { sscanf(line, "-Ndbl %d\n", &(ndbl)); continue; } if(!strncmp("-Ndwl", line, strlen("-Ndwl"))) { sscanf(line, "-Ndwl %d\n", &(ndwl)); continue; } if(!strncmp("-Nspd", line, strlen("-Nspd"))) { sscanf(line, "-Nspd %d\n", &(nspd)); continue; } if(!strncmp("-Ndsam1", line, strlen("-Ndsam1"))) { sscanf(line, "-Ndsam1 %d\n", &(ndsam1)); continue; } if(!strncmp("-Ndsam2", line, strlen("-Ndsam2"))) { sscanf(line, "-Ndsam2 %d\n", &(ndsam2)); continue; } if(!strncmp("-Ndcm", line, strlen("-Ndcm"))) { sscanf(line, "-Ndcm %d\n", &(ndcm)); continue; } } rpters_in_htree = true; fclose(fp); } void InputParameter::display_ip() { cout << "Cache size : " << cache_sz << endl; cout << "Block size : " << line_sz << endl; cout << "Associativity : " << assoc << endl; cout << "Read only ports : " << num_rd_ports << endl; cout << "Write only ports : " << num_wr_ports << endl; cout << "Read write ports : " << num_rw_ports << endl; cout << "Single ended read ports : " << num_se_rd_ports << endl; if (fully_assoc||pure_cam) { cout << "Search ports : " << num_search_ports << endl; } cout << "Cache banks (UCA) : " << nbanks << endl; cout << "Technology : " << F_sz_um << endl; cout << "User specified HP Vdd (v)? : " << std::boolalpha << specific_hp_vdd << endl; if (specific_hp_vdd) { cout << "User defined HP Vdd (v) : " << hp_Vdd << endl; } cout << "User specified LSTP Vdd (v)? : " << std::boolalpha << specific_lstp_vdd << endl; if (specific_lstp_vdd) { cout << "User defined HP Vdd (v) : " << lstp_Vdd << endl; } cout << "User specified LOP Vdd (v)? : " << std::boolalpha << specific_lop_vdd << endl; if (specific_lop_vdd) { cout << "User defined HP Vdd (v) : " << lop_Vdd << endl; } cout << "Temperature : " << temp << endl; cout << "Tag size : " << tag_w << endl; if (is_cache) { cout << "array type : " << "Cache" << endl; } if (pure_ram) { cout << "array type : " << "Scratch RAM" << endl; } if (pure_cam) { cout << "array type : " << "CAM" << endl; } cout << "Model as memory : " << is_main_mem << endl; cout << "Access mode : " << access_mode << endl; cout << "Data array cell type : " << data_arr_ram_cell_tech_type << endl; cout << "Data array peripheral type : " << data_arr_peri_global_tech_type << endl; cout << "Tag array cell type : " << tag_arr_ram_cell_tech_type << endl; cout << "Tag array peripheral type : " << tag_arr_peri_global_tech_type << endl; cout << "Optimization target : " << ed << endl; cout << "Design objective (UCA wt) : " << delay_wt << " " << dynamic_power_wt << " " << leakage_power_wt << " " << cycle_time_wt << " " << area_wt << endl; cout << "Design objective (UCA dev) : " << delay_dev << " " << dynamic_power_dev << " " << leakage_power_dev << " " << cycle_time_dev << " " << area_dev << endl; if (nuca) { cout << "Cores : " << cores << endl; cout << "Design objective (NUCA wt) : " << delay_wt_nuca << " " << dynamic_power_wt_nuca << " " << leakage_power_wt_nuca << " " << cycle_time_wt_nuca << " " << area_wt_nuca << endl; cout << "Design objective (NUCA dev) : " << delay_dev_nuca << " " << dynamic_power_dev_nuca << " " << leakage_power_dev_nuca << " " << cycle_time_dev_nuca << " " << area_dev_nuca << endl; } cout << "Cache model : " << nuca << endl; cout << "Nuca bank : " << nuca_bank_count << endl; cout << "Wire inside mat : " << wire_is_mat_type << endl; cout << "Wire outside mat : " << wire_os_mat_type << endl; cout << "Interconnect projection : " << ic_proj_type << endl; cout << "Wire signalling : " << force_wiretype << endl; cout << "Print level : " << print_detail << endl; cout << "ECC overhead : " << add_ecc_b_ << endl; cout << "Page size : " << page_sz_bits << endl; cout << "Burst length : " << burst_len << endl; cout << "Internal prefetch width : " << int_prefetch_w << endl; cout << "Force cache config : " << g_ip->force_cache_config << endl; if (g_ip->force_cache_config) { cout << "Ndwl : " << g_ip->ndwl << endl; cout << "Ndbl : " << g_ip->ndbl << endl; cout << "Nspd : " << g_ip->nspd << endl; cout << "Ndcm : " << g_ip->ndcm << endl; cout << "Ndsam1 : " << g_ip->ndsam1 << endl; cout << "Ndsam2 : " << g_ip->ndsam2 << endl; } // cout << "Placing subarray out driver vertical? : " << g_ip->cl_vertical << endl; } powerComponents operator+(const powerComponents & x, const powerComponents & y) { powerComponents z; z.dynamic = x.dynamic + y.dynamic; z.leakage = x.leakage + y.leakage; z.gate_leakage = x.gate_leakage + y.gate_leakage; z.short_circuit = x.short_circuit + y.short_circuit; z.longer_channel_leakage = x.longer_channel_leakage + y.longer_channel_leakage; z.power_gated_leakage = x.power_gated_leakage + y.power_gated_leakage; z.power_gated_with_long_channel_leakage = x.power_gated_with_long_channel_leakage + y.power_gated_with_long_channel_leakage; return z; } powerComponents operator*(const powerComponents & x, double const * const y) { powerComponents z; z.dynamic = x.dynamic*y[0]; z.leakage = x.leakage*y[1]; z.gate_leakage = x.gate_leakage*y[2]; z.short_circuit = x.short_circuit*y[3]; z.longer_channel_leakage = x.longer_channel_leakage*y[1];//longer channel leakage has the same behavior as normal leakage z.power_gated_leakage = x.power_gated_leakage*y[1];//power_gated_leakage has the same behavior as normal leakage z.power_gated_with_long_channel_leakage = x.power_gated_with_long_channel_leakage*y[1];//power_gated_with_long_channel_leakage has the same behavior as normal leakage return z; } powerDef operator+(const powerDef & x, const powerDef & y) { powerDef z; z.readOp = x.readOp + y.readOp; z.writeOp = x.writeOp + y.writeOp; z.searchOp = x.searchOp + y.searchOp; return z; } powerDef operator*(const powerDef & x, double const * const y) { powerDef z; z.readOp = x.readOp*y; z.writeOp = x.writeOp*y; z.searchOp = x.searchOp*y; return z; } uca_org_t cacti_interface(const string & infile_name) { uca_org_t fin_res; //uca_org_t result; fin_res.valid = false; g_ip = new InputParameter(); g_ip->parse_cfg(infile_name); if(!g_ip->error_checking()) exit(0); if (g_ip->print_input_args) g_ip->display_ip(); init_tech_params(g_ip->F_sz_um, false);//this init is for initializing wires Wire winit; // Do not delete this line. It initializes wires. // g_tp.peri_global.display(); // g_tp.sram_cell.display(); // For HighRadix Only // //// Wire wirea(g_ip->wt, 1000); // //// wirea.print_wire(); // //// cout << "Wire Area " << wirea.area.get_area() << " sq. u" << endl; // // winit.print_wire(); // // // HighRadix *hr; // hr = new HighRadix(); // hr->compute_power(); // hr->print_router(); // exit(0); // // double sub_switch_sz = 2; // double rows = 32; // for (int i=0; i<6; i++) { // sub_switch_sz = pow(2, i); // rows = 64/sub_switch_sz; // hr = new HighRadix(sub_switch_sz, rows, .8/* freq */, 64, 2, 64, 0.7); // hr->compute_power(); // hr->print_router(); // delete hr; // } // // HighRadix yarc; // // yarc.compute_power(); // // yarc.print_router(); // winit.print_wire(); // exit(0); // For HighRadix Only End if (g_ip->nuca == 1) { Nuca n(&g_tp.peri_global); n.sim_nuca(); } //g_ip->display_ip(); solve(&fin_res); // output_UCA(&fin_res); // Wire::print_wire(); output_data_csv(fin_res); if (!g_ip->dvs_voltage.empty()) { update_dvs(&fin_res); } if (g_ip->power_gating) { update_pg(&fin_res);//this is needed for compute area overhead of power-gating, even the gated power is calculated together un-gated leakage } output_UCA(&fin_res); Wire wprint;//reset wires to original configuration as in *.cfg file (dvs level 0) Wire::print_wire(); delete (g_ip); return fin_res; } //cacti6.5's plain interface, please keep !!! uca_org_t cacti_interface( int cache_size, int line_size, int associativity, int rw_ports, int excl_read_ports, int excl_write_ports, int single_ended_read_ports, int banks, double tech_node, // in nm int page_sz, int burst_length, int pre_width, int output_width, int specific_tag, int tag_width, int access_mode, //0 normal, 1 seq, 2 fast int cache, //scratch ram or cache int main_mem, int obj_func_delay, int obj_func_dynamic_power, int obj_func_leakage_power, int obj_func_area, int obj_func_cycle_time, int dev_func_delay, int dev_func_dynamic_power, int dev_func_leakage_power, int dev_func_area, int dev_func_cycle_time, int ed_ed2_none, // 0 - ED, 1 - ED^2, 2 - use weight and deviate int temp, int wt, //0 - default(search across everything), 1 - global, 2 - 5% delay penalty, 3 - 10%, 4 - 20 %, 5 - 30%, 6 - low-swing int data_arr_ram_cell_tech_flavor_in, // 0-4 int data_arr_peri_global_tech_flavor_in, int tag_arr_ram_cell_tech_flavor_in, int tag_arr_peri_global_tech_flavor_in, int interconnect_projection_type_in, // 0 - aggressive, 1 - normal int wire_inside_mat_type_in, int wire_outside_mat_type_in, int is_nuca, // 0 - UCA, 1 - NUCA int core_count, int cache_level, // 0 - L2, 1 - L3 int nuca_bank_count, int nuca_obj_func_delay, int nuca_obj_func_dynamic_power, int nuca_obj_func_leakage_power, int nuca_obj_func_area, int nuca_obj_func_cycle_time, int nuca_dev_func_delay, int nuca_dev_func_dynamic_power, int nuca_dev_func_leakage_power, int nuca_dev_func_area, int nuca_dev_func_cycle_time, int REPEATERS_IN_HTREE_SEGMENTS_in,//TODO for now only wires with repeaters are supported int p_input) { g_ip = new InputParameter(); g_ip->add_ecc_b_ = true; g_ip->data_arr_ram_cell_tech_type = data_arr_ram_cell_tech_flavor_in; g_ip->data_arr_peri_global_tech_type = data_arr_peri_global_tech_flavor_in; g_ip->tag_arr_ram_cell_tech_type = tag_arr_ram_cell_tech_flavor_in; g_ip->tag_arr_peri_global_tech_type = tag_arr_peri_global_tech_flavor_in; g_ip->ic_proj_type = interconnect_projection_type_in; g_ip->wire_is_mat_type = wire_inside_mat_type_in; g_ip->wire_os_mat_type = wire_outside_mat_type_in; g_ip->burst_len = burst_length; g_ip->int_prefetch_w = pre_width; g_ip->page_sz_bits = page_sz; g_ip->cache_sz = cache_size; g_ip->line_sz = line_size; g_ip->assoc = associativity; g_ip->nbanks = banks; g_ip->out_w = output_width; g_ip->specific_tag = specific_tag; if (tag_width == 0) { g_ip->tag_w = 42; } else { g_ip->tag_w = tag_width; } g_ip->access_mode = access_mode; g_ip->delay_wt = obj_func_delay; g_ip->dynamic_power_wt = obj_func_dynamic_power; g_ip->leakage_power_wt = obj_func_leakage_power; g_ip->area_wt = obj_func_area; g_ip->cycle_time_wt = obj_func_cycle_time; g_ip->delay_dev = dev_func_delay; g_ip->dynamic_power_dev = dev_func_dynamic_power; g_ip->leakage_power_dev = dev_func_leakage_power; g_ip->area_dev = dev_func_area; g_ip->cycle_time_dev = dev_func_cycle_time; g_ip->ed = ed_ed2_none; switch(wt) { case (0): g_ip->force_wiretype = 0; g_ip->wt = Global; break; case (1): g_ip->force_wiretype = 1; g_ip->wt = Global; break; case (2): g_ip->force_wiretype = 1; g_ip->wt = Global_5; break; case (3): g_ip->force_wiretype = 1; g_ip->wt = Global_10; break; case (4): g_ip->force_wiretype = 1; g_ip->wt = Global_20; break; case (5): g_ip->force_wiretype = 1; g_ip->wt = Global_30; break; case (6): g_ip->force_wiretype = 1; g_ip->wt = Low_swing; break; default: cout << "Unknown wire type!\n"; exit(0); } g_ip->delay_wt_nuca = nuca_obj_func_delay; g_ip->dynamic_power_wt_nuca = nuca_obj_func_dynamic_power; g_ip->leakage_power_wt_nuca = nuca_obj_func_leakage_power; g_ip->area_wt_nuca = nuca_obj_func_area; g_ip->cycle_time_wt_nuca = nuca_obj_func_cycle_time; g_ip->delay_dev_nuca = dev_func_delay; g_ip->dynamic_power_dev_nuca = nuca_dev_func_dynamic_power; g_ip->leakage_power_dev_nuca = nuca_dev_func_leakage_power; g_ip->area_dev_nuca = nuca_dev_func_area; g_ip->cycle_time_dev_nuca = nuca_dev_func_cycle_time; g_ip->nuca = is_nuca; g_ip->nuca_bank_count = nuca_bank_count; if(nuca_bank_count > 0) { g_ip->force_nuca_bank = 1; } g_ip->cores = core_count; g_ip->cache_level = cache_level; g_ip->temp = temp; g_ip->F_sz_nm = tech_node; g_ip->F_sz_um = tech_node / 1000; g_ip->is_main_mem = (main_mem != 0) ? true : false; g_ip->is_cache = (cache != 0) ? true : false; g_ip->rpters_in_htree = (REPEATERS_IN_HTREE_SEGMENTS_in != 0) ? true : false; g_ip->num_rw_ports = rw_ports; g_ip->num_rd_ports = excl_read_ports; g_ip->num_wr_ports = excl_write_ports; g_ip->num_se_rd_ports = single_ended_read_ports; g_ip->print_detail = 1; g_ip->nuca = 0; g_ip->wt = Global_5; g_ip->force_cache_config = false; g_ip->force_wiretype = false; g_ip->print_input_args = p_input; uca_org_t fin_res; fin_res.valid = false; if (g_ip->error_checking() == false) exit(0); if (g_ip->print_input_args) g_ip->display_ip(); init_tech_params(g_ip->F_sz_um, false); Wire winit; // Do not delete this line. It initializes wires. if (g_ip->nuca == 1) { Nuca n(&g_tp.peri_global); n.sim_nuca(); } solve(&fin_res); output_UCA(&fin_res); delete (g_ip); return fin_res; } //McPAT's plain interface, please keep !!! uca_org_t cacti_interface( int cache_size, int line_size, int associativity, int rw_ports, int excl_read_ports,// para5 int excl_write_ports, int single_ended_read_ports, int search_ports, int banks, double tech_node,//para10 int output_width, int specific_tag, int tag_width, int access_mode, int cache, //para15 int main_mem, int obj_func_delay, int obj_func_dynamic_power, int obj_func_leakage_power, int obj_func_cycle_time, //para20 int obj_func_area, int dev_func_delay, int dev_func_dynamic_power, int dev_func_leakage_power, int dev_func_area, //para25 int dev_func_cycle_time, int ed_ed2_none, // 0 - ED, 1 - ED^2, 2 - use weight and deviate int temp, int wt, //0 - default(search across everything), 1 - global, 2 - 5% delay penalty, 3 - 10%, 4 - 20 %, 5 - 30%, 6 - low-swing int data_arr_ram_cell_tech_flavor_in,//para30 int data_arr_peri_global_tech_flavor_in, int tag_arr_ram_cell_tech_flavor_in, int tag_arr_peri_global_tech_flavor_in, int interconnect_projection_type_in, int wire_inside_mat_type_in,//para35 int wire_outside_mat_type_in, int REPEATERS_IN_HTREE_SEGMENTS_in, int VERTICAL_HTREE_WIRES_OVER_THE_ARRAY_in, int BROADCAST_ADDR_DATAIN_OVER_VERTICAL_HTREES_in, int PAGE_SIZE_BITS_in,//para40 int BURST_LENGTH_in, int INTERNAL_PREFETCH_WIDTH_in, int force_wiretype, int wiretype, int force_config,//para45 int ndwl, int ndbl, int nspd, int ndcm, int ndsam1,//para50 int ndsam2, int ecc) { g_ip = new InputParameter(); uca_org_t fin_res; fin_res.valid = false; g_ip->data_arr_ram_cell_tech_type = data_arr_ram_cell_tech_flavor_in; g_ip->data_arr_peri_global_tech_type = data_arr_peri_global_tech_flavor_in; g_ip->tag_arr_ram_cell_tech_type = tag_arr_ram_cell_tech_flavor_in; g_ip->tag_arr_peri_global_tech_type = tag_arr_peri_global_tech_flavor_in; g_ip->ic_proj_type = interconnect_projection_type_in; g_ip->wire_is_mat_type = wire_inside_mat_type_in; g_ip->wire_os_mat_type = wire_outside_mat_type_in; g_ip->burst_len = BURST_LENGTH_in; g_ip->int_prefetch_w = INTERNAL_PREFETCH_WIDTH_in; g_ip->page_sz_bits = PAGE_SIZE_BITS_in; g_ip->cache_sz = cache_size; g_ip->line_sz = line_size; g_ip->assoc = associativity; g_ip->nbanks = banks; g_ip->out_w = output_width; g_ip->specific_tag = specific_tag; if (specific_tag == 0) { g_ip->tag_w = 42; } else { g_ip->tag_w = tag_width; } g_ip->access_mode = access_mode; g_ip->delay_wt = obj_func_delay; g_ip->dynamic_power_wt = obj_func_dynamic_power; g_ip->leakage_power_wt = obj_func_leakage_power; g_ip->area_wt = obj_func_area; g_ip->cycle_time_wt = obj_func_cycle_time; g_ip->delay_dev = dev_func_delay; g_ip->dynamic_power_dev = dev_func_dynamic_power; g_ip->leakage_power_dev = dev_func_leakage_power; g_ip->area_dev = dev_func_area; g_ip->cycle_time_dev = dev_func_cycle_time; g_ip->temp = temp; g_ip->ed = ed_ed2_none; g_ip->F_sz_nm = tech_node; g_ip->F_sz_um = tech_node / 1000; g_ip->is_main_mem = (main_mem != 0) ? true : false; g_ip->is_cache = (cache ==1) ? true : false; g_ip->pure_ram = (cache ==0) ? true : false; g_ip->pure_cam = (cache ==2) ? true : false; g_ip->rpters_in_htree = (REPEATERS_IN_HTREE_SEGMENTS_in != 0) ? true : false; g_ip->ver_htree_wires_over_array = VERTICAL_HTREE_WIRES_OVER_THE_ARRAY_in; g_ip->broadcast_addr_din_over_ver_htrees = BROADCAST_ADDR_DATAIN_OVER_VERTICAL_HTREES_in; g_ip->num_rw_ports = rw_ports; g_ip->num_rd_ports = excl_read_ports; g_ip->num_wr_ports = excl_write_ports; g_ip->num_se_rd_ports = single_ended_read_ports; g_ip->num_search_ports = search_ports; g_ip->print_detail = 1; g_ip->nuca = 0; if (force_wiretype == 0) { g_ip->wt = Global; g_ip->force_wiretype = false; } else { g_ip->force_wiretype = true; if (wiretype==10) { g_ip->wt = Global_10; } if (wiretype==20) { g_ip->wt = Global_20; } if (wiretype==30) { g_ip->wt = Global_30; } if (wiretype==5) { g_ip->wt = Global_5; } if (wiretype==0) { g_ip->wt = Low_swing; } } //g_ip->wt = Global_5; if (force_config == 0) { g_ip->force_cache_config = false; } else { g_ip->force_cache_config = true; g_ip->ndbl=ndbl; g_ip->ndwl=ndwl; g_ip->nspd=nspd; g_ip->ndcm=ndcm; g_ip->ndsam1=ndsam1; g_ip->ndsam2=ndsam2; } if (ecc==0){ g_ip->add_ecc_b_=false; } else { g_ip->add_ecc_b_=true; } if(!g_ip->error_checking()) exit(0); init_tech_params(g_ip->F_sz_um, false); Wire winit; // Do not delete this line. It initializes wires. g_ip->display_ip(); solve(&fin_res); output_UCA(&fin_res); output_data_csv(fin_res); delete (g_ip); return fin_res; } bool InputParameter::error_checking() { int A; bool seq_access = false; fast_access = true; fully_assoc = false; switch (access_mode) { case 0: seq_access = false; fast_access = false; break; case 1: seq_access = true; fast_access = false; break; case 2: seq_access = false; fast_access = true; break; } if(is_main_mem) { if(ic_proj_type == 0) { cerr << "DRAM model supports only conservative interconnect projection!\n\n"; return false; } } uint32_t B = line_sz; if (B < 1) { cerr << "Block size must >= 1" << endl; return false; } else if (B*8 < out_w) { cerr << "Block size must be at least " << out_w/8 << endl; return false; } if (F_sz_um <= 0) { cerr << "Feature size must be > 0" << endl; return false; } else if (F_sz_um > 0.181) { cerr << "Feature size must be <= 180 nm" << endl; return false; }else if (F_sz_um >0.091 && (data_arr_ram_cell_tech_type!= itrs_hp || tag_arr_ram_cell_tech_type!= itrs_hp || data_arr_peri_global_tech_type != itrs_hp ||tag_arr_peri_global_tech_type != itrs_hp)) { cerr << "Feature size from 90nm to 180 nm only support the ITRS HP device type" << endl; return false; } uint32_t RWP = num_rw_ports; uint32_t ERP = num_rd_ports; uint32_t EWP = num_wr_ports; uint32_t NSER = num_se_rd_ports; uint32_t SCHP = num_search_ports; //TODO: revisit this. This is an important feature. Sheng thought this should be used // // If multiple banks and multiple ports are specified, then if number of ports is less than or equal to // // the number of banks, we assume that the multiple ports are implemented via the multiple banks. // // In such a case we assume that each bank has 1 RWP port. // if ((RWP + ERP + EWP) <= nbanks && nbanks>1) // { // RWP = 1; // ERP = 0; // EWP = 0; // NSER = 0; // } // else if ((RWP < 0) || (EWP < 0) || (ERP < 0)) // { // cerr << "Ports must >=0" << endl; // return false; // } // else if (RWP > 2) // { // cerr << "Maximum of 2 read/write ports" << endl; // return false; // } // else if ((RWP+ERP+EWP) < 1) // Changed to new implementation: // The number of ports specified at input is per bank if ((RWP+ERP+EWP) < 1) { cerr << "Must have at least one port" << endl; return false; } if (is_pow2(nbanks) == false) { cerr << "Number of subbanks should be greater than or equal to 1 and should be a power of 2" << endl; return false; } int C = cache_sz/nbanks; if (C < 64) { cerr << "Cache size must >=64" << endl; return false; } //TODO: revisit this // if (pure_ram==true && assoc!=1) // { // cerr << "Pure RAM must have assoc as 1" << endl; // return false; // } //fully assoc and cam check if (is_cache && assoc==0) fully_assoc =true; else fully_assoc = false; if (pure_cam==true && assoc!=0) { cerr << "Pure CAM must have associativity as 0" << endl; return false; } if (assoc==0 && (pure_cam==false && is_cache ==false)) { cerr << "Only CAM or Fully associative cache can have associativity as 0" << endl; return false; } if ((fully_assoc==true || pure_cam==true) && (data_arr_ram_cell_tech_type!= tag_arr_ram_cell_tech_type || data_arr_peri_global_tech_type != tag_arr_peri_global_tech_type )) { cerr << "CAM and fully associative cache must have same device type for both data and tag array" << endl; return false; } if ((fully_assoc==true || pure_cam==true) && (data_arr_ram_cell_tech_type== lp_dram || data_arr_ram_cell_tech_type== comm_dram)) { cerr << "DRAM based CAM and fully associative cache are not supported" << endl; return false; } if ((fully_assoc==true || pure_cam==true) && (is_main_mem==true)) { cerr << "CAM and fully associative cache cannot be as main memory" << endl; return false; } if ((fully_assoc || pure_cam) && SCHP<1) { cerr << "CAM and fully associative must have at least 1 search port" << endl; return false; } if (RWP==0 && ERP==0 && SCHP>0 && ((fully_assoc || pure_cam))) { ERP=SCHP; } // if ((!(fully_assoc || pure_cam)) && SCHP>=1) // { // cerr << "None CAM and fully associative cannot have search ports" << endl; // return false; // } if (assoc == 0) { A = C/B; //fully_assoc = true; } else { if (assoc == 1) { A = 1; //fully_assoc = false; } else { //fully_assoc = false; A = assoc; if (is_pow2(A) == false) { cerr << "Associativity must be a power of 2" << endl; return false; } } } if (C/(B*A) <= 1 && assoc!=0) { cerr << "Number of sets is too small: " << endl; cerr << " Need to either increase cache size, or decrease associativity or block size" << endl; cerr << " (or use fully associative cache)" << endl; return false; } block_sz = B; /*dt: testing sequential access mode*/ if(seq_access) { tag_assoc = A; data_assoc = 1; is_seq_acc = true; } else { tag_assoc = A; data_assoc = A; is_seq_acc = false; } if (assoc==0) { data_assoc = 1; } num_rw_ports = RWP; num_rd_ports = ERP; num_wr_ports = EWP; num_se_rd_ports = NSER; if (!(fully_assoc || pure_cam)) num_search_ports = 0; nsets = C/(B*A); if (temp < 300 || temp > 400 || temp%10 != 0) { cerr << temp << " Temperature must be between 300 and 400 Kelvin and multiple of 10." << endl; return false; } if (nsets < 1) { cerr << "Less than one set..." << endl; return false; } // power_gating = (array_power_gated // || bitline_floating // || wl_power_gated // || cl_power_gated // || interconect_power_gated)?true:false; if (power_gating) { array_power_gated = true; bitline_floating = true; wl_power_gated = true; cl_power_gated = true; interconect_power_gated = true; } else { array_power_gated = false; bitline_floating = false; wl_power_gated = false; cl_power_gated = false; interconect_power_gated = false; } // if (power_gating && (!dvs_voltage.empty())) // { // cerr << "Power gating and DVS cannot be active simultaneously, please model them in two runs.\n\n"; // return false; // } if (power_gating && (pure_cam||fully_assoc)) { cerr << "Power gating in CAM is not supported yet.\n\n"<< endl; return false; } if (power_gating && (is_main_mem ||data_arr_ram_cell_tech_type== lp_dram ||data_arr_ram_cell_tech_type== comm_dram ||tag_arr_ram_cell_tech_type== lp_dram ||tag_arr_ram_cell_tech_type== comm_dram ||data_arr_peri_global_tech_type== lp_dram ||data_arr_peri_global_tech_type== comm_dram ||tag_arr_peri_global_tech_type== lp_dram || tag_arr_peri_global_tech_type== comm_dram)) { cerr << "Power gating in DRAM is not supported. \n\n"<< endl; return false; } if (long_channel_device && (is_main_mem ||data_arr_ram_cell_tech_type== lp_dram ||data_arr_ram_cell_tech_type== comm_dram ||tag_arr_ram_cell_tech_type== lp_dram ||tag_arr_ram_cell_tech_type== comm_dram ||data_arr_peri_global_tech_type== lp_dram ||data_arr_peri_global_tech_type== comm_dram ||tag_arr_peri_global_tech_type== lp_dram || tag_arr_peri_global_tech_type== comm_dram)) { cerr << "Long Channel Device in DRAM is not supported. \n\n"<< endl; return false; } if ((!dvs_voltage.empty()) && (is_main_mem ||data_arr_ram_cell_tech_type== lp_dram ||data_arr_ram_cell_tech_type== comm_dram ||tag_arr_ram_cell_tech_type== lp_dram ||tag_arr_ram_cell_tech_type== comm_dram ||data_arr_peri_global_tech_type== lp_dram ||data_arr_peri_global_tech_type== comm_dram ||tag_arr_peri_global_tech_type== lp_dram || tag_arr_peri_global_tech_type== comm_dram)) { cerr << "DVS in DRAM is not supported. \n\n"<< endl; return false; } // if (power_gating && (specific_hp_vdd // || specific_lstp_vdd // || specific_lop_vdd)) // { // cerr << "Default Vdd is recommended when enabling power gating.\n\n"<< endl; // return false; // } if ((!dvs_voltage.empty())&& ((data_arr_ram_cell_tech_type !=data_arr_peri_global_tech_type) ||(tag_arr_peri_global_tech_type !=tag_arr_ram_cell_tech_type) ||(data_arr_ram_cell_tech_type !=tag_arr_ram_cell_tech_type))) { cerr << "Same device types is recommended for tag/data/cell/peripheral for DVS. Same DVS voltage will be applied to different device types\n\n"; return false; } return true; } void output_data_csv(const uca_org_t & fin_res) { //TODO: the csv output should remain fstream file("out.csv", ios::in); bool print_index = file.fail(); file.close(); file.open("out.csv", ios::out|ios::app); if (file.fail() == true) { cerr << "File out.csv could not be opened successfully" << endl; } else { if (print_index == true) { file << "Tech node (nm), "; file << "Capacity (bytes), "; file << "Number of banks, "; file << "Associativity, "; file << "Output width (bits), "; file << "Access time (ns), "; file << "Random cycle time (ns), "; // file << "Multisubbank interleave cycle time (ns), "; // file << "Delay request network (ns), "; // file << "Delay inside mat (ns), "; // file << "Delay reply network (ns), "; // file << "Tag array access time (ns), "; // file << "Data array access time (ns), "; // file << "Refresh period (microsec), "; // file << "DRAM array availability (%), "; file << "Dynamic search energy (nJ), "; file << "Dynamic read energy (nJ), "; file << "Dynamic write energy (nJ), "; // file << "Tag Dynamic read energy (nJ), "; // file << "Data Dynamic read energy (nJ), "; // file << "Dynamic read power (mW), "; file << "Standby leakage per bank(mW), "; // file << "Leakage per bank with leak power management (mW), "; // file << "Leakage per bank with leak power management (mW), "; // file << "Refresh power as percentage of standby leakage, "; file << "Area (mm2), "; file << "Ndwl, "; file << "Ndbl, "; file << "Nspd, "; file << "Ndcm, "; file << "Ndsam_level_1, "; file << "Ndsam_level_2, "; file << "Data arrary area efficiency %, "; file << "Ntwl, "; file << "Ntbl, "; file << "Ntspd, "; file << "Ntcm, "; file << "Ntsam_level_1, "; file << "Ntsam_level_2, "; file << "Tag arrary area efficiency %, "; // file << "Resistance per unit micron (ohm-micron), "; // file << "Capacitance per unit micron (fF per micron), "; // file << "Unit-length wire delay (ps), "; // file << "FO4 delay (ps), "; // file << "delay route to bank (including crossb delay) (ps), "; // file << "Crossbar delay (ps), "; // file << "Dyn read energy per access from closed page (nJ), "; // file << "Dyn read energy per access from open page (nJ), "; // file << "Leak power of an subbank with page closed (mW), "; // file << "Leak power of a subbank with page open (mW), "; // file << "Leak power of request and reply networks (mW), "; // file << "Number of subbanks, "; // file << "Page size in bits, "; // file << "Activate power, "; // file << "Read power, "; // file << "Write power, "; // file << "Precharge power, "; // file << "tRCD, "; // file << "CAS latency, "; // file << "Precharge delay, "; // file << "Perc dyn energy bitlines, "; // file << "perc dyn energy wordlines, "; // file << "perc dyn energy outside mat, "; // file << "Area opt (perc), "; // file << "Delay opt (perc), "; // file << "Repeater opt (perc), "; // file << "Aspect ratio"; file << endl; } file << g_ip->F_sz_nm << ", "; file << g_ip->cache_sz << ", "; file << g_ip->nbanks << ", "; file << g_ip->tag_assoc << ", "; file << g_ip->out_w << ", "; file << fin_res.access_time*1e+9 << ", "; file << fin_res.cycle_time*1e+9 << ", "; // file << fin_res.data_array2->multisubbank_interleave_cycle_time*1e+9 << ", "; // file << fin_res.data_array2->delay_request_network*1e+9 << ", "; // file << fin_res.data_array2->delay_inside_mat*1e+9 << ", "; // file << fin_res.data_array2.delay_reply_network*1e+9 << ", "; // if (!(g_ip->fully_assoc || g_ip->pure_cam || g_ip->pure_ram)) // { // file << fin_res.tag_array2->access_time*1e+9 << ", "; // } // else // { // file << 0 << ", "; // } // file << fin_res.data_array2->access_time*1e+9 << ", "; // file << fin_res.data_array2->dram_refresh_period*1e+6 << ", "; // file << fin_res.data_array2->dram_array_availability << ", "; if (g_ip->fully_assoc || g_ip->pure_cam) { file << fin_res.power.searchOp.dynamic*1e+9 << ", "; } else { file << "N/A" << ", "; } file << fin_res.power.readOp.dynamic*1e+9 << ", "; file << fin_res.power.writeOp.dynamic*1e+9 << ", "; // if (!(g_ip->fully_assoc || g_ip->pure_cam || g_ip->pure_ram)) // { // file << fin_res.tag_array2->power.readOp.dynamic*1e+9 << ", "; // } // else // { // file << "NA" << ", "; // } // file << fin_res.data_array2->power.readOp.dynamic*1e+9 << ", "; // if (g_ip->fully_assoc || g_ip->pure_cam) // { // file << fin_res.power.searchOp.dynamic*1000/fin_res.cycle_time << ", "; // } // else // { // file << fin_res.power.readOp.dynamic*1000/fin_res.cycle_time << ", "; // } file <<( fin_res.power.readOp.leakage + fin_res.power.readOp.gate_leakage )*1000 << ", "; // file << fin_res.leak_power_with_sleep_transistors_in_mats*1000 << ", "; // file << fin_res.data_array.refresh_power / fin_res.data_array.total_power.readOp.leakage << ", "; file << fin_res.area*1e-6 << ", "; file << fin_res.data_array2->Ndwl << ", "; file << fin_res.data_array2->Ndbl << ", "; file << fin_res.data_array2->Nspd << ", "; file << fin_res.data_array2->deg_bl_muxing << ", "; file << fin_res.data_array2->Ndsam_lev_1 << ", "; file << fin_res.data_array2->Ndsam_lev_2 << ", "; file << fin_res.data_array2->area_efficiency << ", "; if (!(g_ip->fully_assoc || g_ip->pure_cam || g_ip->pure_ram)) { file << fin_res.tag_array2->Ndwl << ", "; file << fin_res.tag_array2->Ndbl << ", "; file << fin_res.tag_array2->Nspd << ", "; file << fin_res.tag_array2->deg_bl_muxing << ", "; file << fin_res.tag_array2->Ndsam_lev_1 << ", "; file << fin_res.tag_array2->Ndsam_lev_2 << ", "; file << fin_res.tag_array2->area_efficiency << ", "; } else { file << "N/A" << ", "; file << "N/A"<< ", "; file << "N/A" << ", "; file << "N/A" << ", "; file << "N/A" << ", "; file << "N/A" << ", "; file << "N/A" << ", "; } // file << g_tp.wire_inside_mat.R_per_um << ", "; // file << g_tp.wire_inside_mat.C_per_um / 1e-15 << ", "; // file << g_tp.unit_len_wire_del / 1e-12 << ", "; // file << g_tp.FO4 / 1e-12 << ", "; // file << fin_res.data_array.delay_route_to_bank / 1e-9 << ", "; // file << fin_res.data_array.delay_crossbar / 1e-9 << ", "; // file << fin_res.data_array.dyn_read_energy_from_closed_page / 1e-9 << ", "; // file << fin_res.data_array.dyn_read_energy_from_open_page / 1e-9 << ", "; // file << fin_res.data_array.leak_power_subbank_closed_page / 1e-3 << ", "; // file << fin_res.data_array.leak_power_subbank_open_page / 1e-3 << ", "; // file << fin_res.data_array.leak_power_request_and_reply_networks / 1e-3 << ", "; // file << fin_res.data_array.number_subbanks << ", " ; // file << fin_res.data_array.page_size_in_bits << ", " ; // file << fin_res.data_array.activate_energy * 1e9 << ", " ; // file << fin_res.data_array.read_energy * 1e9 << ", " ; // file << fin_res.data_array.write_energy * 1e9 << ", " ; // file << fin_res.data_array.precharge_energy * 1e9 << ", " ; // file << fin_res.data_array.trcd * 1e9 << ", " ; // file << fin_res.data_array.cas_latency * 1e9 << ", " ; // file << fin_res.data_array.precharge_delay * 1e9 << ", " ; // file << fin_res.data_array.all_banks_height / fin_res.data_array.all_banks_width; file<data_array2->long_channel_leakage_reduction_memcell + 0.2*fr->data_array2->long_channel_leakage_reduction_periperal);//TODO double areaoverhead, overhead_data, overhead_tag; double wakeup_E, wakeup_T, wakeup_E_data, wakeup_T_data, wakeup_E_tag, wakeup_T_tag; int dvs_levels = g_ip->dvs_voltage.size(); int i; bool dvs = !g_ip->dvs_voltage.empty(); // if (NUCA) if (0) { cout << "\n\n Detailed Bank Stats:\n"; cout << " Bank Size (bytes): %d\n" << (int) (g_ip->cache_sz); } else { if (g_ip->data_arr_ram_cell_tech_type == 3) { cout << "\n---------- CACTI-P, with new features: "<data_arr_ram_cell_tech_type == 4) { cout << "\n---------- CACTI-P, with new features: "<cache_sz) << endl; } cout << " Number of banks: " << (int) g_ip->nbanks << endl; if (g_ip->fully_assoc|| g_ip->pure_cam) cout << " Associativity: fully associative\n"; else { if (g_ip->tag_assoc == 1) cout << " Associativity: direct mapped\n"; else cout << " Associativity: " << g_ip->tag_assoc << endl; } cout << " Block size (bytes): " << g_ip->line_sz << endl; cout << " Read/write Ports: " << g_ip->num_rw_ports << endl; cout << " Read ports: " << g_ip->num_rd_ports << endl; cout << " Write ports: " << g_ip->num_wr_ports << endl; if (g_ip->fully_assoc|| g_ip->pure_cam) cout << " search ports: " << g_ip->num_search_ports << endl; cout << " Technology size (nm): " << g_ip->F_sz_nm << endl << endl; cout << " Access time (ns): " << fr->access_time*1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->access_time*1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout << endl; cout << " Cycle time (ns): " << fr->cycle_time*1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->cycle_time*1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; if (g_ip->data_arr_ram_cell_tech_type >= 4) { cout << " Precharge Delay (ns): " << fr->data_array2->precharge_delay*1e9 << endl; cout << " Activate Energy (nJ): " << fr->data_array2->activate_energy*1e9 << endl; cout << " Read Energy (nJ): " << fr->data_array2->read_energy*1e9 << endl; cout << " Write Energy (nJ): " << fr->data_array2->write_energy*1e9 << endl; cout << " Precharge Energy (nJ): " << fr->data_array2->precharge_energy*1e9 << endl; cout << " Leakage Power Closed Page (mW): " << fr->data_array2->leak_power_subbank_closed_page*1e3 << endl; cout << " Leakage Power Open Page (mW): " << fr->data_array2->leak_power_subbank_open_page*1e3 << endl; cout << " Leakage Power I/O (mW): " << fr->data_array2->leak_power_request_and_reply_networks*1e3 << endl; cout << " Refresh power (mW): " << fr->data_array2->refresh_power*1e3 << endl; } else { if ((g_ip->fully_assoc|| g_ip->pure_cam)) { cout << " Total dynamic associative search energy per access (nJ): " << fr->power.searchOp.dynamic*1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->power.searchOp.dynamic*1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; // cout << " Total dynamic read energy per access (nJ): " << // fr->power.readOp.dynamic*1e9 << endl; // cout << " Total dynamic write energy per access (nJ): " << // fr->power.writeOp.dynamic*1e9 << endl; } // else // { cout << " Total dynamic read energy per access (nJ): " << fr->power.readOp.dynamic*1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->power.readOp.dynamic*1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << " Total dynamic write energy per access (nJ): " << fr->power.writeOp.dynamic*1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->power.writeOp.dynamic*1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; // } if (g_ip->power_gating) { cout << " Total leakage power of a bank, with power-gating "; if (!g_ip->user_defined_vcc_underflow) { cout << "(state retained)"; } else { cout << "(non state retained)"; } cout <<", including its network outside" //power gated with retaining memory content " (mW): " << (g_ip->long_channel_device ? fr->power.readOp.power_gated_leakage*long_channel_leakage_reduction : fr->power.readOp.power_gated_leakage)*1e3<long_channel_device ? fr->power.readOp.leakage*long_channel_leakage_reduction : fr->power.readOp.leakage)*1e3; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; ilong_channel_device ? fr->uca_q[i]->power.readOp.leakage*long_channel_leakage_reduction : fr->uca_q[i]->power.readOp.leakage)*1e3 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; } if (g_ip->data_arr_ram_cell_tech_type ==3 || g_ip->data_arr_ram_cell_tech_type ==4) { } cout << " Cache height x width (mm): " << fr->cache_ht*1e-3 << " x " << fr->cache_len*1e-3 << endl; cout << endl; if (g_ip->power_gating) { /* Energy/Power stats */ cout << " Power-gating results (The virtual power supply for gated circuit can only retain the state of idle circuit, not for operating the circuit):" << endl; /* Data array power-gating stats */ if (g_ip->user_defined_vcc_underflow) { cout<<" Warning: user defined power gating voltage is too low to retain state; Please understand the implications of deep sleep state on non state retaining and cold start effects when waking up the structure."<cache_ht*fr->cache_len/fr->uca_pg_reference->cache_ht/fr->uca_pg_reference->cache_len-1)*100;//% cout << " \tPower gating circuits (sleep transistors) induced area overhead: " << areaoverhead << " % " << endl ; wakeup_E = wakeup_E_data = fr->data_array2->sram_sleep_wakeup_energy + fr->data_array2->wl_sleep_wakeup_energy + fr->data_array2->bl_floating_wakeup_energy; wakeup_T = wakeup_T_data=MAX(fr->data_array2->sram_sleep_wakeup_latency, MAX(fr->data_array2->wl_sleep_wakeup_latency,fr->data_array2->bl_floating_wakeup_latency)); if ((!(g_ip->pure_ram|| g_ip->pure_cam || g_ip->fully_assoc)) && !g_ip->is_main_mem) { wakeup_E_tag = fr->tag_array2->sram_sleep_wakeup_energy + fr->tag_array2->wl_sleep_wakeup_energy + fr->tag_array2->bl_floating_wakeup_energy; wakeup_T_tag=MAX(fr->tag_array2->sram_sleep_wakeup_latency, MAX(fr->tag_array2->wl_sleep_wakeup_latency,fr->tag_array2->bl_floating_wakeup_latency)); wakeup_E += wakeup_E_tag; wakeup_T = MAX(wakeup_T_tag, wakeup_T_data); } cout << " \tPower gating Wakeup Latency (ns): " << wakeup_T*1e9 << endl ; cout << " \tPower gating Wakeup Energy (nJ): " << wakeup_E*1e9 << endl ; } cout <data_array2->Ndwl << endl; cout << " Best Ndbl : " << fr->data_array2->Ndbl << endl; cout << " Best Nspd : " << fr->data_array2->Nspd << endl; cout << " Best Ndcm : " << fr->data_array2->deg_bl_muxing << endl; cout << " Best Ndsam L1 : " << fr->data_array2->Ndsam_lev_1 << endl; cout << " Best Ndsam L2 : " << fr->data_array2->Ndsam_lev_2 << endl << endl; if ((!(g_ip->pure_ram|| g_ip->pure_cam || g_ip->fully_assoc)) && !g_ip->is_main_mem) { cout << " Best Ntwl : " << fr->tag_array2->Ndwl << endl; cout << " Best Ntbl : " << fr->tag_array2->Ndbl << endl; cout << " Best Ntspd : " << fr->tag_array2->Nspd << endl; cout << " Best Ntcm : " << fr->tag_array2->deg_bl_muxing << endl; cout << " Best Ntsam L1 : " << fr->tag_array2->Ndsam_lev_1 << endl; cout << " Best Ntsam L2 : " << fr->tag_array2->Ndsam_lev_2 << endl; } switch (fr->data_array2->wt) { case (0): cout << " Data array, H-tree wire type: Delay optimized global wires\n"; break; case (1): cout << " Data array, H-tree wire type: Global wires with 5\% delay penalty\n"; break; case (2): cout << " Data array, H-tree wire type: Global wires with 10\% delay penalty\n"; break; case (3): cout << " Data array, H-tree wire type: Global wires with 20\% delay penalty\n"; break; case (4): cout << " Data array, H-tree wire type: Global wires with 30\% delay penalty\n"; break; case (5): cout << " Data array, wire type: Low swing wires\n"; break; default: cout << "ERROR - Unknown wire type " << (int) fr->data_array2->wt <pure_ram|| g_ip->pure_cam || g_ip->fully_assoc)) { switch (fr->tag_array2->wt) { case (0): cout << " Tag array, H-tree wire type: Delay optimized global wires\n"; break; case (1): cout << " Tag array, H-tree wire type: Global wires with 5\% delay penalty\n"; break; case (2): cout << " Tag array, H-tree wire type: Global wires with 10\% delay penalty\n"; break; case (3): cout << " Tag array, H-tree wire type: Global wires with 20\% delay penalty\n"; break; case (4): cout << " Tag array, H-tree wire type: Global wires with 30\% delay penalty\n"; break; case (5): cout << " Tag array, wire type: Low swing wires\n"; break; default: cout << "ERROR - Unknown wire type " << (int) fr->tag_array2->wt <print_detail) { //if(g_ip->fully_assoc) return; if(0){ //detailed power-gating output if (g_ip->power_gating) { /* Energy/Power stats */ cout << endl << endl << "Power-gating Components:" << endl << endl; /* Data array power-gating stats */ areaoverhead = fr->cache_ht*fr->cache_len/fr->uca_pg_reference->cache_ht/fr->uca_pg_reference->cache_len-1; cout << " Power gating circuits (sleep transistors) induced area overhead: " << areaoverhead << " % " << endl ; wakeup_E = wakeup_E_data = fr->data_array2->sram_sleep_wakeup_energy + fr->data_array2->wl_sleep_wakeup_energy + fr->data_array2->bl_floating_wakeup_energy; wakeup_T = wakeup_T_data=MAX(fr->data_array2->sram_sleep_wakeup_latency, MAX(fr->data_array2->wl_sleep_wakeup_latency,fr->data_array2->bl_floating_wakeup_latency)); if ((!(g_ip->pure_ram|| g_ip->pure_cam || g_ip->fully_assoc)) && !g_ip->is_main_mem) { wakeup_E_tag = fr->tag_array2->sram_sleep_wakeup_energy + fr->tag_array2->wl_sleep_wakeup_energy + fr->tag_array2->bl_floating_wakeup_energy; wakeup_T_tag=MAX(fr->tag_array2->sram_sleep_wakeup_latency, MAX(fr->tag_array2->wl_sleep_wakeup_latency,fr->tag_array2->bl_floating_wakeup_latency)); wakeup_E += wakeup_E_tag; wakeup_T = MAX(wakeup_T_tag, wakeup_T_data); } cout << " Power gating Wakeup Latency (ns): " << wakeup_T*1e9 << endl ; cout << " Power gating Wakeup Energy (nJ): " << wakeup_E*1e9 << endl ; //extra power gating details if (!(g_ip->pure_cam || g_ip->fully_assoc)) cout << " Data array: " << endl; else if (g_ip->pure_cam) cout << " CAM array: " << endl; else cout << " Fully associative cache array: " << endl; cout << "\t Sub-array Sleep Tx size (um) - " << fr->data_array2->sram_sleep_tx_width << endl; // cout << "\t Sub-array Sleep Tx total size (um) - " << // fr->data_array2->sram_sleep_tx_width << endl; cout << "\t Sub-array Sleep Tx total area (mm^2) - " << fr->data_array2->sram_sleep_tx_area*1e-6 << endl; cout << "\t Sub-array wakeup time (ns) - " << fr->data_array2->sram_sleep_wakeup_latency*1e9 << endl; cout << "\t Sub-array Tx energy (nJ) - " << fr->data_array2->sram_sleep_wakeup_energy*1e9 << endl; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ cout << endl; cout << "\t WL Sleep Tx size (um) - " << fr->data_array2->wl_sleep_tx_width << endl; // cout << "\t WL Sleep total Tx size (um) - " << // fr->data_array2->wl_sleep_tx_width << endl; cout << "\t WL Sleep Tx total area (mm^2) - " << fr->data_array2->wl_sleep_tx_area*1e-6 << endl; cout << "\t WL wakeup time (ns) - " << fr->data_array2->wl_sleep_wakeup_latency*1e9 << endl; cout << "\t WL Tx energy (nJ) - " << fr->data_array2->wl_sleep_wakeup_energy*1e9 << endl; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ cout << endl; cout << "\t BL floating wakeup time (ns) - " << fr->data_array2->bl_floating_wakeup_latency*1e9 << endl; cout << "\t BL floating Tx energy (nJ) - " << fr->data_array2->bl_floating_wakeup_energy*1e9 << endl; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ cout << endl; cout << "\t Active mats per access - " << fr->data_array2->num_active_mats<data_array2->num_submarray_mats<pure_ram|| g_ip->pure_cam || g_ip->fully_assoc)) && !g_ip->is_main_mem) { cout << " Tag array: " << endl; cout << "\t Sub-array Sleep Tx size (um) - " << fr->tag_array2->sram_sleep_tx_width << endl; // cout << "\t Sub-array Sleep Tx total size (um) - " << // fr->tag_array2->sram_sleep_tx_width << endl; cout << "\t Sub-array Sleep Tx total area (mm^2) - " << fr->tag_array2->sram_sleep_tx_area*1e-6 << endl; cout << "\t Sub-array wakeup time (ns) - " << fr->tag_array2->sram_sleep_wakeup_latency*1e9 << endl; cout << "\t Sub-array Tx energy (nJ) - " << fr->tag_array2->sram_sleep_wakeup_energy*1e9 << endl; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ cout << endl; cout << "\t WL Sleep Tx size (um) - " << fr->tag_array2->wl_sleep_tx_width << endl; // cout << "\t WL Sleep total Tx size (um) - " << // fr->tag_array2->wl_sleep_tx_width << endl; cout << "\t WL Sleep Tx total area (mm^2) - " << fr->tag_array2->wl_sleep_tx_area*1e-6 << endl; cout << "\t WL wakeup time (ns) - " << fr->tag_array2->wl_sleep_wakeup_latency*1e9 << endl; cout << "\t WL Tx energy (nJ) - " << fr->tag_array2->wl_sleep_wakeup_energy*1e9 << endl; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ cout << endl; cout << "\t BL floating wakeup time (ns) - " << fr->tag_array2->bl_floating_wakeup_latency*1e9 << endl; cout << "\t BL floating Tx energy (nJ) - " << fr->tag_array2->bl_floating_wakeup_energy*1e9 << endl; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ cout << endl; cout << "\t Active mats per access - " << fr->tag_array2->num_active_mats<tag_array2->num_submarray_mats<data_array2->access_time/1e-9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->access_time/1e-9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tH-tree delay outside banks (ns): " << fr->data_array2->delay_route_to_bank * 1e9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->delay_route_to_bank * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tH-tree input delay (inside a bank) (ns): " << fr->data_array2->delay_input_htree * 1e9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->delay_input_htree * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; if (!(g_ip->pure_cam || g_ip->fully_assoc)) { cout << "\tDecoder + wordline delay (ns): " << fr->data_array2->delay_row_predecode_driver_and_block * 1e9 + fr->data_array2->delay_row_decoder * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->delay_row_predecode_driver_and_block * 1e9 + fr->uca_q[i]->data_array2->delay_row_decoder * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; } else { cout << "\tCAM search delay (ns): " << fr->data_array2->delay_matchlines * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->delay_matchlines * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; } cout << "\tBitline delay (ns): " << fr->data_array2->delay_bitlines/1e-9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->delay_bitlines/1e-9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tSense Amplifier delay (ns): " << fr->data_array2->delay_sense_amp * 1e9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->delay_sense_amp*1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tH-tree output delay (inside a bank) (ns): " << fr->data_array2->delay_subarray_output_driver * 1e9 + fr->data_array2->delay_dout_htree * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->delay_subarray_output_driver * 1e9 + fr->uca_q[i]->data_array2->delay_dout_htree * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; if (g_ip->power_gating) { cout << "\tPower gating wakeup time (ns) - " << wakeup_T_data*1e9 << endl; } if ((!(g_ip->pure_ram|| g_ip->pure_cam || g_ip->fully_assoc)) && !g_ip->is_main_mem) { /* tag array stats */ cout << endl << " Tag side (with Output driver) (ns): " << fr->tag_array2->access_time/1e-9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->tag_array2->access_time/1e-9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout << endl; cout << "\tH-tree delay outside banks (ns): " << fr->tag_array2->delay_route_to_bank * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->tag_array2->delay_route_to_bank * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout << endl; cout << "\tH-tree input delay (inside a bank) (ns): " << fr->tag_array2->delay_input_htree * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->tag_array2->delay_input_htree * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout << endl; cout << "\tDecoder + wordline delay (ns): " << fr->tag_array2->delay_row_predecode_driver_and_block * 1e9 + fr->tag_array2->delay_row_decoder * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->tag_array2->delay_row_predecode_driver_and_block * 1e9 + fr->uca_q[i]->tag_array2->delay_row_decoder * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout << endl; cout << "\tBitline delay (ns): " << fr->tag_array2->delay_bitlines/1e-9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->tag_array2->delay_bitlines * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout << endl; cout << "\tSense Amplifier delay (ns): " << fr->tag_array2->delay_sense_amp * 1e9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->tag_array2->delay_sense_amp * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout << endl; cout << "\tComparator delay (ns): " << fr->tag_array2->delay_comparator * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->tag_array2->delay_comparator * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout << endl; cout << "\tH-tree output delay (inside a bank) (ns): " << fr->tag_array2->delay_subarray_output_driver * 1e9 + fr->tag_array2->delay_dout_htree * 1e9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->tag_array2->delay_subarray_output_driver * 1e9 + fr->uca_q[i]->tag_array2->delay_dout_htree * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout << endl; if (g_ip->power_gating) { cout << "\tPower gating wakeup time (ns) - " << wakeup_T_tag*1e9 << endl; } } /* Energy/Power stats */ cout << endl << endl << "Power Components:" << endl << endl; if (!(g_ip->pure_cam || g_ip->fully_assoc)) { cout << " Data array: Total dynamic read energy/access (nJ): " << fr->data_array2->power.readOp.dynamic * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power.readOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; if (g_ip->power_gating) { cout << "\tTotal leakage power of a bank, power gated "; if (!g_ip->user_defined_vcc_underflow) { cout << "with "; } else { cout << "without "; } cout<<"retaining memory content, including its network outside (mW): " << (g_ip->long_channel_device ? fr->data_array2->power.readOp.power_gated_leakage*long_channel_leakage_reduction : fr->data_array2->power.readOp.power_gated_leakage)*1e3 << endl; } // else // { cout << "\tTotal leakage power of a bank without power gating, including its network outside (mW): " << (g_ip->long_channel_device ? fr->data_array2->power.readOp.leakage*long_channel_leakage_reduction : fr->data_array2->power.readOp.leakage)*1e3; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; ilong_channel_device ?fr->uca_q[i]->data_array2->power.readOp.leakage*long_channel_leakage_reduction : fr->uca_q[i]->data_array2->power.readOp.leakage) * 1e3 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; // } cout << "\tTotal energy in H-tree outside banks (that includes both " "address and data transfer) (nJ): " << (fr->data_array2->power_routing_to_bank.readOp.dynamic) * 1e9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_routing_to_bank.readOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tInput H-tree inside bank Energy (nJ): " << (fr->data_array2->power_addr_input_htree.readOp.dynamic) * 1e9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_addr_input_htree.readOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tOutput Htree inside bank Energy (nJ): " << fr->data_array2->power_data_output_htree.readOp.dynamic * 1e9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_data_output_htree.readOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tDecoder (nJ): " << fr->data_array2->power_row_predecoder_drivers.readOp.dynamic * 1e9 + fr->data_array2->power_row_predecoder_blocks.readOp.dynamic * 1e9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_row_predecoder_drivers.readOp.dynamic * 1e9 + fr->uca_q[i]->data_array2->power_row_predecoder_blocks.readOp.dynamic * 1e9) <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tWordline (nJ): " << fr->data_array2->power_row_decoders.readOp.dynamic * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_row_decoders.readOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tBitline mux & associated drivers (nJ): " << fr->data_array2->power_bit_mux_predecoder_drivers.readOp.dynamic * 1e9 + fr->data_array2->power_bit_mux_predecoder_blocks.readOp.dynamic * 1e9 + fr->data_array2->power_bit_mux_decoders.readOp.dynamic * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_bit_mux_predecoder_drivers.readOp.dynamic * 1e9 + fr->uca_q[i]->data_array2->power_bit_mux_predecoder_blocks.readOp.dynamic * 1e9 + fr->uca_q[i]->data_array2->power_bit_mux_decoders.readOp.dynamic * 1e9) <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tSense amp mux & associated drivers (nJ): " << fr->data_array2->power_senseamp_mux_lev_1_predecoder_drivers.readOp.dynamic * 1e9 + fr->data_array2->power_senseamp_mux_lev_1_predecoder_blocks.readOp.dynamic * 1e9 + fr->data_array2->power_senseamp_mux_lev_1_decoders.readOp.dynamic * 1e9 + fr->data_array2->power_senseamp_mux_lev_2_predecoder_drivers.readOp.dynamic * 1e9 + fr->data_array2->power_senseamp_mux_lev_2_predecoder_blocks.readOp.dynamic * 1e9 + fr->data_array2->power_senseamp_mux_lev_2_decoders.readOp.dynamic * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_senseamp_mux_lev_1_predecoder_drivers.readOp.dynamic * 1e9 + fr->uca_q[i]->data_array2->power_senseamp_mux_lev_1_predecoder_blocks.readOp.dynamic * 1e9 + fr->uca_q[i]->data_array2->power_senseamp_mux_lev_1_decoders.readOp.dynamic * 1e9 + fr->uca_q[i]->data_array2->power_senseamp_mux_lev_2_predecoder_drivers.readOp.dynamic * 1e9 + fr->uca_q[i]->data_array2->power_senseamp_mux_lev_2_predecoder_blocks.readOp.dynamic * 1e9 + fr->uca_q[i]->data_array2->power_senseamp_mux_lev_2_decoders.readOp.dynamic * 1e9) <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tBitlines precharge and equalization circuit (nJ): " << fr->data_array2->power_prechg_eq_drivers.readOp.dynamic * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_prechg_eq_drivers.readOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tBitlines (nJ): " << fr->data_array2->power_bitlines.readOp.dynamic * 1e9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_bitlines.readOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tSense amplifier energy (nJ): " << fr->data_array2->power_sense_amps.readOp.dynamic * 1e9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_sense_amps.readOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tSub-array output driver (nJ): " << fr->data_array2->power_output_drivers_at_subarray.readOp.dynamic * 1e9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_output_drivers_at_subarray.readOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; if (g_ip->power_gating) { cout << "\tTotal leakage power in H-tree outside a bank when power gated (that includes both " "address and data network) ((mW)): " << (g_ip->long_channel_device?fr->data_array2->power_routing_to_bank.readOp.power_gated_leakage * long_channel_leakage_reduction: fr->data_array2->power_routing_to_bank.readOp.power_gated_leakage) * 1e3 << endl; } // else // { cout << "\tTotal leakage power in H-tree outside a bank (that includes both " "address and data network) ((mW)): " << (g_ip->long_channel_device? fr->data_array2->power_routing_to_bank.readOp.leakage * long_channel_leakage_reduction: fr->data_array2->power_routing_to_bank.readOp.leakage) * 1e3 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; ilong_channel_device? fr->uca_q[i]->data_array2->power_routing_to_bank.readOp.leakage* long_channel_leakage_reduction: fr->uca_q[i]->data_array2->power_routing_to_bank.readOp.leakage) * 1e3 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; // } // cout << "\tTotal leakage power in H-tree (that includes both " // "address and data network) ((mW)): " << // (fr->data_array2->power_addr_input_htree.readOp.leakage + // fr->data_array2->power_data_output_htree.readOp.leakage + // fr->data_array2->power_routing_to_bank.readOp.leakage) * 1e3 << endl; // cout << "\tTotal leakage power in cells (mW): " << // (fr->data_array2->array_leakage) * 1e3 << endl; // cout << "\tTotal leakage power in row logic(mW): " << // (fr->data_array2->wl_leakage) * 1e3 << endl; // cout << "\tTotal leakage power in column logic(mW): " << // (fr->data_array2->cl_leakage) * 1e3 << endl; // // cout << "\tTotal gate leakage power in H-tree (that includes both " // "address and data network) ((mW)): " << // (fr->data_array2->power_addr_input_htree.readOp.gate_leakage + // fr->data_array2->power_data_output_htree.readOp.gate_leakage + // fr->data_array2->power_routing_to_bank.readOp.gate_leakage) * 1e3 << endl; } if (g_ip->pure_cam||g_ip->fully_assoc) { if (g_ip->pure_cam) cout << " CAM array:"<data_array2->power.searchOp.dynamic * 1e9 << endl; // cout << "\tTotal energy in H-tree (that includes both " // "match key and data transfer) (nJ): " << // (fr->data_array2->power_htree_in_search.searchOp.dynamic + // fr->data_array2->power_htree_out_search.searchOp.dynamic + // fr->data_array2->power_routing_to_bank.searchOp.dynamic) * 1e9 << endl; // cout << "\tKeyword input and result output Htrees inside bank Energy (nJ): " << // (fr->data_array2->power_htree_in_search.searchOp.dynamic + // fr->data_array2->power_htree_out_search.searchOp.dynamic) * 1e9 << endl; // cout << "\tSearchlines (nJ): " << // fr->data_array2->power_searchline.searchOp.dynamic * 1e9 + // fr->data_array2->power_searchline_precharge.searchOp.dynamic * 1e9 << endl; // cout << "\tMatchlines (nJ): " << // fr->data_array2->power_matchlines.searchOp.dynamic * 1e9 + // fr->data_array2->power_matchline_precharge.searchOp.dynamic * 1e9 << endl; // cout << "\tSub-array output driver (nJ): " << // fr->data_array2->power_output_drivers_at_subarray.searchOp.dynamic * 1e9 << endl; // // // cout <data_array2->power.readOp.dynamic * 1e9 << endl; // cout << "\tTotal energy in H-tree (that includes both " // "address and data transfer) (nJ): " << // (fr->data_array2->power_addr_input_htree.readOp.dynamic + // fr->data_array2->power_data_output_htree.readOp.dynamic + // fr->data_array2->power_routing_to_bank.readOp.dynamic) * 1e9 << endl; // cout << "\tOutput Htree inside bank Energy (nJ): " << // fr->data_array2->power_data_output_htree.readOp.dynamic * 1e9 << endl; // cout << "\tDecoder (nJ): " << // fr->data_array2->power_row_predecoder_drivers.readOp.dynamic * 1e9 + // fr->data_array2->power_row_predecoder_blocks.readOp.dynamic * 1e9 << endl; // cout << "\tWordline (nJ): " << // fr->data_array2->power_row_decoders.readOp.dynamic * 1e9 << endl; // cout << "\tBitline mux & associated drivers (nJ): " << // fr->data_array2->power_bit_mux_predecoder_drivers.readOp.dynamic * 1e9 + // fr->data_array2->power_bit_mux_predecoder_blocks.readOp.dynamic * 1e9 + // fr->data_array2->power_bit_mux_decoders.readOp.dynamic * 1e9 << endl; // cout << "\tSense amp mux & associated drivers (nJ): " << // fr->data_array2->power_senseamp_mux_lev_1_predecoder_drivers.readOp.dynamic * 1e9 + // fr->data_array2->power_senseamp_mux_lev_1_predecoder_blocks.readOp.dynamic * 1e9 + // fr->data_array2->power_senseamp_mux_lev_1_decoders.readOp.dynamic * 1e9 + // fr->data_array2->power_senseamp_mux_lev_2_predecoder_drivers.readOp.dynamic * 1e9 + // fr->data_array2->power_senseamp_mux_lev_2_predecoder_blocks.readOp.dynamic * 1e9 + // fr->data_array2->power_senseamp_mux_lev_2_decoders.readOp.dynamic * 1e9 << endl; // cout << "\tBitlines (nJ): " << // fr->data_array2->power_bitlines.readOp.dynamic * 1e9 + // fr->data_array2->power_prechg_eq_drivers.readOp.dynamic * 1e9<< endl; // cout << "\tSense amplifier energy (nJ): " << // fr->data_array2->power_sense_amps.readOp.dynamic * 1e9 << endl; // cout << "\tSub-array output driver (nJ): " << // fr->data_array2->power_output_drivers_at_subarray.readOp.dynamic * 1e9 << endl; // // cout << endl <<" Total leakage power of a bank (mW): " << // fr->data_array2->power.readOp.leakage * 1e3 << endl; // } // else // { if (g_ip->fully_assoc) cout << " Fully associative array:"<data_array2->power.searchOp.dynamic * 1e9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power.searchOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tTotal energy in H-tree outside banks(that includes both " "match key and data transfer) (nJ): " << (fr->data_array2->power_routing_to_bank.searchOp.dynamic) * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_routing_to_bank.searchOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tMatch Key input Htrees inside bank Energy (nJ): " << (fr->data_array2->power_htree_in_search.searchOp.dynamic ) * 1e9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_htree_in_search.searchOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tResult output Htrees inside bank Energy (nJ): " << (fr->data_array2->power_htree_out_search.searchOp.dynamic) * 1e9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_htree_out_search.searchOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tSearchlines (nJ): " << fr->data_array2->power_searchline.searchOp.dynamic * 1e9 + fr->data_array2->power_searchline_precharge.searchOp.dynamic * 1e9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_searchline.searchOp.dynamic * 1e9 + fr->uca_q[i]->data_array2->power_searchline_precharge.searchOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tMatchlines (nJ): " << fr->data_array2->power_matchlines.searchOp.dynamic * 1e9 + fr->data_array2->power_matchline_precharge.searchOp.dynamic * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_matchlines.searchOp.dynamic * 1e9 + fr->uca_q[i]->data_array2->power_matchline_precharge.searchOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; if (g_ip->fully_assoc) { cout << "\tData portion wordline (nJ): " << fr->data_array2->power_matchline_to_wordline_drv.searchOp.dynamic * 1e9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_matchline_to_wordline_drv.searchOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tData Bitlines (nJ): " << fr->data_array2->power_bitlines.searchOp.dynamic * 1e9 + fr->data_array2->power_prechg_eq_drivers.searchOp.dynamic * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_bitlines.searchOp.dynamic * 1e9 + fr->uca_q[i]->data_array2->power_prechg_eq_drivers.searchOp.dynamic * 1e9) <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tSense amplifier energy (nJ): " << fr->data_array2->power_sense_amps.searchOp.dynamic * 1e9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_sense_amps.searchOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; } cout << "\tSub-array output driver (nJ): " << fr->data_array2->power_output_drivers_at_subarray.searchOp.dynamic * 1e9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_output_drivers_at_subarray.searchOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout <data_array2->power.readOp.dynamic * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power.readOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tTotal energy in H-tree outside banks(that includes both " "address and data transfer) (nJ): " << (fr->data_array2->power_routing_to_bank.readOp.dynamic) * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_routing_to_bank.readOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tInput Htree inside bank Energy (nJ): " << (fr->data_array2->power_addr_input_htree.readOp.dynamic ) * 1e9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_addr_input_htree.readOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tOutput Htree inside bank Energy (nJ): " << fr->data_array2->power_data_output_htree.readOp.dynamic * 1e9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_data_output_htree.readOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tDecoder (nJ): " << fr->data_array2->power_row_predecoder_drivers.readOp.dynamic * 1e9 + fr->data_array2->power_row_predecoder_blocks.readOp.dynamic * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_row_predecoder_drivers.readOp.dynamic * 1e9 + fr->uca_q[i]->data_array2->power_row_predecoder_blocks.readOp.dynamic * 1e9) <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tWordline (nJ): " << fr->data_array2->power_row_decoders.readOp.dynamic * 1e9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_row_decoders.readOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tBitline mux & associated drivers (nJ): " << fr->data_array2->power_bit_mux_predecoder_drivers.readOp.dynamic * 1e9 + fr->data_array2->power_bit_mux_predecoder_blocks.readOp.dynamic * 1e9 + fr->data_array2->power_bit_mux_decoders.readOp.dynamic * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_bit_mux_predecoder_drivers.readOp.dynamic * 1e9 + fr->uca_q[i]->data_array2->power_bit_mux_predecoder_blocks.readOp.dynamic * 1e9 + fr->uca_q[i]->data_array2->power_bit_mux_decoders.readOp.dynamic * 1e9) <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tSense amp mux & associated drivers (nJ): " << fr->data_array2->power_senseamp_mux_lev_1_predecoder_drivers.readOp.dynamic * 1e9 + fr->data_array2->power_senseamp_mux_lev_1_predecoder_blocks.readOp.dynamic * 1e9 + fr->data_array2->power_senseamp_mux_lev_1_decoders.readOp.dynamic * 1e9 + fr->data_array2->power_senseamp_mux_lev_2_predecoder_drivers.readOp.dynamic * 1e9 + fr->data_array2->power_senseamp_mux_lev_2_predecoder_blocks.readOp.dynamic * 1e9 + fr->data_array2->power_senseamp_mux_lev_2_decoders.readOp.dynamic * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_senseamp_mux_lev_1_predecoder_drivers.readOp.dynamic * 1e9 + fr->uca_q[i]->data_array2->power_senseamp_mux_lev_1_predecoder_blocks.readOp.dynamic * 1e9 + fr->uca_q[i]->data_array2->power_senseamp_mux_lev_1_decoders.readOp.dynamic * 1e9 + fr->uca_q[i]->data_array2->power_senseamp_mux_lev_2_predecoder_drivers.readOp.dynamic * 1e9 + fr->uca_q[i]->data_array2->power_senseamp_mux_lev_2_predecoder_blocks.readOp.dynamic * 1e9 + fr->uca_q[i]->data_array2->power_senseamp_mux_lev_2_decoders.readOp.dynamic * 1e9) <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tBitlines (nJ): " << fr->data_array2->power_bitlines.readOp.dynamic * 1e9 + fr->data_array2->power_prechg_eq_drivers.readOp.dynamic * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_bitlines.readOp.dynamic * 1e9 + fr->uca_q[i]->data_array2->power_prechg_eq_drivers.readOp.dynamic* 1e9) <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tSense amplifier energy (nJ): " << fr->data_array2->power_sense_amps.readOp.dynamic * 1e9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_sense_amps.readOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tSub-array output driver (nJ): " << fr->data_array2->power_output_drivers_at_subarray.readOp.dynamic * 1e9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->data_array2->power_output_drivers_at_subarray.readOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << endl <<" Total leakage power of a bank, including its network outside (mW): " << (g_ip->long_channel_device ? fr->data_array2->power.readOp.leakage*long_channel_leakage_reduction : fr->data_array2->power.readOp.leakage)*1e3; //CAM/FA does not support PG yet if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; ilong_channel_device ?fr->uca_q[i]->data_array2->power.readOp.leakage*long_channel_leakage_reduction : fr->uca_q[i]->data_array2->power.readOp.leakage) * 1e3 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; } if ((!(g_ip->pure_ram|| g_ip->pure_cam || g_ip->fully_assoc)) && !g_ip->is_main_mem) { cout << endl << " Tag array: Total dynamic read energy/access (nJ): " << fr->tag_array2->power.readOp.dynamic * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->tag_array2->power.readOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; if (g_ip->power_gating) { cout << "\tTotal leakage power of a bank, power gated "; if (!g_ip->user_defined_vcc_underflow) { cout << "with "; } else { cout << "without "; } cout<<"retaining memory content, including its network outside (mW): " << (g_ip->long_channel_device ? fr->tag_array2->power.readOp.power_gated_leakage*long_channel_leakage_reduction : fr->tag_array2->power.readOp.power_gated_leakage)* 1e3 << endl; } // else // { cout << "\tTotal leakage power of a bank without power gating, including its network outside (mW): " << (g_ip->long_channel_device ? fr->tag_array2->power.readOp.leakage * long_channel_leakage_reduction: fr->tag_array2->power.readOp.leakage)* 1e3; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; ilong_channel_device ? fr->uca_q[i]->tag_array2->power.readOp.leakage *long_channel_leakage_reduction: fr->uca_q[i]->tag_array2->power.readOp.leakage) * 1e3 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; // } // cout << "\tTotal leakage read/write power of a bank (mW): " << // fr->tag_array2->power.readOp.leakage * 1e3 << endl; cout << "\tTotal energy in H-tree outside banks (that includes both " "address and data transfer) (nJ): " << (fr->tag_array2->power_routing_to_bank.readOp.dynamic) * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->tag_array2->power_routing_to_bank.readOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tInput H-tree inside banks Energy (nJ): " << (fr->tag_array2->power_addr_input_htree.readOp.dynamic) * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->tag_array2->power_addr_input_htree.readOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tOutput Htree inside a bank Energy (nJ): " << fr->tag_array2->power_data_output_htree.readOp.dynamic * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->tag_array2->power_data_output_htree.readOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tDecoder (nJ): " << fr->tag_array2->power_row_predecoder_drivers.readOp.dynamic * 1e9 + fr->tag_array2->power_row_predecoder_blocks.readOp.dynamic * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->tag_array2->power_row_predecoder_drivers.readOp.dynamic * 1e9 + fr->uca_q[i]->tag_array2->power_row_predecoder_blocks.readOp.dynamic * 1e9) <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tWordline (nJ): " << fr->tag_array2->power_row_decoders.readOp.dynamic * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->tag_array2->power_row_decoders.readOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tBitline mux & associated drivers (nJ): " << fr->tag_array2->power_bit_mux_predecoder_drivers.readOp.dynamic * 1e9 + fr->tag_array2->power_bit_mux_predecoder_blocks.readOp.dynamic * 1e9 + fr->tag_array2->power_bit_mux_decoders.readOp.dynamic * 1e9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->tag_array2->power_bit_mux_predecoder_drivers.readOp.dynamic * 1e9 + fr->uca_q[i]->tag_array2->power_bit_mux_predecoder_blocks.readOp.dynamic * 1e9 + fr->uca_q[i]->tag_array2->power_bit_mux_decoders.readOp.dynamic * 1e9) <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tSense amp mux & associated drivers (nJ): " << fr->tag_array2->power_senseamp_mux_lev_1_predecoder_drivers.readOp.dynamic * 1e9 + fr->tag_array2->power_senseamp_mux_lev_1_predecoder_blocks.readOp.dynamic * 1e9 + fr->tag_array2->power_senseamp_mux_lev_1_decoders.readOp.dynamic * 1e9 + fr->tag_array2->power_senseamp_mux_lev_2_predecoder_drivers.readOp.dynamic * 1e9 + fr->tag_array2->power_senseamp_mux_lev_2_predecoder_blocks.readOp.dynamic * 1e9 + fr->tag_array2->power_senseamp_mux_lev_2_decoders.readOp.dynamic * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->tag_array2->power_senseamp_mux_lev_1_predecoder_drivers.readOp.dynamic * 1e9 + fr->uca_q[i]->tag_array2->power_senseamp_mux_lev_1_predecoder_blocks.readOp.dynamic * 1e9 + fr->uca_q[i]->tag_array2->power_senseamp_mux_lev_1_decoders.readOp.dynamic * 1e9 + fr->uca_q[i]->tag_array2->power_senseamp_mux_lev_2_predecoder_drivers.readOp.dynamic * 1e9 + fr->uca_q[i]->tag_array2->power_senseamp_mux_lev_2_predecoder_blocks.readOp.dynamic * 1e9 + fr->uca_q[i]->tag_array2->power_senseamp_mux_lev_2_decoders.readOp.dynamic * 1e9) <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tBitlines precharge and equalization circuit (nJ): " << fr->tag_array2->power_prechg_eq_drivers.readOp.dynamic * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->tag_array2->power_prechg_eq_drivers.readOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tBitlines (nJ): " << fr->tag_array2->power_bitlines.readOp.dynamic * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->tag_array2->power_bitlines.readOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tSense amplifier energy (nJ): " << fr->tag_array2->power_sense_amps.readOp.dynamic * 1e9; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->tag_array2->power_sense_amps.readOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; cout << "\tSub-array output driver (nJ): " << fr->tag_array2->power_output_drivers_at_subarray.readOp.dynamic * 1e9 ; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; iuca_q[i]->tag_array2->power_output_drivers_at_subarray.readOp.dynamic * 1e9 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; if (g_ip->power_gating) { cout << "\tTotal leakage power in H-tree outside a bank when power gated (that includes both " "address and data network) ((mW)): " << (g_ip->long_channel_device ? fr->tag_array2->power_routing_to_bank.readOp.power_gated_leakage*long_channel_leakage_reduction : fr->tag_array2->power_routing_to_bank.readOp.power_gated_leakage) * 1e3 << endl; } // else // { cout << "\tTotal leakage power in H-tree outside a bank (that includes both " "address and data network) without power gating((mW)): " << (g_ip->long_channel_device ? fr->tag_array2->power_routing_to_bank.readOp.leakage*long_channel_leakage_reduction : fr->tag_array2->power_routing_to_bank.readOp.leakage) * 1e3; if (dvs) { cout<<" (@DVS_Level0); "; for (i = 0; ilong_channel_device ? fr->uca_q[i]->tag_array2->power_routing_to_bank.readOp.leakage *long_channel_leakage_reduction : fr->uca_q[i]->tag_array2->power_routing_to_bank.readOp.leakage) * 1e3 <<" (@DVS_Level"<< i+1<<"_Vdd=" << g_ip->dvs_voltage[i]<<"); "; } cout<< endl; // } // cout << "\tTotal leakage power of a bank (mW): " << // fr->tag_array2->power.readOp.leakage * 1e3 << endl; // cout << "\tTotal leakage power in H-tree (that includes both " // "address and data network) ((mW)): " << // (fr->tag_array2->power_addr_input_htree.readOp.leakage + // fr->tag_array2->power_data_output_htree.readOp.leakage + // fr->tag_array2->power_routing_to_bank.readOp.leakage) * 1e3 << endl; // // cout << "\tTotal leakage power in cells (mW): " << // (fr->tag_array2->array_leakage) * 1e3 << endl; // cout << "\tTotal leakage power in row logic(mW): " << // (fr->tag_array2->wl_leakage) * 1e3 << endl; // cout << "\tTotal leakage power in column logic(mW): " << // (fr->tag_array2->cl_leakage) * 1e3 << endl; // cout << "\tTotal gate leakage power in H-tree (that includes both " // "address and data network) ((mW)): " << // (fr->tag_array2->power_addr_input_htree.readOp.gate_leakage + // fr->tag_array2->power_data_output_htree.readOp.gate_leakage + // fr->tag_array2->power_routing_to_bank.readOp.gate_leakage) * 1e3 << endl; } cout << endl << endl << "Area Components:" << endl << endl; /* Data array area stats */ if (!(g_ip->pure_cam || g_ip->fully_assoc)) cout << " Data array: Area (mm2): " << fr->data_array2->area * 1e-6 << endl; else if (g_ip->pure_cam) cout << " CAM array: Area (mm2): " << fr->data_array2->area * 1e-6 << endl; else cout << " Fully associative cache array: Area (mm2): " << fr->data_array2->area * 1e-6 << endl; cout << "\tHeight (mm): " << fr->data_array2->all_banks_height*1e-3 << endl; cout << "\tWidth (mm): " << fr->data_array2->all_banks_width*1e-3 << endl; if (g_ip->print_detail) { cout << "\tArea efficiency (Memory cell area/Total area) - " << fr->data_array2->area_efficiency << " %" << endl; cout << "\t\tMAT Height (mm): " << fr->data_array2->mat_height*1e-3 << endl; cout << "\t\tMAT Length (mm): " << fr->data_array2->mat_length*1e-3 << endl; cout << "\t\tSubarray Height (mm): " << fr->data_array2->subarray_height*1e-3 << endl; cout << "\t\tSubarray Length (mm): " << fr->data_array2->subarray_length*1e-3 << endl; if (g_ip->power_gating) { overhead_data = (fr->data_array2->area/fr->uca_pg_reference->data_array2->area-1)*100;//%; cout << " Power gating circuits (sleep transistors) induced area overhead: " << overhead_data <<"%" <pure_ram|| g_ip->pure_cam || g_ip->fully_assoc)) && !g_ip->is_main_mem) { cout << endl << " Tag array: Area (mm2): " << fr->tag_array2->area * 1e-6 << endl; cout << "\tHeight (mm): " << fr->tag_array2->all_banks_height*1e-3 << endl; cout << "\tWidth (mm): " << fr->tag_array2->all_banks_width*1e-3 << endl; if (g_ip->print_detail) { cout << "\tArea efficiency (Memory cell area/Total area) - " << fr->tag_array2->area_efficiency << " %" << endl; cout << "\t\tMAT Height (mm): " << fr->tag_array2->mat_height*1e-3 << endl; cout << "\t\tMAT Length (mm): " << fr->tag_array2->mat_length*1e-3 << endl; cout << "\t\tSubarray Height (mm): " << fr->tag_array2->subarray_height*1e-3 << endl; cout << "\t\tSubarray Length (mm): " << fr->tag_array2->subarray_length*1e-3 << endl; } if (g_ip->power_gating) { overhead_tag = (fr->tag_array2->area/fr->uca_pg_reference->tag_array2->area-1)*100;//%; cout << " Power gating circuits (sleep transistors) induced area overhead: " << overhead_tag <<"%" <