int SIM_arbiter_init(SIM_power_arbiter_t *arb, int arbiter_model, int ff_model, u_int req_width, double length, SIM_power_array_info_t *info) { if ((arb->model = arbiter_model) && arbiter_model < ARBITER_MAX_MODEL) { arb->req_width = req_width; SIM_arbiter_clear_stat(arb); /* redundant field */ arb->mask = HAMM_MASK(req_width); switch (arbiter_model) { case RR_ARBITER: arb->e_chg_req = SIM_rr_arbiter_req_cap(length) / 2 * EnergyFactor; /* two grant signals switch together, so no 1/2 */ arb->e_chg_grant = SIM_rr_arbiter_grant_cap() * EnergyFactor; arb->e_chg_carry = SIM_rr_arbiter_carry_cap() / 2 * EnergyFactor; arb->e_chg_carry_in = SIM_rr_arbiter_carry_in_cap() / 2 * EnergyFactor; arb->e_chg_mint = 0; if (SIM_fpfp_init(&arb->pri_ff, ff_model, SIM_rr_arbiter_pri_cap())) return -1; break; case MATRIX_ARBITER: arb->e_chg_req = SIM_matrix_arbiter_req_cap(req_width, length) / 2 * EnergyFactor; /* 2 grant signals switch together, so no 1/2 */ arb->e_chg_grant = SIM_matrix_arbiter_grant_cap(req_width) * EnergyFactor; arb->e_chg_mint = SIM_matrix_arbiter_int_cap() / 2 * EnergyFactor; arb->e_chg_carry = arb->e_chg_carry_in = 0; if (SIM_fpfp_init(&arb->pri_ff, ff_model, SIM_matrix_arbiter_pri_cap(req_width))) return -1; break; case QUEUE_ARBITER: arb->e_chg_req = arb->e_chg_grant = arb->e_chg_mint = 0; arb->e_chg_carry = arb->e_chg_carry_in = 0; return SIM_array_power_init(info, &arb->queue); break; default: /* some error handler */ break; } return 0; } else return -1; }
/* * n_snd -> # of senders * n_rcv -> # of receivers * time -> rise and fall time, 0 means using default transistor sizes * grp_width only matters for BUSINV_ENC */ int SIM_bus_init(SIM_power_bus_t *bus, int model, int encoding, u_int width, u_int grp_width, u_int n_snd, u_int n_rcv, double length, double time) { if ((bus->model = model) && model < BUS_MAX_MODEL) { bus->data_width = width; bus->grp_width = grp_width; bus->n_switch = 0; switch (model) { case RESULT_BUS: /* assume result bus uses identity encoding */ bus->encoding = IDENT_ENC; bus->e_switch = SIM_resultbus_cap() / 2 * EnergyFactor; break; case GENERIC_BUS: if ((bus->encoding = encoding) && encoding < BUS_MAX_ENC) { bus->e_switch = SIM_generic_bus_cap(n_snd, n_rcv, length, time) / 2 * EnergyFactor; /* sanity check */ if (!grp_width || grp_width > width) bus->grp_width = width; } else return -1; default:; /* some error handler */ } bus->bit_width = SIM_bus_bitwidth(bus->encoding, width, bus->grp_width); bus->bus_mask = HAMM_MASK(bus->bit_width); /* BEGIN: legacy */ // npreg_width = SIM_power_logtwo(PARM(RUU_size)); /* assume ruu_issue_width result busses -- power can be scaled linearly * for number of result busses (scale by writeback_access) */ // bus->static_af = 2 * (PARM(data_width) + npreg_width) * PARM(ruu_issue_width) * PARM(AF); /* END: legacy */ 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 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; }
int SIM_arbiter_init(SIM_arbiter_t *arb, int arbiter_model, int ff_model, u_int req_width, double length, SIM_array_info_t *info) { if ((arb->model = arbiter_model) && arbiter_model < ARBITER_MAX_MODEL) { arb->req_width = req_width; SIM_arbiter_clear_stat(arb); /* redundant field */ arb->mask = HAMM_MASK(req_width); double I_static; switch (arbiter_model) { case RR_ARBITER: arb->e_chg_req = SIM_rr_arbiter_req_cap(length) / 2 * EnergyFactor; /* two grant signals switch together, so no 1/2 */ arb->e_chg_grant = SIM_rr_arbiter_grant_cap() * EnergyFactor; arb->e_chg_carry = SIM_rr_arbiter_carry_cap() / 2 * EnergyFactor; arb->e_chg_carry_in = SIM_rr_arbiter_carry_in_cap() / 2 * EnergyFactor; arb->e_chg_mint = 0; if (SIM_fpfp_init(&arb->pri_ff, ff_model, SIM_rr_arbiter_pri_cap())) return -1; /*arbiter static power */ I_static = 0; /* NOR */ I_static += (6 * arb->req_width * ((WdecNORp*NOR2_TAB[0] + WdecNORn*(NOR2_TAB[1] + NOR2_TAB[2] + NOR2_TAB[3]))/4)); /* inverter */ I_static += 2 * arb->req_width * ((Wdecinvn*NMOS_TAB[0] + Wdecinvp*PMOS_TAB[0])/2); /* DFF */ I_static += (arb->req_width * Wdff*DFF_TAB[0]); arb->I_static = I_static; break; case MATRIX_ARBITER: arb->e_chg_req = SIM_matrix_arbiter_req_cap(req_width, length) / 2 * EnergyFactor; /* 2 grant signals switch together, so no 1/2 */ arb->e_chg_grant = SIM_matrix_arbiter_grant_cap(req_width) * EnergyFactor; arb->e_chg_mint = SIM_matrix_arbiter_int_cap() / 2 * EnergyFactor; arb->e_chg_carry = arb->e_chg_carry_in = 0; if (SIM_fpfp_init(&arb->pri_ff, ff_model, SIM_matrix_arbiter_pri_cap(req_width))) return -1; /*arbiter static power */ I_static = 0; /* NOR */ I_static += ((2 * arb->req_width - 1) * arb->req_width) * ((WdecNORp*NOR2_TAB[0] + WdecNORn*(NOR2_TAB[1] + NOR2_TAB[2] + NOR2_TAB[3]))/4); /* inverter */ I_static += arb->req_width * ((Wdecinvn*NMOS_TAB[0] + Wdecinvp*PMOS_TAB[0])/2); /* DFF */ I_static += (arb->req_width * (arb->req_width - 1) / 2) * (Wdff*DFF_TAB[0]); arb->I_static = I_static; break; case QUEUE_ARBITER: arb->e_chg_req = arb->e_chg_grant = arb->e_chg_mint = 0; arb->e_chg_carry = arb->e_chg_carry_in = 0; return SIM_array_power_init(info, &arb->queue); break; default: printf ("error\n"); /* some error handler */ } return 0; } else return -1; }