AtomicSimpleCPU: Separate data stalls from instruction stalls.
Separate simulation of icache stalls and dat stalls.
This commit is contained in:
parent
f24f2c57b6
commit
67a33eed40
|
@ -33,7 +33,8 @@ from BaseCPU import BaseCPU
|
|||
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']:
|
||||
|
|
|
@ -153,8 +153,9 @@ AtomicSimpleCPU::DcachePort::setPeer(Port *port)
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -711,7 +712,7 @@ AtomicSimpleCPU::tick()
|
|||
{
|
||||
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++;
|
||||
|
@ -769,16 +770,21 @@ AtomicSimpleCPU::tick()
|
|||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -786,6 +792,10 @@ AtomicSimpleCPU::tick()
|
|||
advancePC(fault);
|
||||
}
|
||||
|
||||
// instruction takes at least one cycle
|
||||
if (latency < ticks(1))
|
||||
latency = ticks(1);
|
||||
|
||||
if (_status != Idle)
|
||||
tickEvent.schedule(curTick + latency);
|
||||
}
|
||||
|
@ -819,7 +829,8 @@ AtomicSimpleCPUParams::create()
|
|||
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;
|
||||
|
|
|
@ -39,7 +39,8 @@ class AtomicSimpleCPU : public BaseSimpleCPU
|
|||
|
||||
struct Params : public BaseSimpleCPU::Params {
|
||||
int width;
|
||||
bool simulate_stalls;
|
||||
bool simulate_data_stalls;
|
||||
bool simulate_inst_stalls;
|
||||
};
|
||||
|
||||
AtomicSimpleCPU(Params *params);
|
||||
|
@ -74,7 +75,8 @@ class AtomicSimpleCPU : public BaseSimpleCPU
|
|||
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();
|
||||
|
|
Loading…
Reference in a new issue