diff options
Diffstat (limited to 'ext/dsent/model/electrical/MatrixArbiter.cc')
-rw-r--r-- | ext/dsent/model/electrical/MatrixArbiter.cc | 434 |
1 files changed, 434 insertions, 0 deletions
diff --git a/ext/dsent/model/electrical/MatrixArbiter.cc b/ext/dsent/model/electrical/MatrixArbiter.cc new file mode 100644 index 000000000..7f72abd63 --- /dev/null +++ b/ext/dsent/model/electrical/MatrixArbiter.cc @@ -0,0 +1,434 @@ +#include "model/electrical/MatrixArbiter.h" + +#include <cmath> +#include <vector> + +#include "model/PortInfo.h" +#include "model/EventInfo.h" +#include "model/TransitionInfo.h" +#include "model/ModelGen.h" +#include "model/std_cells/StdCell.h" +#include "model/std_cells/StdCellLib.h" + +namespace DSENT +{ + using std::abs; + using std::vector; + + MatrixArbiter::MatrixArbiter(const String& instance_name_, const TechModel* tech_model_) + : ElectricalModel(instance_name_, tech_model_) + { + initParameters(); + initProperties(); + } + + MatrixArbiter::~MatrixArbiter() + {} + + void MatrixArbiter::initParameters() + { + addParameterName("NumberRequests"); + return; + } + + void MatrixArbiter::initProperties() + { + return; + } + + MatrixArbiter* MatrixArbiter::clone() const + { + // TODO + return NULL; + } + + void MatrixArbiter::constructModel() + { + // Get parameters + unsigned int number_requests = getParameter("NumberRequests").toUInt(); + + ASSERT(number_requests > 0, "[Error] " + getInstanceName() + + " -> Number of requests must be > 0!"); + + // Connect ports + createInputPort("CK"); + for(unsigned int i = 0; i < number_requests; ++i) + { + createInputPort("Request" + (String)i); + createOutputPort("Grant" + (String)i); + } + + // Create area, power, event results + createElectricalResults(); + getEventInfo("Idle")->setStaticTransitionInfos(); + getEventInfo("Idle")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); +// for(unsigned int i = 0; i <= number_requests; ++i) +// { +// // Create arbitrate event with i requests +// createElectricalEventResult("Arbitrate" + (String)i); +// EventInfo* event_info = getEventInfo("Arbitrate" + (String)i); +// event_info->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); +// +// for(unsigned int j = 0; j < i; ++j) +// { +// event_info->setTransitionInfo("Request" + (String)j, TransitionInfo(0.0, 0.0, 1.0)); +// } +// for(unsigned int j = i; j < number_requests; ++j) +// { +// event_info->setTransitionInfo("Request" + (String)j, TransitionInfo(1.0, 0.0, 0.0)); +// +// } +// //double P_0 = (double)(number_requests - i) / (double)(number_requests); +// //double P_1 = (double)(i) / (double)(number_requests); +// //TransitionInfo trans(P_0 * P_0, P_0 * P_1, P_1 * P_1); +// +// //for(unsigned int j = 0; j < number_requests; ++j) +// //{ +// // event_info->setTransitionInfo("Request" + (String)j, trans); +// //} +// } + createElectricalEventResult("Arbitrate"); + getEventInfo("Arbitrate")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); + for(unsigned int i = 0; i < number_requests; ++i) + { + getEventInfo("Arbitrate")->setTransitionInfo("Request" + (String)i, TransitionInfo(0.25, 0.25, 0.25)); + } + + if(number_requests == 1) + { + assign("Grant0", "Request0"); + } + else + { + // Init components + vector<String> g_inv_names(number_requests, ""); + vector<StdCell*> g_invs(number_requests, NULL); + vector<String> g_and2_names(number_requests, ""); + vector<StdCell*> g_and2s(number_requests, NULL); + for(unsigned int i = 0; i < number_requests; ++i) + { + g_inv_names[i] = "G_INV" + (String)i; + g_and2_names[i] = "G_AND2" + (String)i; + g_invs[i] = getTechModel()->getStdCellLib()->createStdCell("INV", g_inv_names[i]); + g_invs[i]->construct(); + g_and2s[i] = getTechModel()->getStdCellLib()->createStdCell("AND2", g_and2_names[i]); + g_and2s[i]->construct(); + } + + unsigned int number_states = (number_requests - 1) * number_requests / 2; + + vector<String> w_or2_names(number_states, ""); + vector<StdCell*> w_or2s(number_states, NULL); + vector<String> w_and2_names(number_states, ""); + vector<StdCell*> w_and2s(number_states, NULL); + vector<String> w_inv_names(number_states, ""); + vector<StdCell*> w_invs(number_states, NULL); + vector<String> w_dff_names(number_states, ""); + vector<StdCell*> w_dffs(number_states, NULL); + vector<String> dis_and2_names(number_states * 2, ""); + vector<StdCell*> dis_and2s(number_states * 2, NULL); + vector<String> dis_inv_names(number_states, ""); + vector<StdCell*> dis_invs(number_states, NULL); + unsigned int state_count = 0; + for(unsigned int i = 0; i < number_requests; ++i) + { + for(unsigned int j = i + 1; j < number_requests; ++j) + { + w_or2_names[state_count] = String::format("W_OR2_%d_%d", i, j); + w_and2_names[state_count] = String::format("W_AND2_%d_%d", i, j); + w_inv_names[state_count] = String::format("W_INV_%d_%d", i, j); + w_dff_names[state_count] = String::format("W_DFF_%d_%d", i, j); + w_or2s[state_count] = getTechModel()->getStdCellLib()->createStdCell("OR2", w_or2_names[state_count]); + w_or2s[state_count]->construct(); + w_and2s[state_count] = getTechModel()->getStdCellLib()->createStdCell("AND2", w_and2_names[state_count]); + w_and2s[state_count]->construct(); + w_invs[state_count] = getTechModel()->getStdCellLib()->createStdCell("INV", w_inv_names[state_count]); + w_invs[state_count]->construct(); + w_dffs[state_count] = getTechModel()->getStdCellLib()->createStdCell("DFFQ", w_dff_names[state_count]); + w_dffs[state_count]->construct(); + + dis_inv_names[state_count] = String::format("Dis_INV_%d_%d", i, j); + dis_and2_names[state_count] = String::format("Dis_AND2_%d_%d", i, j); + dis_and2_names[state_count + number_states] = String::format("Dis_AND2_%d_%d", j, i); + dis_invs[state_count] = getTechModel()->getStdCellLib()->createStdCell("INV", dis_inv_names[state_count]); + dis_invs[state_count]->construct(); + dis_and2s[state_count] = getTechModel()->getStdCellLib()->createStdCell("AND2", dis_and2_names[state_count]); + dis_and2s[state_count]->construct(); + dis_and2s[state_count + number_states] = getTechModel()->getStdCellLib()->createStdCell("AND2", dis_and2_names[state_count + number_states]); + dis_and2s[state_count + number_states]->construct(); + state_count++; + } + } + + vector<String> dis_or_names(number_requests, ""); + vector<ElectricalModel*> dis_ors(number_requests, NULL); + for(unsigned int i = 0; i < number_requests; ++i) + { + dis_or_names[i] = "Dis_OR" + (String)i; + dis_ors[i] = (ElectricalModel*)ModelGen::createModel("OR", dis_or_names[i], getTechModel()); + dis_ors[i]->setParameter("NumberInputs", number_requests-1); + dis_ors[i]->setParameter("NumberBits", 1); + dis_ors[i]->construct(); + } + + state_count = 0; + for(unsigned int i = 0; i < number_requests; ++i) + { + createNet("Dis_OR_Out" + (String)i); + createNet("G_INV_Out" + (String)i); + portConnect(g_invs[i], "A", "Dis_OR_Out" + (String)i); + portConnect(g_invs[i], "Y", "G_INV_Out" + (String)i); + portConnect(g_and2s[i], "A", "Request" + (String)i); + portConnect(g_and2s[i], "B", "G_INV_Out" + (String)i); + portConnect(g_and2s[i], "Y", "Grant" + (String)i); + + for(unsigned int j = i + 1; j < number_requests; ++j) + { + createNet(String::format("W_INV_Out_%d_%d", i, j)); + createNet(String::format("W_OR2_Out_%d_%d", i, j)); + createNet(String::format("W_AND2_Out_%d_%d", i, j)); + createNet(String::format("W_DFF_Out_%d_%d", i, j)); + portConnect(w_invs[state_count], "A", "Grant" + (String)i); + portConnect(w_invs[state_count], "Y", String::format("W_INV_Out_%d_%d", i, j)); + portConnect(w_or2s[state_count], "A", String::format("W_DFF_Out_%d_%d", i, j)); + portConnect(w_or2s[state_count], "B", "Grant" + (String)j); + portConnect(w_or2s[state_count], "Y", String::format("W_OR2_Out_%d_%d", i, j)); + portConnect(w_and2s[state_count], "A", String::format("W_OR2_Out_%d_%d", i, j)); + portConnect(w_and2s[state_count], "B", String::format("W_INV_Out_%d_%d", i, j)); + portConnect(w_and2s[state_count], "Y", String::format("W_AND2_Out_%d_%d", i, j)); + portConnect(w_dffs[state_count], "D", String::format("W_AND2_Out_%d_%d", i, j)); + portConnect(w_dffs[state_count], "CK", "CK"); + portConnect(w_dffs[state_count], "Q", String::format("W_DFF_Out_%d_%d", i, j)); + + createNet(String::format("Dis_AND2_Out_%d_%d", i, j)); + createNet(String::format("Dis_AND2_Out_%d_%d", j, i)); + createNet(String::format("Dis_INV_Out_%d_%d", j, i)); + portConnect(dis_and2s[state_count], "A", "Request" + (String)i); + portConnect(dis_and2s[state_count], "B", String::format("W_DFF_Out_%d_%d", i, j)); + portConnect(dis_and2s[state_count], "Y", String::format("Dis_AND2_Out_%d_%d", i, j)); + + portConnect(dis_invs[state_count], "A", String::format("W_DFF_Out_%d_%d", i, j)); + portConnect(dis_invs[state_count], "Y", String::format("Dis_INV_Out_%d_%d", j, i)); + portConnect(dis_and2s[state_count + number_states], "A", "Request" + (String)j); + portConnect(dis_and2s[state_count + number_states], "B", String::format("Dis_INV_Out_%d_%d", j, i)); + portConnect(dis_and2s[state_count + number_states], "Y", String::format("Dis_AND2_Out_%d_%d", j, i)); + + state_count++; + } + } + for(unsigned int i = 0; i < number_requests; ++i) + { + unsigned int k = 0; + for(unsigned int j = 0; j < number_requests; ++j) + { + if(i != j) + { + portConnect(dis_ors[i], "In" + (String)k, String::format("Dis_AND2_Out_%d_%d", j, i)); + k++; + } + } + portConnect(dis_ors[i], "Out", "Dis_OR_Out" + (String)i); + } + + // Add instances + for(unsigned int i = 0; i < number_requests; ++i) + { + addSubInstances(g_invs[i], 1.0); + addElectricalSubResults(g_invs[i], 1.0); + addSubInstances(g_and2s[i], 1.0); + addElectricalSubResults(g_and2s[i], 1.0); + addSubInstances(dis_ors[i], 1.0); + addElectricalSubResults(dis_ors[i], 1.0); + } + for(unsigned int i = 0; i < number_states; ++i) + { + addSubInstances(w_or2s[i], 1.0); + addElectricalSubResults(w_or2s[i], 1.0); + addSubInstances(w_and2s[i], 1.0); + addElectricalSubResults(w_and2s[i], 1.0); + addSubInstances(w_invs[i], 1.0); + addElectricalSubResults(w_invs[i], 1.0); + addSubInstances(w_dffs[i], 1.0); + addElectricalSubResults(w_dffs[i], 1.0); + addSubInstances(dis_and2s[i], 1.0); + addElectricalSubResults(dis_and2s[i], 1.0); + addSubInstances(dis_and2s[i + number_states], 1.0); + addElectricalSubResults(dis_and2s[i + number_states], 1.0); + addSubInstances(dis_invs[i], 1.0); + addElectricalSubResults(dis_invs[i], 1.0); + } + + // Update event + //for(unsigned int i = 0; i <= number_requests; ++i) + //{ + //Result* arb_event = getEventResult("Arbitrate" + (String)i); + Result* arb_event = getEventResult("Arbitrate"); + for(unsigned int j = 0; j < number_requests; ++j) + { + arb_event->addSubResult(g_invs[j]->getEventResult("INV"), g_inv_names[j], 1.0); + arb_event->addSubResult(g_and2s[j]->getEventResult("AND2"), g_and2_names[j], 1.0); + arb_event->addSubResult(dis_ors[j]->getEventResult("OR"), dis_or_names[j], 1.0); + } + for(unsigned int j = 0; j < number_states; ++j) + { + arb_event->addSubResult(w_or2s[j]->getEventResult("OR2"), w_or2_names[j], 1.0); + arb_event->addSubResult(w_and2s[j]->getEventResult("AND2"), w_and2_names[j], 1.0); + arb_event->addSubResult(w_invs[j]->getEventResult("INV"), w_inv_names[j], 1.0); + arb_event->addSubResult(w_dffs[j]->getEventResult("DFFD"), w_dff_names[j], 1.0); + arb_event->addSubResult(w_dffs[j]->getEventResult("DFFQ"), w_dff_names[j], 1.0); + arb_event->addSubResult(w_dffs[j]->getEventResult("CK"), w_dff_names[j], 1.0); + arb_event->addSubResult(dis_and2s[j]->getEventResult("AND2"), dis_and2_names[j], 1.0); + arb_event->addSubResult(dis_and2s[j + number_states]->getEventResult("AND2"), dis_and2_names[j + number_states], 1.0); + arb_event->addSubResult(dis_invs[j]->getEventResult("INV"), dis_inv_names[j], 1.0); + } + //} + } + return; + } + + void MatrixArbiter::propagateTransitionInfo() + { + // Get parameters + unsigned int number_requests = getParameter("NumberRequests").toUInt(); + + if(number_requests == 1) + { + propagatePortTransitionInfo("Grant0", "Request0"); + } + else + { + unsigned int number_states = (number_requests - 1) * number_requests / 2; + + vector<ElectricalModel*> g_and2s(number_requests, NULL); + vector<ElectricalModel*> g_invs(number_requests, NULL); + vector<ElectricalModel*> w_invs(number_states, NULL); + vector<ElectricalModel*> w_or2s(number_states, NULL); + vector<ElectricalModel*> w_and2s(number_states, NULL); + vector<ElectricalModel*> w_dffs(number_states, NULL); + vector<ElectricalModel*> dis_invs(number_states, NULL); + vector<ElectricalModel*> dis_and2s(number_requests * number_requests, NULL); + vector<ElectricalModel*> dis_ors(number_requests, NULL); + for(unsigned int i = 0; i < number_requests; ++i) + { + g_and2s[i] = (ElectricalModel*)getSubInstance("G_AND2" + (String)i); + g_invs[i] = (ElectricalModel*)getSubInstance("G_INV" + (String)i); + dis_ors[i] = (ElectricalModel*)getSubInstance("Dis_OR" + (String)i); + } + unsigned int state_count = 0; + for(unsigned int i = 0; i < number_requests; ++i) + { + for(unsigned int j = i + 1; j < number_requests; ++j) + { + w_invs[state_count] = (ElectricalModel*)getSubInstance(String::format("W_INV_%d_%d", i, j)); + w_or2s[state_count] = (ElectricalModel*)getSubInstance(String::format("W_OR2_%d_%d", i, j)); + w_and2s[state_count] = (ElectricalModel*)getSubInstance(String::format("W_AND2_%d_%d", i, j)); + w_dffs[state_count] = (ElectricalModel*)getSubInstance(String::format("W_DFF_%d_%d", i, j)); + dis_invs[state_count] = (ElectricalModel*)getSubInstance(String::format("Dis_INV_%d_%d", i, j)); + dis_and2s[i * number_requests + j] = (ElectricalModel*)getSubInstance(String::format("Dis_AND2_%d_%d", i, j)); + dis_and2s[j * number_requests + i] = (ElectricalModel*)getSubInstance(String::format("Dis_AND2_%d_%d", j, i)); + + w_dffs[state_count]->getInputPort("D")->setTransitionInfo(TransitionInfo(0.5, 0.0, 0.5)); + propagatePortTransitionInfo(w_dffs[state_count], "CK", "CK"); + w_dffs[state_count]->use(); + + state_count++; + } + } + + unsigned int iteration = 1; + unsigned int max_number_iterations = 10; + //vector<TransitionInfo> trans_vector(number_states, TransitionInfo(0.0, 0.0, 1.0)); + //vector<double> total_P_vector(number_states, 0.0); + while(iteration < max_number_iterations) + { +// for(unsigned int i = 0; i < number_states; ++i) +// { +// w_dffs[i]->getInputPort("D")->setTransitionInfo(trans_vector[i]); +// propagatePortTransitionInfo(w_dffs[i], "CK", "CK"); +// w_dffs[i]->use(); +// } + state_count = 0; + for(unsigned int i = 0; i < number_requests; ++i) + { + for(unsigned int j = i + 1; j < number_requests; ++j) + { + propagatePortTransitionInfo(dis_and2s[i * number_requests + j], "A", "Request" + (String)i); + propagatePortTransitionInfo(dis_and2s[i * number_requests + j], "B", w_dffs[state_count], "Q"); + dis_and2s[i * number_requests + j]->use(); + propagatePortTransitionInfo(dis_invs[state_count], "A", w_dffs[state_count], "Q"); + dis_invs[state_count]->use(); + propagatePortTransitionInfo(dis_and2s[j * number_requests + i], "A", "Request" + (String)j); + propagatePortTransitionInfo(dis_and2s[j * number_requests + i], "B", dis_invs[state_count], "Y"); + dis_and2s[j * number_requests + i]->use(); + + state_count++; + } + } + for(unsigned int i = 0; i < number_requests; ++i) + { + unsigned int k = 0; + for(unsigned int j = 0; j < number_requests; ++j) + { + if(i != j) + { + propagatePortTransitionInfo(dis_ors[i], "In" + (String)k, dis_and2s[j * number_requests + i], "Y"); + k++; + } + } + dis_ors[i]->use(); + } + for(unsigned int i = 0; i < number_requests; ++i) + { + propagatePortTransitionInfo(g_invs[i], "A", dis_ors[i], "Out"); + g_invs[i]->use(); + propagatePortTransitionInfo(g_and2s[i], "A", "Request" + (String)i); + propagatePortTransitionInfo(g_and2s[i], "B", g_invs[i], "Y"); + g_and2s[i]->use(); + } + state_count = 0; + for(unsigned int i = 0; i < number_requests; ++i) + { + for(unsigned int j = i + 1; j < number_requests; ++j) + { + propagatePortTransitionInfo(w_invs[state_count], "A", g_and2s[i], "Y"); + w_invs[state_count]->use(); + propagatePortTransitionInfo(w_or2s[state_count], "A", w_dffs[state_count], "Q"); + propagatePortTransitionInfo(w_or2s[state_count], "B", g_and2s[j], "Y"); + w_or2s[state_count]->use(); + propagatePortTransitionInfo(w_and2s[state_count], "A", w_or2s[state_count], "Y"); + propagatePortTransitionInfo(w_and2s[state_count], "B", w_invs[state_count], "Y"); + w_and2s[state_count]->use(); + propagatePortTransitionInfo(w_dffs[state_count], "D", w_and2s[state_count], "Y"); + propagatePortTransitionInfo(w_dffs[state_count], "CK", "CK"); + w_dffs[state_count]->use(); + state_count++; + } + } + +// for(unsigned int i = 0; i < number_states; ++i) +// { +// const TransitionInfo& new_trans = w_dffs[i]->getOutputPort("Q")->getTransitionInfo(); +// total_P_vector[i] += new_trans.getProbability1(); +// trans_vector[i] = TransitionInfo((1.0 - total_P_vector[i] / iteration) * (1.0 - total_P_vector[i] / iteration), +// (1.0 - total_P_vector[i] / iteration) * (total_P_vector[i] / iteration), +// (total_P_vector[i] / iteration) * (total_P_vector[i] / iteration)); +// } +// +// for(unsigned int i = 0; i < number_requests; ++i) +// { +// g_and2s[i]->getOutputPort("Y")->getTransitionInfo().print(cout); +// } +// cout << endl; + iteration++; + } + + for(unsigned int i = 0; i < number_requests; ++i) + { + propagatePortTransitionInfo("Grant" + (String)i, g_and2s[i], "Y"); + } + } + + return; + } +} // namespace DSENT + |