rob_impl.hh revision 10231:cb2e6950956d
16657Snate@binkert.org/* 26657Snate@binkert.org * Copyright (c) 2012 ARM Limited 36657Snate@binkert.org * All rights reserved 46657Snate@binkert.org * 56657Snate@binkert.org * The license below extends only to copyright in the software and shall 66657Snate@binkert.org * not be construed as granting a license to any other intellectual 76657Snate@binkert.org * property including but not limited to intellectual property relating 86657Snate@binkert.org * to a hardware implementation of the functionality of the software 96657Snate@binkert.org * licensed hereunder. You may use the software subject to the license 106657Snate@binkert.org * terms below provided that you ensure that this notice is replicated 116657Snate@binkert.org * unmodified and in its entirety in all distributions of the software, 126657Snate@binkert.org * modified or unmodified, in source code or in binary form. 136657Snate@binkert.org * 146657Snate@binkert.org * Copyright (c) 2004-2006 The Regents of The University of Michigan 156657Snate@binkert.org * All rights reserved. 166657Snate@binkert.org * 176657Snate@binkert.org * Redistribution and use in source and binary forms, with or without 186657Snate@binkert.org * modification, are permitted provided that the following conditions are 196657Snate@binkert.org * met: redistributions of source code must retain the above copyright 206657Snate@binkert.org * notice, this list of conditions and the following disclaimer; 216657Snate@binkert.org * redistributions in binary form must reproduce the above copyright 226657Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 236657Snate@binkert.org * documentation and/or other materials provided with the distribution; 246657Snate@binkert.org * neither the name of the copyright holders nor the names of its 256657Snate@binkert.org * contributors may be used to endorse or promote products derived from 266657Snate@binkert.org * this software without specific prior written permission. 276657Snate@binkert.org * 286999Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 296657Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 306657Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 316657Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 329302Snilay@cs.wisc.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 336657Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 346657Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 356657Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 366657Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 376657Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 386657Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 396657Snate@binkert.org * 406657Snate@binkert.org * Authors: Kevin Lim 416657Snate@binkert.org * Korey Sewell 426657Snate@binkert.org */ 436657Snate@binkert.org 446657Snate@binkert.org#ifndef __CPU_O3_ROB_IMPL_HH__ 456657Snate@binkert.org#define __CPU_O3_ROB_IMPL_HH__ 466657Snate@binkert.org 476657Snate@binkert.org#include <list> 486657Snate@binkert.org 496657Snate@binkert.org#include "cpu/o3/rob.hh" 506882SBrad.Beckmann@amd.com#include "debug/Fetch.hh" 516657Snate@binkert.org#include "debug/ROB.hh" 526657Snate@binkert.org#include "params/DerivO3CPU.hh" 536657Snate@binkert.org 546657Snate@binkert.orgusing namespace std; 556657Snate@binkert.org 566657Snate@binkert.orgtemplate <class Impl> 576657Snate@binkert.orgROB<Impl>::ROB(O3CPU *_cpu, DerivO3CPUParams *params) 586657Snate@binkert.org : cpu(_cpu), 596657Snate@binkert.org numEntries(params->numROBEntries), 606657Snate@binkert.org squashWidth(params->squashWidth), 616657Snate@binkert.org numInstsInROB(0), 626657Snate@binkert.org numThreads(params->numThreads) 636657Snate@binkert.org{ 646657Snate@binkert.org std::string policy = params->smtROBPolicy; 656657Snate@binkert.org 666657Snate@binkert.org //Convert string to lowercase 676657Snate@binkert.org std::transform(policy.begin(), policy.end(), policy.begin(), 686657Snate@binkert.org (int(*)(int)) tolower); 696657Snate@binkert.org 7010228Snilay@cs.wisc.edu //Figure out rob policy 716657Snate@binkert.org if (policy == "dynamic") { 726657Snate@binkert.org robPolicy = Dynamic; 7310228Snilay@cs.wisc.edu 746657Snate@binkert.org //Set Max Entries to Total ROB Capacity 756657Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; tid++) { 766657Snate@binkert.org maxEntries[tid] = numEntries; 776657Snate@binkert.org } 786657Snate@binkert.org 796657Snate@binkert.org } else if (policy == "partitioned") { 806657Snate@binkert.org robPolicy = Partitioned; 816657Snate@binkert.org DPRINTF(Fetch, "ROB sharing policy set to Partitioned\n"); 826657Snate@binkert.org 836657Snate@binkert.org //@todo:make work if part_amt doesnt divide evenly. 846657Snate@binkert.org int part_amt = numEntries / numThreads; 856657Snate@binkert.org 866657Snate@binkert.org //Divide ROB up evenly 876657Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; tid++) { 886657Snate@binkert.org maxEntries[tid] = part_amt; 896657Snate@binkert.org } 908086SBrad.Beckmann@amd.com 918086SBrad.Beckmann@amd.com } else if (policy == "threshold") { 928086SBrad.Beckmann@amd.com robPolicy = Threshold; 936657Snate@binkert.org DPRINTF(Fetch, "ROB sharing policy set to Threshold\n"); 946657Snate@binkert.org 956657Snate@binkert.org int threshold = params->smtROBThreshold;; 966657Snate@binkert.org 976657Snate@binkert.org //Divide up by threshold amount 986657Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; tid++) { 996657Snate@binkert.org maxEntries[tid] = threshold; 1006657Snate@binkert.org } 1016657Snate@binkert.org } else { 1026657Snate@binkert.org assert(0 && "Invalid ROB Sharing Policy.Options Are:{Dynamic," 1036657Snate@binkert.org "Partitioned, Threshold}"); 1046657Snate@binkert.org } 1056657Snate@binkert.org 1066657Snate@binkert.org resetState(); 1076657Snate@binkert.org} 1086657Snate@binkert.org 1096657Snate@binkert.orgtemplate <class Impl> 1106657Snate@binkert.orgvoid 1116657Snate@binkert.orgROB<Impl>::resetState() 1126657Snate@binkert.org{ 1136657Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; tid++) { 1146657Snate@binkert.org doneSquashing[tid] = true; 1156657Snate@binkert.org threadEntries[tid] = 0; 1166657Snate@binkert.org squashIt[tid] = instList[tid].end(); 1176657Snate@binkert.org squashedSeqNum[tid] = 0; 1186657Snate@binkert.org } 1196657Snate@binkert.org numInstsInROB = 0; 1206657Snate@binkert.org 1216657Snate@binkert.org // Initialize the "universal" ROB head & tail point to invalid 1226657Snate@binkert.org // pointers 1236657Snate@binkert.org head = instList[0].end(); 1246657Snate@binkert.org tail = instList[0].end(); 1256657Snate@binkert.org} 1266657Snate@binkert.org 1276657Snate@binkert.orgtemplate <class Impl> 1286657Snate@binkert.orgstd::string 1299298Snilay@cs.wisc.eduROB<Impl>::name() const 1306657Snate@binkert.org{ 1316657Snate@binkert.org return cpu->name() + ".rob"; 1326657Snate@binkert.org} 1336657Snate@binkert.org 1346657Snate@binkert.orgtemplate <class Impl> 1356657Snate@binkert.orgvoid 1369302Snilay@cs.wisc.eduROB<Impl>::setActiveThreads(list<ThreadID> *at_ptr) 1379302Snilay@cs.wisc.edu{ 1389302Snilay@cs.wisc.edu DPRINTF(ROB, "Setting active threads list pointer.\n"); 1396657Snate@binkert.org activeThreads = at_ptr; 1406657Snate@binkert.org} 1416657Snate@binkert.org 1426657Snate@binkert.orgtemplate <class Impl> 1436657Snate@binkert.orgvoid 1446657Snate@binkert.orgROB<Impl>::drainSanityCheck() const 1456657Snate@binkert.org{ 1466657Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; tid++) 1476882SBrad.Beckmann@amd.com assert(instList[tid].empty()); 1486882SBrad.Beckmann@amd.com assert(isEmpty()); 1496882SBrad.Beckmann@amd.com} 1508086SBrad.Beckmann@amd.com 1518086SBrad.Beckmann@amd.comtemplate <class Impl> 1528086SBrad.Beckmann@amd.comvoid 15310307Snilay@cs.wisc.eduROB<Impl>::takeOverFrom() 15410307Snilay@cs.wisc.edu{ 1556657Snate@binkert.org resetState(); 1566657Snate@binkert.org} 1576657Snate@binkert.org 15810307Snilay@cs.wisc.edutemplate <class Impl> 1599298Snilay@cs.wisc.eduvoid 1609298Snilay@cs.wisc.eduROB<Impl>::resetEntries() 1619298Snilay@cs.wisc.edu{ 1626657Snate@binkert.org if (robPolicy != Dynamic || numThreads > 1) { 1636657Snate@binkert.org int active_threads = activeThreads->size(); 1646657Snate@binkert.org 1656657Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 1666657Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 1676657Snate@binkert.org 1686657Snate@binkert.org while (threads != end) { 1696657Snate@binkert.org ThreadID tid = *threads++; 1706657Snate@binkert.org 1716657Snate@binkert.org if (robPolicy == Partitioned) { 1726657Snate@binkert.org maxEntries[tid] = numEntries / active_threads; 1739219Spower.jg@gmail.com } else if (robPolicy == Threshold && active_threads == 1) { 1746657Snate@binkert.org maxEntries[tid] = numEntries; 1756657Snate@binkert.org } 1766657Snate@binkert.org } 1776657Snate@binkert.org } 1786657Snate@binkert.org} 1796657Snate@binkert.org 1806657Snate@binkert.orgtemplate <class Impl> 1816657Snate@binkert.orgint 1826657Snate@binkert.orgROB<Impl>::entryAmount(ThreadID num_threads) 1836657Snate@binkert.org{ 1846657Snate@binkert.org if (robPolicy == Partitioned) { 1856657Snate@binkert.org return numEntries / num_threads; 1866999Snate@binkert.org } else { 1876657Snate@binkert.org return 0; 1886657Snate@binkert.org } 1896657Snate@binkert.org} 1906657Snate@binkert.org 1916657Snate@binkert.orgtemplate <class Impl> 1926657Snate@binkert.orgint 1936657Snate@binkert.orgROB<Impl>::countInsts() 1947007Snate@binkert.org{ 1957007Snate@binkert.org int total = 0; 1966657Snate@binkert.org 1977002Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; tid++) 1987002Snate@binkert.org total += countInsts(tid); 1999466Snilay@cs.wisc.edu 2006657Snate@binkert.org return total; 2016657Snate@binkert.org} 2026657Snate@binkert.org 2036657Snate@binkert.orgtemplate <class Impl> 2046657Snate@binkert.orgint 2056657Snate@binkert.orgROB<Impl>::countInsts(ThreadID tid) 2066657Snate@binkert.org{ 2076657Snate@binkert.org return instList[tid].size(); 2086657Snate@binkert.org} 2096657Snate@binkert.org 2106657Snate@binkert.orgtemplate <class Impl> 2116657Snate@binkert.orgvoid 2127007Snate@binkert.orgROB<Impl>::insertInst(DynInstPtr &inst) 2137007Snate@binkert.org{ 2146657Snate@binkert.org assert(inst); 2159466Snilay@cs.wisc.edu 2166657Snate@binkert.org robWrites++; 2176657Snate@binkert.org 2189466Snilay@cs.wisc.edu DPRINTF(ROB, "Adding inst PC %s to the ROB.\n", inst->pcState()); 2199508Snilay@cs.wisc.edu 2209466Snilay@cs.wisc.edu assert(numInstsInROB != numEntries); 2219466Snilay@cs.wisc.edu 2229466Snilay@cs.wisc.edu ThreadID tid = inst->threadNumber; 2236657Snate@binkert.org 2246657Snate@binkert.org instList[tid].push_back(inst); 2256657Snate@binkert.org 2266657Snate@binkert.org //Set Up head iterator if this is the 1st instruction in the ROB 2276657Snate@binkert.org if (numInstsInROB == 0) { 2286657Snate@binkert.org head = instList[tid].begin(); 2296657Snate@binkert.org assert((*head) == inst); 2306657Snate@binkert.org } 2316657Snate@binkert.org 2326657Snate@binkert.org //Must Decrement for iterator to actually be valid since __.end() 2336657Snate@binkert.org //actually points to 1 after the last inst 2346657Snate@binkert.org tail = instList[tid].end(); 2356657Snate@binkert.org tail--; 2366657Snate@binkert.org 2376657Snate@binkert.org inst->setInROB(); 2386657Snate@binkert.org 2396657Snate@binkert.org ++numInstsInROB; 2407453Snate@binkert.org ++threadEntries[tid]; 2417453Snate@binkert.org 2427453Snate@binkert.org assert((*tail) == inst); 2437453Snate@binkert.org 2447453Snate@binkert.org DPRINTF(ROB, "[tid:%i] Now has %d instructions.\n", tid, threadEntries[tid]); 2457453Snate@binkert.org} 2467453Snate@binkert.org 2477453Snate@binkert.orgtemplate <class Impl> 2487453Snate@binkert.orgvoid 2497453Snate@binkert.orgROB<Impl>::retireHead(ThreadID tid) 2507453Snate@binkert.org{ 2517453Snate@binkert.org robWrites++; 2527453Snate@binkert.org 2537453Snate@binkert.org assert(numInstsInROB > 0); 2547453Snate@binkert.org 2557453Snate@binkert.org // Get the head ROB instruction. 2567453Snate@binkert.org InstIt head_it = instList[tid].begin(); 2576657Snate@binkert.org 2586657Snate@binkert.org DynInstPtr head_inst = (*head_it); 2596657Snate@binkert.org 2606657Snate@binkert.org assert(head_inst->readyToCommit()); 2619466Snilay@cs.wisc.edu 2626657Snate@binkert.org DPRINTF(ROB, "[tid:%u]: Retiring head instruction, " 2639466Snilay@cs.wisc.edu "instruction PC %s, [sn:%lli]\n", tid, head_inst->pcState(), 2649508Snilay@cs.wisc.edu head_inst->seqNum); 2659466Snilay@cs.wisc.edu 2666657Snate@binkert.org --numInstsInROB; 2676657Snate@binkert.org --threadEntries[tid]; 2686657Snate@binkert.org 2696657Snate@binkert.org head_inst->clearInROB(); 2709466Snilay@cs.wisc.edu head_inst->setCommitted(); 2719466Snilay@cs.wisc.edu 2729466Snilay@cs.wisc.edu instList[tid].erase(head_it); 2739466Snilay@cs.wisc.edu 2746657Snate@binkert.org //Update "Global" Head of ROB 2756657Snate@binkert.org updateHead(); 2766657Snate@binkert.org 2776657Snate@binkert.org // @todo: A special case is needed if the instruction being 2786657Snate@binkert.org // retired is the only instruction in the ROB; otherwise the tail 2796657Snate@binkert.org // iterator will become invalidated. 2806657Snate@binkert.org cpu->removeFrontInst(head_inst); 2816657Snate@binkert.org} 2826657Snate@binkert.org 2836657Snate@binkert.orgtemplate <class Impl> 2846657Snate@binkert.orgbool 2859466Snilay@cs.wisc.eduROB<Impl>::isHeadReady(ThreadID tid) 28610472Sandreas.hansson@arm.com{ 28710472Sandreas.hansson@arm.com robReads++; 28810472Sandreas.hansson@arm.com if (threadEntries[tid] != 0) { 28910472Sandreas.hansson@arm.com return instList[tid].front()->readyToCommit(); 29010472Sandreas.hansson@arm.com } 29110472Sandreas.hansson@arm.com 29210472Sandreas.hansson@arm.com return false; 29310472Sandreas.hansson@arm.com} 29410472Sandreas.hansson@arm.com 29510472Sandreas.hansson@arm.comtemplate <class Impl> 2967453Snate@binkert.orgbool 2977007Snate@binkert.orgROB<Impl>::canCommit() 2987007Snate@binkert.org{ 2997453Snate@binkert.org //@todo: set ActiveThreads through ROB or CPU 3007007Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 3016657Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 3026657Snate@binkert.org 3036657Snate@binkert.org while (threads != end) { 3046657Snate@binkert.org ThreadID tid = *threads++; 3056657Snate@binkert.org 3066657Snate@binkert.org if (isHeadReady(tid)) { 3076657Snate@binkert.org return true; 3086657Snate@binkert.org } 3096657Snate@binkert.org } 3106657Snate@binkert.org 3117007Snate@binkert.org return false; 3127007Snate@binkert.org} 3137007Snate@binkert.org 3147007Snate@binkert.orgtemplate <class Impl> 3157007Snate@binkert.orgunsigned 3166657Snate@binkert.orgROB<Impl>::numFreeEntries() 3176657Snate@binkert.org{ 3186657Snate@binkert.org return numEntries - numInstsInROB; 3196657Snate@binkert.org} 3206657Snate@binkert.org 3216657Snate@binkert.orgtemplate <class Impl> 3226657Snate@binkert.orgunsigned 3236657Snate@binkert.orgROB<Impl>::numFreeEntries(ThreadID tid) 3246657Snate@binkert.org{ 3257007Snate@binkert.org return maxEntries[tid] - threadEntries[tid]; 3267007Snate@binkert.org} 3277007Snate@binkert.org 3287007Snate@binkert.orgtemplate <class Impl> 3297007Snate@binkert.orgvoid 3306657Snate@binkert.orgROB<Impl>::doSquash(ThreadID tid) 3316657Snate@binkert.org{ 3326657Snate@binkert.org robWrites++; 3336657Snate@binkert.org DPRINTF(ROB, "[tid:%u]: Squashing instructions until [sn:%i].\n", 3346657Snate@binkert.org tid, squashedSeqNum[tid]); 3356657Snate@binkert.org 3366657Snate@binkert.org assert(squashIt[tid] != instList[tid].end()); 3377007Snate@binkert.org 3387007Snate@binkert.org if ((*squashIt[tid])->seqNum < squashedSeqNum[tid]) { 3397007Snate@binkert.org DPRINTF(ROB, "[tid:%u]: Done squashing instructions.\n", 3407007Snate@binkert.org tid); 3417007Snate@binkert.org 3426657Snate@binkert.org squashIt[tid] = instList[tid].end(); 3436657Snate@binkert.org 3447002Snate@binkert.org doneSquashing[tid] = true; 3456657Snate@binkert.org return; 3466657Snate@binkert.org } 3476657Snate@binkert.org 3486657Snate@binkert.org bool robTailUpdate = false; 3496657Snate@binkert.org 3506657Snate@binkert.org for (int numSquashed = 0; 3516657Snate@binkert.org numSquashed < squashWidth && 3526657Snate@binkert.org squashIt[tid] != instList[tid].end() && 3536657Snate@binkert.org (*squashIt[tid])->seqNum > squashedSeqNum[tid]; 3546657Snate@binkert.org ++numSquashed) 3556657Snate@binkert.org { 3566657Snate@binkert.org DPRINTF(ROB, "[tid:%u]: Squashing instruction PC %s, seq num %i.\n", 3576657Snate@binkert.org (*squashIt[tid])->threadNumber, 3586657Snate@binkert.org (*squashIt[tid])->pcState(), 3596657Snate@binkert.org (*squashIt[tid])->seqNum); 3606657Snate@binkert.org 3616657Snate@binkert.org // Mark the instruction as squashed, and ready to commit so that 3626657Snate@binkert.org // it can drain out of the pipeline. 3636657Snate@binkert.org (*squashIt[tid])->setSquashed(); 3646657Snate@binkert.org 3656657Snate@binkert.org (*squashIt[tid])->setCanCommit(); 3667007Snate@binkert.org 3676657Snate@binkert.org 3687007Snate@binkert.org if (squashIt[tid] == instList[tid].begin()) { 3696657Snate@binkert.org DPRINTF(ROB, "Reached head of instruction list while " 37010307Snilay@cs.wisc.edu "squashing.\n"); 37110307Snilay@cs.wisc.edu 37210307Snilay@cs.wisc.edu squashIt[tid] = instList[tid].end(); 3739298Snilay@cs.wisc.edu 3749298Snilay@cs.wisc.edu doneSquashing[tid] = true; 3759298Snilay@cs.wisc.edu 3766657Snate@binkert.org return; 3776657Snate@binkert.org } 3786657Snate@binkert.org 3796657Snate@binkert.org InstIt tail_thread = instList[tid].end(); 3807055Snate@binkert.org tail_thread--; 3817007Snate@binkert.org 3826657Snate@binkert.org if ((*squashIt[tid]) == (*tail_thread)) 3836657Snate@binkert.org robTailUpdate = true; 3847002Snate@binkert.org 3856657Snate@binkert.org squashIt[tid]--; 3866657Snate@binkert.org } 3876657Snate@binkert.org 3887007Snate@binkert.org 3896657Snate@binkert.org // Check if ROB is done squashing. 3906657Snate@binkert.org if ((*squashIt[tid])->seqNum <= squashedSeqNum[tid]) { 3916657Snate@binkert.org DPRINTF(ROB, "[tid:%u]: Done squashing instructions.\n", 3926657Snate@binkert.org tid); 3936657Snate@binkert.org 3946999Snate@binkert.org squashIt[tid] = instList[tid].end(); 3956657Snate@binkert.org 3966657Snate@binkert.org doneSquashing[tid] = true; 3976657Snate@binkert.org } 3986657Snate@binkert.org 3996657Snate@binkert.org if (robTailUpdate) { 4006657Snate@binkert.org updateTail(); 4016657Snate@binkert.org } 4027002Snate@binkert.org} 40310472Sandreas.hansson@arm.com 4047002Snate@binkert.org 4056657Snate@binkert.orgtemplate <class Impl> 4069499Snilay@cs.wisc.eduvoid 4079499Snilay@cs.wisc.eduROB<Impl>::updateHead() 4087002Snate@binkert.org{ 4097002Snate@binkert.org InstSeqNum lowest_num = 0; 4106657Snate@binkert.org bool first_valid = true; 4116657Snate@binkert.org 4126657Snate@binkert.org // @todo: set ActiveThreads through ROB or CPU 4136657Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 4147007Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 4157007Snate@binkert.org 4166657Snate@binkert.org while (threads != end) { 4176657Snate@binkert.org ThreadID tid = *threads++; 4186657Snate@binkert.org 4196657Snate@binkert.org if (instList[tid].empty()) 4206657Snate@binkert.org continue; 4216657Snate@binkert.org 4226657Snate@binkert.org if (first_valid) { 4236657Snate@binkert.org head = instList[tid].begin(); 4246657Snate@binkert.org lowest_num = (*head)->seqNum; 4256657Snate@binkert.org first_valid = false; 4269206Snilay@cs.wisc.edu continue; 4276657Snate@binkert.org } 4286657Snate@binkert.org 4296657Snate@binkert.org InstIt head_thread = instList[tid].begin(); 4306657Snate@binkert.org 4316657Snate@binkert.org DynInstPtr head_inst = (*head_thread); 4326657Snate@binkert.org 4336657Snate@binkert.org assert(head_inst != 0); 43410307Snilay@cs.wisc.edu 43510307Snilay@cs.wisc.edu if (head_inst->seqNum < lowest_num) { 43610307Snilay@cs.wisc.edu head = head_thread; 4379298Snilay@cs.wisc.edu lowest_num = head_inst->seqNum; 4386657Snate@binkert.org } 4396657Snate@binkert.org } 4406657Snate@binkert.org 4416999Snate@binkert.org if (first_valid) { 4426657Snate@binkert.org head = instList[0].end(); 4436657Snate@binkert.org } 4446657Snate@binkert.org 4456657Snate@binkert.org} 4466657Snate@binkert.org 4477007Snate@binkert.orgtemplate <class Impl> 4487007Snate@binkert.orgvoid 4497007Snate@binkert.orgROB<Impl>::updateTail() 4506657Snate@binkert.org{ 4517002Snate@binkert.org tail = instList[0].end(); 4527002Snate@binkert.org bool first_valid = true; 4537002Snate@binkert.org 4548086SBrad.Beckmann@amd.com list<ThreadID>::iterator threads = activeThreads->begin(); 4558086SBrad.Beckmann@amd.com list<ThreadID>::iterator end = activeThreads->end(); 4568086SBrad.Beckmann@amd.com 4578086SBrad.Beckmann@amd.com while (threads != end) { 4588602Snilay@cs.wisc.edu ThreadID tid = *threads++; 4598602Snilay@cs.wisc.edu 4608602Snilay@cs.wisc.edu if (instList[tid].empty()) { 4618602Snilay@cs.wisc.edu continue; 4628602Snilay@cs.wisc.edu } 4638086SBrad.Beckmann@amd.com 4646657Snate@binkert.org // If this is the first valid then assign w/out 4657007Snate@binkert.org // comparison 4666657Snate@binkert.org if (first_valid) { 4676657Snate@binkert.org tail = instList[tid].end(); 4686657Snate@binkert.org tail--; 4696657Snate@binkert.org first_valid = false; 4706657Snate@binkert.org continue; 4716657Snate@binkert.org } 4726657Snate@binkert.org 4736657Snate@binkert.org // Assign new tail if this thread's tail is younger 4746657Snate@binkert.org // than our current "tail high" 4756657Snate@binkert.org InstIt tail_thread = instList[tid].end(); 4766657Snate@binkert.org tail_thread--; 4776862Sdrh5@cs.wisc.edu 4786862Sdrh5@cs.wisc.edu if ((*tail_thread)->seqNum > (*tail)->seqNum) { 4796862Sdrh5@cs.wisc.edu tail = tail_thread; 4806862Sdrh5@cs.wisc.edu } 4816657Snate@binkert.org } 4826657Snate@binkert.org} 4836657Snate@binkert.org 4846657Snate@binkert.org 4856657Snate@binkert.orgtemplate <class Impl> 4867007Snate@binkert.orgvoid 4877007Snate@binkert.orgROB<Impl>::squash(InstSeqNum squash_num, ThreadID tid) 4887002Snate@binkert.org{ 4897007Snate@binkert.org if (isEmpty(tid)) { 4907007Snate@binkert.org DPRINTF(ROB, "Does not need to squash due to being empty " 4917002Snate@binkert.org "[sn:%i]\n", 4927007Snate@binkert.org squash_num); 4937007Snate@binkert.org 4946657Snate@binkert.org return; 4956657Snate@binkert.org } 4966657Snate@binkert.org 4976657Snate@binkert.org DPRINTF(ROB, "Starting to squash within the ROB.\n"); 4986657Snate@binkert.org 4996657Snate@binkert.org robStatus[tid] = ROBSquashing; 5006657Snate@binkert.org 5016657Snate@binkert.org doneSquashing[tid] = false; 5026657Snate@binkert.org 5036657Snate@binkert.org squashedSeqNum[tid] = squash_num; 5046657Snate@binkert.org 5056657Snate@binkert.org if (!instList[tid].empty()) { 5066657Snate@binkert.org InstIt tail_thread = instList[tid].end(); 5078602Snilay@cs.wisc.edu tail_thread--; 5088602Snilay@cs.wisc.edu 5098602Snilay@cs.wisc.edu squashIt[tid] = tail_thread; 5108602Snilay@cs.wisc.edu 5118602Snilay@cs.wisc.edu doSquash(tid); 5128602Snilay@cs.wisc.edu } 5138602Snilay@cs.wisc.edu} 5148602Snilay@cs.wisc.edu 5158602Snilay@cs.wisc.edutemplate <class Impl> 5168086SBrad.Beckmann@amd.comtypename Impl::DynInstPtr 5178086SBrad.Beckmann@amd.comROB<Impl>::readHeadInst(ThreadID tid) 5188086SBrad.Beckmann@amd.com{ 5198086SBrad.Beckmann@amd.com if (threadEntries[tid] != 0) { 5208086SBrad.Beckmann@amd.com InstIt head_thread = instList[tid].begin(); 5218086SBrad.Beckmann@amd.com 5228086SBrad.Beckmann@amd.com assert((*head_thread)->isInROB()); 5238086SBrad.Beckmann@amd.com 5246657Snate@binkert.org return *head_thread; 5256657Snate@binkert.org } else { 5267002Snate@binkert.org return dummyInst; 5276657Snate@binkert.org } 5287007Snate@binkert.org} 5296657Snate@binkert.org 5306657Snate@binkert.orgtemplate <class Impl> 5316657Snate@binkert.orgtypename Impl::DynInstPtr 5326657Snate@binkert.orgROB<Impl>::readTailInst(ThreadID tid) 5336657Snate@binkert.org{ 5346999Snate@binkert.org InstIt tail_thread = instList[tid].end(); 5356657Snate@binkert.org tail_thread--; 5366657Snate@binkert.org 5376657Snate@binkert.org return *tail_thread; 5386657Snate@binkert.org} 5396657Snate@binkert.org 5406657Snate@binkert.orgtemplate <class Impl> 5417832Snate@binkert.orgvoid 5427002Snate@binkert.orgROB<Impl>::regStats() 5437002Snate@binkert.org{ 5447002Snate@binkert.org using namespace Stats; 5457805Snilay@cs.wisc.edu robReads 5466657Snate@binkert.org .name(name() + ".rob_reads") 5476657Snate@binkert.org .desc("The number of ROB reads"); 5487002Snate@binkert.org 5497002Snate@binkert.org robWrites 5506657Snate@binkert.org .name(name() + ".rob_writes") 5516657Snate@binkert.org .desc("The number of ROB writes"); 5528086SBrad.Beckmann@amd.com} 5538086SBrad.Beckmann@amd.com 5548086SBrad.Beckmann@amd.comtemplate <class Impl> 5558086SBrad.Beckmann@amd.comtypename Impl::DynInstPtr 5568086SBrad.Beckmann@amd.comROB<Impl>::findInst(ThreadID tid, InstSeqNum squash_inst) 5578086SBrad.Beckmann@amd.com{ 5588086SBrad.Beckmann@amd.com for (InstIt it = instList[tid].begin(); it != instList[tid].end(); it++) { 5598086SBrad.Beckmann@amd.com if ((*it)->seqNum == squash_inst) { 5608086SBrad.Beckmann@amd.com return *it; 5618086SBrad.Beckmann@amd.com } 5628086SBrad.Beckmann@amd.com } 5638086SBrad.Beckmann@amd.com return NULL; 5648086SBrad.Beckmann@amd.com} 5658086SBrad.Beckmann@amd.com 5668086SBrad.Beckmann@amd.com#endif//__CPU_O3_ROB_IMPL_HH__ 5678086SBrad.Beckmann@amd.com