/* * Copyright (c) 2001-2005 The Regents of The University of Michigan * 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; * neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * 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. * * Authors: Steve Raasch * Steve Reinhardt */ #ifndef __SAT_COUNTER_HH__ #define __SAT_COUNTER_HH__ #include #include "base/predictor.hh" #include "base/statistics.hh" #include "sim/stats.hh" // // // A simple saturating counter predictor // // class SaturatingCounterPred : public GenericPredictor { private: std::string pred_name; std::string zero_name; std::string one_name; unsigned index_bits; unsigned counter_bits; unsigned zero_change; unsigned one_change; unsigned thresh; unsigned init_value; unsigned max_value; // maximum counter value unsigned long max_index; // also the index mask value unsigned *table; // Statistics Stats::Scalar<> predicted_one; // Total predictions of one, preds_one Stats::Scalar<> predicted_zero; // Total predictions of zero, preds_zero Stats::Scalar<> correct_pred_one; // Total correct predictions of one, correct_one Stats::Scalar<> correct_pred_zero; // Total correct predictions of zero, correct_zero Stats::Scalar<> record_zero; //updates_zero Stats::Scalar<> record_one; //updates_one Stats::Formula preds_total; Stats::Formula pred_frac_zero; Stats::Formula pred_frac_one; Stats::Formula correct_total; Stats::Formula updates_total; Stats::Formula pred_rate; Stats::Formula frac_correct_zero; Stats::Formula frac_correct_one; Stats::Formula coverage_zero; Stats::Formula coverage_one; private: bool pred_one(unsigned &counter) { return counter > thresh; } bool pred_zero(unsigned &counter) { return counter <= thresh; } void update_one(unsigned &counter) { if (one_change) counter += one_change; else counter = 0; // check for wrap if (counter > max_value) counter = max_value; } void update_zero(unsigned &counter) { if (zero_change) { // check for wrap if (counter < zero_change) counter = 0; else counter -= zero_change; } else counter = 0; } public: SaturatingCounterPred(std::string p_name, std::string z_name, std::string o_name, unsigned _index_bits, unsigned _counter_bits = 2, unsigned _zero_change = 1, unsigned _one_change = 1, unsigned _thresh = 1, unsigned _init_value = 0); void clear() { for (int i = 0; i <= max_index; ++i) table[i] = init_value; } // Record the ACTUAL result... and indicate whether the prediction // corresponding to this event was correct void record(unsigned long _index, unsigned _val, unsigned _predicted, unsigned _pdata) { record(_index, _val, _predicted); } void record(unsigned long _index, unsigned _val, unsigned _predicted) { unsigned long index = _index & max_index; if (_val) { update_one(table[index]); ++record_one; if (_predicted) ++correct_pred_one; } else { update_zero(table[index]); ++record_zero; if (!_predicted) ++correct_pred_zero; } } unsigned value(unsigned long _index) { unsigned long index = _index & max_index; return table[index]; } unsigned predict(unsigned long _index, unsigned &pdata) { return predict(_index); } unsigned predict(unsigned long _index) { unsigned long index = _index & max_index; if (pred_one(table[index])) { ++predicted_one; return 1; } ++predicted_zero; return 0; } // No internal state is changed here unsigned peek(unsigned long _index) { unsigned long index = _index & max_index; if (pred_one(table[index])) return 1; return 0; } //======================================================= void regStats(); void regFormulas(); }; #endif // __SAT_COUNTER_HH__