class AtomicSimpleCPU(BaseCPU):
type = 'AtomicSimpleCPU'
width = Param.Int(1, "CPU width")
- simulate_stalls = Param.Bool(False, "Simulate cache stall cycles")
+ simulate_data_stalls = Param.Bool(False, "Simulate dcache stall cycles")
+ simulate_inst_stalls = Param.Bool(False, "Simulate icache stall cycles")
function_trace = Param.Bool(False, "Enable function trace")
function_trace_start = Param.Tick(0, "Cycle to start function trace")
if build_env['FULL_SYSTEM']:
}
AtomicSimpleCPU::AtomicSimpleCPU(Params *p)
- : BaseSimpleCPU(p), tickEvent(this),
- width(p->width), simulate_stalls(p->simulate_stalls),
+ : BaseSimpleCPU(p), tickEvent(this), width(p->width),
+ simulate_data_stalls(p->simulate_data_stalls),
+ simulate_inst_stalls(p->simulate_inst_stalls),
icachePort(name() + "-iport", this), dcachePort(name() + "-iport", this),
physmemPort(name() + "-iport", this), hasPhysMemPort(false)
{
{
DPRINTF(SimpleCPU, "Tick\n");
- Tick latency = ticks(1); // instruction takes one cycle by default
+ Tick latency = 0;
for (int i = 0; i < width; ++i) {
numCycles++;
curStaticInst->isFirstMicroop()))
instCnt++;
- if (simulate_stalls) {
- Tick icache_stall =
- icache_access ? icache_latency - ticks(1) : 0;
- Tick dcache_stall =
- dcache_access ? dcache_latency - ticks(1) : 0;
- Tick stall_cycles = (icache_stall + dcache_stall) / ticks(1);
- if (ticks(stall_cycles) < (icache_stall + dcache_stall))
- latency += ticks(stall_cycles+1);
- else
- latency += ticks(stall_cycles);
+ Tick stall_ticks = 0;
+ if (simulate_inst_stalls && icache_access)
+ stall_ticks += icache_latency;
+
+ if (simulate_data_stalls && dcache_access)
+ stall_ticks += dcache_latency;
+
+ if (stall_ticks) {
+ Tick stall_cycles = stall_ticks / ticks(1);
+ Tick aligned_stall_ticks = ticks(stall_cycles);
+
+ if (aligned_stall_ticks < stall_ticks)
+ aligned_stall_ticks += 1;
+
+ latency += aligned_stall_ticks;
}
}
advancePC(fault);
}
+ // instruction takes at least one cycle
+ if (latency < ticks(1))
+ latency = ticks(1);
+
if (_status != Idle)
tickEvent.schedule(curTick + latency);
}
params->functionTrace = function_trace;
params->functionTraceStart = function_trace_start;
params->width = width;
- params->simulate_stalls = simulate_stalls;
+ params->simulate_data_stalls = simulate_data_stalls;
+ params->simulate_inst_stalls = simulate_inst_stalls;
params->system = system;
params->cpu_id = cpu_id;
params->tracer = tracer;
struct Params : public BaseSimpleCPU::Params {
int width;
- bool simulate_stalls;
+ bool simulate_data_stalls;
+ bool simulate_inst_stalls;
};
AtomicSimpleCPU(Params *params);
TickEvent tickEvent;
const int width;
- const bool simulate_stalls;
+ const bool simulate_data_stalls;
+ const bool simulate_inst_stalls;
// main simulation loop (one cycle)
void tick();