clocked_object.cc revision 12089
111524Sdavid.guillen@arm.com/* 211524Sdavid.guillen@arm.com * Copyright (c) 2015-2016 ARM Limited 311524Sdavid.guillen@arm.com * All rights reserved 411524Sdavid.guillen@arm.com * 511524Sdavid.guillen@arm.com * The license below extends only to copyright in the software and shall 611524Sdavid.guillen@arm.com * not be construed as granting a license to any other intellectual 711524Sdavid.guillen@arm.com * property including but not limited to intellectual property relating 811524Sdavid.guillen@arm.com * to a hardware implementation of the functionality of the software 911524Sdavid.guillen@arm.com * licensed hereunder. You may use the software subject to the license 1011524Sdavid.guillen@arm.com * terms below provided that you ensure that this notice is replicated 1111524Sdavid.guillen@arm.com * unmodified and in its entirety in all distributions of the software, 1211524Sdavid.guillen@arm.com * modified or unmodified, in source code or in binary form. 1311524Sdavid.guillen@arm.com * 1411524Sdavid.guillen@arm.com * Redistribution and use in source and binary forms, with or without 1511524Sdavid.guillen@arm.com * modification, are permitted provided that the following conditions are 1611524Sdavid.guillen@arm.com * met: redistributions of source code must retain the above copyright 1711524Sdavid.guillen@arm.com * notice, this list of conditions and the following disclaimer; 1811524Sdavid.guillen@arm.com * redistributions in binary form must reproduce the above copyright 1911524Sdavid.guillen@arm.com * notice, this list of conditions and the following disclaimer in the 2011524Sdavid.guillen@arm.com * documentation and/or other materials provided with the distribution; 2111524Sdavid.guillen@arm.com * neither the name of the copyright holders nor the names of its 2211524Sdavid.guillen@arm.com * contributors may be used to endorse or promote products derived from 2311524Sdavid.guillen@arm.com * this software without specific prior written permission. 2411524Sdavid.guillen@arm.com * 2511524Sdavid.guillen@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2611524Sdavid.guillen@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2711524Sdavid.guillen@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2811524Sdavid.guillen@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2911524Sdavid.guillen@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3011524Sdavid.guillen@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3111524Sdavid.guillen@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3211524Sdavid.guillen@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3311524Sdavid.guillen@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3411524Sdavid.guillen@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3511524Sdavid.guillen@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3611524Sdavid.guillen@arm.com * 3711524Sdavid.guillen@arm.com * Authors: Akash Bagdia 3811524Sdavid.guillen@arm.com * David Guillen Fandos 3911524Sdavid.guillen@arm.com */ 4011524Sdavid.guillen@arm.com 4111524Sdavid.guillen@arm.com#include "sim/clocked_object.hh" 4211524Sdavid.guillen@arm.com 4311524Sdavid.guillen@arm.com#include "base/misc.hh" 4411527Sdavid.guillen@arm.com#include "sim/power/power_model.hh" 4511527Sdavid.guillen@arm.com 4611527Sdavid.guillen@arm.comClockedObject::ClockedObject(const ClockedObjectParams *p) : 4711527Sdavid.guillen@arm.com SimObject(p), Clocked(*p->clk_domain), 4811527Sdavid.guillen@arm.com _currPwrState(p->default_p_state), 4911527Sdavid.guillen@arm.com prvEvalTick(0) 5011527Sdavid.guillen@arm.com{ 5111527Sdavid.guillen@arm.com // Register the power_model with the object 5211527Sdavid.guillen@arm.com if (p->power_model) 5311527Sdavid.guillen@arm.com p->power_model->setClockedObject(this); 5411527Sdavid.guillen@arm.com} 5511524Sdavid.guillen@arm.com 5611524Sdavid.guillen@arm.comvoid 5711524Sdavid.guillen@arm.comClockedObject::serialize(CheckpointOut &cp) const 5811524Sdavid.guillen@arm.com{ 5911524Sdavid.guillen@arm.com unsigned int currPwrState = (unsigned int)_currPwrState; 6011524Sdavid.guillen@arm.com 6111524Sdavid.guillen@arm.com SERIALIZE_SCALAR(currPwrState); 6211524Sdavid.guillen@arm.com SERIALIZE_SCALAR(prvEvalTick); 6311524Sdavid.guillen@arm.com} 6411524Sdavid.guillen@arm.com 6511524Sdavid.guillen@arm.comvoid 6611524Sdavid.guillen@arm.comClockedObject::unserialize(CheckpointIn &cp) 6711524Sdavid.guillen@arm.com{ 6811524Sdavid.guillen@arm.com unsigned int currPwrState; 6911524Sdavid.guillen@arm.com 7011524Sdavid.guillen@arm.com UNSERIALIZE_SCALAR(currPwrState); 7111524Sdavid.guillen@arm.com UNSERIALIZE_SCALAR(prvEvalTick); 7211524Sdavid.guillen@arm.com 7311524Sdavid.guillen@arm.com _currPwrState = Enums::PwrState(currPwrState); 7411524Sdavid.guillen@arm.com} 7511524Sdavid.guillen@arm.com 7611524Sdavid.guillen@arm.comvoid 7711524Sdavid.guillen@arm.comClockedObject::pwrState(Enums::PwrState p) 7811524Sdavid.guillen@arm.com{ 7911524Sdavid.guillen@arm.com // Function should ideally be called only when there is a state change 8011524Sdavid.guillen@arm.com if (_currPwrState == p) { 8111529Sandreas.sandberg@arm.com warn_once("ClockedObject: Already in the requested power state, " \ 8211529Sandreas.sandberg@arm.com "request ignored"); 8311524Sdavid.guillen@arm.com return; 8411524Sdavid.guillen@arm.com } 8511524Sdavid.guillen@arm.com 8611524Sdavid.guillen@arm.com // No need to compute stats if in the same tick, update state though. This 8711524Sdavid.guillen@arm.com // can happen in cases like a) during start of the simulation multiple 8811524Sdavid.guillen@arm.com // state changes happens in init/startup phase, b) one takes a decision to 8911524Sdavid.guillen@arm.com // migrate state but decides to reverts back to the original state in the 9011524Sdavid.guillen@arm.com // same tick if other conditions are not met elsewhere. 9111524Sdavid.guillen@arm.com // Any state change related stats would have been recorded on previous call 9211524Sdavid.guillen@arm.com // to the pwrState() function. 9312089Sjason@lowepower.com if (prvEvalTick == curTick() && curTick() != 0) { 9411524Sdavid.guillen@arm.com warn("ClockedObject: More than one power state change request "\ 9511524Sdavid.guillen@arm.com "encountered within the same simulation tick"); 9611524Sdavid.guillen@arm.com _currPwrState = p; 9711524Sdavid.guillen@arm.com return; 9811524Sdavid.guillen@arm.com } 9911524Sdavid.guillen@arm.com 10011524Sdavid.guillen@arm.com // Record stats for previous state. 10111524Sdavid.guillen@arm.com computeStats(); 10211524Sdavid.guillen@arm.com 10311524Sdavid.guillen@arm.com _currPwrState = p; 10411524Sdavid.guillen@arm.com 10511524Sdavid.guillen@arm.com numPwrStateTransitions++; 10611524Sdavid.guillen@arm.com} 10711524Sdavid.guillen@arm.com 10811524Sdavid.guillen@arm.comvoid 10911524Sdavid.guillen@arm.comClockedObject::computeStats() 11011524Sdavid.guillen@arm.com{ 11111524Sdavid.guillen@arm.com // Calculate time elapsed from last (valid) state change 11211524Sdavid.guillen@arm.com Tick elapsed_time = curTick() - prvEvalTick; 11311524Sdavid.guillen@arm.com 11411524Sdavid.guillen@arm.com pwrStateResidencyTicks[_currPwrState] += elapsed_time; 11511524Sdavid.guillen@arm.com 11611524Sdavid.guillen@arm.com // Time spent in CLK_GATED state, this might change depending on 11711524Sdavid.guillen@arm.com // transition to other low power states in respective simulation 11811524Sdavid.guillen@arm.com // objects. 11911524Sdavid.guillen@arm.com if (_currPwrState == Enums::PwrState::CLK_GATED) { 12011524Sdavid.guillen@arm.com pwrStateClkGateDist.sample(elapsed_time); 12111524Sdavid.guillen@arm.com } 12211524Sdavid.guillen@arm.com 12311524Sdavid.guillen@arm.com prvEvalTick = curTick(); 12411524Sdavid.guillen@arm.com} 12511524Sdavid.guillen@arm.com 12611524Sdavid.guillen@arm.comstd::vector<double> 12711524Sdavid.guillen@arm.comClockedObject::pwrStateWeights() const 12811524Sdavid.guillen@arm.com{ 12911524Sdavid.guillen@arm.com // Get residency stats 13011524Sdavid.guillen@arm.com std::vector<double> ret; 13111524Sdavid.guillen@arm.com Stats::VCounter residencies; 13211524Sdavid.guillen@arm.com pwrStateResidencyTicks.value(residencies); 13311524Sdavid.guillen@arm.com 13411524Sdavid.guillen@arm.com // Account for current state too! 13511524Sdavid.guillen@arm.com Tick elapsed_time = curTick() - prvEvalTick; 13611524Sdavid.guillen@arm.com residencies[_currPwrState] += elapsed_time; 13711524Sdavid.guillen@arm.com 13811524Sdavid.guillen@arm.com ret.resize(Enums::PwrState::Num_PwrState); 13911524Sdavid.guillen@arm.com for (unsigned i = 0; i < Enums::PwrState::Num_PwrState; i++) 14011524Sdavid.guillen@arm.com ret[i] = residencies[i] / \ 14111524Sdavid.guillen@arm.com (pwrStateResidencyTicks.total() + elapsed_time); 14211524Sdavid.guillen@arm.com 14311524Sdavid.guillen@arm.com return ret; 14411524Sdavid.guillen@arm.com} 14511524Sdavid.guillen@arm.com 14611524Sdavid.guillen@arm.comvoid 14711524Sdavid.guillen@arm.comClockedObject::regStats() 14811524Sdavid.guillen@arm.com{ 14911524Sdavid.guillen@arm.com SimObject::regStats(); 15011524Sdavid.guillen@arm.com 15111524Sdavid.guillen@arm.com using namespace Stats; 15211524Sdavid.guillen@arm.com 15311524Sdavid.guillen@arm.com numPwrStateTransitions 15411524Sdavid.guillen@arm.com .name(params()->name + ".numPwrStateTransitions") 15511524Sdavid.guillen@arm.com .desc("Number of power state transitions") 15611525Sandreas.sandberg@arm.com .flags(nozero) 15711524Sdavid.guillen@arm.com ; 15811524Sdavid.guillen@arm.com 15911524Sdavid.guillen@arm.com // Each sample is time in ticks 16011524Sdavid.guillen@arm.com unsigned num_bins = std::max(params()->p_state_clk_gate_bins, 10U); 16111524Sdavid.guillen@arm.com pwrStateClkGateDist 16211524Sdavid.guillen@arm.com .init(params()->p_state_clk_gate_min, params()->p_state_clk_gate_max, 16311524Sdavid.guillen@arm.com (params()->p_state_clk_gate_max / num_bins)) 16411524Sdavid.guillen@arm.com .name(params()->name + ".pwrStateClkGateDist") 16511524Sdavid.guillen@arm.com .desc("Distribution of time spent in the clock gated state") 16611525Sandreas.sandberg@arm.com .flags(pdf | nozero | nonan) 16711524Sdavid.guillen@arm.com ; 16811524Sdavid.guillen@arm.com 16911524Sdavid.guillen@arm.com pwrStateResidencyTicks 17011524Sdavid.guillen@arm.com .init(Enums::PwrState::Num_PwrState) 17111524Sdavid.guillen@arm.com .name(params()->name + ".pwrStateResidencyTicks") 17211524Sdavid.guillen@arm.com .desc("Cumulative time (in ticks) in various power states") 17311525Sandreas.sandberg@arm.com .flags(nozero) 17411524Sdavid.guillen@arm.com ; 17511524Sdavid.guillen@arm.com for (int i = 0; i < Enums::PwrState::Num_PwrState; i++) { 17611524Sdavid.guillen@arm.com pwrStateResidencyTicks.subname(i, Enums::PwrStateStrings[i]); 17711524Sdavid.guillen@arm.com } 17811524Sdavid.guillen@arm.com 17911524Sdavid.guillen@arm.com numPwrStateTransitions = 0; 18011524Sdavid.guillen@arm.com 18111524Sdavid.guillen@arm.com /** 18211524Sdavid.guillen@arm.com * For every stats dump, the power state residency and other distribution 18311524Sdavid.guillen@arm.com * stats should be computed just before the dump to ensure correct stats 18411524Sdavid.guillen@arm.com * value being reported for current dump window. It avoids things like 18511524Sdavid.guillen@arm.com * having any unreported time spent in a power state to be forwarded to the 18611524Sdavid.guillen@arm.com * next dump window which might have rather unpleasant effects (like 18711524Sdavid.guillen@arm.com * perturbing the distribution stats). 18811524Sdavid.guillen@arm.com */ 18911524Sdavid.guillen@arm.com registerDumpCallback(new ClockedObjectDumpCallback(this)); 19011524Sdavid.guillen@arm.com} 191