예제 #1
0
void Comparator::CalculateLatency(double _rampInput) {
	if (!initialized) {
		cout << "[Comparator] Error: Require initialization first!" << endl;
	} else {
		rampInput = _rampInput;
		double resPullDown;
		double capNode;
		double tr;	/* time constant */
		double gm;	/* transconductance */
		double beta;	/* for horowitz calculation */
		double temp;
		readLatency = 0;
		for (int i = 0; i < COMPARATOR_INV_CHAIN_LEN - 1; i++) {
			resPullDown = CalculateOnResistance(widthNMOSInv[i], NMOS, inputParameter->temperature, *tech);
			capNode = capOutput[i] + capInput[i+1];
			tr = resPullDown * capNode;
			gm = CalculateTransconductance(widthNMOSInv[i], NMOS, *tech);
			beta = 1 / (resPullDown * gm);
			readLatency += horowitz(tr, beta, rampInput, &temp);
			rampInput = temp;	/* for next stage */
		}
		tr = resBottom * capBottom + (resBottom + resTop) * capTop;
		readLatency += horowitz(tr, 0, rampInput, &rampOutput);
		rampInput = _rampInput;
		writeLatency = readLatency;
	}
}
예제 #2
0
파일: htree2.cpp 프로젝트: bugamn/esesc
// 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;
}
예제 #3
0
파일: wire.cpp 프로젝트: Hopobcn/cacti
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
}
예제 #4
0
void TSV::_CalculateLatencyAndPower(double _rampInput, double &_dynamicEnergy, double &_latency)
{
    //Buffer chain delay and Dynamic Power
    double delay = 0.0;
    double rd, tf, this_delay, c_load, c_intrinsic; 
    double capInput, capOutput;
    double rampInput, rampOutput;
    double beta = 0.5; /* Carried over from CACTI3DD. */

    if (num_gates > 0) {
        rd = CalculateOnResistance(w_TSV_n[0], NMOS, inputParameter->temperature, *tech);
        CalculateGateCapacitance(INV, 1, w_TSV_n[1], w_TSV_p[1], tech->featureSize * MAX_TRANSISTOR_HEIGHT, *tech, &capInput, &capOutput);

        c_load = capInput + capOutput;
        c_intrinsic = CalculateDrainCap(w_TSV_p[0], PMOS, tech->featureSize * MAX_TRANSISTOR_HEIGHT, *tech) 
                     + CalculateDrainCap(w_TSV_n[0], NMOS, tech->featureSize * MAX_TRANSISTOR_HEIGHT, *tech);
        tf = rd * (c_intrinsic + c_load);

        // NVSIM3D - _rampInput should be subarray's senseAmpMuxLev2 rampOutput
        rampInput = _rampInput;
        this_delay = horowitz(tf, beta, rampInput, &rampOutput);
        delay += this_delay;

        double Vdd = tech->vdd;
        _dynamicEnergy = (c_load + c_intrinsic) * Vdd * Vdd;

        int i;
        for (i = 1; i < num_gates - 1; ++i)
        {
            rd = CalculateOnResistance(w_TSV_n[i], NMOS, inputParameter->temperature, *tech);
            CalculateGateCapacitance(INV, 1, w_TSV_n[i+1], w_TSV_p[i+1], tech->featureSize * MAX_TRANSISTOR_HEIGHT, *tech, &capInput, &capOutput);

            c_load = capInput + capOutput;
            c_intrinsic = CalculateDrainCap(w_TSV_p[i], PMOS, tech->featureSize * MAX_TRANSISTOR_HEIGHT, *tech) 
                       + CalculateDrainCap(w_TSV_n[i], NMOS, tech->featureSize * MAX_TRANSISTOR_HEIGHT, *tech);

            tf = rd * (c_intrinsic + c_load);
            rampInput = rampOutput;
            this_delay = horowitz(tf, beta, rampInput, &rampOutput);
            delay += this_delay;

            _dynamicEnergy += (c_load + c_intrinsic) * Vdd * Vdd;
        }

        // add delay of final inverter that drives the TSV
        i = num_gates - 1;
        c_load = C_load_TSV;

        rd = CalculateOnResistance(w_TSV_n[i], NMOS, inputParameter->temperature, *tech);
        c_intrinsic = CalculateDrainCap(w_TSV_p[i], PMOS, tech->featureSize * MAX_TRANSISTOR_HEIGHT, *tech) 
                     + CalculateDrainCap(w_TSV_n[i], NMOS, tech->featureSize * MAX_TRANSISTOR_HEIGHT, *tech);

        double R_TSV_out = res;
        tf = rd * (c_intrinsic + c_load) + R_TSV_out * c_load / 2;

        rampInput = rampOutput;
        this_delay = horowitz(tf, beta, rampInput, &rampOutput);
        delay  += this_delay;

        _dynamicEnergy += (c_load + c_intrinsic) * Vdd * Vdd;

        _latency = delay;
    } else {
        rampInput = _rampInput;
        c_load = cap;
        double R_TSV_out = res;
        tf = R_TSV_out * c_load / 2;
        double Vdd = tech->vdd;

        this_delay = horowitz(tf, beta, rampInput, &rampOutput);
        delay  += this_delay;

        _dynamicEnergy += (c_load) * Vdd * Vdd;

        _latency = delay;
    }
}
예제 #5
0
파일: wire.cpp 프로젝트: Hopobcn/cacti
/*
 * 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;
}
예제 #6
0
파일: htree2.cpp 프로젝트: bugamn/esesc
// 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;
  }
}