| /***************************************************************************** | |
| * McPAT/CACTI | |
| * SOFTWARE LICENSE AGREEMENT | |
| * Copyright 2012 Hewlett-Packard Development Company, L.P. | |
| * Copyright (c) 2010-2013 Advanced Micro Devices, Inc. | |
| * 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 <fstream> | |
| #include <iostream> | |
| #include <sstream> | |
| #include "Ucache.h" | |
| #include "arbiter.h" | |
| #include "area.h" | |
| #include "basic_circuit.h" | |
| #include "crossbar.h" | |
| #include "io.h" | |
| #include "nuca.h" | |
| #include "parameter.h" | |
| //#include "highradix.h" | |
| using namespace std; | |
| /* 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]; | |
| 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("-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("-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 << "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; | |
| } | |
| } | |
| 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; | |
| 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]; | |
| //longer channel leakage has the same behavior as normal leakage | |
| z.longer_channel_leakage = x.longer_channel_leakage * y[1]; | |
| 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(infile_name)) | |
| 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. | |
| // 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); | |
| output_data_csv(fin_res); | |
| 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(string name) { | |
| int A; | |
| bool seq_access = false; | |
| fast_access = true; | |
| 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 << name | |
| << ": DRAM model supports only conservative interconnect " | |
| << "projection but is set to aggressive!\n\n"; | |
| return false; | |
| } | |
| } | |
| uint32_t B = line_sz; | |
| if (B < 1) { | |
| cerr << name << ": Block size must be >= 1, but is set to " << B | |
| << endl; | |
| return false; | |
| } else if (B*8 < out_w) { | |
| cerr << name << ": Block size must be at least " << out_w / 8 | |
| << ", but is set to " << B << endl; | |
| return false; | |
| } | |
| if (F_sz_um <= 0) { | |
| cerr << name << ": Feature size must be > 0, but is set to " | |
| << F_sz_um << endl; | |
| return false; | |
| } else if (F_sz_um > 0.091) { | |
| cerr << name << ": Feature size must be <= 90 nm, but is set to " | |
| << F_sz_um << 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 << name << ": Must have at least one port" << endl; | |
| return false; | |
| } | |
| if (is_pow2(nbanks) == false) { | |
| cerr << name << ": Number of subbanks should be greater than or " | |
| << "equal to 1 and should be a power of 2, but is set to " | |
| << nbanks << endl; | |
| return false; | |
| } | |
| int C = cache_sz / nbanks; | |
| if (C < 64) { | |
| cerr << name << ": Cache size must be >=64, but is set to " << C | |
| << 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 << name | |
| << ": Pure CAM must have associativity as 0, but is set to" | |
| << assoc << endl; | |
| return false; | |
| } | |
| if (assoc == 0 && (pure_cam == false && is_cache == false)) { | |
| cerr << name | |
| << ": 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 << name | |
| << ": CAM and fully associative cache must have same device type " | |
| << "for both data and tag array" << endl; | |
| cerr << "\tData array RAM cell = " << data_arr_ram_cell_tech_type | |
| << ", Tag array RAM cell = " << tag_arr_ram_cell_tech_type << endl | |
| << "\tData array peripheral = " << data_arr_peri_global_tech_type | |
| << ", Tag array peripheral = " << tag_arr_peri_global_tech_type | |
| << 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 << name << ": 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 << name | |
| << ": CAM and fully associative cache cannot be as main memory" | |
| << endl; | |
| return false; | |
| } | |
| if ((fully_assoc || pure_cam) && SCHP < 1) { | |
| cerr << name | |
| << ": CAM and fully associative must have at least 1 search port," | |
| << " but are set to " << SCHP << 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 << name | |
| << ": Associativity must be a power of 2, but is set to " | |
| << A << endl; | |
| return false; | |
| } | |
| } | |
| } | |
| if (C / (B*A) <= 1 && assoc != 0) { | |
| cerr << name << ": Number of sets (" << (C / (B * A)) | |
| << ") 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 << name << ": " << temp | |
| << " Temperature must be between 300 and 400 Kelvin and multiple " | |
| << "of 10." << endl; | |
| return false; | |
| } | |
| if (nsets < 1) { | |
| cerr << name << ": Less than one set..." << endl; | |
| 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 << "Dynamic search energy (nJ), "; | |
| file << "Dynamic read energy (nJ), "; | |
| file << "Dynamic write energy (nJ), "; | |
| file << "Standby leakage per bank(mW), "; | |
| 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<<endl; | |
| } | |
| file.close(); | |
| } | |
| void output_UCA(uca_org_t *fr) { | |
| // 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 version 6.5, Uniform Cache Access " << | |
| "Logic Process Based DRAM Model ----------\n"; | |
| } else if (g_ip->data_arr_ram_cell_tech_type == 4) { | |
| cout << "\n---------- CACTI version 6.5, Uniform" << | |
| "Cache Access Commodity DRAM Model ----------\n"; | |
| } else { | |
| cout << "\n---------- CACTI version 6.5, Uniform Cache Access " | |
| "SRAM Model ----------\n"; | |
| } | |
| cout << "\nCache Parameters:\n"; | |
| cout << " Total cache size (bytes): " << | |
| (int) (g_ip->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 << endl; | |
| cout << " Cycle time (ns): " << fr->cycle_time*1e9 << 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 << 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 << endl; | |
| cout << " Total dynamic write energy per access (nJ): " << | |
| fr->power.writeOp.dynamic*1e9 << endl; | |
| // } | |
| cout << " Total leakage power of a bank" | |
| " (mW): " << fr->power.readOp.leakage*1e3 << endl; | |
| cout << " Total gate leakage power of a bank" | |
| " (mW): " << fr->power.readOp.gate_leakage*1e3 << 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 << endl; | |
| cout << " Best Ndwl : " << fr->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 << endl; | |
| exit(0); | |
| } | |
| if (!(g_ip->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 << endl; | |
| exit(-1); | |
| } | |
| } | |
| if (g_ip->print_detail) { | |
| /* Delay stats */ | |
| /* data array stats */ | |
| cout << endl << "Time Components:" << endl << endl; | |
| cout << " Data side (with Output driver) (ns): " << | |
| fr->data_array2->access_time / 1e-9 << endl; | |
| cout << "\tH-tree input delay (ns): " << | |
| fr->data_array2->delay_route_to_bank * 1e9 + | |
| fr->data_array2->delay_input_htree * 1e9 << 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 << endl; | |
| } else { | |
| cout << "\tCAM search delay (ns): " << | |
| fr->data_array2->delay_matchlines * 1e9 << endl; | |
| } | |
| cout << "\tBitline delay (ns): " << | |
| fr->data_array2->delay_bitlines / 1e-9 << endl; | |
| cout << "\tSense Amplifier delay (ns): " << | |
| fr->data_array2->delay_sense_amp * 1e9 << endl; | |
| cout << "\tH-tree output delay (ns): " << | |
| fr->data_array2->delay_subarray_output_driver * 1e9 + | |
| fr->data_array2->delay_dout_htree * 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 << endl; | |
| cout << "\tH-tree input delay (ns): " << | |
| fr->tag_array2->delay_route_to_bank * 1e9 + | |
| fr->tag_array2->delay_input_htree * 1e9 << endl; | |
| cout << "\tDecoder + wordline delay (ns): " << | |
| fr->tag_array2->delay_row_predecode_driver_and_block * 1e9 + | |
| fr->tag_array2->delay_row_decoder * 1e9 << endl; | |
| cout << "\tBitline delay (ns): " << | |
| fr->tag_array2->delay_bitlines / 1e-9 << endl; | |
| cout << "\tSense Amplifier delay (ns): " << | |
| fr->tag_array2->delay_sense_amp * 1e9 << endl; | |
| cout << "\tComparator delay (ns): " << | |
| fr->tag_array2->delay_comparator * 1e9 << endl; | |
| cout << "\tH-tree output delay (ns): " << | |
| fr->tag_array2->delay_subarray_output_driver * 1e9 + | |
| fr->tag_array2->delay_dout_htree * 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 << endl; | |
| cout << "\tTotal leakage read/write power of a bank (mW): " << | |
| fr->data_array2->power.readOp.leakage * 1e3 << 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 << "\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 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; | |
| 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 precharge and equalization circuit (nJ): " << | |
| fr->data_array2->power_prechg_eq_drivers.readOp.dynamic * 1e9 << endl; | |
| cout << "\tBitlines (nJ): " << | |
| fr->data_array2->power_bitlines.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; | |
| } | |
| else if (g_ip->pure_cam) { | |
| cout << " CAM array:" << endl; | |
| cout << " Total dynamic associative search energy/access (nJ): " << | |
| fr->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 << endl << " Total dynamic read energy/access (nJ): " << | |
| fr->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 { | |
| cout << " Fully associative array:" << endl; | |
| cout << " Total dynamic associative search energy/access (nJ): " << | |
| fr->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 << "\tData portion wordline (nJ): " << | |
| fr->data_array2->power_matchline_to_wordline_drv.searchOp.dynamic * 1e9 << endl; | |
| cout << "\tData Bitlines (nJ): " << | |
| fr->data_array2->power_bitlines.searchOp.dynamic * 1e9 + | |
| fr->data_array2->power_prechg_eq_drivers.searchOp.dynamic * 1e9 << endl; | |
| cout << "\tSense amplifier energy (nJ): " << | |
| fr->data_array2->power_sense_amps.searchOp.dynamic * 1e9 << endl; | |
| cout << "\tSub-array output driver (nJ): " << | |
| fr->data_array2->power_output_drivers_at_subarray.searchOp.dynamic * 1e9 << endl; | |
| cout << endl << " Total dynamic read energy/access (nJ): " << | |
| fr->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; | |
| } | |
| 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 << 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 (that includes both " | |
| "address and data transfer) (nJ): " << | |
| (fr->tag_array2->power_addr_input_htree.readOp.dynamic + | |
| fr->tag_array2->power_data_output_htree.readOp.dynamic + | |
| fr->tag_array2->power_routing_to_bank.readOp.dynamic) * 1e9 << 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 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 << "\tOutput Htree inside a bank Energy (nJ): " << | |
| fr->tag_array2->power_data_output_htree.readOp.dynamic * 1e9 << endl; | |
| cout << "\tDecoder (nJ): " << | |
| fr->tag_array2->power_row_predecoder_drivers.readOp.dynamic * 1e9 + | |
| fr->tag_array2->power_row_predecoder_blocks.readOp.dynamic * 1e9 << endl; | |
| cout << "\tWordline (nJ): " << | |
| fr->tag_array2->power_row_decoders.readOp.dynamic * 1e9 << 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 << 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 << endl; | |
| cout << "\tBitlines precharge and equalization circuit (nJ): " << | |
| fr->tag_array2->power_prechg_eq_drivers.readOp.dynamic * 1e9 << endl; | |
| cout << "\tBitlines (nJ): " << | |
| fr->tag_array2->power_bitlines.readOp.dynamic * 1e9 << endl; | |
| cout << "\tSense amplifier energy (nJ): " << | |
| fr->tag_array2->power_sense_amps.readOp.dynamic * 1e9 << endl; | |
| cout << "\tSub-array output driver (nJ): " << | |
| fr->tag_array2->power_output_drivers_at_subarray.readOp.dynamic * 1e9 << 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; | |
| } | |
| /* Tag array area stats */ | |
| if ((!(g_ip->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; | |
| } | |
| } | |
| Wire wpr; | |
| wpr.print_wire(); | |
| } | |
| } | |
| //McPAT's plain interface, please keep !!! | |
| uca_org_t cacti_interface(InputParameter * const local_interface) { | |
| uca_org_t fin_res; | |
| fin_res.valid = false; | |
| g_ip = local_interface; | |
| 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. | |
| solve(&fin_res); | |
| return fin_res; | |
| } | |
| //McPAT's plain interface, please keep !!! | |
| uca_org_t init_interface(InputParameter* const local_interface, | |
| const string &name) { | |
| uca_org_t fin_res; | |
| fin_res.valid = false; | |
| g_ip = local_interface; | |
| if (!g_ip->error_checking(name)) { | |
| exit(0); | |
| } | |
| init_tech_params(g_ip->F_sz_um, false); | |
| Wire winit; // Do not delete this line. It initializes wires. | |
| return fin_res; | |
| } | |
| void reconfigure(InputParameter *local_interface, uca_org_t *fin_res) | |
| { | |
| // Copy the InputParameter to global interface (g_ip) and do error checking. | |
| g_ip = local_interface; | |
| g_ip->error_checking(); | |
| // Initialize technology parameters | |
| init_tech_params(g_ip->F_sz_um,false); | |
| Wire winit; // Do not delete this line. It initializes wires. | |
| // This corresponds to solve() in the initialization process. | |
| update(fin_res); | |
| } |