Ejemplo n.º 1
0
void Wire::delay_optimal_wire() {
    double len = wire_length;
    //double min_wire_width = wire_width; //m
    double beta = pmos_to_nmos_sz_ratio();
    double switching = 0;  // switching energy
    double short_ckt = 0;  // short-circuit energy
    double tc = 0;  // time constant
    // input cap of min sized driver
    double input_cap = gate_C(g_tp.min_w_nmos_ + min_w_pmos, 0);

    // output parasitic capacitance of
    // the min. sized driver
    double out_cap = drain_C_(min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) +
                     drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def);
    // drive resistance
    double out_res = (tr_R_on(g_tp.min_w_nmos_, NCH, 1) + tr_R_on(min_w_pmos, PCH, 1)) / 2;
    double wr = wire_res(len); //ohm

    // wire cap /m
    double wc = wire_cap(len);

    // size the repeater such that the delay of the wire is minimum
    double repeater_scaling = sqrt(out_res * wc / (wr * input_cap)); // len will cancel

    // calc the optimum spacing between the repeaters (m)

    repeater_spacing = sqrt(2 * out_res * (out_cap + input_cap) / ((wr / len) * (wc / len)));
    repeater_size = repeater_scaling;

    switching = (repeater_scaling * (input_cap + out_cap) + repeater_spacing * (wc / len)) * deviceType->Vdd *
                deviceType->Vdd;

    tc = out_res * (input_cap + out_cap) + out_res * wc / len * repeater_spacing / repeater_scaling +
         wr / len * repeater_spacing * input_cap * repeater_scaling +
         0.5 * (wr / len) * (wc / len) * repeater_spacing * repeater_spacing;

    delay = 0.693 * tc * len / repeater_spacing;

#define Ishort_ckt 65e-6 /* across all tech Ref:Banerjee et al. {IEEE TED} */
    short_ckt = deviceType->Vdd * g_tp.min_w_nmos_ * Ishort_ckt * 1.0986 * repeater_scaling * tc;

    area.set_area((len / repeater_spacing) *
                  compute_gate_area(INV, 1, min_w_pmos * repeater_scaling, g_tp.min_w_nmos_ * repeater_scaling,
                                    g_tp.cell_h_def));
    power.readOp.dynamic = ((len / repeater_spacing) * (switching + short_ckt));
    power.readOp.leakage = ((len / repeater_spacing) * (1 + beta) / 2 * deviceType->Vdd * deviceType->I_off_n *
                            g_tp.min_w_nmos_ * repeater_scaling);
}
Ejemplo n.º 2
0
// nand gate sizing calculation
void Htree2::input_nand(double s1, double s2, double l_eff)
{
  Wire w1(wt, l_eff);
  double pton_size = deviceType->n_to_p_eff_curr_drv_ratio;
  // input capacitance of a repeater  = input capacitance of nand.
  double nsize = s1*(1 + pton_size)/(2 + pton_size);
  nsize = (nsize < 1) ? 1 : nsize;

  double tc = 2*tr_R_on(nsize*min_w_nmos, NCH, 1) *
    (drain_C_(nsize*min_w_nmos, NCH, 1, 1, g_tp.cell_h_def)*2 +
     2 * gate_C(s2*(min_w_nmos + min_w_pmos), 0));
  delay+= horowitz (w1.out_rise_time, tc,
      deviceType->Vth/deviceType->Vdd, deviceType->Vth/deviceType->Vdd, RISE);
  power.readOp.dynamic += 0.5 *
    (2*drain_C_(pton_size * nsize*min_w_pmos, PCH, 1, 1, g_tp.cell_h_def)
     + drain_C_(nsize*min_w_nmos, NCH, 1, 1, g_tp.cell_h_def)
     + 2*gate_C(s2*(min_w_nmos + min_w_pmos), 0)) *
    deviceType->Vdd * deviceType->Vdd;

    power.searchOp.dynamic += 0.5 *
    (2*drain_C_(pton_size * nsize*min_w_pmos, PCH, 1, 1, g_tp.cell_h_def)
     + drain_C_(nsize*min_w_nmos, NCH, 1, 1, g_tp.cell_h_def)
     + 2*gate_C(s2*(min_w_nmos + min_w_pmos), 0)) *
    deviceType->Vdd * deviceType->Vdd * wire_bw ;
  power.readOp.leakage += (wire_bw*cmos_Isub_leakage(min_w_nmos*(nsize*2), min_w_pmos * nsize * 2, 2, nand))*deviceType->Vdd;
  power.readOp.gate_leakage += (wire_bw*cmos_Ig_leakage(min_w_nmos*(nsize*2), min_w_pmos * nsize * 2, 2, nand))*deviceType->Vdd;
}
Ejemplo n.º 3
0
powerDef Wire::wire_model(double space, double size, double* delay) {
    powerDef ptemp;
    double len = 1;
    //double min_wire_width = wire_width; //m
    double beta = pmos_to_nmos_sz_ratio();
    // switching energy
    double switching = 0;
    // short-circuit energy
    double short_ckt = 0;
    // time constant
    double tc = 0;
    // input cap of min sized driver
    double input_cap = gate_C(g_tp.min_w_nmos_ + min_w_pmos, 0);

    // output parasitic capacitance of
    // the min. sized driver
    double out_cap = drain_C_(min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) +
                     drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def);
    // drive resistance
    double out_res = (tr_R_on(g_tp.min_w_nmos_, NCH, 1) + tr_R_on(min_w_pmos, PCH, 1)) / 2;
    double wr = wire_res(len); //ohm

    // wire cap /m
    double wc = wire_cap(len);

    repeater_spacing = space;
    repeater_size = size;

    switching = (repeater_size * (input_cap + out_cap) + repeater_spacing * (wc / len)) * deviceType->Vdd *
                deviceType->Vdd;

    tc = out_res * (input_cap + out_cap) + out_res * wc / len * repeater_spacing / repeater_size +
         wr / len * repeater_spacing * out_cap * repeater_size +
         0.5 * (wr / len) * (wc / len) * repeater_spacing * repeater_spacing;

    *delay = 0.693 * tc * len / repeater_spacing;

#define Ishort_ckt 65e-6 /* across all tech Ref:Banerjee et al. {IEEE TED} */
    short_ckt = deviceType->Vdd * g_tp.min_w_nmos_ * Ishort_ckt * 1.0986 * repeater_size * tc;

    ptemp.readOp.dynamic = ((len / repeater_spacing) * (switching + short_ckt));
    ptemp.readOp.leakage = ((len / repeater_spacing) * (1 + beta) / 2 * deviceType->Vdd * deviceType->I_off_n *
                            g_tp.min_w_nmos_ * repeater_size);
    return ptemp;
}
Ejemplo n.º 4
0
double Wire::signal_rise_time() {

    /* rise time of inverter 1's output */
    double ft;
    /* fall time of inverter 2's output */
    double rt;
    double timeconst;

    timeconst =
            (drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) + drain_C_(min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) +
             gate_C(min_w_pmos + g_tp.min_w_nmos_, 0)) * tr_R_on(g_tp.min_w_nmos_, NCH, 1);
    rt = horowitz(0, timeconst, deviceType->Vth / deviceType->Vdd, deviceType->Vth / deviceType->Vdd, RISE) /
         deviceType->Vth;
    timeconst =
            (drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) + drain_C_(min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) +
             gate_C(min_w_pmos + g_tp.min_w_nmos_, 0)) * tr_R_on(min_w_pmos, PCH, 1);
    ft = horowitz(rt, timeconst, deviceType->Vth / deviceType->Vdd, deviceType->Vth / deviceType->Vdd, FALL) /
         (deviceType->Vdd - deviceType->Vth);
    return ft; //sec
}
Ejemplo n.º 5
0
/*
 * Calculates the delay, power and area of the transmitter circuit.
 *
 * The transmitter delay is the sum of nand gate delay, inverter delay
 * low swing nmos delay, and the wire delay
 * (ref: Technical report 6)
 */
void
Wire::low_swing_model() {
    double len = wire_length;
    double beta = pmos_to_nmos_sz_ratio();


    double inputrise = (in_rise_time == 0) ? signal_rise_time() : in_rise_time;

    /* Final nmos low swing driver size calculation:
     * Try to size the driver such that the delay
     * is less than 8FO4.
     * If the driver size is greater than
     * the max allowable size, assume max size for the driver.
     * In either case, recalculate the delay using
     * the final driver size assuming slow input with
     * finite rise time instead of ideal step input
     *
     * (ref: Technical report 6)
     */
    double cwire = wire_cap(len); /* load capacitance */
    double rwire = wire_res(len);

#define RES_ADJ (8.6) // Increase in resistance due to low driving vol.

    double driver_res = (-8 * g_tp.FO4 / (log(0.5) * cwire)) / RES_ADJ;
    double nsize = R_to_w(driver_res, NCH);

    nsize = MIN(nsize, g_tp.max_w_nmos_);
    nsize = MAX(nsize, g_tp.min_w_nmos_);

    if (rwire * cwire > 8 * g_tp.FO4) {
        nsize = g_tp.max_w_nmos_;
    }

    // size the inverter appropriately to minimize the transmitter delay
    // Note - In order to minimize leakage, we are not adding a set of inverters to
    // bring down delay. Instead, we are sizing the single gate
    // based on the logical effort.
    double st_eff = sqrt(
            (2 + beta / 1 + beta) * gate_C(nsize, 0) / (gate_C(2 * g_tp.min_w_nmos_, 0) + gate_C(2 * min_w_pmos, 0)));
    double req_cin = ((2 + beta / 1 + beta) * gate_C(nsize, 0)) / st_eff;
    double inv_size = req_cin / (gate_C(min_w_pmos, 0) + gate_C(g_tp.min_w_nmos_, 0));
    inv_size = MAX(inv_size, 1);

    /* nand gate delay */
    double res_eq = (2 * tr_R_on(g_tp.min_w_nmos_, NCH, 1));
    double cap_eq = 2 * drain_C_(min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) +
                    drain_C_(2 * g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) +
                    gate_C(inv_size * g_tp.min_w_nmos_, 0) + gate_C(inv_size * min_w_pmos, 0);

    double timeconst = res_eq * cap_eq;

    delay = horowitz(inputrise, timeconst, deviceType->Vth / deviceType->Vdd, deviceType->Vth / deviceType->Vdd, RISE);
    double temp_power = cap_eq * deviceType->Vdd * deviceType->Vdd;

    inputrise = delay / (deviceType->Vdd - deviceType->Vth); /* for the next stage */

    /* Inverter delay:
     * The load capacitance of this inv depends on
     * the gate capacitance of the final stage nmos
     * transistor which in turn depends on nsize
     */
    res_eq = tr_R_on(inv_size * min_w_pmos, PCH, 1);
    cap_eq = drain_C_(inv_size * min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) +
             drain_C_(inv_size * g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) + gate_C(nsize, 0);
    timeconst = res_eq * cap_eq;

    delay += horowitz(inputrise, timeconst, deviceType->Vth / deviceType->Vdd, deviceType->Vth / deviceType->Vdd, FALL);
    temp_power += cap_eq * deviceType->Vdd * deviceType->Vdd;


    transmitter.delay = delay;
    transmitter.power.readOp.dynamic = temp_power * 2; /* since it is a diff. model*/
    transmitter.power.readOp.leakage = 0.5 * deviceType->Vdd *
                                       (4 * cmos_Ileak(g_tp.min_w_nmos_, min_w_pmos, g_ip->temp) *
                                        NAND2_LEAK_STACK_FACTOR +
                                        4 * cmos_Ileak(g_tp.min_w_nmos_, g_tp.min_w_nmos_, g_ip->temp));

    inputrise = delay / deviceType->Vth;

    /* nmos delay + wire delay */
    cap_eq = cwire + drain_C_(nsize, NCH, 1, 1, g_tp.cell_h_def) * 2 + nsense * sense_amp_input_cap(); //+receiver cap
    /*
     * NOTE: nmos is used as both pull up and pull down transistor
     * in the transmitter. This is because for low voltage swing, drive
     * resistance of nmos is less than pmos
     * (for a detailed graph ref: On-Chip Wires: Scaling and Efficiency)
     */
    timeconst = (tr_R_on(nsize, NCH, 1) * RES_ADJ) * (cwire + drain_C_(nsize, NCH, 1, 1, g_tp.cell_h_def) * 2) +
                rwire * cwire / 2 + (tr_R_on(nsize, NCH, 1) * RES_ADJ + rwire) * nsense * sense_amp_input_cap();

    /*
     * since we are pre-equalizing and overdriving the low
     * swing wires, the net time constant is less
     * than the actual value
     */
    delay += horowitz(inputrise, timeconst, deviceType->Vth / deviceType->Vdd, .25, 0);
#define VOL_SWING .1
    temp_power += cap_eq * VOL_SWING * .400; /* .4v is the over drive voltage */
    temp_power *= 2; /* differential wire */

    l_wire.delay = delay - transmitter.delay;
    l_wire.power.readOp.dynamic = temp_power - transmitter.power.readOp.dynamic;
    l_wire.power.readOp.leakage = 0.5 * deviceType->Vdd * (4 * simplified_nmos_leakage(nsize, g_ip->temp));


    //double rt = horowitz(inputrise, timeconst, deviceType->Vth/deviceType->Vdd,
    //    deviceType->Vth/deviceType->Vdd, RISE)/deviceType->Vth;

    delay += g_tp.sense_delay;

    sense_amp.delay = g_tp.sense_delay;
    out_rise_time = g_tp.sense_delay / (deviceType->Vth);
    sense_amp.power.readOp.dynamic = g_tp.sense_dy_power;
    sense_amp.power.readOp.leakage = 0; //FIXME

    power.readOp.dynamic = temp_power + sense_amp.power.readOp.dynamic;
    power.readOp.leakage = transmitter.power.readOp.leakage + l_wire.power.readOp.leakage +
                           sense_amp.power.readOp.leakage;
}
Ejemplo n.º 6
0
// tristate buffer model consisting of not, nand, nor, and driver transistors
void Htree2::output_buffer(double s1, double s2, double l_eff)
{
  Wire w1(wt, l_eff);
  double pton_size = deviceType->n_to_p_eff_curr_drv_ratio;
  // input capacitance of repeater = input capacitance of nand + nor.
  double size = s1*(1 + pton_size)/(2 + pton_size + 1 + 2*pton_size);
  double s_eff =  //stage eff of a repeater in a wire
    (gate_C(s2*(min_w_nmos + min_w_pmos), 0) + w1.wire_cap(l_eff*1e-6))/
    gate_C(s2*(min_w_nmos + min_w_pmos), 0);
  double tr_size = gate_C(s1*(min_w_nmos + min_w_pmos), 0) * 1/2/(s_eff*gate_C(min_w_pmos, 0));
  size = (size < 1) ? 1 : size;

  double res_nor = 2*tr_R_on(size*min_w_pmos, PCH, 1);
  double res_ptrans = tr_R_on(tr_size*min_w_nmos, NCH, 1);
  double cap_nand_out = drain_C_(size*min_w_nmos, NCH, 1, 1, g_tp.cell_h_def) +
                        drain_C_(size*min_w_pmos, PCH, 1, 1, g_tp.cell_h_def)*2 +
                        gate_C(tr_size*min_w_pmos, 0);
  double cap_ptrans_out = 2 *(drain_C_(tr_size*min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) +
                              drain_C_(tr_size*min_w_nmos, NCH, 1, 1, g_tp.cell_h_def)) +
                          gate_C(s1*(min_w_nmos + min_w_pmos), 0);

  double tc = res_nor * cap_nand_out + (res_nor + res_ptrans) * cap_ptrans_out;


  delay += horowitz (w1.out_rise_time, tc,
      deviceType->Vth/deviceType->Vdd, deviceType->Vth/deviceType->Vdd, RISE);

  //nand
  power.readOp.dynamic += 0.5 *
    (2*drain_C_(size*min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) +
       drain_C_(size*min_w_nmos, NCH, 1, 1, g_tp.cell_h_def) +
     gate_C(tr_size*(min_w_pmos), 0)) *
    deviceType->Vdd * deviceType->Vdd;

    power.searchOp.dynamic += 0.5 *
    (2*drain_C_(size*min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) +
       drain_C_(size*min_w_nmos, NCH, 1, 1, g_tp.cell_h_def) +
     gate_C(tr_size*(min_w_pmos), 0)) *
    deviceType->Vdd * deviceType->Vdd*init_wire_bw;

  //not
  power.readOp.dynamic += 0.5 *
    (drain_C_(size*min_w_pmos, PCH, 1, 1, g_tp.cell_h_def)
     +drain_C_(size*min_w_nmos, NCH, 1, 1, g_tp.cell_h_def)
     +gate_C(size*(min_w_nmos + min_w_pmos), 0)) *
    deviceType->Vdd * deviceType->Vdd;

    power.searchOp.dynamic += 0.5 *
    (drain_C_(size*min_w_pmos, PCH, 1, 1, g_tp.cell_h_def)
     +drain_C_(size*min_w_nmos, NCH, 1, 1, g_tp.cell_h_def)
     +gate_C(size*(min_w_nmos + min_w_pmos), 0)) *
    deviceType->Vdd * deviceType->Vdd*init_wire_bw;

  //nor
  power.readOp.dynamic += 0.5 *
    (drain_C_(size*min_w_pmos, PCH, 1, 1, g_tp.cell_h_def)
     + 2*drain_C_(size*min_w_nmos, NCH, 1, 1, g_tp.cell_h_def)
     +gate_C(tr_size*(min_w_nmos + min_w_pmos), 0)) *
    deviceType->Vdd * deviceType->Vdd;

    power.searchOp.dynamic += 0.5 *
    (drain_C_(size*min_w_pmos, PCH, 1, 1, g_tp.cell_h_def)
     + 2*drain_C_(size*min_w_nmos, NCH, 1, 1, g_tp.cell_h_def)
     +gate_C(tr_size*(min_w_nmos + min_w_pmos), 0)) *
    deviceType->Vdd * deviceType->Vdd*init_wire_bw;

  //output transistor
  power.readOp.dynamic += 0.5 *
    ((drain_C_(tr_size*min_w_pmos, PCH, 1, 1, g_tp.cell_h_def)
      +drain_C_(tr_size*min_w_nmos, NCH, 1, 1, g_tp.cell_h_def))*2
     + gate_C(s1*(min_w_nmos + min_w_pmos), 0)) *
    deviceType->Vdd * deviceType->Vdd;

    power.searchOp.dynamic += 0.5 *
    ((drain_C_(tr_size*min_w_pmos, PCH, 1, 1, g_tp.cell_h_def)
      +drain_C_(tr_size*min_w_nmos, NCH, 1, 1, g_tp.cell_h_def))*2
     + gate_C(s1*(min_w_nmos + min_w_pmos), 0)) *
    deviceType->Vdd * deviceType->Vdd*init_wire_bw;

  if(uca_tree) {
	power.readOp.leakage += cmos_Isub_leakage(min_w_nmos*tr_size*2, min_w_pmos*tr_size*2, 1, inv)*deviceType->Vdd*wire_bw;/*inverter + output tr*/
	power.readOp.leakage += cmos_Isub_leakage(min_w_nmos*size*3, min_w_pmos*size*3, 2, nand)*deviceType->Vdd*wire_bw;//nand
	power.readOp.leakage += cmos_Isub_leakage(min_w_nmos*size*3, min_w_pmos*size*3, 2, nor)*deviceType->Vdd*wire_bw;//nor

	power.readOp.gate_leakage += cmos_Ig_leakage(min_w_nmos*tr_size*2, min_w_pmos*tr_size*2, 1, inv)*deviceType->Vdd*wire_bw;/*inverter + output tr*/
    power.readOp.gate_leakage += cmos_Ig_leakage(min_w_nmos*size*3, min_w_pmos*size*3, 2, nand)*deviceType->Vdd*wire_bw;//nand
    power.readOp.gate_leakage += cmos_Ig_leakage(min_w_nmos*size*3, min_w_pmos*size*3, 2, nor)*deviceType->Vdd*wire_bw;//nor
    //power.readOp.gate_leakage *=;
  }
  else {
	power.readOp.leakage += cmos_Isub_leakage(min_w_nmos*tr_size*2, min_w_pmos*tr_size*2, 1, inv)*deviceType->Vdd*wire_bw;/*inverter + output tr*/
	power.readOp.leakage += cmos_Isub_leakage(min_w_nmos*size*3, min_w_pmos*size*3, 2, nand)*deviceType->Vdd*wire_bw;//nand
	power.readOp.leakage += cmos_Isub_leakage(min_w_nmos*size*3, min_w_pmos*size*3, 2, nor)*deviceType->Vdd*wire_bw;//nor

	power.readOp.gate_leakage += cmos_Ig_leakage(min_w_nmos*tr_size*2, min_w_pmos*tr_size*2, 1, inv)*deviceType->Vdd*wire_bw;/*inverter + output tr*/
    power.readOp.gate_leakage += cmos_Ig_leakage(min_w_nmos*size*3, min_w_pmos*size*3, 2, nand)*deviceType->Vdd*wire_bw;//nand
    power.readOp.gate_leakage += cmos_Ig_leakage(min_w_nmos*size*3, min_w_pmos*size*3, 2, nor)*deviceType->Vdd*wire_bw;//nor
    //power.readOp.gate_leakage *=deviceType->Vdd*wire_bw;
  }
}