static double SIM_crossbar_in_cap(double wire_cap, u_int n_out, int connect_type, int trans_type, double *Nsize) { double Ctotal = 0, Ctrans=0.0, psize, nsize; /* part 1: wire cap */ Ctotal = wire_cap; /* part 2: drain cap of transmission gate or gate cap of tri-state gate */ if (connect_type == TRANS_GATE) { /* FIXME: resizing strategy */ nsize = Nsize ? *Nsize : Wmemcellr; psize = nsize * Wdecinvp / Wdecinvn; Ctrans = SIM_power_draincap(nsize, NCH, 1); if (trans_type == NP_GATE) Ctrans += SIM_power_draincap(psize, PCH, 1); } else if (connect_type == TRISTATE_GATE) { Ctrans = SIM_power_gatecap(Woutdrvnandn + Woutdrvnandp, 0) + SIM_power_gatecap(Woutdrvnorn + Woutdrvnorp, 0); } else {/* some error handler */} Ctotal += n_out * Ctrans; /* part 3: input driver */ /* FIXME: how to specify timing? */ psize = SIM_power_driver_size(Ctotal, Period / 3); nsize = psize * Wdecinvn / Wdecinvp; Ctotal += SIM_power_draincap(nsize, NCH, 1) + SIM_power_draincap(psize, PCH, 1) + SIM_power_gatecap(nsize + psize, 0); return Ctotal / 2; }
/* switch cap of grant signal (round robin arbiter) */ static double SIM_rr_arbiter_grant_cap() { double Ctotal = 0; /* part 1: drain cap of NOR gate */ /* FIXME: need actual size */ Ctotal += 2 * SIM_power_draincap(WdecNORn, NCH, 1) + SIM_power_draincap(WdecNORp, PCH, 2); return Ctotal; }
/* switch cap of internal node (matrix arbiter) */ static double SIM_matrix_arbiter_int_cap() { double Ctotal = 0; /* part 1: drain cap of NOR gate */ Ctotal += 2 * SIM_power_draincap(WdecNORn, NCH, 1) + SIM_power_draincap(WdecNORp, PCH, 2); /* part 2: gate cap of the "huge" NOR gate */ Ctotal += SIM_power_gatecap(WdecNORn + WdecNORp, 0); return Ctotal; }
/* no 1/2 due to req precharging */ static double SIM_iwin_sel_enc_cap(u_int level) { double Ctotal; /* part 1: drain cap of priority encoder */ Ctotal = level * SIM_power_draincap(WSelPn, NCH, 1) + SIM_power_draincap(WSelPp, PCH, level); /* part 2: gate cap of next-level NAND gate */ /* WHS: 20 should go to PARM */ Ctotal += SIM_power_gatecap(WSelEnn + WSelEnp, 20); return Ctotal; }
/* this model is based on the gate-level design given by Randy H. Katz "Contemporary Logic Design" * Figure 6.24, node numbers (1-6) are assigned to all gate outputs, left to right, top to bottom * * We should have pure cap functions and leave the decision of whether or not to have coefficient * 1/2 in init function. */ static double SIM_fpfp_node_cap(u_int fan_in, u_int fan_out) { double Ctotal = 0; /* FIXME: all need actual sizes */ /* part 1: drain cap of NOR gate */ Ctotal += fan_in * SIM_power_draincap(WdecNORn, NCH, 1) + SIM_power_draincap(WdecNORp, PCH, fan_in); /* part 2: gate cap of NOR gates */ Ctotal += fan_out * SIM_power_gatecap(WdecNORn + WdecNORp, 0); return Ctotal; }
/* switch cap of internal carry node (round robin arbiter) */ static double SIM_rr_arbiter_carry_in_cap() { double Ctotal = 0; /* part 1: gate cap of 2 NOR gates */ /* FIXME: need actual size */ Ctotal += 2 * SIM_power_gatecap(WdecNORn + WdecNORp, 0); /* part 2: drain cap of NOR gate */ /* FIXME: need actual size */ Ctotal += 2 * SIM_power_draincap(WdecNORn, NCH, 1) + SIM_power_draincap(WdecNORp, PCH, 2); return Ctotal; }
static double SIM_generic_bus_cap(u_int n_snd, u_int n_rcv, double length, double time) { double Ctotal = 0; double n_size, p_size; /* part 1: wire cap */ /* WHS: use minimal pitch for buses */ Ctotal += CCmetal * length; if ((n_snd == 1) && (n_rcv == 1)) { /* directed bus if only one sender and one receiver */ /* part 2: repeater cap */ /* FIXME: ratio taken from Raw, does not scale now */ n_size = Lamda * 10; p_size = n_size * 2; Ctotal += SIM_power_gatecap(n_size + p_size, 0) + SIM_power_draincap(n_size, NCH, 1) + SIM_power_draincap(p_size, PCH, 1); n_size *= 2.5; p_size *= 2.5; Ctotal += SIM_power_gatecap(n_size + p_size, 0) + SIM_power_draincap(n_size, NCH, 1) + SIM_power_draincap(p_size, PCH, 1); } else { /* otherwise, broadcasting bus */ /* part 2: input cap */ /* WHS: no idea how input interface is, use an inverter for now */ Ctotal += n_rcv * SIM_power_gatecap(Wdecinvn + Wdecinvp, 0); /* part 3: output driver cap */ if (time) { p_size = SIM_power_driver_size(Ctotal, time); n_size = p_size / 2; } else { p_size = Wbusdrvp; n_size = Wbusdrvn; } Ctotal += n_snd * (SIM_power_draincap(Wdecinvn, NCH, 1) + SIM_power_draincap(Wdecinvp, PCH, 1)); } return Ctotal; }
/* no 1/2 due to precharging */ static double SIM_iwin_sel_anyreq_cap(u_int width) { double Ctotal; /* part 1: drain cap of precharging gate */ Ctotal = SIM_power_draincap(WSelORprequ, PCH, 1); /* part 2: drain cap of NOR gate */ Ctotal += width * SIM_power_draincap(WSelORn, NCH, 1); /* part 3: inverter cap */ /* WHS: no size information, assume decinv */ Ctotal += SIM_power_draincap(Wdecinvn, NCH, 1) + SIM_power_draincap(Wdecinvp, PCH, 1) + SIM_power_gatecap(Wdecinvn + Wdecinvp, 1); return Ctotal; }
/* switch cap of request signal (round robin arbiter) */ static double SIM_rr_arbiter_req_cap(double length) { double Ctotal = 0; /* part 1: gate cap of 2 NOR gates */ /* FIXME: need actual size */ Ctotal += 2 * SIM_power_gatecap(WdecNORn + WdecNORp, 0); /* part 2: inverter */ /* FIXME: need actual size */ Ctotal += SIM_power_draincap(Wdecinvn, NCH, 1) + SIM_power_draincap(Wdecinvp, PCH, 1) + SIM_power_gatecap(Wdecinvn + Wdecinvp, 0); /* part 3: wire cap */ Ctotal += length * Cmetal; return Ctotal; }
/* no 1/2 due to req precharging */ static double SIM_iwin_sel_grant_cap(u_int width) { double Ctotal; /* part 1: drain cap of NAND gate */ Ctotal = SIM_power_draincap(WSelEnn, NCH, 2) + 2 * SIM_power_draincap(WSelEnp, PCH, 1); /* part 2: inverter cap */ /* WHS: no size information, assume decinv */ Ctotal += SIM_power_draincap(Wdecinvn, NCH, 1) + SIM_power_draincap(Wdecinvp, PCH, 1) + SIM_power_gatecap(Wdecinvn + Wdecinvp, 1); /* part 3: gate cap of enable signal */ /* grant signal is enable signal to the lower-level arbiter */ /* WHS: 20 should go to PARM */ Ctotal += width * SIM_power_gatecap(WSelEnn + WSelEnp, 20); return Ctotal; }
/* switch cap of request signal (matrix arbiter) */ static double SIM_matrix_arbiter_req_cap(u_int req_width, double length) { double Ctotal = 0; /* FIXME: all need actual sizes */ /* part 1: gate cap of NOR gates */ Ctotal += (req_width - 1) * SIM_power_gatecap(WdecNORn + WdecNORp, 0); /* part 2: inverter */ Ctotal += SIM_power_draincap(Wdecinvn, NCH, 1) + SIM_power_draincap(Wdecinvp, PCH, 1) + SIM_power_gatecap(Wdecinvn + Wdecinvp, 0); /* part 3: gate cap of the "huge" NOR gate */ Ctotal += SIM_power_gatecap(WdecNORn + WdecNORp, 0); /* part 4: wire cap */ Ctotal += length * Cmetal; return Ctotal; }
static double SIM_crossbar_ctr_cap(double length, u_int data_width, int prev_ctr, int next_ctr, u_int degree, int connect_type, int trans_type) { double Ctotal = 0, Cgate=0.0; /* part 1: wire cap */ Ctotal = Cmetal * length; /* part 2: gate cap of transmission gate or tri-state gate */ if (connect_type == TRANS_GATE) { /* FIXME: Wmemcellr and resize */ Cgate = SIM_power_gatecap(Wmemcellr, 0); if (trans_type == NP_GATE) Cgate += SIM_power_gatecap(Wmemcellr * Wdecinvp / Wdecinvn, 0); } else if (connect_type == TRISTATE_GATE) { Cgate = SIM_power_gatecap(Woutdrvnandn + Woutdrvnandp, 0) + SIM_power_gatecap(Woutdrvnorn + Woutdrvnorp, 0); } else {/* some error handler */} Ctotal += data_width * Cgate; /* part 3: inverter */ if (!(connect_type == TRANS_GATE && trans_type == N_GATE && !prev_ctr)) /* FIXME: need accurate size, use minimal size for now */ Ctotal += SIM_power_draincap(Wdecinvn, NCH, 1) + SIM_power_draincap(Wdecinvp, PCH, 1) + SIM_power_gatecap(Wdecinvn + Wdecinvp, 0); /* part 4: drain cap of previous level control signal */ if (prev_ctr) /* FIXME: need actual size, use decoder data for now */ Ctotal += degree * SIM_power_draincap(WdecNORn, NCH, 1) + SIM_power_draincap(WdecNORp, PCH, degree); /* part 5: gate cap of next level control signal */ if (next_ctr) /* FIXME: need actual size, use decoder data for now */ Ctotal += SIM_power_gatecap(WdecNORn + WdecNORp, degree * 40 + 20); return Ctotal; }
/* cut-through crossbar only supports 4x4 now */ static double SIM_crossbar_io_cap(double length) { double Ctotal = 0, psize, nsize; /* part 1: wire cap */ Ctotal += CC3metal * length; /* part 2: gate cap of tri-state gate */ Ctotal += 2 * (SIM_power_gatecap(Woutdrvnandn + Woutdrvnandp, 0) + SIM_power_gatecap(Woutdrvnorn + Woutdrvnorp, 0)); /* part 3: drain cap of tri-state gate */ Ctotal += 2 * (SIM_power_draincap(Woutdrivern, NCH, 1) + SIM_power_draincap(Woutdriverp, PCH, 1)); /* part 4: input driver */ /* FIXME: how to specify timing? */ psize = SIM_power_driver_size(Ctotal, Period * 0.8); nsize = psize * Wdecinvn / Wdecinvp; Ctotal += SIM_power_draincap(nsize, NCH, 1) + SIM_power_draincap(psize, PCH, 1) + SIM_power_gatecap(nsize + psize, 0); /* part 5: output driver */ Ctotal += SIM_power_draincap(Woutdrivern, NCH, 1) + SIM_power_draincap(Woutdriverp, PCH, 1) + SIM_power_gatecap(Woutdrivern + Woutdriverp, 0); /* HACK HACK HACK */ /* this HACK is to count a 1:4 mux and a 4:1 mux, so we have a 5x5 crossbar */ return Ctotal / 2 * 1.32; }
static double SIM_crossbar_out_cap(double length, u_int n_in, double n_seg, int connect_type, int trans_type, double *Nsize) { double Ctotal = 0, Ctrans, psize, nsize; /* part 1: wire cap */ Ctotal += CC3metal * length; /* part 2: drain cap of transmission gate or tri-state gate */ if (connect_type == TRANS_GATE) { /* FIXME: resizing strategy */ if (Nsize) { /* FIXME: how to specify timing? */ psize = SIM_power_driver_size(Ctotal, Period / 3); *Nsize = nsize = psize * Wdecinvn / Wdecinvp; } else { nsize = Wmemcellr; psize = nsize * Wdecinvp / Wdecinvn; } Ctrans = SIM_power_draincap(nsize, NCH, 1); if (trans_type == NP_GATE) Ctrans += SIM_power_draincap(psize, PCH, 1); } else if (connect_type == TRISTATE_GATE) { Ctrans = SIM_power_draincap(Woutdrivern, NCH, 1) + SIM_power_draincap(Woutdriverp, PCH, 1); } else {/* some error handler */} Ctotal += n_in * Ctrans; /* segmented crossbar */ if (n_seg > 1) { Ctotal *= (n_seg + 1)/(n_seg * 2); /* input capacitance of tri-state buffer */ Ctotal += (n_seg + 2)*(n_seg - 1)/(n_seg * 2)*(SIM_power_gatecap(Woutdrvnandn + Woutdrvnandp, 0) + SIM_power_gatecap(Woutdrvnorn + Woutdrvnorp, 0)); /* output capacitance of tri-state buffer */ Ctotal += (n_seg - 1) / 2 * (SIM_power_draincap(Woutdrivern, NCH, 1) + SIM_power_draincap(Woutdriverp, PCH, 1)); } /* part 3: output driver */ Ctotal += SIM_power_draincap(Woutdrivern, NCH, 1) + SIM_power_draincap(Woutdriverp, PCH, 1) + SIM_power_gatecap(Woutdrivern + Woutdriverp, 0); return Ctotal / 2; }
static double SIM_crossbar_int_cap(u_int degree, int connect_type, int trans_type) { double Ctotal = 0, Ctrans; if (connect_type == TRANS_GATE) { /* part 1: drain cap of transmission gate */ /* FIXME: Wmemcellr and resize */ Ctrans = SIM_power_draincap(Wmemcellr, NCH, 1); if (trans_type == NP_GATE) Ctrans += SIM_power_draincap(Wmemcellr * Wdecinvp / Wdecinvn, PCH, 1); Ctotal += (degree + 1) * Ctrans; } else if (connect_type == TRISTATE_GATE) { /* part 1: drain cap of tri-state gate */ Ctotal += degree * (SIM_power_draincap(Woutdrivern, NCH, 1) + SIM_power_draincap(Woutdriverp, PCH, 1)); /* part 2: gate cap of tri-state gate */ Ctotal += SIM_power_gatecap(Woutdrvnandn + Woutdrvnandp, 0) + SIM_power_gatecap(Woutdrvnorn + Woutdrvnorp, 0); } else {/* some error handler */} return Ctotal / 2; }
static double c_NAND(u_int n_in) { if (n_in == 2) return (2 * SIM_power_draincap(Walu2NANDp, PCH, 1) + SIM_power_draincap(Walu2NANDn, NCH, 2) + 2 * SIM_power_gatecap(Walu2NANDp + Walu2NANDn, 0)); else if (n_in == 3) return (3 * SIM_power_draincap(Walu3NANDp, PCH, 1) + SIM_power_draincap(Walu3NANDn, NCH, 3) + 3 * SIM_power_gatecap(Walu3NANDp + Walu3NANDn, 0)); else if (n_in == 4) return (4 * SIM_power_draincap(Walu4NANDp, PCH, 1) + SIM_power_draincap(Walu4NANDn, NCH, 4) + 4 * SIM_power_gatecap(Walu4NANDp + Walu4NANDn, 0)); else return -1; }
static double c_NOR(u_int n_in) { if (n_in == 2) return (SIM_power_draincap(Walu2NORp, PCH, 2) + 2 * SIM_power_draincap(Walu2NORn, NCH, 1) + 2 * SIM_power_gatecap(Walu2NORp + Walu2NORn, 0)); else if (n_in == 3) return (SIM_power_draincap(Walu3NORp, PCH, 3) + 3 * SIM_power_draincap(Walu3NORn, NCH, 1) + 3 * SIM_power_gatecap(Walu3NORp + Walu3NORn, 0)); else if (n_in == 4) return (SIM_power_draincap(Walu4NORp, PCH, 4) + 4 * SIM_power_draincap(Walu4NORn, NCH, 1) + 4 * SIM_power_gatecap(Walu4NORp + Walu4NORn, 0)); else return -1; }
static double SIM_crossbar_out_cap(double length, u_int n_in, int connect_type, int trans_type, double *Nsize) { double Ctotal = 0, Ctrans=0.0, psize, nsize; /* part 1: wire cap */ Ctotal = CC3metal * length; /* part 2: output driver */ Ctotal += SIM_power_draincap(Woutdrivern, NCH, 1) + SIM_power_draincap(Woutdriverp, PCH, 1) + SIM_power_gatecap(Woutdrivern + Woutdriverp, 0); /* part 3: drain cap of transmission gate or tri-state gate */ if (connect_type == TRANS_GATE) { /* FIXME: resizing strategy */ if (Nsize) { /* FIXME: how to specify timing? */ psize = SIM_power_driver_size(Ctotal, Period / 3); *Nsize = nsize = psize * Wdecinvn / Wdecinvp; } else { nsize = Wmemcellr; psize = nsize * Wdecinvp / Wdecinvn; } Ctrans = SIM_power_draincap(nsize, NCH, 1); if (trans_type == NP_GATE) Ctrans += SIM_power_draincap(psize, PCH, 1); } else if (connect_type == TRISTATE_GATE) { Ctrans = SIM_power_draincap(Woutdrivern, NCH, 1) + SIM_power_draincap(Woutdriverp, PCH, 1); } else {/* some error handler */} Ctotal += n_in * Ctrans; return Ctotal / 2; }
static double c_NOT(void) { return (SIM_power_draincap(WaluNOTp, PCH, 1) + SIM_power_draincap(WaluNOTn, NCH, 1) + SIM_power_gatecap(WaluNOTp + WaluNOTn, 0)); }
/* switch cap of grant signal (matrix arbiter) */ static double SIM_matrix_arbiter_grant_cap(u_int req_width) { /* drain cap of the "huge" NOR gate */ return (req_width * SIM_power_draincap(WdecNORn, NCH, 1) + SIM_power_draincap(WdecNORp, PCH, req_width)); }
static double c_XOR(void) { /* FIXME: ??? */ return (SIM_power_draincap(WaluXORp, PCH, 2) + SIM_power_draincap(WaluXORn, NCH, 2) + 2 * SIM_power_gatecap(WaluXORp + WaluXORn, 0)); }
static double c_PASS(void) { return (2 * (SIM_power_draincap(WaluPASSp, PCH, 1) + SIM_power_draincap(WaluPASSn, NCH, 1)) + SIM_power_gatecap(WaluPASSp + WaluPASSn, 0)); }