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; }
/* 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_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; }
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; }