Пример #1
0
void TSV::Initialize(TSV_type tsv_type, bool buffered)
{
    int num_gates_min = 1;
    double min_w_pmos = tech->pnSizeRatio * MIN_NMOS_SIZE * tech->featureSize;
    num_gates = 1;

    cap = tech->capTSV[tsv_type];
    res = tech->resTSV[tsv_type];
    min_area = tech->areaTSV[tsv_type] * 1e-12;

    if (!buffered) {
        num_gates = 0;
    } else {
        double first_buf_stg_coef = 5; // To tune the total buffer delay.
        w_TSV_n[0] = MIN_NMOS_SIZE * first_buf_stg_coef * tech->featureSize;
        w_TSV_p[0] = w_TSV_n[0] * tech->pnSizeRatio;

        //BEOL parasitics in Katti's E modeling and charac. of TSV.  Needs further detailed values.
        //double res_beol    = 0.1;//inaccurate
        //double cap_beol    = 1e-15;

        //C_load_TSV    = cap_beol + cap + cap_beol + gate_C(g_tp.min_w_nmos_ + min_w_pmos, 0);

        C_load_TSV    = cap + CalculateGateCap(MIN_NMOS_SIZE * tech->featureSize + min_w_pmos, *tech); //+ 57.5e-15;
#ifdef NVSIM3DDEBUG
            cout << " The input cap of 1st buffer: " << CalculateGateCap(w_TSV_n[0] + w_TSV_p[0], *tech) * 1e15 << " fF";
#endif

        F = C_load_TSV / CalculateGateCap(w_TSV_n[0] + w_TSV_p[0], *tech);
#ifdef NVSIM3DDEBUG
        cout<<"\nF  is "<<F<<" \n";
#endif

        //Obtain buffer chain stages using logic effort function. Does stage number have to be even?
        num_gates = logical_effort(
            num_gates_min,
            1,
            F,
            w_TSV_n,
            w_TSV_p,
            C_load_TSV,
            tech->pnSizeRatio,
            MAX_NMOS_SIZE * tech->featureSize,
            *tech
        );
    }

    initialized = true;
    if (num_gates > MAX_NUMBER_GATES_STAGE) {
        invalid = true;
    }
}
Пример #2
0
void CalculateGateCapacitance(
		int gateType, int numInput,
		double widthNMOS, double widthPMOS,
		double heightTransistorRegion, Technology tech,
		double *capInput, double *capOutput) {
	/* TO-DO: most parts of this function is the same of CalculateGateArea,
	 * perhaps they will be combined in future
	 */
	double	ratio = widthPMOS / (widthPMOS + widthNMOS);

	double maxWidthPMOS = 0, maxWidthNMOS = 0;
	double unitWidthDrainP = 0, unitWidthDrainN = 0;
	double widthDrainP = 0, widthDrainN = 0;
	double heightDrainP = 0, heightDrainN = 0;
	int numFoldedPMOS = 1, numFoldedNMOS = 1;

	if (ratio == 0) {	/* no PMOS */
		maxWidthPMOS = 0;
		maxWidthNMOS = heightTransistorRegion;
	} else if (ratio == 1) {	/* no NMOS */
		maxWidthPMOS = heightTransistorRegion;
		maxWidthNMOS = 0;
	} else {
		maxWidthPMOS = ratio * (heightTransistorRegion - MIN_GAP_BET_P_AND_N_DIFFS * tech.featureSize);
		maxWidthNMOS = maxWidthPMOS / ratio * (1 - ratio);
	}

	if (widthPMOS > 0) {
		if (widthPMOS < maxWidthPMOS) { /* No folding */
			unitWidthDrainP = 0;
			heightDrainP = widthPMOS;
		} else {	/* Folding */
			if (maxWidthPMOS < 3 * tech.featureSize) {
				cout << "Error: Unable to do PMOS folding because PMOS size limitation is less than 3F!" <<endl;
				exit(-1);
			}
			numFoldedPMOS = (int)(ceil(widthPMOS / (maxWidthPMOS - 3 * tech.featureSize)));	/* 3F for folding overhead */
			unitWidthDrainP = (numFoldedPMOS-1) * tech.featureSize * MIN_GAP_BET_POLY;
			heightDrainP = maxWidthPMOS;
		}
	} else {
		unitWidthDrainP = 0;
		heightDrainP = 0;
	}

	if (widthNMOS > 0) {
		if (widthNMOS < maxWidthNMOS) { /* No folding */
			unitWidthDrainN = 0;
			heightDrainN = widthNMOS;
		} else {	/* Folding */
			if (maxWidthNMOS < 3 * tech.featureSize) {
				cout << "Error: Unable to do NMOS folding because NMOS size limitation is less than 3F!" <<endl;
				exit(-1);
			}
			numFoldedNMOS = (int)(ceil(widthNMOS / (maxWidthNMOS - 3 * tech.featureSize)));	/* 3F for folding overhead */
			unitWidthDrainN = (numFoldedNMOS-1) * tech.featureSize * MIN_GAP_BET_POLY;
			heightDrainN = maxWidthNMOS;
		}
	} else {
		unitWidthDrainN = 0;
		heightDrainN = 0;
	}

	switch (gateType) {
	case INV:
		if (widthPMOS > 0)
			widthDrainP = tech.featureSize * (CONTACT_SIZE + MIN_GAP_BET_CONTACT_POLY * 2) + unitWidthDrainP;
		if (widthNMOS > 0)
			widthDrainN = tech.featureSize * (CONTACT_SIZE + MIN_GAP_BET_CONTACT_POLY * 2) + unitWidthDrainN;
		break;
	case NOR:
		/* PMOS is in series, worst case capacitance is below */
		if (widthPMOS > 0)
			widthDrainP = tech.featureSize * (CONTACT_SIZE + MIN_GAP_BET_CONTACT_POLY * 2)
						+ unitWidthDrainP * numInput + (numInput - 1) * tech.featureSize * MIN_GAP_BET_POLY;
		/* NMOS is parallel, capacitance is multiplied as below */
		if (widthNMOS > 0)
			widthDrainN = (tech.featureSize * (CONTACT_SIZE + MIN_GAP_BET_CONTACT_POLY * 2)
						+ unitWidthDrainN) * numInput;
		break;
	case NAND:
		/* NMOS is in series, worst case capacitance is below */
		if (widthNMOS > 0)
			widthDrainN = tech.featureSize * (CONTACT_SIZE + MIN_GAP_BET_CONTACT_POLY * 2)
						+ unitWidthDrainN * numInput + (numInput - 1) * tech.featureSize * MIN_GAP_BET_POLY;
		/* PMOS is parallel, capacitance is multiplied as below */
		if (widthPMOS > 0)
			widthDrainP = (tech.featureSize * (CONTACT_SIZE + MIN_GAP_BET_CONTACT_POLY * 2)
						+ unitWidthDrainP) * numInput;
		break;
	default:
		widthDrainN = widthDrainP = 0;
	}

	/* Junction capacitance */
	double capDrainBottomN = widthDrainN * heightDrainN * tech.capJunction;
	double capDrainBottomP = widthDrainP * heightDrainP * tech.capJunction;

	/* Sidewall capacitance */
	double capDrainSidewallN, capDrainSidewallP;
	if (numFoldedNMOS % 2 == 0)
		capDrainSidewallN = 2 * widthDrainN * tech.capSidewall;
	else
		capDrainSidewallN = (2 * widthDrainN + heightDrainN) * tech.capSidewall;
	if (numFoldedPMOS % 2 == 0)
		capDrainSidewallP = 2 * widthDrainP * tech.capSidewall;
	else
		capDrainSidewallP = (2* widthDrainP + heightDrainP) * tech.capSidewall;

	/* Drain to channel capacitance */
	double capDrainToChannelN = numFoldedNMOS * heightDrainN * tech.capDrainToChannel;
	double capDrainToChannelP = numFoldedPMOS * heightDrainP * tech.capDrainToChannel;

	if (capOutput)
		*(capOutput) = capDrainBottomN + capDrainBottomP + capDrainSidewallN + capDrainSidewallP + capDrainToChannelN + capDrainToChannelP;
	if (capInput)
		*(capInput) = CalculateGateCap(widthNMOS, tech) + CalculateGateCap(widthPMOS, tech);
}