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 <cassert>
3610152Satgutier@umich.edu
3710152Satgutier@umich.edu#include "mat.h"
3810152Satgutier@umich.edu
3910152Satgutier@umich.eduMat::Mat(const DynamicParameter & dyn_p)
4010234Syasuko.eckert@amd.com    : dp(dyn_p),
4110234Syasuko.eckert@amd.com      power_subarray_out_drv(),
4210234Syasuko.eckert@amd.com      delay_fa_tag(0), delay_cam(0),
4310234Syasuko.eckert@amd.com      delay_before_decoder(0), delay_bitline(0),
4410234Syasuko.eckert@amd.com      delay_wl_reset(0), delay_bl_restore(0),
4510234Syasuko.eckert@amd.com      delay_searchline(0), delay_matchchline(0),
4610234Syasuko.eckert@amd.com      delay_cam_sl_restore(0), delay_cam_ml_reset(0),
4710234Syasuko.eckert@amd.com      delay_fa_ram_wl(0), delay_hit_miss_reset(0),
4810234Syasuko.eckert@amd.com      delay_hit_miss(0),
4910234Syasuko.eckert@amd.com      subarray(dp, dp.fully_assoc),
5010234Syasuko.eckert@amd.com      power_bitline(), per_bitline_read_energy(0),
5110234Syasuko.eckert@amd.com      deg_bl_muxing(dp.deg_bl_muxing),
5210234Syasuko.eckert@amd.com      num_act_mats_hor_dir(dyn_p.num_act_mats_hor_dir),
5310234Syasuko.eckert@amd.com      delay_writeback(0),
5410234Syasuko.eckert@amd.com      cell(subarray.cell), cam_cell(subarray.cam_cell),
5510234Syasuko.eckert@amd.com      is_dram(dyn_p.is_dram),
5610234Syasuko.eckert@amd.com      pure_cam(dyn_p.pure_cam),
5710234Syasuko.eckert@amd.com      num_mats(dp.num_mats),
5810234Syasuko.eckert@amd.com      power_sa(), delay_sa(0),
5910234Syasuko.eckert@amd.com      leak_power_sense_amps_closed_page_state(0),
6010234Syasuko.eckert@amd.com      leak_power_sense_amps_open_page_state(0),
6110234Syasuko.eckert@amd.com      delay_subarray_out_drv(0),
6210234Syasuko.eckert@amd.com      delay_comparator(0), power_comparator(),
6310234Syasuko.eckert@amd.com      num_do_b_mat(dyn_p.num_do_b_mat), num_so_b_mat(dyn_p.num_so_b_mat),
6410234Syasuko.eckert@amd.com      num_subarrays_per_mat(dp.num_subarrays / dp.num_mats),
6510234Syasuko.eckert@amd.com      num_subarrays_per_row(dp.Ndwl / dp.num_mats_h_dir) {
6610234Syasuko.eckert@amd.com    assert(num_subarrays_per_mat <= 4);
6710234Syasuko.eckert@amd.com    assert(num_subarrays_per_row <= 2);
6810234Syasuko.eckert@amd.com    is_fa = (dp.fully_assoc) ? true : false;
6910234Syasuko.eckert@amd.com    camFlag = (is_fa || pure_cam);//although cam_cell.w = cell.w for fa, we still differentiate them.
7010152Satgutier@umich.edu
7110234Syasuko.eckert@amd.com    if (is_fa || pure_cam) {
7210234Syasuko.eckert@amd.com        num_subarrays_per_row = num_subarrays_per_mat > 2 ?
7310234Syasuko.eckert@amd.com            num_subarrays_per_mat / 2 : num_subarrays_per_mat;
7410234Syasuko.eckert@amd.com    }
7510152Satgutier@umich.edu
7610234Syasuko.eckert@amd.com    if (dp.use_inp_params == 1) {
7710234Syasuko.eckert@amd.com        RWP  = dp.num_rw_ports;
7810234Syasuko.eckert@amd.com        ERP  = dp.num_rd_ports;
7910234Syasuko.eckert@amd.com        EWP  = dp.num_wr_ports;
8010234Syasuko.eckert@amd.com        SCHP = dp.num_search_ports;
8110234Syasuko.eckert@amd.com    } else {
8210234Syasuko.eckert@amd.com        RWP = g_ip->num_rw_ports;
8310234Syasuko.eckert@amd.com        ERP = g_ip->num_rd_ports;
8410234Syasuko.eckert@amd.com        EWP = g_ip->num_wr_ports;
8510234Syasuko.eckert@amd.com        SCHP = g_ip->num_search_ports;
8610152Satgutier@umich.edu
8710234Syasuko.eckert@amd.com    }
8810152Satgutier@umich.edu
8910234Syasuko.eckert@amd.com    double number_sa_subarray;
9010152Satgutier@umich.edu
9110234Syasuko.eckert@amd.com    if (!is_fa && !pure_cam) {
9210234Syasuko.eckert@amd.com        number_sa_subarray = subarray.num_cols / deg_bl_muxing;
9310234Syasuko.eckert@amd.com    } else if (is_fa && !pure_cam) {
9410234Syasuko.eckert@amd.com        number_sa_subarray =  (subarray.num_cols_fa_cam + subarray.num_cols_fa_ram) / deg_bl_muxing;
9510234Syasuko.eckert@amd.com    }
9610152Satgutier@umich.edu
9710234Syasuko.eckert@amd.com    else {
9810234Syasuko.eckert@amd.com        number_sa_subarray =  (subarray.num_cols_fa_cam) / deg_bl_muxing;
9910234Syasuko.eckert@amd.com    }
10010152Satgutier@umich.edu
10110234Syasuko.eckert@amd.com    int    num_dec_signals           = subarray.num_rows;
10210234Syasuko.eckert@amd.com    double C_ld_bit_mux_dec_out      = 0;
10310234Syasuko.eckert@amd.com    double C_ld_sa_mux_lev_1_dec_out = 0;
10410234Syasuko.eckert@amd.com    double C_ld_sa_mux_lev_2_dec_out = 0;
10510234Syasuko.eckert@amd.com    double R_wire_wl_drv_out;
10610152Satgutier@umich.edu
10710234Syasuko.eckert@amd.com    if (!is_fa && !pure_cam) {
10810234Syasuko.eckert@amd.com        R_wire_wl_drv_out = subarray.num_cols * cell.w * g_tp.wire_local.R_per_um;
10910234Syasuko.eckert@amd.com    } else if (is_fa && !pure_cam) {
11010152Satgutier@umich.edu        R_wire_wl_drv_out = (subarray.num_cols_fa_cam * cam_cell.w + subarray.num_cols_fa_ram * cell.w) * g_tp.wire_local.R_per_um ;
11110234Syasuko.eckert@amd.com    } else {
11210152Satgutier@umich.edu        R_wire_wl_drv_out = (subarray.num_cols_fa_cam * cam_cell.w ) * g_tp.wire_local.R_per_um;
11310152Satgutier@umich.edu    }
11410152Satgutier@umich.edu
11510234Syasuko.eckert@amd.com    double R_wire_bit_mux_dec_out = num_subarrays_per_row * subarray.num_cols * g_tp.wire_inside_mat.R_per_um * cell.w;//TODO:revisit for FA
11610234Syasuko.eckert@amd.com    double R_wire_sa_mux_dec_out  = num_subarrays_per_row * subarray.num_cols * g_tp.wire_inside_mat.R_per_um * cell.w;
11710152Satgutier@umich.edu
11810234Syasuko.eckert@amd.com    if (deg_bl_muxing > 1) {
11910234Syasuko.eckert@amd.com        C_ld_bit_mux_dec_out =
12010234Syasuko.eckert@amd.com            (2 * num_subarrays_per_mat * subarray.num_cols / deg_bl_muxing) *
12110234Syasuko.eckert@amd.com            gate_C(g_tp.w_nmos_b_mux, 0, is_dram) +  // 2 transistor per cell
12210234Syasuko.eckert@amd.com            num_subarrays_per_row * subarray.num_cols *
12310234Syasuko.eckert@amd.com            g_tp.wire_inside_mat.C_per_um * cell.get_w();
12410234Syasuko.eckert@amd.com    }
12510152Satgutier@umich.edu
12610234Syasuko.eckert@amd.com    if (dp.Ndsam_lev_1 > 1) {
12710234Syasuko.eckert@amd.com        C_ld_sa_mux_lev_1_dec_out =
12810234Syasuko.eckert@amd.com            (num_subarrays_per_mat * number_sa_subarray / dp.Ndsam_lev_1) *
12910234Syasuko.eckert@amd.com            gate_C(g_tp.w_nmos_sa_mux, 0, is_dram) +
13010234Syasuko.eckert@amd.com            num_subarrays_per_row * subarray.num_cols *
13110234Syasuko.eckert@amd.com            g_tp.wire_inside_mat.C_per_um * cell.get_w();
13210234Syasuko.eckert@amd.com    }
13310234Syasuko.eckert@amd.com    if (dp.Ndsam_lev_2 > 1) {
13410234Syasuko.eckert@amd.com        C_ld_sa_mux_lev_2_dec_out =
13510234Syasuko.eckert@amd.com            (num_subarrays_per_mat * number_sa_subarray /
13610234Syasuko.eckert@amd.com             (dp.Ndsam_lev_1 * dp.Ndsam_lev_2)) *
13710234Syasuko.eckert@amd.com            gate_C(g_tp.w_nmos_sa_mux, 0, is_dram) +
13810234Syasuko.eckert@amd.com            num_subarrays_per_row * subarray.num_cols *
13910234Syasuko.eckert@amd.com            g_tp.wire_inside_mat.C_per_um * cell.get_w();
14010234Syasuko.eckert@amd.com    }
14110152Satgutier@umich.edu
14210234Syasuko.eckert@amd.com    if (num_subarrays_per_row >= 2) {
14310234Syasuko.eckert@amd.com        // wire heads for both right and left side of a mat, so half the resistance
14410234Syasuko.eckert@amd.com        R_wire_bit_mux_dec_out /= 2.0;
14510234Syasuko.eckert@amd.com        R_wire_sa_mux_dec_out  /= 2.0;
14610234Syasuko.eckert@amd.com    }
14710152Satgutier@umich.edu
14810152Satgutier@umich.edu
14910234Syasuko.eckert@amd.com    row_dec = new Decoder(
15010234Syasuko.eckert@amd.com        num_dec_signals,
15110234Syasuko.eckert@amd.com        false,
15210234Syasuko.eckert@amd.com        subarray.C_wl,
15310234Syasuko.eckert@amd.com        R_wire_wl_drv_out,
15410234Syasuko.eckert@amd.com        false/*is_fa*/,
15510234Syasuko.eckert@amd.com        is_dram,
15610234Syasuko.eckert@amd.com        true,
15710234Syasuko.eckert@amd.com        camFlag ? cam_cell : cell);
15810152Satgutier@umich.edu//  if (is_fa && (!dp.is_tag))
15910152Satgutier@umich.edu//  {
16010152Satgutier@umich.edu//    row_dec->exist = true;
16110152Satgutier@umich.edu//  }
16210234Syasuko.eckert@amd.com    bit_mux_dec = new Decoder(
16310234Syasuko.eckert@amd.com        deg_bl_muxing,// This number is 1 for FA or CAM
16410234Syasuko.eckert@amd.com        false,
16510234Syasuko.eckert@amd.com        C_ld_bit_mux_dec_out,
16610234Syasuko.eckert@amd.com        R_wire_bit_mux_dec_out,
16710234Syasuko.eckert@amd.com        false/*is_fa*/,
16810234Syasuko.eckert@amd.com        is_dram,
16910234Syasuko.eckert@amd.com        false,
17010234Syasuko.eckert@amd.com        camFlag ? cam_cell : cell);
17110234Syasuko.eckert@amd.com    sa_mux_lev_1_dec = new Decoder(
17210234Syasuko.eckert@amd.com        dp.deg_senseamp_muxing_non_associativity, // This number is 1 for FA or CAM
17310234Syasuko.eckert@amd.com        dp.number_way_select_signals_mat ? true : false,//only sa_mux_lev_1_dec needs way select signal
17410234Syasuko.eckert@amd.com        C_ld_sa_mux_lev_1_dec_out,
17510234Syasuko.eckert@amd.com        R_wire_sa_mux_dec_out,
17610234Syasuko.eckert@amd.com        false/*is_fa*/,
17710234Syasuko.eckert@amd.com        is_dram,
17810234Syasuko.eckert@amd.com        false,
17910234Syasuko.eckert@amd.com        camFlag ? cam_cell : cell);
18010234Syasuko.eckert@amd.com    sa_mux_lev_2_dec = new Decoder(
18110234Syasuko.eckert@amd.com        dp.Ndsam_lev_2, // This number is 1 for FA or CAM
18210234Syasuko.eckert@amd.com        false,
18310234Syasuko.eckert@amd.com        C_ld_sa_mux_lev_2_dec_out,
18410234Syasuko.eckert@amd.com        R_wire_sa_mux_dec_out,
18510234Syasuko.eckert@amd.com        false/*is_fa*/,
18610234Syasuko.eckert@amd.com        is_dram,
18710234Syasuko.eckert@amd.com        false,
18810234Syasuko.eckert@amd.com        camFlag ? cam_cell : cell);
18910152Satgutier@umich.edu
19010234Syasuko.eckert@amd.com    double C_wire_predec_blk_out;
19110234Syasuko.eckert@amd.com    double R_wire_predec_blk_out;
19210152Satgutier@umich.edu
19310234Syasuko.eckert@amd.com    if (!is_fa && !pure_cam) {
19410152Satgutier@umich.edu
19510234Syasuko.eckert@amd.com        C_wire_predec_blk_out  = num_subarrays_per_row * subarray.num_rows * g_tp.wire_inside_mat.C_per_um * cell.h;
19610234Syasuko.eckert@amd.com        R_wire_predec_blk_out  = num_subarrays_per_row * subarray.num_rows * g_tp.wire_inside_mat.R_per_um * cell.h;
19710152Satgutier@umich.edu
19810234Syasuko.eckert@amd.com    } else { //for pre-decode block's load is same for both FA and CAM
19910234Syasuko.eckert@amd.com        C_wire_predec_blk_out  = subarray.num_rows * g_tp.wire_inside_mat.C_per_um * cam_cell.h;
20010234Syasuko.eckert@amd.com        R_wire_predec_blk_out  = subarray.num_rows * g_tp.wire_inside_mat.R_per_um * cam_cell.h;
20110234Syasuko.eckert@amd.com    }
20210152Satgutier@umich.edu
20310152Satgutier@umich.edu
20410234Syasuko.eckert@amd.com    if (is_fa || pure_cam)
20510234Syasuko.eckert@amd.com        num_dec_signals += _log2(num_subarrays_per_mat);
20610152Satgutier@umich.edu
20710234Syasuko.eckert@amd.com    PredecBlk * r_predec_blk1 = new PredecBlk(
20810234Syasuko.eckert@amd.com        num_dec_signals,
20910234Syasuko.eckert@amd.com        row_dec,
21010234Syasuko.eckert@amd.com        C_wire_predec_blk_out,
21110234Syasuko.eckert@amd.com        R_wire_predec_blk_out,
21210234Syasuko.eckert@amd.com        num_subarrays_per_mat,
21310234Syasuko.eckert@amd.com        is_dram,
21410234Syasuko.eckert@amd.com        true);
21510234Syasuko.eckert@amd.com    PredecBlk * r_predec_blk2 = new PredecBlk(
21610234Syasuko.eckert@amd.com        num_dec_signals,
21710234Syasuko.eckert@amd.com        row_dec,
21810234Syasuko.eckert@amd.com        C_wire_predec_blk_out,
21910234Syasuko.eckert@amd.com        R_wire_predec_blk_out,
22010234Syasuko.eckert@amd.com        num_subarrays_per_mat,
22110234Syasuko.eckert@amd.com        is_dram,
22210234Syasuko.eckert@amd.com        false);
22310234Syasuko.eckert@amd.com    PredecBlk * b_mux_predec_blk1 = new PredecBlk(deg_bl_muxing, bit_mux_dec, 0, 0, 1, is_dram, true);
22410234Syasuko.eckert@amd.com    PredecBlk * b_mux_predec_blk2 = new PredecBlk(deg_bl_muxing, bit_mux_dec, 0, 0, 1, is_dram, false);
22510234Syasuko.eckert@amd.com    PredecBlk * sa_mux_lev_1_predec_blk1 = new PredecBlk(dyn_p.deg_senseamp_muxing_non_associativity, sa_mux_lev_1_dec, 0, 0, 1, is_dram, true);
22610234Syasuko.eckert@amd.com    PredecBlk * sa_mux_lev_1_predec_blk2 = new PredecBlk(dyn_p.deg_senseamp_muxing_non_associativity, sa_mux_lev_1_dec, 0, 0, 1, is_dram, false);
22710234Syasuko.eckert@amd.com    PredecBlk * sa_mux_lev_2_predec_blk1 = new PredecBlk(dp.Ndsam_lev_2, sa_mux_lev_2_dec, 0, 0, 1, is_dram, true);
22810234Syasuko.eckert@amd.com    PredecBlk * sa_mux_lev_2_predec_blk2 = new PredecBlk(dp.Ndsam_lev_2, sa_mux_lev_2_dec, 0, 0, 1, is_dram, false);
22910234Syasuko.eckert@amd.com    dummy_way_sel_predec_blk1 = new PredecBlk(1, sa_mux_lev_1_dec, 0, 0, 0, is_dram, true);
23010234Syasuko.eckert@amd.com    dummy_way_sel_predec_blk2 = new PredecBlk(1, sa_mux_lev_1_dec, 0, 0, 0, is_dram, false);
23110152Satgutier@umich.edu
23210234Syasuko.eckert@amd.com    PredecBlkDrv * r_predec_blk_drv1 = new PredecBlkDrv(0, r_predec_blk1, is_dram);
23310234Syasuko.eckert@amd.com    PredecBlkDrv * r_predec_blk_drv2 = new PredecBlkDrv(0, r_predec_blk2, is_dram);
23410234Syasuko.eckert@amd.com    PredecBlkDrv * b_mux_predec_blk_drv1 = new PredecBlkDrv(0, b_mux_predec_blk1, is_dram);
23510234Syasuko.eckert@amd.com    PredecBlkDrv * b_mux_predec_blk_drv2 = new PredecBlkDrv(0, b_mux_predec_blk2, is_dram);
23610234Syasuko.eckert@amd.com    PredecBlkDrv * sa_mux_lev_1_predec_blk_drv1 = new PredecBlkDrv(0, sa_mux_lev_1_predec_blk1, is_dram);
23710234Syasuko.eckert@amd.com    PredecBlkDrv * sa_mux_lev_1_predec_blk_drv2 = new PredecBlkDrv(0, sa_mux_lev_1_predec_blk2, is_dram);
23810234Syasuko.eckert@amd.com    PredecBlkDrv * sa_mux_lev_2_predec_blk_drv1 = new PredecBlkDrv(0, sa_mux_lev_2_predec_blk1, is_dram);
23910234Syasuko.eckert@amd.com    PredecBlkDrv * sa_mux_lev_2_predec_blk_drv2 = new PredecBlkDrv(0, sa_mux_lev_2_predec_blk2, is_dram);
24010234Syasuko.eckert@amd.com    way_sel_drv1 = new PredecBlkDrv(dyn_p.number_way_select_signals_mat, dummy_way_sel_predec_blk1, is_dram);
24110234Syasuko.eckert@amd.com    dummy_way_sel_predec_blk_drv2 = new PredecBlkDrv(1, dummy_way_sel_predec_blk2, is_dram);
24210152Satgutier@umich.edu
24310234Syasuko.eckert@amd.com    r_predec            = new Predec(r_predec_blk_drv1, r_predec_blk_drv2);
24410234Syasuko.eckert@amd.com    b_mux_predec        = new Predec(b_mux_predec_blk_drv1, b_mux_predec_blk_drv2);
24510234Syasuko.eckert@amd.com    sa_mux_lev_1_predec = new Predec(sa_mux_lev_1_predec_blk_drv1, sa_mux_lev_1_predec_blk_drv2);
24610234Syasuko.eckert@amd.com    sa_mux_lev_2_predec = new Predec(sa_mux_lev_2_predec_blk_drv1, sa_mux_lev_2_predec_blk_drv2);
24710152Satgutier@umich.edu
24810234Syasuko.eckert@amd.com    subarray_out_wire   = new Wire(g_ip->wt, subarray.area.h);//Bug should be subarray.area.w Owen and Sheng
24910152Satgutier@umich.edu
25010234Syasuko.eckert@amd.com    double driver_c_gate_load;
25110234Syasuko.eckert@amd.com    double driver_c_wire_load;
25210234Syasuko.eckert@amd.com    double driver_r_wire_load;
25310152Satgutier@umich.edu
25410234Syasuko.eckert@amd.com    if (is_fa || pure_cam)
25510152Satgutier@umich.edu
25610234Syasuko.eckert@amd.com    {   //Although CAM and RAM use different bl pre-charge driver, assuming the precharge p size is the same
25710234Syasuko.eckert@amd.com        driver_c_gate_load = (subarray.num_cols_fa_cam ) *
25810234Syasuko.eckert@amd.com            gate_C(2 * g_tp.w_pmos_bl_precharge + g_tp.w_pmos_bl_eq, 0,
25910234Syasuko.eckert@amd.com                   is_dram, false, false);
26010234Syasuko.eckert@amd.com        driver_c_wire_load = subarray.num_cols_fa_cam * cam_cell.w *
26110234Syasuko.eckert@amd.com            g_tp.wire_outside_mat.C_per_um;
26210234Syasuko.eckert@amd.com        driver_r_wire_load = subarray.num_cols_fa_cam * cam_cell.w *
26310234Syasuko.eckert@amd.com            g_tp.wire_outside_mat.R_per_um;
26410234Syasuko.eckert@amd.com        cam_bl_precharge_eq_drv = new Driver(
26510234Syasuko.eckert@amd.com            driver_c_gate_load,
26610234Syasuko.eckert@amd.com            driver_c_wire_load,
26710234Syasuko.eckert@amd.com            driver_r_wire_load,
26810234Syasuko.eckert@amd.com            is_dram);
26910152Satgutier@umich.edu
27010234Syasuko.eckert@amd.com        if (!pure_cam) {
27110234Syasuko.eckert@amd.com            //This is only used for fully asso not pure CAM
27210234Syasuko.eckert@amd.com            driver_c_gate_load = (subarray.num_cols_fa_ram ) *
27310234Syasuko.eckert@amd.com                gate_C(2 * g_tp.w_pmos_bl_precharge + g_tp.w_pmos_bl_eq, 0,
27410234Syasuko.eckert@amd.com                       is_dram, false, false);
27510234Syasuko.eckert@amd.com            driver_c_wire_load = subarray.num_cols_fa_ram * cell.w *
27610234Syasuko.eckert@amd.com                g_tp.wire_outside_mat.C_per_um;
27710234Syasuko.eckert@amd.com            driver_r_wire_load = subarray.num_cols_fa_ram * cell.w *
27810234Syasuko.eckert@amd.com                g_tp.wire_outside_mat.R_per_um;
27910234Syasuko.eckert@amd.com            bl_precharge_eq_drv = new Driver(
28010234Syasuko.eckert@amd.com                driver_c_gate_load,
28110234Syasuko.eckert@amd.com                driver_c_wire_load,
28210234Syasuko.eckert@amd.com                driver_r_wire_load,
28310234Syasuko.eckert@amd.com                is_dram);
28410234Syasuko.eckert@amd.com        }
28510234Syasuko.eckert@amd.com    }
28610152Satgutier@umich.edu
28710234Syasuko.eckert@amd.com    else {
28810234Syasuko.eckert@amd.com        driver_c_gate_load =  subarray.num_cols * gate_C(2 * g_tp.w_pmos_bl_precharge + g_tp.w_pmos_bl_eq, 0, is_dram, false, false);
28910234Syasuko.eckert@amd.com        driver_c_wire_load =  subarray.num_cols * cell.w * g_tp.wire_outside_mat.C_per_um;
29010234Syasuko.eckert@amd.com        driver_r_wire_load =  subarray.num_cols * cell.w * g_tp.wire_outside_mat.R_per_um;
29110234Syasuko.eckert@amd.com        bl_precharge_eq_drv = new Driver(
29210234Syasuko.eckert@amd.com            driver_c_gate_load,
29310234Syasuko.eckert@amd.com            driver_c_wire_load,
29410234Syasuko.eckert@amd.com            driver_r_wire_load,
29510234Syasuko.eckert@amd.com            is_dram);
29610234Syasuko.eckert@amd.com    }
29710234Syasuko.eckert@amd.com    double area_row_decoder = row_dec->area.get_area() * subarray.num_rows * (RWP + ERP + EWP);
29810234Syasuko.eckert@amd.com    double w_row_decoder    = area_row_decoder / subarray.area.get_h();
29910152Satgutier@umich.edu
30010234Syasuko.eckert@amd.com    double h_bit_mux_sense_amp_precharge_sa_mux_write_driver_write_mux =
30110234Syasuko.eckert@amd.com        compute_bit_mux_sa_precharge_sa_mux_wr_drv_wr_mux_h();
30210152Satgutier@umich.edu
30310234Syasuko.eckert@amd.com    double h_subarray_out_drv = subarray_out_wire->area.get_area() *
30410234Syasuko.eckert@amd.com                                (subarray.num_cols / (deg_bl_muxing * dp.Ndsam_lev_1 * dp.Ndsam_lev_2)) / subarray.area.get_w();
30510152Satgutier@umich.edu
30610152Satgutier@umich.edu
30710234Syasuko.eckert@amd.com    h_subarray_out_drv *= (RWP + ERP + SCHP);
30810152Satgutier@umich.edu
30910234Syasuko.eckert@amd.com    double h_comparators                = 0.0;
31010234Syasuko.eckert@amd.com    double w_row_predecode_output_wires = 0.0;
31110234Syasuko.eckert@amd.com    double h_bit_mux_dec_out_wires      = 0.0;
31210234Syasuko.eckert@amd.com    double h_senseamp_mux_dec_out_wires = 0.0;
31310152Satgutier@umich.edu
31410234Syasuko.eckert@amd.com    if ((!is_fa) && (dp.is_tag)) {
31510234Syasuko.eckert@amd.com        //tagbits = (4 * num_cols_subarray / (deg_bl_muxing * dp.Ndsam_lev_1 * dp.Ndsam_lev_2)) / num_do_b_mat;
31610234Syasuko.eckert@amd.com        h_comparators  = compute_comparators_height(dp.tagbits, dyn_p.num_do_b_mat, subarray.area.get_w());
31710234Syasuko.eckert@amd.com        h_comparators *= (RWP + ERP);
31810234Syasuko.eckert@amd.com    }
31910152Satgutier@umich.edu
32010152Satgutier@umich.edu
32110152Satgutier@umich.edu    int branch_effort_predec_blk1_out = (1 << r_predec_blk2->number_input_addr_bits);
32210152Satgutier@umich.edu    int branch_effort_predec_blk2_out = (1 << r_predec_blk1->number_input_addr_bits);
32310152Satgutier@umich.edu    w_row_predecode_output_wires   = (branch_effort_predec_blk1_out + branch_effort_predec_blk2_out) *
32410234Syasuko.eckert@amd.com                                     g_tp.wire_inside_mat.pitch * (RWP + ERP + EWP);
32510152Satgutier@umich.edu
32610152Satgutier@umich.edu
32710234Syasuko.eckert@amd.com    double h_non_cell_area = (num_subarrays_per_mat / num_subarrays_per_row) *
32810234Syasuko.eckert@amd.com                             (h_bit_mux_sense_amp_precharge_sa_mux_write_driver_write_mux +
32910234Syasuko.eckert@amd.com                              h_subarray_out_drv + h_comparators);
33010152Satgutier@umich.edu
33110234Syasuko.eckert@amd.com    double w_non_cell_area = MAX(w_row_predecode_output_wires, num_subarrays_per_row * w_row_decoder);
33210152Satgutier@umich.edu
33310234Syasuko.eckert@amd.com    if (deg_bl_muxing > 1) {
33410234Syasuko.eckert@amd.com        h_bit_mux_dec_out_wires = deg_bl_muxing * g_tp.wire_inside_mat.pitch * (RWP + ERP);
33510234Syasuko.eckert@amd.com    }
33610234Syasuko.eckert@amd.com    if (dp.Ndsam_lev_1 > 1) {
33710234Syasuko.eckert@amd.com        h_senseamp_mux_dec_out_wires =  dp.Ndsam_lev_1 * g_tp.wire_inside_mat.pitch * (RWP + ERP);
33810234Syasuko.eckert@amd.com    }
33910234Syasuko.eckert@amd.com    if (dp.Ndsam_lev_2 > 1) {
34010234Syasuko.eckert@amd.com        h_senseamp_mux_dec_out_wires += dp.Ndsam_lev_2 * g_tp.wire_inside_mat.pitch * (RWP + ERP);
34110234Syasuko.eckert@amd.com    }
34210152Satgutier@umich.edu
34310234Syasuko.eckert@amd.com    double h_addr_datain_wires;
34410234Syasuko.eckert@amd.com    if (!g_ip->ver_htree_wires_over_array) {
34510234Syasuko.eckert@amd.com        h_addr_datain_wires = (dp.number_addr_bits_mat +
34610234Syasuko.eckert@amd.com                               dp.number_way_select_signals_mat +
34710234Syasuko.eckert@amd.com                               (dp.num_di_b_mat + dp.num_do_b_mat) /
34810234Syasuko.eckert@amd.com                               num_subarrays_per_row) *
34910234Syasuko.eckert@amd.com            g_tp.wire_inside_mat.pitch * (RWP + ERP + EWP);
35010152Satgutier@umich.edu
35110234Syasuko.eckert@amd.com        if (is_fa || pure_cam) {
35210234Syasuko.eckert@amd.com            h_addr_datain_wires =
35310234Syasuko.eckert@amd.com                (dp.number_addr_bits_mat +
35410234Syasuko.eckert@amd.com                 dp.number_way_select_signals_mat +  //TODO: revisit
35510234Syasuko.eckert@amd.com                 (dp.num_di_b_mat + dp.num_do_b_mat ) / num_subarrays_per_row) *
35610234Syasuko.eckert@amd.com                g_tp.wire_inside_mat.pitch * (RWP + ERP + EWP) +
35710234Syasuko.eckert@amd.com                (dp.num_si_b_mat + dp.num_so_b_mat ) / num_subarrays_per_row *
35810234Syasuko.eckert@amd.com                g_tp.wire_inside_mat.pitch * SCHP;
35910234Syasuko.eckert@amd.com        }
36010234Syasuko.eckert@amd.com        //h_non_cell_area = 2 * h_bit_mux_sense_amp_precharge_sa_mux +
36110234Syasuko.eckert@amd.com        //MAX(h_addr_datain_wires, 2 * h_subarray_out_drv);
36210234Syasuko.eckert@amd.com        h_non_cell_area = (h_bit_mux_sense_amp_precharge_sa_mux_write_driver_write_mux + h_comparators +
36310234Syasuko.eckert@amd.com                           h_subarray_out_drv) * (num_subarrays_per_mat / num_subarrays_per_row) +
36410234Syasuko.eckert@amd.com                          h_addr_datain_wires +
36510234Syasuko.eckert@amd.com                          h_bit_mux_dec_out_wires +
36610234Syasuko.eckert@amd.com                          h_senseamp_mux_dec_out_wires;
36710234Syasuko.eckert@amd.com
36810152Satgutier@umich.edu    }
36910152Satgutier@umich.edu
37010234Syasuko.eckert@amd.com    // double area_rectangle_center_mat = h_non_cell_area * w_non_cell_area;
37110234Syasuko.eckert@amd.com    double area_mat_center_circuitry = (r_predec_blk_drv1->area.get_area() +
37210234Syasuko.eckert@amd.com                                        b_mux_predec_blk_drv1->area.get_area() +
37310234Syasuko.eckert@amd.com                                        sa_mux_lev_1_predec_blk_drv1->area.get_area() +
37410234Syasuko.eckert@amd.com                                        sa_mux_lev_2_predec_blk_drv1->area.get_area() +
37510234Syasuko.eckert@amd.com                                        way_sel_drv1->area.get_area() +
37610234Syasuko.eckert@amd.com                                        r_predec_blk_drv2->area.get_area() +
37710234Syasuko.eckert@amd.com                                        b_mux_predec_blk_drv2->area.get_area() +
37810234Syasuko.eckert@amd.com                                        sa_mux_lev_1_predec_blk_drv2->area.get_area() +
37910234Syasuko.eckert@amd.com                                        sa_mux_lev_2_predec_blk_drv2->area.get_area() +
38010234Syasuko.eckert@amd.com                                        r_predec_blk1->area.get_area() +
38110234Syasuko.eckert@amd.com                                        b_mux_predec_blk1->area.get_area() +
38210234Syasuko.eckert@amd.com                                        sa_mux_lev_1_predec_blk1->area.get_area() +
38310234Syasuko.eckert@amd.com                                        sa_mux_lev_2_predec_blk1->area.get_area() +
38410234Syasuko.eckert@amd.com                                        r_predec_blk2->area.get_area() +
38510234Syasuko.eckert@amd.com                                        b_mux_predec_blk2->area.get_area() +
38610234Syasuko.eckert@amd.com                                        sa_mux_lev_1_predec_blk2->area.get_area() +
38710234Syasuko.eckert@amd.com                                        sa_mux_lev_2_predec_blk2->area.get_area() +
38810234Syasuko.eckert@amd.com                                        bit_mux_dec->area.get_area() +
38910234Syasuko.eckert@amd.com                                        sa_mux_lev_1_dec->area.get_area() +
39010234Syasuko.eckert@amd.com                                        sa_mux_lev_2_dec->area.get_area()) * (RWP + ERP + EWP);
39110152Satgutier@umich.edu
39210234Syasuko.eckert@amd.com    double area_efficiency_mat;
39310152Satgutier@umich.edu
39410152Satgutier@umich.edu//  if (!is_fa)
39510152Satgutier@umich.edu//  {
39610234Syasuko.eckert@amd.com    assert(num_subarrays_per_mat / num_subarrays_per_row > 0);
39710234Syasuko.eckert@amd.com    area.h = (num_subarrays_per_mat / num_subarrays_per_row) *
39810234Syasuko.eckert@amd.com        subarray.area.h + h_non_cell_area;
39910152Satgutier@umich.edu    area.w = num_subarrays_per_row * subarray.area.get_w() + w_non_cell_area;
40010234Syasuko.eckert@amd.com    area.w = (area.h * area.w + area_mat_center_circuitry) / area.h;
40110234Syasuko.eckert@amd.com    area_efficiency_mat = subarray.area.get_area() * num_subarrays_per_mat *
40210234Syasuko.eckert@amd.com        100.0 / area.get_area();
40310152Satgutier@umich.edu
40410152Satgutier@umich.edu//    cout<<"h_bit_mux_sense_amp_precharge_sa_mux_write_driver_write_mux"<<h_bit_mux_sense_amp_precharge_sa_mux_write_driver_write_mux<<endl;
40510152Satgutier@umich.edu//    cout<<"h_comparators"<<h_comparators<<endl;
40610152Satgutier@umich.edu//    cout<<"h_subarray_out_drv"<<h_subarray_out_drv<<endl;
40710152Satgutier@umich.edu//    cout<<"h_addr_datain_wires"<<h_addr_datain_wires<<endl;
40810152Satgutier@umich.edu//    cout<<"h_bit_mux_dec_out_wires"<<h_bit_mux_dec_out_wires<<endl;
40910152Satgutier@umich.edu//    cout<<"h_senseamp_mux_dec_out_wires"<<h_senseamp_mux_dec_out_wires<<endl;
41010152Satgutier@umich.edu//    cout<<"h_non_cell_area"<<h_non_cell_area<<endl;
41110152Satgutier@umich.edu//    cout<<"area.h =" << (num_subarrays_per_mat/num_subarrays_per_row)* subarray.area.h<<endl;
41210152Satgutier@umich.edu//    cout<<"w_non_cell_area"<<w_non_cell_area<<endl;
41310152Satgutier@umich.edu//    cout<<"area_mat_center_circuitry"<<area_mat_center_circuitry<<endl;
41410152Satgutier@umich.edu
41510234Syasuko.eckert@amd.com    assert(area.h > 0);
41610234Syasuko.eckert@amd.com    assert(area.w > 0);
41710152Satgutier@umich.edu//  }
41810152Satgutier@umich.edu//  else
41910152Satgutier@umich.edu//  {
42010152Satgutier@umich.edu//    area.h = (num_subarrays_per_mat / num_subarrays_per_row) * subarray.area.get_h() + h_non_cell_area;
42110152Satgutier@umich.edu//    area.w = num_subarrays_per_row * subarray.area.get_w() + w_non_cell_area;
42210152Satgutier@umich.edu//    area.w = (area.h*area.w + area_mat_center_circuitry) / area.h;
42310152Satgutier@umich.edu//    area_efficiency_mat = subarray.area.get_area() * num_subarrays_per_row * 100.0 / area.get_area();
42410152Satgutier@umich.edu//  }
42510152Satgutier@umich.edu}
42610152Satgutier@umich.edu
42710152Satgutier@umich.edu
42810152Satgutier@umich.edu
42910234Syasuko.eckert@amd.comMat::~Mat() {
43010234Syasuko.eckert@amd.com    delete row_dec;
43110234Syasuko.eckert@amd.com    delete bit_mux_dec;
43210234Syasuko.eckert@amd.com    delete sa_mux_lev_1_dec;
43310234Syasuko.eckert@amd.com    delete sa_mux_lev_2_dec;
43410152Satgutier@umich.edu
43510234Syasuko.eckert@amd.com    delete r_predec->blk1;
43610234Syasuko.eckert@amd.com    delete r_predec->blk2;
43710234Syasuko.eckert@amd.com    delete b_mux_predec->blk1;
43810234Syasuko.eckert@amd.com    delete b_mux_predec->blk2;
43910234Syasuko.eckert@amd.com    delete sa_mux_lev_1_predec->blk1;
44010234Syasuko.eckert@amd.com    delete sa_mux_lev_1_predec->blk2;
44110234Syasuko.eckert@amd.com    delete sa_mux_lev_2_predec->blk1;
44210234Syasuko.eckert@amd.com    delete sa_mux_lev_2_predec->blk2;
44310234Syasuko.eckert@amd.com    delete dummy_way_sel_predec_blk1;
44410234Syasuko.eckert@amd.com    delete dummy_way_sel_predec_blk2;
44510152Satgutier@umich.edu
44610234Syasuko.eckert@amd.com    delete r_predec->drv1;
44710234Syasuko.eckert@amd.com    delete r_predec->drv2;
44810234Syasuko.eckert@amd.com    delete b_mux_predec->drv1;
44910234Syasuko.eckert@amd.com    delete b_mux_predec->drv2;
45010234Syasuko.eckert@amd.com    delete sa_mux_lev_1_predec->drv1;
45110234Syasuko.eckert@amd.com    delete sa_mux_lev_1_predec->drv2;
45210234Syasuko.eckert@amd.com    delete sa_mux_lev_2_predec->drv1;
45310234Syasuko.eckert@amd.com    delete sa_mux_lev_2_predec->drv2;
45410234Syasuko.eckert@amd.com    delete way_sel_drv1;
45510234Syasuko.eckert@amd.com    delete dummy_way_sel_predec_blk_drv2;
45610152Satgutier@umich.edu
45710234Syasuko.eckert@amd.com    delete r_predec;
45810234Syasuko.eckert@amd.com    delete b_mux_predec;
45910234Syasuko.eckert@amd.com    delete sa_mux_lev_1_predec;
46010234Syasuko.eckert@amd.com    delete sa_mux_lev_2_predec;
46110152Satgutier@umich.edu
46210234Syasuko.eckert@amd.com    delete subarray_out_wire;
46310234Syasuko.eckert@amd.com    if (!pure_cam)
46410234Syasuko.eckert@amd.com        delete bl_precharge_eq_drv;
46510152Satgutier@umich.edu
46610234Syasuko.eckert@amd.com    if (is_fa || pure_cam) {
46710234Syasuko.eckert@amd.com        delete sl_precharge_eq_drv ;
46810234Syasuko.eckert@amd.com        delete sl_data_drv ;
46910234Syasuko.eckert@amd.com        delete cam_bl_precharge_eq_drv;
47010234Syasuko.eckert@amd.com        delete ml_precharge_drv;
47110234Syasuko.eckert@amd.com        delete ml_to_ram_wl_drv;
47210152Satgutier@umich.edu    }
47310152Satgutier@umich.edu}
47410152Satgutier@umich.edu
47510152Satgutier@umich.edu
47610152Satgutier@umich.edu
47710234Syasuko.eckert@amd.comdouble Mat::compute_delays(double inrisetime) {
47810234Syasuko.eckert@amd.com    int k;
47910234Syasuko.eckert@amd.com    double rd, C_intrinsic, C_ld, tf, R_bl_precharge, r_b_metal, R_bl, C_bl;
48010234Syasuko.eckert@amd.com    double outrisetime_search, outrisetime, row_dec_outrisetime;
48110234Syasuko.eckert@amd.com    // delay calculation for tags of fully associative cache
48210234Syasuko.eckert@amd.com    if (is_fa || pure_cam) {
48310234Syasuko.eckert@amd.com        //Compute search access time
48410234Syasuko.eckert@amd.com        outrisetime_search = compute_cam_delay(inrisetime);
48510234Syasuko.eckert@amd.com        if (is_fa) {
48610234Syasuko.eckert@amd.com            bl_precharge_eq_drv->compute_delay(0);
48710234Syasuko.eckert@amd.com            k = ml_to_ram_wl_drv->number_gates - 1;
48810234Syasuko.eckert@amd.com            rd = tr_R_on(ml_to_ram_wl_drv->width_n[k], NCH, 1, is_dram, false, true);
48910234Syasuko.eckert@amd.com            C_intrinsic = drain_C_(ml_to_ram_wl_drv->width_n[k], PCH, 1, 1, 4 *
49010234Syasuko.eckert@amd.com                                   cell.h, is_dram, false, true) +
49110234Syasuko.eckert@amd.com                drain_C_(ml_to_ram_wl_drv->width_n[k], NCH, 1, 1, 4 * cell.h,
49210234Syasuko.eckert@amd.com                         is_dram, false, true);
49310234Syasuko.eckert@amd.com            C_ld = ml_to_ram_wl_drv->c_gate_load +
49410234Syasuko.eckert@amd.com                ml_to_ram_wl_drv->c_wire_load;
49510234Syasuko.eckert@amd.com            tf = rd * (C_intrinsic + C_ld) + ml_to_ram_wl_drv->r_wire_load * C_ld / 2;
49610234Syasuko.eckert@amd.com            delay_wl_reset = horowitz(0, tf, 0.5, 0.5, RISE);
49710152Satgutier@umich.edu
49810234Syasuko.eckert@amd.com            R_bl_precharge = tr_R_on(g_tp.w_pmos_bl_precharge, PCH, 1, is_dram, false, false);
49910234Syasuko.eckert@amd.com            r_b_metal = cam_cell.h * g_tp.wire_local.R_per_um;//dummy rows in sram are filled in
50010234Syasuko.eckert@amd.com            R_bl = subarray.num_rows * r_b_metal;
50110234Syasuko.eckert@amd.com            C_bl = subarray.C_bl;
50210234Syasuko.eckert@amd.com            delay_bl_restore = bl_precharge_eq_drv->delay +
50310234Syasuko.eckert@amd.com                log((g_tp.sram.Vbitpre - 0.1 * dp.V_b_sense) /
50410234Syasuko.eckert@amd.com                    (g_tp.sram.Vbitpre - dp.V_b_sense)) *
50510234Syasuko.eckert@amd.com                (R_bl_precharge * C_bl + R_bl * C_bl / 2);
50610152Satgutier@umich.edu
50710152Satgutier@umich.edu
50810234Syasuko.eckert@amd.com            outrisetime_search = compute_bitline_delay(outrisetime_search);
50910234Syasuko.eckert@amd.com            outrisetime_search = compute_sa_delay(outrisetime_search);
51010234Syasuko.eckert@amd.com        }
51110234Syasuko.eckert@amd.com        outrisetime_search = compute_subarray_out_drv(outrisetime_search);
51210234Syasuko.eckert@amd.com        subarray_out_wire->set_in_rise_time(outrisetime_search);
51310234Syasuko.eckert@amd.com        outrisetime_search = subarray_out_wire->signal_rise_time();
51410234Syasuko.eckert@amd.com        delay_subarray_out_drv_htree = delay_subarray_out_drv + subarray_out_wire->delay;
51510152Satgutier@umich.edu
51610152Satgutier@umich.edu
51710234Syasuko.eckert@amd.com        //TODO: this is just for compute plain read/write energy for fa and cam, plain read/write access timing need to be revisited.
51810234Syasuko.eckert@amd.com        outrisetime = r_predec->compute_delays(inrisetime);
51910234Syasuko.eckert@amd.com        row_dec_outrisetime = row_dec->compute_delays(outrisetime);
52010152Satgutier@umich.edu
52110234Syasuko.eckert@amd.com        outrisetime = b_mux_predec->compute_delays(inrisetime);
52210234Syasuko.eckert@amd.com        bit_mux_dec->compute_delays(outrisetime);
52310152Satgutier@umich.edu
52410234Syasuko.eckert@amd.com        outrisetime = sa_mux_lev_1_predec->compute_delays(inrisetime);
52510234Syasuko.eckert@amd.com        sa_mux_lev_1_dec->compute_delays(outrisetime);
52610152Satgutier@umich.edu
52710234Syasuko.eckert@amd.com        outrisetime = sa_mux_lev_2_predec->compute_delays(inrisetime);
52810234Syasuko.eckert@amd.com        sa_mux_lev_2_dec->compute_delays(outrisetime);
52910234Syasuko.eckert@amd.com
53010234Syasuko.eckert@amd.com        if (pure_cam) {
53110234Syasuko.eckert@amd.com            outrisetime = compute_bitline_delay(row_dec_outrisetime);
53210234Syasuko.eckert@amd.com            outrisetime = compute_sa_delay(outrisetime);
53310234Syasuko.eckert@amd.com        }
53410234Syasuko.eckert@amd.com        return outrisetime_search;
53510234Syasuko.eckert@amd.com    } else {
53610234Syasuko.eckert@amd.com        bl_precharge_eq_drv->compute_delay(0);
53710234Syasuko.eckert@amd.com        if (row_dec->exist == true) {
53810234Syasuko.eckert@amd.com            int k = row_dec->num_gates - 1;
53910234Syasuko.eckert@amd.com            double rd = tr_R_on(row_dec->w_dec_n[k], NCH, 1, is_dram, false, true);
54010234Syasuko.eckert@amd.com            // TODO: this 4*cell.h number must be revisited
54110234Syasuko.eckert@amd.com            double C_intrinsic = drain_C_(row_dec->w_dec_p[k], PCH, 1, 1, 4 *
54210234Syasuko.eckert@amd.com                                          cell.h, is_dram, false, true) +
54310234Syasuko.eckert@amd.com                drain_C_(row_dec->w_dec_n[k], NCH, 1, 1, 4 * cell.h, is_dram,
54410234Syasuko.eckert@amd.com                         false, true);
54510234Syasuko.eckert@amd.com            double C_ld = row_dec->C_ld_dec_out;
54610234Syasuko.eckert@amd.com            double tf = rd * (C_intrinsic + C_ld) + row_dec->R_wire_dec_out * C_ld / 2;
54710234Syasuko.eckert@amd.com            delay_wl_reset = horowitz(0, tf, 0.5, 0.5, RISE);
54810234Syasuko.eckert@amd.com        }
54910234Syasuko.eckert@amd.com        double R_bl_precharge = tr_R_on(g_tp.w_pmos_bl_precharge, PCH, 1, is_dram, false, false);
55010234Syasuko.eckert@amd.com        double r_b_metal = cell.h * g_tp.wire_local.R_per_um;
55110234Syasuko.eckert@amd.com        double R_bl = subarray.num_rows * r_b_metal;
55210234Syasuko.eckert@amd.com        double C_bl = subarray.C_bl;
55310234Syasuko.eckert@amd.com
55410234Syasuko.eckert@amd.com        if (is_dram) {
55510234Syasuko.eckert@amd.com            delay_bl_restore = bl_precharge_eq_drv->delay + 2.3 * (R_bl_precharge * C_bl + R_bl * C_bl / 2);
55610234Syasuko.eckert@amd.com        } else {
55710234Syasuko.eckert@amd.com            delay_bl_restore = bl_precharge_eq_drv->delay +
55810234Syasuko.eckert@amd.com                log((g_tp.sram.Vbitpre - 0.1 * dp.V_b_sense) /
55910234Syasuko.eckert@amd.com                    (g_tp.sram.Vbitpre - dp.V_b_sense)) *
56010234Syasuko.eckert@amd.com                (R_bl_precharge * C_bl + R_bl * C_bl / 2);
56110234Syasuko.eckert@amd.com        }
56210234Syasuko.eckert@amd.com    }
56310234Syasuko.eckert@amd.com
56410234Syasuko.eckert@amd.com
56510234Syasuko.eckert@amd.com
56610234Syasuko.eckert@amd.com    outrisetime = r_predec->compute_delays(inrisetime);
56710234Syasuko.eckert@amd.com    row_dec_outrisetime = row_dec->compute_delays(outrisetime);
56810234Syasuko.eckert@amd.com
56910234Syasuko.eckert@amd.com    outrisetime = b_mux_predec->compute_delays(inrisetime);
57010234Syasuko.eckert@amd.com    bit_mux_dec->compute_delays(outrisetime);
57110234Syasuko.eckert@amd.com
57210234Syasuko.eckert@amd.com    outrisetime = sa_mux_lev_1_predec->compute_delays(inrisetime);
57310234Syasuko.eckert@amd.com    sa_mux_lev_1_dec->compute_delays(outrisetime);
57410234Syasuko.eckert@amd.com
57510234Syasuko.eckert@amd.com    outrisetime = sa_mux_lev_2_predec->compute_delays(inrisetime);
57610234Syasuko.eckert@amd.com    sa_mux_lev_2_dec->compute_delays(outrisetime);
57710234Syasuko.eckert@amd.com
57810234Syasuko.eckert@amd.com    outrisetime = compute_bitline_delay(row_dec_outrisetime);
57910234Syasuko.eckert@amd.com    outrisetime = compute_sa_delay(outrisetime);
58010234Syasuko.eckert@amd.com    outrisetime = compute_subarray_out_drv(outrisetime);
58110234Syasuko.eckert@amd.com    subarray_out_wire->set_in_rise_time(outrisetime);
58210234Syasuko.eckert@amd.com    outrisetime = subarray_out_wire->signal_rise_time();
58310234Syasuko.eckert@amd.com
58410234Syasuko.eckert@amd.com    delay_subarray_out_drv_htree = delay_subarray_out_drv + subarray_out_wire->delay;
58510234Syasuko.eckert@amd.com
58610234Syasuko.eckert@amd.com    if (dp.is_tag == true && dp.fully_assoc == false) {
58710234Syasuko.eckert@amd.com        compute_comparator_delay(0);
58810234Syasuko.eckert@amd.com    }
58910234Syasuko.eckert@amd.com
59010234Syasuko.eckert@amd.com    if (row_dec->exist == false) {
59110234Syasuko.eckert@amd.com        delay_wl_reset = MAX(r_predec->blk1->delay, r_predec->blk2->delay);
59210234Syasuko.eckert@amd.com    }
59310234Syasuko.eckert@amd.com    return outrisetime;
59410152Satgutier@umich.edu}
59510152Satgutier@umich.edu
59610152Satgutier@umich.edu
59710152Satgutier@umich.edu
59810234Syasuko.eckert@amd.comdouble Mat::compute_bit_mux_sa_precharge_sa_mux_wr_drv_wr_mux_h() {
59910152Satgutier@umich.edu
60010234Syasuko.eckert@amd.com    double height =
60110234Syasuko.eckert@amd.com        compute_tr_width_after_folding(g_tp.w_pmos_bl_precharge,
60210234Syasuko.eckert@amd.com                                       camFlag ? cam_cell.w :
60310234Syasuko.eckert@amd.com                                       cell.w / (2 * (RWP + ERP + SCHP))) +
60410234Syasuko.eckert@amd.com        // precharge circuitry
60510234Syasuko.eckert@amd.com        compute_tr_width_after_folding(g_tp.w_pmos_bl_eq,
60610234Syasuko.eckert@amd.com                                       camFlag ? cam_cell.w :
60710234Syasuko.eckert@amd.com                                       cell.w / (RWP + ERP + SCHP));
60810152Satgutier@umich.edu
60910234Syasuko.eckert@amd.com    if (deg_bl_muxing > 1) {
61010234Syasuko.eckert@amd.com        // col mux tr height
61110234Syasuko.eckert@amd.com        height +=
61210234Syasuko.eckert@amd.com            compute_tr_width_after_folding(g_tp.w_nmos_b_mux,
61310234Syasuko.eckert@amd.com                                           cell.w / (2 * (RWP + ERP)));
61410234Syasuko.eckert@amd.com        // height += deg_bl_muxing * g_tp.wire_inside_mat.pitch * (RWP + ERP);  // bit mux dec out wires height
61510234Syasuko.eckert@amd.com    }
61610152Satgutier@umich.edu
61710234Syasuko.eckert@amd.com    height += height_sense_amplifier(/*camFlag? sram_cell.w:*/cell.w * deg_bl_muxing / (RWP + ERP));  // sense_amp_height
61810234Syasuko.eckert@amd.com
61910234Syasuko.eckert@amd.com    if (dp.Ndsam_lev_1 > 1) {
62010234Syasuko.eckert@amd.com        height += compute_tr_width_after_folding(
62110234Syasuko.eckert@amd.com                      g_tp.w_nmos_sa_mux, cell.w * dp.Ndsam_lev_1 / (RWP + ERP));  // sense_amp_mux_height
62210234Syasuko.eckert@amd.com        //height_senseamp_mux_decode_output_wires =  Ndsam * wire_inside_mat_pitch * (RWP + ERP);
62310234Syasuko.eckert@amd.com    }
62410234Syasuko.eckert@amd.com
62510234Syasuko.eckert@amd.com    if (dp.Ndsam_lev_2 > 1) {
62610234Syasuko.eckert@amd.com        height += compute_tr_width_after_folding(
62710234Syasuko.eckert@amd.com                      g_tp.w_nmos_sa_mux, cell.w * deg_bl_muxing * dp.Ndsam_lev_1 / (RWP + ERP));  // sense_amp_mux_height
62810234Syasuko.eckert@amd.com        //height_senseamp_mux_decode_output_wires =  Ndsam * wire_inside_mat_pitch * (RWP + ERP);
62910234Syasuko.eckert@amd.com
63010234Syasuko.eckert@amd.com        // add height of inverter-buffers between the two levels (pass-transistors) of sense-amp mux
63110234Syasuko.eckert@amd.com        height += 2 * compute_tr_width_after_folding(
63210234Syasuko.eckert@amd.com                      pmos_to_nmos_sz_ratio(is_dram) * g_tp.min_w_nmos_, cell.w * dp.Ndsam_lev_2 / (RWP + ERP));
63310234Syasuko.eckert@amd.com        height += 2 * compute_tr_width_after_folding(g_tp.min_w_nmos_, cell.w * dp.Ndsam_lev_2 / (RWP + ERP));
63410234Syasuko.eckert@amd.com    }
63510234Syasuko.eckert@amd.com
63610234Syasuko.eckert@amd.com    // TODO: this should be uncommented...
63710234Syasuko.eckert@amd.com    /*if (deg_bl_muxing * dp.Ndsam_lev_1 * dp.Ndsam_lev_2 > 1)
63810234Syasuko.eckert@amd.com      {
63910234Syasuko.eckert@amd.com    //height_write_mux_decode_output_wires = deg_bl_muxing * Ndsam * g_tp.wire_inside_mat.pitch * (RWP + EWP);
64010234Syasuko.eckert@amd.com    double width_write_driver_write_mux  = width_write_driver_or_write_mux();
64110234Syasuko.eckert@amd.com    double height_write_driver_write_mux = compute_tr_width_after_folding(2 * width_write_driver_write_mux,
64210234Syasuko.eckert@amd.com    cell.w *
64310234Syasuko.eckert@amd.com    // deg_bl_muxing *
64410234Syasuko.eckert@amd.com    dp.Ndsam_lev_1 * dp.Ndsam_lev_2 / (RWP + EWP));
64510234Syasuko.eckert@amd.com    height += height_write_driver_write_mux;
64610234Syasuko.eckert@amd.com    }*/
64710234Syasuko.eckert@amd.com
64810234Syasuko.eckert@amd.com    return height;
64910234Syasuko.eckert@amd.com}
65010234Syasuko.eckert@amd.com
65110234Syasuko.eckert@amd.com
65210234Syasuko.eckert@amd.com
65310234Syasuko.eckert@amd.comdouble Mat::compute_cam_delay(double inrisetime) {
65410234Syasuko.eckert@amd.com
65510234Syasuko.eckert@amd.com    double out_time_ramp, this_delay;
65610234Syasuko.eckert@amd.com    double Rwire, tf, c_intrinsic, rd, Cwire, c_gate_load;
65710234Syasuko.eckert@amd.com
65810234Syasuko.eckert@amd.com
65910234Syasuko.eckert@amd.com    double Wdecdrivep, Wdecdriven, Wfadriven, Wfadrivep, Wfadrive2n, Wfadrive2p, Wfadecdrive1n, Wfadecdrive1p,
66010152Satgutier@umich.edu    Wfadecdrive2n, Wfadecdrive2p, Wfadecdriven, Wfadecdrivep, Wfaprechn, Wfaprechp,
66110152Satgutier@umich.edu    Wdummyn, Wdummyinvn, Wdummyinvp, Wfainvn, Wfainvp, Waddrnandn, Waddrnandp,
66210152Satgutier@umich.edu    Wfanandn, Wfanandp, Wfanorn, Wfanorp, Wdecnandn, Wdecnandp, W_hit_miss_n, W_hit_miss_p;
66310152Satgutier@umich.edu
66410234Syasuko.eckert@amd.com    double c_matchline_metal, r_matchline_metal, c_searchline_metal, r_searchline_metal,  dynSearchEng;
66510234Syasuko.eckert@amd.com    int Htagbits;
66610152Satgutier@umich.edu
66710234Syasuko.eckert@amd.com    double driver_c_gate_load;
66810234Syasuko.eckert@amd.com    double driver_c_wire_load;
66910234Syasuko.eckert@amd.com    double driver_r_wire_load;
67010234Syasuko.eckert@amd.com    //double searchline_precharge_time;
67110152Satgutier@umich.edu
67210234Syasuko.eckert@amd.com    double leak_power_cc_inverters_sram_cell         = 0;
67310234Syasuko.eckert@amd.com    double leak_power_acc_tr_RW_or_WR_port_sram_cell = 0;
67410234Syasuko.eckert@amd.com    double leak_power_RD_port_sram_cell              = 0;
67510234Syasuko.eckert@amd.com    double leak_power_SCHP_port_sram_cell            = 0;
67610234Syasuko.eckert@amd.com    double leak_comparator_cam_cell                  =0;
67710152Satgutier@umich.edu
67810234Syasuko.eckert@amd.com    double gate_leak_comparator_cam_cell          = 0;
67910234Syasuko.eckert@amd.com    double gate_leak_power_cc_inverters_sram_cell = 0;
68010234Syasuko.eckert@amd.com    double gate_leak_power_RD_port_sram_cell      = 0;
68110234Syasuko.eckert@amd.com    double gate_leak_power_SCHP_port_sram_cell    = 0;
68210152Satgutier@umich.edu
68310234Syasuko.eckert@amd.com    c_matchline_metal   = cam_cell.get_w() * g_tp.wire_local.C_per_um;
68410234Syasuko.eckert@amd.com    c_searchline_metal  = cam_cell.get_h() * g_tp.wire_local.C_per_um;
68510234Syasuko.eckert@amd.com    r_matchline_metal   = cam_cell.get_w() * g_tp.wire_local.R_per_um;
68610234Syasuko.eckert@amd.com    r_searchline_metal  = cam_cell.get_h() * g_tp.wire_local.R_per_um;
68710152Satgutier@umich.edu
68810234Syasuko.eckert@amd.com    dynSearchEng = 0.0;
68910234Syasuko.eckert@amd.com    delay_matchchline = 0.0;
69010234Syasuko.eckert@amd.com    double p_to_n_sizing_r = pmos_to_nmos_sz_ratio(is_dram);
69110234Syasuko.eckert@amd.com    bool linear_scaling = false;
69210152Satgutier@umich.edu
69310234Syasuko.eckert@amd.com    if (linear_scaling) {
69410234Syasuko.eckert@amd.com        Wdecdrivep    =  450 * g_ip->F_sz_um;//this was 360 micron for the 0.8 micron process
69510234Syasuko.eckert@amd.com        Wdecdriven    =  300 * g_ip->F_sz_um;//this was 240 micron for the 0.8 micron process
69610234Syasuko.eckert@amd.com        Wfadriven     = 62.5 * g_ip->F_sz_um;//this was  50 micron for the 0.8 micron process
69710234Syasuko.eckert@amd.com        Wfadrivep     =  125 * g_ip->F_sz_um;//this was 100 micron for the 0.8 micron process
69810234Syasuko.eckert@amd.com        Wfadrive2n    =  250 * g_ip->F_sz_um;//this was 200 micron for the 0.8 micron process
69910234Syasuko.eckert@amd.com        Wfadrive2p    =  500 * g_ip->F_sz_um;//this was 400 micron for the 0.8 micron process
70010234Syasuko.eckert@amd.com        Wfadecdrive1n = 6.25 * g_ip->F_sz_um;//this was   5 micron for the 0.8 micron process
70110234Syasuko.eckert@amd.com        Wfadecdrive1p = 12.5 * g_ip->F_sz_um;//this was  10 micron for the 0.8 micron process
70210234Syasuko.eckert@amd.com        Wfadecdrive2n =   25 * g_ip->F_sz_um;//this was  20 micron for the 0.8 micron process
70310234Syasuko.eckert@amd.com        Wfadecdrive2p =   50 * g_ip->F_sz_um;//this was  40 micron for the 0.8 micron process
70410234Syasuko.eckert@amd.com        Wfadecdriven  = 62.5 * g_ip->F_sz_um;//this was  50 micron for the 0.8 micron process
70510234Syasuko.eckert@amd.com        Wfadecdrivep  =  125 * g_ip->F_sz_um;//this was 100 micron for the 0.8 micron process
70610234Syasuko.eckert@amd.com        Wfaprechn     =  7.5 * g_ip->F_sz_um;//this was   6 micron for the 0.8 micron process
70710234Syasuko.eckert@amd.com        Wfainvn       = 12.5 * g_ip->F_sz_um;//this was  10 micron for the 0.8 micron process
70810234Syasuko.eckert@amd.com        Wfainvp       =   25 * g_ip->F_sz_um;//this was  20 micron for the 0.8 micron process
70910234Syasuko.eckert@amd.com        Wfanandn      =   25 * g_ip->F_sz_um;//this was  20 micron for the 0.8 micron process
71010234Syasuko.eckert@amd.com        Wfanandp      = 37.5 * g_ip->F_sz_um;//this was  30 micron for the 0.8 micron process
71110234Syasuko.eckert@amd.com        Wdecnandn     = 12.5 * g_ip->F_sz_um;//this was  10 micron for the 0.8 micron process
71210234Syasuko.eckert@amd.com        Wdecnandp     = 37.5 * g_ip->F_sz_um;//this was  30 micron for the 0.8 micron process
71310152Satgutier@umich.edu
71410234Syasuko.eckert@amd.com        Wfaprechp     = 12.5 * g_ip->F_sz_um;//this was  10 micron for the 0.8 micron process
71510234Syasuko.eckert@amd.com        Wdummyn       = 12.5 * g_ip->F_sz_um;//this was  10 micron for the 0.8 micron process
71610234Syasuko.eckert@amd.com        Wdummyinvn    =   75 * g_ip->F_sz_um;//this was  60 micron for the 0.8 micron process
71710234Syasuko.eckert@amd.com        Wdummyinvp    =  100 * g_ip->F_sz_um;//this was  80 micron for the 0.8 micron process
71810234Syasuko.eckert@amd.com        Waddrnandn    = 62.5 * g_ip->F_sz_um;//this was  50 micron for the 0.8 micron process
71910234Syasuko.eckert@amd.com        Waddrnandp    = 62.5 * g_ip->F_sz_um;//this was  50 micron for the 0.8 micron process
72010234Syasuko.eckert@amd.com        Wfanorn       = 6.25 * g_ip->F_sz_um;//this was   5 micron for the 0.8 micron process
72110234Syasuko.eckert@amd.com        Wfanorp       = 12.5 * g_ip->F_sz_um;//this was  10 micron for the 0.8 micron process
72210234Syasuko.eckert@amd.com        W_hit_miss_n    = Wdummyn;
72310234Syasuko.eckert@amd.com        W_hit_miss_p    = g_tp.min_w_nmos_*p_to_n_sizing_r;
72410234Syasuko.eckert@amd.com        //TODO: this number should updated using new layout; from the NAND to output NOR should be computed using logical effort
72510234Syasuko.eckert@amd.com    } else {
72610234Syasuko.eckert@amd.com        Wdecdrivep    =  450 * g_ip->F_sz_um;//this was 360 micron for the 0.8 micron process
72710234Syasuko.eckert@amd.com        Wdecdriven    =  300 * g_ip->F_sz_um;//this was 240 micron for the 0.8 micron process
72810234Syasuko.eckert@amd.com        Wfadriven     = 62.5 * g_ip->F_sz_um;//this was  50 micron for the 0.8 micron process
72910234Syasuko.eckert@amd.com        Wfadrivep     =  125 * g_ip->F_sz_um;//this was 100 micron for the 0.8 micron process
73010234Syasuko.eckert@amd.com        Wfadrive2n    =  250 * g_ip->F_sz_um;//this was 200 micron for the 0.8 micron process
73110234Syasuko.eckert@amd.com        Wfadrive2p    =  500 * g_ip->F_sz_um;//this was 400 micron for the 0.8 micron process
73210234Syasuko.eckert@amd.com        Wfadecdrive1n = 6.25 * g_ip->F_sz_um;//this was   5 micron for the 0.8 micron process
73310234Syasuko.eckert@amd.com        Wfadecdrive1p = 12.5 * g_ip->F_sz_um;//this was  10 micron for the 0.8 micron process
73410234Syasuko.eckert@amd.com        Wfadecdrive2n =   25 * g_ip->F_sz_um;//this was  20 micron for the 0.8 micron process
73510234Syasuko.eckert@amd.com        Wfadecdrive2p =   50 * g_ip->F_sz_um;//this was  40 micron for the 0.8 micron process
73610234Syasuko.eckert@amd.com        Wfadecdriven  = 62.5 * g_ip->F_sz_um;//this was  50 micron for the 0.8 micron process
73710234Syasuko.eckert@amd.com        Wfadecdrivep  =  125 * g_ip->F_sz_um;//this was 100 micron for the 0.8 micron process
73810234Syasuko.eckert@amd.com        Wfaprechn     =  7.5 * g_ip->F_sz_um;//this was   6 micron for the 0.8 micron process
73910234Syasuko.eckert@amd.com        Wfainvn       = 12.5 * g_ip->F_sz_um;//this was  10 micron for the 0.8 micron process
74010234Syasuko.eckert@amd.com        Wfainvp       =   25 * g_ip->F_sz_um;//this was  20 micron for the 0.8 micron process
74110234Syasuko.eckert@amd.com        Wfanandn      =   25 * g_ip->F_sz_um;//this was  20 micron for the 0.8 micron process
74210234Syasuko.eckert@amd.com        Wfanandp      = 37.5 * g_ip->F_sz_um;//this was  30 micron for the 0.8 micron process
74310234Syasuko.eckert@amd.com        Wdecnandn     = 12.5 * g_ip->F_sz_um;//this was  10 micron for the 0.8 micron process
74410234Syasuko.eckert@amd.com        Wdecnandp     = 37.5 * g_ip->F_sz_um;//this was  30 micron for the 0.8 micron process
74510152Satgutier@umich.edu
74610234Syasuko.eckert@amd.com        Wfaprechp     = g_tp.w_pmos_bl_precharge;//this was  10 micron for the 0.8 micron process
74710234Syasuko.eckert@amd.com        Wdummyn       = g_tp.cam.cell_nmos_w;
74810234Syasuko.eckert@amd.com        Wdummyinvn    =   75 * g_ip->F_sz_um;//this was  60 micron for the 0.8 micron process
74910234Syasuko.eckert@amd.com        Wdummyinvp    =  100 * g_ip->F_sz_um;//this was  80 micron for the 0.8 micron process
75010234Syasuko.eckert@amd.com        Waddrnandn    = 62.5 * g_ip->F_sz_um;//this was  50 micron for the 0.8 micron process
75110234Syasuko.eckert@amd.com        Waddrnandp    = 62.5 * g_ip->F_sz_um;//this was  50 micron for the 0.8 micron process
75210234Syasuko.eckert@amd.com        Wfanorn       = 6.25 * g_ip->F_sz_um;//this was   5 micron for the 0.8 micron process
75310234Syasuko.eckert@amd.com        Wfanorp       = 12.5 * g_ip->F_sz_um;//this was  10 micron for the 0.8 micron process
75410234Syasuko.eckert@amd.com        W_hit_miss_n    = Wdummyn;
75510234Syasuko.eckert@amd.com        W_hit_miss_p    = g_tp.min_w_nmos_*p_to_n_sizing_r;
75610234Syasuko.eckert@amd.com    }
75710152Satgutier@umich.edu
75810234Syasuko.eckert@amd.com    Htagbits = (int)(ceil ((double) (subarray.num_cols_fa_cam) / 2.0));
75910152Satgutier@umich.edu
76010234Syasuko.eckert@amd.com    /* First stage, searchline is precharged. searchline data driver drives the searchline to open (if miss) the comparators.
76110234Syasuko.eckert@amd.com       search_line_delay, search_line_power, search_line_restore_delay for cycle time computation.
76210234Syasuko.eckert@amd.com       From the driver(am and an) to the comparators in all the rows including the dummy row,
76310234Syasuko.eckert@amd.com       Assuming that comparators in both the normal matching line and the dummy matching line have the same sizing */
76410152Satgutier@umich.edu
76510234Syasuko.eckert@amd.com    //Searchline precharge circuitry is same as that of bitline. However, no sharing between search ports and r/w ports
76610234Syasuko.eckert@amd.com    //Searchline precharge routes horizontally
76710234Syasuko.eckert@amd.com    driver_c_gate_load = subarray.num_cols_fa_cam * gate_C(2 * g_tp.w_pmos_bl_precharge + g_tp.w_pmos_bl_eq, 0, is_dram, false, false);
76810234Syasuko.eckert@amd.com    driver_c_wire_load = subarray.num_cols_fa_cam * cam_cell.w * g_tp.wire_outside_mat.C_per_um;
76910234Syasuko.eckert@amd.com    driver_r_wire_load = subarray.num_cols_fa_cam * cam_cell.w * g_tp.wire_outside_mat.R_per_um;
77010152Satgutier@umich.edu
77110234Syasuko.eckert@amd.com    sl_precharge_eq_drv = new Driver(
77210234Syasuko.eckert@amd.com        driver_c_gate_load,
77310234Syasuko.eckert@amd.com        driver_c_wire_load,
77410234Syasuko.eckert@amd.com        driver_r_wire_load,
77510234Syasuko.eckert@amd.com        is_dram);
77610152Satgutier@umich.edu
77710234Syasuko.eckert@amd.com    //searchline data driver ; subarray.num_rows + 1 is because of the dummy row
77810234Syasuko.eckert@amd.com    //data drv should only have gate_C not 2*gate_C since the two searchlines are differential--same as bitlines
77910234Syasuko.eckert@amd.com    driver_c_gate_load = (subarray.num_rows + 1) * gate_C(Wdummyn, 0, is_dram, false, false);
78010234Syasuko.eckert@amd.com    driver_c_wire_load = (subarray.num_rows + 1) * c_searchline_metal;
78110234Syasuko.eckert@amd.com    driver_r_wire_load = (subarray.num_rows + 1) * r_searchline_metal;
78210234Syasuko.eckert@amd.com    sl_data_drv = new Driver(
78310234Syasuko.eckert@amd.com        driver_c_gate_load,
78410234Syasuko.eckert@amd.com        driver_c_wire_load,
78510234Syasuko.eckert@amd.com        driver_r_wire_load,
78610234Syasuko.eckert@amd.com        is_dram);
78710152Satgutier@umich.edu
78810234Syasuko.eckert@amd.com    sl_precharge_eq_drv->compute_delay(0);
78910234Syasuko.eckert@amd.com    double R_bl_precharge = tr_R_on(g_tp.w_pmos_bl_precharge, PCH, 1, is_dram, false, false);//Assuming CAM and SRAM have same Pre_eq_dr
79010234Syasuko.eckert@amd.com    double r_b_metal = cam_cell.h * g_tp.wire_local.R_per_um;
79110234Syasuko.eckert@amd.com    double R_bl = (subarray.num_rows + 1) * r_b_metal;
79210234Syasuko.eckert@amd.com    double C_bl = subarray.C_bl_cam;
79310234Syasuko.eckert@amd.com    delay_cam_sl_restore = sl_precharge_eq_drv->delay
79410234Syasuko.eckert@amd.com        + log(g_tp.cam.Vbitpre) * (R_bl_precharge * C_bl + R_bl * C_bl / 2);
79510152Satgutier@umich.edu
79610234Syasuko.eckert@amd.com    out_time_ramp = sl_data_drv->compute_delay(inrisetime);//After entering one mat, start to consider the inrisetime from 0(0 is passed from outside)
79710152Satgutier@umich.edu
79810234Syasuko.eckert@amd.com    //matchline ops delay
79910234Syasuko.eckert@amd.com    delay_matchchline += sl_data_drv->delay;
80010152Satgutier@umich.edu
80110234Syasuko.eckert@amd.com    /* second stage, from the trasistors in the comparators(both normal row and dummy row) to the NAND gates that combins both half*/
80210234Syasuko.eckert@amd.com    //matchline delay, matchline power, matchline_reset for cycle time computation,
80310152Satgutier@umich.edu
80410234Syasuko.eckert@amd.com    ////matchline precharge circuitry routes vertically
80510234Syasuko.eckert@amd.com    //There are two matchline precharge driver chains per subarray.
80610234Syasuko.eckert@amd.com    driver_c_gate_load = (subarray.num_rows + 1) * gate_C(Wfaprechp, 0, is_dram);
80710234Syasuko.eckert@amd.com    driver_c_wire_load = (subarray.num_rows + 1) * c_searchline_metal;
80810234Syasuko.eckert@amd.com    driver_r_wire_load = (subarray.num_rows + 1) * r_searchline_metal;
80910152Satgutier@umich.edu
81010234Syasuko.eckert@amd.com    ml_precharge_drv = new Driver(
81110234Syasuko.eckert@amd.com        driver_c_gate_load,
81210234Syasuko.eckert@amd.com        driver_c_wire_load,
81310234Syasuko.eckert@amd.com        driver_r_wire_load,
81410234Syasuko.eckert@amd.com        is_dram);
81510152Satgutier@umich.edu
81610234Syasuko.eckert@amd.com    ml_precharge_drv->compute_delay(0);
81710152Satgutier@umich.edu
81810152Satgutier@umich.edu
81910234Syasuko.eckert@amd.com    rd =  tr_R_on(Wdummyn, NCH, 2, is_dram);
82010234Syasuko.eckert@amd.com    c_intrinsic = Htagbits *
82110234Syasuko.eckert@amd.com        (2 * drain_C_(Wdummyn, NCH, 2, 1, g_tp.cell_h_def,
82210234Syasuko.eckert@amd.com                      is_dram)//TODO: the cell_h_def should be revisit
82310234Syasuko.eckert@amd.com         + drain_C_(Wfaprechp, PCH, 1, 1, g_tp.cell_h_def, is_dram) /
82410234Syasuko.eckert@amd.com         Htagbits);//since each halve only has one precharge tx per matchline
82510152Satgutier@umich.edu
82610234Syasuko.eckert@amd.com    Cwire = c_matchline_metal * Htagbits;
82710234Syasuko.eckert@amd.com    Rwire = r_matchline_metal * Htagbits;
82810234Syasuko.eckert@amd.com    c_gate_load = gate_C(Waddrnandn + Waddrnandp, 0, is_dram);
82910152Satgutier@umich.edu
83010234Syasuko.eckert@amd.com    double R_ml_precharge = tr_R_on(Wfaprechp, PCH, 1, is_dram);
83110234Syasuko.eckert@amd.com    //double r_ml_metal = cam_cell.w * g_tp.wire_local.R_per_um;
83210234Syasuko.eckert@amd.com    double R_ml = Rwire;
83310234Syasuko.eckert@amd.com    double C_ml = Cwire + c_intrinsic;
83410234Syasuko.eckert@amd.com    //TODO: latest CAM has sense amps on matchlines too
83510234Syasuko.eckert@amd.com    delay_cam_ml_reset = ml_precharge_drv->delay
83610234Syasuko.eckert@amd.com        + log(g_tp.cam.Vbitpre) * (R_ml_precharge * C_ml + R_ml * C_ml / 2);
83710152Satgutier@umich.edu
83810234Syasuko.eckert@amd.com    //matchline ops delay
83910234Syasuko.eckert@amd.com    tf = rd * (c_intrinsic + Cwire / 2 + c_gate_load) + Rwire * (Cwire / 2 + c_gate_load);
84010234Syasuko.eckert@amd.com    this_delay = horowitz(out_time_ramp, tf, VTHFA2, VTHFA3, FALL);
84110234Syasuko.eckert@amd.com    delay_matchchline += this_delay;
84210234Syasuko.eckert@amd.com    out_time_ramp = this_delay / VTHFA3;
84310152Satgutier@umich.edu
84410234Syasuko.eckert@amd.com    dynSearchEng += ((c_intrinsic + Cwire + c_gate_load) *
84510234Syasuko.eckert@amd.com                     (subarray.num_rows + 1)) //TODO: need to be precise
84610234Syasuko.eckert@amd.com        * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd *
84710234Syasuko.eckert@amd.com        2;//each subarry has two halves
84810152Satgutier@umich.edu
84910234Syasuko.eckert@amd.com    /* third stage, from the NAND2 gates to the drivers in the dummy row */
85010234Syasuko.eckert@amd.com    rd = tr_R_on(Waddrnandn, NCH, 2, is_dram);
85110234Syasuko.eckert@amd.com    c_intrinsic = drain_C_(Waddrnandn, NCH, 2, 1, g_tp.cell_h_def, is_dram) +
85210234Syasuko.eckert@amd.com                  drain_C_(Waddrnandp, PCH, 1, 1, g_tp.cell_h_def, is_dram) * 2;
85310234Syasuko.eckert@amd.com    c_gate_load = gate_C(Wdummyinvn + Wdummyinvp, 0, is_dram);
85410234Syasuko.eckert@amd.com    tf = rd * (c_intrinsic + c_gate_load);
85510234Syasuko.eckert@amd.com    this_delay = horowitz(out_time_ramp, tf, VTHFA3, VTHFA4, RISE);
85610234Syasuko.eckert@amd.com    out_time_ramp = this_delay / (1 - VTHFA4);
85710234Syasuko.eckert@amd.com    delay_matchchline += this_delay;
85810152Satgutier@umich.edu
85910234Syasuko.eckert@amd.com    //only the dummy row has the extra inverter between NAND and NOR gates
86010234Syasuko.eckert@amd.com    dynSearchEng += (c_intrinsic * (subarray.num_rows + 1) + c_gate_load * 2) *
86110234Syasuko.eckert@amd.com        g_tp.peri_global.Vdd * g_tp.peri_global.Vdd;//  * Ntbl;
86210152Satgutier@umich.edu
86310234Syasuko.eckert@amd.com    /* fourth stage, from the driver in dummy matchline to the NOR2 gate which drives the wordline of the data portion */
86410234Syasuko.eckert@amd.com    rd = tr_R_on(Wdummyinvn, NCH, 1, is_dram);
86510234Syasuko.eckert@amd.com    c_intrinsic = drain_C_(Wdummyinvn, NCH, 1, 1, g_tp.cell_h_def, is_dram) + drain_C_(Wdummyinvp, NCH, 1, 1, g_tp.cell_h_def, is_dram);
86610234Syasuko.eckert@amd.com    Cwire = c_matchline_metal * Htagbits +  c_searchline_metal *
86710234Syasuko.eckert@amd.com        (subarray.num_rows + 1) / 2;
86810234Syasuko.eckert@amd.com    Rwire = r_matchline_metal * Htagbits +  r_searchline_metal *
86910234Syasuko.eckert@amd.com        (subarray.num_rows + 1) / 2;
87010234Syasuko.eckert@amd.com    c_gate_load = gate_C(Wfanorn + Wfanorp, 0, is_dram);
87110234Syasuko.eckert@amd.com    tf = rd * (c_intrinsic + Cwire + c_gate_load) + Rwire * (Cwire / 2 + c_gate_load);
87210234Syasuko.eckert@amd.com    this_delay = horowitz (out_time_ramp, tf, VTHFA4, VTHFA5, FALL);
87310234Syasuko.eckert@amd.com    out_time_ramp = this_delay / VTHFA5;
87410234Syasuko.eckert@amd.com    delay_matchchline += this_delay;
87510152Satgutier@umich.edu
87610234Syasuko.eckert@amd.com    dynSearchEng += (c_intrinsic + Cwire + subarray.num_rows * c_gate_load) *
87710234Syasuko.eckert@amd.com        g_tp.peri_global.Vdd * g_tp.peri_global.Vdd;//* Ntbl;
87810152Satgutier@umich.edu
87910234Syasuko.eckert@amd.com    /*final statge from the NOR gate to drive the wordline of the data portion */
88010152Satgutier@umich.edu
88110234Syasuko.eckert@amd.com    //searchline data driver There are two matchline precharge driver chains per subarray.
88210234Syasuko.eckert@amd.com    driver_c_gate_load = gate_C(W_hit_miss_n, 0, is_dram, false, false);//nmos of the pull down logic
88310234Syasuko.eckert@amd.com    driver_c_wire_load = subarray.C_wl_ram;
88410234Syasuko.eckert@amd.com    driver_r_wire_load = subarray.R_wl_ram;
88510152Satgutier@umich.edu
88610234Syasuko.eckert@amd.com    ml_to_ram_wl_drv = new Driver(
88710234Syasuko.eckert@amd.com        driver_c_gate_load,
88810234Syasuko.eckert@amd.com        driver_c_wire_load,
88910234Syasuko.eckert@amd.com        driver_r_wire_load,
89010234Syasuko.eckert@amd.com        is_dram);
89110152Satgutier@umich.edu
89210152Satgutier@umich.edu
89310152Satgutier@umich.edu
89410234Syasuko.eckert@amd.com    rd = tr_R_on(Wfanorn, NCH, 1, is_dram);
89510234Syasuko.eckert@amd.com    c_intrinsic = 2 * drain_C_(Wfanorn, NCH, 1, 1, g_tp.cell_h_def, is_dram) +
89610234Syasuko.eckert@amd.com        drain_C_(Wfanorp, NCH, 1, 1, g_tp.cell_h_def, is_dram);
89710234Syasuko.eckert@amd.com    c_gate_load = gate_C(ml_to_ram_wl_drv->width_n[0] + ml_to_ram_wl_drv->width_p[0], 0, is_dram);
89810234Syasuko.eckert@amd.com    tf = rd * (c_intrinsic + c_gate_load);
89910234Syasuko.eckert@amd.com    this_delay = horowitz (out_time_ramp, tf, 0.5, 0.5, RISE);
90010234Syasuko.eckert@amd.com    out_time_ramp = this_delay / (1 - 0.5);
90110234Syasuko.eckert@amd.com    delay_matchchline += this_delay;
90210152Satgutier@umich.edu
90310234Syasuko.eckert@amd.com    out_time_ramp   = ml_to_ram_wl_drv->compute_delay(out_time_ramp);
90410152Satgutier@umich.edu
90510234Syasuko.eckert@amd.com    //c_gate_load energy is computed in ml_to_ram_wl_drv
90610234Syasuko.eckert@amd.com    dynSearchEng  += (c_intrinsic) * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd;//* Ntbl;
90710152Satgutier@umich.edu
90810152Satgutier@umich.edu
90910234Syasuko.eckert@amd.com    /* peripheral-- hitting logic "CMOS VLSI Design Fig11.51*/
91010234Syasuko.eckert@amd.com    /*Precharge the hitting logic */
91110234Syasuko.eckert@amd.com    c_intrinsic = 2 *
91210234Syasuko.eckert@amd.com        drain_C_(W_hit_miss_p, NCH, 2, 1, g_tp.cell_h_def, is_dram);
91310234Syasuko.eckert@amd.com    Cwire = c_searchline_metal * subarray.num_rows;
91410234Syasuko.eckert@amd.com    Rwire = r_searchline_metal * subarray.num_rows;
91510234Syasuko.eckert@amd.com    c_gate_load = drain_C_(W_hit_miss_n, NCH, 1, 1, g_tp.cell_h_def, is_dram) *
91610234Syasuko.eckert@amd.com        subarray.num_rows;
91710152Satgutier@umich.edu
91810234Syasuko.eckert@amd.com    rd = tr_R_on(W_hit_miss_p, PCH, 1, is_dram, false, false);
91910234Syasuko.eckert@amd.com    //double r_ml_metal = cam_cell.w * g_tp.wire_local.R_per_um;
92010234Syasuko.eckert@amd.com    double R_hit_miss = Rwire;
92110234Syasuko.eckert@amd.com    double C_hit_miss = Cwire + c_intrinsic;
92210234Syasuko.eckert@amd.com    delay_hit_miss_reset = log(g_tp.cam.Vbitpre) *
92310234Syasuko.eckert@amd.com        (rd * C_hit_miss + R_hit_miss * C_hit_miss / 2);
92410234Syasuko.eckert@amd.com    dynSearchEng  += (c_intrinsic + Cwire + c_gate_load) * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd;
92510152Satgutier@umich.edu
92610234Syasuko.eckert@amd.com    /*hitting logic evaluation */
92710234Syasuko.eckert@amd.com    c_intrinsic = 2 *
92810234Syasuko.eckert@amd.com        drain_C_(W_hit_miss_n, NCH, 2, 1, g_tp.cell_h_def, is_dram);
92910234Syasuko.eckert@amd.com    Cwire = c_searchline_metal * subarray.num_rows;
93010234Syasuko.eckert@amd.com    Rwire = r_searchline_metal * subarray.num_rows;
93110234Syasuko.eckert@amd.com    c_gate_load = drain_C_(W_hit_miss_n, NCH, 1, 1, g_tp.cell_h_def, is_dram) *
93210234Syasuko.eckert@amd.com        subarray.num_rows;
93310152Satgutier@umich.edu
93410234Syasuko.eckert@amd.com    rd = tr_R_on(W_hit_miss_n, PCH, 1, is_dram, false, false);
93510234Syasuko.eckert@amd.com    tf = rd * (c_intrinsic + Cwire / 2 + c_gate_load) + Rwire * (Cwire / 2 + c_gate_load);
93610152Satgutier@umich.edu
93710234Syasuko.eckert@amd.com    delay_hit_miss = horowitz(0, tf, 0.5, 0.5, FALL);
93810152Satgutier@umich.edu
93910234Syasuko.eckert@amd.com    if (is_fa)
94010234Syasuko.eckert@amd.com        delay_matchchline += MAX(ml_to_ram_wl_drv->delay, delay_hit_miss);
94110152Satgutier@umich.edu
94210234Syasuko.eckert@amd.com    dynSearchEng  += (c_intrinsic + Cwire + c_gate_load) * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd;
94310152Satgutier@umich.edu
94410234Syasuko.eckert@amd.com    /* TODO: peripheral-- Priority Encoder, usually this is not necessary in processor components*/
94510152Satgutier@umich.edu
94610234Syasuko.eckert@amd.com    power_matchline.searchOp.dynamic = dynSearchEng;
94710152Satgutier@umich.edu
94810234Syasuko.eckert@amd.com    //leakage in one subarray
94910234Syasuko.eckert@amd.com    double Iport     = cmos_Isub_leakage(g_tp.cam.cell_a_w, 0,  1, nmos, false, true);//TODO: how much is the idle time? just by *2?
95010234Syasuko.eckert@amd.com    double Iport_erp = cmos_Isub_leakage(g_tp.cam.cell_a_w, 0,  2, nmos, false, true);
95110234Syasuko.eckert@amd.com    double Icell = cmos_Isub_leakage(g_tp.cam.cell_nmos_w, g_tp.cam.cell_pmos_w,
95210234Syasuko.eckert@amd.com                                     1, inv, false, true) * 2;
95310234Syasuko.eckert@amd.com    //approx XOR with Inv
95410234Syasuko.eckert@amd.com    double Icell_comparator = cmos_Isub_leakage(Wdummyn, Wdummyn, 1, inv,
95510234Syasuko.eckert@amd.com                                                false, true) * 2;
95610152Satgutier@umich.edu
95710234Syasuko.eckert@amd.com    leak_power_cc_inverters_sram_cell         = Icell * g_tp.cam_cell.Vdd;
95810234Syasuko.eckert@amd.com    leak_comparator_cam_cell                  = Icell_comparator * g_tp.cam_cell.Vdd;
95910234Syasuko.eckert@amd.com    leak_power_acc_tr_RW_or_WR_port_sram_cell = Iport * g_tp.cam_cell.Vdd;
96010234Syasuko.eckert@amd.com    leak_power_RD_port_sram_cell              = Iport_erp * g_tp.cam_cell.Vdd;
96110234Syasuko.eckert@amd.com    leak_power_SCHP_port_sram_cell            = 0;//search port and r/w port are sperate, therefore no access txs in search ports
96210152Satgutier@umich.edu
96310234Syasuko.eckert@amd.com    power_matchline.searchOp.leakage += leak_power_cc_inverters_sram_cell +
96410234Syasuko.eckert@amd.com                                        leak_comparator_cam_cell +
96510234Syasuko.eckert@amd.com                                        leak_power_acc_tr_RW_or_WR_port_sram_cell +
96610234Syasuko.eckert@amd.com                                        leak_power_acc_tr_RW_or_WR_port_sram_cell * (RWP + EWP - 1) +
96710234Syasuko.eckert@amd.com                                        leak_power_RD_port_sram_cell * ERP +
96810234Syasuko.eckert@amd.com                                        leak_power_SCHP_port_sram_cell * SCHP;
96910152Satgutier@umich.edu//  power_matchline.searchOp.leakage += leak_comparator_cam_cell;
97010234Syasuko.eckert@amd.com    power_matchline.searchOp.leakage *= (subarray.num_rows + 1) *
97110234Syasuko.eckert@amd.com        subarray.num_cols_fa_cam;//TODO:dumy line precise
97210234Syasuko.eckert@amd.com    power_matchline.searchOp.leakage += (subarray.num_rows + 1) *
97310234Syasuko.eckert@amd.com        cmos_Isub_leakage(0, Wfaprechp, 1, pmos) * g_tp.cam_cell.Vdd;
97410234Syasuko.eckert@amd.com    power_matchline.searchOp.leakage += (subarray.num_rows + 1) *
97510234Syasuko.eckert@amd.com        cmos_Isub_leakage(Waddrnandn, Waddrnandp, 2, nand) * g_tp.cam_cell.Vdd;
97610234Syasuko.eckert@amd.com    power_matchline.searchOp.leakage += (subarray.num_rows + 1) *
97710234Syasuko.eckert@amd.com        cmos_Isub_leakage(Wfanorn, Wfanorp, 2, nor) * g_tp.cam_cell.Vdd;
97810234Syasuko.eckert@amd.com    //In idle states, the hit/miss txs are closed (on) therefore no Isub
97910234Syasuko.eckert@amd.com    power_matchline.searchOp.leakage += 0;// subarray.num_rows * cmos_Isub_leakage(W_hit_miss_n, 0,1, nmos) * g_tp.cam_cell.Vdd+
98010152Satgutier@umich.edu    // + cmos_Isub_leakage(0, W_hit_miss_p,1, pmos) * g_tp.cam_cell.Vdd;
98110152Satgutier@umich.edu
98210234Syasuko.eckert@amd.com    //in idle state, Ig_on only possibly exist in access transistors of read only ports
98310234Syasuko.eckert@amd.com    double Ig_port_erp = cmos_Ig_leakage(g_tp.cam.cell_a_w, 0, 1, nmos, false, true);
98410234Syasuko.eckert@amd.com    double Ig_cell = cmos_Ig_leakage(g_tp.cam.cell_nmos_w, g_tp.cam.cell_pmos_w,
98510234Syasuko.eckert@amd.com                                     1, inv, false, true) * 2;
98610234Syasuko.eckert@amd.com    double Ig_cell_comparator = cmos_Ig_leakage(Wdummyn, Wdummyn, 1, inv,
98710234Syasuko.eckert@amd.com                                                false, true) * 2;
98810152Satgutier@umich.edu
98910234Syasuko.eckert@amd.com    gate_leak_comparator_cam_cell = Ig_cell_comparator * g_tp.cam_cell.Vdd;
99010234Syasuko.eckert@amd.com    gate_leak_power_cc_inverters_sram_cell = Ig_cell * g_tp.cam_cell.Vdd;
99110234Syasuko.eckert@amd.com    gate_leak_power_RD_port_sram_cell = Ig_port_erp * g_tp.sram_cell.Vdd;
99210234Syasuko.eckert@amd.com    gate_leak_power_SCHP_port_sram_cell = 0;
99310152Satgutier@umich.edu
99410234Syasuko.eckert@amd.com    //cout<<"power_matchline.searchOp.leakage"<<power_matchline.searchOp.leakage<<endl;
99510152Satgutier@umich.edu
99610234Syasuko.eckert@amd.com    power_matchline.searchOp.gate_leakage +=
99710234Syasuko.eckert@amd.com        gate_leak_power_cc_inverters_sram_cell;
99810234Syasuko.eckert@amd.com    power_matchline.searchOp.gate_leakage += gate_leak_comparator_cam_cell;
99910234Syasuko.eckert@amd.com    power_matchline.searchOp.gate_leakage +=
100010234Syasuko.eckert@amd.com        gate_leak_power_SCHP_port_sram_cell * SCHP +
100110234Syasuko.eckert@amd.com        gate_leak_power_RD_port_sram_cell * ERP;
100210234Syasuko.eckert@amd.com    power_matchline.searchOp.gate_leakage *= (subarray.num_rows + 1) *
100310234Syasuko.eckert@amd.com        subarray.num_cols_fa_cam;//TODO:dumy line precise
100410234Syasuko.eckert@amd.com    power_matchline.searchOp.gate_leakage += (subarray.num_rows + 1) *
100510234Syasuko.eckert@amd.com        cmos_Ig_leakage(0, Wfaprechp, 1, pmos) * g_tp.cam_cell.Vdd;
100610234Syasuko.eckert@amd.com    power_matchline.searchOp.gate_leakage += (subarray.num_rows + 1) *
100710234Syasuko.eckert@amd.com        cmos_Ig_leakage(Waddrnandn, Waddrnandp, 2, nand) * g_tp.cam_cell.Vdd;
100810234Syasuko.eckert@amd.com    power_matchline.searchOp.gate_leakage += (subarray.num_rows + 1) *
100910234Syasuko.eckert@amd.com        cmos_Ig_leakage(Wfanorn, Wfanorp, 2, nor) * g_tp.cam_cell.Vdd;
101010234Syasuko.eckert@amd.com    power_matchline.searchOp.gate_leakage += subarray.num_rows *
101110234Syasuko.eckert@amd.com        cmos_Ig_leakage(W_hit_miss_n, 0, 1, nmos) * g_tp.cam_cell.Vdd +
101210234Syasuko.eckert@amd.com        + cmos_Ig_leakage(0, W_hit_miss_p, 1, pmos) * g_tp.cam_cell.Vdd;
101310152Satgutier@umich.edu
101410152Satgutier@umich.edu
101510234Syasuko.eckert@amd.com    return out_time_ramp;
101610152Satgutier@umich.edu}
101710152Satgutier@umich.edu
101810152Satgutier@umich.edu
101910234Syasuko.eckert@amd.comdouble Mat::width_write_driver_or_write_mux() {
102010234Syasuko.eckert@amd.com    // calculate resistance of SRAM cell pull-up PMOS transistor
102110234Syasuko.eckert@amd.com    // cam and sram have same cell trasistor properties
102210234Syasuko.eckert@amd.com    double R_sram_cell_pull_up_tr  = tr_R_on(g_tp.sram.cell_pmos_w, NCH, 1, is_dram, true);
102310234Syasuko.eckert@amd.com    double R_access_tr             = tr_R_on(g_tp.sram.cell_a_w,    NCH, 1, is_dram, true);
102410234Syasuko.eckert@amd.com    double target_R_write_driver_and_mux = (2 * R_sram_cell_pull_up_tr - R_access_tr) / 2;
102510234Syasuko.eckert@amd.com    double width_write_driver_nmos = R_to_w(target_R_write_driver_and_mux, NCH, is_dram);
102610152Satgutier@umich.edu
102710234Syasuko.eckert@amd.com    return width_write_driver_nmos;
102810152Satgutier@umich.edu}
102910152Satgutier@umich.edu
103010152Satgutier@umich.edu
103110152Satgutier@umich.edu
103210152Satgutier@umich.edudouble Mat::compute_comparators_height(
103310152Satgutier@umich.edu    int tagbits,
103410152Satgutier@umich.edu    int number_ways_in_mat,
103510234Syasuko.eckert@amd.com    double subarray_mem_cell_area_width) {
103610234Syasuko.eckert@amd.com    double nand2_area = compute_gate_area(NAND, 2, 0, g_tp.w_comp_n, g_tp.cell_h_def);
103710234Syasuko.eckert@amd.com    double cumulative_area = nand2_area * number_ways_in_mat * tagbits / 4;
103810234Syasuko.eckert@amd.com    return cumulative_area / subarray_mem_cell_area_width;
103910152Satgutier@umich.edu}
104010152Satgutier@umich.edu
104110152Satgutier@umich.edu
104210152Satgutier@umich.edu
104310234Syasuko.eckert@amd.comdouble Mat::compute_bitline_delay(double inrisetime) {
104410234Syasuko.eckert@amd.com    double V_b_pre, v_th_mem_cell, V_wl;
104510234Syasuko.eckert@amd.com    double tstep;
104610234Syasuko.eckert@amd.com    double dynRdEnergy = 0.0, dynWriteEnergy = 0.0;
104710234Syasuko.eckert@amd.com    double R_cell_pull_down = 0.0, R_cell_acc = 0.0, r_dev = 0.0;
104810234Syasuko.eckert@amd.com    int deg_senseamp_muxing = dp.Ndsam_lev_1 * dp.Ndsam_lev_2;
104910152Satgutier@umich.edu
105010234Syasuko.eckert@amd.com    double R_b_metal = camFlag ? cam_cell.h : cell.h * g_tp.wire_local.R_per_um;
105110234Syasuko.eckert@amd.com    double R_bl      = subarray.num_rows * R_b_metal;
105210234Syasuko.eckert@amd.com    double C_bl      = subarray.C_bl;
105310152Satgutier@umich.edu
105410234Syasuko.eckert@amd.com    // TODO: no leakage for DRAMs?
105510234Syasuko.eckert@amd.com    double leak_power_cc_inverters_sram_cell = 0;
105610234Syasuko.eckert@amd.com    double gate_leak_power_cc_inverters_sram_cell = 0;
105710234Syasuko.eckert@amd.com    double leak_power_acc_tr_RW_or_WR_port_sram_cell = 0;
105810234Syasuko.eckert@amd.com    double leak_power_RD_port_sram_cell = 0;
105910234Syasuko.eckert@amd.com    double gate_leak_power_RD_port_sram_cell = 0;
106010152Satgutier@umich.edu
106110234Syasuko.eckert@amd.com    if (is_dram == true) {
106210234Syasuko.eckert@amd.com        V_b_pre = g_tp.dram.Vbitpre;
106310234Syasuko.eckert@amd.com        v_th_mem_cell = g_tp.dram_acc.Vth;
106410234Syasuko.eckert@amd.com        V_wl = g_tp.vpp;
106510234Syasuko.eckert@amd.com        //The access transistor is not folded. So we just need to specify a
106610234Syasuko.eckert@amd.com        // threshold value for the folding width that is equal to or greater
106710234Syasuko.eckert@amd.com        // than Wmemcella.
106810234Syasuko.eckert@amd.com        R_cell_acc = tr_R_on(g_tp.dram.cell_a_w, NCH, 1, true, true);
106910234Syasuko.eckert@amd.com        r_dev = g_tp.dram_cell_Vdd / g_tp.dram_cell_I_on + R_bl / 2;
107010234Syasuko.eckert@amd.com    } else { //SRAM
107110234Syasuko.eckert@amd.com        V_b_pre = g_tp.sram.Vbitpre;
107210234Syasuko.eckert@amd.com        v_th_mem_cell = g_tp.sram_cell.Vth;
107310234Syasuko.eckert@amd.com        V_wl = g_tp.sram_cell.Vdd;
107410234Syasuko.eckert@amd.com        R_cell_pull_down = tr_R_on(g_tp.sram.cell_nmos_w, NCH, 1, false, true);
107510234Syasuko.eckert@amd.com        R_cell_acc = tr_R_on(g_tp.sram.cell_a_w, NCH, 1, false, true);
107610152Satgutier@umich.edu
107710234Syasuko.eckert@amd.com        //Leakage current of an SRAM cell
107810234Syasuko.eckert@amd.com        //TODO: how much is the idle time? just by *2?
107910234Syasuko.eckert@amd.com        double Iport = cmos_Isub_leakage(g_tp.sram.cell_a_w, 0,  1, nmos,
108010234Syasuko.eckert@amd.com                                         false, true);
108110234Syasuko.eckert@amd.com        double Iport_erp = cmos_Isub_leakage(g_tp.sram.cell_a_w, 0,  2, nmos,
108210234Syasuko.eckert@amd.com                                             false, true);
108310234Syasuko.eckert@amd.com        double Icell = cmos_Isub_leakage(g_tp.sram.cell_nmos_w,
108410234Syasuko.eckert@amd.com                                         g_tp.sram.cell_pmos_w, 1, inv, false,
108510234Syasuko.eckert@amd.com                                         true) * 2;//two invs per cell
108610152Satgutier@umich.edu
108710234Syasuko.eckert@amd.com        leak_power_cc_inverters_sram_cell         = Icell * g_tp.sram_cell.Vdd;
108810234Syasuko.eckert@amd.com        leak_power_acc_tr_RW_or_WR_port_sram_cell = Iport * g_tp.sram_cell.Vdd;
108910234Syasuko.eckert@amd.com        leak_power_RD_port_sram_cell              = Iport_erp * g_tp.sram_cell.Vdd;
109010152Satgutier@umich.edu
109110152Satgutier@umich.edu
109210234Syasuko.eckert@amd.com        //in idle state, Ig_on only possibly exist in access transistors of read only ports
109310234Syasuko.eckert@amd.com        double Ig_port_erp = cmos_Ig_leakage(g_tp.sram.cell_a_w, 0, 1, nmos,
109410234Syasuko.eckert@amd.com                                             false, true);
109510234Syasuko.eckert@amd.com        double Ig_cell = cmos_Ig_leakage(g_tp.sram.cell_nmos_w,
109610234Syasuko.eckert@amd.com                                         g_tp.sram.cell_pmos_w, 1, inv, false,
109710234Syasuko.eckert@amd.com                                         true);
109810152Satgutier@umich.edu
109910234Syasuko.eckert@amd.com        gate_leak_power_cc_inverters_sram_cell = Ig_cell * g_tp.sram_cell.Vdd;
110010234Syasuko.eckert@amd.com        gate_leak_power_RD_port_sram_cell = Ig_port_erp * g_tp.sram_cell.Vdd;
110110234Syasuko.eckert@amd.com    }
110210152Satgutier@umich.edu
110310152Satgutier@umich.edu
110410234Syasuko.eckert@amd.com    double C_drain_bit_mux = drain_C_(g_tp.w_nmos_b_mux, NCH, 1, 0,
110510234Syasuko.eckert@amd.com                                      camFlag ? cam_cell.w : cell.w /
110610234Syasuko.eckert@amd.com                                      (2 * (RWP + ERP + SCHP)), is_dram);
110710234Syasuko.eckert@amd.com    double R_bit_mux = tr_R_on(g_tp.w_nmos_b_mux, NCH, 1, is_dram);
110810234Syasuko.eckert@amd.com    double C_drain_sense_amp_iso = drain_C_(g_tp.w_iso, PCH, 1, 0,
110910234Syasuko.eckert@amd.com                                            camFlag ? cam_cell.w :
111010234Syasuko.eckert@amd.com                                            cell.w * deg_bl_muxing /
111110234Syasuko.eckert@amd.com                                            (RWP + ERP + SCHP), is_dram);
111210234Syasuko.eckert@amd.com    double R_sense_amp_iso = tr_R_on(g_tp.w_iso, PCH, 1, is_dram);
111310234Syasuko.eckert@amd.com    double C_sense_amp_latch = gate_C(g_tp.w_sense_p + g_tp.w_sense_n, 0,
111410234Syasuko.eckert@amd.com                                      is_dram) +
111510234Syasuko.eckert@amd.com        drain_C_(g_tp.w_sense_n, NCH, 1, 0, camFlag ? cam_cell.w :
111610234Syasuko.eckert@amd.com                 cell.w * deg_bl_muxing / (RWP + ERP + SCHP), is_dram) +
111710234Syasuko.eckert@amd.com        drain_C_(g_tp.w_sense_p, PCH, 1, 0, camFlag ? cam_cell.w :
111810234Syasuko.eckert@amd.com                 cell.w * deg_bl_muxing / (RWP + ERP + SCHP), is_dram);
111910234Syasuko.eckert@amd.com    double C_drain_sense_amp_mux = drain_C_(g_tp.w_nmos_sa_mux, NCH, 1, 0,
112010234Syasuko.eckert@amd.com                                            camFlag ? cam_cell.w :
112110234Syasuko.eckert@amd.com                                            cell.w * deg_bl_muxing /
112210234Syasuko.eckert@amd.com                                            (RWP + ERP + SCHP), is_dram);
112310152Satgutier@umich.edu
112410234Syasuko.eckert@amd.com    if (is_dram) {
112510234Syasuko.eckert@amd.com        double fraction = dp.V_b_sense / ((g_tp.dram_cell_Vdd / 2) *
112610234Syasuko.eckert@amd.com                                          g_tp.dram_cell_C /
112710234Syasuko.eckert@amd.com                                          (g_tp.dram_cell_C + C_bl));
112810234Syasuko.eckert@amd.com        tstep = 2.3 * fraction * r_dev *
112910234Syasuko.eckert@amd.com            (g_tp.dram_cell_C * (C_bl + 2 * C_drain_sense_amp_iso +
113010234Syasuko.eckert@amd.com                                 C_sense_amp_latch + C_drain_sense_amp_mux)) /
113110234Syasuko.eckert@amd.com            (g_tp.dram_cell_C + (C_bl + 2 * C_drain_sense_amp_iso +
113210234Syasuko.eckert@amd.com                                 C_sense_amp_latch + C_drain_sense_amp_mux));
113310234Syasuko.eckert@amd.com        delay_writeback = tstep;
113410234Syasuko.eckert@amd.com        dynRdEnergy += (C_bl + 2 * C_drain_sense_amp_iso + C_sense_amp_latch +
113510234Syasuko.eckert@amd.com                        C_drain_sense_amp_mux) *
113610234Syasuko.eckert@amd.com            (g_tp.dram_cell_Vdd / 2) *
113710234Syasuko.eckert@amd.com            g_tp.dram_cell_Vdd /* subarray.num_cols * num_subarrays_per_mat*/;
113810234Syasuko.eckert@amd.com        dynWriteEnergy += (C_bl + 2 * C_drain_sense_amp_iso + C_sense_amp_latch) *
113910234Syasuko.eckert@amd.com            (g_tp.dram_cell_Vdd / 2) *
114010234Syasuko.eckert@amd.com            g_tp.dram_cell_Vdd /* subarray.num_cols * num_subarrays_per_mat*/ *
114110234Syasuko.eckert@amd.com            num_act_mats_hor_dir * 100;
114210234Syasuko.eckert@amd.com        per_bitline_read_energy = (C_bl + 2 * C_drain_sense_amp_iso +
114310234Syasuko.eckert@amd.com                                   C_sense_amp_latch + C_drain_sense_amp_mux) *
114410234Syasuko.eckert@amd.com            (g_tp.dram_cell_Vdd / 2) * g_tp.dram_cell_Vdd;
114510234Syasuko.eckert@amd.com    } else {
114610234Syasuko.eckert@amd.com        double tau;
114710152Satgutier@umich.edu
114810234Syasuko.eckert@amd.com        if (deg_bl_muxing > 1) {
114910234Syasuko.eckert@amd.com            tau = (R_cell_pull_down + R_cell_acc) *
115010234Syasuko.eckert@amd.com                (C_bl + 2 * C_drain_bit_mux + 2 * C_drain_sense_amp_iso +
115110234Syasuko.eckert@amd.com                 C_sense_amp_latch + C_drain_sense_amp_mux) +
115210234Syasuko.eckert@amd.com                R_bl * (C_bl / 2 + 2 * C_drain_bit_mux + 2 *
115310234Syasuko.eckert@amd.com                        C_drain_sense_amp_iso + C_sense_amp_latch +
115410234Syasuko.eckert@amd.com                        C_drain_sense_amp_mux) +
115510234Syasuko.eckert@amd.com                R_bit_mux * (C_drain_bit_mux + 2 * C_drain_sense_amp_iso +
115610234Syasuko.eckert@amd.com                             C_sense_amp_latch + C_drain_sense_amp_mux) +
115710234Syasuko.eckert@amd.com                R_sense_amp_iso * (C_drain_sense_amp_iso + C_sense_amp_latch +
115810234Syasuko.eckert@amd.com                                   C_drain_sense_amp_mux);
115910234Syasuko.eckert@amd.com            dynRdEnergy += (C_bl + 2 * C_drain_bit_mux) * 2 * dp.V_b_sense *
116010234Syasuko.eckert@amd.com                g_tp.sram_cell.Vdd;
116110234Syasuko.eckert@amd.com            dynRdEnergy += (2 * C_drain_sense_amp_iso + C_sense_amp_latch +
116210234Syasuko.eckert@amd.com                            C_drain_sense_amp_mux) *
116310234Syasuko.eckert@amd.com                2 * dp.V_b_sense * g_tp.sram_cell.Vdd *
116410234Syasuko.eckert@amd.com                (1.0/*subarray.num_cols * num_subarrays_per_mat*/ /
116510234Syasuko.eckert@amd.com                 deg_bl_muxing);
116610234Syasuko.eckert@amd.com            dynWriteEnergy += ((1.0/*subarray.num_cols *num_subarrays_per_mat*/ /
116710234Syasuko.eckert@amd.com                                deg_bl_muxing) / deg_senseamp_muxing) *
116810234Syasuko.eckert@amd.com                num_act_mats_hor_dir * (C_bl + 2 * C_drain_bit_mux) *
116910234Syasuko.eckert@amd.com                g_tp.sram_cell.Vdd * g_tp.sram_cell.Vdd * 2;
117010234Syasuko.eckert@amd.com            //Write Ops are differential for SRAM
117110234Syasuko.eckert@amd.com        } else {
117210234Syasuko.eckert@amd.com            tau = (R_cell_pull_down + R_cell_acc) *
117310234Syasuko.eckert@amd.com                  (C_bl + C_drain_sense_amp_iso + C_sense_amp_latch + C_drain_sense_amp_mux) + R_bl * C_bl / 2 +
117410234Syasuko.eckert@amd.com                  R_sense_amp_iso * (C_drain_sense_amp_iso + C_sense_amp_latch + C_drain_sense_amp_mux);
117510234Syasuko.eckert@amd.com            dynRdEnergy += (C_bl + 2 * C_drain_sense_amp_iso + C_sense_amp_latch + C_drain_sense_amp_mux) *
117610234Syasuko.eckert@amd.com                           2 * dp.V_b_sense * g_tp.sram_cell.Vdd /* subarray.num_cols * num_subarrays_per_mat*/;
117710234Syasuko.eckert@amd.com            dynWriteEnergy += (((1.0/*subarray.num_cols * num_subarrays_per_mat*/ /
117810234Syasuko.eckert@amd.com                                 deg_bl_muxing) / deg_senseamp_muxing) *
117910234Syasuko.eckert@amd.com                               num_act_mats_hor_dir * C_bl) *
118010234Syasuko.eckert@amd.com                g_tp.sram_cell.Vdd * g_tp.sram_cell.Vdd * 2;
118110234Syasuko.eckert@amd.com
118210234Syasuko.eckert@amd.com        }
118310234Syasuko.eckert@amd.com        tstep = tau * log(V_b_pre / (V_b_pre - dp.V_b_sense));
118410234Syasuko.eckert@amd.com        power_bitline.readOp.leakage =
118510234Syasuko.eckert@amd.com            leak_power_cc_inverters_sram_cell +
118610234Syasuko.eckert@amd.com            leak_power_acc_tr_RW_or_WR_port_sram_cell +
118710234Syasuko.eckert@amd.com            leak_power_acc_tr_RW_or_WR_port_sram_cell * (RWP + EWP - 1) +
118810234Syasuko.eckert@amd.com            leak_power_RD_port_sram_cell * ERP;
118910234Syasuko.eckert@amd.com        power_bitline.readOp.gate_leakage = gate_leak_power_cc_inverters_sram_cell +
119010234Syasuko.eckert@amd.com                                            gate_leak_power_RD_port_sram_cell * ERP;
119110152Satgutier@umich.edu
119210152Satgutier@umich.edu    }
119310152Satgutier@umich.edu
119410152Satgutier@umich.edu//  cout<<"leak_power_cc_inverters_sram_cell"<<leak_power_cc_inverters_sram_cell<<endl;
119510152Satgutier@umich.edu//  cout<<"leak_power_acc_tr_RW_or_WR_port_sram_cell"<<leak_power_acc_tr_RW_or_WR_port_sram_cell<<endl;
119610152Satgutier@umich.edu//  cout<<"leak_power_acc_tr_RW_or_WR_port_sram_cell"<<leak_power_acc_tr_RW_or_WR_port_sram_cell<<endl;
119710152Satgutier@umich.edu//  cout<<"leak_power_RD_port_sram_cell"<<leak_power_RD_port_sram_cell<<endl;
119810152Satgutier@umich.edu
119910152Satgutier@umich.edu
120010234Syasuko.eckert@amd.com    /* take input rise time into account */
120110234Syasuko.eckert@amd.com    double m = V_wl / inrisetime;
120210234Syasuko.eckert@amd.com    if (tstep <= (0.5 * (V_wl - v_th_mem_cell) / m)) {
120310234Syasuko.eckert@amd.com        delay_bitline = sqrt(2 * tstep * (V_wl - v_th_mem_cell) / m);
120410234Syasuko.eckert@amd.com    } else {
120510234Syasuko.eckert@amd.com        delay_bitline = tstep + (V_wl - v_th_mem_cell) / (2 * m);
120610234Syasuko.eckert@amd.com    }
120710152Satgutier@umich.edu
120810234Syasuko.eckert@amd.com    bool is_fa = (dp.fully_assoc) ? true : false;
120910152Satgutier@umich.edu
121010234Syasuko.eckert@amd.com    if (dp.is_tag == false || is_fa == false) {
121110234Syasuko.eckert@amd.com        power_bitline.readOp.dynamic  = dynRdEnergy;
121210234Syasuko.eckert@amd.com        power_bitline.writeOp.dynamic = dynWriteEnergy;
121310234Syasuko.eckert@amd.com    }
121410152Satgutier@umich.edu
121510234Syasuko.eckert@amd.com    double outrisetime = 0;
121610234Syasuko.eckert@amd.com    return outrisetime;
121710152Satgutier@umich.edu}
121810152Satgutier@umich.edu
121910152Satgutier@umich.edu
122010152Satgutier@umich.edu
122110234Syasuko.eckert@amd.comdouble Mat::compute_sa_delay(double inrisetime) {
122210234Syasuko.eckert@amd.com    //int num_sa_subarray = subarray.num_cols / deg_bl_muxing; //in a subarray
122310152Satgutier@umich.edu
122410234Syasuko.eckert@amd.com    //Bitline circuitry leakage.
122510234Syasuko.eckert@amd.com    double Iiso     = simplified_pmos_leakage(g_tp.w_iso, is_dram);
122610234Syasuko.eckert@amd.com    double IsenseEn = simplified_nmos_leakage(g_tp.w_sense_en, is_dram);
122710234Syasuko.eckert@amd.com    double IsenseN  = simplified_nmos_leakage(g_tp.w_sense_n, is_dram);
122810234Syasuko.eckert@amd.com    double IsenseP  = simplified_pmos_leakage(g_tp.w_sense_p, is_dram);
122910152Satgutier@umich.edu
123010234Syasuko.eckert@amd.com    double lkgIdlePh  = IsenseEn;//+ 2*IoBufP;
123110234Syasuko.eckert@amd.com    //double lkgWritePh = Iiso + IsenseEn;// + 2*IoBufP + 2*Ipch;
123210234Syasuko.eckert@amd.com    double lkgReadPh  = Iiso + IsenseN + IsenseP;//+ IoBufN + IoBufP + 2*IsPch ;
123310234Syasuko.eckert@amd.com    //double lkgRead = lkgReadPh * num_sa_subarray * 4 * num_act_mats_hor_dir +
123410234Syasuko.eckert@amd.com    //    lkgIdlePh * num_sa_subarray * 4 * (num_mats - num_act_mats_hor_dir);
123510234Syasuko.eckert@amd.com    double lkgIdle = lkgIdlePh /*num_sa_subarray * num_subarrays_per_mat*/;
123610234Syasuko.eckert@amd.com    leak_power_sense_amps_closed_page_state = lkgIdlePh * g_tp.peri_global.Vdd /* num_sa_subarray * num_subarrays_per_mat*/;
123710234Syasuko.eckert@amd.com    leak_power_sense_amps_open_page_state   = lkgReadPh * g_tp.peri_global.Vdd /* num_sa_subarray * num_subarrays_per_mat*/;
123810152Satgutier@umich.edu
123910234Syasuko.eckert@amd.com    // sense amplifier has to drive logic in "data out driver" and sense precharge load.
124010234Syasuko.eckert@amd.com    // load seen by sense amp. New delay model for sense amp that is sensitive to both the output time
124110234Syasuko.eckert@amd.com    //constant as well as the magnitude of input differential voltage.
124210234Syasuko.eckert@amd.com    double C_ld = gate_C(g_tp.w_sense_p + g_tp.w_sense_n, 0, is_dram) +
124310234Syasuko.eckert@amd.com        drain_C_(g_tp.w_sense_n, NCH, 1, 0,
124410234Syasuko.eckert@amd.com                 camFlag ? cam_cell.w : cell.w * deg_bl_muxing /
124510234Syasuko.eckert@amd.com                 (RWP + ERP + SCHP), is_dram) +
124610234Syasuko.eckert@amd.com        drain_C_(g_tp.w_sense_p, PCH, 1, 0, camFlag ?
124710234Syasuko.eckert@amd.com                 cam_cell.w : cell.w * deg_bl_muxing / (RWP + ERP + SCHP),
124810234Syasuko.eckert@amd.com                 is_dram) +
124910234Syasuko.eckert@amd.com        drain_C_(g_tp.w_iso, PCH, 1, 0, camFlag ?
125010234Syasuko.eckert@amd.com                 cam_cell.w : cell.w * deg_bl_muxing / (RWP + ERP + SCHP),
125110234Syasuko.eckert@amd.com                 is_dram) +
125210234Syasuko.eckert@amd.com        drain_C_(g_tp.w_nmos_sa_mux, NCH, 1, 0, camFlag ?
125310234Syasuko.eckert@amd.com                 cam_cell.w : cell.w * deg_bl_muxing / (RWP + ERP + SCHP),
125410234Syasuko.eckert@amd.com                 is_dram);
125510234Syasuko.eckert@amd.com    double tau = C_ld / g_tp.gm_sense_amp_latch;
125610234Syasuko.eckert@amd.com    delay_sa = tau * log(g_tp.peri_global.Vdd / dp.V_b_sense);
125710234Syasuko.eckert@amd.com    power_sa.readOp.dynamic = C_ld * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd /* num_sa_subarray
125810152Satgutier@umich.edu                            num_subarrays_per_mat * num_act_mats_hor_dir*/;
125910234Syasuko.eckert@amd.com    power_sa.readOp.leakage = lkgIdle * g_tp.peri_global.Vdd;
126010152Satgutier@umich.edu
126110234Syasuko.eckert@amd.com    double outrisetime = 0;
126210234Syasuko.eckert@amd.com    return outrisetime;
126310152Satgutier@umich.edu}
126410152Satgutier@umich.edu
126510152Satgutier@umich.edu
126610152Satgutier@umich.edu
126710234Syasuko.eckert@amd.comdouble Mat::compute_subarray_out_drv(double inrisetime) {
126810234Syasuko.eckert@amd.com    double C_ld, rd, tf, this_delay;
126910234Syasuko.eckert@amd.com    double p_to_n_sz_r = pmos_to_nmos_sz_ratio(is_dram);
127010152Satgutier@umich.edu
127110234Syasuko.eckert@amd.com    // delay of signal through pass-transistor of first level of sense-amp mux to input of inverter-buffer.
127210234Syasuko.eckert@amd.com    rd = tr_R_on(g_tp.w_nmos_sa_mux, NCH, 1, is_dram);
127310234Syasuko.eckert@amd.com    C_ld = dp.Ndsam_lev_1 * drain_C_(g_tp.w_nmos_sa_mux, NCH, 1, 0,
127410234Syasuko.eckert@amd.com                                     camFlag ? cam_cell.w : cell.w *
127510234Syasuko.eckert@amd.com                                     deg_bl_muxing / (RWP + ERP + SCHP),
127610234Syasuko.eckert@amd.com                                     is_dram) +
127710234Syasuko.eckert@amd.com        gate_C(g_tp.min_w_nmos_ + p_to_n_sz_r * g_tp.min_w_nmos_, 0.0, is_dram);
127810234Syasuko.eckert@amd.com    tf = rd * C_ld;
127910234Syasuko.eckert@amd.com    this_delay = horowitz(inrisetime, tf, 0.5, 0.5, RISE);
128010234Syasuko.eckert@amd.com    delay_subarray_out_drv += this_delay;
128110234Syasuko.eckert@amd.com    inrisetime = this_delay / (1.0 - 0.5);
128210234Syasuko.eckert@amd.com    power_subarray_out_drv.readOp.dynamic += C_ld * 0.5 * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd;
128310234Syasuko.eckert@amd.com    power_subarray_out_drv.readOp.leakage += 0;  // for now, let leakage of the pass transistor be 0
128410234Syasuko.eckert@amd.com    power_subarray_out_drv.readOp.gate_leakage +=
128510234Syasuko.eckert@amd.com        cmos_Ig_leakage(g_tp.w_nmos_sa_mux, 0, 1, nmos) * g_tp.peri_global.Vdd;
128610234Syasuko.eckert@amd.com    // delay of signal through inverter-buffer to second level of sense-amp mux.
128710234Syasuko.eckert@amd.com    // internal delay of buffer
128810234Syasuko.eckert@amd.com    rd = tr_R_on(g_tp.min_w_nmos_, NCH, 1, is_dram);
128910234Syasuko.eckert@amd.com    C_ld = drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def, is_dram) +
129010234Syasuko.eckert@amd.com           drain_C_(p_to_n_sz_r * g_tp.min_w_nmos_, PCH, 1, 1, g_tp.cell_h_def, is_dram) +
129110234Syasuko.eckert@amd.com           gate_C(g_tp.min_w_nmos_ + p_to_n_sz_r * g_tp.min_w_nmos_, 0.0, is_dram);
129210234Syasuko.eckert@amd.com    tf = rd * C_ld;
129310234Syasuko.eckert@amd.com    this_delay = horowitz(inrisetime, tf, 0.5, 0.5, RISE);
129410234Syasuko.eckert@amd.com    delay_subarray_out_drv += this_delay;
129510234Syasuko.eckert@amd.com    inrisetime = this_delay / (1.0 - 0.5);
129610234Syasuko.eckert@amd.com    power_subarray_out_drv.readOp.dynamic      += C_ld * 0.5 * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd;
129710234Syasuko.eckert@amd.com    power_subarray_out_drv.readOp.leakage +=
129810234Syasuko.eckert@amd.com        cmos_Isub_leakage(g_tp.min_w_nmos_, p_to_n_sz_r * g_tp.min_w_nmos_, 1,
129910234Syasuko.eckert@amd.com                          inv, is_dram) * g_tp.peri_global.Vdd;
130010234Syasuko.eckert@amd.com    power_subarray_out_drv.readOp.gate_leakage +=
130110234Syasuko.eckert@amd.com        cmos_Ig_leakage(g_tp.min_w_nmos_, p_to_n_sz_r * g_tp.min_w_nmos_, 1,
130210234Syasuko.eckert@amd.com                        inv) * g_tp.peri_global.Vdd;
130310152Satgutier@umich.edu
130410234Syasuko.eckert@amd.com    // inverter driving drain of pass transistor of second level of sense-amp mux.
130510234Syasuko.eckert@amd.com    rd = tr_R_on(g_tp.min_w_nmos_, NCH, 1, is_dram);
130610234Syasuko.eckert@amd.com    C_ld = drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def, is_dram) +
130710234Syasuko.eckert@amd.com        drain_C_(p_to_n_sz_r * g_tp.min_w_nmos_, PCH, 1, 1, g_tp.cell_h_def,
130810234Syasuko.eckert@amd.com                 is_dram) +
130910234Syasuko.eckert@amd.com        drain_C_(g_tp.w_nmos_sa_mux, NCH, 1, 0, camFlag ?
131010234Syasuko.eckert@amd.com                 cam_cell.w : cell.w * deg_bl_muxing * dp.Ndsam_lev_1 /
131110234Syasuko.eckert@amd.com                 (RWP + ERP + SCHP), is_dram);
131210234Syasuko.eckert@amd.com    tf = rd * C_ld;
131310234Syasuko.eckert@amd.com    this_delay = horowitz(inrisetime, tf, 0.5, 0.5, RISE);
131410234Syasuko.eckert@amd.com    delay_subarray_out_drv += this_delay;
131510234Syasuko.eckert@amd.com    inrisetime = this_delay / (1.0 - 0.5);
131610234Syasuko.eckert@amd.com    power_subarray_out_drv.readOp.dynamic      += C_ld * 0.5 * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd;
131710234Syasuko.eckert@amd.com    power_subarray_out_drv.readOp.leakage +=
131810234Syasuko.eckert@amd.com        cmos_Isub_leakage(g_tp.min_w_nmos_, p_to_n_sz_r * g_tp.min_w_nmos_, 1,
131910234Syasuko.eckert@amd.com                          inv) * g_tp.peri_global.Vdd;
132010234Syasuko.eckert@amd.com    power_subarray_out_drv.readOp.gate_leakage +=
132110234Syasuko.eckert@amd.com        cmos_Ig_leakage(g_tp.min_w_nmos_, p_to_n_sz_r * g_tp.min_w_nmos_, 1,
132210234Syasuko.eckert@amd.com                        inv) * g_tp.peri_global.Vdd;
132310152Satgutier@umich.edu
132410152Satgutier@umich.edu
132510234Syasuko.eckert@amd.com    // delay of signal through pass-transistor to input of subarray output driver.
132610234Syasuko.eckert@amd.com    rd = tr_R_on(g_tp.w_nmos_sa_mux, NCH, 1, is_dram);
132710234Syasuko.eckert@amd.com    C_ld = dp.Ndsam_lev_2 *
132810234Syasuko.eckert@amd.com        drain_C_(g_tp.w_nmos_sa_mux, NCH, 1, 0, camFlag ? cam_cell.w :
132910234Syasuko.eckert@amd.com                 cell.w * deg_bl_muxing * dp.Ndsam_lev_1 / (RWP + ERP + SCHP),
133010234Syasuko.eckert@amd.com                 is_dram) +
133110234Syasuko.eckert@amd.com           //gate_C(subarray_out_wire->repeater_size * g_tp.min_w_nmos_ * (1 + p_to_n_sz_r), 0.0, is_dram);
133210234Syasuko.eckert@amd.com        gate_C(subarray_out_wire->repeater_size *
133310234Syasuko.eckert@amd.com               (subarray_out_wire->wire_length /
133410234Syasuko.eckert@amd.com                subarray_out_wire->repeater_spacing) * g_tp.min_w_nmos_ *
133510234Syasuko.eckert@amd.com               (1 + p_to_n_sz_r), 0.0, is_dram);
133610234Syasuko.eckert@amd.com    tf = rd * C_ld;
133710234Syasuko.eckert@amd.com    this_delay = horowitz(inrisetime, tf, 0.5, 0.5, RISE);
133810234Syasuko.eckert@amd.com    delay_subarray_out_drv += this_delay;
133910234Syasuko.eckert@amd.com    inrisetime = this_delay / (1.0 - 0.5);
134010234Syasuko.eckert@amd.com    power_subarray_out_drv.readOp.dynamic += C_ld * 0.5 * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd;
134110234Syasuko.eckert@amd.com    power_subarray_out_drv.readOp.leakage += 0;  // for now, let leakage of the pass transistor be 0
134210234Syasuko.eckert@amd.com    power_subarray_out_drv.readOp.gate_leakage +=
134310234Syasuko.eckert@amd.com        cmos_Ig_leakage(g_tp.w_nmos_sa_mux, 0, 1, nmos) * g_tp.peri_global.Vdd;
134410152Satgutier@umich.edu
134510152Satgutier@umich.edu
134610234Syasuko.eckert@amd.com    return inrisetime;
134710152Satgutier@umich.edu}
134810152Satgutier@umich.edu
134910152Satgutier@umich.edu
135010152Satgutier@umich.edu
135110234Syasuko.eckert@amd.comdouble Mat::compute_comparator_delay(double inrisetime) {
135210234Syasuko.eckert@amd.com    int A = g_ip->tag_assoc;
135310152Satgutier@umich.edu
135410234Syasuko.eckert@amd.com    int tagbits_ = dp.tagbits / 4; // Assuming there are 4 quarter comparators. input tagbits is already
135510234Syasuko.eckert@amd.com    // a multiple of 4.
135610152Satgutier@umich.edu
135710234Syasuko.eckert@amd.com    /* First Inverter */
135810234Syasuko.eckert@amd.com    double Ceq = gate_C(g_tp.w_comp_inv_n2 + g_tp.w_comp_inv_p2, 0, is_dram) +
135910234Syasuko.eckert@amd.com                 drain_C_(g_tp.w_comp_inv_p1, PCH, 1, 1, g_tp.cell_h_def, is_dram) +
136010234Syasuko.eckert@amd.com                 drain_C_(g_tp.w_comp_inv_n1, NCH, 1, 1, g_tp.cell_h_def, is_dram);
136110234Syasuko.eckert@amd.com    double Req = tr_R_on(g_tp.w_comp_inv_p1, PCH, 1, is_dram);
136210234Syasuko.eckert@amd.com    double tf  = Req * Ceq;
136310234Syasuko.eckert@amd.com    double st1del = horowitz(inrisetime, tf, VTHCOMPINV, VTHCOMPINV, FALL);
136410234Syasuko.eckert@amd.com    double nextinputtime = st1del / VTHCOMPINV;
136510234Syasuko.eckert@amd.com    power_comparator.readOp.dynamic += 0.5 * Ceq * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd * 4 * A;
136610152Satgutier@umich.edu
136710234Syasuko.eckert@amd.com    //For each degree of associativity
136810234Syasuko.eckert@amd.com    //there are 4 such quarter comparators
136910234Syasuko.eckert@amd.com    double lkgCurrent = cmos_Isub_leakage(g_tp.w_comp_inv_n1,
137010234Syasuko.eckert@amd.com                                          g_tp.w_comp_inv_p1, 1, inv,
137110234Syasuko.eckert@amd.com                                          is_dram) * 4 * A;
137210234Syasuko.eckert@amd.com    double gatelkgCurrent = cmos_Ig_leakage(g_tp.w_comp_inv_n1,
137310234Syasuko.eckert@amd.com                                            g_tp.w_comp_inv_p1, 1, inv,
137410234Syasuko.eckert@amd.com                                            is_dram) * 4 * A;
137510234Syasuko.eckert@amd.com    /* Second Inverter */
137610234Syasuko.eckert@amd.com    Ceq = gate_C(g_tp.w_comp_inv_n3 + g_tp.w_comp_inv_p3, 0, is_dram) +
137710234Syasuko.eckert@amd.com          drain_C_(g_tp.w_comp_inv_p2, PCH, 1, 1, g_tp.cell_h_def, is_dram) +
137810234Syasuko.eckert@amd.com          drain_C_(g_tp.w_comp_inv_n2, NCH, 1, 1, g_tp.cell_h_def, is_dram);
137910234Syasuko.eckert@amd.com    Req = tr_R_on(g_tp.w_comp_inv_n2, NCH, 1, is_dram);
138010234Syasuko.eckert@amd.com    tf = Req * Ceq;
138110234Syasuko.eckert@amd.com    double st2del = horowitz(nextinputtime, tf, VTHCOMPINV, VTHCOMPINV, RISE);
138210234Syasuko.eckert@amd.com    nextinputtime = st2del / (1.0 - VTHCOMPINV);
138310234Syasuko.eckert@amd.com    power_comparator.readOp.dynamic += 0.5 * Ceq * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd * 4 * A;
138410234Syasuko.eckert@amd.com    lkgCurrent += cmos_Isub_leakage(g_tp.w_comp_inv_n2, g_tp.w_comp_inv_p2, 1,
138510234Syasuko.eckert@amd.com                                    inv, is_dram) * 4 * A;
138610234Syasuko.eckert@amd.com    gatelkgCurrent += cmos_Ig_leakage(g_tp.w_comp_inv_n2, g_tp.w_comp_inv_p2, 1,
138710234Syasuko.eckert@amd.com                                      inv, is_dram) * 4 * A;
138810152Satgutier@umich.edu
138910234Syasuko.eckert@amd.com    /* Third Inverter */
139010234Syasuko.eckert@amd.com    Ceq = gate_C(g_tp.w_eval_inv_n + g_tp.w_eval_inv_p, 0, is_dram) +
139110234Syasuko.eckert@amd.com          drain_C_(g_tp.w_comp_inv_p3, PCH, 1, 1, g_tp.cell_h_def, is_dram) +
139210234Syasuko.eckert@amd.com          drain_C_(g_tp.w_comp_inv_n3, NCH, 1, 1, g_tp.cell_h_def, is_dram);
139310234Syasuko.eckert@amd.com    Req = tr_R_on(g_tp.w_comp_inv_p3, PCH, 1, is_dram);
139410234Syasuko.eckert@amd.com    tf = Req * Ceq;
139510234Syasuko.eckert@amd.com    double st3del = horowitz(nextinputtime, tf, VTHCOMPINV, VTHEVALINV, FALL);
139610234Syasuko.eckert@amd.com    nextinputtime = st3del / (VTHEVALINV);
139710234Syasuko.eckert@amd.com    power_comparator.readOp.dynamic += 0.5 * Ceq * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd * 4 * A;
139810234Syasuko.eckert@amd.com    lkgCurrent += cmos_Isub_leakage(g_tp.w_comp_inv_n3, g_tp.w_comp_inv_p3, 1,
139910234Syasuko.eckert@amd.com                                    inv, is_dram) * 4 * A;
140010234Syasuko.eckert@amd.com    gatelkgCurrent += cmos_Ig_leakage(g_tp.w_comp_inv_n3, g_tp.w_comp_inv_p3,
140110234Syasuko.eckert@amd.com                                      1, inv, is_dram) * 4 * A;
140210152Satgutier@umich.edu
140310234Syasuko.eckert@amd.com    /* Final Inverter (virtual ground driver) discharging compare part */
140410234Syasuko.eckert@amd.com    double r1 = tr_R_on(g_tp.w_comp_n, NCH, 2, is_dram);
140510234Syasuko.eckert@amd.com    double r2 = tr_R_on(g_tp.w_eval_inv_n, NCH, 1, is_dram); /* was switch */
140610234Syasuko.eckert@amd.com    double c2 = (tagbits_) * (drain_C_(g_tp.w_comp_n, NCH, 1, 1,
140710234Syasuko.eckert@amd.com                                       g_tp.cell_h_def, is_dram) +
140810234Syasuko.eckert@amd.com                              drain_C_(g_tp.w_comp_n, NCH, 2, 1,
140910234Syasuko.eckert@amd.com                                       g_tp.cell_h_def, is_dram)) +
141010234Syasuko.eckert@amd.com        drain_C_(g_tp.w_eval_inv_p, PCH, 1, 1, g_tp.cell_h_def, is_dram) +
141110234Syasuko.eckert@amd.com        drain_C_(g_tp.w_eval_inv_n, NCH, 1, 1, g_tp.cell_h_def, is_dram);
141210234Syasuko.eckert@amd.com    double c1 = (tagbits_) * (drain_C_(g_tp.w_comp_n, NCH, 1, 1,
141310234Syasuko.eckert@amd.com                                       g_tp.cell_h_def, is_dram) +
141410234Syasuko.eckert@amd.com                              drain_C_(g_tp.w_comp_n, NCH, 2, 1,
141510234Syasuko.eckert@amd.com                                       g_tp.cell_h_def, is_dram)) +
141610234Syasuko.eckert@amd.com        drain_C_(g_tp.w_comp_p, PCH, 1, 1, g_tp.cell_h_def, is_dram) +
141710234Syasuko.eckert@amd.com        gate_C(WmuxdrvNANDn + WmuxdrvNANDp, 0, is_dram);
141810234Syasuko.eckert@amd.com    power_comparator.readOp.dynamic += 0.5 * c2 * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd * 4 * A;
141910234Syasuko.eckert@amd.com    power_comparator.readOp.dynamic += c1 * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd *  (A - 1);
142010234Syasuko.eckert@amd.com    lkgCurrent += cmos_Isub_leakage(g_tp.w_eval_inv_n, g_tp.w_eval_inv_p, 1,
142110234Syasuko.eckert@amd.com                                    inv, is_dram) * 4 * A;
142210234Syasuko.eckert@amd.com    lkgCurrent += cmos_Isub_leakage(g_tp.w_comp_n, g_tp.w_comp_n, 1, inv,
142310234Syasuko.eckert@amd.com                                    is_dram) * 4 * A; // stack factor of 0.2
142410152Satgutier@umich.edu
142510234Syasuko.eckert@amd.com    gatelkgCurrent += cmos_Ig_leakage(g_tp.w_eval_inv_n, g_tp.w_eval_inv_p, 1,
142610234Syasuko.eckert@amd.com                                      inv, is_dram) * 4 * A;
142710234Syasuko.eckert@amd.com    //for gate leakage this equals to a inverter
142810234Syasuko.eckert@amd.com    gatelkgCurrent += cmos_Ig_leakage(g_tp.w_comp_n, g_tp.w_comp_n, 1, inv,
142910234Syasuko.eckert@amd.com                                      is_dram) * 4 * A;
143010152Satgutier@umich.edu
143110234Syasuko.eckert@amd.com    /* time to go to threshold of mux driver */
143210234Syasuko.eckert@amd.com    double tstep = (r2 * c2 + (r1 + r2) * c1) * log(1.0 / VTHMUXNAND);
143310234Syasuko.eckert@amd.com    /* take into account non-zero input rise time */
143410234Syasuko.eckert@amd.com    double m = g_tp.peri_global.Vdd / nextinputtime;
143510234Syasuko.eckert@amd.com    double Tcomparatorni;
143610152Satgutier@umich.edu
143710234Syasuko.eckert@amd.com    if ((tstep) <= (0.5*(g_tp.peri_global.Vdd - g_tp.peri_global.Vth) / m)) {
143810234Syasuko.eckert@amd.com        double a = m;
143910234Syasuko.eckert@amd.com        double b = 2 * ((g_tp.peri_global.Vdd * VTHEVALINV) -
144010234Syasuko.eckert@amd.com                        g_tp.peri_global.Vth);
144110234Syasuko.eckert@amd.com        double c = -2 * (tstep) * (g_tp.peri_global.Vdd -
144210234Syasuko.eckert@amd.com                                   g_tp.peri_global.Vth) + 1 / m *
144310234Syasuko.eckert@amd.com            ((g_tp.peri_global.Vdd * VTHEVALINV) - g_tp.peri_global.Vth) *
144410234Syasuko.eckert@amd.com            ((g_tp.peri_global.Vdd * VTHEVALINV) - g_tp.peri_global.Vth);
144510234Syasuko.eckert@amd.com        Tcomparatorni = (-b + sqrt(b * b - 4 * a * c)) / (2 * a);
144610234Syasuko.eckert@amd.com    } else {
144710234Syasuko.eckert@amd.com        Tcomparatorni = (tstep) + (g_tp.peri_global.Vdd +
144810234Syasuko.eckert@amd.com                                   g_tp.peri_global.Vth) / (2 * m) -
144910234Syasuko.eckert@amd.com            (g_tp.peri_global.Vdd * VTHEVALINV) / m;
145010234Syasuko.eckert@amd.com    }
145110234Syasuko.eckert@amd.com    delay_comparator = Tcomparatorni + st1del + st2del + st3del;
145210234Syasuko.eckert@amd.com    power_comparator.readOp.leakage = lkgCurrent * g_tp.peri_global.Vdd;
145310234Syasuko.eckert@amd.com    power_comparator.readOp.gate_leakage = gatelkgCurrent * g_tp.peri_global.Vdd;
145410152Satgutier@umich.edu
145510234Syasuko.eckert@amd.com    return Tcomparatorni / (1.0 - VTHMUXNAND);;
145610152Satgutier@umich.edu}
145710152Satgutier@umich.edu
145810152Satgutier@umich.edu
145910152Satgutier@umich.edu
146010234Syasuko.eckert@amd.comvoid Mat::compute_power_energy() {
146110234Syasuko.eckert@amd.com    //for cam and FA, power.readOp is the plain read power, power.searchOp is the associative search related power
146210152Satgutier@umich.edu    //when search all subarrays and all mats are fully active
146310234Syasuko.eckert@amd.com    //when plain read/write only one subarray in a single mat is active.
146410152Satgutier@umich.edu
146510152Satgutier@umich.edu    // add energy consumed in predecoder drivers. This unit is shared by all subarrays in a mat.
146610234Syasuko.eckert@amd.com    power.readOp.dynamic += r_predec->power.readOp.dynamic +
146710234Syasuko.eckert@amd.com                            b_mux_predec->power.readOp.dynamic +
146810234Syasuko.eckert@amd.com                            sa_mux_lev_1_predec->power.readOp.dynamic +
146910234Syasuko.eckert@amd.com                            sa_mux_lev_2_predec->power.readOp.dynamic;
147010152Satgutier@umich.edu
147110234Syasuko.eckert@amd.com    // add energy consumed in decoders
147210234Syasuko.eckert@amd.com    power_row_decoders.readOp.dynamic        = row_dec->power.readOp.dynamic;
147310234Syasuko.eckert@amd.com    if (!(is_fa || pure_cam))
147410234Syasuko.eckert@amd.com        power_row_decoders.readOp.dynamic        *= num_subarrays_per_mat;
147510152Satgutier@umich.edu
147610234Syasuko.eckert@amd.com    // add energy consumed in bitline prechagers, SAs, and bitlines
147710234Syasuko.eckert@amd.com    if (!(is_fa || pure_cam)) {
147810234Syasuko.eckert@amd.com        // add energy consumed in bitline prechagers
147910234Syasuko.eckert@amd.com        power_bl_precharge_eq_drv.readOp.dynamic = bl_precharge_eq_drv->power.readOp.dynamic;
148010234Syasuko.eckert@amd.com        power_bl_precharge_eq_drv.readOp.dynamic *= num_subarrays_per_mat;
148110152Satgutier@umich.edu
148210234Syasuko.eckert@amd.com        //Add sense amps energy
148310234Syasuko.eckert@amd.com        num_sa_subarray = subarray.num_cols / deg_bl_muxing;
148410234Syasuko.eckert@amd.com        power_sa.readOp.dynamic *= num_sa_subarray * num_subarrays_per_mat ;
148510152Satgutier@umich.edu
148610234Syasuko.eckert@amd.com        // add energy consumed in bitlines
148710234Syasuko.eckert@amd.com        //cout<<"bitline power"<<power_bitline.readOp.dynamic<<endl;
148810234Syasuko.eckert@amd.com        power_bitline.readOp.dynamic *= num_subarrays_per_mat *
148910234Syasuko.eckert@amd.com            subarray.num_cols;
149010234Syasuko.eckert@amd.com        power_bitline.writeOp.dynamic *= num_subarrays_per_mat *
149110234Syasuko.eckert@amd.com            subarray.num_cols;
149210234Syasuko.eckert@amd.com        //cout<<"bitline power"<<power_bitline.readOp.dynamic<<"subarray"<<num_subarrays_per_mat<<"cols"<<subarray.num_cols<<endl;
149310234Syasuko.eckert@amd.com        //Add subarray output energy
149410234Syasuko.eckert@amd.com        power_subarray_out_drv.readOp.dynamic =
149510234Syasuko.eckert@amd.com            (power_subarray_out_drv.readOp.dynamic + subarray_out_wire->power.readOp.dynamic) * num_do_b_mat;
149610152Satgutier@umich.edu
149710234Syasuko.eckert@amd.com        power.readOp.dynamic += power_bl_precharge_eq_drv.readOp.dynamic +
149810234Syasuko.eckert@amd.com                                power_sa.readOp.dynamic +
149910234Syasuko.eckert@amd.com                                power_bitline.readOp.dynamic +
150010234Syasuko.eckert@amd.com                                power_subarray_out_drv.readOp.dynamic;
150110152Satgutier@umich.edu
150210234Syasuko.eckert@amd.com        power.readOp.dynamic += power_row_decoders.readOp.dynamic +
150310234Syasuko.eckert@amd.com                                bit_mux_dec->power.readOp.dynamic +
150410234Syasuko.eckert@amd.com                                sa_mux_lev_1_dec->power.readOp.dynamic +
150510234Syasuko.eckert@amd.com                                sa_mux_lev_2_dec->power.readOp.dynamic +
150610234Syasuko.eckert@amd.com                                power_comparator.readOp.dynamic;
150710234Syasuko.eckert@amd.com    }
150810152Satgutier@umich.edu
150910234Syasuko.eckert@amd.com    else if (is_fa) {
151010234Syasuko.eckert@amd.com        //for plain read/write only one subarray in a mat is active
151110234Syasuko.eckert@amd.com        // add energy consumed in bitline prechagers
151210234Syasuko.eckert@amd.com        power_bl_precharge_eq_drv.readOp.dynamic = bl_precharge_eq_drv->power.readOp.dynamic
151310234Syasuko.eckert@amd.com                + cam_bl_precharge_eq_drv->power.readOp.dynamic;
151410234Syasuko.eckert@amd.com        power_bl_precharge_eq_drv.searchOp.dynamic = bl_precharge_eq_drv->power.readOp.dynamic;
151510152Satgutier@umich.edu
151610234Syasuko.eckert@amd.com        //Add sense amps energy
151710234Syasuko.eckert@amd.com        num_sa_subarray = (subarray.num_cols_fa_cam +
151810234Syasuko.eckert@amd.com                           subarray.num_cols_fa_ram) / deg_bl_muxing;
151910234Syasuko.eckert@amd.com        num_sa_subarray_search = subarray.num_cols_fa_ram / deg_bl_muxing;
152010234Syasuko.eckert@amd.com        power_sa.searchOp.dynamic = power_sa.readOp.dynamic *
152110234Syasuko.eckert@amd.com            num_sa_subarray_search;
152210234Syasuko.eckert@amd.com        power_sa.readOp.dynamic *= num_sa_subarray;
152310152Satgutier@umich.edu
152410152Satgutier@umich.edu
152510234Syasuko.eckert@amd.com        // add energy consumed in bitlines
152610234Syasuko.eckert@amd.com        power_bitline.searchOp.dynamic = power_bitline.readOp.dynamic;
152710234Syasuko.eckert@amd.com        power_bitline.readOp.dynamic *= (subarray.num_cols_fa_cam +
152810234Syasuko.eckert@amd.com                                         subarray.num_cols_fa_ram);
152910234Syasuko.eckert@amd.com        power_bitline.writeOp.dynamic *= (subarray.num_cols_fa_cam +
153010234Syasuko.eckert@amd.com                                          subarray.num_cols_fa_ram);
153110234Syasuko.eckert@amd.com        power_bitline.searchOp.dynamic *= subarray.num_cols_fa_ram;
153210152Satgutier@umich.edu
153310234Syasuko.eckert@amd.com        //Add subarray output energy
153410234Syasuko.eckert@amd.com        power_subarray_out_drv.searchOp.dynamic =
153510234Syasuko.eckert@amd.com            (power_subarray_out_drv.readOp.dynamic + subarray_out_wire->power.readOp.dynamic) * num_so_b_mat;
153610234Syasuko.eckert@amd.com        power_subarray_out_drv.readOp.dynamic =
153710234Syasuko.eckert@amd.com            (power_subarray_out_drv.readOp.dynamic + subarray_out_wire->power.readOp.dynamic) * num_do_b_mat;
153810152Satgutier@umich.edu
153910152Satgutier@umich.edu
154010234Syasuko.eckert@amd.com        power.readOp.dynamic += power_bl_precharge_eq_drv.readOp.dynamic +
154110234Syasuko.eckert@amd.com                                power_sa.readOp.dynamic +
154210234Syasuko.eckert@amd.com                                power_bitline.readOp.dynamic +
154310234Syasuko.eckert@amd.com                                power_subarray_out_drv.readOp.dynamic;
154410152Satgutier@umich.edu
154510234Syasuko.eckert@amd.com        power.readOp.dynamic += power_row_decoders.readOp.dynamic +
154610234Syasuko.eckert@amd.com                                bit_mux_dec->power.readOp.dynamic +
154710234Syasuko.eckert@amd.com                                sa_mux_lev_1_dec->power.readOp.dynamic +
154810234Syasuko.eckert@amd.com                                sa_mux_lev_2_dec->power.readOp.dynamic +
154910234Syasuko.eckert@amd.com                                power_comparator.readOp.dynamic;
155010152Satgutier@umich.edu
155110234Syasuko.eckert@amd.com        //add energy consumed inside cam
155210234Syasuko.eckert@amd.com        power_matchline.searchOp.dynamic *= num_subarrays_per_mat;
155310234Syasuko.eckert@amd.com        power_searchline_precharge = sl_precharge_eq_drv->power;
155410234Syasuko.eckert@amd.com        power_searchline_precharge.searchOp.dynamic = power_searchline_precharge.readOp.dynamic * num_subarrays_per_mat;
155510234Syasuko.eckert@amd.com        power_searchline = sl_data_drv->power;
155610234Syasuko.eckert@amd.com        power_searchline.searchOp.dynamic = power_searchline.readOp.dynamic *
155710234Syasuko.eckert@amd.com            subarray.num_cols_fa_cam * num_subarrays_per_mat;;
155810234Syasuko.eckert@amd.com        power_matchline_precharge  = ml_precharge_drv->power;
155910234Syasuko.eckert@amd.com        power_matchline_precharge.searchOp.dynamic =
156010234Syasuko.eckert@amd.com            power_matchline_precharge.readOp.dynamic * num_subarrays_per_mat;
156110234Syasuko.eckert@amd.com        power_ml_to_ram_wl_drv = ml_to_ram_wl_drv->power;
156210234Syasuko.eckert@amd.com        power_ml_to_ram_wl_drv.searchOp.dynamic =
156310234Syasuko.eckert@amd.com            ml_to_ram_wl_drv->power.readOp.dynamic;
156410152Satgutier@umich.edu
156510234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.dynamic = power_matchline.searchOp.dynamic;
156610234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.dynamic +=
156710234Syasuko.eckert@amd.com            power_searchline_precharge.searchOp.dynamic;
156810234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.dynamic +=
156910234Syasuko.eckert@amd.com            power_searchline.searchOp.dynamic;
157010234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.dynamic +=
157110234Syasuko.eckert@amd.com            power_matchline_precharge.searchOp.dynamic;
157210152Satgutier@umich.edu
157310234Syasuko.eckert@amd.com        power.searchOp.dynamic += power_cam_all_active.searchOp.dynamic;
157410234Syasuko.eckert@amd.com        //power.searchOp.dynamic += ml_to_ram_wl_drv->power.readOp.dynamic;
157510152Satgutier@umich.edu
157610234Syasuko.eckert@amd.com    } else {
157710234Syasuko.eckert@amd.com        // add energy consumed in bitline prechagers
157810234Syasuko.eckert@amd.com        power_bl_precharge_eq_drv.readOp.dynamic = cam_bl_precharge_eq_drv->power.readOp.dynamic;
157910234Syasuko.eckert@amd.com        //power_bl_precharge_eq_drv.readOp.dynamic *= num_subarrays_per_mat;
158010234Syasuko.eckert@amd.com        //power_bl_precharge_eq_drv.searchOp.dynamic = cam_bl_precharge_eq_drv->power.readOp.dynamic;
158110234Syasuko.eckert@amd.com        //power_bl_precharge_eq_drv.searchOp.dynamic *= num_subarrays_per_mat;
158210152Satgutier@umich.edu
158310234Syasuko.eckert@amd.com        //Add sense amps energy
158410234Syasuko.eckert@amd.com        num_sa_subarray = subarray.num_cols_fa_cam / deg_bl_muxing;
158510234Syasuko.eckert@amd.com        power_sa.readOp.dynamic *= num_sa_subarray;//*num_subarrays_per_mat;
158610234Syasuko.eckert@amd.com        power_sa.searchOp.dynamic = 0;
158710152Satgutier@umich.edu
158810234Syasuko.eckert@amd.com        power_bitline.readOp.dynamic *= subarray.num_cols_fa_cam;
158910234Syasuko.eckert@amd.com        power_bitline.searchOp.dynamic = 0;
159010234Syasuko.eckert@amd.com        power_bitline.writeOp.dynamic *= subarray.num_cols_fa_cam;
159110152Satgutier@umich.edu
159210234Syasuko.eckert@amd.com        power_subarray_out_drv.searchOp.dynamic =
159310234Syasuko.eckert@amd.com            (power_subarray_out_drv.readOp.dynamic + subarray_out_wire->power.readOp.dynamic) * num_so_b_mat;
159410234Syasuko.eckert@amd.com        power_subarray_out_drv.readOp.dynamic =
159510234Syasuko.eckert@amd.com            (power_subarray_out_drv.readOp.dynamic + subarray_out_wire->power.readOp.dynamic) * num_do_b_mat;
159610152Satgutier@umich.edu
159710234Syasuko.eckert@amd.com        power.readOp.dynamic += power_bl_precharge_eq_drv.readOp.dynamic +
159810234Syasuko.eckert@amd.com                                power_sa.readOp.dynamic +
159910234Syasuko.eckert@amd.com                                power_bitline.readOp.dynamic +
160010234Syasuko.eckert@amd.com                                power_subarray_out_drv.readOp.dynamic;
160110152Satgutier@umich.edu
160210234Syasuko.eckert@amd.com        power.readOp.dynamic += power_row_decoders.readOp.dynamic +
160310234Syasuko.eckert@amd.com                                bit_mux_dec->power.readOp.dynamic +
160410234Syasuko.eckert@amd.com                                sa_mux_lev_1_dec->power.readOp.dynamic +
160510234Syasuko.eckert@amd.com                                sa_mux_lev_2_dec->power.readOp.dynamic +
160610234Syasuko.eckert@amd.com                                power_comparator.readOp.dynamic;
160710152Satgutier@umich.edu
160810152Satgutier@umich.edu
160910234Syasuko.eckert@amd.com        ////add energy consumed inside cam
161010234Syasuko.eckert@amd.com        power_matchline.searchOp.dynamic *= num_subarrays_per_mat;
161110234Syasuko.eckert@amd.com        power_searchline_precharge = sl_precharge_eq_drv->power;
161210234Syasuko.eckert@amd.com        power_searchline_precharge.searchOp.dynamic = power_searchline_precharge.readOp.dynamic * num_subarrays_per_mat;
161310234Syasuko.eckert@amd.com        power_searchline = sl_data_drv->power;
161410234Syasuko.eckert@amd.com        power_searchline.searchOp.dynamic = power_searchline.readOp.dynamic *
161510234Syasuko.eckert@amd.com            subarray.num_cols_fa_cam * num_subarrays_per_mat;;
161610234Syasuko.eckert@amd.com        power_matchline_precharge  = ml_precharge_drv->power;
161710234Syasuko.eckert@amd.com        power_matchline_precharge.searchOp.dynamic =
161810234Syasuko.eckert@amd.com            power_matchline_precharge.readOp.dynamic * num_subarrays_per_mat;
161910234Syasuko.eckert@amd.com        power_ml_to_ram_wl_drv = ml_to_ram_wl_drv->power;
162010234Syasuko.eckert@amd.com        power_ml_to_ram_wl_drv.searchOp.dynamic =
162110234Syasuko.eckert@amd.com            ml_to_ram_wl_drv->power.readOp.dynamic;
162210152Satgutier@umich.edu
162310234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.dynamic =
162410234Syasuko.eckert@amd.com            power_matchline.searchOp.dynamic;
162510234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.dynamic +=
162610234Syasuko.eckert@amd.com            power_searchline_precharge.searchOp.dynamic;
162710234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.dynamic +=
162810234Syasuko.eckert@amd.com            power_searchline.searchOp.dynamic;
162910234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.dynamic +=
163010234Syasuko.eckert@amd.com            power_matchline_precharge.searchOp.dynamic;
163110152Satgutier@umich.edu
163210234Syasuko.eckert@amd.com        power.searchOp.dynamic += power_cam_all_active.searchOp.dynamic;
163310234Syasuko.eckert@amd.com        //power.searchOp.dynamic += ml_to_ram_wl_drv->power.readOp.dynamic;
163410152Satgutier@umich.edu
163510234Syasuko.eckert@amd.com    }
163610152Satgutier@umich.edu
163710152Satgutier@umich.edu
163810152Satgutier@umich.edu
163910234Syasuko.eckert@amd.com    // calculate leakage power
164010234Syasuko.eckert@amd.com    if (!(is_fa || pure_cam)) {
164110152Satgutier@umich.edu        int number_output_drivers_subarray = num_sa_subarray / (dp.Ndsam_lev_1 * dp.Ndsam_lev_2);
164210152Satgutier@umich.edu
164310152Satgutier@umich.edu        power_bitline.readOp.leakage            *= subarray.num_rows * subarray.num_cols * num_subarrays_per_mat;
164410234Syasuko.eckert@amd.com        power_bl_precharge_eq_drv.readOp.leakage = bl_precharge_eq_drv->power.readOp.leakage * num_subarrays_per_mat;
164510234Syasuko.eckert@amd.com        power_sa.readOp.leakage *= num_sa_subarray * num_subarrays_per_mat *
164610234Syasuko.eckert@amd.com            (RWP + ERP);
164710152Satgutier@umich.edu
164810234Syasuko.eckert@amd.com        //num_sa_subarray             = subarray.num_cols / deg_bl_muxing;
164910234Syasuko.eckert@amd.com        power_subarray_out_drv.readOp.leakage =
165010234Syasuko.eckert@amd.com            (power_subarray_out_drv.readOp.leakage + subarray_out_wire->power.readOp.leakage) *
165110234Syasuko.eckert@amd.com            number_output_drivers_subarray * num_subarrays_per_mat * (RWP + ERP);
165210152Satgutier@umich.edu
165310234Syasuko.eckert@amd.com        power.readOp.leakage += power_bitline.readOp.leakage +
165410234Syasuko.eckert@amd.com                                power_bl_precharge_eq_drv.readOp.leakage +
165510234Syasuko.eckert@amd.com                                power_sa.readOp.leakage +
165610234Syasuko.eckert@amd.com                                power_subarray_out_drv.readOp.leakage;
165710234Syasuko.eckert@amd.com        //cout<<"leakage"<<power.readOp.leakage<<endl;
165810152Satgutier@umich.edu
165910234Syasuko.eckert@amd.com        power_comparator.readOp.leakage *= num_do_b_mat * (RWP + ERP);
166010234Syasuko.eckert@amd.com        power.readOp.leakage += power_comparator.readOp.leakage;
166110152Satgutier@umich.edu
166210234Syasuko.eckert@amd.com        //cout<<"leakage1"<<power.readOp.leakage<<endl;
166310152Satgutier@umich.edu
166410234Syasuko.eckert@amd.com        // leakage power
166510234Syasuko.eckert@amd.com        power_row_decoders.readOp.leakage = row_dec->power.readOp.leakage * subarray.num_rows * num_subarrays_per_mat;
166610234Syasuko.eckert@amd.com        power_bit_mux_decoders.readOp.leakage      = bit_mux_dec->power.readOp.leakage * deg_bl_muxing;
166710234Syasuko.eckert@amd.com        power_sa_mux_lev_1_decoders.readOp.leakage = sa_mux_lev_1_dec->power.readOp.leakage * dp.Ndsam_lev_1;
166810234Syasuko.eckert@amd.com        power_sa_mux_lev_2_decoders.readOp.leakage = sa_mux_lev_2_dec->power.readOp.leakage * dp.Ndsam_lev_2;
166910152Satgutier@umich.edu
167010234Syasuko.eckert@amd.com        power.readOp.leakage += r_predec->power.readOp.leakage +
167110234Syasuko.eckert@amd.com                                b_mux_predec->power.readOp.leakage +
167210234Syasuko.eckert@amd.com                                sa_mux_lev_1_predec->power.readOp.leakage +
167310234Syasuko.eckert@amd.com                                sa_mux_lev_2_predec->power.readOp.leakage +
167410234Syasuko.eckert@amd.com                                power_row_decoders.readOp.leakage +
167510234Syasuko.eckert@amd.com                                power_bit_mux_decoders.readOp.leakage +
167610234Syasuko.eckert@amd.com                                power_sa_mux_lev_1_decoders.readOp.leakage +
167710234Syasuko.eckert@amd.com                                power_sa_mux_lev_2_decoders.readOp.leakage;
167810234Syasuko.eckert@amd.com        //cout<<"leakage2"<<power.readOp.leakage<<endl;
167910152Satgutier@umich.edu
168010234Syasuko.eckert@amd.com        //++++Below is gate leakage
168110152Satgutier@umich.edu        power_bitline.readOp.gate_leakage            *= subarray.num_rows * subarray.num_cols * num_subarrays_per_mat;
168210234Syasuko.eckert@amd.com        power_bl_precharge_eq_drv.readOp.gate_leakage = bl_precharge_eq_drv->power.readOp.gate_leakage * num_subarrays_per_mat;
168310234Syasuko.eckert@amd.com        power_sa.readOp.gate_leakage *= num_sa_subarray *
168410234Syasuko.eckert@amd.com            num_subarrays_per_mat * (RWP + ERP);
168510152Satgutier@umich.edu
168610234Syasuko.eckert@amd.com        //num_sa_subarray             = subarray.num_cols / deg_bl_muxing;
168710234Syasuko.eckert@amd.com        power_subarray_out_drv.readOp.gate_leakage =
168810234Syasuko.eckert@amd.com            (power_subarray_out_drv.readOp.gate_leakage + subarray_out_wire->power.readOp.gate_leakage) *
168910234Syasuko.eckert@amd.com            number_output_drivers_subarray * num_subarrays_per_mat * (RWP + ERP);
169010152Satgutier@umich.edu
169110234Syasuko.eckert@amd.com        power.readOp.gate_leakage += power_bitline.readOp.gate_leakage +
169210234Syasuko.eckert@amd.com                                     power_bl_precharge_eq_drv.readOp.gate_leakage +
169310234Syasuko.eckert@amd.com                                     power_sa.readOp.gate_leakage +
169410234Syasuko.eckert@amd.com                                     power_subarray_out_drv.readOp.gate_leakage;
169510234Syasuko.eckert@amd.com        //cout<<"leakage"<<power.readOp.leakage<<endl;
169610152Satgutier@umich.edu
169710234Syasuko.eckert@amd.com        power_comparator.readOp.gate_leakage *= num_do_b_mat * (RWP + ERP);
169810234Syasuko.eckert@amd.com        power.readOp.gate_leakage += power_comparator.readOp.gate_leakage;
169910152Satgutier@umich.edu
170010234Syasuko.eckert@amd.com        //cout<<"leakage1"<<power.readOp.gate_leakage<<endl;
170110152Satgutier@umich.edu
170210234Syasuko.eckert@amd.com        // gate_leakage power
170310234Syasuko.eckert@amd.com        power_row_decoders.readOp.gate_leakage = row_dec->power.readOp.gate_leakage * subarray.num_rows * num_subarrays_per_mat;
170410234Syasuko.eckert@amd.com        power_bit_mux_decoders.readOp.gate_leakage      = bit_mux_dec->power.readOp.gate_leakage * deg_bl_muxing;
170510234Syasuko.eckert@amd.com        power_sa_mux_lev_1_decoders.readOp.gate_leakage = sa_mux_lev_1_dec->power.readOp.gate_leakage * dp.Ndsam_lev_1;
170610234Syasuko.eckert@amd.com        power_sa_mux_lev_2_decoders.readOp.gate_leakage = sa_mux_lev_2_dec->power.readOp.gate_leakage * dp.Ndsam_lev_2;
170710152Satgutier@umich.edu
170810234Syasuko.eckert@amd.com        power.readOp.gate_leakage += r_predec->power.readOp.gate_leakage +
170910234Syasuko.eckert@amd.com                                     b_mux_predec->power.readOp.gate_leakage +
171010234Syasuko.eckert@amd.com                                     sa_mux_lev_1_predec->power.readOp.gate_leakage +
171110234Syasuko.eckert@amd.com                                     sa_mux_lev_2_predec->power.readOp.gate_leakage +
171210234Syasuko.eckert@amd.com                                     power_row_decoders.readOp.gate_leakage +
171310234Syasuko.eckert@amd.com                                     power_bit_mux_decoders.readOp.gate_leakage +
171410234Syasuko.eckert@amd.com                                     power_sa_mux_lev_1_decoders.readOp.gate_leakage +
171510234Syasuko.eckert@amd.com                                     power_sa_mux_lev_2_decoders.readOp.gate_leakage;
171610234Syasuko.eckert@amd.com    } else if (is_fa) {
171710234Syasuko.eckert@amd.com        int number_output_drivers_subarray = num_sa_subarray;// / (dp.Ndsam_lev_1 * dp.Ndsam_lev_2);
171810152Satgutier@umich.edu
171910234Syasuko.eckert@amd.com        power_bitline.readOp.leakage            *= subarray.num_rows * subarray.num_cols * num_subarrays_per_mat;
172010234Syasuko.eckert@amd.com        power_bl_precharge_eq_drv.readOp.leakage = bl_precharge_eq_drv->power.readOp.leakage * num_subarrays_per_mat;
172110234Syasuko.eckert@amd.com        power_bl_precharge_eq_drv.searchOp.leakage = cam_bl_precharge_eq_drv->power.readOp.leakage * num_subarrays_per_mat;
172210234Syasuko.eckert@amd.com        power_sa.readOp.leakage *= num_sa_subarray * num_subarrays_per_mat *
172310234Syasuko.eckert@amd.com            (RWP + ERP + SCHP);
172410152Satgutier@umich.edu
172510234Syasuko.eckert@amd.com        //cout<<"leakage3"<<power.readOp.leakage<<endl;
172610152Satgutier@umich.edu
172710152Satgutier@umich.edu
172810234Syasuko.eckert@amd.com        power_subarray_out_drv.readOp.leakage =
172910234Syasuko.eckert@amd.com            (power_subarray_out_drv.readOp.leakage + subarray_out_wire->power.readOp.leakage) *
173010234Syasuko.eckert@amd.com            number_output_drivers_subarray * num_subarrays_per_mat * (RWP + ERP + SCHP);
173110152Satgutier@umich.edu
173210234Syasuko.eckert@amd.com        power.readOp.leakage += power_bitline.readOp.leakage +
173310234Syasuko.eckert@amd.com                                power_bl_precharge_eq_drv.readOp.leakage +
173410234Syasuko.eckert@amd.com                                power_bl_precharge_eq_drv.searchOp.leakage +
173510234Syasuko.eckert@amd.com                                power_sa.readOp.leakage +
173610234Syasuko.eckert@amd.com                                power_subarray_out_drv.readOp.leakage;
173710152Satgutier@umich.edu
173810234Syasuko.eckert@amd.com        //cout<<"leakage4"<<power.readOp.leakage<<endl;
173910152Satgutier@umich.edu
174010234Syasuko.eckert@amd.com        // leakage power
174110234Syasuko.eckert@amd.com        power_row_decoders.readOp.leakage = row_dec->power.readOp.leakage * subarray.num_rows * num_subarrays_per_mat;
174210234Syasuko.eckert@amd.com        power.readOp.leakage += r_predec->power.readOp.leakage +
174310234Syasuko.eckert@amd.com                                power_row_decoders.readOp.leakage;
174410152Satgutier@umich.edu
174510234Syasuko.eckert@amd.com        //cout<<"leakage5"<<power.readOp.leakage<<endl;
174610152Satgutier@umich.edu
174710234Syasuko.eckert@amd.com        //inside cam
174810234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.leakage = power_matchline.searchOp.leakage;
174910234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.leakage +=
175010234Syasuko.eckert@amd.com            sl_precharge_eq_drv->power.readOp.leakage;
175110234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.leakage +=
175210234Syasuko.eckert@amd.com            sl_data_drv->power.readOp.leakage * subarray.num_cols_fa_cam;
175310234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.leakage +=
175410234Syasuko.eckert@amd.com            ml_precharge_drv->power.readOp.dynamic;
175510234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.leakage *=
175610234Syasuko.eckert@amd.com            num_subarrays_per_mat;
175710152Satgutier@umich.edu
175810234Syasuko.eckert@amd.com        power.readOp.leakage += power_cam_all_active.searchOp.leakage;
175910152Satgutier@umich.edu
176010152Satgutier@umich.edu//	  cout<<"leakage6"<<power.readOp.leakage<<endl;
176110152Satgutier@umich.edu
176210234Syasuko.eckert@amd.com        //+++Below is gate leakage
176310234Syasuko.eckert@amd.com        power_bitline.readOp.gate_leakage            *= subarray.num_rows * subarray.num_cols * num_subarrays_per_mat;
176410234Syasuko.eckert@amd.com        power_bl_precharge_eq_drv.readOp.gate_leakage = bl_precharge_eq_drv->power.readOp.gate_leakage * num_subarrays_per_mat;
176510234Syasuko.eckert@amd.com        power_bl_precharge_eq_drv.searchOp.gate_leakage = cam_bl_precharge_eq_drv->power.readOp.gate_leakage * num_subarrays_per_mat;
176610234Syasuko.eckert@amd.com        power_sa.readOp.gate_leakage *= num_sa_subarray *
176710234Syasuko.eckert@amd.com            num_subarrays_per_mat * (RWP + ERP + SCHP);
176810152Satgutier@umich.edu
176910234Syasuko.eckert@amd.com        //cout<<"leakage3"<<power.readOp.gate_leakage<<endl;
177010152Satgutier@umich.edu
177110152Satgutier@umich.edu
177210234Syasuko.eckert@amd.com        power_subarray_out_drv.readOp.gate_leakage =
177310234Syasuko.eckert@amd.com            (power_subarray_out_drv.readOp.gate_leakage + subarray_out_wire->power.readOp.gate_leakage) *
177410234Syasuko.eckert@amd.com            number_output_drivers_subarray * num_subarrays_per_mat * (RWP + ERP + SCHP);
177510152Satgutier@umich.edu
177610234Syasuko.eckert@amd.com        power.readOp.gate_leakage += power_bitline.readOp.gate_leakage +
177710234Syasuko.eckert@amd.com                                     power_bl_precharge_eq_drv.readOp.gate_leakage +
177810234Syasuko.eckert@amd.com                                     power_bl_precharge_eq_drv.searchOp.gate_leakage +
177910234Syasuko.eckert@amd.com                                     power_sa.readOp.gate_leakage +
178010234Syasuko.eckert@amd.com                                     power_subarray_out_drv.readOp.gate_leakage;
178110152Satgutier@umich.edu
178210234Syasuko.eckert@amd.com        //cout<<"leakage4"<<power.readOp.gate_leakage<<endl;
178310152Satgutier@umich.edu
178410234Syasuko.eckert@amd.com        // gate_leakage power
178510234Syasuko.eckert@amd.com        power_row_decoders.readOp.gate_leakage = row_dec->power.readOp.gate_leakage * subarray.num_rows * num_subarrays_per_mat;
178610234Syasuko.eckert@amd.com        power.readOp.gate_leakage += r_predec->power.readOp.gate_leakage +
178710234Syasuko.eckert@amd.com                                     power_row_decoders.readOp.gate_leakage;
178810152Satgutier@umich.edu
178910234Syasuko.eckert@amd.com        //cout<<"leakage5"<<power.readOp.gate_leakage<<endl;
179010152Satgutier@umich.edu
179110234Syasuko.eckert@amd.com        //inside cam
179210234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.gate_leakage =
179310234Syasuko.eckert@amd.com            power_matchline.searchOp.gate_leakage;
179410234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.gate_leakage +=
179510234Syasuko.eckert@amd.com            sl_precharge_eq_drv->power.readOp.gate_leakage;
179610234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.gate_leakage +=
179710234Syasuko.eckert@amd.com            sl_data_drv->power.readOp.gate_leakage * subarray.num_cols_fa_cam;
179810234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.gate_leakage +=
179910234Syasuko.eckert@amd.com            ml_precharge_drv->power.readOp.dynamic;
180010234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.gate_leakage *= num_subarrays_per_mat;
180110152Satgutier@umich.edu
180210234Syasuko.eckert@amd.com        power.readOp.gate_leakage += power_cam_all_active.searchOp.gate_leakage;
180310152Satgutier@umich.edu
180410234Syasuko.eckert@amd.com    } else {
180510234Syasuko.eckert@amd.com        int number_output_drivers_subarray = num_sa_subarray;// / (dp.Ndsam_lev_1 * dp.Ndsam_lev_2);
180610152Satgutier@umich.edu
180710234Syasuko.eckert@amd.com        //power_bitline.readOp.leakage            *= subarray.num_rows * subarray.num_cols * num_subarrays_per_mat;
180810234Syasuko.eckert@amd.com        //power_bl_precharge_eq_drv.readOp.leakage = bl_precharge_eq_drv->power.readOp.leakage * num_subarrays_per_mat;
180910234Syasuko.eckert@amd.com        power_bl_precharge_eq_drv.searchOp.leakage = cam_bl_precharge_eq_drv->power.readOp.leakage * num_subarrays_per_mat;
181010234Syasuko.eckert@amd.com        power_sa.readOp.leakage *= num_sa_subarray * num_subarrays_per_mat *
181110234Syasuko.eckert@amd.com            (RWP + ERP + SCHP);
181210152Satgutier@umich.edu
181310152Satgutier@umich.edu
181410234Syasuko.eckert@amd.com        power_subarray_out_drv.readOp.leakage =
181510234Syasuko.eckert@amd.com            (power_subarray_out_drv.readOp.leakage + subarray_out_wire->power.readOp.leakage) *
181610234Syasuko.eckert@amd.com            number_output_drivers_subarray * num_subarrays_per_mat * (RWP + ERP + SCHP);
181710152Satgutier@umich.edu
181810234Syasuko.eckert@amd.com        power.readOp.leakage += //power_bitline.readOp.leakage +
181910234Syasuko.eckert@amd.com            //power_bl_precharge_eq_drv.readOp.leakage +
182010234Syasuko.eckert@amd.com            power_bl_precharge_eq_drv.searchOp.leakage +
182110234Syasuko.eckert@amd.com            power_sa.readOp.leakage +
182210234Syasuko.eckert@amd.com            power_subarray_out_drv.readOp.leakage;
182310152Satgutier@umich.edu
182410234Syasuko.eckert@amd.com        // leakage power
182510234Syasuko.eckert@amd.com        power_row_decoders.readOp.leakage = row_dec->power.readOp.leakage *
182610234Syasuko.eckert@amd.com            subarray.num_rows * num_subarrays_per_mat * (RWP + ERP + EWP);
182710234Syasuko.eckert@amd.com        power.readOp.leakage += r_predec->power.readOp.leakage +
182810234Syasuko.eckert@amd.com                                power_row_decoders.readOp.leakage;
182910152Satgutier@umich.edu
183010234Syasuko.eckert@amd.com        //inside cam
183110234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.leakage = power_matchline.searchOp.leakage;
183210234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.leakage +=
183310234Syasuko.eckert@amd.com            sl_precharge_eq_drv->power.readOp.leakage;
183410234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.leakage +=
183510234Syasuko.eckert@amd.com            sl_data_drv->power.readOp.leakage * subarray.num_cols_fa_cam;
183610234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.leakage +=
183710234Syasuko.eckert@amd.com            ml_precharge_drv->power.readOp.dynamic;
183810234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.leakage *= num_subarrays_per_mat;
183910152Satgutier@umich.edu
184010234Syasuko.eckert@amd.com        power.readOp.leakage += power_cam_all_active.searchOp.leakage;
184110152Satgutier@umich.edu
184210234Syasuko.eckert@amd.com        //+++Below is gate leakage
184310234Syasuko.eckert@amd.com        power_bl_precharge_eq_drv.searchOp.gate_leakage = cam_bl_precharge_eq_drv->power.readOp.gate_leakage * num_subarrays_per_mat;
184410234Syasuko.eckert@amd.com        power_sa.readOp.gate_leakage *= num_sa_subarray *
184510234Syasuko.eckert@amd.com            num_subarrays_per_mat * (RWP + ERP + SCHP);
184610152Satgutier@umich.edu
184710152Satgutier@umich.edu
184810234Syasuko.eckert@amd.com        power_subarray_out_drv.readOp.gate_leakage =
184910234Syasuko.eckert@amd.com            (power_subarray_out_drv.readOp.gate_leakage + subarray_out_wire->power.readOp.gate_leakage) *
185010234Syasuko.eckert@amd.com            number_output_drivers_subarray * num_subarrays_per_mat * (RWP + ERP + SCHP);
185110152Satgutier@umich.edu
185210234Syasuko.eckert@amd.com        power.readOp.gate_leakage += //power_bitline.readOp.gate_leakage +
185310234Syasuko.eckert@amd.com            //power_bl_precharge_eq_drv.readOp.gate_leakage +
185410234Syasuko.eckert@amd.com            power_bl_precharge_eq_drv.searchOp.gate_leakage +
185510234Syasuko.eckert@amd.com            power_sa.readOp.gate_leakage +
185610234Syasuko.eckert@amd.com            power_subarray_out_drv.readOp.gate_leakage;
185710152Satgutier@umich.edu
185810234Syasuko.eckert@amd.com        // gate_leakage power
185910234Syasuko.eckert@amd.com        power_row_decoders.readOp.gate_leakage =
186010234Syasuko.eckert@amd.com            row_dec->power.readOp.gate_leakage * subarray.num_rows *
186110234Syasuko.eckert@amd.com            num_subarrays_per_mat * (RWP + ERP + EWP);
186210234Syasuko.eckert@amd.com        power.readOp.gate_leakage += r_predec->power.readOp.gate_leakage +
186310234Syasuko.eckert@amd.com                                     power_row_decoders.readOp.gate_leakage;
186410152Satgutier@umich.edu
186510234Syasuko.eckert@amd.com        //inside cam
186610234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.gate_leakage =
186710234Syasuko.eckert@amd.com            power_matchline.searchOp.gate_leakage;
186810234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.gate_leakage +=
186910234Syasuko.eckert@amd.com            sl_precharge_eq_drv->power.readOp.gate_leakage;
187010234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.gate_leakage +=
187110234Syasuko.eckert@amd.com            sl_data_drv->power.readOp.gate_leakage * subarray.num_cols_fa_cam;
187210234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.gate_leakage +=
187310234Syasuko.eckert@amd.com            ml_precharge_drv->power.readOp.dynamic;
187410234Syasuko.eckert@amd.com        power_cam_all_active.searchOp.gate_leakage *=
187510234Syasuko.eckert@amd.com            num_subarrays_per_mat;
187610152Satgutier@umich.edu
187710234Syasuko.eckert@amd.com        power.readOp.gate_leakage += power_cam_all_active.searchOp.gate_leakage;
187810234Syasuko.eckert@amd.com    }
187910152Satgutier@umich.edu}
188010152Satgutier@umich.edu
1881