⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 time.c.svn-base

📁 模拟多核状态下龙芯处理器的功能
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
    rows = (C/(B*Ndbl));
    if(!force_tag) {
      //tagbits = ADDRESS_BITS + EXTRA_TAG_BITS-(int)logtwo((double)B);
      tagbits = ADDRESS_BITS + EXTRA_TAG_BITS-(int)(logtwo((double)B) + EPSILON);
    }
    else {
      tagbits = force_tag_size;
    }
    cols = (CHUNKSIZE*B)+tagbits;
  }

  /* calculate some layout info */


  if(Ndwl*Ndbl==1) {
    l_outdrv_v= 0;
    l_outdrv_h= cols;

    Coutdrvtreesegments[0] = GlobalCwordmetal*cols;
    Routdrvtreesegments[0] = 0.5*GlobalRwordmetal*cols;

    Cline = gatecap(Wsenseextdrv1n+Wsenseextdrv1p,10.0 / FUDGEFACTOR)+GlobalCwordmetal*cols;
    Cload = Cline / gatecap(1.0,0.0);

    current_ndriveW = Cload*SizingRatio/3;
    current_pdriveW = 2*Cload*SizingRatio/3;

    nr_outdrvtreesegments = 0;
  }
  else if(Ndwl*Ndbl==2) {
    l_outdrv_v= 0;
    l_outdrv_h= 2*cols;

    Coutdrvtreesegments[0] = GlobalCwordmetal*2*cols;
    Routdrvtreesegments[0] = 0.5*GlobalRwordmetal*2*cols;

    Cline = gatecap(Wsenseextdrv1n+Wsenseextdrv1p,10.0/ FUDGEFACTOR)+GlobalCwordmetal*2*cols;
    Cload = Cline / gatecap(1.0,0.0);

    current_ndriveW = Cload*SizingRatio/3;
    current_pdriveW = 2*Cload*SizingRatio/3;

    nr_outdrvtreesegments = 0;
  }
  else if(Ndwl*Ndbl>2) {
    nr_subarrays_left = Ndwl* Ndbl;
    nr_subarrays_left /= 2;
    /*dt: assuming the sense amps are in the middle of each subarray */
    horizontal_step = cols/2;
    vertical_step = rows/2;
    l_outdrv_h = horizontal_step;

    Coutdrvtreesegments[0] = GlobalCwordmetal*horizontal_step;
    Routdrvtreesegments[0] = 0.5*GlobalRwordmetal*horizontal_step;
    nr_outdrvtreesegments = 1;

    horizontal_step *= 2;
    v_or_h = 1; // next step is vertical

    while(nr_subarrays_left > 1) {
      nr_outdrvtreesegments++;
      if(v_or_h) {
        l_outdrv_v += vertical_step;

        Coutdrvtreesegments[nr_outdrvtreesegments-1] = GlobalCbitmetal*vertical_step;
        Routdrvtreesegments[nr_outdrvtreesegments-1] = 0.5*GlobalRbitmetal*vertical_step;

        v_or_h = 0;
        vertical_step *= 2;
        nr_subarrays_left /= 2;
      }
      else {
        l_outdrv_h += horizontal_step;

        Coutdrvtreesegments[nr_outdrvtreesegments-1] = GlobalCwordmetal*horizontal_step;
        Routdrvtreesegments[nr_outdrvtreesegments-1] = 0.5*GlobalRwordmetal*horizontal_step;

        v_or_h = 1;
        horizontal_step *= 2;
        nr_subarrays_left /= 2;
      }
    }

    /*dt: Now that we have all the H-tree segments for the output tree, 
      we can walk it in reverse and calc the gate widths*/

    previous_ndriveW = Wsenseextdrv1n;
    previous_pdriveW = Wsenseextdrv1p;
    for(i = nr_outdrvtreesegments-1;i>0;i--) {
      Cline = gatecap(previous_ndriveW+previous_pdriveW,0)+Coutdrvtreesegments[i];
      Cload = Cline / gatecap(1.0,0.0);

      current_ndriveW = Cload*SizingRatio/3;
      current_pdriveW = 2*Cload*SizingRatio/3;

      WoutdrvtreeN[i] = current_ndriveW;

      previous_ndriveW = current_ndriveW;
      previous_pdriveW = current_pdriveW;
    }
  }

  if(nr_outdrvtreesegments >= 20) {
    printf("Too many segments in the output H-tree. Overflowing the preallocated array!");
    exit(1);
  }
  // typical width of gate considered for the estimating val of draincap.
  Cload = gatecap(previous_ndriveW+previous_pdriveW,0) + Coutdrvtreesegments[0] + 
    (draincap(5.0/ FUDGEFACTOR,NCH,1)+draincap(5.0/ FUDGEFACTOR,PCH,1))*A*muxover;

  Woutdrivern = 	(Cload/gatecap(1.0,0.0))*SizingRatio/3;
  Woutdriverp = 	(Cload/gatecap(1.0,0.0))*SizingRatio*2/3;

  // eff load for nor gate = gatecap(drv_p);
  // factor of 2 is needed to account for series nmos transistors in nor2
  Woutdrvnorp = 2*Woutdriverp*SizingRatio*2/3;
  Woutdrvnorn = Woutdriverp*SizingRatio/3;

  // factor of 2 is needed to account for series nmos transistors in nand2
  Woutdrvnandp = Woutdrivern*SizingRatio*2/3;
  Woutdrvnandn = 2*Woutdrivern*SizingRatio/3;

  Woutdrvselp = (Woutdrvnandp + Woutdrvnandn) * SizingRatio*2/3;
  Woutdrvseln = (Woutdrvnandp + Woutdrvnandn) * SizingRatio/3;

}


void compute_tag_device_widths(int C,int B,int A,int Ntspd,int Ntwl,int Ntbl,double NSubbanks)
{

  int rows,cols, tagbits, numstack,l_predec_nor_v,l_predec_nor_h;
  double Cline, Cload, Rpdrive,desiredrisetime;
  double effWtdecNORn,effWtdecNORp,effWtdec3to8n,effWtdec3to8p, wire_res, wire_cap;
  int horizontal_edge = 0;
  int nr_subarrays_left = 0, v_or_h = 0;
  int horizontal_step = 0, vertical_step = 0;
  int h_inv_predecode = 0, v_inv_predecode = 0;

  double previous_ndriveW = 0, previous_pdriveW = 0, current_ndriveW = 0, current_pdriveW = 0;

  rows = C/(CHUNKSIZE*B*A*Ntbl*Ntspd);
  if(!force_tag) {
    //v4.1: Fixing double->int type conversion problems. EPSILON is added below to make sure
    //the final int value is the correct one 
    //tagbits = ADDRESS_BITS + EXTRA_TAG_BITS-(int)logtwo((double)C)+(int)logtwo((double)A)-(int)(logtwo(NSubbanks));
    tagbits = (int) (ADDRESS_BITS + EXTRA_TAG_BITS-(int)logtwo((double)C)+(int)logtwo((double)A)-(int)(logtwo(NSubbanks)) + EPSILON);
  }
  else {
    tagbits = force_tag_size;
  }
  cols = tagbits * A * Ntspd/Ntwl;

  // capacitive load on the wordline - C_int + C_memCellLoad * NCells
  Cline = (gatecappass(Wmemcella,(BitWidth-2*Wmemcella)/2.0)+
      gatecappass(Wmemcella,(BitWidth-2*Wmemcella)/2.0)+ TagCwordmetal)*cols;

  /*dt: changing the calculations for the tag wordline to be the same as for the data wordline*/
  /* Use a first-order approx */
  desiredrisetime = krise*log((double)(cols))/2.0;

  Rpdrive = desiredrisetime/(Cline*log(VSINV)*-1.0);
  WtwlDrvp = restowidth(Rpdrive,PCH);
  if (WtwlDrvp > Wworddrivemax) {
    WtwlDrvp = Wworddrivemax;
  }

  WtwlDrvn = WtwlDrvp/2;

  Wtdecinvn = (WtwlDrvn + WtwlDrvp)*SizingRatio*1/3;
  Wtdecinvp = (WtwlDrvn + WtwlDrvp)*SizingRatio*2/3;

  // determine widths of nand, nor gates in the tag decoder
  // width of NOR driving decInv -
  // effective width (NORp + NORn = Cout/SizingRatio( FANOUT))
  // Cout = Wdecinvn + Wdecinvp; SizingRatio = 3;
  // nsize = effWidth/3; psize = 2*effWidth/3;
  numstack =
    (int)ceil((1.0/3.0)*logtwo( (double)((double)C/(double)(B*A*Ntbl*Ntspd))));
  if (numstack==0) numstack = 1;
  if (numstack>5) numstack = 5;

  effWtdecNORn = (Wtdecinvn + Wtdecinvp)*SizingRatio/3;
  effWtdecNORp = 2*(Wtdecinvn + Wtdecinvp)*SizingRatio/3;
  WtdecNORn = effWtdecNORn;
  WtdecNORp = effWtdecNORp * numstack;

  /*dt: The *8 is there because above we mysteriously divide the capacity in BYTES by the number of BITS per wordline */
  l_predec_nor_v = rows*8; 
  /*dt: If we follow the original drawings from the TR's, then there is almost no horizontal wires, only the poly for contacting
    the nor gates. The poly part we don't model right now */
  l_predec_nor_h = 0;

  // find width of the nand gates in the 3-8 decoders
  Cline = gatecap(WtdecNORn+WtdecNORp,((numstack*40)/ FUDGEFACTOR + 20.0 / FUDGEFACTOR))*rows/8 +
    GlobalCbitmetal*(l_predec_nor_v) + GlobalCwordmetal*(l_predec_nor_h);

  Cload = Cline / gatecap(1.0,0.0);

  effWtdec3to8n = Cload*SizingRatio/3;
  effWtdec3to8p = 2*Cload*SizingRatio/3;

  Wtdec3to8n = effWtdec3to8n * 3; // nand3 gate
  Wtdec3to8p = effWtdec3to8p;

  horizontal_edge = cols*Ntwl;

  previous_ndriveW = Wtdec3to8n;
  previous_pdriveW = Wtdec3to8p;

  if(Ntwl*Ntbl==1 ) {
    wire_cap = GlobalCwordmetal*horizontal_edge;
    wire_res = 0.5*GlobalRwordmetal*horizontal_edge;

    Ctdectreesegments[0] = GlobalCwordmetal*horizontal_edge;
    Rtdectreesegments[0] = 0.5*GlobalRwordmetal*horizontal_edge;

    Cline = 4*gatecap(previous_ndriveW+previous_pdriveW,10.0 / FUDGEFACTOR)+GlobalCwordmetal*horizontal_edge;
    Cload = Cline / gatecap(1.0,0.0);

    current_ndriveW = Cload*SizingRatio/3;
    current_pdriveW = 2*Cload*SizingRatio/3;

    nr_tdectreesegments = 0;
  }
  else if(Ntwl*Ntbl==2 || Ntwl*Ntbl==4) {
    wire_cap = GlobalCwordmetal*0.5*horizontal_edge;
    wire_res = 0.5*GlobalRwordmetal*0.5*horizontal_edge;

    Ctdectreesegments[0] = GlobalCwordmetal*horizontal_edge;
    Rtdectreesegments[0] = 0.5*GlobalRwordmetal*horizontal_edge;

    Cline = 4*gatecap(previous_ndriveW+previous_pdriveW,10.0 / FUDGEFACTOR)+GlobalCwordmetal*horizontal_edge;
    Cload = Cline / gatecap(1.0,0.0);

    current_ndriveW = Cload*SizingRatio/3;
    current_pdriveW = 2*Cload*SizingRatio/3;

    nr_tdectreesegments = 0;
  }
  else {
    nr_subarrays_left = Ntwl*Ntbl;
    nr_subarrays_left /= 4;
    horizontal_step = cols;
    vertical_step = C/(B*A*Ntbl*Ntspd);
    h_inv_predecode = horizontal_step;

    Ctdectreesegments[0] = GlobalCwordmetal*horizontal_step;
    Rtdectreesegments[0] = 0.5*GlobalRwordmetal*horizontal_step;
    Cline = 4*gatecap(previous_ndriveW+previous_pdriveW,10.0 / FUDGEFACTOR)+GlobalCwordmetal*horizontal_step;
    Cload = Cline / gatecap(1.0,0.0);

    current_ndriveW = Cload*SizingRatio/3;
    current_pdriveW = 2*Cload*SizingRatio/3;
    WtdecdrivetreeN[0] = current_ndriveW;
    nr_tdectreesegments = 1;

    horizontal_step *= 2;
    v_or_h = 1; // next step is vertical

    while(nr_subarrays_left > 1) {
      previous_ndriveW = current_ndriveW;
      previous_pdriveW = current_pdriveW;
      nr_tdectreesegments++;
      if(v_or_h) {
        v_inv_predecode += vertical_step;
        Ctdectreesegments[nr_tdectreesegments-1] = GlobalCbitmetal*vertical_step;
        Rtdectreesegments[nr_tdectreesegments-1] = 0.5*GlobalRbitmetal*vertical_step;
        Cline = gatecap(previous_ndriveW+previous_pdriveW,0)+GlobalCbitmetal*vertical_step;
        v_or_h = 0;
        vertical_step *= 2;
        nr_subarrays_left /= 2;
      }
      else {
        h_inv_predecode += horizontal_step;
        Ctdectreesegments[nr_tdectreesegments-1] = GlobalCwordmetal*horizontal_step;
        Rtdectreesegments[nr_tdectreesegments-1] = 0.5*GlobalRwordmetal*horizontal_step;
        Cline = gatecap(previous_ndriveW+previous_pdriveW,0)+GlobalCwordmetal*horizontal_step;
        v_or_h = 1;
        horizontal_step *= 2;
        nr_subarrays_left /= 2;
      }
      Cload = Cline / gatecap(1.0,0.0);

      current_ndriveW = Cload*SizingRatio/3;
      current_pdriveW = 2*Cload*SizingRatio/3;

      WtdecdrivetreeN[nr_tdectreesegments-1] = current_ndriveW;
    }

    if(nr_tdectreesegments >= 10) {
      printf("Too many segments in the tag decoder H-tree. Overflowing the preallocated array!");
      exit(1);
    }

    wire_cap = GlobalCbitmetal*v_inv_predecode + GlobalCwordmetal*h_inv_predecode;
    wire_res = 0.5*(GlobalRbitmetal*v_inv_predecode + GlobalRwordmetal*h_inv_predecode);
  }

  Cline = 4*gatecap(Wtdec3to8n+Wtdec3to8p,10.0 / FUDGEFACTOR) + wire_cap;
  Cload = Cline / gatecap(1.0,0.0);

  Wtdecdriven_second = current_ndriveW;
  Wtdecdrivep_second = current_pdriveW;

  // Size of second driver

  Wtdecdriven_first = (Wtdecdriven_second + Wtdecdrivep_second)*SizingRatio/3;
  Wtdecdrivep_first = 2*(Wtdecdriven_second + Wtdecdrivep_second)*SizingRatio/3;

}
double cmos_ileakage(double nWidth, double pWidth,
    double nVthresh_dual, double nVthreshold, double pVthresh_dual, double pVthreshold) {
  double leakage = 0.0;
  static int valid_cache = 0;
  static double cached_nmos_thresh = 0;
  static double cached_pmos_thresh = 0;

  static double norm_nmos_leakage = 0;
  static double norm_pmos_leakage = 0;

  if(have_leakage_params) {

    if (dualVt == TRUE) {

      if((cached_nmos_thresh == nVthresh_dual) && (cached_pmos_thresh == pVthresh_dual) && valid_cache) {
        leakage = nWidth*norm_nmos_leakage + pWidth*norm_pmos_leakage;
      }
      else {
        leakage = simplified_cmos_leakage(nWidth*inv_Leff,pWidth*inv_Leff,nVthresh_dual,pVthresh_dual,&norm_nmos_leakage,&norm_pmos_leakage);
        cached_nmos_thresh = nVthresh_dual;
        cached_pmos_thresh = pVthresh_dual;
        norm_nmos_leakage = inv_Leff*norm_nmos_leakage;
        norm_pmos_leakage = inv_Leff*norm_pmos_leakage;
        valid_cache = 1;
      }
    }
    else {

      if((cached_nmos_thresh == nVthreshold) && (cached_pmos_thresh == pVthreshold) && valid_cache) {
        leakage = nWidth*norm_nmos_leakage + pWidth*norm_pmos_leakage;
      }
      else {
        leakage = simplified_cmos_leakage(nWidth*inv_Leff,pWidth*inv_Leff,nVthreshold,pVthreshold,&norm_nmos_leakage,&norm_pmos_leakage);
        cached_nmos_thresh = nVthreshold;
        cached_pmos_thresh = pVthreshold;
        norm_nmos_leakage = inv_Leff*norm_nmos_leakage;
        norm_pmos_leakage = inv_Leff*norm_pmos_leakage;
        valid_cache = 1;
      }
    }
  }
  else {
    leakage = 0;
  }
  return leakage;
}
void reset_powerDef(powerDef *power) {
  power->readOp.dynamic = 0.0;
  power->readOp.leakage = 0.0;

  power->writeOp.dynamic = 0.0;
  power->writeOp.leakage = 0.0;
}
void mult_powerDef(powerDef *power, int val) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -