diff --git a/src/cpu/trace/TraceCPU.py b/src/cpu/trace/TraceCPU.py index 1be16518d7..586e77caed 100644 --- a/src/cpu/trace/TraceCPU.py +++ b/src/cpu/trace/TraceCPU.py @@ -1,4 +1,4 @@ -# Copyright (c) 2013 - 2016 ARM Limited +# Copyright (c) 2013 - 2016, 2023 Arm Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -34,10 +34,11 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from m5.params import * -from m5.objects.BaseCPU import BaseCPU +from m5.proxy import * +from m5.objects.ClockedObject import ClockedObject -class TraceCPU(BaseCPU): +class TraceCPU(ClockedObject): """Trace CPU model which replays traces generated in a prior simulation using DerivO3CPU or its derived classes. It interfaces with L1 caches. """ @@ -54,13 +55,14 @@ class TraceCPU(BaseCPU): def require_caches(cls): return True - def addPMU(self, pmu=None): - pass - @classmethod def support_take_over(cls): return True + system = Param.System(Parent.any, "system object") + + icache_port = RequestPort("Instruction Port") + dcache_port = RequestPort("Data Port") instTraceFile = Param.String("", "Instruction trace file") dataTraceFile = Param.String("", "Data dependency trace file") sizeStoreBuffer = Param.Unsigned( diff --git a/src/cpu/trace/trace_cpu.cc b/src/cpu/trace/trace_cpu.cc index 7399cf6199..ab14c8784a 100644 --- a/src/cpu/trace/trace_cpu.cc +++ b/src/cpu/trace/trace_cpu.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 - 2016 ARM Limited + * Copyright (c) 2013 - 2016, 2023 Arm Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -47,7 +47,8 @@ namespace gem5 int TraceCPU::numTraceCPUs = 0; TraceCPU::TraceCPU(const TraceCPUParams ¶ms) - : BaseCPU(params), + : ClockedObject(params), + cacheLineSize(params.system->cacheLineSize()), icachePort(this), dcachePort(this), instRequestorID(params.system->getRequestorId(this, "inst")), @@ -109,7 +110,7 @@ TraceCPU::init() DPRINTF(TraceCPUData, "Data memory request trace file is \"%s\".\n", dataTraceFile); - BaseCPU::init(); + ClockedObject::init(); // Get the send tick of the first instruction read request Tick first_icache_tick = icacheGen.init(); @@ -176,7 +177,7 @@ TraceCPU::schedDcacheNext() DPRINTF(TraceCPUData, "DcacheGen event.\n"); // Update stat for numCycles - baseStats.numCycles = clockEdge() / clockPeriod(); + traceStats.numCycles = clockEdge() / clockPeriod(); dcacheGen.execute(); if (dcacheGen.isExecComplete()) { @@ -216,7 +217,7 @@ TraceCPU::checkAndSchedExitEvent() ADD_STAT(cpi, statistics::units::Rate< statistics::units::Cycle, statistics::units::Count>::get(), "Cycles per micro-op used as a proxy for CPI", - trace->baseStats.numCycles / numOps) + trace->traceStats.numCycles / numOps) { cpi.precision(6); } @@ -591,7 +592,7 @@ TraceCPU::ElasticDataGen::executeMemReq(GraphNode* node_ptr) // stat counting this is useful to keep a check on how frequently this // happens. If required the code could be revised to mimick splitting such // a request into two. - unsigned blk_size = owner.cacheLineSize(); + unsigned blk_size = owner.cacheLineSize; Addr blk_offset = (node_ptr->physAddr & (Addr)(blk_size - 1)); if (!(blk_offset + node_ptr->size <= blk_size)) { node_ptr->size = blk_size - blk_offset; @@ -1152,6 +1153,20 @@ TraceCPU::schedDcacheNextEvent(Tick when) } +Port & +TraceCPU::getPort(const std::string &if_name, PortID idx) +{ + // Get the right port based on name. This applies to all the + // subclasses of the base CPU and relies on their implementation + // of getDataPort and getInstPort. + if (if_name == "dcache_port") + return getDataPort(); + else if (if_name == "icache_port") + return getInstPort(); + else + return ClockedObject::getPort(if_name, idx); +} + bool TraceCPU::IcachePort::recvTimingResp(PacketPtr pkt) { diff --git a/src/cpu/trace/trace_cpu.hh b/src/cpu/trace/trace_cpu.hh index 87f820fe6d..f3f5c38786 100644 --- a/src/cpu/trace/trace_cpu.hh +++ b/src/cpu/trace/trace_cpu.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 - 2016 ARM Limited + * Copyright (c) 2013 - 2016, 2023 Arm Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -48,10 +48,13 @@ #include "cpu/base.hh" #include "debug/TraceCPUData.hh" #include "debug/TraceCPUInst.hh" +#include "mem/packet.hh" +#include "mem/request.hh" #include "params/TraceCPU.hh" #include "proto/inst_dep_record.pb.h" #include "proto/packet.pb.h" #include "proto/protoio.hh" +#include "sim/clocked_object.hh" #include "sim/sim_events.hh" namespace gem5 @@ -66,8 +69,7 @@ namespace gem5 * simulation compared to the detailed cpu model and good correlation when the * same trace is used for playback on different memory sub-systems. * - * The TraceCPU inherits from BaseCPU so some virtual methods need to be - * defined. It has two port subclasses inherited from RequestPort for + * The TraceCPU has two port subclasses inherited from RequestPort for * instruction and data ports. It issues the memory requests deducing the * timing from the trace and without performing real execution of micro-ops. As * soon as the last dependency for an instruction is complete, its @@ -139,7 +141,7 @@ namespace gem5 * exit. */ -class TraceCPU : public BaseCPU +class TraceCPU : public ClockedObject { public: @@ -147,15 +149,6 @@ class TraceCPU : public BaseCPU void init(); - /** - * This is a pure virtual function in BaseCPU. As we don't know how many - * insts are in the trace but only know how how many micro-ops are we - * cannot count this stat. - * - * @return 0 - */ - Counter totalInsts() const { return 0; } - /** * Return totalOps as the number of committed micro-ops plus the * speculatively issued loads that are modelled in the TraceCPU replay. @@ -170,9 +163,6 @@ class TraceCPU : public BaseCPU */ void updateNumOps(uint64_t rob_num); - /* Pure virtual function in BaseCPU. Do nothing. */ - void wakeup(ThreadID tid=0) { return; } - /* * When resuming from checkpoint in FS mode, the TraceCPU takes over from * the old cpu. This function overrides the takeOverFrom() function in the @@ -303,6 +293,9 @@ class TraceCPU : public BaseCPU TraceCPU* owner; }; + /** Cache the cache line size that we get from the system */ + const unsigned int cacheLineSize; + /** Port to connect to L1 instruction cache. */ IcachePort icachePort; @@ -1112,6 +1105,8 @@ class TraceCPU : public BaseCPU /** Stat for number of simulated micro-ops. */ statistics::Scalar numOps; + /** Number of CPU cycles simulated */ + statistics::Scalar numCycles; /** Stat for the CPI. This is really cycles per * micro-op and not inst. */ statistics::Formula cpi; @@ -1125,6 +1120,18 @@ class TraceCPU : public BaseCPU /** Used to get a reference to the dcache port. */ Port &getDataPort() { return dcachePort; } + /** + * Get a port on this CPU. All CPUs have a data and + * instruction port, and this method uses getDataPort and + * getInstPort of the subclasses to resolve the two ports. + * + * @param if_name the port name + * @param idx ignored index + * + * @return a reference to the port with the given name + */ + Port &getPort(const std::string &if_name, + PortID idx=InvalidPortID) override; }; } // namespace gem5