timing.cc (8737:770ccf3af571) | timing.cc (8779:2a590c51adb1) |
---|---|
1/* 2 * Copyright (c) 2010 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 40 unchanged lines hidden (view full) --- 49#include "cpu/exetrace.hh" 50#include "debug/Config.hh" 51#include "debug/ExecFaulting.hh" 52#include "debug/SimpleCPU.hh" 53#include "mem/packet.hh" 54#include "mem/packet_access.hh" 55#include "params/TimingSimpleCPU.hh" 56#include "sim/faults.hh" | 1/* 2 * Copyright (c) 2010 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 40 unchanged lines hidden (view full) --- 49#include "cpu/exetrace.hh" 50#include "debug/Config.hh" 51#include "debug/ExecFaulting.hh" 52#include "debug/SimpleCPU.hh" 53#include "mem/packet.hh" 54#include "mem/packet_access.hh" 55#include "params/TimingSimpleCPU.hh" 56#include "sim/faults.hh" |
57#include "sim/full_system.hh" |
|
57#include "sim/system.hh" 58 59using namespace std; 60using namespace TheISA; 61 62Port * 63TimingSimpleCPU::getPort(const std::string &if_name, int idx) 64{ --- 4 unchanged lines hidden (view full) --- 69 else 70 panic("No Such Port\n"); 71} 72 73void 74TimingSimpleCPU::init() 75{ 76 BaseCPU::init(); | 58#include "sim/system.hh" 59 60using namespace std; 61using namespace TheISA; 62 63Port * 64TimingSimpleCPU::getPort(const std::string &if_name, int idx) 65{ --- 4 unchanged lines hidden (view full) --- 70 else 71 panic("No Such Port\n"); 72} 73 74void 75TimingSimpleCPU::init() 76{ 77 BaseCPU::init(); |
78 if (FullSystem) { 79 for (int i = 0; i < threadContexts.size(); ++i) { |
|
77#if FULL_SYSTEM | 80#if FULL_SYSTEM |
78 for (int i = 0; i < threadContexts.size(); ++i) { 79 ThreadContext *tc = threadContexts[i]; | 81 ThreadContext *tc = threadContexts[i]; 82 // initialize CPU, including PC 83 TheISA::initCPU(tc, _cpuId); 84#endif 85 } 86 } 87} |
80 | 88 |
81 // initialize CPU, including PC 82 TheISA::initCPU(tc, _cpuId); | 89Tick 90TimingSimpleCPU::CpuPort::recvAtomic(PacketPtr pkt) 91{ 92 panic("TimingSimpleCPU doesn't expect recvAtomic callback!"); 93 return curTick(); 94} 95 96void 97TimingSimpleCPU::CpuPort::recvFunctional(PacketPtr pkt) 98{ 99 //No internal storage to update, jusst return 100 return; 101} 102 103void 104TimingSimpleCPU::CpuPort::recvStatusChange(Status status) 105{ 106 if (status == RangeChange) { 107 if (!snoopRangeSent) { 108 snoopRangeSent = true; 109 sendStatusChange(Port::RangeChange); 110 } 111 return; |
83 } 84 | 112 } 113 |
85 // Initialise the ThreadContext's memory proxies 86 tcBase()->initMemProxies(tcBase()); 87#endif | 114 panic("TimingSimpleCPU doesn't expect recvStatusChange callback!"); |
88} 89 | 115} 116 |
117 |
|
90void | 118void |
91TimingSimpleCPU::TimingCPUPort::TickEvent::schedule(PacketPtr _pkt, Tick t) | 119TimingSimpleCPU::CpuPort::TickEvent::schedule(PacketPtr _pkt, Tick t) |
92{ 93 pkt = _pkt; 94 cpu->schedule(this, t); 95} 96 97TimingSimpleCPU::TimingSimpleCPU(TimingSimpleCPUParams *p) | 120{ 121 pkt = _pkt; 122 cpu->schedule(this, t); 123} 124 125TimingSimpleCPU::TimingSimpleCPU(TimingSimpleCPUParams *p) |
98 : BaseSimpleCPU(p), fetchTranslation(this), icachePort(this), 99 dcachePort(this), fetchEvent(this) | 126 : BaseSimpleCPU(p), fetchTranslation(this), icachePort(this, p->clock), 127 dcachePort(this, p->clock), fetchEvent(this) |
100{ 101 _status = Idle; 102 | 128{ 129 _status = Idle; 130 |
131 icachePort.snoopRangeSent = false; 132 dcachePort.snoopRangeSent = false; 133 |
|
103 ifetch_pkt = dcache_pkt = NULL; 104 drainEvent = NULL; 105 previousTick = 0; 106 changeState(SimObject::Running); 107 system->totalNumInsts = 0; 108} 109 110 --- 60 unchanged lines hidden (view full) --- 171 if (fetchEvent.scheduled()) 172 deschedule(fetchEvent); 173} 174 175 176void 177TimingSimpleCPU::takeOverFrom(BaseCPU *oldCPU) 178{ | 134 ifetch_pkt = dcache_pkt = NULL; 135 drainEvent = NULL; 136 previousTick = 0; 137 changeState(SimObject::Running); 138 system->totalNumInsts = 0; 139} 140 141 --- 60 unchanged lines hidden (view full) --- 202 if (fetchEvent.scheduled()) 203 deschedule(fetchEvent); 204} 205 206 207void 208TimingSimpleCPU::takeOverFrom(BaseCPU *oldCPU) 209{ |
179 BaseCPU::takeOverFrom(oldCPU); | 210 BaseCPU::takeOverFrom(oldCPU, &icachePort, &dcachePort); |
180 181 // if any of this CPU's ThreadContexts are active, mark the CPU as 182 // running and schedule its tick event. 183 for (int i = 0; i < threadContexts.size(); ++i) { 184 ThreadContext *tc = threadContexts[i]; 185 if (tc->status() == ThreadContext::Active && _status != Running) { 186 _status = Running; 187 break; --- 4 unchanged lines hidden (view full) --- 192 _status = Idle; 193 } 194 assert(threadContexts.size() == 1); 195 previousTick = curTick(); 196} 197 198 199void | 211 212 // if any of this CPU's ThreadContexts are active, mark the CPU as 213 // running and schedule its tick event. 214 for (int i = 0; i < threadContexts.size(); ++i) { 215 ThreadContext *tc = threadContexts[i]; 216 if (tc->status() == ThreadContext::Active && _status != Running) { 217 _status = Running; 218 break; --- 4 unchanged lines hidden (view full) --- 223 _status = Idle; 224 } 225 assert(threadContexts.size() == 1); 226 previousTick = curTick(); 227} 228 229 230void |
200TimingSimpleCPU::activateContext(ThreadID thread_num, int delay) | 231TimingSimpleCPU::activateContext(int thread_num, int delay) |
201{ 202 DPRINTF(SimpleCPU, "ActivateContext %d (%d cycles)\n", thread_num, delay); 203 204 assert(thread_num == 0); 205 assert(thread); 206 207 assert(_status == Idle); 208 209 notIdleFraction++; 210 _status = Running; 211 212 // kick things off by initiating the fetch of the next instruction 213 schedule(fetchEvent, nextCycle(curTick() + ticks(delay))); 214} 215 216 217void | 232{ 233 DPRINTF(SimpleCPU, "ActivateContext %d (%d cycles)\n", thread_num, delay); 234 235 assert(thread_num == 0); 236 assert(thread); 237 238 assert(_status == Idle); 239 240 notIdleFraction++; 241 _status = Running; 242 243 // kick things off by initiating the fetch of the next instruction 244 schedule(fetchEvent, nextCycle(curTick() + ticks(delay))); 245} 246 247 248void |
218TimingSimpleCPU::suspendContext(ThreadID thread_num) | 249TimingSimpleCPU::suspendContext(int thread_num) |
219{ 220 DPRINTF(SimpleCPU, "SuspendContext %d\n", thread_num); 221 222 assert(thread_num == 0); 223 assert(thread); 224 225 if (_status == Idle) 226 return; --- 613 unchanged lines hidden (view full) --- 840void 841TimingSimpleCPU::completeDrain() 842{ 843 DPRINTF(Config, "Done draining\n"); 844 changeState(SimObject::Drained); 845 drainEvent->process(); 846} 847 | 250{ 251 DPRINTF(SimpleCPU, "SuspendContext %d\n", thread_num); 252 253 assert(thread_num == 0); 254 assert(thread); 255 256 if (_status == Idle) 257 return; --- 613 unchanged lines hidden (view full) --- 871void 872TimingSimpleCPU::completeDrain() 873{ 874 DPRINTF(Config, "Done draining\n"); 875 changeState(SimObject::Drained); 876 drainEvent->process(); 877} 878 |
879void 880TimingSimpleCPU::DcachePort::setPeer(Port *port) 881{ 882 Port::setPeer(port); 883 884 if (FullSystem) { 885 // Update the ThreadContext's memory ports (Functional/Virtual 886 // Ports) 887 cpu->tcBase()->connectMemPorts(cpu->tcBase()); 888 } 889} 890 |
|
848bool 849TimingSimpleCPU::DcachePort::recvTiming(PacketPtr pkt) 850{ 851 if (pkt->isResponse() && !pkt->wasNacked()) { 852 // delay processing of returned data until next CPU clock edge 853 Tick next_tick = cpu->nextCycle(curTick()); 854 855 if (next_tick == curTick()) { 856 cpu->completeDataAccess(pkt); 857 } else { 858 if (!tickEvent.scheduled()) { 859 tickEvent.schedule(pkt, next_tick); 860 } else { 861 // In the case of a split transaction and a cache that is 862 // faster than a CPU we could get two responses before 863 // next_tick expires 864 if (!retryEvent.scheduled()) | 891bool 892TimingSimpleCPU::DcachePort::recvTiming(PacketPtr pkt) 893{ 894 if (pkt->isResponse() && !pkt->wasNacked()) { 895 // delay processing of returned data until next CPU clock edge 896 Tick next_tick = cpu->nextCycle(curTick()); 897 898 if (next_tick == curTick()) { 899 cpu->completeDataAccess(pkt); 900 } else { 901 if (!tickEvent.scheduled()) { 902 tickEvent.schedule(pkt, next_tick); 903 } else { 904 // In the case of a split transaction and a cache that is 905 // faster than a CPU we could get two responses before 906 // next_tick expires 907 if (!retryEvent.scheduled()) |
865 cpu->schedule(retryEvent, next_tick); | 908 schedule(retryEvent, next_tick); |
866 return false; 867 } 868 } 869 870 return true; 871 } 872 else if (pkt->wasNacked()) { 873 assert(cpu->_status == DcacheWaitResponse); --- 88 unchanged lines hidden (view full) --- 962// 963// TimingSimpleCPU Simulation Object 964// 965TimingSimpleCPU * 966TimingSimpleCPUParams::create() 967{ 968 numThreads = 1; 969#if !FULL_SYSTEM | 909 return false; 910 } 911 } 912 913 return true; 914 } 915 else if (pkt->wasNacked()) { 916 assert(cpu->_status == DcacheWaitResponse); --- 88 unchanged lines hidden (view full) --- 1005// 1006// TimingSimpleCPU Simulation Object 1007// 1008TimingSimpleCPU * 1009TimingSimpleCPUParams::create() 1010{ 1011 numThreads = 1; 1012#if !FULL_SYSTEM |
970 if (workload.size() != 1) | 1013 if (!FullSystem && workload.size() != 1) |
971 panic("only one workload allowed"); 972#endif 973 return new TimingSimpleCPU(this); 974} | 1014 panic("only one workload allowed"); 1015#endif 1016 return new TimingSimpleCPU(this); 1017} |