110152Satgutier@umich.edu/*****************************************************************************
210152Satgutier@umich.edu *                                McPAT/CACTI
310152Satgutier@umich.edu *                      SOFTWARE LICENSE AGREEMENT
410152Satgutier@umich.edu *            Copyright 2012 Hewlett-Packard Development Company, L.P.
510234Syasuko.eckert@amd.com *            Copyright (c) 2010-2013 Advanced Micro Devices, Inc.
610152Satgutier@umich.edu *                          All Rights Reserved
710152Satgutier@umich.edu *
810152Satgutier@umich.edu * Redistribution and use in source and binary forms, with or without
910152Satgutier@umich.edu * modification, are permitted provided that the following conditions are
1010152Satgutier@umich.edu * met: redistributions of source code must retain the above copyright
1110152Satgutier@umich.edu * notice, this list of conditions and the following disclaimer;
1210152Satgutier@umich.edu * redistributions in binary form must reproduce the above copyright
1310152Satgutier@umich.edu * notice, this list of conditions and the following disclaimer in the
1410152Satgutier@umich.edu * documentation and/or other materials provided with the distribution;
1510152Satgutier@umich.edu * neither the name of the copyright holders nor the names of its
1610152Satgutier@umich.edu * contributors may be used to endorse or promote products derived from
1710152Satgutier@umich.edu * this software without specific prior written permission.
1810152Satgutier@umich.edu
1910152Satgutier@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2010152Satgutier@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2110152Satgutier@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2210152Satgutier@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2310152Satgutier@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2410152Satgutier@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2510152Satgutier@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2610152Satgutier@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2710152Satgutier@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2810152Satgutier@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2910234Syasuko.eckert@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3010152Satgutier@umich.edu *
3110152Satgutier@umich.edu ***************************************************************************/
3210152Satgutier@umich.edu
3310152Satgutier@umich.edu
3410152Satgutier@umich.edu
3510152Satgutier@umich.edu#include <iomanip>
3610152Satgutier@umich.edu#include <iostream>
3710152Satgutier@umich.edu#include <string>
3810152Satgutier@umich.edu
3910152Satgutier@umich.edu#include "area.h"
4010152Satgutier@umich.edu#include "parameter.h"
4110152Satgutier@umich.edu
4210152Satgutier@umich.eduusing namespace std;
4310152Satgutier@umich.edu
4410152Satgutier@umich.edu
4510152Satgutier@umich.eduInputParameter * g_ip;
4610152Satgutier@umich.eduTechnologyParameter g_tp;
4710152Satgutier@umich.edu
4810152Satgutier@umich.edu
4910152Satgutier@umich.edu
5010234Syasuko.eckert@amd.comvoid TechnologyParameter::DeviceType::display(uint32_t indent) {
5110234Syasuko.eckert@amd.com    string indent_str(indent, ' ');
5210152Satgutier@umich.edu
5310234Syasuko.eckert@amd.com    cout << indent_str << "C_g_ideal = " << setw(12) << C_g_ideal << " F/um" << endl;
5410234Syasuko.eckert@amd.com    cout << indent_str << "C_fringe  = " << setw(12) << C_fringe  << " F/um" << endl;
5510234Syasuko.eckert@amd.com    cout << indent_str << "C_overlap = " << setw(12) << C_overlap << " F/um" << endl;
5610234Syasuko.eckert@amd.com    cout << indent_str << "C_junc    = " << setw(12) << C_junc    << " F/um^2" << endl;
5710234Syasuko.eckert@amd.com    cout << indent_str << "l_phy     = " << setw(12) << l_phy     << " um" << endl;
5810234Syasuko.eckert@amd.com    cout << indent_str << "l_elec    = " << setw(12) << l_elec    << " um" << endl;
5910234Syasuko.eckert@amd.com    cout << indent_str << "R_nch_on  = " << setw(12) << R_nch_on  << " ohm-um" << endl;
6010234Syasuko.eckert@amd.com    cout << indent_str << "R_pch_on  = " << setw(12) << R_pch_on  << " ohm-um" << endl;
6110234Syasuko.eckert@amd.com    cout << indent_str << "Vdd       = " << setw(12) << Vdd       << " V" << endl;
6210234Syasuko.eckert@amd.com    cout << indent_str << "Vth       = " << setw(12) << Vth       << " V" << endl;
6310234Syasuko.eckert@amd.com    cout << indent_str << "I_on_n    = " << setw(12) << I_on_n    << " A/um" << endl;
6410234Syasuko.eckert@amd.com    cout << indent_str << "I_on_p    = " << setw(12) << I_on_p    << " A/um" << endl;
6510234Syasuko.eckert@amd.com    cout << indent_str << "I_off_n   = " << setw(12) << I_off_n   << " A/um" << endl;
6610234Syasuko.eckert@amd.com    cout << indent_str << "I_off_p   = " << setw(12) << I_off_p   << " A/um" << endl;
6710234Syasuko.eckert@amd.com    cout << indent_str << "C_ox      = " << setw(12) << C_ox      << " F/um^2" << endl;
6810234Syasuko.eckert@amd.com    cout << indent_str << "t_ox      = " << setw(12) << t_ox      << " um" << endl;
6910234Syasuko.eckert@amd.com    cout << indent_str << "n_to_p_eff_curr_drv_ratio = " << n_to_p_eff_curr_drv_ratio << endl;
7010152Satgutier@umich.edu}
7110152Satgutier@umich.edu
7210152Satgutier@umich.edu
7310152Satgutier@umich.edu
7410234Syasuko.eckert@amd.comvoid TechnologyParameter::InterconnectType::display(uint32_t indent) {
7510234Syasuko.eckert@amd.com    string indent_str(indent, ' ');
7610152Satgutier@umich.edu
7710234Syasuko.eckert@amd.com    cout << indent_str << "pitch    = " << setw(12) << pitch    << " um" << endl;
7810234Syasuko.eckert@amd.com    cout << indent_str << "R_per_um = " << setw(12) << R_per_um << " ohm/um" << endl;
7910234Syasuko.eckert@amd.com    cout << indent_str << "C_per_um = " << setw(12) << C_per_um << " F/um" << endl;
8010152Satgutier@umich.edu}
8110152Satgutier@umich.edu
8210234Syasuko.eckert@amd.comvoid TechnologyParameter::ScalingFactor::display(uint32_t indent) {
8310234Syasuko.eckert@amd.com    string indent_str(indent, ' ');
8410152Satgutier@umich.edu
8510234Syasuko.eckert@amd.com    cout << indent_str << "logic_scaling_co_eff    = " << setw(12) << logic_scaling_co_eff << endl;
8610234Syasuko.eckert@amd.com    cout << indent_str << "curr_core_tx_density = " << setw(12) << core_tx_density << " # of tx/um^2" << endl;
8710152Satgutier@umich.edu}
8810152Satgutier@umich.edu
8910234Syasuko.eckert@amd.comvoid TechnologyParameter::MemoryType::display(uint32_t indent) {
9010234Syasuko.eckert@amd.com    string indent_str(indent, ' ');
9110152Satgutier@umich.edu
9210234Syasuko.eckert@amd.com    cout << indent_str << "b_w         = " << setw(12) << b_w << " um" << endl;
9310234Syasuko.eckert@amd.com    cout << indent_str << "b_h         = " << setw(12) << b_h << " um" << endl;
9410234Syasuko.eckert@amd.com    cout << indent_str << "cell_a_w    = " << setw(12) << cell_a_w << " um" << endl;
9510234Syasuko.eckert@amd.com    cout << indent_str << "cell_pmos_w = " << setw(12) << cell_pmos_w << " um" << endl;
9610234Syasuko.eckert@amd.com    cout << indent_str << "cell_nmos_w = " << setw(12) << cell_nmos_w << " um" << endl;
9710234Syasuko.eckert@amd.com    cout << indent_str << "Vbitpre     = " << setw(12) << Vbitpre << " V" << endl;
9810152Satgutier@umich.edu}
9910152Satgutier@umich.edu
10010152Satgutier@umich.edu
10110152Satgutier@umich.edu
10210234Syasuko.eckert@amd.comvoid TechnologyParameter::display(uint32_t indent) {
10310234Syasuko.eckert@amd.com    string indent_str(indent, ' ');
10410152Satgutier@umich.edu
10510234Syasuko.eckert@amd.com    cout << indent_str << "ram_wl_stitching_overhead_ = " << setw(12) << ram_wl_stitching_overhead_ << " um" << endl;
10610234Syasuko.eckert@amd.com    cout << indent_str << "min_w_nmos_                = " << setw(12) << min_w_nmos_                << " um" << endl;
10710234Syasuko.eckert@amd.com    cout << indent_str << "max_w_nmos_                = " << setw(12) << max_w_nmos_                << " um" << endl;
10810234Syasuko.eckert@amd.com    cout << indent_str << "unit_len_wire_del          = " << setw(12) << unit_len_wire_del          << " s/um^2" << endl;
10910234Syasuko.eckert@amd.com    cout << indent_str << "FO4                        = " << setw(12) << FO4                        << " s" << endl;
11010234Syasuko.eckert@amd.com    cout << indent_str << "kinv                       = " << setw(12) << kinv                       << " s" << endl;
11110234Syasuko.eckert@amd.com    cout << indent_str << "vpp                        = " << setw(12) << vpp                        << " V" << endl;
11210234Syasuko.eckert@amd.com    cout << indent_str << "w_sense_en                 = " << setw(12) << w_sense_en                 << " um" << endl;
11310234Syasuko.eckert@amd.com    cout << indent_str << "w_sense_n                  = " << setw(12) << w_sense_n                  << " um" << endl;
11410234Syasuko.eckert@amd.com    cout << indent_str << "w_sense_p                  = " << setw(12) << w_sense_p                  << " um" << endl;
11510234Syasuko.eckert@amd.com    cout << indent_str << "w_iso                      = " << setw(12) << w_iso                      << " um" << endl;
11610234Syasuko.eckert@amd.com    cout << indent_str << "w_poly_contact             = " << setw(12) << w_poly_contact             << " um" << endl;
11710234Syasuko.eckert@amd.com    cout << indent_str << "spacing_poly_to_poly       = " << setw(12) << spacing_poly_to_poly       << " um" << endl;
11810234Syasuko.eckert@amd.com    cout << indent_str << "spacing_poly_to_contact    = " << setw(12) << spacing_poly_to_contact    << " um" << endl;
11910234Syasuko.eckert@amd.com    cout << endl;
12010234Syasuko.eckert@amd.com    cout << indent_str << "w_comp_inv_p1              = " << setw(12) << w_comp_inv_p1 << " um" << endl;
12110234Syasuko.eckert@amd.com    cout << indent_str << "w_comp_inv_p2              = " << setw(12) << w_comp_inv_p2 << " um" << endl;
12210234Syasuko.eckert@amd.com    cout << indent_str << "w_comp_inv_p3              = " << setw(12) << w_comp_inv_p3 << " um" << endl;
12310234Syasuko.eckert@amd.com    cout << indent_str << "w_comp_inv_n1              = " << setw(12) << w_comp_inv_n1 << " um" << endl;
12410234Syasuko.eckert@amd.com    cout << indent_str << "w_comp_inv_n2              = " << setw(12) << w_comp_inv_n2 << " um" << endl;
12510234Syasuko.eckert@amd.com    cout << indent_str << "w_comp_inv_n3              = " << setw(12) << w_comp_inv_n3 << " um" << endl;
12610234Syasuko.eckert@amd.com    cout << indent_str << "w_eval_inv_p               = " << setw(12) << w_eval_inv_p  << " um" << endl;
12710234Syasuko.eckert@amd.com    cout << indent_str << "w_eval_inv_n               = " << setw(12) << w_eval_inv_n  << " um" << endl;
12810234Syasuko.eckert@amd.com    cout << indent_str << "w_comp_n                   = " << setw(12) << w_comp_n      << " um" << endl;
12910234Syasuko.eckert@amd.com    cout << indent_str << "w_comp_p                   = " << setw(12) << w_comp_p      << " um" << endl;
13010234Syasuko.eckert@amd.com    cout << endl;
13110234Syasuko.eckert@amd.com    cout << indent_str << "dram_cell_I_on             = " << setw(12) << dram_cell_I_on << " A/um" << endl;
13210234Syasuko.eckert@amd.com    cout << indent_str << "dram_cell_Vdd              = " << setw(12) << dram_cell_Vdd  << " V" << endl;
13310234Syasuko.eckert@amd.com    cout << indent_str << "dram_cell_I_off_worst_case_len_temp = " << setw(12) << dram_cell_I_off_worst_case_len_temp << " A/um" << endl;
13410234Syasuko.eckert@amd.com    cout << indent_str << "dram_cell_C                = " << setw(12) << dram_cell_C               << " F" << endl;
13510234Syasuko.eckert@amd.com    cout << indent_str << "gm_sense_amp_latch         = " << setw(12) << gm_sense_amp_latch        << " F/s" << endl;
13610234Syasuko.eckert@amd.com    cout << endl;
13710234Syasuko.eckert@amd.com    cout << indent_str << "w_nmos_b_mux               = " << setw(12) << w_nmos_b_mux              << " um" << endl;
13810234Syasuko.eckert@amd.com    cout << indent_str << "w_nmos_sa_mux              = " << setw(12) << w_nmos_sa_mux             << " um" << endl;
13910234Syasuko.eckert@amd.com    cout << indent_str << "w_pmos_bl_precharge        = " << setw(12) << w_pmos_bl_precharge       << " um" << endl;
14010234Syasuko.eckert@amd.com    cout << indent_str << "w_pmos_bl_eq               = " << setw(12) << w_pmos_bl_eq              << " um" << endl;
14110234Syasuko.eckert@amd.com    cout << indent_str << "MIN_GAP_BET_P_AND_N_DIFFS  = " << setw(12) << MIN_GAP_BET_P_AND_N_DIFFS << " um" << endl;
14210234Syasuko.eckert@amd.com    cout << indent_str << "HPOWERRAIL                 = " << setw(12) << HPOWERRAIL                << " um" << endl;
14310234Syasuko.eckert@amd.com    cout << indent_str << "cell_h_def                 = " << setw(12) << cell_h_def                << " um" << endl;
14410152Satgutier@umich.edu
14510234Syasuko.eckert@amd.com    cout << endl;
14610234Syasuko.eckert@amd.com    cout << indent_str << "SRAM cell transistor: " << endl;
14710234Syasuko.eckert@amd.com    sram_cell.display(indent + 2);
14810152Satgutier@umich.edu
14910234Syasuko.eckert@amd.com    cout << endl;
15010234Syasuko.eckert@amd.com    cout << indent_str << "DRAM access transistor: " << endl;
15110234Syasuko.eckert@amd.com    dram_acc.display(indent + 2);
15210152Satgutier@umich.edu
15310234Syasuko.eckert@amd.com    cout << endl;
15410234Syasuko.eckert@amd.com    cout << indent_str << "DRAM wordline transistor: " << endl;
15510234Syasuko.eckert@amd.com    dram_wl.display(indent + 2);
15610152Satgutier@umich.edu
15710234Syasuko.eckert@amd.com    cout << endl;
15810234Syasuko.eckert@amd.com    cout << indent_str << "peripheral global transistor: " << endl;
15910234Syasuko.eckert@amd.com    peri_global.display(indent + 2);
16010152Satgutier@umich.edu
16110234Syasuko.eckert@amd.com    cout << endl;
16210234Syasuko.eckert@amd.com    cout << indent_str << "wire local" << endl;
16310234Syasuko.eckert@amd.com    wire_local.display(indent + 2);
16410152Satgutier@umich.edu
16510234Syasuko.eckert@amd.com    cout << endl;
16610234Syasuko.eckert@amd.com    cout << indent_str << "wire inside mat" << endl;
16710234Syasuko.eckert@amd.com    wire_inside_mat.display(indent + 2);
16810152Satgutier@umich.edu
16910234Syasuko.eckert@amd.com    cout << endl;
17010234Syasuko.eckert@amd.com    cout << indent_str << "wire outside mat" << endl;
17110234Syasuko.eckert@amd.com    wire_outside_mat.display(indent + 2);
17210152Satgutier@umich.edu
17310234Syasuko.eckert@amd.com    cout << endl;
17410234Syasuko.eckert@amd.com    cout << indent_str << "SRAM" << endl;
17510234Syasuko.eckert@amd.com    sram.display(indent + 2);
17610152Satgutier@umich.edu
17710234Syasuko.eckert@amd.com    cout << endl;
17810234Syasuko.eckert@amd.com    cout << indent_str << "DRAM" << endl;
17910234Syasuko.eckert@amd.com    dram.display(indent + 2);
18010152Satgutier@umich.edu}
18110152Satgutier@umich.edu
18210152Satgutier@umich.edu
18310152Satgutier@umich.eduDynamicParameter::DynamicParameter():
18410234Syasuko.eckert@amd.com        use_inp_params(0), cell(), is_valid(true) {
18510152Satgutier@umich.edu}
18610152Satgutier@umich.edu
18710152Satgutier@umich.edu
18810152Satgutier@umich.edu
18910152Satgutier@umich.eduDynamicParameter::DynamicParameter(
19010152Satgutier@umich.edu    bool is_tag_,
19110152Satgutier@umich.edu    int pure_ram_,
19210152Satgutier@umich.edu    int pure_cam_,
19310152Satgutier@umich.edu    double Nspd_,
19410152Satgutier@umich.edu    unsigned int Ndwl_,
19510152Satgutier@umich.edu    unsigned int Ndbl_,
19610152Satgutier@umich.edu    unsigned int Ndcm_,
19710152Satgutier@umich.edu    unsigned int Ndsam_lev_1_,
19810152Satgutier@umich.edu    unsigned int Ndsam_lev_2_,
19910152Satgutier@umich.edu    bool is_main_mem_):
20010234Syasuko.eckert@amd.com    is_tag(is_tag_), pure_ram(pure_ram_), pure_cam(pure_cam_), tagbits(0),
20110234Syasuko.eckert@amd.com    Nspd(Nspd_), Ndwl(Ndwl_), Ndbl(Ndbl_), Ndcm(Ndcm_),
20210234Syasuko.eckert@amd.com    Ndsam_lev_1(Ndsam_lev_1_), Ndsam_lev_2(Ndsam_lev_2_),
20310234Syasuko.eckert@amd.com    number_way_select_signals_mat(0), V_b_sense(0), use_inp_params(0),
20410234Syasuko.eckert@amd.com    is_main_mem(is_main_mem_), cell(), is_valid(false) {
20510234Syasuko.eckert@amd.com    ram_cell_tech_type = (is_tag) ? g_ip->tag_arr_ram_cell_tech_type : g_ip->data_arr_ram_cell_tech_type;
20610234Syasuko.eckert@amd.com    is_dram            = ((ram_cell_tech_type == lp_dram) || (ram_cell_tech_type == comm_dram));
20710152Satgutier@umich.edu
20810234Syasuko.eckert@amd.com    unsigned int capacity_per_die = g_ip->cache_sz / NUMBER_STACKED_DIE_LAYERS;  // capacity per stacked die layer
20910234Syasuko.eckert@amd.com    const TechnologyParameter::InterconnectType & wire_local = g_tp.wire_local;
21010234Syasuko.eckert@amd.com    fully_assoc = (g_ip->fully_assoc) ? true : false;
21110152Satgutier@umich.edu
21210234Syasuko.eckert@amd.com    // fully-assocative cache -- ref: CACTi 2.0 report
21310234Syasuko.eckert@amd.com    if (fully_assoc || pure_cam) {
21410234Syasuko.eckert@amd.com        if (Ndwl != 1 ||            //Ndwl is fixed to 1 for FA
21510234Syasuko.eckert@amd.com                Ndcm != 1 ||            //Ndcm is fixed to 1 for FA
21610234Syasuko.eckert@amd.com                Nspd < 1 || Nspd > 1 || //Nspd is fixed to 1 for FA
21710234Syasuko.eckert@amd.com                Ndsam_lev_1 != 1 ||     //Ndsam_lev_1 is fixed to one
21810234Syasuko.eckert@amd.com                Ndsam_lev_2 != 1 ||     //Ndsam_lev_2 is fixed to one
21910234Syasuko.eckert@amd.com                Ndbl < 2) {
22010234Syasuko.eckert@amd.com            return;
22110234Syasuko.eckert@amd.com        }
22210234Syasuko.eckert@amd.com    }
22310152Satgutier@umich.edu
22410234Syasuko.eckert@amd.com    if ((is_dram) && (!is_tag) && (Ndcm > 1)) {
22510234Syasuko.eckert@amd.com        return;  // For a DRAM array, each bitline has its own sense-amp
22610234Syasuko.eckert@amd.com    }
22710152Satgutier@umich.edu
22810234Syasuko.eckert@amd.com    // If it's not an FA tag/data array, Ndwl should be at least two and Ndbl should be
22910234Syasuko.eckert@amd.com    // at least two because an array is assumed to have at least one mat. And a mat
23010234Syasuko.eckert@amd.com    // is formed out of two horizontal subarrays and two vertical subarrays
23110234Syasuko.eckert@amd.com    if (fully_assoc == false && (Ndwl < 1 || Ndbl < 1)) {
23210234Syasuko.eckert@amd.com        return;
23310234Syasuko.eckert@amd.com    }
23410152Satgutier@umich.edu
23510234Syasuko.eckert@amd.com    //***********compute row, col of an subarray
23610234Syasuko.eckert@amd.com    if (!(fully_assoc || pure_cam)) {
23710234Syasuko.eckert@amd.com        //Not fully_asso nor cam
23810234Syasuko.eckert@amd.com        // if data array, let tagbits = 0
23910234Syasuko.eckert@amd.com        if (is_tag) {
24010234Syasuko.eckert@amd.com            if (g_ip->specific_tag) {
24110234Syasuko.eckert@amd.com                tagbits = g_ip->tag_w;
24210234Syasuko.eckert@amd.com            } else {
24310234Syasuko.eckert@amd.com                tagbits = ADDRESS_BITS + EXTRA_TAG_BITS - _log2(capacity_per_die) +
24410234Syasuko.eckert@amd.com                          _log2(g_ip->tag_assoc * 2 - 1) - _log2(g_ip->nbanks);
24510152Satgutier@umich.edu
24610234Syasuko.eckert@amd.com            }
24710234Syasuko.eckert@amd.com            tagbits = (((tagbits + 3) >> 2) << 2);
24810152Satgutier@umich.edu
24910234Syasuko.eckert@amd.com            num_r_subarray = (int)ceil(capacity_per_die / (g_ip->nbanks *
25010234Syasuko.eckert@amd.com                                       g_ip->block_sz * g_ip->tag_assoc * Ndbl * Nspd));// + EPSILON);
25110234Syasuko.eckert@amd.com            num_c_subarray = (int)ceil((tagbits * g_ip->tag_assoc * Nspd / Ndwl));// + EPSILON);
25210234Syasuko.eckert@amd.com            //burst_length = 1;
25310234Syasuko.eckert@amd.com        } else {
25410234Syasuko.eckert@amd.com            num_r_subarray = (int)ceil(capacity_per_die / (g_ip->nbanks *
25510234Syasuko.eckert@amd.com                                       g_ip->block_sz * g_ip->data_assoc * Ndbl * Nspd));// + EPSILON);
25610234Syasuko.eckert@amd.com            num_c_subarray = (int)ceil((8 * g_ip->block_sz * g_ip->data_assoc * Nspd / Ndwl));// + EPSILON); + EPSILON);
25710234Syasuko.eckert@amd.com            // burst_length = g_ip->block_sz * 8 / g_ip->out_w;
25810234Syasuko.eckert@amd.com        }
25910152Satgutier@umich.edu
26010234Syasuko.eckert@amd.com        if (num_r_subarray < MINSUBARRAYROWS) return;
26110234Syasuko.eckert@amd.com        if (num_r_subarray == 0) return;
26210234Syasuko.eckert@amd.com        if (num_r_subarray > MAXSUBARRAYROWS) return;
26310234Syasuko.eckert@amd.com        if (num_c_subarray < MINSUBARRAYCOLS) return;
26410234Syasuko.eckert@amd.com        if (num_c_subarray > MAXSUBARRAYCOLS) return;
26510152Satgutier@umich.edu
26610234Syasuko.eckert@amd.com    }
26710152Satgutier@umich.edu
26810234Syasuko.eckert@amd.com    else {//either fully-asso or cam
26910234Syasuko.eckert@amd.com        if (pure_cam) {
27010234Syasuko.eckert@amd.com            if (g_ip->specific_tag) {
27110234Syasuko.eckert@amd.com                tagbits = int(ceil(g_ip->tag_w / 8.0) * 8);
27210234Syasuko.eckert@amd.com            } else {
27310234Syasuko.eckert@amd.com                tagbits = int(ceil((ADDRESS_BITS + EXTRA_TAG_BITS) / 8.0) * 8);
27410152Satgutier@umich.edu//			  cout<<"Pure CAM needs tag width to be specified"<<endl;
27510152Satgutier@umich.edu//			  exit(0);
27610234Syasuko.eckert@amd.com            }
27710234Syasuko.eckert@amd.com            //tagbits = (((tagbits + 3) >> 2) << 2);
27810152Satgutier@umich.edu
27910234Syasuko.eckert@amd.com            //TODO: error check input of tagbits and blocksize
28010234Syasuko.eckert@amd.com            //TODO: for pure CAM, g_ip->block should be number of entries.
28110234Syasuko.eckert@amd.com            tag_num_r_subarray = (int)ceil(capacity_per_die /
28210234Syasuko.eckert@amd.com                                           (g_ip->nbanks * tagbits / 8.0 * Ndbl));
28310234Syasuko.eckert@amd.com            //tag_num_c_subarray = (int)(tagbits  + EPSILON);
28410234Syasuko.eckert@amd.com            tag_num_c_subarray = tagbits;
28510234Syasuko.eckert@amd.com            if (tag_num_r_subarray == 0) return;
28610234Syasuko.eckert@amd.com            if (tag_num_r_subarray > MAXSUBARRAYROWS) return;
28710234Syasuko.eckert@amd.com            if (tag_num_c_subarray < MINSUBARRAYCOLS) return;
28810234Syasuko.eckert@amd.com            if (tag_num_c_subarray > MAXSUBARRAYCOLS) return;
28910234Syasuko.eckert@amd.com            num_r_subarray = tag_num_r_subarray;
29010234Syasuko.eckert@amd.com        } else { //fully associative
29110234Syasuko.eckert@amd.com            if (g_ip->specific_tag) {
29210234Syasuko.eckert@amd.com                tagbits = g_ip->tag_w;
29310234Syasuko.eckert@amd.com            } else {
29410234Syasuko.eckert@amd.com                tagbits = ADDRESS_BITS + EXTRA_TAG_BITS - _log2(g_ip->block_sz);//TODO: should be the page_offset=log2(page size), but this info is not avail with CACTI, for McPAT this is no problem.
29510234Syasuko.eckert@amd.com            }
29610234Syasuko.eckert@amd.com            tagbits = (((tagbits + 3) >> 2) << 2);
29710152Satgutier@umich.edu
29810234Syasuko.eckert@amd.com            tag_num_r_subarray = (int)(capacity_per_die /
29910234Syasuko.eckert@amd.com                                       (g_ip->nbanks * g_ip->block_sz * Ndbl));
30010234Syasuko.eckert@amd.com            tag_num_c_subarray = (int)ceil((tagbits * Nspd / Ndwl));// + EPSILON);
30110234Syasuko.eckert@amd.com            if (tag_num_r_subarray == 0) return;
30210234Syasuko.eckert@amd.com            if (tag_num_r_subarray > MAXSUBARRAYROWS) return;
30310234Syasuko.eckert@amd.com            if (tag_num_c_subarray < MINSUBARRAYCOLS) return;
30410234Syasuko.eckert@amd.com            if (tag_num_c_subarray > MAXSUBARRAYCOLS) return;
30510152Satgutier@umich.edu
30610234Syasuko.eckert@amd.com            data_num_r_subarray = tag_num_r_subarray;
30710234Syasuko.eckert@amd.com            data_num_c_subarray = 8 * g_ip->block_sz;
30810234Syasuko.eckert@amd.com            if (data_num_r_subarray == 0) return;
30910234Syasuko.eckert@amd.com            if (data_num_r_subarray > MAXSUBARRAYROWS) return;
31010234Syasuko.eckert@amd.com            if (data_num_c_subarray < MINSUBARRAYCOLS) return;
31110234Syasuko.eckert@amd.com            if (data_num_c_subarray > MAXSUBARRAYCOLS) return;
31210234Syasuko.eckert@amd.com            num_r_subarray = tag_num_r_subarray;
31310234Syasuko.eckert@amd.com        }
31410234Syasuko.eckert@amd.com    }
31510152Satgutier@umich.edu
31610234Syasuko.eckert@amd.com    num_subarrays = Ndwl * Ndbl;
31710234Syasuko.eckert@amd.com    //****************end of computation of row, col of an subarray
31810152Satgutier@umich.edu
31910234Syasuko.eckert@amd.com    // calculate wire parameters
32010234Syasuko.eckert@amd.com    if (fully_assoc || pure_cam) {
32110234Syasuko.eckert@amd.com        cam_cell.h = g_tp.cam.b_h + 2 * wire_local.pitch *
32210234Syasuko.eckert@amd.com            (g_ip->num_rw_ports - 1 + g_ip->num_rd_ports + g_ip->num_wr_ports)
32310234Syasuko.eckert@amd.com            + 2 * wire_local.pitch * (g_ip->num_search_ports - 1) +
32410234Syasuko.eckert@amd.com            wire_local.pitch * g_ip->num_se_rd_ports;
32510234Syasuko.eckert@amd.com        cam_cell.w = g_tp.cam.b_w + 2 * wire_local.pitch *
32610234Syasuko.eckert@amd.com            (g_ip->num_rw_ports - 1 + g_ip->num_rd_ports + g_ip->num_wr_ports)
32710234Syasuko.eckert@amd.com            + 2 * wire_local.pitch * (g_ip->num_search_ports - 1) +
32810234Syasuko.eckert@amd.com            wire_local.pitch * g_ip->num_se_rd_ports;
32910152Satgutier@umich.edu
33010234Syasuko.eckert@amd.com        cell.h = g_tp.sram.b_h + 2 * wire_local.pitch *
33110234Syasuko.eckert@amd.com            (g_ip->num_wr_ports + g_ip->num_rw_ports - 1 + g_ip->num_rd_ports)
33210234Syasuko.eckert@amd.com            + 2 * wire_local.pitch * (g_ip->num_search_ports - 1);
33310234Syasuko.eckert@amd.com        cell.w = g_tp.sram.b_w + 2 * wire_local.pitch *
33410234Syasuko.eckert@amd.com            (g_ip->num_rw_ports - 1 + (g_ip->num_rd_ports -
33510234Syasuko.eckert@amd.com                                       g_ip->num_se_rd_ports)
33610234Syasuko.eckert@amd.com             + g_ip->num_wr_ports) + g_tp.wire_local.pitch *
33710234Syasuko.eckert@amd.com            g_ip->num_se_rd_ports + 2 * wire_local.pitch *
33810234Syasuko.eckert@amd.com            (g_ip->num_search_ports - 1);
33910234Syasuko.eckert@amd.com    } else {
34010234Syasuko.eckert@amd.com        if (is_tag) {
34110234Syasuko.eckert@amd.com            cell.h = g_tp.sram.b_h + 2 * wire_local.pitch * (g_ip->num_rw_ports - 1 + g_ip->num_rd_ports +
34210234Syasuko.eckert@amd.com                     g_ip->num_wr_ports);
34310234Syasuko.eckert@amd.com            cell.w = g_tp.sram.b_w + 2 * wire_local.pitch * (g_ip->num_rw_ports - 1 + g_ip->num_wr_ports +
34410234Syasuko.eckert@amd.com                     (g_ip->num_rd_ports - g_ip->num_se_rd_ports)) +
34510234Syasuko.eckert@amd.com                     wire_local.pitch * g_ip->num_se_rd_ports;
34610234Syasuko.eckert@amd.com        } else {
34710234Syasuko.eckert@amd.com            if (is_dram) {
34810234Syasuko.eckert@amd.com                cell.h = g_tp.dram.b_h;
34910234Syasuko.eckert@amd.com                cell.w = g_tp.dram.b_w;
35010234Syasuko.eckert@amd.com            } else {
35110234Syasuko.eckert@amd.com                cell.h = g_tp.sram.b_h + 2 * wire_local.pitch * (g_ip->num_wr_ports +
35210234Syasuko.eckert@amd.com                         g_ip->num_rw_ports - 1 + g_ip->num_rd_ports);
35310234Syasuko.eckert@amd.com                cell.w = g_tp.sram.b_w + 2 * wire_local.pitch * (g_ip->num_rw_ports - 1 +
35410234Syasuko.eckert@amd.com                         (g_ip->num_rd_ports - g_ip->num_se_rd_ports) +
35510234Syasuko.eckert@amd.com                         g_ip->num_wr_ports) + g_tp.wire_local.pitch * g_ip->num_se_rd_ports;
35610234Syasuko.eckert@amd.com            }
35710234Syasuko.eckert@amd.com        }
35810234Syasuko.eckert@amd.com    }
35910152Satgutier@umich.edu
36010234Syasuko.eckert@amd.com    double c_b_metal = cell.h * wire_local.C_per_um;
36110234Syasuko.eckert@amd.com    double C_bl;
36210152Satgutier@umich.edu
36310234Syasuko.eckert@amd.com    if (!(fully_assoc || pure_cam)) {
36410234Syasuko.eckert@amd.com        if (is_dram) {
36510234Syasuko.eckert@amd.com            deg_bl_muxing = 1;
36610234Syasuko.eckert@amd.com            if (ram_cell_tech_type == comm_dram) {
36710234Syasuko.eckert@amd.com                C_bl  = num_r_subarray * c_b_metal;
36810234Syasuko.eckert@amd.com                V_b_sense = (g_tp.dram_cell_Vdd / 2) * g_tp.dram_cell_C /
36910234Syasuko.eckert@amd.com                    (g_tp.dram_cell_C + C_bl);
37010234Syasuko.eckert@amd.com                if (V_b_sense < VBITSENSEMIN) {
37110234Syasuko.eckert@amd.com                    return;
37210234Syasuko.eckert@amd.com                }
37310234Syasuko.eckert@amd.com                V_b_sense = VBITSENSEMIN;  // in any case, we fix sense amp input signal to a constant value
37410234Syasuko.eckert@amd.com                dram_refresh_period = 64e-3;
37510234Syasuko.eckert@amd.com            } else {
37610234Syasuko.eckert@amd.com                double Cbitrow_drain_cap = drain_C_(g_tp.dram.cell_a_w, NCH, 1, 0, cell.w, true, true) / 2.0;
37710234Syasuko.eckert@amd.com                C_bl  = num_r_subarray * (Cbitrow_drain_cap + c_b_metal);
37810234Syasuko.eckert@amd.com                V_b_sense = (g_tp.dram_cell_Vdd / 2) * g_tp.dram_cell_C /
37910234Syasuko.eckert@amd.com                    (g_tp.dram_cell_C + C_bl);
38010152Satgutier@umich.edu
38110234Syasuko.eckert@amd.com                if (V_b_sense < VBITSENSEMIN) {
38210234Syasuko.eckert@amd.com                    return; //Sense amp input signal is smaller that minimum allowable sense amp input signal
38310234Syasuko.eckert@amd.com                }
38410234Syasuko.eckert@amd.com                V_b_sense = VBITSENSEMIN; // in any case, we fix sense amp input signal to a constant value
38510234Syasuko.eckert@amd.com                //v_storage_worst = g_tp.dram_cell_Vdd / 2 - VBITSENSEMIN * (g_tp.dram_cell_C + C_bl) / g_tp.dram_cell_C;
38610234Syasuko.eckert@amd.com                //dram_refresh_period = 1.1 * g_tp.dram_cell_C * v_storage_worst / g_tp.dram_cell_I_off_worst_case_len_temp;
38710234Syasuko.eckert@amd.com                dram_refresh_period = 0.9 * g_tp.dram_cell_C * VDD_STORAGE_LOSS_FRACTION_WORST * g_tp.dram_cell_Vdd / g_tp.dram_cell_I_off_worst_case_len_temp;
38810234Syasuko.eckert@amd.com            }
38910234Syasuko.eckert@amd.com        } else { //SRAM
39010234Syasuko.eckert@amd.com            V_b_sense = (0.05 * g_tp.sram_cell.Vdd > VBITSENSEMIN) ? 0.05 * g_tp.sram_cell.Vdd : VBITSENSEMIN;
39110234Syasuko.eckert@amd.com            deg_bl_muxing = Ndcm;
39210234Syasuko.eckert@amd.com            // "/ 2.0" below is due to the fact that two adjacent access transistors share drain
39310234Syasuko.eckert@amd.com            // contacts in a physical layout
39410234Syasuko.eckert@amd.com            double Cbitrow_drain_cap = drain_C_(g_tp.sram.cell_a_w, NCH, 1, 0, cell.w, false, true) / 2.0;
39510234Syasuko.eckert@amd.com            C_bl = num_r_subarray * (Cbitrow_drain_cap + c_b_metal);
39610234Syasuko.eckert@amd.com            dram_refresh_period = 0;
39710234Syasuko.eckert@amd.com        }
39810234Syasuko.eckert@amd.com    } else {
39910234Syasuko.eckert@amd.com        c_b_metal = cam_cell.h * wire_local.C_per_um;//IBM and SUN design, SRAM array uses dummy cells to fill the blank space due to mismatch on CAM-RAM
40010234Syasuko.eckert@amd.com        V_b_sense = (0.05 * g_tp.sram_cell.Vdd > VBITSENSEMIN) ? 0.05 * g_tp.sram_cell.Vdd : VBITSENSEMIN;
40110234Syasuko.eckert@amd.com        deg_bl_muxing = 1;//FA fix as 1
40210234Syasuko.eckert@amd.com        // "/ 2.0" below is due to the fact that two adjacent access transistors share drain
40310234Syasuko.eckert@amd.com        // contacts in a physical layout
40410234Syasuko.eckert@amd.com        double Cbitrow_drain_cap = drain_C_(g_tp.cam.cell_a_w, NCH, 1, 0, cam_cell.w, false, true) / 2.0;//TODO: comment out these two lines
40510234Syasuko.eckert@amd.com        C_bl = num_r_subarray * (Cbitrow_drain_cap + c_b_metal);
40610234Syasuko.eckert@amd.com        dram_refresh_period = 0;
40710234Syasuko.eckert@amd.com    }
40810152Satgutier@umich.edu
40910152Satgutier@umich.edu
41010234Syasuko.eckert@amd.com    // do/di: data in/out, for fully associative they are the data width for normal read and write
41110234Syasuko.eckert@amd.com    // so/si: search data in/out, for fully associative they are the data width for the search ops
41210234Syasuko.eckert@amd.com    // for CAM, si=di, but so = matching address. do = data out = di (for normal read/write)
41310234Syasuko.eckert@amd.com    // so/si needs broadcase while do/di do not
41410152Satgutier@umich.edu
41510234Syasuko.eckert@amd.com    if (fully_assoc || pure_cam) {
41610234Syasuko.eckert@amd.com        switch (Ndbl) {
41710234Syasuko.eckert@amd.com        case (0):
41810234Syasuko.eckert@amd.com            cout <<  "   Invalid Ndbl \n" << endl;
41910234Syasuko.eckert@amd.com            exit(0);
42010234Syasuko.eckert@amd.com            break;
42110234Syasuko.eckert@amd.com        case (1):
42210234Syasuko.eckert@amd.com            num_mats_h_dir = 1;//one subarray per mat
42310234Syasuko.eckert@amd.com            num_mats_v_dir = 1;
42410234Syasuko.eckert@amd.com            break;
42510234Syasuko.eckert@amd.com        case (2):
42610234Syasuko.eckert@amd.com            num_mats_h_dir = 1;//two subarrays per mat
42710234Syasuko.eckert@amd.com            num_mats_v_dir = 1;
42810234Syasuko.eckert@amd.com            break;
42910234Syasuko.eckert@amd.com        default:
43010234Syasuko.eckert@amd.com            num_mats_h_dir = int(floor(sqrt(Ndbl / 4.0)));//4 subbarrys per mat
43110234Syasuko.eckert@amd.com            num_mats_v_dir = int(Ndbl / 4.0 / num_mats_h_dir);
43210234Syasuko.eckert@amd.com        }
43310234Syasuko.eckert@amd.com        num_mats = num_mats_h_dir * num_mats_v_dir;
43410234Syasuko.eckert@amd.com
43510234Syasuko.eckert@amd.com        if (fully_assoc) {
43610234Syasuko.eckert@amd.com            num_so_b_mat   = data_num_c_subarray;
43710234Syasuko.eckert@amd.com            num_do_b_mat   = data_num_c_subarray + tagbits;
43810234Syasuko.eckert@amd.com        } else {
43910234Syasuko.eckert@amd.com            num_so_b_mat = int(ceil(log2(num_r_subarray)) + ceil(log2(num_subarrays)));//the address contains the matched data
44010234Syasuko.eckert@amd.com            num_do_b_mat = tagbits;
44110234Syasuko.eckert@amd.com        }
44210234Syasuko.eckert@amd.com    } else {
44310234Syasuko.eckert@amd.com        num_mats_h_dir = MAX(Ndwl / 2, 1);
44410234Syasuko.eckert@amd.com        num_mats_v_dir = MAX(Ndbl / 2, 1);
44510234Syasuko.eckert@amd.com        num_mats       = num_mats_h_dir * num_mats_v_dir;
44610234Syasuko.eckert@amd.com        num_do_b_mat = MAX((num_subarrays / num_mats) * num_c_subarray /
44710234Syasuko.eckert@amd.com                           (deg_bl_muxing * Ndsam_lev_1 * Ndsam_lev_2), 1);
44810234Syasuko.eckert@amd.com    }
44910234Syasuko.eckert@amd.com
45010234Syasuko.eckert@amd.com    if (!(fully_assoc || pure_cam) && (num_do_b_mat <
45110234Syasuko.eckert@amd.com                                       (num_subarrays / num_mats))) {
45210234Syasuko.eckert@amd.com        return;
45310234Syasuko.eckert@amd.com    }
45410234Syasuko.eckert@amd.com
45510234Syasuko.eckert@amd.com
45610234Syasuko.eckert@amd.com    int deg_sa_mux_l1_non_assoc;
45710234Syasuko.eckert@amd.com    //TODO:the i/o for subbank is not necessary and should be removed.
45810234Syasuko.eckert@amd.com    if (!(fully_assoc || pure_cam)) {
45910234Syasuko.eckert@amd.com        if (!is_tag) {
46010234Syasuko.eckert@amd.com            if (is_main_mem == true) {
46110234Syasuko.eckert@amd.com                num_do_b_subbank = g_ip->int_prefetch_w * g_ip->out_w;
46210234Syasuko.eckert@amd.com                deg_sa_mux_l1_non_assoc = Ndsam_lev_1;
46310234Syasuko.eckert@amd.com            } else {
46410234Syasuko.eckert@amd.com                if (g_ip->fast_access == true) {
46510234Syasuko.eckert@amd.com                    num_do_b_subbank = g_ip->out_w * g_ip->data_assoc;
46610234Syasuko.eckert@amd.com                    deg_sa_mux_l1_non_assoc = Ndsam_lev_1;
46710234Syasuko.eckert@amd.com                } else {
46810234Syasuko.eckert@amd.com
46910234Syasuko.eckert@amd.com                    num_do_b_subbank = g_ip->out_w;
47010234Syasuko.eckert@amd.com                    deg_sa_mux_l1_non_assoc = Ndsam_lev_1 / g_ip->data_assoc;
47110234Syasuko.eckert@amd.com                    if (deg_sa_mux_l1_non_assoc < 1) {
47210234Syasuko.eckert@amd.com                        return;
47310234Syasuko.eckert@amd.com                    }
47410234Syasuko.eckert@amd.com
47510234Syasuko.eckert@amd.com                }
47610152Satgutier@umich.edu            }
47710234Syasuko.eckert@amd.com        } else {
47810234Syasuko.eckert@amd.com            num_do_b_subbank = tagbits * g_ip->tag_assoc;
47910234Syasuko.eckert@amd.com            if (num_do_b_mat < tagbits) {
48010234Syasuko.eckert@amd.com                return;
48110234Syasuko.eckert@amd.com            }
48210234Syasuko.eckert@amd.com            deg_sa_mux_l1_non_assoc = Ndsam_lev_1;
48310234Syasuko.eckert@amd.com            //num_do_b_mat = g_ip->tag_assoc / num_mats_h_dir;
48410234Syasuko.eckert@amd.com        }
48510234Syasuko.eckert@amd.com    } else {
48610234Syasuko.eckert@amd.com        if (fully_assoc) {
48710234Syasuko.eckert@amd.com            num_so_b_subbank = 8 * g_ip->block_sz;//TODO:internal perfetch should be considered also for fa
48810234Syasuko.eckert@amd.com            num_do_b_subbank = num_so_b_subbank + tag_num_c_subarray;
48910234Syasuko.eckert@amd.com        } else {
49010234Syasuko.eckert@amd.com            num_so_b_subbank = int(ceil(log2(num_r_subarray)) + ceil(log2(num_subarrays)));//the address contains the matched data
49110234Syasuko.eckert@amd.com            num_do_b_subbank = tag_num_c_subarray;
49210234Syasuko.eckert@amd.com        }
49310152Satgutier@umich.edu
49410234Syasuko.eckert@amd.com        deg_sa_mux_l1_non_assoc = 1;
49510234Syasuko.eckert@amd.com    }
49610152Satgutier@umich.edu
49710234Syasuko.eckert@amd.com    deg_senseamp_muxing_non_associativity = deg_sa_mux_l1_non_assoc;
49810152Satgutier@umich.edu
49910234Syasuko.eckert@amd.com    if (fully_assoc || pure_cam) {
50010234Syasuko.eckert@amd.com        num_act_mats_hor_dir = 1;
50110234Syasuko.eckert@amd.com        num_act_mats_hor_dir_sl = num_mats_h_dir;//TODO: this is unnecessary, since search op, num_mats is used
50210234Syasuko.eckert@amd.com    } else {
50310234Syasuko.eckert@amd.com        num_act_mats_hor_dir = num_do_b_subbank / num_do_b_mat;
50410234Syasuko.eckert@amd.com        if (num_act_mats_hor_dir == 0) {
50510234Syasuko.eckert@amd.com            return;
50610234Syasuko.eckert@amd.com        }
50710234Syasuko.eckert@amd.com    }
50810152Satgutier@umich.edu
50910234Syasuko.eckert@amd.com    //compute num_do_mat for tag
51010234Syasuko.eckert@amd.com    if (is_tag) {
51110234Syasuko.eckert@amd.com        if (!(fully_assoc || pure_cam)) {
51210234Syasuko.eckert@amd.com            num_do_b_mat     = g_ip->tag_assoc / num_act_mats_hor_dir;
51310234Syasuko.eckert@amd.com            num_do_b_subbank = num_act_mats_hor_dir * num_do_b_mat;
51410234Syasuko.eckert@amd.com        }
51510234Syasuko.eckert@amd.com    }
51610152Satgutier@umich.edu
51710234Syasuko.eckert@amd.com    if ((g_ip->is_cache == false && is_main_mem == true) ||
51810234Syasuko.eckert@amd.com        (PAGE_MODE == 1 && is_dram)) {
51910234Syasuko.eckert@amd.com        if (num_act_mats_hor_dir * num_do_b_mat * Ndsam_lev_1 * Ndsam_lev_2 !=
52010234Syasuko.eckert@amd.com            (int)g_ip->page_sz_bits) {
52110234Syasuko.eckert@amd.com            return;
52210234Syasuko.eckert@amd.com        }
52310234Syasuko.eckert@amd.com    }
52410152Satgutier@umich.edu
52510152Satgutier@umich.edu//  if (is_tag == false && g_ip->is_cache == true && !fully_assoc && !pure_cam && //TODO: TODO burst transfer should also apply to RAM arrays
52610234Syasuko.eckert@amd.com    if (is_tag == false && g_ip->is_main_mem == true &&
52710234Syasuko.eckert@amd.com        num_act_mats_hor_dir*num_do_b_mat*Ndsam_lev_1*Ndsam_lev_2 <
52810234Syasuko.eckert@amd.com        ((int) g_ip->out_w * (int) g_ip->burst_len * (int) g_ip->data_assoc)) {
52910234Syasuko.eckert@amd.com        return;
53010234Syasuko.eckert@amd.com    }
53110152Satgutier@umich.edu
53210234Syasuko.eckert@amd.com    if (num_act_mats_hor_dir > num_mats_h_dir) {
53310234Syasuko.eckert@amd.com        return;
53410234Syasuko.eckert@amd.com    }
53510152Satgutier@umich.edu
53610152Satgutier@umich.edu
53710234Syasuko.eckert@amd.com    //compute di for mat subbank and bank
53810234Syasuko.eckert@amd.com    if (!(fully_assoc || pure_cam)) {
53910234Syasuko.eckert@amd.com        if (!is_tag) {
54010234Syasuko.eckert@amd.com            if (g_ip->fast_access == true) {
54110234Syasuko.eckert@amd.com                num_di_b_mat = num_do_b_mat / g_ip->data_assoc;
54210234Syasuko.eckert@amd.com            } else {
54310234Syasuko.eckert@amd.com                num_di_b_mat = num_do_b_mat;
54410234Syasuko.eckert@amd.com            }
54510234Syasuko.eckert@amd.com        } else {
54610234Syasuko.eckert@amd.com            num_di_b_mat = tagbits;
54710234Syasuko.eckert@amd.com        }
54810234Syasuko.eckert@amd.com    } else {
54910234Syasuko.eckert@amd.com        if (fully_assoc) {
55010234Syasuko.eckert@amd.com            num_di_b_mat = num_do_b_mat;
55110234Syasuko.eckert@amd.com            //*num_subarrays/num_mats; bits per mat of CAM/FA is as same as cache,
55210234Syasuko.eckert@amd.com            //but inside the mat wire tracks need to be reserved for search data bus
55310234Syasuko.eckert@amd.com            num_si_b_mat = tagbits;
55410234Syasuko.eckert@amd.com        } else {
55510234Syasuko.eckert@amd.com            num_di_b_mat = tagbits;
55610234Syasuko.eckert@amd.com            num_si_b_mat = tagbits;//*num_subarrays/num_mats;
55710234Syasuko.eckert@amd.com        }
55810152Satgutier@umich.edu
55910234Syasuko.eckert@amd.com    }
56010152Satgutier@umich.edu
56110234Syasuko.eckert@amd.com    num_di_b_subbank       = num_di_b_mat * num_act_mats_hor_dir;//normal cache or normal r/w for FA
56210234Syasuko.eckert@amd.com    num_si_b_subbank       = num_si_b_mat; //* num_act_mats_hor_dir_sl; inside the data is broadcast
56310152Satgutier@umich.edu
56410234Syasuko.eckert@amd.com    int num_addr_b_row_dec     = _log2(num_r_subarray);
56510234Syasuko.eckert@amd.com    if  ((fully_assoc || pure_cam))
56610234Syasuko.eckert@amd.com        num_addr_b_row_dec     += _log2(num_subarrays / num_mats);
56710234Syasuko.eckert@amd.com    int number_subbanks        = num_mats / num_act_mats_hor_dir;
56810234Syasuko.eckert@amd.com    number_subbanks_decode = _log2(number_subbanks);//TODO: add log2(num_subarray_per_bank) to FA/CAM
56910152Satgutier@umich.edu
57010234Syasuko.eckert@amd.com    num_rw_ports = g_ip->num_rw_ports;
57110234Syasuko.eckert@amd.com    num_rd_ports = g_ip->num_rd_ports;
57210234Syasuko.eckert@amd.com    num_wr_ports = g_ip->num_wr_ports;
57310234Syasuko.eckert@amd.com    num_se_rd_ports = g_ip->num_se_rd_ports;
57410234Syasuko.eckert@amd.com    num_search_ports = g_ip->num_search_ports;
57510152Satgutier@umich.edu
57610234Syasuko.eckert@amd.com    if (is_dram && is_main_mem) {
57710234Syasuko.eckert@amd.com        number_addr_bits_mat = MAX((unsigned int) num_addr_b_row_dec,
57810234Syasuko.eckert@amd.com                                   _log2(deg_bl_muxing) + _log2(deg_sa_mux_l1_non_assoc) + _log2(Ndsam_lev_2));
57910234Syasuko.eckert@amd.com    } else {
58010234Syasuko.eckert@amd.com        number_addr_bits_mat = num_addr_b_row_dec + _log2(deg_bl_muxing) +
58110234Syasuko.eckert@amd.com                               _log2(deg_sa_mux_l1_non_assoc) + _log2(Ndsam_lev_2);
58210234Syasuko.eckert@amd.com    }
58310152Satgutier@umich.edu
58410234Syasuko.eckert@amd.com    if (!(fully_assoc || pure_cam)) {
58510234Syasuko.eckert@amd.com        if (is_tag) {
58610234Syasuko.eckert@amd.com            num_di_b_bank_per_port = tagbits;
58710234Syasuko.eckert@amd.com            num_do_b_bank_per_port = g_ip->data_assoc;
58810234Syasuko.eckert@amd.com        } else {
58910234Syasuko.eckert@amd.com            num_di_b_bank_per_port = g_ip->out_w + g_ip->data_assoc;
59010234Syasuko.eckert@amd.com            num_do_b_bank_per_port = g_ip->out_w;
59110234Syasuko.eckert@amd.com        }
59210234Syasuko.eckert@amd.com    } else {
59310234Syasuko.eckert@amd.com        if (fully_assoc) {
59410234Syasuko.eckert@amd.com            num_di_b_bank_per_port = g_ip->out_w + tagbits;//TODO: out_w or block_sz?
59510234Syasuko.eckert@amd.com            num_si_b_bank_per_port = tagbits;
59610234Syasuko.eckert@amd.com            num_do_b_bank_per_port = g_ip->out_w + tagbits;
59710234Syasuko.eckert@amd.com            num_so_b_bank_per_port = g_ip->out_w;
59810234Syasuko.eckert@amd.com        } else {
59910234Syasuko.eckert@amd.com            num_di_b_bank_per_port = tagbits;
60010234Syasuko.eckert@amd.com            num_si_b_bank_per_port = tagbits;
60110234Syasuko.eckert@amd.com            num_do_b_bank_per_port = tagbits;
60210234Syasuko.eckert@amd.com            num_so_b_bank_per_port = int(ceil(log2(num_r_subarray)) + ceil(log2(num_subarrays)));
60310234Syasuko.eckert@amd.com        }
60410234Syasuko.eckert@amd.com    }
60510152Satgutier@umich.edu
60610234Syasuko.eckert@amd.com    if ((!is_tag) && (g_ip->data_assoc > 1) && (!g_ip->fast_access)) {
60710234Syasuko.eckert@amd.com        number_way_select_signals_mat = g_ip->data_assoc;
60810234Syasuko.eckert@amd.com    }
60910152Satgutier@umich.edu
61010234Syasuko.eckert@amd.com    // add ECC adjustment to all data signals that traverse on H-trees.
61110234Syasuko.eckert@amd.com    if (g_ip->add_ecc_b_ == true) {
61210234Syasuko.eckert@amd.com        num_do_b_mat += (int) (ceil(num_do_b_mat / num_bits_per_ecc_b_));
61310234Syasuko.eckert@amd.com        num_di_b_mat += (int) (ceil(num_di_b_mat / num_bits_per_ecc_b_));
61410234Syasuko.eckert@amd.com        num_di_b_subbank += (int) (ceil(num_di_b_subbank / num_bits_per_ecc_b_));
61510234Syasuko.eckert@amd.com        num_do_b_subbank += (int) (ceil(num_do_b_subbank / num_bits_per_ecc_b_));
61610234Syasuko.eckert@amd.com        num_di_b_bank_per_port += (int) (ceil(num_di_b_bank_per_port / num_bits_per_ecc_b_));
61710234Syasuko.eckert@amd.com        num_do_b_bank_per_port += (int) (ceil(num_do_b_bank_per_port / num_bits_per_ecc_b_));
61810152Satgutier@umich.edu
61910234Syasuko.eckert@amd.com        num_so_b_mat += (int) (ceil(num_so_b_mat / num_bits_per_ecc_b_));
62010234Syasuko.eckert@amd.com        num_si_b_mat += (int) (ceil(num_si_b_mat / num_bits_per_ecc_b_));
62110234Syasuko.eckert@amd.com        num_si_b_subbank += (int) (ceil(num_si_b_subbank / num_bits_per_ecc_b_));
62210234Syasuko.eckert@amd.com        num_so_b_subbank += (int) (ceil(num_so_b_subbank / num_bits_per_ecc_b_));
62310234Syasuko.eckert@amd.com        num_si_b_bank_per_port += (int) (ceil(num_si_b_bank_per_port / num_bits_per_ecc_b_));
62410234Syasuko.eckert@amd.com        num_so_b_bank_per_port += (int) (ceil(num_so_b_bank_per_port / num_bits_per_ecc_b_));
62510234Syasuko.eckert@amd.com    }
62610152Satgutier@umich.edu
62710234Syasuko.eckert@amd.com    is_valid = true;
62810152Satgutier@umich.edu}
62910152Satgutier@umich.edu
630