decoder.cc revision 10152
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.
510152Satgutier@umich.edu *                          All Rights Reserved
610152Satgutier@umich.edu *
710152Satgutier@umich.edu * Redistribution and use in source and binary forms, with or without
810152Satgutier@umich.edu * modification, are permitted provided that the following conditions are
910152Satgutier@umich.edu * met: redistributions of source code must retain the above copyright
1010152Satgutier@umich.edu * notice, this list of conditions and the following disclaimer;
1110152Satgutier@umich.edu * redistributions in binary form must reproduce the above copyright
1210152Satgutier@umich.edu * notice, this list of conditions and the following disclaimer in the
1310152Satgutier@umich.edu * documentation and/or other materials provided with the distribution;
1410152Satgutier@umich.edu * neither the name of the copyright holders nor the names of its
1510152Satgutier@umich.edu * contributors may be used to endorse or promote products derived from
1610152Satgutier@umich.edu * this software without specific prior written permission.
1710152Satgutier@umich.edu
1810152Satgutier@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1910152Satgutier@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2010152Satgutier@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2110152Satgutier@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2210152Satgutier@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2310152Satgutier@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2410152Satgutier@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2510152Satgutier@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2610152Satgutier@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2710152Satgutier@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2810152Satgutier@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.”
2910152Satgutier@umich.edu *
3010152Satgutier@umich.edu ***************************************************************************/
3110152Satgutier@umich.edu
3210152Satgutier@umich.edu
3310152Satgutier@umich.edu
3410152Satgutier@umich.edu#include <cassert>
3510152Satgutier@umich.edu#include <cmath>
3610152Satgutier@umich.edu#include <iostream>
3710152Satgutier@umich.edu
3810152Satgutier@umich.edu#include "area.h"
3910152Satgutier@umich.edu#include "decoder.h"
4010152Satgutier@umich.edu#include "parameter.h"
4110152Satgutier@umich.edu
4210152Satgutier@umich.eduusing namespace std;
4310152Satgutier@umich.edu
4410152Satgutier@umich.edu
4510152Satgutier@umich.eduDecoder::Decoder(
4610152Satgutier@umich.edu    int    _num_dec_signals,
4710152Satgutier@umich.edu    bool   flag_way_select,
4810152Satgutier@umich.edu    double _C_ld_dec_out,
4910152Satgutier@umich.edu    double _R_wire_dec_out,
5010152Satgutier@umich.edu    bool   fully_assoc_,
5110152Satgutier@umich.edu    bool   is_dram_,
5210152Satgutier@umich.edu    bool   is_wl_tr_,
5310152Satgutier@umich.edu    const  Area & cell_)
5410152Satgutier@umich.edu:exist(false),
5510152Satgutier@umich.edu  C_ld_dec_out(_C_ld_dec_out),
5610152Satgutier@umich.edu  R_wire_dec_out(_R_wire_dec_out),
5710152Satgutier@umich.edu  num_gates(0), num_gates_min(2),
5810152Satgutier@umich.edu  delay(0),
5910152Satgutier@umich.edu  //power(),
6010152Satgutier@umich.edu  fully_assoc(fully_assoc_), is_dram(is_dram_),
6110152Satgutier@umich.edu  is_wl_tr(is_wl_tr_), cell(cell_)
6210152Satgutier@umich.edu{
6310152Satgutier@umich.edu
6410152Satgutier@umich.edu  for (int i = 0; i < MAX_NUMBER_GATES_STAGE; i++)
6510152Satgutier@umich.edu  {
6610152Satgutier@umich.edu    w_dec_n[i] = 0;
6710152Satgutier@umich.edu    w_dec_p[i] = 0;
6810152Satgutier@umich.edu  }
6910152Satgutier@umich.edu
7010152Satgutier@umich.edu  /*
7110152Satgutier@umich.edu   * _num_dec_signals is the number of decoded signal as output
7210152Satgutier@umich.edu   * num_addr_bits_dec is the number of signal to be decoded
7310152Satgutier@umich.edu   * as the decoders input.
7410152Satgutier@umich.edu   */
7510152Satgutier@umich.edu  int num_addr_bits_dec = _log2(_num_dec_signals);
7610152Satgutier@umich.edu
7710152Satgutier@umich.edu  if (num_addr_bits_dec < 4)
7810152Satgutier@umich.edu  {
7910152Satgutier@umich.edu    if (flag_way_select)
8010152Satgutier@umich.edu    {
8110152Satgutier@umich.edu      exist = true;
8210152Satgutier@umich.edu      num_in_signals = 2;
8310152Satgutier@umich.edu    }
8410152Satgutier@umich.edu    else
8510152Satgutier@umich.edu    {
8610152Satgutier@umich.edu      num_in_signals = 0;
8710152Satgutier@umich.edu    }
8810152Satgutier@umich.edu  }
8910152Satgutier@umich.edu  else
9010152Satgutier@umich.edu  {
9110152Satgutier@umich.edu    exist = true;
9210152Satgutier@umich.edu
9310152Satgutier@umich.edu    if (flag_way_select)
9410152Satgutier@umich.edu    {
9510152Satgutier@umich.edu      num_in_signals = 3;
9610152Satgutier@umich.edu    }
9710152Satgutier@umich.edu    else
9810152Satgutier@umich.edu    {
9910152Satgutier@umich.edu      num_in_signals = 2;
10010152Satgutier@umich.edu    }
10110152Satgutier@umich.edu  }
10210152Satgutier@umich.edu
10310152Satgutier@umich.edu  assert(cell.h>0);
10410152Satgutier@umich.edu  assert(cell.w>0);
10510152Satgutier@umich.edu  // the height of a row-decoder-driver cell is fixed to be 4 * cell.h;
10610152Satgutier@umich.edu  //area.h = 4 * cell.h;
10710152Satgutier@umich.edu  area.h = g_tp.h_dec * cell.h;
10810152Satgutier@umich.edu
10910152Satgutier@umich.edu  compute_widths();
11010152Satgutier@umich.edu  compute_area();
11110152Satgutier@umich.edu}
11210152Satgutier@umich.edu
11310152Satgutier@umich.edu
11410152Satgutier@umich.edu
11510152Satgutier@umich.eduvoid Decoder::compute_widths()
11610152Satgutier@umich.edu{
11710152Satgutier@umich.edu  double F;
11810152Satgutier@umich.edu  double p_to_n_sz_ratio = pmos_to_nmos_sz_ratio(is_dram, is_wl_tr);
11910152Satgutier@umich.edu  double gnand2     = (2 + p_to_n_sz_ratio) / (1 + p_to_n_sz_ratio);
12010152Satgutier@umich.edu  double gnand3     = (3 + p_to_n_sz_ratio) / (1 + p_to_n_sz_ratio);
12110152Satgutier@umich.edu
12210152Satgutier@umich.edu  if (exist)
12310152Satgutier@umich.edu  {
12410152Satgutier@umich.edu    if (num_in_signals == 2 || fully_assoc)
12510152Satgutier@umich.edu    {
12610152Satgutier@umich.edu      w_dec_n[0] = 2 * g_tp.min_w_nmos_;
12710152Satgutier@umich.edu      w_dec_p[0] = p_to_n_sz_ratio * g_tp.min_w_nmos_;
12810152Satgutier@umich.edu      F = gnand2;
12910152Satgutier@umich.edu    }
13010152Satgutier@umich.edu    else
13110152Satgutier@umich.edu    {
13210152Satgutier@umich.edu      w_dec_n[0] = 3 * g_tp.min_w_nmos_;
13310152Satgutier@umich.edu      w_dec_p[0] = p_to_n_sz_ratio * g_tp.min_w_nmos_;
13410152Satgutier@umich.edu      F = gnand3;
13510152Satgutier@umich.edu    }
13610152Satgutier@umich.edu
13710152Satgutier@umich.edu    F *= C_ld_dec_out / (gate_C(w_dec_n[0], 0, is_dram, false, is_wl_tr) +
13810152Satgutier@umich.edu                         gate_C(w_dec_p[0], 0, is_dram, false, is_wl_tr));
13910152Satgutier@umich.edu    num_gates = logical_effort(
14010152Satgutier@umich.edu        num_gates_min,
14110152Satgutier@umich.edu        num_in_signals == 2 ? gnand2 : gnand3,
14210152Satgutier@umich.edu        F,
14310152Satgutier@umich.edu        w_dec_n,
14410152Satgutier@umich.edu        w_dec_p,
14510152Satgutier@umich.edu        C_ld_dec_out,
14610152Satgutier@umich.edu        p_to_n_sz_ratio,
14710152Satgutier@umich.edu        is_dram,
14810152Satgutier@umich.edu        is_wl_tr,
14910152Satgutier@umich.edu        g_tp.max_w_nmos_dec);
15010152Satgutier@umich.edu  }
15110152Satgutier@umich.edu}
15210152Satgutier@umich.edu
15310152Satgutier@umich.edu
15410152Satgutier@umich.edu
15510152Satgutier@umich.eduvoid Decoder::compute_area()
15610152Satgutier@umich.edu{
15710152Satgutier@umich.edu  double cumulative_area = 0;
15810152Satgutier@umich.edu  double cumulative_curr = 0;  // cumulative leakage current
15910152Satgutier@umich.edu  double cumulative_curr_Ig = 0;  // cumulative leakage current
16010152Satgutier@umich.edu
16110152Satgutier@umich.edu  if (exist)
16210152Satgutier@umich.edu  { // First check if this decoder exists
16310152Satgutier@umich.edu    if (num_in_signals == 2)
16410152Satgutier@umich.edu    {
16510152Satgutier@umich.edu      cumulative_area = compute_gate_area(NAND, 2, w_dec_p[0], w_dec_n[0], area.h);
16610152Satgutier@umich.edu      cumulative_curr = cmos_Isub_leakage(w_dec_n[0], w_dec_p[0], 2, nand,is_dram);
16710152Satgutier@umich.edu      cumulative_curr_Ig = cmos_Ig_leakage(w_dec_n[0], w_dec_p[0], 2, nand,is_dram);
16810152Satgutier@umich.edu    }
16910152Satgutier@umich.edu    else if (num_in_signals == 3)
17010152Satgutier@umich.edu    {
17110152Satgutier@umich.edu      cumulative_area = compute_gate_area(NAND, 3, w_dec_p[0], w_dec_n[0], area.h);
17210152Satgutier@umich.edu      cumulative_curr = cmos_Isub_leakage(w_dec_n[0], w_dec_p[0], 3, nand, is_dram);;
17310152Satgutier@umich.edu      cumulative_curr_Ig = cmos_Ig_leakage(w_dec_n[0], w_dec_p[0], 3, nand, is_dram);
17410152Satgutier@umich.edu    }
17510152Satgutier@umich.edu
17610152Satgutier@umich.edu    for (int i = 1; i < num_gates; i++)
17710152Satgutier@umich.edu    {
17810152Satgutier@umich.edu      cumulative_area += compute_gate_area(INV, 1, w_dec_p[i], w_dec_n[i], area.h);
17910152Satgutier@umich.edu      cumulative_curr += cmos_Isub_leakage(w_dec_n[i], w_dec_p[i], 1, inv, is_dram);
18010152Satgutier@umich.edu      cumulative_curr_Ig = cmos_Ig_leakage(w_dec_n[i], w_dec_p[i], 1, inv, is_dram);
18110152Satgutier@umich.edu    }
18210152Satgutier@umich.edu    power.readOp.leakage = cumulative_curr * g_tp.peri_global.Vdd;
18310152Satgutier@umich.edu    power.readOp.gate_leakage = cumulative_curr_Ig * g_tp.peri_global.Vdd;
18410152Satgutier@umich.edu
18510152Satgutier@umich.edu    area.w = (cumulative_area / area.h);
18610152Satgutier@umich.edu  }
18710152Satgutier@umich.edu}
18810152Satgutier@umich.edu
18910152Satgutier@umich.edu
19010152Satgutier@umich.edu
19110152Satgutier@umich.edudouble Decoder::compute_delays(double inrisetime)
19210152Satgutier@umich.edu{
19310152Satgutier@umich.edu  if (exist)
19410152Satgutier@umich.edu  {
19510152Satgutier@umich.edu    double ret_val = 0;  // outrisetime
19610152Satgutier@umich.edu    int    i;
19710152Satgutier@umich.edu    double rd, tf, this_delay, c_load, c_intrinsic, Vpp;
19810152Satgutier@umich.edu    double Vdd = g_tp.peri_global.Vdd;
19910152Satgutier@umich.edu
20010152Satgutier@umich.edu    if ((is_wl_tr) && (is_dram))
20110152Satgutier@umich.edu    {
20210152Satgutier@umich.edu      Vpp = g_tp.vpp;
20310152Satgutier@umich.edu    }
20410152Satgutier@umich.edu    else if (is_wl_tr)
20510152Satgutier@umich.edu    {
20610152Satgutier@umich.edu      Vpp = g_tp.sram_cell.Vdd;
20710152Satgutier@umich.edu    }
20810152Satgutier@umich.edu    else
20910152Satgutier@umich.edu    {
21010152Satgutier@umich.edu      Vpp = g_tp.peri_global.Vdd;
21110152Satgutier@umich.edu    }
21210152Satgutier@umich.edu
21310152Satgutier@umich.edu    // first check whether a decoder is required at all
21410152Satgutier@umich.edu    rd = tr_R_on(w_dec_n[0], NCH, num_in_signals, is_dram, false, is_wl_tr);
21510152Satgutier@umich.edu    c_load = gate_C(w_dec_n[1] + w_dec_p[1], 0.0, is_dram, false, is_wl_tr);
21610152Satgutier@umich.edu    c_intrinsic = drain_C_(w_dec_p[0], PCH, 1, 1, area.h, is_dram, false, is_wl_tr) * num_in_signals +
21710152Satgutier@umich.edu                  drain_C_(w_dec_n[0], NCH, num_in_signals, 1, area.h, is_dram, false, is_wl_tr);
21810152Satgutier@umich.edu    tf = rd * (c_intrinsic + c_load);
21910152Satgutier@umich.edu    this_delay = horowitz(inrisetime, tf, 0.5, 0.5, RISE);
22010152Satgutier@umich.edu    delay += this_delay;
22110152Satgutier@umich.edu    inrisetime = this_delay / (1.0 - 0.5);
22210152Satgutier@umich.edu    power.readOp.dynamic += (c_load + c_intrinsic) * Vdd * Vdd;
22310152Satgutier@umich.edu
22410152Satgutier@umich.edu    for (i = 1; i < num_gates - 1; ++i)
22510152Satgutier@umich.edu    {
22610152Satgutier@umich.edu      rd = tr_R_on(w_dec_n[i], NCH, 1, is_dram, false, is_wl_tr);
22710152Satgutier@umich.edu      c_load = gate_C(w_dec_p[i+1] + w_dec_n[i+1], 0.0, is_dram, false, is_wl_tr);
22810152Satgutier@umich.edu      c_intrinsic = drain_C_(w_dec_p[i], PCH, 1, 1, area.h, is_dram, false, is_wl_tr) +
22910152Satgutier@umich.edu                    drain_C_(w_dec_n[i], NCH, 1, 1, area.h, is_dram, false, is_wl_tr);
23010152Satgutier@umich.edu      tf = rd * (c_intrinsic + c_load);
23110152Satgutier@umich.edu      this_delay = horowitz(inrisetime, tf, 0.5, 0.5, RISE);
23210152Satgutier@umich.edu      delay += this_delay;
23310152Satgutier@umich.edu      inrisetime = this_delay / (1.0 - 0.5);
23410152Satgutier@umich.edu      power.readOp.dynamic += (c_load + c_intrinsic) * Vdd * Vdd;
23510152Satgutier@umich.edu    }
23610152Satgutier@umich.edu
23710152Satgutier@umich.edu    // add delay of final inverter that drives the wordline
23810152Satgutier@umich.edu    i = num_gates - 1;
23910152Satgutier@umich.edu    c_load = C_ld_dec_out;
24010152Satgutier@umich.edu    rd = tr_R_on(w_dec_n[i], NCH, 1, is_dram, false, is_wl_tr);
24110152Satgutier@umich.edu    c_intrinsic = drain_C_(w_dec_p[i], PCH, 1, 1, area.h, is_dram, false, is_wl_tr) +
24210152Satgutier@umich.edu                  drain_C_(w_dec_n[i], NCH, 1, 1, area.h, is_dram, false, is_wl_tr);
24310152Satgutier@umich.edu    tf = rd * (c_intrinsic + c_load) + R_wire_dec_out * c_load / 2;
24410152Satgutier@umich.edu    this_delay = horowitz(inrisetime, tf, 0.5, 0.5, RISE);
24510152Satgutier@umich.edu    delay  += this_delay;
24610152Satgutier@umich.edu    ret_val = this_delay / (1.0 - 0.5);
24710152Satgutier@umich.edu    power.readOp.dynamic += c_load * Vpp * Vpp + c_intrinsic * Vdd * Vdd;
24810152Satgutier@umich.edu
24910152Satgutier@umich.edu    return ret_val;
25010152Satgutier@umich.edu  }
25110152Satgutier@umich.edu  else
25210152Satgutier@umich.edu  {
25310152Satgutier@umich.edu    return 0.0;
25410152Satgutier@umich.edu  }
25510152Satgutier@umich.edu}
25610152Satgutier@umich.edu
25710152Satgutier@umich.eduvoid Decoder::leakage_feedback(double temperature)
25810152Satgutier@umich.edu{
25910152Satgutier@umich.edu  double cumulative_curr = 0;  // cumulative leakage current
26010152Satgutier@umich.edu  double cumulative_curr_Ig = 0;  // cumulative leakage current
26110152Satgutier@umich.edu
26210152Satgutier@umich.edu  if (exist)
26310152Satgutier@umich.edu  { // First check if this decoder exists
26410152Satgutier@umich.edu    if (num_in_signals == 2)
26510152Satgutier@umich.edu    {
26610152Satgutier@umich.edu      cumulative_curr = cmos_Isub_leakage(w_dec_n[0], w_dec_p[0], 2, nand,is_dram);
26710152Satgutier@umich.edu      cumulative_curr_Ig = cmos_Ig_leakage(w_dec_n[0], w_dec_p[0], 2, nand,is_dram);
26810152Satgutier@umich.edu    }
26910152Satgutier@umich.edu    else if (num_in_signals == 3)
27010152Satgutier@umich.edu    {
27110152Satgutier@umich.edu      cumulative_curr = cmos_Isub_leakage(w_dec_n[0], w_dec_p[0], 3, nand, is_dram);;
27210152Satgutier@umich.edu      cumulative_curr_Ig = cmos_Ig_leakage(w_dec_n[0], w_dec_p[0], 3, nand, is_dram);
27310152Satgutier@umich.edu    }
27410152Satgutier@umich.edu
27510152Satgutier@umich.edu    for (int i = 1; i < num_gates; i++)
27610152Satgutier@umich.edu    {
27710152Satgutier@umich.edu      cumulative_curr += cmos_Isub_leakage(w_dec_n[i], w_dec_p[i], 1, inv, is_dram);
27810152Satgutier@umich.edu      cumulative_curr_Ig = cmos_Ig_leakage(w_dec_n[i], w_dec_p[i], 1, inv, is_dram);
27910152Satgutier@umich.edu    }
28010152Satgutier@umich.edu
28110152Satgutier@umich.edu    power.readOp.leakage = cumulative_curr * g_tp.peri_global.Vdd;
28210152Satgutier@umich.edu    power.readOp.gate_leakage = cumulative_curr_Ig * g_tp.peri_global.Vdd;
28310152Satgutier@umich.edu  }
28410152Satgutier@umich.edu}
28510152Satgutier@umich.edu
28610152Satgutier@umich.eduPredecBlk::PredecBlk(
28710152Satgutier@umich.edu    int    num_dec_signals,
28810152Satgutier@umich.edu    Decoder * dec_,
28910152Satgutier@umich.edu    double C_wire_predec_blk_out,
29010152Satgutier@umich.edu    double R_wire_predec_blk_out_,
29110152Satgutier@umich.edu    int    num_dec_per_predec,
29210152Satgutier@umich.edu    bool   is_dram,
29310152Satgutier@umich.edu    bool   is_blk1)
29410152Satgutier@umich.edu :dec(dec_),
29510152Satgutier@umich.edu  exist(false),
29610152Satgutier@umich.edu  number_input_addr_bits(0),
29710152Satgutier@umich.edu  C_ld_predec_blk_out(0),
29810152Satgutier@umich.edu  R_wire_predec_blk_out(0),
29910152Satgutier@umich.edu  branch_effort_nand2_gate_output(1),
30010152Satgutier@umich.edu  branch_effort_nand3_gate_output(1),
30110152Satgutier@umich.edu  flag_two_unique_paths(false),
30210152Satgutier@umich.edu  flag_L2_gate(0),
30310152Satgutier@umich.edu  number_inputs_L1_gate(0),
30410152Satgutier@umich.edu  number_gates_L1_nand2_path(0),
30510152Satgutier@umich.edu  number_gates_L1_nand3_path(0),
30610152Satgutier@umich.edu  number_gates_L2(0),
30710152Satgutier@umich.edu  min_number_gates_L1(2),
30810152Satgutier@umich.edu  min_number_gates_L2(2),
30910152Satgutier@umich.edu  num_L1_active_nand2_path(0),
31010152Satgutier@umich.edu  num_L1_active_nand3_path(0),
31110152Satgutier@umich.edu  delay_nand2_path(0),
31210152Satgutier@umich.edu  delay_nand3_path(0),
31310152Satgutier@umich.edu  power_nand2_path(),
31410152Satgutier@umich.edu  power_nand3_path(),
31510152Satgutier@umich.edu  power_L2(),
31610152Satgutier@umich.edu  is_dram_(is_dram)
31710152Satgutier@umich.edu{
31810152Satgutier@umich.edu  int    branch_effort_predec_out;
31910152Satgutier@umich.edu  double C_ld_dec_gate;
32010152Satgutier@umich.edu  int    num_addr_bits_dec = _log2(num_dec_signals);
32110152Satgutier@umich.edu  int    blk1_num_input_addr_bits = (num_addr_bits_dec + 1) / 2;
32210152Satgutier@umich.edu  int    blk2_num_input_addr_bits = num_addr_bits_dec - blk1_num_input_addr_bits;
32310152Satgutier@umich.edu
32410152Satgutier@umich.edu  w_L1_nand2_n[0] = 0;
32510152Satgutier@umich.edu  w_L1_nand2_p[0] = 0;
32610152Satgutier@umich.edu  w_L1_nand3_n[0] = 0;
32710152Satgutier@umich.edu  w_L1_nand3_p[0] = 0;
32810152Satgutier@umich.edu
32910152Satgutier@umich.edu  if (is_blk1 == true)
33010152Satgutier@umich.edu  {
33110152Satgutier@umich.edu    if (num_addr_bits_dec <= 0)
33210152Satgutier@umich.edu    {
33310152Satgutier@umich.edu      return;
33410152Satgutier@umich.edu    }
33510152Satgutier@umich.edu    else if (num_addr_bits_dec < 4)
33610152Satgutier@umich.edu    {
33710152Satgutier@umich.edu      // Just one predecoder block is required with NAND2 gates. No decoder required.
33810152Satgutier@umich.edu      // The first level of predecoding directly drives the decoder output load
33910152Satgutier@umich.edu      exist = true;
34010152Satgutier@umich.edu      number_input_addr_bits = num_addr_bits_dec;
34110152Satgutier@umich.edu      R_wire_predec_blk_out = dec->R_wire_dec_out;
34210152Satgutier@umich.edu      C_ld_predec_blk_out = dec->C_ld_dec_out;
34310152Satgutier@umich.edu    }
34410152Satgutier@umich.edu    else
34510152Satgutier@umich.edu    {
34610152Satgutier@umich.edu      exist = true;
34710152Satgutier@umich.edu      number_input_addr_bits   = blk1_num_input_addr_bits;
34810152Satgutier@umich.edu      branch_effort_predec_out = (1 << blk2_num_input_addr_bits);
34910152Satgutier@umich.edu      C_ld_dec_gate = num_dec_per_predec * gate_C(dec->w_dec_n[0] + dec->w_dec_p[0], 0, is_dram_, false, false);
35010152Satgutier@umich.edu      R_wire_predec_blk_out = R_wire_predec_blk_out_;
35110152Satgutier@umich.edu      C_ld_predec_blk_out = branch_effort_predec_out * C_ld_dec_gate + C_wire_predec_blk_out;
35210152Satgutier@umich.edu    }
35310152Satgutier@umich.edu  }
35410152Satgutier@umich.edu  else
35510152Satgutier@umich.edu  {
35610152Satgutier@umich.edu    if (num_addr_bits_dec >= 4)
35710152Satgutier@umich.edu    {
35810152Satgutier@umich.edu      exist = true;
35910152Satgutier@umich.edu      number_input_addr_bits   = blk2_num_input_addr_bits;
36010152Satgutier@umich.edu      branch_effort_predec_out = (1 << blk1_num_input_addr_bits);
36110152Satgutier@umich.edu      C_ld_dec_gate = num_dec_per_predec * gate_C(dec->w_dec_n[0] + dec->w_dec_p[0], 0, is_dram_, false, false);
36210152Satgutier@umich.edu      R_wire_predec_blk_out = R_wire_predec_blk_out_;
36310152Satgutier@umich.edu      C_ld_predec_blk_out = branch_effort_predec_out * C_ld_dec_gate + C_wire_predec_blk_out;
36410152Satgutier@umich.edu    }
36510152Satgutier@umich.edu  }
36610152Satgutier@umich.edu
36710152Satgutier@umich.edu  compute_widths();
36810152Satgutier@umich.edu  compute_area();
36910152Satgutier@umich.edu}
37010152Satgutier@umich.edu
37110152Satgutier@umich.edu
37210152Satgutier@umich.edu
37310152Satgutier@umich.eduvoid PredecBlk::compute_widths()
37410152Satgutier@umich.edu{
37510152Satgutier@umich.edu  double F, c_load_nand3_path, c_load_nand2_path;
37610152Satgutier@umich.edu  double p_to_n_sz_ratio = pmos_to_nmos_sz_ratio(is_dram_);
37710152Satgutier@umich.edu  double gnand2 = (2 + p_to_n_sz_ratio) / (1 + p_to_n_sz_ratio);
37810152Satgutier@umich.edu  double gnand3 = (3 + p_to_n_sz_ratio) / (1 + p_to_n_sz_ratio);
37910152Satgutier@umich.edu
38010152Satgutier@umich.edu  if (exist == false) return;
38110152Satgutier@umich.edu
38210152Satgutier@umich.edu
38310152Satgutier@umich.edu  switch (number_input_addr_bits)
38410152Satgutier@umich.edu  {
38510152Satgutier@umich.edu    case 1:
38610152Satgutier@umich.edu      flag_two_unique_paths           = false;
38710152Satgutier@umich.edu      number_inputs_L1_gate           = 2;
38810152Satgutier@umich.edu      flag_L2_gate                    = 0;
38910152Satgutier@umich.edu      break;
39010152Satgutier@umich.edu    case 2:
39110152Satgutier@umich.edu      flag_two_unique_paths           = false;
39210152Satgutier@umich.edu      number_inputs_L1_gate           = 2;
39310152Satgutier@umich.edu      flag_L2_gate                    = 0;
39410152Satgutier@umich.edu      break;
39510152Satgutier@umich.edu    case 3:
39610152Satgutier@umich.edu      flag_two_unique_paths           = false;
39710152Satgutier@umich.edu      number_inputs_L1_gate           = 3;
39810152Satgutier@umich.edu      flag_L2_gate                    = 0;
39910152Satgutier@umich.edu      break;
40010152Satgutier@umich.edu    case 4:
40110152Satgutier@umich.edu      flag_two_unique_paths           = false;
40210152Satgutier@umich.edu      number_inputs_L1_gate           = 2;
40310152Satgutier@umich.edu      flag_L2_gate                    = 2;
40410152Satgutier@umich.edu      branch_effort_nand2_gate_output = 4;
40510152Satgutier@umich.edu      break;
40610152Satgutier@umich.edu    case 5:
40710152Satgutier@umich.edu      flag_two_unique_paths           = true;
40810152Satgutier@umich.edu      flag_L2_gate                    = 2;
40910152Satgutier@umich.edu      branch_effort_nand2_gate_output = 8;
41010152Satgutier@umich.edu      branch_effort_nand3_gate_output = 4;
41110152Satgutier@umich.edu      break;
41210152Satgutier@umich.edu    case 6:
41310152Satgutier@umich.edu      flag_two_unique_paths           = false;
41410152Satgutier@umich.edu      number_inputs_L1_gate           = 3;
41510152Satgutier@umich.edu      flag_L2_gate                    = 2;
41610152Satgutier@umich.edu      branch_effort_nand3_gate_output = 8;
41710152Satgutier@umich.edu      break;
41810152Satgutier@umich.edu    case 7:
41910152Satgutier@umich.edu      flag_two_unique_paths           = true;
42010152Satgutier@umich.edu      flag_L2_gate                    = 3;
42110152Satgutier@umich.edu      branch_effort_nand2_gate_output = 32;
42210152Satgutier@umich.edu      branch_effort_nand3_gate_output = 16;
42310152Satgutier@umich.edu      break;
42410152Satgutier@umich.edu    case 8:
42510152Satgutier@umich.edu      flag_two_unique_paths           = true;
42610152Satgutier@umich.edu      flag_L2_gate                    = 3;
42710152Satgutier@umich.edu      branch_effort_nand2_gate_output = 64;
42810152Satgutier@umich.edu      branch_effort_nand3_gate_output = 32;
42910152Satgutier@umich.edu      break;
43010152Satgutier@umich.edu    case 9:
43110152Satgutier@umich.edu      flag_two_unique_paths           = false;
43210152Satgutier@umich.edu      number_inputs_L1_gate           = 3;
43310152Satgutier@umich.edu      flag_L2_gate                    = 3;
43410152Satgutier@umich.edu      branch_effort_nand3_gate_output = 64;
43510152Satgutier@umich.edu      break;
43610152Satgutier@umich.edu    default:
43710152Satgutier@umich.edu      assert(0);
43810152Satgutier@umich.edu      break;
43910152Satgutier@umich.edu  }
44010152Satgutier@umich.edu
44110152Satgutier@umich.edu  // find the number of gates and sizing in second level of predecoder (if there is a second level)
44210152Satgutier@umich.edu  if (flag_L2_gate)
44310152Satgutier@umich.edu  {
44410152Satgutier@umich.edu    if (flag_L2_gate == 2)
44510152Satgutier@umich.edu    { // 2nd level is a NAND2 gate
44610152Satgutier@umich.edu      w_L2_n[0] = 2 * g_tp.min_w_nmos_;
44710152Satgutier@umich.edu      F = gnand2;
44810152Satgutier@umich.edu    }
44910152Satgutier@umich.edu    else
45010152Satgutier@umich.edu    { // 2nd level is a NAND3 gate
45110152Satgutier@umich.edu      w_L2_n[0] = 3 * g_tp.min_w_nmos_;
45210152Satgutier@umich.edu      F = gnand3;
45310152Satgutier@umich.edu    }
45410152Satgutier@umich.edu    w_L2_p[0] = p_to_n_sz_ratio * g_tp.min_w_nmos_;
45510152Satgutier@umich.edu    F *= C_ld_predec_blk_out / (gate_C(w_L2_n[0], 0, is_dram_) + gate_C(w_L2_p[0], 0, is_dram_));
45610152Satgutier@umich.edu    number_gates_L2 = logical_effort(
45710152Satgutier@umich.edu        min_number_gates_L2,
45810152Satgutier@umich.edu        flag_L2_gate == 2 ? gnand2 : gnand3,
45910152Satgutier@umich.edu        F,
46010152Satgutier@umich.edu        w_L2_n,
46110152Satgutier@umich.edu        w_L2_p,
46210152Satgutier@umich.edu        C_ld_predec_blk_out,
46310152Satgutier@umich.edu        p_to_n_sz_ratio,
46410152Satgutier@umich.edu        is_dram_, false,
46510152Satgutier@umich.edu        g_tp.max_w_nmos_);
46610152Satgutier@umich.edu
46710152Satgutier@umich.edu    // Now find the number of gates and widths in first level of predecoder
46810152Satgutier@umich.edu    if ((flag_two_unique_paths)||(number_inputs_L1_gate == 2))
46910152Satgutier@umich.edu    { // Whenever flag_two_unique_paths is true, it means first level of decoder employs
47010152Satgutier@umich.edu      // both NAND2 and NAND3 gates. Or when number_inputs_L1_gate is 2, it means
47110152Satgutier@umich.edu      // a NAND2 gate is used in the first level of the predecoder
47210152Satgutier@umich.edu      c_load_nand2_path = branch_effort_nand2_gate_output *
47310152Satgutier@umich.edu        (gate_C(w_L2_n[0], 0, is_dram_) +
47410152Satgutier@umich.edu         gate_C(w_L2_p[0], 0, is_dram_));
47510152Satgutier@umich.edu      w_L1_nand2_n[0] = 2 * g_tp.min_w_nmos_;
47610152Satgutier@umich.edu      w_L1_nand2_p[0] = p_to_n_sz_ratio * g_tp.min_w_nmos_;
47710152Satgutier@umich.edu      F = gnand2 * c_load_nand2_path /
47810152Satgutier@umich.edu        (gate_C(w_L1_nand2_n[0], 0, is_dram_) +
47910152Satgutier@umich.edu         gate_C(w_L1_nand2_p[0], 0, is_dram_));
48010152Satgutier@umich.edu      number_gates_L1_nand2_path = logical_effort(
48110152Satgutier@umich.edu          min_number_gates_L1,
48210152Satgutier@umich.edu          gnand2,
48310152Satgutier@umich.edu          F,
48410152Satgutier@umich.edu          w_L1_nand2_n,
48510152Satgutier@umich.edu          w_L1_nand2_p,
48610152Satgutier@umich.edu          c_load_nand2_path,
48710152Satgutier@umich.edu          p_to_n_sz_ratio,
48810152Satgutier@umich.edu          is_dram_, false,
48910152Satgutier@umich.edu          g_tp.max_w_nmos_);
49010152Satgutier@umich.edu    }
49110152Satgutier@umich.edu
49210152Satgutier@umich.edu    //Now find widths of gates along path in which first gate is a NAND3
49310152Satgutier@umich.edu    if ((flag_two_unique_paths)||(number_inputs_L1_gate == 3))
49410152Satgutier@umich.edu    { // Whenever flag_two_unique_paths is TRUE, it means first level of decoder employs
49510152Satgutier@umich.edu      // both NAND2 and NAND3 gates. Or when number_inputs_L1_gate is 3, it means
49610152Satgutier@umich.edu      // a NAND3 gate is used in the first level of the predecoder
49710152Satgutier@umich.edu      c_load_nand3_path = branch_effort_nand3_gate_output *
49810152Satgutier@umich.edu        (gate_C(w_L2_n[0], 0, is_dram_) +
49910152Satgutier@umich.edu         gate_C(w_L2_p[0], 0, is_dram_));
50010152Satgutier@umich.edu      w_L1_nand3_n[0] = 3 * g_tp.min_w_nmos_;
50110152Satgutier@umich.edu      w_L1_nand3_p[0] = p_to_n_sz_ratio * g_tp.min_w_nmos_;
50210152Satgutier@umich.edu      F = gnand3 * c_load_nand3_path /
50310152Satgutier@umich.edu        (gate_C(w_L1_nand3_n[0], 0, is_dram_) +
50410152Satgutier@umich.edu         gate_C(w_L1_nand3_p[0], 0, is_dram_));
50510152Satgutier@umich.edu      number_gates_L1_nand3_path = logical_effort(
50610152Satgutier@umich.edu          min_number_gates_L1,
50710152Satgutier@umich.edu          gnand3,
50810152Satgutier@umich.edu          F,
50910152Satgutier@umich.edu          w_L1_nand3_n,
51010152Satgutier@umich.edu          w_L1_nand3_p,
51110152Satgutier@umich.edu          c_load_nand3_path,
51210152Satgutier@umich.edu          p_to_n_sz_ratio,
51310152Satgutier@umich.edu          is_dram_, false,
51410152Satgutier@umich.edu          g_tp.max_w_nmos_);
51510152Satgutier@umich.edu    }
51610152Satgutier@umich.edu  }
51710152Satgutier@umich.edu  else
51810152Satgutier@umich.edu  { // find number of gates and widths in first level of predecoder block when there is no second level
51910152Satgutier@umich.edu    if (number_inputs_L1_gate == 2)
52010152Satgutier@umich.edu    {
52110152Satgutier@umich.edu      w_L1_nand2_n[0] = 2 * g_tp.min_w_nmos_;
52210152Satgutier@umich.edu      w_L1_nand2_p[0] = p_to_n_sz_ratio * g_tp.min_w_nmos_;
52310152Satgutier@umich.edu      F = gnand2*C_ld_predec_blk_out /
52410152Satgutier@umich.edu        (gate_C(w_L1_nand2_n[0], 0, is_dram_) +
52510152Satgutier@umich.edu         gate_C(w_L1_nand2_p[0], 0, is_dram_));
52610152Satgutier@umich.edu      number_gates_L1_nand2_path = logical_effort(
52710152Satgutier@umich.edu          min_number_gates_L1,
52810152Satgutier@umich.edu          gnand2,
52910152Satgutier@umich.edu          F,
53010152Satgutier@umich.edu          w_L1_nand2_n,
53110152Satgutier@umich.edu          w_L1_nand2_p,
53210152Satgutier@umich.edu          C_ld_predec_blk_out,
53310152Satgutier@umich.edu          p_to_n_sz_ratio,
53410152Satgutier@umich.edu          is_dram_, false,
53510152Satgutier@umich.edu          g_tp.max_w_nmos_);
53610152Satgutier@umich.edu    }
53710152Satgutier@umich.edu    else if (number_inputs_L1_gate == 3)
53810152Satgutier@umich.edu    {
53910152Satgutier@umich.edu      w_L1_nand3_n[0] = 3 * g_tp.min_w_nmos_;
54010152Satgutier@umich.edu      w_L1_nand3_p[0] = p_to_n_sz_ratio * g_tp.min_w_nmos_;
54110152Satgutier@umich.edu      F = gnand3*C_ld_predec_blk_out /
54210152Satgutier@umich.edu        (gate_C(w_L1_nand3_n[0], 0, is_dram_) +
54310152Satgutier@umich.edu         gate_C(w_L1_nand3_p[0], 0, is_dram_));
54410152Satgutier@umich.edu      number_gates_L1_nand3_path = logical_effort(
54510152Satgutier@umich.edu          min_number_gates_L1,
54610152Satgutier@umich.edu          gnand3,
54710152Satgutier@umich.edu          F,
54810152Satgutier@umich.edu          w_L1_nand3_n,
54910152Satgutier@umich.edu          w_L1_nand3_p,
55010152Satgutier@umich.edu          C_ld_predec_blk_out,
55110152Satgutier@umich.edu          p_to_n_sz_ratio,
55210152Satgutier@umich.edu          is_dram_, false,
55310152Satgutier@umich.edu          g_tp.max_w_nmos_);
55410152Satgutier@umich.edu    }
55510152Satgutier@umich.edu  }
55610152Satgutier@umich.edu}
55710152Satgutier@umich.edu
55810152Satgutier@umich.edu
55910152Satgutier@umich.edu
56010152Satgutier@umich.eduvoid PredecBlk::compute_area()
56110152Satgutier@umich.edu{
56210152Satgutier@umich.edu  if (exist)
56310152Satgutier@umich.edu  { // First check whether a predecoder block is needed
56410152Satgutier@umich.edu    int num_L1_nand2 = 0;
56510152Satgutier@umich.edu    int num_L1_nand3 = 0;
56610152Satgutier@umich.edu    int num_L2 = 0;
56710152Satgutier@umich.edu    double tot_area_L1_nand3  =0;
56810152Satgutier@umich.edu    double leak_L1_nand3      =0;
56910152Satgutier@umich.edu    double gate_leak_L1_nand3 =0;
57010152Satgutier@umich.edu
57110152Satgutier@umich.edu    double tot_area_L1_nand2  = compute_gate_area(NAND, 2, w_L1_nand2_p[0], w_L1_nand2_n[0], g_tp.cell_h_def);
57210152Satgutier@umich.edu    double leak_L1_nand2      = cmos_Isub_leakage(w_L1_nand2_n[0], w_L1_nand2_p[0], 2, nand, is_dram_);
57310152Satgutier@umich.edu    double gate_leak_L1_nand2 = cmos_Ig_leakage(w_L1_nand2_n[0], w_L1_nand2_p[0], 2, nand, is_dram_);
57410152Satgutier@umich.edu    if (number_inputs_L1_gate != 3) {
57510152Satgutier@umich.edu      tot_area_L1_nand3 = 0;
57610152Satgutier@umich.edu      leak_L1_nand3 = 0;
57710152Satgutier@umich.edu      gate_leak_L1_nand3 =0;
57810152Satgutier@umich.edu    }
57910152Satgutier@umich.edu    else {
58010152Satgutier@umich.edu      tot_area_L1_nand3  = compute_gate_area(NAND, 3, w_L1_nand3_p[0], w_L1_nand3_n[0], g_tp.cell_h_def);
58110152Satgutier@umich.edu      leak_L1_nand3      = cmos_Isub_leakage(w_L1_nand3_n[0], w_L1_nand3_p[0], 3, nand);
58210152Satgutier@umich.edu      gate_leak_L1_nand3 = cmos_Ig_leakage(w_L1_nand3_n[0], w_L1_nand3_p[0], 3, nand);
58310152Satgutier@umich.edu    }
58410152Satgutier@umich.edu
58510152Satgutier@umich.edu    switch (number_input_addr_bits)
58610152Satgutier@umich.edu    {
58710152Satgutier@umich.edu      case 1: //2 NAND2 gates
58810152Satgutier@umich.edu        num_L1_nand2 = 2;
58910152Satgutier@umich.edu        num_L2       = 0;
59010152Satgutier@umich.edu        num_L1_active_nand2_path =1;
59110152Satgutier@umich.edu        num_L1_active_nand3_path =0;
59210152Satgutier@umich.edu        break;
59310152Satgutier@umich.edu      case 2: //4 NAND2 gates
59410152Satgutier@umich.edu        num_L1_nand2 = 4;
59510152Satgutier@umich.edu        num_L2       = 0;
59610152Satgutier@umich.edu        num_L1_active_nand2_path =1;
59710152Satgutier@umich.edu        num_L1_active_nand3_path =0;
59810152Satgutier@umich.edu        break;
59910152Satgutier@umich.edu      case 3: //8 NAND3 gates
60010152Satgutier@umich.edu        num_L1_nand3 = 8;
60110152Satgutier@umich.edu        num_L2       = 0;
60210152Satgutier@umich.edu        num_L1_active_nand2_path =0;
60310152Satgutier@umich.edu        num_L1_active_nand3_path =1;
60410152Satgutier@umich.edu        break;
60510152Satgutier@umich.edu      case 4: //4 + 4 NAND2 gates
60610152Satgutier@umich.edu        num_L1_nand2 = 8;
60710152Satgutier@umich.edu        num_L2       = 16;
60810152Satgutier@umich.edu        num_L1_active_nand2_path =2;
60910152Satgutier@umich.edu        num_L1_active_nand3_path =0;
61010152Satgutier@umich.edu        break;
61110152Satgutier@umich.edu      case 5: //4 NAND2 gates, 8 NAND3 gates
61210152Satgutier@umich.edu        num_L1_nand2 = 4;
61310152Satgutier@umich.edu        num_L1_nand3 = 8;
61410152Satgutier@umich.edu        num_L2       = 32;
61510152Satgutier@umich.edu        num_L1_active_nand2_path =1;
61610152Satgutier@umich.edu        num_L1_active_nand3_path =1;
61710152Satgutier@umich.edu        break;
61810152Satgutier@umich.edu      case 6: //8 + 8 NAND3 gates
61910152Satgutier@umich.edu        num_L1_nand3 = 16;
62010152Satgutier@umich.edu        num_L2       = 64;
62110152Satgutier@umich.edu        num_L1_active_nand2_path =0;
62210152Satgutier@umich.edu        num_L1_active_nand3_path =2;
62310152Satgutier@umich.edu        break;
62410152Satgutier@umich.edu      case 7: //4 + 4 NAND2 gates, 8 NAND3 gates
62510152Satgutier@umich.edu        num_L1_nand2 = 8;
62610152Satgutier@umich.edu        num_L1_nand3 = 8;
62710152Satgutier@umich.edu        num_L2       = 128;
62810152Satgutier@umich.edu        num_L1_active_nand2_path =2;
62910152Satgutier@umich.edu        num_L1_active_nand3_path =1;
63010152Satgutier@umich.edu        break;
63110152Satgutier@umich.edu      case 8: //4 NAND2 gates, 8 + 8 NAND3 gates
63210152Satgutier@umich.edu        num_L1_nand2 = 4;
63310152Satgutier@umich.edu        num_L1_nand3 = 16;
63410152Satgutier@umich.edu        num_L2       = 256;
63510152Satgutier@umich.edu        num_L1_active_nand2_path =2;
63610152Satgutier@umich.edu        num_L1_active_nand3_path =2;
63710152Satgutier@umich.edu        break;
63810152Satgutier@umich.edu      case 9: //8 + 8 + 8 NAND3 gates
63910152Satgutier@umich.edu        num_L1_nand3 = 24;
64010152Satgutier@umich.edu        num_L2       = 512;
64110152Satgutier@umich.edu        num_L1_active_nand2_path =0;
64210152Satgutier@umich.edu        num_L1_active_nand3_path =3;
64310152Satgutier@umich.edu        break;
64410152Satgutier@umich.edu      default:
64510152Satgutier@umich.edu        break;
64610152Satgutier@umich.edu    }
64710152Satgutier@umich.edu
64810152Satgutier@umich.edu    for (int i = 1; i < number_gates_L1_nand2_path; ++i)
64910152Satgutier@umich.edu    {
65010152Satgutier@umich.edu      tot_area_L1_nand2  += compute_gate_area(INV, 1, w_L1_nand2_p[i], w_L1_nand2_n[i], g_tp.cell_h_def);
65110152Satgutier@umich.edu      leak_L1_nand2      += cmos_Isub_leakage(w_L1_nand2_n[i], w_L1_nand2_p[i], 2, nand, is_dram_);
65210152Satgutier@umich.edu      gate_leak_L1_nand2 += cmos_Ig_leakage(w_L1_nand2_n[i], w_L1_nand2_p[i], 2, nand, is_dram_);
65310152Satgutier@umich.edu    }
65410152Satgutier@umich.edu    tot_area_L1_nand2  *= num_L1_nand2;
65510152Satgutier@umich.edu    leak_L1_nand2      *= num_L1_nand2;
65610152Satgutier@umich.edu    gate_leak_L1_nand2 *= num_L1_nand2;
65710152Satgutier@umich.edu
65810152Satgutier@umich.edu    for (int i = 1; i < number_gates_L1_nand3_path; ++i)
65910152Satgutier@umich.edu    {
66010152Satgutier@umich.edu      tot_area_L1_nand3  += compute_gate_area(INV, 1, w_L1_nand3_p[i], w_L1_nand3_n[i], g_tp.cell_h_def);
66110152Satgutier@umich.edu      leak_L1_nand3      += cmos_Isub_leakage(w_L1_nand3_n[i], w_L1_nand3_p[i], 3, nand, is_dram_);
66210152Satgutier@umich.edu      gate_leak_L1_nand3 += cmos_Ig_leakage(w_L1_nand3_n[i], w_L1_nand3_p[i], 3, nand, is_dram_);
66310152Satgutier@umich.edu    }
66410152Satgutier@umich.edu    tot_area_L1_nand3  *= num_L1_nand3;
66510152Satgutier@umich.edu    leak_L1_nand3      *= num_L1_nand3;
66610152Satgutier@umich.edu    gate_leak_L1_nand3 *= num_L1_nand3;
66710152Satgutier@umich.edu
66810152Satgutier@umich.edu    double cumulative_area_L1 = tot_area_L1_nand2 + tot_area_L1_nand3;
66910152Satgutier@umich.edu    double cumulative_area_L2 = 0.0;
67010152Satgutier@umich.edu    double leakage_L2         = 0.0;
67110152Satgutier@umich.edu    double gate_leakage_L2    = 0.0;
67210152Satgutier@umich.edu
67310152Satgutier@umich.edu    if (flag_L2_gate == 2)
67410152Satgutier@umich.edu    {
67510152Satgutier@umich.edu      cumulative_area_L2 = compute_gate_area(NAND, 2, w_L2_p[0], w_L2_n[0], g_tp.cell_h_def);
67610152Satgutier@umich.edu      leakage_L2         = cmos_Isub_leakage(w_L2_n[0], w_L2_p[0], 2, nand, is_dram_);
67710152Satgutier@umich.edu      gate_leakage_L2    = cmos_Ig_leakage(w_L2_n[0], w_L2_p[0], 2, nand, is_dram_);
67810152Satgutier@umich.edu    }
67910152Satgutier@umich.edu    else if (flag_L2_gate == 3)
68010152Satgutier@umich.edu    {
68110152Satgutier@umich.edu      cumulative_area_L2 = compute_gate_area(NAND, 3, w_L2_p[0], w_L2_n[0], g_tp.cell_h_def);
68210152Satgutier@umich.edu      leakage_L2         = cmos_Isub_leakage(w_L2_n[0], w_L2_p[0], 3, nand, is_dram_);
68310152Satgutier@umich.edu      gate_leakage_L2    = cmos_Ig_leakage(w_L2_n[0], w_L2_p[0], 3, nand, is_dram_);
68410152Satgutier@umich.edu    }
68510152Satgutier@umich.edu
68610152Satgutier@umich.edu    for (int i = 1; i < number_gates_L2; ++i)
68710152Satgutier@umich.edu    {
68810152Satgutier@umich.edu      cumulative_area_L2 += compute_gate_area(INV, 1, w_L2_p[i], w_L2_n[i], g_tp.cell_h_def);
68910152Satgutier@umich.edu      leakage_L2         += cmos_Isub_leakage(w_L2_n[i], w_L2_p[i], 2, inv, is_dram_);
69010152Satgutier@umich.edu      gate_leakage_L2    += cmos_Ig_leakage(w_L2_n[i], w_L2_p[i], 2, inv, is_dram_);
69110152Satgutier@umich.edu    }
69210152Satgutier@umich.edu    cumulative_area_L2 *= num_L2;
69310152Satgutier@umich.edu    leakage_L2         *= num_L2;
69410152Satgutier@umich.edu    gate_leakage_L2    *= num_L2;
69510152Satgutier@umich.edu
69610152Satgutier@umich.edu    power_nand2_path.readOp.leakage = leak_L1_nand2 * g_tp.peri_global.Vdd;
69710152Satgutier@umich.edu    power_nand3_path.readOp.leakage = leak_L1_nand3 * g_tp.peri_global.Vdd;
69810152Satgutier@umich.edu    power_L2.readOp.leakage         = leakage_L2    * g_tp.peri_global.Vdd;
69910152Satgutier@umich.edu    area.set_area(cumulative_area_L1 + cumulative_area_L2);
70010152Satgutier@umich.edu    power_nand2_path.readOp.gate_leakage = gate_leak_L1_nand2 * g_tp.peri_global.Vdd;
70110152Satgutier@umich.edu    power_nand3_path.readOp.gate_leakage = gate_leak_L1_nand3 * g_tp.peri_global.Vdd;
70210152Satgutier@umich.edu    power_L2.readOp.gate_leakage         = gate_leakage_L2    * g_tp.peri_global.Vdd;
70310152Satgutier@umich.edu  }
70410152Satgutier@umich.edu}
70510152Satgutier@umich.edu
70610152Satgutier@umich.edu
70710152Satgutier@umich.edu
70810152Satgutier@umich.edupair<double, double> PredecBlk::compute_delays(
70910152Satgutier@umich.edu    pair<double, double> inrisetime)  // <nand2, nand3>
71010152Satgutier@umich.edu{
71110152Satgutier@umich.edu  pair<double, double> ret_val;
71210152Satgutier@umich.edu  ret_val.first  = 0;  // outrisetime_nand2_path
71310152Satgutier@umich.edu  ret_val.second = 0;  // outrisetime_nand3_path
71410152Satgutier@umich.edu
71510152Satgutier@umich.edu  double inrisetime_nand2_path = inrisetime.first;
71610152Satgutier@umich.edu  double inrisetime_nand3_path = inrisetime.second;
71710152Satgutier@umich.edu  int    i;
71810152Satgutier@umich.edu  double rd, c_load, c_intrinsic, tf, this_delay;
71910152Satgutier@umich.edu  double Vdd = g_tp.peri_global.Vdd;
72010152Satgutier@umich.edu
72110152Satgutier@umich.edu  // TODO: following delay calculation part can be greatly simplified.
72210152Satgutier@umich.edu  // first check whether a predecoder block is required
72310152Satgutier@umich.edu  if (exist)
72410152Satgutier@umich.edu  {
72510152Satgutier@umich.edu    //Find delay in first level of predecoder block
72610152Satgutier@umich.edu    //First find delay in path
72710152Satgutier@umich.edu    if ((flag_two_unique_paths) || (number_inputs_L1_gate == 2))
72810152Satgutier@umich.edu    {
72910152Satgutier@umich.edu      //First gate is a NAND2 gate
73010152Satgutier@umich.edu      rd = tr_R_on(w_L1_nand2_n[0], NCH, 2, is_dram_);
73110152Satgutier@umich.edu      c_load = gate_C(w_L1_nand2_n[1] + w_L1_nand2_p[1], 0.0, is_dram_);
73210152Satgutier@umich.edu      c_intrinsic = 2 * drain_C_(w_L1_nand2_p[0], PCH, 1, 1, g_tp.cell_h_def, is_dram_) +
73310152Satgutier@umich.edu                        drain_C_(w_L1_nand2_n[0], NCH, 2, 1, g_tp.cell_h_def, is_dram_);
73410152Satgutier@umich.edu      tf = rd * (c_intrinsic + c_load);
73510152Satgutier@umich.edu      this_delay = horowitz(inrisetime_nand2_path, tf, 0.5, 0.5, RISE);
73610152Satgutier@umich.edu      delay_nand2_path += this_delay;
73710152Satgutier@umich.edu      inrisetime_nand2_path = this_delay / (1.0 - 0.5);
73810152Satgutier@umich.edu      power_nand2_path.readOp.dynamic += (c_load + c_intrinsic) * Vdd * Vdd;
73910152Satgutier@umich.edu
74010152Satgutier@umich.edu      //Add delays of all but the last inverter in the chain
74110152Satgutier@umich.edu      for (i = 1; i < number_gates_L1_nand2_path - 1; ++i)
74210152Satgutier@umich.edu      {
74310152Satgutier@umich.edu        rd = tr_R_on(w_L1_nand2_n[i], NCH, 1, is_dram_);
74410152Satgutier@umich.edu        c_load = gate_C(w_L1_nand2_n[i+1] + w_L1_nand2_p[i+1], 0.0, is_dram_);
74510152Satgutier@umich.edu        c_intrinsic = drain_C_(w_L1_nand2_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) +
74610152Satgutier@umich.edu                      drain_C_(w_L1_nand2_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_);
74710152Satgutier@umich.edu        tf = rd * (c_intrinsic + c_load);
74810152Satgutier@umich.edu        this_delay = horowitz(inrisetime_nand2_path, tf, 0.5, 0.5, RISE);
74910152Satgutier@umich.edu        delay_nand2_path += this_delay;
75010152Satgutier@umich.edu        inrisetime_nand2_path = this_delay / (1.0 - 0.5);
75110152Satgutier@umich.edu        power_nand2_path.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd;
75210152Satgutier@umich.edu      }
75310152Satgutier@umich.edu
75410152Satgutier@umich.edu      //Add delay of the last inverter
75510152Satgutier@umich.edu      i = number_gates_L1_nand2_path - 1;
75610152Satgutier@umich.edu      rd = tr_R_on(w_L1_nand2_n[i], NCH, 1, is_dram_);
75710152Satgutier@umich.edu      if (flag_L2_gate)
75810152Satgutier@umich.edu      {
75910152Satgutier@umich.edu        c_load = branch_effort_nand2_gate_output*(gate_C(w_L2_n[0], 0, is_dram_) + gate_C(w_L2_p[0], 0, is_dram_));
76010152Satgutier@umich.edu        c_intrinsic = drain_C_(w_L1_nand2_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) +
76110152Satgutier@umich.edu                      drain_C_(w_L1_nand2_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_);
76210152Satgutier@umich.edu        tf = rd * (c_intrinsic + c_load);
76310152Satgutier@umich.edu        this_delay = horowitz(inrisetime_nand2_path, tf, 0.5, 0.5, RISE);
76410152Satgutier@umich.edu        delay_nand2_path += this_delay;
76510152Satgutier@umich.edu        inrisetime_nand2_path = this_delay / (1.0 - 0.5);
76610152Satgutier@umich.edu        power_nand2_path.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd;
76710152Satgutier@umich.edu      }
76810152Satgutier@umich.edu      else
76910152Satgutier@umich.edu      { //First level directly drives decoder output load
77010152Satgutier@umich.edu        c_load = C_ld_predec_blk_out;
77110152Satgutier@umich.edu        c_intrinsic = drain_C_(w_L1_nand2_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) +
77210152Satgutier@umich.edu                      drain_C_(w_L1_nand2_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_);
77310152Satgutier@umich.edu        tf = rd * (c_intrinsic + c_load) + R_wire_predec_blk_out * c_load / 2;
77410152Satgutier@umich.edu        this_delay = horowitz(inrisetime_nand2_path, tf, 0.5, 0.5, RISE);
77510152Satgutier@umich.edu        delay_nand2_path += this_delay;
77610152Satgutier@umich.edu        ret_val.first = this_delay / (1.0 - 0.5);
77710152Satgutier@umich.edu        power_nand2_path.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd;
77810152Satgutier@umich.edu      }
77910152Satgutier@umich.edu    }
78010152Satgutier@umich.edu
78110152Satgutier@umich.edu    if ((flag_two_unique_paths) || (number_inputs_L1_gate == 3))
78210152Satgutier@umich.edu    { //Check if the number of gates in the first level is more than 1.
78310152Satgutier@umich.edu      //First gate is a NAND3 gate
78410152Satgutier@umich.edu      rd = tr_R_on(w_L1_nand3_n[0], NCH, 3, is_dram_);
78510152Satgutier@umich.edu      c_load = gate_C(w_L1_nand3_n[1] + w_L1_nand3_p[1], 0.0, is_dram_);
78610152Satgutier@umich.edu      c_intrinsic = 3 * drain_C_(w_L1_nand3_p[0], PCH, 1, 1, g_tp.cell_h_def, is_dram_) +
78710152Satgutier@umich.edu                        drain_C_(w_L1_nand3_n[0], NCH, 3, 1, g_tp.cell_h_def, is_dram_);
78810152Satgutier@umich.edu      tf = rd * (c_intrinsic + c_load);
78910152Satgutier@umich.edu      this_delay = horowitz(inrisetime_nand3_path, tf, 0.5, 0.5, RISE);
79010152Satgutier@umich.edu      delay_nand3_path += this_delay;
79110152Satgutier@umich.edu      inrisetime_nand3_path = this_delay / (1.0 - 0.5);
79210152Satgutier@umich.edu      power_nand3_path.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd;
79310152Satgutier@umich.edu
79410152Satgutier@umich.edu      //Add delays of all but the last inverter in the chain
79510152Satgutier@umich.edu      for (i = 1; i < number_gates_L1_nand3_path - 1; ++i)
79610152Satgutier@umich.edu      {
79710152Satgutier@umich.edu        rd = tr_R_on(w_L1_nand3_n[i], NCH, 1, is_dram_);
79810152Satgutier@umich.edu        c_load = gate_C(w_L1_nand3_n[i+1] + w_L1_nand3_p[i+1], 0.0, is_dram_);
79910152Satgutier@umich.edu        c_intrinsic = drain_C_(w_L1_nand3_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) +
80010152Satgutier@umich.edu                      drain_C_(w_L1_nand3_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_);
80110152Satgutier@umich.edu        tf = rd * (c_intrinsic + c_load);
80210152Satgutier@umich.edu        this_delay = horowitz(inrisetime_nand3_path, tf, 0.5, 0.5, RISE);
80310152Satgutier@umich.edu        delay_nand3_path += this_delay;
80410152Satgutier@umich.edu        inrisetime_nand3_path = this_delay / (1.0 - 0.5);
80510152Satgutier@umich.edu        power_nand3_path.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd;
80610152Satgutier@umich.edu      }
80710152Satgutier@umich.edu
80810152Satgutier@umich.edu      //Add delay of the last inverter
80910152Satgutier@umich.edu      i = number_gates_L1_nand3_path - 1;
81010152Satgutier@umich.edu      rd = tr_R_on(w_L1_nand3_n[i], NCH, 1, is_dram_);
81110152Satgutier@umich.edu      if (flag_L2_gate)
81210152Satgutier@umich.edu      {
81310152Satgutier@umich.edu        c_load = branch_effort_nand3_gate_output*(gate_C(w_L2_n[0], 0, is_dram_) + gate_C(w_L2_p[0], 0, is_dram_));
81410152Satgutier@umich.edu        c_intrinsic = drain_C_(w_L1_nand3_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) +
81510152Satgutier@umich.edu                      drain_C_(w_L1_nand3_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_);
81610152Satgutier@umich.edu        tf = rd * (c_intrinsic + c_load);
81710152Satgutier@umich.edu        this_delay = horowitz(inrisetime_nand3_path, tf, 0.5, 0.5, RISE);
81810152Satgutier@umich.edu        delay_nand3_path += this_delay;
81910152Satgutier@umich.edu        inrisetime_nand3_path = this_delay / (1.0 - 0.5);
82010152Satgutier@umich.edu        power_nand3_path.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd;
82110152Satgutier@umich.edu      }
82210152Satgutier@umich.edu      else
82310152Satgutier@umich.edu      { //First level directly drives decoder output load
82410152Satgutier@umich.edu        c_load = C_ld_predec_blk_out;
82510152Satgutier@umich.edu        c_intrinsic = drain_C_(w_L1_nand3_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) +
82610152Satgutier@umich.edu                      drain_C_(w_L1_nand3_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_);
82710152Satgutier@umich.edu        tf = rd * (c_intrinsic + c_load) + R_wire_predec_blk_out * c_load / 2;
82810152Satgutier@umich.edu        this_delay = horowitz(inrisetime_nand3_path, tf, 0.5, 0.5, RISE);
82910152Satgutier@umich.edu        delay_nand3_path += this_delay;
83010152Satgutier@umich.edu        ret_val.second = this_delay / (1.0 - 0.5);
83110152Satgutier@umich.edu        power_nand3_path.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd;
83210152Satgutier@umich.edu      }
83310152Satgutier@umich.edu    }
83410152Satgutier@umich.edu
83510152Satgutier@umich.edu    // Find delay through second level
83610152Satgutier@umich.edu    if (flag_L2_gate)
83710152Satgutier@umich.edu    {
83810152Satgutier@umich.edu      if (flag_L2_gate == 2)
83910152Satgutier@umich.edu      {
84010152Satgutier@umich.edu        rd = tr_R_on(w_L2_n[0], NCH, 2, is_dram_);
84110152Satgutier@umich.edu        c_load = gate_C(w_L2_n[1] + w_L2_p[1], 0.0, is_dram_);
84210152Satgutier@umich.edu        c_intrinsic = 2 * drain_C_(w_L2_p[0], PCH, 1, 1, g_tp.cell_h_def, is_dram_) +
84310152Satgutier@umich.edu                          drain_C_(w_L2_n[0], NCH, 2, 1, g_tp.cell_h_def, is_dram_);
84410152Satgutier@umich.edu        tf = rd * (c_intrinsic + c_load);
84510152Satgutier@umich.edu        this_delay = horowitz(inrisetime_nand2_path, tf, 0.5, 0.5, RISE);
84610152Satgutier@umich.edu        delay_nand2_path += this_delay;
84710152Satgutier@umich.edu        inrisetime_nand2_path = this_delay / (1.0 - 0.5);
84810152Satgutier@umich.edu        power_L2.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd;
84910152Satgutier@umich.edu      }
85010152Satgutier@umich.edu      else
85110152Satgutier@umich.edu      { // flag_L2_gate = 3
85210152Satgutier@umich.edu        rd = tr_R_on(w_L2_n[0], NCH, 3, is_dram_);
85310152Satgutier@umich.edu        c_load = gate_C(w_L2_n[1] + w_L2_p[1], 0.0, is_dram_);
85410152Satgutier@umich.edu        c_intrinsic = 3 * drain_C_(w_L2_p[0], PCH, 1, 1, g_tp.cell_h_def, is_dram_) +
85510152Satgutier@umich.edu                          drain_C_(w_L2_n[0], NCH, 3, 1, g_tp.cell_h_def, is_dram_);
85610152Satgutier@umich.edu        tf = rd * (c_intrinsic + c_load);
85710152Satgutier@umich.edu        this_delay = horowitz(inrisetime_nand3_path, tf, 0.5, 0.5, RISE);
85810152Satgutier@umich.edu        delay_nand3_path += this_delay;
85910152Satgutier@umich.edu        inrisetime_nand3_path = this_delay / (1.0 - 0.5);
86010152Satgutier@umich.edu        power_L2.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd;
86110152Satgutier@umich.edu      }
86210152Satgutier@umich.edu
86310152Satgutier@umich.edu      for (i = 1; i < number_gates_L2 - 1; ++i)
86410152Satgutier@umich.edu      {
86510152Satgutier@umich.edu        rd = tr_R_on(w_L2_n[i], NCH, 1, is_dram_);
86610152Satgutier@umich.edu        c_load = gate_C(w_L2_n[i+1] + w_L2_p[i+1], 0.0, is_dram_);
86710152Satgutier@umich.edu        c_intrinsic = drain_C_(w_L2_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) +
86810152Satgutier@umich.edu                      drain_C_(w_L2_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_);
86910152Satgutier@umich.edu        tf = rd * (c_intrinsic + c_load);
87010152Satgutier@umich.edu        this_delay = horowitz(inrisetime_nand2_path, tf, 0.5, 0.5, RISE);
87110152Satgutier@umich.edu        delay_nand2_path += this_delay;
87210152Satgutier@umich.edu        inrisetime_nand2_path = this_delay / (1.0 - 0.5);
87310152Satgutier@umich.edu        this_delay = horowitz(inrisetime_nand3_path, tf, 0.5, 0.5, RISE);
87410152Satgutier@umich.edu        delay_nand3_path += this_delay;
87510152Satgutier@umich.edu        inrisetime_nand3_path = this_delay / (1.0 - 0.5);
87610152Satgutier@umich.edu        power_L2.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd;
87710152Satgutier@umich.edu      }
87810152Satgutier@umich.edu
87910152Satgutier@umich.edu      //Add delay of final inverter that drives the wordline decoders
88010152Satgutier@umich.edu      i = number_gates_L2 - 1;
88110152Satgutier@umich.edu      c_load = C_ld_predec_blk_out;
88210152Satgutier@umich.edu      rd = tr_R_on(w_L2_n[i], NCH, 1, is_dram_);
88310152Satgutier@umich.edu      c_intrinsic = drain_C_(w_L2_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) +
88410152Satgutier@umich.edu                    drain_C_(w_L2_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_);
88510152Satgutier@umich.edu      tf = rd * (c_intrinsic + c_load) + R_wire_predec_blk_out * c_load / 2;
88610152Satgutier@umich.edu      this_delay = horowitz(inrisetime_nand2_path, tf, 0.5, 0.5, RISE);
88710152Satgutier@umich.edu      delay_nand2_path += this_delay;
88810152Satgutier@umich.edu      ret_val.first = this_delay / (1.0 - 0.5);
88910152Satgutier@umich.edu      this_delay = horowitz(inrisetime_nand3_path, tf, 0.5, 0.5, RISE);
89010152Satgutier@umich.edu      delay_nand3_path += this_delay;
89110152Satgutier@umich.edu      ret_val.second = this_delay / (1.0 - 0.5);
89210152Satgutier@umich.edu      power_L2.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd;
89310152Satgutier@umich.edu    }
89410152Satgutier@umich.edu  }
89510152Satgutier@umich.edu
89610152Satgutier@umich.edu  delay = (ret_val.first > ret_val.second) ? ret_val.first : ret_val.second;
89710152Satgutier@umich.edu  return ret_val;
89810152Satgutier@umich.edu}
89910152Satgutier@umich.edu
90010152Satgutier@umich.eduvoid PredecBlk::leakage_feedback(double temperature)
90110152Satgutier@umich.edu{
90210152Satgutier@umich.edu  if (exist)
90310152Satgutier@umich.edu  { // First check whether a predecoder block is needed
90410152Satgutier@umich.edu    int num_L1_nand2 = 0;
90510152Satgutier@umich.edu    int num_L1_nand3 = 0;
90610152Satgutier@umich.edu    int num_L2 = 0;
90710152Satgutier@umich.edu    double leak_L1_nand3      =0;
90810152Satgutier@umich.edu    double gate_leak_L1_nand3 =0;
90910152Satgutier@umich.edu
91010152Satgutier@umich.edu    double leak_L1_nand2      = cmos_Isub_leakage(w_L1_nand2_n[0], w_L1_nand2_p[0], 2, nand, is_dram_);
91110152Satgutier@umich.edu    double gate_leak_L1_nand2 = cmos_Ig_leakage(w_L1_nand2_n[0], w_L1_nand2_p[0], 2, nand, is_dram_);
91210152Satgutier@umich.edu    if (number_inputs_L1_gate != 3) {
91310152Satgutier@umich.edu      leak_L1_nand3 = 0;
91410152Satgutier@umich.edu      gate_leak_L1_nand3 =0;
91510152Satgutier@umich.edu    }
91610152Satgutier@umich.edu    else {
91710152Satgutier@umich.edu      leak_L1_nand3      = cmos_Isub_leakage(w_L1_nand3_n[0], w_L1_nand3_p[0], 3, nand);
91810152Satgutier@umich.edu      gate_leak_L1_nand3 = cmos_Ig_leakage(w_L1_nand3_n[0], w_L1_nand3_p[0], 3, nand);
91910152Satgutier@umich.edu    }
92010152Satgutier@umich.edu
92110152Satgutier@umich.edu    switch (number_input_addr_bits)
92210152Satgutier@umich.edu    {
92310152Satgutier@umich.edu      case 1: //2 NAND2 gates
92410152Satgutier@umich.edu        num_L1_nand2 = 2;
92510152Satgutier@umich.edu        num_L2       = 0;
92610152Satgutier@umich.edu        num_L1_active_nand2_path =1;
92710152Satgutier@umich.edu        num_L1_active_nand3_path =0;
92810152Satgutier@umich.edu        break;
92910152Satgutier@umich.edu      case 2: //4 NAND2 gates
93010152Satgutier@umich.edu        num_L1_nand2 = 4;
93110152Satgutier@umich.edu        num_L2       = 0;
93210152Satgutier@umich.edu        num_L1_active_nand2_path =1;
93310152Satgutier@umich.edu        num_L1_active_nand3_path =0;
93410152Satgutier@umich.edu        break;
93510152Satgutier@umich.edu      case 3: //8 NAND3 gates
93610152Satgutier@umich.edu        num_L1_nand3 = 8;
93710152Satgutier@umich.edu        num_L2       = 0;
93810152Satgutier@umich.edu        num_L1_active_nand2_path =0;
93910152Satgutier@umich.edu        num_L1_active_nand3_path =1;
94010152Satgutier@umich.edu        break;
94110152Satgutier@umich.edu      case 4: //4 + 4 NAND2 gates
94210152Satgutier@umich.edu        num_L1_nand2 = 8;
94310152Satgutier@umich.edu        num_L2       = 16;
94410152Satgutier@umich.edu        num_L1_active_nand2_path =2;
94510152Satgutier@umich.edu        num_L1_active_nand3_path =0;
94610152Satgutier@umich.edu        break;
94710152Satgutier@umich.edu      case 5: //4 NAND2 gates, 8 NAND3 gates
94810152Satgutier@umich.edu        num_L1_nand2 = 4;
94910152Satgutier@umich.edu        num_L1_nand3 = 8;
95010152Satgutier@umich.edu        num_L2       = 32;
95110152Satgutier@umich.edu        num_L1_active_nand2_path =1;
95210152Satgutier@umich.edu        num_L1_active_nand3_path =1;
95310152Satgutier@umich.edu        break;
95410152Satgutier@umich.edu      case 6: //8 + 8 NAND3 gates
95510152Satgutier@umich.edu        num_L1_nand3 = 16;
95610152Satgutier@umich.edu        num_L2       = 64;
95710152Satgutier@umich.edu        num_L1_active_nand2_path =0;
95810152Satgutier@umich.edu        num_L1_active_nand3_path =2;
95910152Satgutier@umich.edu        break;
96010152Satgutier@umich.edu      case 7: //4 + 4 NAND2 gates, 8 NAND3 gates
96110152Satgutier@umich.edu        num_L1_nand2 = 8;
96210152Satgutier@umich.edu        num_L1_nand3 = 8;
96310152Satgutier@umich.edu        num_L2       = 128;
96410152Satgutier@umich.edu        num_L1_active_nand2_path =2;
96510152Satgutier@umich.edu        num_L1_active_nand3_path =1;
96610152Satgutier@umich.edu        break;
96710152Satgutier@umich.edu      case 8: //4 NAND2 gates, 8 + 8 NAND3 gates
96810152Satgutier@umich.edu        num_L1_nand2 = 4;
96910152Satgutier@umich.edu        num_L1_nand3 = 16;
97010152Satgutier@umich.edu        num_L2       = 256;
97110152Satgutier@umich.edu        num_L1_active_nand2_path =2;
97210152Satgutier@umich.edu        num_L1_active_nand3_path =2;
97310152Satgutier@umich.edu        break;
97410152Satgutier@umich.edu      case 9: //8 + 8 + 8 NAND3 gates
97510152Satgutier@umich.edu        num_L1_nand3 = 24;
97610152Satgutier@umich.edu        num_L2       = 512;
97710152Satgutier@umich.edu        num_L1_active_nand2_path =0;
97810152Satgutier@umich.edu        num_L1_active_nand3_path =3;
97910152Satgutier@umich.edu        break;
98010152Satgutier@umich.edu      default:
98110152Satgutier@umich.edu        break;
98210152Satgutier@umich.edu    }
98310152Satgutier@umich.edu
98410152Satgutier@umich.edu    for (int i = 1; i < number_gates_L1_nand2_path; ++i)
98510152Satgutier@umich.edu    {
98610152Satgutier@umich.edu      leak_L1_nand2      += cmos_Isub_leakage(w_L1_nand2_n[i], w_L1_nand2_p[i], 2, nand, is_dram_);
98710152Satgutier@umich.edu      gate_leak_L1_nand2 += cmos_Ig_leakage(w_L1_nand2_n[i], w_L1_nand2_p[i], 2, nand, is_dram_);
98810152Satgutier@umich.edu    }
98910152Satgutier@umich.edu    leak_L1_nand2      *= num_L1_nand2;
99010152Satgutier@umich.edu    gate_leak_L1_nand2 *= num_L1_nand2;
99110152Satgutier@umich.edu
99210152Satgutier@umich.edu    for (int i = 1; i < number_gates_L1_nand3_path; ++i)
99310152Satgutier@umich.edu    {
99410152Satgutier@umich.edu      leak_L1_nand3      += cmos_Isub_leakage(w_L1_nand3_n[i], w_L1_nand3_p[i], 3, nand, is_dram_);
99510152Satgutier@umich.edu      gate_leak_L1_nand3 += cmos_Ig_leakage(w_L1_nand3_n[i], w_L1_nand3_p[i], 3, nand, is_dram_);
99610152Satgutier@umich.edu    }
99710152Satgutier@umich.edu    leak_L1_nand3      *= num_L1_nand3;
99810152Satgutier@umich.edu    gate_leak_L1_nand3 *= num_L1_nand3;
99910152Satgutier@umich.edu
100010152Satgutier@umich.edu    double leakage_L2         = 0.0;
100110152Satgutier@umich.edu    double gate_leakage_L2    = 0.0;
100210152Satgutier@umich.edu
100310152Satgutier@umich.edu    if (flag_L2_gate == 2)
100410152Satgutier@umich.edu    {
100510152Satgutier@umich.edu      leakage_L2         = cmos_Isub_leakage(w_L2_n[0], w_L2_p[0], 2, nand, is_dram_);
100610152Satgutier@umich.edu      gate_leakage_L2    = cmos_Ig_leakage(w_L2_n[0], w_L2_p[0], 2, nand, is_dram_);
100710152Satgutier@umich.edu    }
100810152Satgutier@umich.edu    else if (flag_L2_gate == 3)
100910152Satgutier@umich.edu    {
101010152Satgutier@umich.edu      leakage_L2         = cmos_Isub_leakage(w_L2_n[0], w_L2_p[0], 3, nand, is_dram_);
101110152Satgutier@umich.edu      gate_leakage_L2    = cmos_Ig_leakage(w_L2_n[0], w_L2_p[0], 3, nand, is_dram_);
101210152Satgutier@umich.edu    }
101310152Satgutier@umich.edu
101410152Satgutier@umich.edu    for (int i = 1; i < number_gates_L2; ++i)
101510152Satgutier@umich.edu    {
101610152Satgutier@umich.edu      leakage_L2         += cmos_Isub_leakage(w_L2_n[i], w_L2_p[i], 2, inv, is_dram_);
101710152Satgutier@umich.edu      gate_leakage_L2    += cmos_Ig_leakage(w_L2_n[i], w_L2_p[i], 2, inv, is_dram_);
101810152Satgutier@umich.edu    }
101910152Satgutier@umich.edu    leakage_L2         *= num_L2;
102010152Satgutier@umich.edu    gate_leakage_L2    *= num_L2;
102110152Satgutier@umich.edu
102210152Satgutier@umich.edu    power_nand2_path.readOp.leakage = leak_L1_nand2 * g_tp.peri_global.Vdd;
102310152Satgutier@umich.edu    power_nand3_path.readOp.leakage = leak_L1_nand3 * g_tp.peri_global.Vdd;
102410152Satgutier@umich.edu    power_L2.readOp.leakage         = leakage_L2    * g_tp.peri_global.Vdd;
102510152Satgutier@umich.edu
102610152Satgutier@umich.edu    power_nand2_path.readOp.gate_leakage = gate_leak_L1_nand2 * g_tp.peri_global.Vdd;
102710152Satgutier@umich.edu    power_nand3_path.readOp.gate_leakage = gate_leak_L1_nand3 * g_tp.peri_global.Vdd;
102810152Satgutier@umich.edu    power_L2.readOp.gate_leakage         = gate_leakage_L2    * g_tp.peri_global.Vdd;
102910152Satgutier@umich.edu  }
103010152Satgutier@umich.edu}
103110152Satgutier@umich.edu
103210152Satgutier@umich.eduPredecBlkDrv::PredecBlkDrv(
103310152Satgutier@umich.edu    int    way_select_,
103410152Satgutier@umich.edu    PredecBlk * blk_,
103510152Satgutier@umich.edu    bool   is_dram)
103610152Satgutier@umich.edu :flag_driver_exists(0),
103710152Satgutier@umich.edu  number_gates_nand2_path(0),
103810152Satgutier@umich.edu  number_gates_nand3_path(0),
103910152Satgutier@umich.edu  min_number_gates(2),
104010152Satgutier@umich.edu  num_buffers_driving_1_nand2_load(0),
104110152Satgutier@umich.edu  num_buffers_driving_2_nand2_load(0),
104210152Satgutier@umich.edu  num_buffers_driving_4_nand2_load(0),
104310152Satgutier@umich.edu  num_buffers_driving_2_nand3_load(0),
104410152Satgutier@umich.edu  num_buffers_driving_8_nand3_load(0),
104510152Satgutier@umich.edu  num_buffers_nand3_path(0),
104610152Satgutier@umich.edu  c_load_nand2_path_out(0),
104710152Satgutier@umich.edu  c_load_nand3_path_out(0),
104810152Satgutier@umich.edu  r_load_nand2_path_out(0),
104910152Satgutier@umich.edu  r_load_nand3_path_out(0),
105010152Satgutier@umich.edu  delay_nand2_path(0),
105110152Satgutier@umich.edu  delay_nand3_path(0),
105210152Satgutier@umich.edu  power_nand2_path(),
105310152Satgutier@umich.edu  power_nand3_path(),
105410152Satgutier@umich.edu  blk(blk_), dec(blk->dec),
105510152Satgutier@umich.edu  is_dram_(is_dram),
105610152Satgutier@umich.edu  way_select(way_select_)
105710152Satgutier@umich.edu{
105810152Satgutier@umich.edu  for (int i = 0; i < MAX_NUMBER_GATES_STAGE; i++)
105910152Satgutier@umich.edu  {
106010152Satgutier@umich.edu    width_nand2_path_n[i] = 0;
106110152Satgutier@umich.edu    width_nand2_path_p[i] = 0;
106210152Satgutier@umich.edu    width_nand3_path_n[i] = 0;
106310152Satgutier@umich.edu    width_nand3_path_p[i] = 0;
106410152Satgutier@umich.edu  }
106510152Satgutier@umich.edu
106610152Satgutier@umich.edu  number_input_addr_bits = blk->number_input_addr_bits;
106710152Satgutier@umich.edu
106810152Satgutier@umich.edu  if (way_select > 1)
106910152Satgutier@umich.edu  {
107010152Satgutier@umich.edu    flag_driver_exists     = 1;
107110152Satgutier@umich.edu    number_input_addr_bits = way_select;
107210152Satgutier@umich.edu    if (dec->num_in_signals == 2)
107310152Satgutier@umich.edu    {
107410152Satgutier@umich.edu      c_load_nand2_path_out = gate_C(dec->w_dec_n[0] + dec->w_dec_p[0], 0, is_dram_);
107510152Satgutier@umich.edu      num_buffers_driving_2_nand2_load = number_input_addr_bits;
107610152Satgutier@umich.edu    }
107710152Satgutier@umich.edu    else if (dec->num_in_signals == 3)
107810152Satgutier@umich.edu    {
107910152Satgutier@umich.edu      c_load_nand3_path_out = gate_C(dec->w_dec_n[0] + dec->w_dec_p[0], 0, is_dram_);
108010152Satgutier@umich.edu      num_buffers_driving_2_nand3_load = number_input_addr_bits;
108110152Satgutier@umich.edu    }
108210152Satgutier@umich.edu  }
108310152Satgutier@umich.edu  else if (way_select == 0)
108410152Satgutier@umich.edu  {
108510152Satgutier@umich.edu    if (blk->exist)
108610152Satgutier@umich.edu    {
108710152Satgutier@umich.edu      flag_driver_exists = 1;
108810152Satgutier@umich.edu    }
108910152Satgutier@umich.edu  }
109010152Satgutier@umich.edu
109110152Satgutier@umich.edu  compute_widths();
109210152Satgutier@umich.edu  compute_area();
109310152Satgutier@umich.edu}
109410152Satgutier@umich.edu
109510152Satgutier@umich.edu
109610152Satgutier@umich.edu
109710152Satgutier@umich.eduvoid PredecBlkDrv::compute_widths()
109810152Satgutier@umich.edu{
109910152Satgutier@umich.edu  // The predecode block driver accepts as input the address bits from the h-tree network. For
110010152Satgutier@umich.edu  // each addr bit it then generates addr and addrbar as outputs. For now ignore the effect of
110110152Satgutier@umich.edu  // inversion to generate addrbar and simply treat addrbar as addr.
110210152Satgutier@umich.edu
110310152Satgutier@umich.edu  double F;
110410152Satgutier@umich.edu  double p_to_n_sz_ratio = pmos_to_nmos_sz_ratio(is_dram_);
110510152Satgutier@umich.edu
110610152Satgutier@umich.edu  if (flag_driver_exists)
110710152Satgutier@umich.edu  {
110810152Satgutier@umich.edu    double C_nand2_gate_blk = gate_C(blk->w_L1_nand2_n[0] + blk->w_L1_nand2_p[0], 0, is_dram_);
110910152Satgutier@umich.edu    double C_nand3_gate_blk = gate_C(blk->w_L1_nand3_n[0] + blk->w_L1_nand3_p[0], 0, is_dram_);
111010152Satgutier@umich.edu
111110152Satgutier@umich.edu    if (way_select == 0)
111210152Satgutier@umich.edu    {
111310152Satgutier@umich.edu      if (blk->number_input_addr_bits == 1)
111410152Satgutier@umich.edu      { //2 NAND2 gates
111510152Satgutier@umich.edu        num_buffers_driving_2_nand2_load = 1;
111610152Satgutier@umich.edu        c_load_nand2_path_out            = 2 * C_nand2_gate_blk;
111710152Satgutier@umich.edu      }
111810152Satgutier@umich.edu      else if (blk->number_input_addr_bits == 2)
111910152Satgutier@umich.edu      { //4 NAND2 gates  one 2-4 decoder
112010152Satgutier@umich.edu        num_buffers_driving_4_nand2_load = 2;
112110152Satgutier@umich.edu        c_load_nand2_path_out            = 4 * C_nand2_gate_blk;
112210152Satgutier@umich.edu      }
112310152Satgutier@umich.edu      else if (blk->number_input_addr_bits == 3)
112410152Satgutier@umich.edu      { //8 NAND3 gates  one 3-8 decoder
112510152Satgutier@umich.edu        num_buffers_driving_8_nand3_load = 3;
112610152Satgutier@umich.edu        c_load_nand3_path_out            = 8 * C_nand3_gate_blk;
112710152Satgutier@umich.edu      }
112810152Satgutier@umich.edu      else if (blk->number_input_addr_bits == 4)
112910152Satgutier@umich.edu      { //4 + 4 NAND2 gates two 2-4 decoder
113010152Satgutier@umich.edu        num_buffers_driving_4_nand2_load = 4;
113110152Satgutier@umich.edu        c_load_nand2_path_out            = 4 * C_nand2_gate_blk;
113210152Satgutier@umich.edu      }
113310152Satgutier@umich.edu      else if (blk->number_input_addr_bits == 5)
113410152Satgutier@umich.edu      { //4 NAND2 gates, 8 NAND3 gates one 2-4 decoder and one 3-8 decoder
113510152Satgutier@umich.edu        num_buffers_driving_4_nand2_load = 2;
113610152Satgutier@umich.edu        num_buffers_driving_8_nand3_load = 3;
113710152Satgutier@umich.edu        c_load_nand2_path_out            = 4 * C_nand2_gate_blk;
113810152Satgutier@umich.edu        c_load_nand3_path_out            = 8 * C_nand3_gate_blk;
113910152Satgutier@umich.edu      }
114010152Satgutier@umich.edu      else if (blk->number_input_addr_bits == 6)
114110152Satgutier@umich.edu      { //8 + 8 NAND3 gates two 3-8 decoder
114210152Satgutier@umich.edu        num_buffers_driving_8_nand3_load = 6;
114310152Satgutier@umich.edu        c_load_nand3_path_out            = 8 * C_nand3_gate_blk;
114410152Satgutier@umich.edu      }
114510152Satgutier@umich.edu      else if (blk->number_input_addr_bits == 7)
114610152Satgutier@umich.edu      { //4 + 4 NAND2 gates, 8 NAND3 gates two 2-4 decoder and one 3-8 decoder
114710152Satgutier@umich.edu        num_buffers_driving_4_nand2_load = 4;
114810152Satgutier@umich.edu        num_buffers_driving_8_nand3_load = 3;
114910152Satgutier@umich.edu        c_load_nand2_path_out            = 4 * C_nand2_gate_blk;
115010152Satgutier@umich.edu        c_load_nand3_path_out            = 8 * C_nand3_gate_blk;
115110152Satgutier@umich.edu      }
115210152Satgutier@umich.edu      else if (blk->number_input_addr_bits == 8)
115310152Satgutier@umich.edu      { //4 NAND2 gates, 8 + 8 NAND3 gates one 2-4 decoder and two 3-8 decoder
115410152Satgutier@umich.edu        num_buffers_driving_4_nand2_load = 2;
115510152Satgutier@umich.edu        num_buffers_driving_8_nand3_load = 6;
115610152Satgutier@umich.edu        c_load_nand2_path_out            = 4 * C_nand2_gate_blk;
115710152Satgutier@umich.edu        c_load_nand3_path_out            = 8 * C_nand3_gate_blk;
115810152Satgutier@umich.edu      }
115910152Satgutier@umich.edu      else if (blk->number_input_addr_bits == 9)
116010152Satgutier@umich.edu      { //8 + 8 + 8 NAND3 gates three 3-8 decoder
116110152Satgutier@umich.edu        num_buffers_driving_8_nand3_load = 9;
116210152Satgutier@umich.edu        c_load_nand3_path_out            = 8 * C_nand3_gate_blk;
116310152Satgutier@umich.edu      }
116410152Satgutier@umich.edu    }
116510152Satgutier@umich.edu
116610152Satgutier@umich.edu    if ((blk->flag_two_unique_paths) ||
116710152Satgutier@umich.edu        (blk->number_inputs_L1_gate == 2) ||
116810152Satgutier@umich.edu        (number_input_addr_bits == 0) ||
116910152Satgutier@umich.edu        ((way_select)&&(dec->num_in_signals == 2)))
117010152Satgutier@umich.edu    { //this means that way_select is driving NAND2 in decoder.
117110152Satgutier@umich.edu      width_nand2_path_n[0] = g_tp.min_w_nmos_;
117210152Satgutier@umich.edu      width_nand2_path_p[0] = p_to_n_sz_ratio * width_nand2_path_n[0];
117310152Satgutier@umich.edu      F = c_load_nand2_path_out / gate_C(width_nand2_path_n[0] + width_nand2_path_p[0], 0, is_dram_);
117410152Satgutier@umich.edu      number_gates_nand2_path = logical_effort(
117510152Satgutier@umich.edu          min_number_gates,
117610152Satgutier@umich.edu          1,
117710152Satgutier@umich.edu          F,
117810152Satgutier@umich.edu          width_nand2_path_n,
117910152Satgutier@umich.edu          width_nand2_path_p,
118010152Satgutier@umich.edu          c_load_nand2_path_out,
118110152Satgutier@umich.edu          p_to_n_sz_ratio,
118210152Satgutier@umich.edu          is_dram_, false, g_tp.max_w_nmos_);
118310152Satgutier@umich.edu    }
118410152Satgutier@umich.edu
118510152Satgutier@umich.edu    if ((blk->flag_two_unique_paths) ||
118610152Satgutier@umich.edu        (blk->number_inputs_L1_gate == 3) ||
118710152Satgutier@umich.edu        ((way_select)&&(dec->num_in_signals == 3)))
118810152Satgutier@umich.edu    { //this means that way_select is driving NAND3 in decoder.
118910152Satgutier@umich.edu      width_nand3_path_n[0] = g_tp.min_w_nmos_;
119010152Satgutier@umich.edu      width_nand3_path_p[0] = p_to_n_sz_ratio * width_nand3_path_n[0];
119110152Satgutier@umich.edu      F = c_load_nand3_path_out / gate_C(width_nand3_path_n[0] + width_nand3_path_p[0], 0, is_dram_);
119210152Satgutier@umich.edu      number_gates_nand3_path = logical_effort(
119310152Satgutier@umich.edu          min_number_gates,
119410152Satgutier@umich.edu          1,
119510152Satgutier@umich.edu          F,
119610152Satgutier@umich.edu          width_nand3_path_n,
119710152Satgutier@umich.edu          width_nand3_path_p,
119810152Satgutier@umich.edu          c_load_nand3_path_out,
119910152Satgutier@umich.edu          p_to_n_sz_ratio,
120010152Satgutier@umich.edu          is_dram_, false, g_tp.max_w_nmos_);
120110152Satgutier@umich.edu    }
120210152Satgutier@umich.edu  }
120310152Satgutier@umich.edu}
120410152Satgutier@umich.edu
120510152Satgutier@umich.edu
120610152Satgutier@umich.edu
120710152Satgutier@umich.eduvoid PredecBlkDrv::compute_area()
120810152Satgutier@umich.edu{
120910152Satgutier@umich.edu  double area_nand2_path = 0;
121010152Satgutier@umich.edu  double area_nand3_path = 0;
121110152Satgutier@umich.edu  double leak_nand2_path = 0;
121210152Satgutier@umich.edu  double leak_nand3_path = 0;
121310152Satgutier@umich.edu  double gate_leak_nand2_path = 0;
121410152Satgutier@umich.edu  double gate_leak_nand3_path = 0;
121510152Satgutier@umich.edu
121610152Satgutier@umich.edu  if (flag_driver_exists)
121710152Satgutier@umich.edu  { // first check whether a predecoder block driver is needed
121810152Satgutier@umich.edu    for (int i = 0; i < number_gates_nand2_path; ++i)
121910152Satgutier@umich.edu    {
122010152Satgutier@umich.edu      area_nand2_path += compute_gate_area(INV, 1, width_nand2_path_p[i], width_nand2_path_n[i], g_tp.cell_h_def);
122110152Satgutier@umich.edu      leak_nand2_path += cmos_Isub_leakage(width_nand2_path_n[i], width_nand2_path_p[i], 1, inv,is_dram_);
122210152Satgutier@umich.edu      gate_leak_nand2_path += cmos_Ig_leakage(width_nand2_path_n[i], width_nand2_path_p[i], 1, inv,is_dram_);
122310152Satgutier@umich.edu    }
122410152Satgutier@umich.edu    area_nand2_path *= (num_buffers_driving_1_nand2_load +
122510152Satgutier@umich.edu                        num_buffers_driving_2_nand2_load +
122610152Satgutier@umich.edu                        num_buffers_driving_4_nand2_load);
122710152Satgutier@umich.edu    leak_nand2_path *= (num_buffers_driving_1_nand2_load +
122810152Satgutier@umich.edu                        num_buffers_driving_2_nand2_load +
122910152Satgutier@umich.edu                        num_buffers_driving_4_nand2_load);
123010152Satgutier@umich.edu    gate_leak_nand2_path *= (num_buffers_driving_1_nand2_load +
123110152Satgutier@umich.edu                            num_buffers_driving_2_nand2_load +
123210152Satgutier@umich.edu                            num_buffers_driving_4_nand2_load);
123310152Satgutier@umich.edu
123410152Satgutier@umich.edu    for (int i = 0; i < number_gates_nand3_path; ++i)
123510152Satgutier@umich.edu    {
123610152Satgutier@umich.edu      area_nand3_path += compute_gate_area(INV, 1, width_nand3_path_p[i], width_nand3_path_n[i], g_tp.cell_h_def);
123710152Satgutier@umich.edu      leak_nand3_path += cmos_Isub_leakage(width_nand3_path_n[i], width_nand3_path_p[i], 1, inv,is_dram_);
123810152Satgutier@umich.edu      gate_leak_nand3_path += cmos_Ig_leakage(width_nand3_path_n[i], width_nand3_path_p[i], 1, inv,is_dram_);
123910152Satgutier@umich.edu    }
124010152Satgutier@umich.edu    area_nand3_path *= (num_buffers_driving_2_nand3_load + num_buffers_driving_8_nand3_load);
124110152Satgutier@umich.edu    leak_nand3_path *= (num_buffers_driving_2_nand3_load + num_buffers_driving_8_nand3_load);
124210152Satgutier@umich.edu    gate_leak_nand3_path *= (num_buffers_driving_2_nand3_load + num_buffers_driving_8_nand3_load);
124310152Satgutier@umich.edu
124410152Satgutier@umich.edu    power_nand2_path.readOp.leakage = leak_nand2_path * g_tp.peri_global.Vdd;
124510152Satgutier@umich.edu    power_nand3_path.readOp.leakage = leak_nand3_path * g_tp.peri_global.Vdd;
124610152Satgutier@umich.edu    power_nand2_path.readOp.gate_leakage = gate_leak_nand2_path * g_tp.peri_global.Vdd;
124710152Satgutier@umich.edu    power_nand3_path.readOp.gate_leakage = gate_leak_nand3_path * g_tp.peri_global.Vdd;
124810152Satgutier@umich.edu    area.set_area(area_nand2_path + area_nand3_path);
124910152Satgutier@umich.edu  }
125010152Satgutier@umich.edu}
125110152Satgutier@umich.edu
125210152Satgutier@umich.edu
125310152Satgutier@umich.edu
125410152Satgutier@umich.edupair<double, double> PredecBlkDrv::compute_delays(
125510152Satgutier@umich.edu    double inrisetime_nand2_path,
125610152Satgutier@umich.edu    double inrisetime_nand3_path)
125710152Satgutier@umich.edu{
125810152Satgutier@umich.edu  pair<double, double> ret_val;
125910152Satgutier@umich.edu  ret_val.first  = 0;  // outrisetime_nand2_path
126010152Satgutier@umich.edu  ret_val.second = 0;  // outrisetime_nand3_path
126110152Satgutier@umich.edu  int i;
126210152Satgutier@umich.edu  double rd, c_gate_load, c_load, c_intrinsic, tf, this_delay;
126310152Satgutier@umich.edu  double Vdd = g_tp.peri_global.Vdd;
126410152Satgutier@umich.edu
126510152Satgutier@umich.edu  if (flag_driver_exists)
126610152Satgutier@umich.edu  {
126710152Satgutier@umich.edu    for (i = 0; i < number_gates_nand2_path - 1; ++i)
126810152Satgutier@umich.edu    {
126910152Satgutier@umich.edu      rd = tr_R_on(width_nand2_path_n[i], NCH, 1, is_dram_);
127010152Satgutier@umich.edu      c_gate_load = gate_C(width_nand2_path_p[i+1] + width_nand2_path_n[i+1], 0.0, is_dram_);
127110152Satgutier@umich.edu      c_intrinsic = drain_C_(width_nand2_path_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) +
127210152Satgutier@umich.edu                    drain_C_(width_nand2_path_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_);
127310152Satgutier@umich.edu      tf = rd * (c_intrinsic + c_gate_load);
127410152Satgutier@umich.edu      this_delay = horowitz(inrisetime_nand2_path, tf, 0.5, 0.5, RISE);
127510152Satgutier@umich.edu      delay_nand2_path += this_delay;
127610152Satgutier@umich.edu      inrisetime_nand2_path = this_delay / (1.0 - 0.5);
127710152Satgutier@umich.edu      power_nand2_path.readOp.dynamic += (c_gate_load + c_intrinsic) * 0.5 * Vdd * Vdd;
127810152Satgutier@umich.edu    }
127910152Satgutier@umich.edu
128010152Satgutier@umich.edu    // Final inverter drives the predecoder block or the decoder output load
128110152Satgutier@umich.edu    if (number_gates_nand2_path != 0)
128210152Satgutier@umich.edu    {
128310152Satgutier@umich.edu      i = number_gates_nand2_path - 1;
128410152Satgutier@umich.edu      rd = tr_R_on(width_nand2_path_n[i], NCH, 1, is_dram_);
128510152Satgutier@umich.edu      c_intrinsic = drain_C_(width_nand2_path_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) +
128610152Satgutier@umich.edu                    drain_C_(width_nand2_path_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_);
128710152Satgutier@umich.edu      c_load = c_load_nand2_path_out;
128810152Satgutier@umich.edu      tf = rd * (c_intrinsic + c_load) + r_load_nand2_path_out*c_load/ 2;
128910152Satgutier@umich.edu      this_delay = horowitz(inrisetime_nand2_path, tf, 0.5, 0.5, RISE);
129010152Satgutier@umich.edu      delay_nand2_path += this_delay;
129110152Satgutier@umich.edu      ret_val.first = this_delay / (1.0 - 0.5);
129210152Satgutier@umich.edu      power_nand2_path.readOp.dynamic += (c_intrinsic + c_load) * 0.5 * Vdd * Vdd;
129310152Satgutier@umich.edu//      cout<< "c_intrinsic = " << c_intrinsic << "c_load" << c_load <<endl;
129410152Satgutier@umich.edu    }
129510152Satgutier@umich.edu
129610152Satgutier@umich.edu    for (i = 0; i < number_gates_nand3_path - 1; ++i)
129710152Satgutier@umich.edu    {
129810152Satgutier@umich.edu      rd = tr_R_on(width_nand3_path_n[i], NCH, 1, is_dram_);
129910152Satgutier@umich.edu      c_gate_load = gate_C(width_nand3_path_p[i+1] + width_nand3_path_n[i+1], 0.0, is_dram_);
130010152Satgutier@umich.edu      c_intrinsic = drain_C_(width_nand3_path_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) +
130110152Satgutier@umich.edu                    drain_C_(width_nand3_path_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_);
130210152Satgutier@umich.edu      tf = rd * (c_intrinsic + c_gate_load);
130310152Satgutier@umich.edu      this_delay = horowitz(inrisetime_nand3_path, tf, 0.5, 0.5, RISE);
130410152Satgutier@umich.edu      delay_nand3_path += this_delay;
130510152Satgutier@umich.edu      inrisetime_nand3_path = this_delay / (1.0 - 0.5);
130610152Satgutier@umich.edu      power_nand3_path.readOp.dynamic += (c_gate_load + c_intrinsic) * 0.5 * Vdd * Vdd;
130710152Satgutier@umich.edu    }
130810152Satgutier@umich.edu
130910152Satgutier@umich.edu    // Final inverter drives the predecoder block or the decoder output load
131010152Satgutier@umich.edu    if (number_gates_nand3_path != 0)
131110152Satgutier@umich.edu    {
131210152Satgutier@umich.edu      i = number_gates_nand3_path - 1;
131310152Satgutier@umich.edu      rd = tr_R_on(width_nand3_path_n[i], NCH, 1, is_dram_);
131410152Satgutier@umich.edu      c_intrinsic = drain_C_(width_nand3_path_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) +
131510152Satgutier@umich.edu                    drain_C_(width_nand3_path_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_);
131610152Satgutier@umich.edu      c_load = c_load_nand3_path_out;
131710152Satgutier@umich.edu      tf = rd*(c_intrinsic + c_load) + r_load_nand3_path_out*c_load / 2;
131810152Satgutier@umich.edu      this_delay = horowitz(inrisetime_nand3_path, tf, 0.5, 0.5, RISE);
131910152Satgutier@umich.edu      delay_nand3_path += this_delay;
132010152Satgutier@umich.edu      ret_val.second = this_delay / (1.0 - 0.5);
132110152Satgutier@umich.edu      power_nand3_path.readOp.dynamic += (c_intrinsic + c_load) * 0.5 * Vdd * Vdd;
132210152Satgutier@umich.edu    }
132310152Satgutier@umich.edu  }
132410152Satgutier@umich.edu  return ret_val;
132510152Satgutier@umich.edu}
132610152Satgutier@umich.edu
132710152Satgutier@umich.edu
132810152Satgutier@umich.edudouble PredecBlkDrv::get_rdOp_dynamic_E(int num_act_mats_hor_dir)
132910152Satgutier@umich.edu{
133010152Satgutier@umich.edu  return (num_addr_bits_nand2_path()*power_nand2_path.readOp.dynamic +
133110152Satgutier@umich.edu          num_addr_bits_nand3_path()*power_nand3_path.readOp.dynamic) * num_act_mats_hor_dir;
133210152Satgutier@umich.edu}
133310152Satgutier@umich.edu
133410152Satgutier@umich.edu
133510152Satgutier@umich.edu
133610152Satgutier@umich.eduPredec::Predec(
133710152Satgutier@umich.edu    PredecBlkDrv * drv1_,
133810152Satgutier@umich.edu    PredecBlkDrv * drv2_)
133910152Satgutier@umich.edu:blk1(drv1_->blk), blk2(drv2_->blk), drv1(drv1_), drv2(drv2_)
134010152Satgutier@umich.edu{
134110152Satgutier@umich.edu  driver_power.readOp.leakage = drv1->power_nand2_path.readOp.leakage +
134210152Satgutier@umich.edu                                drv1->power_nand3_path.readOp.leakage +
134310152Satgutier@umich.edu                                drv2->power_nand2_path.readOp.leakage +
134410152Satgutier@umich.edu                                drv2->power_nand3_path.readOp.leakage;
134510152Satgutier@umich.edu  block_power.readOp.leakage = blk1->power_nand2_path.readOp.leakage +
134610152Satgutier@umich.edu                               blk1->power_nand3_path.readOp.leakage +
134710152Satgutier@umich.edu                               blk1->power_L2.readOp.leakage +
134810152Satgutier@umich.edu                               blk2->power_nand2_path.readOp.leakage +
134910152Satgutier@umich.edu                               blk2->power_nand3_path.readOp.leakage +
135010152Satgutier@umich.edu                               blk2->power_L2.readOp.leakage;
135110152Satgutier@umich.edu  power.readOp.leakage = driver_power.readOp.leakage + block_power.readOp.leakage;
135210152Satgutier@umich.edu
135310152Satgutier@umich.edu  driver_power.readOp.gate_leakage = drv1->power_nand2_path.readOp.gate_leakage +
135410152Satgutier@umich.edu                                  drv1->power_nand3_path.readOp.gate_leakage +
135510152Satgutier@umich.edu                                  drv2->power_nand2_path.readOp.gate_leakage +
135610152Satgutier@umich.edu                                  drv2->power_nand3_path.readOp.gate_leakage;
135710152Satgutier@umich.edu  block_power.readOp.gate_leakage = blk1->power_nand2_path.readOp.gate_leakage +
135810152Satgutier@umich.edu                                 blk1->power_nand3_path.readOp.gate_leakage +
135910152Satgutier@umich.edu                                 blk1->power_L2.readOp.gate_leakage +
136010152Satgutier@umich.edu                                 blk2->power_nand2_path.readOp.gate_leakage +
136110152Satgutier@umich.edu                                 blk2->power_nand3_path.readOp.gate_leakage +
136210152Satgutier@umich.edu                                 blk2->power_L2.readOp.gate_leakage;
136310152Satgutier@umich.edu  power.readOp.gate_leakage = driver_power.readOp.gate_leakage + block_power.readOp.gate_leakage;
136410152Satgutier@umich.edu}
136510152Satgutier@umich.edu
136610152Satgutier@umich.eduvoid PredecBlkDrv::leakage_feedback(double temperature)
136710152Satgutier@umich.edu{
136810152Satgutier@umich.edu  double leak_nand2_path = 0;
136910152Satgutier@umich.edu  double leak_nand3_path = 0;
137010152Satgutier@umich.edu  double gate_leak_nand2_path = 0;
137110152Satgutier@umich.edu  double gate_leak_nand3_path = 0;
137210152Satgutier@umich.edu
137310152Satgutier@umich.edu  if (flag_driver_exists)
137410152Satgutier@umich.edu  { // first check whether a predecoder block driver is needed
137510152Satgutier@umich.edu    for (int i = 0; i < number_gates_nand2_path; ++i)
137610152Satgutier@umich.edu    {
137710152Satgutier@umich.edu      leak_nand2_path += cmos_Isub_leakage(width_nand2_path_n[i], width_nand2_path_p[i], 1, inv,is_dram_);
137810152Satgutier@umich.edu      gate_leak_nand2_path += cmos_Ig_leakage(width_nand2_path_n[i], width_nand2_path_p[i], 1, inv,is_dram_);
137910152Satgutier@umich.edu    }
138010152Satgutier@umich.edu    leak_nand2_path *= (num_buffers_driving_1_nand2_load +
138110152Satgutier@umich.edu                        num_buffers_driving_2_nand2_load +
138210152Satgutier@umich.edu                        num_buffers_driving_4_nand2_load);
138310152Satgutier@umich.edu    gate_leak_nand2_path *= (num_buffers_driving_1_nand2_load +
138410152Satgutier@umich.edu                            num_buffers_driving_2_nand2_load +
138510152Satgutier@umich.edu                            num_buffers_driving_4_nand2_load);
138610152Satgutier@umich.edu
138710152Satgutier@umich.edu    for (int i = 0; i < number_gates_nand3_path; ++i)
138810152Satgutier@umich.edu    {
138910152Satgutier@umich.edu      leak_nand3_path += cmos_Isub_leakage(width_nand3_path_n[i], width_nand3_path_p[i], 1, inv,is_dram_);
139010152Satgutier@umich.edu      gate_leak_nand3_path += cmos_Ig_leakage(width_nand3_path_n[i], width_nand3_path_p[i], 1, inv,is_dram_);
139110152Satgutier@umich.edu    }
139210152Satgutier@umich.edu    leak_nand3_path *= (num_buffers_driving_2_nand3_load + num_buffers_driving_8_nand3_load);
139310152Satgutier@umich.edu    gate_leak_nand3_path *= (num_buffers_driving_2_nand3_load + num_buffers_driving_8_nand3_load);
139410152Satgutier@umich.edu
139510152Satgutier@umich.edu    power_nand2_path.readOp.leakage = leak_nand2_path * g_tp.peri_global.Vdd;
139610152Satgutier@umich.edu    power_nand3_path.readOp.leakage = leak_nand3_path * g_tp.peri_global.Vdd;
139710152Satgutier@umich.edu    power_nand2_path.readOp.gate_leakage = gate_leak_nand2_path * g_tp.peri_global.Vdd;
139810152Satgutier@umich.edu    power_nand3_path.readOp.gate_leakage = gate_leak_nand3_path * g_tp.peri_global.Vdd;
139910152Satgutier@umich.edu  }
140010152Satgutier@umich.edu}
140110152Satgutier@umich.edu
140210152Satgutier@umich.edudouble Predec::compute_delays(double inrisetime)
140310152Satgutier@umich.edu{
140410152Satgutier@umich.edu  // TODO: Jung Ho thinks that predecoder block driver locates between decoder and predecoder block.
140510152Satgutier@umich.edu  pair<double, double> tmp_pair1, tmp_pair2;
140610152Satgutier@umich.edu  tmp_pair1 = drv1->compute_delays(inrisetime, inrisetime);
140710152Satgutier@umich.edu  tmp_pair1 = blk1->compute_delays(tmp_pair1);
140810152Satgutier@umich.edu  tmp_pair2 = drv2->compute_delays(inrisetime, inrisetime);
140910152Satgutier@umich.edu  tmp_pair2 = blk2->compute_delays(tmp_pair2);
141010152Satgutier@umich.edu  tmp_pair1 = get_max_delay_before_decoder(tmp_pair1, tmp_pair2);
141110152Satgutier@umich.edu
141210152Satgutier@umich.edu  driver_power.readOp.dynamic =
141310152Satgutier@umich.edu    drv1->num_addr_bits_nand2_path() * drv1->power_nand2_path.readOp.dynamic +
141410152Satgutier@umich.edu    drv1->num_addr_bits_nand3_path() * drv1->power_nand3_path.readOp.dynamic +
141510152Satgutier@umich.edu    drv2->num_addr_bits_nand2_path() * drv2->power_nand2_path.readOp.dynamic +
141610152Satgutier@umich.edu    drv2->num_addr_bits_nand3_path() * drv2->power_nand3_path.readOp.dynamic;
141710152Satgutier@umich.edu
141810152Satgutier@umich.edu  block_power.readOp.dynamic =
141910152Satgutier@umich.edu    blk1->power_nand2_path.readOp.dynamic*blk1->num_L1_active_nand2_path +
142010152Satgutier@umich.edu    blk1->power_nand3_path.readOp.dynamic*blk1->num_L1_active_nand3_path +
142110152Satgutier@umich.edu    blk1->power_L2.readOp.dynamic +
142210152Satgutier@umich.edu    blk2->power_nand2_path.readOp.dynamic*blk1->num_L1_active_nand2_path  +
142310152Satgutier@umich.edu    blk2->power_nand3_path.readOp.dynamic*blk1->num_L1_active_nand3_path +
142410152Satgutier@umich.edu    blk2->power_L2.readOp.dynamic;
142510152Satgutier@umich.edu
142610152Satgutier@umich.edu  power.readOp.dynamic = driver_power.readOp.dynamic + block_power.readOp.dynamic;
142710152Satgutier@umich.edu
142810152Satgutier@umich.edu  delay = tmp_pair1.first;
142910152Satgutier@umich.edu  return  tmp_pair1.second;
143010152Satgutier@umich.edu}
143110152Satgutier@umich.edu
143210152Satgutier@umich.edu
143310152Satgutier@umich.eduvoid Predec::leakage_feedback(double temperature)
143410152Satgutier@umich.edu{
143510152Satgutier@umich.edu  drv1->leakage_feedback(temperature);
143610152Satgutier@umich.edu  drv2->leakage_feedback(temperature);
143710152Satgutier@umich.edu  blk1->leakage_feedback(temperature);
143810152Satgutier@umich.edu  blk2->leakage_feedback(temperature);
143910152Satgutier@umich.edu
144010152Satgutier@umich.edu  driver_power.readOp.leakage = drv1->power_nand2_path.readOp.leakage +
144110152Satgutier@umich.edu                                drv1->power_nand3_path.readOp.leakage +
144210152Satgutier@umich.edu                                drv2->power_nand2_path.readOp.leakage +
144310152Satgutier@umich.edu                                drv2->power_nand3_path.readOp.leakage;
144410152Satgutier@umich.edu  block_power.readOp.leakage = blk1->power_nand2_path.readOp.leakage +
144510152Satgutier@umich.edu                               blk1->power_nand3_path.readOp.leakage +
144610152Satgutier@umich.edu                               blk1->power_L2.readOp.leakage +
144710152Satgutier@umich.edu                               blk2->power_nand2_path.readOp.leakage +
144810152Satgutier@umich.edu                               blk2->power_nand3_path.readOp.leakage +
144910152Satgutier@umich.edu                               blk2->power_L2.readOp.leakage;
145010152Satgutier@umich.edu  power.readOp.leakage = driver_power.readOp.leakage + block_power.readOp.leakage;
145110152Satgutier@umich.edu
145210152Satgutier@umich.edu  driver_power.readOp.gate_leakage = drv1->power_nand2_path.readOp.gate_leakage +
145310152Satgutier@umich.edu                                  drv1->power_nand3_path.readOp.gate_leakage +
145410152Satgutier@umich.edu                                  drv2->power_nand2_path.readOp.gate_leakage +
145510152Satgutier@umich.edu                                  drv2->power_nand3_path.readOp.gate_leakage;
145610152Satgutier@umich.edu  block_power.readOp.gate_leakage = blk1->power_nand2_path.readOp.gate_leakage +
145710152Satgutier@umich.edu                                 blk1->power_nand3_path.readOp.gate_leakage +
145810152Satgutier@umich.edu                                 blk1->power_L2.readOp.gate_leakage +
145910152Satgutier@umich.edu                                 blk2->power_nand2_path.readOp.gate_leakage +
146010152Satgutier@umich.edu                                 blk2->power_nand3_path.readOp.gate_leakage +
146110152Satgutier@umich.edu                                 blk2->power_L2.readOp.gate_leakage;
146210152Satgutier@umich.edu  power.readOp.gate_leakage = driver_power.readOp.gate_leakage + block_power.readOp.gate_leakage;
146310152Satgutier@umich.edu}
146410152Satgutier@umich.edu
146510152Satgutier@umich.edu// returns <delay, risetime>
146610152Satgutier@umich.edupair<double, double> Predec::get_max_delay_before_decoder(
146710152Satgutier@umich.edu    pair<double, double> input_pair1,
146810152Satgutier@umich.edu    pair<double, double> input_pair2)
146910152Satgutier@umich.edu{
147010152Satgutier@umich.edu  pair<double, double> ret_val;
147110152Satgutier@umich.edu  double delay;
147210152Satgutier@umich.edu
147310152Satgutier@umich.edu  delay = drv1->delay_nand2_path + blk1->delay_nand2_path;
147410152Satgutier@umich.edu  ret_val.first  = delay;
147510152Satgutier@umich.edu  ret_val.second = input_pair1.first;
147610152Satgutier@umich.edu  delay = drv1->delay_nand3_path + blk1->delay_nand3_path;
147710152Satgutier@umich.edu  if (ret_val.first < delay)
147810152Satgutier@umich.edu  {
147910152Satgutier@umich.edu    ret_val.first  = delay;
148010152Satgutier@umich.edu    ret_val.second = input_pair1.second;
148110152Satgutier@umich.edu  }
148210152Satgutier@umich.edu  delay = drv2->delay_nand2_path + blk2->delay_nand2_path;
148310152Satgutier@umich.edu  if (ret_val.first < delay)
148410152Satgutier@umich.edu  {
148510152Satgutier@umich.edu    ret_val.first  = delay;
148610152Satgutier@umich.edu    ret_val.second = input_pair2.first;
148710152Satgutier@umich.edu  }
148810152Satgutier@umich.edu  delay = drv2->delay_nand3_path + blk2->delay_nand3_path;
148910152Satgutier@umich.edu  if (ret_val.first < delay)
149010152Satgutier@umich.edu  {
149110152Satgutier@umich.edu    ret_val.first  = delay;
149210152Satgutier@umich.edu    ret_val.second = input_pair2.second;
149310152Satgutier@umich.edu  }
149410152Satgutier@umich.edu
149510152Satgutier@umich.edu  return ret_val;
149610152Satgutier@umich.edu}
149710152Satgutier@umich.edu
149810152Satgutier@umich.edu
149910152Satgutier@umich.edu
150010152Satgutier@umich.eduDriver::Driver(double c_gate_load_, double c_wire_load_, double r_wire_load_, bool is_dram)
150110152Satgutier@umich.edu:number_gates(0),
150210152Satgutier@umich.edu  min_number_gates(2),
150310152Satgutier@umich.edu  c_gate_load(c_gate_load_),
150410152Satgutier@umich.edu  c_wire_load(c_wire_load_),
150510152Satgutier@umich.edu  r_wire_load(r_wire_load_),
150610152Satgutier@umich.edu  delay(0),
150710152Satgutier@umich.edu  power(),
150810152Satgutier@umich.edu  is_dram_(is_dram)
150910152Satgutier@umich.edu{
151010152Satgutier@umich.edu  for (int i = 0; i < MAX_NUMBER_GATES_STAGE; i++)
151110152Satgutier@umich.edu  {
151210152Satgutier@umich.edu    width_n[i] = 0;
151310152Satgutier@umich.edu    width_p[i] = 0;
151410152Satgutier@umich.edu  }
151510152Satgutier@umich.edu
151610152Satgutier@umich.edu  compute_widths();
151710152Satgutier@umich.edu}
151810152Satgutier@umich.edu
151910152Satgutier@umich.edu
152010152Satgutier@umich.eduvoid Driver::compute_widths()
152110152Satgutier@umich.edu{
152210152Satgutier@umich.edu  double p_to_n_sz_ratio = pmos_to_nmos_sz_ratio(is_dram_);
152310152Satgutier@umich.edu  double c_load = c_gate_load + c_wire_load;
152410152Satgutier@umich.edu  width_n[0] = g_tp.min_w_nmos_;
152510152Satgutier@umich.edu  width_p[0] = p_to_n_sz_ratio * g_tp.min_w_nmos_;
152610152Satgutier@umich.edu
152710152Satgutier@umich.edu  double F = c_load / gate_C(width_n[0] + width_p[0], 0, is_dram_);
152810152Satgutier@umich.edu  number_gates = logical_effort(
152910152Satgutier@umich.edu      min_number_gates,
153010152Satgutier@umich.edu      1,
153110152Satgutier@umich.edu      F,
153210152Satgutier@umich.edu      width_n,
153310152Satgutier@umich.edu      width_p,
153410152Satgutier@umich.edu      c_load,
153510152Satgutier@umich.edu      p_to_n_sz_ratio,
153610152Satgutier@umich.edu      is_dram_, false,
153710152Satgutier@umich.edu      g_tp.max_w_nmos_);
153810152Satgutier@umich.edu}
153910152Satgutier@umich.edu
154010152Satgutier@umich.edu
154110152Satgutier@umich.edu
154210152Satgutier@umich.edudouble Driver::compute_delay(double inrisetime)
154310152Satgutier@umich.edu{
154410152Satgutier@umich.edu  int    i;
154510152Satgutier@umich.edu  double rd, c_load, c_intrinsic, tf;
154610152Satgutier@umich.edu  double this_delay = 0;
154710152Satgutier@umich.edu
154810152Satgutier@umich.edu  for (i = 0; i < number_gates - 1; ++i)
154910152Satgutier@umich.edu  {
155010152Satgutier@umich.edu    rd = tr_R_on(width_n[i], NCH, 1, is_dram_);
155110152Satgutier@umich.edu    c_load = gate_C(width_n[i+1] + width_p[i+1], 0.0, is_dram_);
155210152Satgutier@umich.edu    c_intrinsic = drain_C_(width_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) +
155310152Satgutier@umich.edu                  drain_C_(width_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_);
155410152Satgutier@umich.edu    tf = rd * (c_intrinsic + c_load);
155510152Satgutier@umich.edu    this_delay = horowitz(inrisetime, tf, 0.5, 0.5, RISE);
155610152Satgutier@umich.edu    delay += this_delay;
155710152Satgutier@umich.edu    inrisetime = this_delay / (1.0 - 0.5);
155810152Satgutier@umich.edu    power.readOp.dynamic += (c_intrinsic + c_load) * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd;
155910152Satgutier@umich.edu    power.readOp.leakage += cmos_Isub_leakage(width_n[i], width_p[i], 1, inv, is_dram_) *g_tp.peri_global.Vdd;
156010152Satgutier@umich.edu    power.readOp.gate_leakage += cmos_Ig_leakage(width_n[i], width_p[i], 1, inv, is_dram_)* g_tp.peri_global.Vdd;
156110152Satgutier@umich.edu  }
156210152Satgutier@umich.edu
156310152Satgutier@umich.edu  i = number_gates - 1;
156410152Satgutier@umich.edu  c_load = c_gate_load + c_wire_load;
156510152Satgutier@umich.edu  rd = tr_R_on(width_n[i], NCH, 1, is_dram_);
156610152Satgutier@umich.edu  c_intrinsic = drain_C_(width_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) +
156710152Satgutier@umich.edu                drain_C_(width_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_);
156810152Satgutier@umich.edu  tf = rd * (c_intrinsic + c_load) + r_wire_load * (c_wire_load / 2 + c_gate_load);
156910152Satgutier@umich.edu  this_delay = horowitz(inrisetime, tf, 0.5, 0.5, RISE);
157010152Satgutier@umich.edu  delay += this_delay;
157110152Satgutier@umich.edu  power.readOp.dynamic += (c_intrinsic + c_load) * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd;
157210152Satgutier@umich.edu  power.readOp.leakage += cmos_Isub_leakage(width_n[i], width_p[i], 1, inv, is_dram_) * g_tp.peri_global.Vdd;
157310152Satgutier@umich.edu  power.readOp.gate_leakage += cmos_Ig_leakage(width_n[i], width_p[i], 1, inv, is_dram_)* g_tp.peri_global.Vdd;
157410152Satgutier@umich.edu
157510152Satgutier@umich.edu  return this_delay / (1.0 - 0.5);
157610152Satgutier@umich.edu}
157710152Satgutier@umich.edu
1578