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#include <iostream>
3710152Satgutier@umich.edu
3810152Satgutier@umich.edu#include "htree2.h"
3910152Satgutier@umich.edu#include "wire.h"
4010152Satgutier@umich.edu
4110152Satgutier@umich.eduHtree2::Htree2(
4210152Satgutier@umich.edu    enum Wire_type wire_model, double mat_w, double mat_h,
4310234Syasuko.eckert@amd.com    int a_bits, int d_inbits, int search_data_in, int d_outbits,
4410234Syasuko.eckert@amd.com    int search_data_out, int bl, int wl, enum Htree_type htree_type,
4510152Satgutier@umich.edu    bool uca_tree_, bool search_tree_, TechnologyParameter::DeviceType *dt)
4610234Syasuko.eckert@amd.com    : in_rise_time(0), out_rise_time(0),
4710234Syasuko.eckert@amd.com      tree_type(htree_type), mat_width(mat_w), mat_height(mat_h),
4810234Syasuko.eckert@amd.com      add_bits(a_bits), data_in_bits(d_inbits),
4910234Syasuko.eckert@amd.com      search_data_in_bits(search_data_in), data_out_bits(d_outbits),
5010234Syasuko.eckert@amd.com      search_data_out_bits(search_data_out), ndbl(bl), ndwl(wl),
5110234Syasuko.eckert@amd.com      uca_tree(uca_tree_), search_tree(search_tree_), wt(wire_model),
5210234Syasuko.eckert@amd.com      deviceType(dt) {
5310234Syasuko.eckert@amd.com    assert(ndbl >= 2 && ndwl >= 2);
5410152Satgutier@umich.edu
5510152Satgutier@umich.edu//  if (ndbl == 1 && ndwl == 1)
5610152Satgutier@umich.edu//  {
5710152Satgutier@umich.edu//    delay = 0;
5810152Satgutier@umich.edu//    power.readOp.dynamic = 0;
5910152Satgutier@umich.edu//    power.readOp.leakage = 0;
6010152Satgutier@umich.edu//    area.w = mat_w;
6110152Satgutier@umich.edu//    area.h = mat_h;
6210152Satgutier@umich.edu//    return;
6310152Satgutier@umich.edu//  }
6410152Satgutier@umich.edu//  if (ndwl == 1) ndwl++;
6510152Satgutier@umich.edu//  if (ndbl == 1) ndbl++;
6610152Satgutier@umich.edu
6710234Syasuko.eckert@amd.com    max_unpipelined_link_delay = 0; //TODO
6810234Syasuko.eckert@amd.com    min_w_nmos = g_tp.min_w_nmos_;
6910234Syasuko.eckert@amd.com    min_w_pmos = deviceType->n_to_p_eff_curr_drv_ratio * min_w_nmos;
7010152Satgutier@umich.edu
7110234Syasuko.eckert@amd.com    switch (htree_type) {
7210152Satgutier@umich.edu    case Add_htree:
7310234Syasuko.eckert@amd.com        wire_bw = init_wire_bw = add_bits;
7410234Syasuko.eckert@amd.com        in_htree();
7510234Syasuko.eckert@amd.com        break;
7610152Satgutier@umich.edu    case Data_in_htree:
7710234Syasuko.eckert@amd.com        wire_bw = init_wire_bw = data_in_bits;
7810234Syasuko.eckert@amd.com        in_htree();
7910234Syasuko.eckert@amd.com        break;
8010152Satgutier@umich.edu    case Data_out_htree:
8110234Syasuko.eckert@amd.com        wire_bw = init_wire_bw = data_out_bits;
8210234Syasuko.eckert@amd.com        out_htree();
8310234Syasuko.eckert@amd.com        break;
8410152Satgutier@umich.edu    case Search_in_htree:
8510234Syasuko.eckert@amd.com        wire_bw = init_wire_bw = search_data_in_bits;//in_search_tree is broad cast, out_htree is not.
8610234Syasuko.eckert@amd.com        in_htree();
8710234Syasuko.eckert@amd.com        break;
8810152Satgutier@umich.edu    case Search_out_htree:
8910234Syasuko.eckert@amd.com        wire_bw = init_wire_bw = search_data_out_bits;
9010234Syasuko.eckert@amd.com        out_htree();
9110234Syasuko.eckert@amd.com        break;
9210152Satgutier@umich.edu    default:
9310234Syasuko.eckert@amd.com        assert(0);
9410234Syasuko.eckert@amd.com        break;
9510234Syasuko.eckert@amd.com    }
9610152Satgutier@umich.edu
9710234Syasuko.eckert@amd.com    power_bit = power;
9810234Syasuko.eckert@amd.com    power.readOp.dynamic *= init_wire_bw;
9910152Satgutier@umich.edu
10010234Syasuko.eckert@amd.com    assert(power.readOp.dynamic >= 0);
10110234Syasuko.eckert@amd.com    assert(power.readOp.leakage >= 0);
10210152Satgutier@umich.edu}
10310152Satgutier@umich.edu
10410152Satgutier@umich.edu
10510152Satgutier@umich.edu
10610152Satgutier@umich.edu// nand gate sizing calculation
10710234Syasuko.eckert@amd.comvoid Htree2::input_nand(double s1, double s2, double l_eff) {
10810234Syasuko.eckert@amd.com    Wire w1(wt, l_eff);
10910234Syasuko.eckert@amd.com    double pton_size = deviceType->n_to_p_eff_curr_drv_ratio;
11010234Syasuko.eckert@amd.com    // input capacitance of a repeater  = input capacitance of nand.
11110234Syasuko.eckert@amd.com    double nsize = s1 * (1 + pton_size) / (2 + pton_size);
11210234Syasuko.eckert@amd.com    nsize = (nsize < 1) ? 1 : nsize;
11310152Satgutier@umich.edu
11410234Syasuko.eckert@amd.com    double tc = 2 * tr_R_on(nsize * min_w_nmos, NCH, 1) *
11510234Syasuko.eckert@amd.com        (drain_C_(nsize * min_w_nmos, NCH, 1, 1, g_tp.cell_h_def) * 2 +
11610234Syasuko.eckert@amd.com         2 * gate_C(s2 * (min_w_nmos + min_w_pmos), 0));
11710234Syasuko.eckert@amd.com    delay += horowitz(w1.out_rise_time, tc,
11810234Syasuko.eckert@amd.com                      deviceType->Vth / deviceType->Vdd, deviceType->Vth /
11910234Syasuko.eckert@amd.com                      deviceType->Vdd, RISE);
12010234Syasuko.eckert@amd.com    power.readOp.dynamic += 0.5 *
12110234Syasuko.eckert@amd.com        (2 * drain_C_(pton_size * nsize * min_w_pmos, PCH, 1, 1, g_tp.cell_h_def)
12210234Syasuko.eckert@amd.com         + drain_C_(nsize * min_w_nmos, NCH, 1, 1, g_tp.cell_h_def)
12310234Syasuko.eckert@amd.com         + 2 * gate_C(s2 * (min_w_nmos + min_w_pmos), 0)) *
12410234Syasuko.eckert@amd.com        deviceType->Vdd * deviceType->Vdd;
12510152Satgutier@umich.edu
12610152Satgutier@umich.edu    power.searchOp.dynamic += 0.5 *
12710234Syasuko.eckert@amd.com        (2 * drain_C_(pton_size * nsize * min_w_pmos, PCH, 1, 1, g_tp.cell_h_def)
12810234Syasuko.eckert@amd.com         + drain_C_(nsize * min_w_nmos, NCH, 1, 1, g_tp.cell_h_def)
12910234Syasuko.eckert@amd.com         + 2 * gate_C(s2 * (min_w_nmos + min_w_pmos), 0)) *
13010234Syasuko.eckert@amd.com        deviceType->Vdd * deviceType->Vdd * wire_bw ;
13110234Syasuko.eckert@amd.com    power.readOp.leakage += (wire_bw *
13210234Syasuko.eckert@amd.com                             cmos_Isub_leakage(min_w_nmos * (nsize * 2),
13310234Syasuko.eckert@amd.com                                               min_w_pmos * nsize * 2, 2,
13410234Syasuko.eckert@amd.com                                               nand)) * deviceType->Vdd;
13510234Syasuko.eckert@amd.com    power.readOp.gate_leakage += (wire_bw *
13610234Syasuko.eckert@amd.com                                  cmos_Ig_leakage(min_w_nmos * (nsize * 2),
13710234Syasuko.eckert@amd.com                                                  min_w_pmos * nsize * 2, 2,
13810234Syasuko.eckert@amd.com                                                  nand)) * deviceType->Vdd;
13910152Satgutier@umich.edu}
14010152Satgutier@umich.edu
14110152Satgutier@umich.edu
14210152Satgutier@umich.edu
14310152Satgutier@umich.edu// tristate buffer model consisting of not, nand, nor, and driver transistors
14410234Syasuko.eckert@amd.comvoid Htree2::output_buffer(double s1, double s2, double l_eff) {
14510234Syasuko.eckert@amd.com    Wire w1(wt, l_eff);
14610234Syasuko.eckert@amd.com    double pton_size = deviceType->n_to_p_eff_curr_drv_ratio;
14710234Syasuko.eckert@amd.com    // input capacitance of repeater = input capacitance of nand + nor.
14810234Syasuko.eckert@amd.com    double size = s1 * (1 + pton_size) / (2 + pton_size + 1 + 2 * pton_size);
14910234Syasuko.eckert@amd.com    double s_eff =  //stage eff of a repeater in a wire
15010234Syasuko.eckert@amd.com        (gate_C(s2 * (min_w_nmos + min_w_pmos), 0) + w1.wire_cap(l_eff * 1e-6,
15110234Syasuko.eckert@amd.com                                                                 true)) /
15210234Syasuko.eckert@amd.com        gate_C(s2 * (min_w_nmos + min_w_pmos), 0);
15310234Syasuko.eckert@amd.com    double tr_size = gate_C(s1 * (min_w_nmos + min_w_pmos), 0) * 1 / 2 /
15410234Syasuko.eckert@amd.com        (s_eff * gate_C(min_w_pmos, 0));
15510234Syasuko.eckert@amd.com    size = (size < 1) ? 1 : size;
15610152Satgutier@umich.edu
15710234Syasuko.eckert@amd.com    double res_nor = 2 * tr_R_on(size * min_w_pmos, PCH, 1);
15810234Syasuko.eckert@amd.com    double res_ptrans = tr_R_on(tr_size * min_w_nmos, NCH, 1);
15910234Syasuko.eckert@amd.com    double cap_nand_out =
16010234Syasuko.eckert@amd.com        drain_C_(size * min_w_nmos, NCH, 1, 1, g_tp.cell_h_def) +
16110234Syasuko.eckert@amd.com        drain_C_(size * min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) * 2 +
16210234Syasuko.eckert@amd.com        gate_C(tr_size * min_w_pmos, 0);
16310234Syasuko.eckert@amd.com    double cap_ptrans_out = 2 *
16410234Syasuko.eckert@amd.com        (drain_C_(tr_size * min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) +
16510234Syasuko.eckert@amd.com         drain_C_(tr_size * min_w_nmos, NCH, 1, 1, g_tp.cell_h_def)) +
16610234Syasuko.eckert@amd.com        gate_C(s1 * (min_w_nmos + min_w_pmos), 0);
16710152Satgutier@umich.edu
16810234Syasuko.eckert@amd.com    double tc = res_nor * cap_nand_out + (res_nor + res_ptrans) * cap_ptrans_out;
16910152Satgutier@umich.edu
17010152Satgutier@umich.edu
17110234Syasuko.eckert@amd.com    delay += horowitz(w1.out_rise_time, tc,
17210234Syasuko.eckert@amd.com                      deviceType->Vth / deviceType->Vdd, deviceType->Vth /
17310234Syasuko.eckert@amd.com                      deviceType->Vdd, RISE);
17410152Satgutier@umich.edu
17510234Syasuko.eckert@amd.com    //nand
17610234Syasuko.eckert@amd.com    power.readOp.dynamic += 0.5 *
17710234Syasuko.eckert@amd.com        (2 * drain_C_(size * min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) +
17810234Syasuko.eckert@amd.com         drain_C_(size * min_w_nmos, NCH, 1, 1, g_tp.cell_h_def) +
17910234Syasuko.eckert@amd.com         gate_C(tr_size * (min_w_pmos), 0)) *
18010234Syasuko.eckert@amd.com        deviceType->Vdd * deviceType->Vdd;
18110152Satgutier@umich.edu
18210152Satgutier@umich.edu    power.searchOp.dynamic += 0.5 *
18310234Syasuko.eckert@amd.com        (2 * drain_C_(size * min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) +
18410234Syasuko.eckert@amd.com         drain_C_(size * min_w_nmos, NCH, 1, 1, g_tp.cell_h_def) +
18510234Syasuko.eckert@amd.com         gate_C(tr_size * (min_w_pmos), 0)) *
18610234Syasuko.eckert@amd.com        deviceType->Vdd * deviceType->Vdd * init_wire_bw;
18710152Satgutier@umich.edu
18810234Syasuko.eckert@amd.com    //not
18910234Syasuko.eckert@amd.com    power.readOp.dynamic += 0.5 *
19010234Syasuko.eckert@amd.com        (drain_C_(size * min_w_pmos, PCH, 1, 1, g_tp.cell_h_def)
19110234Syasuko.eckert@amd.com         + drain_C_(size * min_w_nmos, NCH, 1, 1, g_tp.cell_h_def)
19210234Syasuko.eckert@amd.com         + gate_C(size * (min_w_nmos + min_w_pmos), 0)) *
19310234Syasuko.eckert@amd.com        deviceType->Vdd * deviceType->Vdd;
19410152Satgutier@umich.edu
19510152Satgutier@umich.edu    power.searchOp.dynamic += 0.5 *
19610234Syasuko.eckert@amd.com        (drain_C_(size * min_w_pmos, PCH, 1, 1, g_tp.cell_h_def)
19710234Syasuko.eckert@amd.com         + drain_C_(size * min_w_nmos, NCH, 1, 1, g_tp.cell_h_def)
19810234Syasuko.eckert@amd.com         + gate_C(size * (min_w_nmos + min_w_pmos), 0)) *
19910234Syasuko.eckert@amd.com        deviceType->Vdd * deviceType->Vdd * init_wire_bw;
20010152Satgutier@umich.edu
20110234Syasuko.eckert@amd.com    //nor
20210234Syasuko.eckert@amd.com    power.readOp.dynamic += 0.5 *
20310234Syasuko.eckert@amd.com        (drain_C_(size * min_w_pmos, PCH, 1, 1, g_tp.cell_h_def)
20410234Syasuko.eckert@amd.com         + 2 * drain_C_(size * min_w_nmos, NCH, 1, 1, g_tp.cell_h_def)
20510234Syasuko.eckert@amd.com         + gate_C(tr_size * (min_w_nmos + min_w_pmos), 0)) *
20610234Syasuko.eckert@amd.com        deviceType->Vdd * deviceType->Vdd;
20710152Satgutier@umich.edu
20810152Satgutier@umich.edu    power.searchOp.dynamic += 0.5 *
20910234Syasuko.eckert@amd.com        (drain_C_(size * min_w_pmos, PCH, 1, 1, g_tp.cell_h_def)
21010234Syasuko.eckert@amd.com         + 2 * drain_C_(size * min_w_nmos, NCH, 1, 1, g_tp.cell_h_def)
21110234Syasuko.eckert@amd.com         + gate_C(tr_size * (min_w_nmos + min_w_pmos), 0)) *
21210234Syasuko.eckert@amd.com        deviceType->Vdd * deviceType->Vdd * init_wire_bw;
21310152Satgutier@umich.edu
21410234Syasuko.eckert@amd.com    //output transistor
21510234Syasuko.eckert@amd.com    power.readOp.dynamic += 0.5 *
21610234Syasuko.eckert@amd.com        ((drain_C_(tr_size * min_w_pmos, PCH, 1, 1, g_tp.cell_h_def)
21710234Syasuko.eckert@amd.com          + drain_C_(tr_size * min_w_nmos, NCH, 1, 1, g_tp.cell_h_def)) * 2
21810234Syasuko.eckert@amd.com         + gate_C(s1 * (min_w_nmos + min_w_pmos), 0)) *
21910234Syasuko.eckert@amd.com        deviceType->Vdd * deviceType->Vdd;
22010152Satgutier@umich.edu
22110152Satgutier@umich.edu    power.searchOp.dynamic += 0.5 *
22210234Syasuko.eckert@amd.com        ((drain_C_(tr_size * min_w_pmos, PCH, 1, 1, g_tp.cell_h_def)
22310234Syasuko.eckert@amd.com          + drain_C_(tr_size * min_w_nmos, NCH, 1, 1, g_tp.cell_h_def)) * 2
22410234Syasuko.eckert@amd.com         + gate_C(s1 * (min_w_nmos + min_w_pmos), 0)) *
22510234Syasuko.eckert@amd.com        deviceType->Vdd * deviceType->Vdd * init_wire_bw;
22610152Satgutier@umich.edu
22710234Syasuko.eckert@amd.com    if (uca_tree) {
22810234Syasuko.eckert@amd.com        power.readOp.leakage +=
22910234Syasuko.eckert@amd.com            cmos_Isub_leakage(min_w_nmos * tr_size * 2, min_w_pmos * tr_size *
23010234Syasuko.eckert@amd.com                              2, 1, inv) *
23110234Syasuko.eckert@amd.com            deviceType->Vdd * wire_bw;/*inverter + output tr*/
23210234Syasuko.eckert@amd.com        power.readOp.leakage +=
23310234Syasuko.eckert@amd.com            cmos_Isub_leakage(min_w_nmos * size * 3, min_w_pmos * size * 3, 2,
23410234Syasuko.eckert@amd.com                              nand) * deviceType->Vdd * wire_bw;//nand
23510234Syasuko.eckert@amd.com        power.readOp.leakage +=
23610234Syasuko.eckert@amd.com            cmos_Isub_leakage(min_w_nmos * size * 3, min_w_pmos * size * 3, 2,
23710234Syasuko.eckert@amd.com                              nor) * deviceType->Vdd * wire_bw;//nor
23810152Satgutier@umich.edu
23910234Syasuko.eckert@amd.com        power.readOp.gate_leakage +=
24010234Syasuko.eckert@amd.com            cmos_Ig_leakage(min_w_nmos * tr_size * 2, min_w_pmos * tr_size * 2,
24110234Syasuko.eckert@amd.com                            1, inv) *
24210234Syasuko.eckert@amd.com            deviceType->Vdd * wire_bw;/*inverter + output tr*/
24310234Syasuko.eckert@amd.com        power.readOp.gate_leakage +=
24410234Syasuko.eckert@amd.com            cmos_Ig_leakage(min_w_nmos * size * 3, min_w_pmos * size * 3, 2,
24510234Syasuko.eckert@amd.com                            nand) * deviceType->Vdd * wire_bw;//nand
24610234Syasuko.eckert@amd.com        power.readOp.gate_leakage +=
24710234Syasuko.eckert@amd.com            cmos_Ig_leakage(min_w_nmos * size * 3, min_w_pmos * size * 3, 2,
24810234Syasuko.eckert@amd.com                            nor) * deviceType->Vdd * wire_bw;//nor
24910234Syasuko.eckert@amd.com    } else {
25010234Syasuko.eckert@amd.com        power.readOp.leakage +=
25110234Syasuko.eckert@amd.com            cmos_Isub_leakage(min_w_nmos * tr_size * 2, min_w_pmos * tr_size *
25210234Syasuko.eckert@amd.com                              2, 1, inv) *
25310234Syasuko.eckert@amd.com            deviceType->Vdd * wire_bw;/*inverter + output tr*/
25410234Syasuko.eckert@amd.com        power.readOp.leakage +=
25510234Syasuko.eckert@amd.com            cmos_Isub_leakage(min_w_nmos * size * 3, min_w_pmos * size * 3, 2,
25610234Syasuko.eckert@amd.com                              nand) * deviceType->Vdd * wire_bw;//nand
25710234Syasuko.eckert@amd.com        power.readOp.leakage +=
25810234Syasuko.eckert@amd.com            cmos_Isub_leakage(min_w_nmos * size * 3, min_w_pmos * size * 3, 2,
25910234Syasuko.eckert@amd.com                              nor) * deviceType->Vdd * wire_bw;//nor
26010152Satgutier@umich.edu
26110234Syasuko.eckert@amd.com        power.readOp.gate_leakage +=
26210234Syasuko.eckert@amd.com            cmos_Ig_leakage(min_w_nmos * tr_size * 2, min_w_pmos * tr_size * 2,
26310234Syasuko.eckert@amd.com                            1, inv) *
26410234Syasuko.eckert@amd.com            deviceType->Vdd * wire_bw;/*inverter + output tr*/
26510234Syasuko.eckert@amd.com        power.readOp.gate_leakage +=
26610234Syasuko.eckert@amd.com            cmos_Ig_leakage(min_w_nmos * size * 3, min_w_pmos * size * 3, 2,
26710234Syasuko.eckert@amd.com                            nand) * deviceType->Vdd * wire_bw;//nand
26810234Syasuko.eckert@amd.com        power.readOp.gate_leakage +=
26910234Syasuko.eckert@amd.com            cmos_Ig_leakage(min_w_nmos * size * 3, min_w_pmos * size * 3, 2,
27010234Syasuko.eckert@amd.com                            nor) * deviceType->Vdd * wire_bw;//nor
27110234Syasuko.eckert@amd.com    }
27210152Satgutier@umich.edu}
27310152Satgutier@umich.edu
27410152Satgutier@umich.edu
27510152Satgutier@umich.edu
27610152Satgutier@umich.edu/* calculates the input h-tree delay/power
27710152Satgutier@umich.edu * A nand gate is used at each node to
27810152Satgutier@umich.edu * limit the signal
27910152Satgutier@umich.edu * The area of an unbalanced htree (rows != columns)
28010152Satgutier@umich.edu * depends on how data is traversed.
28110152Satgutier@umich.edu * In the following function, if ( no. of rows < no. of columns),
28210152Satgutier@umich.edu * then data first traverse in excess hor. links until vertical
28310152Satgutier@umich.edu * and horizontal nodes are same.
28410152Satgutier@umich.edu * If no. of rows is bigger, then data traverse in
28510152Satgutier@umich.edu * a hor. link followed by a ver. link in a repeated
28610152Satgutier@umich.edu * fashion (similar to a balanced tree) until there are no
28710152Satgutier@umich.edu * hor. links left. After this it goes through the remaining vertical
28810152Satgutier@umich.edu * links.
28910152Satgutier@umich.edu */
29010234Syasuko.eckert@amd.comvoid
29110234Syasuko.eckert@amd.comHtree2::in_htree() {
29210234Syasuko.eckert@amd.com    //temp var
29310234Syasuko.eckert@amd.com    double s1 = 0, s2 = 0, s3 = 0;
29410234Syasuko.eckert@amd.com    double l_eff = 0;
29510234Syasuko.eckert@amd.com    Wire *wtemp1 = 0, *wtemp2 = 0, *wtemp3 = 0;
29610234Syasuko.eckert@amd.com    double len = 0, ht = 0;
29710234Syasuko.eckert@amd.com    int option = 0;
29810152Satgutier@umich.edu
29910234Syasuko.eckert@amd.com    int h = (int) _log2(ndwl / 2); // horizontal nodes
30010234Syasuko.eckert@amd.com    int v = (int) _log2(ndbl / 2); // vertical nodes
30110234Syasuko.eckert@amd.com    double len_temp;
30210234Syasuko.eckert@amd.com    double ht_temp;
30310234Syasuko.eckert@amd.com    if (uca_tree) {
30410234Syasuko.eckert@amd.com        //Sheng: this computation do not consider the wires that route from
30510234Syasuko.eckert@amd.com        //edge to middle.
30610234Syasuko.eckert@amd.com        ht_temp = (mat_height * ndbl / 2 +
30710234Syasuko.eckert@amd.com                   /* since uca_tree models interbank tree,
30810234Syasuko.eckert@amd.com                      mat_height => bank height */
30910234Syasuko.eckert@amd.com                   ((add_bits + data_in_bits + data_out_bits +
31010234Syasuko.eckert@amd.com                     (search_data_in_bits + search_data_out_bits)) *
31110234Syasuko.eckert@amd.com                    g_tp.wire_outside_mat.pitch *
31210234Syasuko.eckert@amd.com                    2 * (1 - pow(0.5, h)))) / 2;
31310234Syasuko.eckert@amd.com        len_temp = (mat_width * ndwl / 2 +
31410234Syasuko.eckert@amd.com                    ((add_bits + data_in_bits + data_out_bits +
31510234Syasuko.eckert@amd.com                      (search_data_in_bits + search_data_out_bits)) *
31610234Syasuko.eckert@amd.com                     g_tp.wire_outside_mat.pitch *
31710234Syasuko.eckert@amd.com                     2 * (1 - pow(0.5, v)))) / 2;
31810234Syasuko.eckert@amd.com    } else {
31910234Syasuko.eckert@amd.com        if (ndwl == ndbl) {
32010234Syasuko.eckert@amd.com            ht_temp = ((mat_height * ndbl / 2) +
32110234Syasuko.eckert@amd.com                       ((add_bits + (search_data_in_bits +
32210234Syasuko.eckert@amd.com                                     search_data_out_bits)) * (ndbl / 2 - 1) *
32310234Syasuko.eckert@amd.com                        g_tp.wire_outside_mat.pitch) +
32410234Syasuko.eckert@amd.com                       ((data_in_bits + data_out_bits) *
32510234Syasuko.eckert@amd.com                        g_tp.wire_outside_mat.pitch * h)
32610234Syasuko.eckert@amd.com                      ) / 2;
32710234Syasuko.eckert@amd.com            len_temp = (mat_width * ndwl / 2 +
32810234Syasuko.eckert@amd.com                        ((add_bits + (search_data_in_bits +
32910234Syasuko.eckert@amd.com                                      search_data_out_bits)) * (ndwl / 2 - 1) *
33010234Syasuko.eckert@amd.com                         g_tp.wire_outside_mat.pitch) +
33110234Syasuko.eckert@amd.com                        ((data_in_bits + data_out_bits) *
33210234Syasuko.eckert@amd.com                         g_tp.wire_outside_mat.pitch * v)) / 2;
33310234Syasuko.eckert@amd.com        } else if (ndwl > ndbl) {
33410234Syasuko.eckert@amd.com            double excess_part = (_log2(ndwl / 2) - _log2(ndbl / 2));
33510234Syasuko.eckert@amd.com            ht_temp = ((mat_height * ndbl / 2) +
33610234Syasuko.eckert@amd.com                       ((add_bits + + (search_data_in_bits +
33710234Syasuko.eckert@amd.com                                       search_data_out_bits)) *
33810234Syasuko.eckert@amd.com                        ((ndbl / 2 - 1) + excess_part) *
33910234Syasuko.eckert@amd.com                        g_tp.wire_outside_mat.pitch) +
34010234Syasuko.eckert@amd.com                       (data_in_bits + data_out_bits) *
34110234Syasuko.eckert@amd.com                       g_tp.wire_outside_mat.pitch *
34210234Syasuko.eckert@amd.com                       (2 * (1 - pow(0.5, h - v)) + pow(0.5, v - h) * v)) / 2;
34310234Syasuko.eckert@amd.com            len_temp = (mat_width * ndwl / 2 +
34410234Syasuko.eckert@amd.com                        ((add_bits +
34510234Syasuko.eckert@amd.com                          (search_data_in_bits + search_data_out_bits)) *
34610234Syasuko.eckert@amd.com                         (ndwl / 2 - 1) * g_tp.wire_outside_mat.pitch) +
34710234Syasuko.eckert@amd.com                        ((data_in_bits + data_out_bits) *
34810234Syasuko.eckert@amd.com                         g_tp.wire_outside_mat.pitch * v)) / 2;
34910234Syasuko.eckert@amd.com        } else {
35010234Syasuko.eckert@amd.com            double excess_part = (_log2(ndbl / 2) - _log2(ndwl / 2));
35110234Syasuko.eckert@amd.com            ht_temp = ((mat_height * ndbl / 2) +
35210234Syasuko.eckert@amd.com                       ((add_bits +
35310234Syasuko.eckert@amd.com                         (search_data_in_bits + search_data_out_bits)) *
35410234Syasuko.eckert@amd.com                        ((ndwl / 2 - 1) + excess_part) *
35510234Syasuko.eckert@amd.com                        g_tp.wire_outside_mat.pitch) +
35610234Syasuko.eckert@amd.com                       ((data_in_bits + data_out_bits) *
35710234Syasuko.eckert@amd.com                        g_tp.wire_outside_mat.pitch * h)
35810234Syasuko.eckert@amd.com                      ) / 2;
35910234Syasuko.eckert@amd.com            len_temp = (mat_width * ndwl / 2 +
36010234Syasuko.eckert@amd.com                        ((add_bits +
36110234Syasuko.eckert@amd.com                          (search_data_in_bits + search_data_out_bits)) *
36210234Syasuko.eckert@amd.com                         ((ndwl / 2 - 1) + excess_part) *
36310234Syasuko.eckert@amd.com                         g_tp.wire_outside_mat.pitch) +
36410234Syasuko.eckert@amd.com                        (data_in_bits + data_out_bits) *
36510234Syasuko.eckert@amd.com                        g_tp.wire_outside_mat.pitch *
36610234Syasuko.eckert@amd.com                        (h + 2 * (1 - pow(0.5, v - h)))) / 2;
36710234Syasuko.eckert@amd.com        }
36810152Satgutier@umich.edu    }
36910234Syasuko.eckert@amd.com
37010234Syasuko.eckert@amd.com    area.h   = ht_temp * 2;
37110234Syasuko.eckert@amd.com    area.w   = len_temp * 2;
37210234Syasuko.eckert@amd.com    delay = 0;
37310234Syasuko.eckert@amd.com    power.readOp.dynamic = 0;
37410234Syasuko.eckert@amd.com    power.readOp.leakage = 0;
37510234Syasuko.eckert@amd.com    power.searchOp.dynamic = 0;
37610234Syasuko.eckert@amd.com    len = len_temp;
37710234Syasuko.eckert@amd.com    ht  = ht_temp / 2;
37810234Syasuko.eckert@amd.com
37910234Syasuko.eckert@amd.com    while (v > 0 || h > 0) {
38010234Syasuko.eckert@amd.com        if (wtemp1) delete wtemp1;
38110234Syasuko.eckert@amd.com        if (wtemp2) delete wtemp2;
38210234Syasuko.eckert@amd.com        if (wtemp3) delete wtemp3;
38310234Syasuko.eckert@amd.com
38410234Syasuko.eckert@amd.com        if (h > v) {
38510234Syasuko.eckert@amd.com            //the iteration considers only one horizontal link
38610234Syasuko.eckert@amd.com            wtemp1 = new Wire(wt, len); // hor
38710234Syasuko.eckert@amd.com            wtemp2 = new Wire(wt, len / 2);  // ver
38810234Syasuko.eckert@amd.com            len_temp = len;
38910234Syasuko.eckert@amd.com            len /= 2;
39010234Syasuko.eckert@amd.com            wtemp3 = 0;
39110234Syasuko.eckert@amd.com            h--;
39210234Syasuko.eckert@amd.com            option = 0;
39310234Syasuko.eckert@amd.com        } else if (v > 0 && h > 0) {
39410234Syasuko.eckert@amd.com            //considers one horizontal link and one vertical link
39510234Syasuko.eckert@amd.com            wtemp1 = new Wire(wt, len); // hor
39610234Syasuko.eckert@amd.com            wtemp2 = new Wire(wt, ht);  // ver
39710234Syasuko.eckert@amd.com            wtemp3 = new Wire(wt, len / 2);  // next hor
39810234Syasuko.eckert@amd.com            len_temp = len;
39910234Syasuko.eckert@amd.com            ht_temp = ht;
40010234Syasuko.eckert@amd.com            len /= 2;
40110234Syasuko.eckert@amd.com            ht  /= 2;
40210234Syasuko.eckert@amd.com            v--;
40310234Syasuko.eckert@amd.com            h--;
40410234Syasuko.eckert@amd.com            option = 1;
40510234Syasuko.eckert@amd.com        } else {
40610234Syasuko.eckert@amd.com            // considers only one vertical link
40710234Syasuko.eckert@amd.com            assert(h == 0);
40810234Syasuko.eckert@amd.com            wtemp1 = new Wire(wt, ht); // ver
40910234Syasuko.eckert@amd.com            wtemp2 = new Wire(wt, ht / 2);  // hor
41010234Syasuko.eckert@amd.com            ht_temp = ht;
41110234Syasuko.eckert@amd.com            ht /= 2;
41210234Syasuko.eckert@amd.com            wtemp3 = 0;
41310234Syasuko.eckert@amd.com            v--;
41410234Syasuko.eckert@amd.com            option = 2;
41510234Syasuko.eckert@amd.com        }
41610234Syasuko.eckert@amd.com
41710234Syasuko.eckert@amd.com        delay += wtemp1->delay;
41810234Syasuko.eckert@amd.com        power.readOp.dynamic += wtemp1->power.readOp.dynamic;
41910234Syasuko.eckert@amd.com        power.searchOp.dynamic += wtemp1->power.readOp.dynamic * wire_bw;
42010234Syasuko.eckert@amd.com        power.readOp.leakage += wtemp1->power.readOp.leakage * wire_bw;
42110234Syasuko.eckert@amd.com        power.readOp.gate_leakage += wtemp1->power.readOp.gate_leakage * wire_bw;
42210234Syasuko.eckert@amd.com        if ((uca_tree == false && option == 2) || search_tree == true) {
42310234Syasuko.eckert@amd.com            wire_bw *= 2;  // wire bandwidth doubles only for vertical branches
42410234Syasuko.eckert@amd.com        }
42510234Syasuko.eckert@amd.com
42610234Syasuko.eckert@amd.com        if (uca_tree == false) {
42710234Syasuko.eckert@amd.com            if (len_temp > wtemp1->repeater_spacing) {
42810234Syasuko.eckert@amd.com                s1 = wtemp1->repeater_size;
42910234Syasuko.eckert@amd.com                l_eff = wtemp1->repeater_spacing;
43010234Syasuko.eckert@amd.com            } else {
43110234Syasuko.eckert@amd.com                s1 = (len_temp / wtemp1->repeater_spacing) *
43210234Syasuko.eckert@amd.com                    wtemp1->repeater_size;
43310234Syasuko.eckert@amd.com                l_eff = len_temp;
43410234Syasuko.eckert@amd.com            }
43510234Syasuko.eckert@amd.com
43610234Syasuko.eckert@amd.com            if (ht_temp > wtemp2->repeater_spacing) {
43710234Syasuko.eckert@amd.com                s2 = wtemp2->repeater_size;
43810234Syasuko.eckert@amd.com            } else {
43910234Syasuko.eckert@amd.com                s2 = (len_temp / wtemp2->repeater_spacing) *
44010234Syasuko.eckert@amd.com                    wtemp2->repeater_size;
44110234Syasuko.eckert@amd.com            }
44210234Syasuko.eckert@amd.com            // first level
44310234Syasuko.eckert@amd.com            input_nand(s1, s2, l_eff);
44410234Syasuko.eckert@amd.com        }
44510234Syasuko.eckert@amd.com
44610234Syasuko.eckert@amd.com
44710234Syasuko.eckert@amd.com        if (option != 1) {
44810234Syasuko.eckert@amd.com            continue;
44910234Syasuko.eckert@amd.com        }
45010234Syasuko.eckert@amd.com
45110234Syasuko.eckert@amd.com        // second level
45210234Syasuko.eckert@amd.com        delay += wtemp2->delay;
45310234Syasuko.eckert@amd.com        power.readOp.dynamic += wtemp2->power.readOp.dynamic;
45410234Syasuko.eckert@amd.com        power.searchOp.dynamic += wtemp2->power.readOp.dynamic * wire_bw;
45510234Syasuko.eckert@amd.com        power.readOp.leakage += wtemp2->power.readOp.leakage * wire_bw;
45610234Syasuko.eckert@amd.com        power.readOp.gate_leakage += wtemp2->power.readOp.gate_leakage * wire_bw;
45710234Syasuko.eckert@amd.com
45810234Syasuko.eckert@amd.com        if (uca_tree) {
45910234Syasuko.eckert@amd.com            power.readOp.leakage += (wtemp2->power.readOp.leakage * wire_bw);
46010234Syasuko.eckert@amd.com            power.readOp.gate_leakage +=
46110234Syasuko.eckert@amd.com                wtemp2->power.readOp.gate_leakage * wire_bw;
46210234Syasuko.eckert@amd.com        } else {
46310234Syasuko.eckert@amd.com            power.readOp.leakage += (wtemp2->power.readOp.leakage * wire_bw);
46410234Syasuko.eckert@amd.com            power.readOp.gate_leakage +=
46510234Syasuko.eckert@amd.com                wtemp2->power.readOp.gate_leakage * wire_bw;
46610234Syasuko.eckert@amd.com            wire_bw *= 2;
46710234Syasuko.eckert@amd.com
46810234Syasuko.eckert@amd.com            if (ht_temp > wtemp3->repeater_spacing) {
46910234Syasuko.eckert@amd.com                s3    = wtemp3->repeater_size;
47010234Syasuko.eckert@amd.com                l_eff = wtemp3->repeater_spacing;
47110234Syasuko.eckert@amd.com            } else {
47210234Syasuko.eckert@amd.com                s3 = (len_temp / wtemp3->repeater_spacing) *
47310234Syasuko.eckert@amd.com                    wtemp3->repeater_size;
47410234Syasuko.eckert@amd.com                l_eff = ht_temp;
47510234Syasuko.eckert@amd.com            }
47610234Syasuko.eckert@amd.com
47710234Syasuko.eckert@amd.com            input_nand(s2, s3, l_eff);
47810234Syasuko.eckert@amd.com        }
47910152Satgutier@umich.edu    }
48010152Satgutier@umich.edu
48110152Satgutier@umich.edu    if (wtemp1) delete wtemp1;
48210152Satgutier@umich.edu    if (wtemp2) delete wtemp2;
48310152Satgutier@umich.edu    if (wtemp3) delete wtemp3;
48410152Satgutier@umich.edu}
48510152Satgutier@umich.edu
48610152Satgutier@umich.edu
48710152Satgutier@umich.edu
48810152Satgutier@umich.edu/* a tristate buffer is used to handle fan-ins
48910152Satgutier@umich.edu * The area of an unbalanced htree (rows != columns)
49010152Satgutier@umich.edu * depends on how data is traversed.
49110152Satgutier@umich.edu * In the following function, if ( no. of rows < no. of columns),
49210152Satgutier@umich.edu * then data first traverse in excess hor. links until vertical
49310152Satgutier@umich.edu * and horizontal nodes are same.
49410152Satgutier@umich.edu * If no. of rows is bigger, then data traverse in
49510152Satgutier@umich.edu * a hor. link followed by a ver. link in a repeated
49610152Satgutier@umich.edu * fashion (similar to a balanced tree) until there are no
49710152Satgutier@umich.edu * hor. links left. After this it goes through the remaining vertical
49810152Satgutier@umich.edu * links.
49910152Satgutier@umich.edu */
50010234Syasuko.eckert@amd.comvoid Htree2::out_htree() {
50110234Syasuko.eckert@amd.com    //temp var
50210234Syasuko.eckert@amd.com    double s1 = 0, s2 = 0, s3 = 0;
50310234Syasuko.eckert@amd.com    double l_eff = 0;
50410234Syasuko.eckert@amd.com    Wire *wtemp1 = 0, *wtemp2 = 0, *wtemp3 = 0;
50510234Syasuko.eckert@amd.com    double len = 0, ht = 0;
50610234Syasuko.eckert@amd.com    int option = 0;
50710152Satgutier@umich.edu
50810234Syasuko.eckert@amd.com    int h = (int) _log2(ndwl / 2);
50910234Syasuko.eckert@amd.com    int v = (int) _log2(ndbl / 2);
51010234Syasuko.eckert@amd.com    double len_temp;
51110234Syasuko.eckert@amd.com    double ht_temp;
51210234Syasuko.eckert@amd.com    if (uca_tree) {
51310234Syasuko.eckert@amd.com        ht_temp = (mat_height * ndbl / 2 +
51410234Syasuko.eckert@amd.com                   /* since uca_tree models interbank tree,
51510234Syasuko.eckert@amd.com                      mat_height => bank height */
51610234Syasuko.eckert@amd.com                   ((add_bits + data_in_bits + data_out_bits +
51710234Syasuko.eckert@amd.com                     (search_data_in_bits + search_data_out_bits)) *
51810234Syasuko.eckert@amd.com                    g_tp.wire_outside_mat.pitch *
51910234Syasuko.eckert@amd.com                    2 * (1 - pow(0.5, h)))) / 2;
52010234Syasuko.eckert@amd.com        len_temp = (mat_width * ndwl / 2 +
52110234Syasuko.eckert@amd.com                    ((add_bits + data_in_bits + data_out_bits +
52210234Syasuko.eckert@amd.com                      (search_data_in_bits + search_data_out_bits)) *
52310234Syasuko.eckert@amd.com                     g_tp.wire_outside_mat.pitch *
52410234Syasuko.eckert@amd.com                     2 * (1 - pow(0.5, v)))) / 2;
52510234Syasuko.eckert@amd.com    } else {
52610234Syasuko.eckert@amd.com        if (ndwl == ndbl) {
52710234Syasuko.eckert@amd.com            ht_temp = ((mat_height * ndbl / 2) +
52810234Syasuko.eckert@amd.com                       ((add_bits + (search_data_in_bits +
52910234Syasuko.eckert@amd.com                                     search_data_out_bits)) *
53010234Syasuko.eckert@amd.com                        (ndbl / 2 - 1) * g_tp.wire_outside_mat.pitch) +
53110234Syasuko.eckert@amd.com                       ((data_in_bits + data_out_bits) *
53210234Syasuko.eckert@amd.com                        g_tp.wire_outside_mat.pitch * h)
53310234Syasuko.eckert@amd.com                ) / 2;
53410234Syasuko.eckert@amd.com            len_temp = (mat_width * ndwl / 2 +
53510234Syasuko.eckert@amd.com                        ((add_bits + (search_data_in_bits +
53610234Syasuko.eckert@amd.com                                      search_data_out_bits)) * (ndwl / 2 - 1) *
53710234Syasuko.eckert@amd.com                         g_tp.wire_outside_mat.pitch) +
53810234Syasuko.eckert@amd.com                        ((data_in_bits + data_out_bits) *
53910234Syasuko.eckert@amd.com                         g_tp.wire_outside_mat.pitch * v)) / 2;
54010152Satgutier@umich.edu
54110234Syasuko.eckert@amd.com        } else if (ndwl > ndbl) {
54210234Syasuko.eckert@amd.com            double excess_part = (_log2(ndwl / 2) - _log2(ndbl / 2));
54310234Syasuko.eckert@amd.com            ht_temp = ((mat_height * ndbl / 2) +
54410234Syasuko.eckert@amd.com                       ((add_bits +
54510234Syasuko.eckert@amd.com                         (search_data_in_bits + search_data_out_bits)) *
54610234Syasuko.eckert@amd.com                        ((ndbl / 2 - 1) + excess_part) *
54710234Syasuko.eckert@amd.com                        g_tp.wire_outside_mat.pitch) +
54810234Syasuko.eckert@amd.com                       (data_in_bits + data_out_bits) *
54910234Syasuko.eckert@amd.com                       g_tp.wire_outside_mat.pitch *
55010234Syasuko.eckert@amd.com                       (2 * (1 - pow(0.5, h - v)) + pow(0.5, v - h) * v)) / 2;
55110234Syasuko.eckert@amd.com            len_temp = (mat_width * ndwl / 2 +
55210234Syasuko.eckert@amd.com                        ((add_bits +
55310234Syasuko.eckert@amd.com                          (search_data_in_bits + search_data_out_bits)) *
55410234Syasuko.eckert@amd.com                         (ndwl / 2 - 1) * g_tp.wire_outside_mat.pitch) +
55510234Syasuko.eckert@amd.com                        ((data_in_bits + data_out_bits) *
55610234Syasuko.eckert@amd.com                         g_tp.wire_outside_mat.pitch * v)) / 2;
55710234Syasuko.eckert@amd.com        } else {
55810234Syasuko.eckert@amd.com            double excess_part = (_log2(ndbl / 2) - _log2(ndwl / 2));
55910234Syasuko.eckert@amd.com            ht_temp = ((mat_height * ndbl / 2) +
56010234Syasuko.eckert@amd.com                       ((add_bits +
56110234Syasuko.eckert@amd.com                         (search_data_in_bits + search_data_out_bits)) *
56210234Syasuko.eckert@amd.com                        ((ndwl / 2 - 1) + excess_part) *
56310234Syasuko.eckert@amd.com                        g_tp.wire_outside_mat.pitch) +
56410234Syasuko.eckert@amd.com                       ((data_in_bits + data_out_bits) *
56510234Syasuko.eckert@amd.com                        g_tp.wire_outside_mat.pitch * h)
56610234Syasuko.eckert@amd.com                      ) / 2;
56710234Syasuko.eckert@amd.com            len_temp = (mat_width * ndwl / 2 +
56810234Syasuko.eckert@amd.com                        ((add_bits + (search_data_in_bits +
56910234Syasuko.eckert@amd.com                                      search_data_out_bits)) *
57010234Syasuko.eckert@amd.com                         ((ndwl / 2 - 1) + excess_part) *
57110234Syasuko.eckert@amd.com                         g_tp.wire_outside_mat.pitch) +
57210234Syasuko.eckert@amd.com                        (data_in_bits + data_out_bits) *
57310234Syasuko.eckert@amd.com                        g_tp.wire_outside_mat.pitch *
57410234Syasuko.eckert@amd.com                        (h + 2 * (1 - pow(0.5, v - h)))) / 2;
57510234Syasuko.eckert@amd.com        }
57610152Satgutier@umich.edu    }
57710234Syasuko.eckert@amd.com    area.h = ht_temp * 2;
57810234Syasuko.eckert@amd.com    area.w = len_temp * 2;
57910234Syasuko.eckert@amd.com    delay = 0;
58010234Syasuko.eckert@amd.com    power.readOp.dynamic = 0;
58110234Syasuko.eckert@amd.com    power.readOp.leakage = 0;
58210234Syasuko.eckert@amd.com    power.readOp.gate_leakage = 0;
58310234Syasuko.eckert@amd.com    //cout<<"power.readOp.gate_leakage"<<power.readOp.gate_leakage<<endl;
58410234Syasuko.eckert@amd.com    len = len_temp;
58510234Syasuko.eckert@amd.com    ht = ht_temp / 2;
58610234Syasuko.eckert@amd.com
58710234Syasuko.eckert@amd.com    while (v > 0 || h > 0) { //finds delay/power of each link in the tree
58810234Syasuko.eckert@amd.com        if (wtemp1) delete wtemp1;
58910234Syasuko.eckert@amd.com        if (wtemp2) delete wtemp2;
59010234Syasuko.eckert@amd.com        if (wtemp3) delete wtemp3;
59110234Syasuko.eckert@amd.com
59210234Syasuko.eckert@amd.com        if (h > v) {
59310234Syasuko.eckert@amd.com            //the iteration considers only one horizontal link
59410234Syasuko.eckert@amd.com            wtemp1 = new Wire(wt, len); // hor
59510234Syasuko.eckert@amd.com            wtemp2 = new Wire(wt, len / 2);  // ver
59610234Syasuko.eckert@amd.com            len_temp = len;
59710234Syasuko.eckert@amd.com            len /= 2;
59810234Syasuko.eckert@amd.com            wtemp3 = 0;
59910234Syasuko.eckert@amd.com            h--;
60010234Syasuko.eckert@amd.com            option = 0;
60110234Syasuko.eckert@amd.com        } else if (v > 0 && h > 0) {
60210234Syasuko.eckert@amd.com            //considers one horizontal link and one vertical link
60310234Syasuko.eckert@amd.com            wtemp1 = new Wire(wt, len); // hor
60410234Syasuko.eckert@amd.com            wtemp2 = new Wire(wt, ht);  // ver
60510234Syasuko.eckert@amd.com            wtemp3 = new Wire(wt, len / 2);  // next hor
60610234Syasuko.eckert@amd.com            len_temp = len;
60710234Syasuko.eckert@amd.com            ht_temp = ht;
60810234Syasuko.eckert@amd.com            len /= 2;
60910234Syasuko.eckert@amd.com            ht /= 2;
61010234Syasuko.eckert@amd.com            v--;
61110234Syasuko.eckert@amd.com            h--;
61210234Syasuko.eckert@amd.com            option = 1;
61310234Syasuko.eckert@amd.com        } else {
61410234Syasuko.eckert@amd.com            // considers only one vertical link
61510234Syasuko.eckert@amd.com            assert(h == 0);
61610234Syasuko.eckert@amd.com            wtemp1 = new Wire(wt, ht); // hor
61710234Syasuko.eckert@amd.com            wtemp2 = new Wire(wt, ht / 2);  // ver
61810234Syasuko.eckert@amd.com            ht_temp = ht;
61910234Syasuko.eckert@amd.com            ht /= 2;
62010234Syasuko.eckert@amd.com            wtemp3 = 0;
62110234Syasuko.eckert@amd.com            v--;
62210234Syasuko.eckert@amd.com            option = 2;
62310234Syasuko.eckert@amd.com        }
62410234Syasuko.eckert@amd.com        delay += wtemp1->delay;
62510234Syasuko.eckert@amd.com        power.readOp.dynamic += wtemp1->power.readOp.dynamic;
62610234Syasuko.eckert@amd.com        power.searchOp.dynamic += wtemp1->power.readOp.dynamic * init_wire_bw;
62710234Syasuko.eckert@amd.com        power.readOp.leakage += wtemp1->power.readOp.leakage * wire_bw;
62810234Syasuko.eckert@amd.com        power.readOp.gate_leakage += wtemp1->power.readOp.gate_leakage * wire_bw;
62910234Syasuko.eckert@amd.com        if ((uca_tree == false && option == 2) || search_tree == true) {
63010234Syasuko.eckert@amd.com            wire_bw *= 2;
63110234Syasuko.eckert@amd.com        }
63210234Syasuko.eckert@amd.com
63310234Syasuko.eckert@amd.com        if (uca_tree == false) {
63410234Syasuko.eckert@amd.com            if (len_temp > wtemp1->repeater_spacing) {
63510234Syasuko.eckert@amd.com                s1 = wtemp1->repeater_size;
63610234Syasuko.eckert@amd.com                l_eff = wtemp1->repeater_spacing;
63710234Syasuko.eckert@amd.com            } else {
63810234Syasuko.eckert@amd.com                s1 = (len_temp / wtemp1->repeater_spacing) *
63910234Syasuko.eckert@amd.com                    wtemp1->repeater_size;
64010234Syasuko.eckert@amd.com                l_eff = len_temp;
64110234Syasuko.eckert@amd.com            }
64210234Syasuko.eckert@amd.com            if (ht_temp > wtemp2->repeater_spacing) {
64310234Syasuko.eckert@amd.com                s2 = wtemp2->repeater_size;
64410234Syasuko.eckert@amd.com            } else {
64510234Syasuko.eckert@amd.com                s2 = (len_temp / wtemp2->repeater_spacing) *
64610234Syasuko.eckert@amd.com                    wtemp2->repeater_size;
64710234Syasuko.eckert@amd.com            }
64810234Syasuko.eckert@amd.com            // first level
64910234Syasuko.eckert@amd.com            output_buffer(s1, s2, l_eff);
65010234Syasuko.eckert@amd.com        }
65110234Syasuko.eckert@amd.com
65210234Syasuko.eckert@amd.com
65310234Syasuko.eckert@amd.com        if (option != 1) {
65410234Syasuko.eckert@amd.com            continue;
65510234Syasuko.eckert@amd.com        }
65610234Syasuko.eckert@amd.com
65710234Syasuko.eckert@amd.com        // second level
65810234Syasuko.eckert@amd.com        delay += wtemp2->delay;
65910234Syasuko.eckert@amd.com        power.readOp.dynamic += wtemp2->power.readOp.dynamic;
66010234Syasuko.eckert@amd.com        power.searchOp.dynamic += wtemp2->power.readOp.dynamic * init_wire_bw;
66110234Syasuko.eckert@amd.com        power.readOp.leakage += wtemp2->power.readOp.leakage * wire_bw;
66210234Syasuko.eckert@amd.com        power.readOp.gate_leakage += wtemp2->power.readOp.gate_leakage * wire_bw;
66310234Syasuko.eckert@amd.com        //cout<<"power.readOp.gate_leakage"<<power.readOp.gate_leakage<<endl;
66410234Syasuko.eckert@amd.com        if (uca_tree) {
66510234Syasuko.eckert@amd.com            power.readOp.leakage += (wtemp2->power.readOp.leakage * wire_bw);
66610234Syasuko.eckert@amd.com            power.readOp.gate_leakage +=
66710234Syasuko.eckert@amd.com                wtemp2->power.readOp.gate_leakage * wire_bw;
66810234Syasuko.eckert@amd.com        } else {
66910234Syasuko.eckert@amd.com            power.readOp.leakage += (wtemp2->power.readOp.leakage * wire_bw);
67010234Syasuko.eckert@amd.com            power.readOp.gate_leakage +=
67110234Syasuko.eckert@amd.com                wtemp2->power.readOp.gate_leakage * wire_bw;
67210234Syasuko.eckert@amd.com            wire_bw *= 2;
67310234Syasuko.eckert@amd.com
67410234Syasuko.eckert@amd.com            if (ht_temp > wtemp3->repeater_spacing) {
67510234Syasuko.eckert@amd.com                s3 = wtemp3->repeater_size;
67610234Syasuko.eckert@amd.com                l_eff = wtemp3->repeater_spacing;
67710234Syasuko.eckert@amd.com            } else {
67810234Syasuko.eckert@amd.com                s3 = (len_temp / wtemp3->repeater_spacing) *
67910234Syasuko.eckert@amd.com                    wtemp3->repeater_size;
68010234Syasuko.eckert@amd.com                l_eff = ht_temp;
68110234Syasuko.eckert@amd.com            }
68210234Syasuko.eckert@amd.com
68310234Syasuko.eckert@amd.com            output_buffer(s2, s3, l_eff);
68410234Syasuko.eckert@amd.com        }
68510234Syasuko.eckert@amd.com        //cout<<"power.readOp.leakage"<<power.readOp.leakage<<endl;
68610234Syasuko.eckert@amd.com        //cout<<"power.readOp.gate_leakage"<<power.readOp.gate_leakage<<endl;
68710234Syasuko.eckert@amd.com        //cout<<"wtemp2->power.readOp.gate_leakage"<<wtemp2->power.readOp.gate_leakage<<endl;
68810152Satgutier@umich.edu    }
68910152Satgutier@umich.edu
69010152Satgutier@umich.edu    if (wtemp1) delete wtemp1;
69110152Satgutier@umich.edu    if (wtemp2) delete wtemp2;
69210152Satgutier@umich.edu    if (wtemp3) delete wtemp3;
69310152Satgutier@umich.edu}
69410152Satgutier@umich.edu
695