diff --git a/src/cpu/trace/TraceCPU.py b/src/cpu/trace/TraceCPU.py index e1c02ae63..bbce9c0ad 100644 --- a/src/cpu/trace/TraceCPU.py +++ b/src/cpu/trace/TraceCPU.py @@ -1,4 +1,4 @@ -# Copyright (c) 2013 - 2015 ARM Limited +# Copyright (c) 2013 - 2016 ARM Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -69,3 +69,9 @@ class TraceCPU(BaseCPU): sizeLoadBuffer = Param.Unsigned(16, "Number of entries in the load buffer") sizeROB = Param.Unsigned(40, "Number of entries in the re-order buffer") + # Frequency multiplier used to effectively scale the Trace CPU frequency + # either up or down. Note that the Trace CPU's clock domain must also be + # changed when frequency is scaled. A default value of 1.0 means the same + # frequency as was used for generating the traces. + freqMultiplier = Param.Float(1.0, "Multiplier scale the Trace CPU "\ + "frequency up or down") diff --git a/src/cpu/trace/trace_cpu.cc b/src/cpu/trace/trace_cpu.cc index e81a79818..42620a177 100644 --- a/src/cpu/trace/trace_cpu.cc +++ b/src/cpu/trace/trace_cpu.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 - 2015 ARM Limited + * Copyright (c) 2013 - 2016 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -56,8 +56,7 @@ TraceCPU::TraceCPU(TraceCPUParams *params) dataTraceFile(params->dataTraceFile), icacheGen(*this, ".iside", icachePort, instMasterID, instTraceFile), dcacheGen(*this, ".dside", dcachePort, dataMasterID, dataTraceFile, - params->sizeROB, params->sizeStoreBuffer, - params->sizeLoadBuffer), + params), icacheNextEvent(this), dcacheNextEvent(this), oneTraceComplete(false), @@ -1225,8 +1224,11 @@ TraceCPU::DcachePort::recvReqRetry() owner->dcacheRetryRecvd(); } -TraceCPU::ElasticDataGen::InputStream::InputStream(const std::string& filename) +TraceCPU::ElasticDataGen::InputStream::InputStream( + const std::string& filename, + const double time_multiplier) : trace(filename), + timeMultiplier(time_multiplier), microOpCount(0) { // Create a protobuf message for the header and read it from the stream @@ -1259,7 +1261,8 @@ TraceCPU::ElasticDataGen::InputStream::read(GraphNode* element) // Required fields element->seqNum = pkt_msg.seq_num(); element->type = pkt_msg.type(); - element->compDelay = pkt_msg.comp_delay(); + // Scale the compute delay to effectively scale the Trace CPU frequency + element->compDelay = pkt_msg.comp_delay() * timeMultiplier; // Repeated field robDepList element->clearRobDep(); diff --git a/src/cpu/trace/trace_cpu.hh b/src/cpu/trace/trace_cpu.hh index bb59c3fab..2c7168d51 100644 --- a/src/cpu/trace/trace_cpu.hh +++ b/src/cpu/trace/trace_cpu.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 - 2015 ARM Limited + * Copyright (c) 2013 - 2016 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -795,6 +795,14 @@ class TraceCPU : public BaseCPU /** Input file stream for the protobuf trace */ ProtoInputStream trace; + /** + * A multiplier for the compute delays in the trace to modulate + * the Trace CPU frequency either up or down. The Trace CPU's + * clock domain frequency must also be set to match the expected + * result of frequency scaling. + */ + const double timeMultiplier; + /** Count of committed ops read from trace plus the filtered ops */ uint64_t microOpCount; @@ -809,8 +817,10 @@ class TraceCPU : public BaseCPU * Create a trace input stream for a given file name. * * @param filename Path to the file to read from + * @param time_multiplier used to scale the compute delays */ - InputStream(const std::string& filename); + InputStream(const std::string& filename, + const double time_multiplier); /** * Reset the stream such that it can be played once @@ -840,19 +850,19 @@ class TraceCPU : public BaseCPU /* Constructor */ ElasticDataGen(TraceCPU& _owner, const std::string& _name, MasterPort& _port, MasterID master_id, - const std::string& trace_file, uint16_t max_rob, - uint16_t max_stores, uint16_t max_loads) + const std::string& trace_file, TraceCPUParams *params) : owner(_owner), port(_port), masterID(master_id), - trace(trace_file), + trace(trace_file, 1.0 / params->freqMultiplier), genName(owner.name() + ".elastic" + _name), retryPkt(nullptr), traceComplete(false), nextRead(false), execComplete(false), windowSize(trace.getWindowSize()), - hwResource(max_rob, max_stores, max_loads) + hwResource(params->sizeROB, params->sizeStoreBuffer, + params->sizeLoadBuffer) { DPRINTF(TraceCPUData, "Window size in the trace is %d.\n", windowSize);