?? cpu.cc
字號:
/* * Copyright (c) 2001, 2002, 2003, 2004, 2005 * The Regents of The University of Michigan * All Rights Reserved * * This code is part of the M5 simulator, developed by Nathan Binkert, * Erik Hallnor, Steve Raasch, and Steve Reinhardt, with contributions * from Ron Dreslinski, Dave Greene, Lisa Hsu, Kevin Lim, Ali Saidi, * and Andrew Schultz. * * Permission is granted to use, copy, create derivative works and * redistribute this software and such derivative works for any * purpose, so long as the copyright notice above, this grant of * permission, and the disclaimer below appear in all copies made; and * so long as the name of The University of Michigan is not used in * any advertising or publicity pertaining to the use or distribution * of this software without specific, written prior authorization. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH * DAMAGES. */#include <sys/types.h>#include <sys/stat.h>#include <errno.h>#include <fcntl.h>#include <unistd.h>#include <iostream>#include <string>#include <sstream>#include <vector>#include "base/callback.hh"#include "base/cprintf.hh"#include "base/statistics.hh"#include "encumbered/cpu/full/cpu.hh"#include "encumbered/cpu/full/dd_queue.hh"#include "encumbered/cpu/full/rob_station.hh"#include "mem/cache/cache.hh" // for dynamic cast#include "mem/mem_interface.hh"#include "sim/builder.hh"#include "sim/sim_events.hh"#include "sim/sim_exit.hh"#include "sim/stats.hh"#if FULL_SYSTEM#include "base/remote_gdb.hh"#include "cpu/exec_context.hh"#include "mem/functional/memory_control.hh"#include "mem/functional/physical.hh"#include "sim/system.hh"#include "targetarch/alpha_memory.hh"#include "targetarch/pseudo_inst.hh"#endifusing namespace std;//////////////////////////////////////////////////////////////////////////////// Support for Multiple IQ's & Function-Unit Pools//////////////////////////////////////////////////////////////////////////////unsignedFullCPU::IQLeastFull(){ unsigned iq_idx = 0; unsigned least_count = IQ[0]->count(); for (int i = 1; i < numIQueues; ++i) { unsigned num = IQ[i]->count(); if (least_count > num) { iq_idx = i; least_count = num; } } return iq_idx;}unsignedFullCPU::IQMostFull(){ unsigned iq_idx = 0; unsigned most_count = IQ[0]->count(); for (int i = 1; i < numIQueues; ++i) { unsigned num = IQ[i]->count(); if (most_count < num) { iq_idx = i; most_count = num; } } return iq_idx;}voidFullCPU::ROBDump(){ ROB.dump();}voidFullCPU::fuDump(int p){ FUPools[p]->dump();}voidFullCPU::fuDump(){ for (int i = 0; i < numFUPools; ++i) FUPools[i]->dump();}unsignedFullCPU::IQNumInstructions(){ unsigned num = 0; for (int i = 0; i < numIQueues; ++i) num += IQ[i]->count(); return num;}unsignedFullCPU::IQNumInstructions(unsigned thread){ unsigned num = 0; for (int i = 0; i < numIQueues; ++i) num += IQ[i]->count(thread); return num;}unsignedFullCPU::IQNumReadyInstructions(){ unsigned num = 0; for (int i = 0; i < numIQueues; ++i) num += IQ[i]->ready_count(); return num;}voidFullCPU::dumpIQ(){ for (int i = 0; i < numIQueues; ++i) IQ[i]->dump(); cout << "done with dump!\n";}// Returns true only if _ALL_ queues have their caps metboolFullCPU::IQCapMet(unsigned thread){ switch (dispatch_policy) { case MODULO_N: case DEPENDENCE: for (int i = 0; i < numIQueues; ++i) if (!IQ[i]->cap_met(thread)) return false; break; case THREAD_PER_QUEUE: return IQ[thread % numIQueues]->cap_met(thread); break; } return true;}// Returns the number of free slots in the queue with the largest number// of slots available --> does not take caps into accountunsignedFullCPU::IQFreeSlots(){ unsigned max_slots = 0; for (int i = 0; i < numIQueues; ++i) { unsigned fs = IQ[i]->free_slots(); if (fs > max_slots) max_slots = fs; } return max_slots;}// Returns the number of free slots in all EXCEPT queue// 'idx'unsignedFullCPU::IQFreeSlotsX(unsigned idx){ unsigned slots = 0; for (unsigned i = 0; i < numIQueues; ++i) if (i != idx) slots += IQ[i]->free_slots(); return slots;}// Returns the number of free slots in the queue with the largest number// of slots available -> queues with the cap met for this thread have NO// slots availableunsignedFullCPU::IQFreeSlots(unsigned thread){ unsigned max_slots = 0; for (int i = 0; i < numIQueues; ++i) { if (!IQ[i]->cap_met(thread)) { unsigned fs = IQ[i]->free_slots(); if (fs > max_slots) max_slots = fs; } } return max_slots;}BaseIQ::iteratorFullCPU::IQOldestInstruction(){ BaseIQ::iterator oldest = 0; for (int i = 0; i < numIQueues; ++i) { if (oldest.notnull()) { if (IQ[i]->oldest().notnull()) { if ((*oldest).seq > (*IQ[i]->oldest()).seq) oldest = IQ[i]->oldest(); } } else oldest = IQ[i]->oldest(); } return oldest;}BaseIQ::iteratorFullCPU::IQOldestInstruction(unsigned thread){ BaseIQ::iterator oldest = 0; for (int i = 0; i < numIQueues; ++i) { if (oldest.notnull()) { if (IQ[i]->oldest(thread).notnull()) { if ((*oldest).seq > (*IQ[i]->oldest(thread)).seq) oldest = IQ[i]->oldest(thread); } } else oldest = IQ[i]->oldest(thread); } return oldest;}//////////////////////////////////////////////////////////////////////////////// CPU constructor//////////////////////////////////////////////////////////////////////////////FullCPU::FullCPU(Params *p,#if FULL_SYSTEM AlphaITB *itb, AlphaDTB *dtb, FunctionalMemory *mem,#else vector<Process *> workload,#endif // FULL_SYSTEM // // Caches // MemInterface *_icache_interface, MemInterface *_dcache_interface, SoftwarePrefetchPolicy _softwarePrefetchPolicy, // // Internal structures // vector<BaseIQ *> _IQ, unsigned _ROB_size, unsigned _LSQ_size, unsigned _storebuffer_size, // // Fetch // int _fetch_width, int _lines_to_fetch, int _num_icache_ports, int _fetch_branches, int _ifq_size, int _decode_dispatch_latency, BranchPred *_bpred, int _fetch_policy, bool _fetch_priority_enable, vector<unsigned> _icount_bias, // // Decode/Dispatch // bool _mt_frontend, int _decode_width, int _dispatch_to_issue_latency, vector<unsigned> _rob_caps, DispatchPolicyEnum disp_policy, bool _loose_mod_n, bool _use_hm_predictor, bool _use_lr_predictor, bool _use_lat_predictor, unsigned _max_chains, unsigned _max_wires, ChainWireInfo::MappingPolicy _chainWirePolicy, // // Issue // int _issue_width, vector<unsigned> _issue_bandwidth, bool _inorder_issue, MemDisambiguationEnum _disambig_mode, bool _prioritize_issue, vector<FuncUnitPool *> fupools, vector<unsigned> _thread_weights, // // Writeback // int _mispred_fixup_penalty, int _fault_handler_delay, unsigned _iq_comm_latency, // // Commit // int _commit_width, bool _prioritized_commit, CommitModelEnum _commit_model, // // Other // int _pc_sample_interval, PipeTrace *_ptrace) : BaseCPU(p), ROB_size(_ROB_size), LSQ_size(_LSQ_size), storebuffer_size(_storebuffer_size), icacheInterface(_icache_interface), dcacheInterface(_dcache_interface), softwarePrefetchPolicy(_softwarePrefetchPolicy), fetch_width(_fetch_width), lines_to_fetch(_lines_to_fetch), num_icache_ports(_num_icache_ports), fetch_branches(_fetch_branches), ifq_size(_ifq_size), decode_dispatch_latency(_decode_dispatch_latency), branch_pred(_bpred), fetch_policy(_fetch_policy), fetch_priority_enable(_fetch_priority_enable), mt_frontend(_mt_frontend), decode_width(_decode_width), dispatch_to_issue_latency(_dispatch_to_issue_latency), loose_mod_n_policy(_loose_mod_n), use_hm_predictor(_use_hm_predictor), use_lr_predictor(_use_lr_predictor), use_lat_predictor(_use_lat_predictor), max_chains(_max_chains), max_wires(_max_wires), chainWirePolicy(_chainWirePolicy), issue_width(_issue_width), inorder_issue(_inorder_issue), disambig_mode(_disambig_mode), prioritize_issue(_prioritize_issue), FUPools(fupools), mispred_fixup_penalty(_mispred_fixup_penalty), fault_handler_delay(_fault_handler_delay), iq_comm_latency(_iq_comm_latency), commit_width(_commit_width), commit_model(_commit_model), prioritized_commit(_prioritized_commit), ptrace(_ptrace), writebackEventQueue("writeback event queue"), tickEvent(this), pcSampleEvent(NULL){ //Initialize Counters to 0 lsq_fcount = 0; sim_invalid_addrs = 0; dependence_depth_count = 0; for (int i=0; i < SMT_MAX_THREADS; i++) { used_int_physical_regs[i] = 0; used_fp_physical_regs[i] = 0; } expected_inorder_seq_num = 1; // // check options for sanity // if (mispred_fixup_penalty < 1) fatal("mis-prediction penalty must be at least 1 cycle"); if (ifq_size < 1) fatal("inst fetch queue size must be positive > 0"); if (fetch_width < 1) fatal("fetch width must be positive non-zero and a power of two"); if (lines_to_fetch < 1) fatal("lines to fetch must be positive non-zero"); if (decode_width < 1) fatal("decode width must be positive non-zero"); if (issue_width < 1) fatal("issue width must be positive non-zero"); if (commit_width < 1) fatal("commit width must be positive non-zero"); if (prioritized_commit && commit_model != COMMIT_MODEL_SMT) fatal("Cannot do prioritized commit with this commit model"); if (use_lat_predictor && use_lr_predictor) fatal("SegmentedIQ: You really don't want to use BOTH the latency " "and L/R predictors"); mod_n_queue_idx = 0; // dispatch_width is not (currently) a user-modifiable value dispatch_width = decode_width; // note number of IQ's, copy IQ pointers from vector to array // let IQ know which CPU it belongs to numIQueues = _IQ.size(); if (numIQueues == 0) fatal("You must specify at least one IQ"); if (numIQueues > 1) { if (issue_width % numIQueues) panic("issue bandwidth doesn't distribute evenly"); if (dispatch_width % numIQueues) panic("dispatch bandwidth doesn't distribute evenly"); }
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -