int SIM_crossbar_init(SIM_power_crossbar_t *crsbar, int model, u_int n_in, u_int n_out, u_int data_width, u_int degree, int connect_type, int trans_type, double in_len, double out_len, double *req_len) { double in_length, out_length, ctr_length, Nsize, in_wire_cap; if ((crsbar->model = model) && model < CROSSBAR_MAX_MODEL) { crsbar->n_in = n_in; crsbar->n_out = n_out; crsbar->data_width = data_width; crsbar->degree = degree; crsbar->connect_type = connect_type; crsbar->trans_type = trans_type; /* redundant field */ crsbar->mask = HAMM_MASK(data_width); crsbar->n_chg_in = crsbar->n_chg_int = crsbar->n_chg_out = crsbar->n_chg_ctr = 0; switch (model) { case MATRIX_CROSSBAR: /* FIXME: need accurate spacing */ in_length = n_out * data_width * CrsbarCellWidth; out_length = n_in * data_width * CrsbarCellHeight; if (in_length < in_len) in_length = in_len; if (out_length < out_len) out_length = out_len; ctr_length = in_length / 2; if (req_len) *req_len = in_length; in_wire_cap = in_length * CC3metal; crsbar->e_chg_out = SIM_crossbar_out_cap(out_length, n_in, connect_type, trans_type, &Nsize) * EnergyFactor; crsbar->e_chg_in = SIM_crossbar_in_cap(in_wire_cap, n_out, connect_type, trans_type, &Nsize) * EnergyFactor; //crsbar->e_chg_out = SIM_crossbar_out_cap(out_length, n_in, connect_type, trans_type, NULL) * EnergyFactor; //crsbar->e_chg_in = SIM_crossbar_in_cap(in_length, n_out, connect_type, trans_type, NULL) * EnergyFactor; /* FIXME: wire length estimation, really reset? */ /* control signal should reset after transmission is done, so no 1/2 */ crsbar->e_chg_ctr = SIM_crossbar_ctr_cap(ctr_length, data_width, 0, 0, 0, connect_type, trans_type) * EnergyFactor; crsbar->e_chg_int = 0; break; case MULTREE_CROSSBAR: /* input wire horizontal segment length */ in_length = n_in * data_width * CrsbarCellWidth * (n_out / 2); in_wire_cap = in_length * CCmetal; /* input wire vertical segment length */ in_length = n_in * data_width * (5 * Lamda) * (n_out / 2); in_wire_cap += in_length * CC3metal; ctr_length = n_in * data_width * CrsbarCellWidth * (n_out / 2) / 2; crsbar->e_chg_out = SIM_crossbar_out_cap(0, degree, connect_type, trans_type, NULL) * EnergyFactor; crsbar->e_chg_in = SIM_crossbar_in_cap(in_wire_cap, n_out, connect_type, trans_type, NULL) * EnergyFactor; crsbar->e_chg_int = SIM_crossbar_int_cap(degree, connect_type, trans_type) * EnergyFactor; /* redundant field */ crsbar->depth = (u_int)ceil(log(n_in) / log(degree)); /* control signal should reset after transmission is done, so no 1/2 */ if (crsbar->depth == 1) /* only one level of control signal */ crsbar->e_chg_ctr = SIM_crossbar_ctr_cap(ctr_length, data_width, 0, 0, degree, connect_type, trans_type) * EnergyFactor; else { /* first level and last level control signals */ crsbar->e_chg_ctr = SIM_crossbar_ctr_cap(ctr_length, data_width, 0, 1, degree, connect_type, trans_type) * EnergyFactor + SIM_crossbar_ctr_cap(0, data_width, 1, 0, degree, connect_type, trans_type) * EnergyFactor; /* intermediate control signals */ if (crsbar->depth > 2) crsbar->e_chg_ctr += (crsbar->depth - 2) * SIM_crossbar_ctr_cap(0, data_width, 1, 1, degree, connect_type, trans_type) * EnergyFactor; } break; } return 0; } else return -1; }
int SIM_crossbar_init(SIM_power_crossbar_t *crsbar, int model, u_int n_in, u_int n_out, u_int in_seg, u_int out_seg, u_int data_width, u_int degree, int connect_type, int trans_type, double in_len, double out_len, double *req_len) { double in_length, out_length, ctr_length, Nsize, in_wire_cap, I_static; if ((crsbar->model = model) && model < CROSSBAR_MAX_MODEL) { crsbar->n_in = n_in; crsbar->n_out = n_out; crsbar->in_seg = 0; crsbar->out_seg = 0; crsbar->data_width = data_width; crsbar->degree = degree; crsbar->connect_type = connect_type; crsbar->trans_type = trans_type; /* redundant field */ crsbar->mask = HAMM_MASK(data_width); crsbar->n_chg_in = crsbar->n_chg_int = crsbar->n_chg_out = crsbar->n_chg_ctr = 0; switch (model) { case MATRIX_CROSSBAR: crsbar->in_seg = in_seg; crsbar->out_seg = out_seg; /* FIXME: need accurate spacing */ in_length = n_out * data_width * CrsbarCellWidth; out_length = n_in * data_width * CrsbarCellHeight; if (in_length < in_len) in_length = in_len; if (out_length < out_len) out_length = out_len; ctr_length = in_length / 2; if (req_len) *req_len = in_length; in_wire_cap = in_length * CC3metal; crsbar->e_chg_out = SIM_crossbar_out_cap(out_length, n_in, out_seg, connect_type, trans_type, &Nsize) * EnergyFactor; crsbar->e_chg_in = SIM_crossbar_in_cap(in_wire_cap, n_out, in_seg, connect_type, trans_type, &Nsize) * EnergyFactor; /* FIXME: wire length estimation, really reset? */ /* control signal should reset after transmission is done, so no 1/2 */ crsbar->e_chg_ctr = SIM_crossbar_ctr_cap(ctr_length, data_width, 0, 0, 0, connect_type, trans_type) * EnergyFactor; crsbar->e_chg_int = 0; /* static power */ I_static = 0; /* tri-state buffers */ I_static += ((Woutdrvnandp * (NAND2_TAB[0] + NAND2_TAB[1] + NAND2_TAB[2]) + Woutdrvnandn * NAND2_TAB[3]) / 4 + (Woutdrvnorp * NOR2_TAB[0] + Woutdrvnorn * (NOR2_TAB[1] + NOR2_TAB[2] + NOR2_TAB[3])) / 4 + Woutdrivern * NMOS_TAB[0] + Woutdriverp * PMOS_TAB[0]) * n_in * n_out * data_width; /* input driver */ I_static += (Wdecinvn * NMOS_TAB[0] + Wdecinvp * PMOS_TAB[0]) * n_in * data_width; /* output driver */ I_static += (Woutdrivern * NMOS_TAB[0] + Woutdriverp * PMOS_TAB[0]) * n_out * data_width; /* control signal inverter */ I_static += (Wdecinvn * NMOS_TAB[0] + Wdecinvp * PMOS_TAB[0]) * n_in * n_out; crsbar->I_static = I_static / PARM(TECH_POINT) * 100; break; case MULTREE_CROSSBAR: /* input wire horizontal segment length */ in_length = n_in * data_width * CrsbarCellWidth * (n_out / 2); in_wire_cap = in_length * CCmetal; /* input wire vertical segment length */ in_length = n_in * data_width * (5 * Lamda) * (n_out / 2); in_wire_cap += in_length * CC3metal; ctr_length = n_in * data_width * CrsbarCellWidth * (n_out / 2) / 2; crsbar->e_chg_out = SIM_crossbar_out_cap(0, degree, 0, connect_type, trans_type, NULL) * EnergyFactor; crsbar->e_chg_in = SIM_crossbar_in_cap(in_wire_cap, n_out, 0, connect_type, trans_type, NULL) * EnergyFactor; crsbar->e_chg_int = SIM_crossbar_int_cap(degree, connect_type, trans_type) * EnergyFactor; /* redundant field */ crsbar->depth = (u_int)ceil(log(n_in) / log(degree)); /* control signal should reset after transmission is done, so no 1/2 */ if (crsbar->depth == 1) /* only one level of control signal */ crsbar->e_chg_ctr = SIM_crossbar_ctr_cap(ctr_length, data_width, 0, 0, degree, connect_type, trans_type) * EnergyFactor; else { /* first level and last level control signals */ crsbar->e_chg_ctr = SIM_crossbar_ctr_cap(ctr_length, data_width, 0, 1, degree, connect_type, trans_type) * EnergyFactor + SIM_crossbar_ctr_cap(0, data_width, 1, 0, degree, connect_type, trans_type) * EnergyFactor; /* intermediate control signals */ if (crsbar->depth > 2) crsbar->e_chg_ctr += (crsbar->depth - 2) * SIM_crossbar_ctr_cap(0, data_width, 1, 1, degree, connect_type, trans_type) * EnergyFactor; } /* static power */ I_static = 0; /* input driver */ I_static += (Wdecinvn * NMOS_TAB[0] + Wdecinvp * PMOS_TAB[0]) * n_in * data_width; /* output driver */ I_static += (Woutdrivern * NMOS_TAB[0] + Woutdriverp * PMOS_TAB[0]) * n_out * data_width; /* mux */ I_static += (WdecNORp * NOR2_TAB[0] + WdecNORn * (NOR2_TAB[1] + NOR2_TAB[2] + NOR2_TAB[3])) / 4 * (2 * n_in - 1) * n_out * data_width; /* control signal inverter */ I_static += (Wdecinvn * NMOS_TAB[0] + Wdecinvp * PMOS_TAB[0]) * n_in * n_out; crsbar->I_static = I_static / PARM(TECH_POINT) * 100; break; case CUT_THRU_CROSSBAR: /* only support 4x4 now */ in_length = 2 * data_width * MAX(CrsbarCellWidth, CrsbarCellHeight); ctr_length = in_length / 2; crsbar->e_chg_in = SIM_crossbar_io_cap(in_length) * EnergyFactor; crsbar->e_chg_out = 0; /* control signal should reset after transmission is done, so no 1/2 */ crsbar->e_chg_ctr = SIM_crossbar_ctr_cap(ctr_length, data_width, 0, 0, 0, TRISTATE_GATE, 0) * EnergyFactor; crsbar->e_chg_int = 0; break; default: /* some error handler */ break; } return 0; } else return -1; }