inline int SIM_arbiter_record(SIM_power_arbiter_t *arb, LIB_Type_max_uint new_req, LIB_Type_max_uint old_req, u_int new_grant, u_int old_grant) { switch (arb->model) { case MATRIX_ARBITER: arb->n_chg_req += SIM_power_Hamming(new_req, old_req, arb->mask); arb->n_chg_grant += new_grant != old_grant; /* FIXME: approximation */ arb->n_chg_mint += (arb->req_width - 1) * arb->req_width / 2; /* priority registers */ /* FIXME: use average instead */ arb->pri_ff.n_switch += (arb->req_width - 1) / 2; break; case RR_ARBITER: arb->n_chg_req += SIM_power_Hamming(new_req, old_req, arb->mask); arb->n_chg_grant += new_grant != old_grant; /* FIXME: use average instead */ arb->n_chg_carry += arb->req_width / 2; arb->n_chg_carry_in += arb->req_width / 2 - 1; /* priority registers */ arb->pri_ff.n_switch += 2; break; case QUEUE_ARBITER: break; } return 0; }
/* FIXME: MULTREE_CROSSBAR record missing */ inline int SIM_crossbar_record(SIM_power_crossbar_t *xb, int io, LIB_Type_max_uint new_data, LIB_Type_max_uint old_data, u_int new_port, u_int old_port) { switch (xb->model) { case MATRIX_CROSSBAR: if (io) /* input port */ xb->n_chg_in += SIM_power_Hamming(new_data, old_data, xb->mask); else { /* output port */ xb->n_chg_out += SIM_power_Hamming(new_data, old_data, xb->mask); xb->n_chg_ctr += new_port != old_port; } break; case CUT_THRU_CROSSBAR: if (io) /* input port */ xb->n_chg_in += SIM_power_Hamming(new_data, old_data, xb->mask); else { /* output port */ xb->n_chg_ctr += new_port != old_port; } break; case MULTREE_CROSSBAR: break; default: /* some error handler */ break; } return 0; }
/* * this function is provided to upper layers to compute the exact binary bus representation * only correct when grp_width divides data_width */ LIB_Type_max_uint SIM_bus_state(SIM_power_bus_t *bus, LIB_Type_max_uint old_data, LIB_Type_max_uint old_state, LIB_Type_max_uint new_data) { LIB_Type_max_uint mask_bus, mask_data; LIB_Type_max_uint new_state = 0; u_int done_width = 0; switch (bus->encoding) { case IDENT_ENC: return new_data; case TRANS_ENC: return new_data ^ old_data; case BUSINV_ENC: /* FIXME: this function should be re-written for boundary checking */ mask_data = (BIGONE << bus->grp_width) - 1; mask_bus = (mask_data << 1) + 1; while (bus->data_width > done_width) { if (SIM_power_Hamming(old_state & mask_bus, new_data & mask_data, mask_bus) > bus->grp_width / 2) new_state += (~(new_data & mask_data) & mask_bus) << done_width + done_width / bus->grp_width; else new_state += (new_data & mask_data) << done_width + done_width / bus->grp_width; done_width += bus->grp_width; old_state >>= bus->grp_width + 1; new_data >>= bus->grp_width; } return new_state; default:; /* some error handler */ } }
inline int SIM_bus_record(SIM_power_bus_t *bus, LIB_Type_max_uint old_state, LIB_Type_max_uint new_state) { bus->n_switch += SIM_power_Hamming(new_state, old_state, bus->bus_mask); return 0; }