summaryrefslogtreecommitdiff
path: root/src/intersim2/arbiters/tree_arb.cpp
diff options
context:
space:
mode:
authorDongdong Li <[email protected]>2013-08-08 00:15:58 -0800
committerAndrew Boktor <[email protected]>2014-08-14 13:50:58 -0700
commit7f49fe9feb174d34efc2a011bad79b38522a360b (patch)
treeab5b7b66e40315a81871acbf386722981020f866 /src/intersim2/arbiters/tree_arb.cpp
parent5f91e7435742bab74dfbeca18afc63e466498f36 (diff)
Intesim2 Integration
Details: See Review 80001 https://gpgpu-sim-code-review.appspot.com/80001/ [git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 16747]
Diffstat (limited to 'src/intersim2/arbiters/tree_arb.cpp')
-rw-r--r--src/intersim2/arbiters/tree_arb.cpp119
1 files changed, 119 insertions, 0 deletions
diff --git a/src/intersim2/arbiters/tree_arb.cpp b/src/intersim2/arbiters/tree_arb.cpp
new file mode 100644
index 0000000..11033dc
--- /dev/null
+++ b/src/intersim2/arbiters/tree_arb.cpp
@@ -0,0 +1,119 @@
+// $Id: tree_arb.cpp 5188 2012-08-30 00:31:31Z dub $
+
+/*
+ Copyright (c) 2007-2012, Trustees of The Leland Stanford Junior University
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or
+ other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// ----------------------------------------------------------------------
+//
+// TreeArbiter
+//
+// ----------------------------------------------------------------------
+
+#include "tree_arb.hpp"
+#include <iostream>
+#include <sstream>
+
+using namespace std ;
+
+TreeArbiter::TreeArbiter( Module *parent, const string &name,
+ int size, int groups, const string & arb_type )
+ : Arbiter( parent, name, size ) {
+ assert(size % groups == 0);
+ _group_arbiters.resize(groups);
+ _group_reqs.resize(groups, 0);
+ _group_size = size / groups;
+ for(int i = 0; i < groups; ++i) {
+ ostringstream group_arb_name;
+ group_arb_name << "group_arb" << i;
+ _group_arbiters[i] = Arbiter::NewArbiter(this, group_arb_name.str(), arb_type, _group_size);
+ }
+ _global_arbiter = Arbiter::NewArbiter(this, "global_arb", arb_type, groups);
+}
+
+TreeArbiter::~TreeArbiter() {
+ for(int i = 0; i < (int)_group_arbiters.size(); ++i) {
+ delete _group_arbiters[i];
+ }
+ delete _global_arbiter;
+}
+
+void TreeArbiter::PrintState() const {
+ for(int i = 0; i < (int)_group_arbiters.size(); ++i) {
+ cout << "Group arbiter " << i << ":" << endl;
+ _group_arbiters[i]->PrintState();
+ }
+ cout << "Global arbiter:" << endl;
+ _global_arbiter->PrintState();
+}
+
+void TreeArbiter::UpdateState() {
+ if(_selected > -1) {
+ int last_winner = _global_arbiter->LastWinner();
+ assert(last_winner >= 0 && last_winner < (int)_group_arbiters.size());
+ _group_arbiters[last_winner]->UpdateState();
+ _global_arbiter->UpdateState();
+ }
+}
+
+void TreeArbiter::AddRequest( int input, int id, int pri )
+{
+ Arbiter::AddRequest(input, id, pri);
+ int group_index = input / _group_size;
+ _group_arbiters[group_index]->AddRequest( input % _group_size, id, pri );
+ ++_group_reqs[group_index];
+}
+
+int TreeArbiter::Arbitrate( int* id, int* pri ) {
+ if(!_num_reqs) {
+ return -1;
+ }
+ for(int i = 0; i < (int)_group_arbiters.size(); ++i) {
+ if(_group_reqs[i]) {
+ int group_id, group_pri;
+ _group_arbiters[i]->Arbitrate(&group_id, &group_pri);
+ _global_arbiter->AddRequest(i, group_id, group_pri);
+ }
+ }
+ int group = _global_arbiter->Arbitrate(NULL, NULL);
+ assert(group >= 0 && group < (int)_group_arbiters.size());
+ int group_sel = _group_arbiters[group]->LastWinner();
+ assert(group_sel >= 0 && group_sel < _group_size);
+ _selected = group * _group_size + group_sel;
+ assert(_selected >= 0 && _selected < _size);
+ return Arbiter::Arbitrate(id, pri);
+}
+
+void TreeArbiter::Clear()
+{
+ if(!_num_reqs) {
+ return;
+ }
+ for(int i = 0; i < (int)_group_arbiters.size(); ++i) {
+ _group_arbiters[i]->Clear();
+ _group_reqs[i] = 0;
+ }
+ _global_arbiter->Clear();
+ Arbiter::Clear();
+}