changeset ed91b534ed04 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=ed91b534ed04
description:
CPU: Round-two unifying instr/data CPU ports across models
This patch continues the unification of how the different CPU models
create and share their instruction and data ports. Most importantly,
it forces every CPU to have an instruction and a data port, and gives
these ports explicit getters in the BaseCPU (getDataPort and
getInstPort). The patch helps in simplifying the code, make
assumptions more explicit, andfurther ease future patches related to
the CPU ports.
The biggest changes are in the in-order model (that was not modified
in the previous unification patch), which now moves the ports from the
CacheUnit to the CPU. It also distinguishes the instruction fetch and
load-store unit from the rest of the resources, and avoids the use of
indices and casting in favour of keeping track of these two units
explicitly (since they are always there anyways). The atomic, timing
and O3 model simply return references to their already existing ports.
diffstat:
src/cpu/base.cc | 35 +++++++++---
src/cpu/base.hh | 35 ++++++++++++-
src/cpu/base_dyn_inst.hh | 2 +-
src/cpu/inorder/InOrderCPU.py | 3 -
src/cpu/inorder/cpu.cc | 91 ++++++++++++++++++--------------
src/cpu/inorder/cpu.hh | 78 ++++++++++++++++++++-------
src/cpu/inorder/resource.hh | 6 --
src/cpu/inorder/resource_pool.9stage.cc | 61 +++++++++------------
src/cpu/inorder/resource_pool.cc | 86 +++++++++----------------------
src/cpu/inorder/resource_pool.hh | 48 ++++++++++++----
src/cpu/inorder/resources/cache_unit.cc | 76 ++++++---------------------
src/cpu/inorder/resources/cache_unit.hh | 38 +-------------
src/cpu/o3/cpu.cc | 12 ----
src/cpu/o3/cpu.hh | 7 +-
src/cpu/o3/fetch_impl.hh | 8 +-
src/cpu/o3/iew_impl.hh | 2 +-
src/cpu/o3/lsq_impl.hh | 2 +-
src/cpu/simple/atomic.cc | 10 +--
src/cpu/simple/atomic.hh | 12 ++++
src/cpu/simple/base.hh | 1 -
src/cpu/simple/timing.cc | 11 ---
src/cpu/simple/timing.hh | 10 ++-
src/cpu/thread_state.cc | 2 +-
src/kern/tru64/tru64_events.cc | 4 +-
src/mem/fs_translating_port_proxy.cc | 2 +-
25 files changed, 308 insertions(+), 334 deletions(-)
diffs (truncated from 1227 to 300 lines):
diff -r 6c15fa5fe377 -r ed91b534ed04 src/cpu/base.cc
--- a/src/cpu/base.cc Fri Feb 24 11:40:29 2012 -0500
+++ b/src/cpu/base.cc Fri Feb 24 11:42:00 2012 -0500
@@ -296,6 +296,21 @@
threadContexts[0]->regStats(name());
}
+Port *
+BaseCPU::getPort(const string &if_name, int 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. In all cases there methods
+ // return a CpuPort pointer.
+ if (if_name == "dcache_port")
+ return &getDataPort();
+ else if (if_name == "icache_port")
+ return &getInstPort();
+ else
+ panic("CPU %s has no port named %s\n", name(), if_name);
+}
+
Tick
BaseCPU::nextCycle()
{
@@ -363,8 +378,8 @@
void
BaseCPU::takeOverFrom(BaseCPU *oldCPU)
{
- Port *ic = getPort("icache_port");
- Port *dc = getPort("dcache_port");
+ CpuPort &ic = getInstPort();
+ CpuPort &dc = getDataPort();
assert(threadContexts.size() == oldCPU->threadContexts.size());
_cpuId = oldCPU->cpuId();
@@ -453,16 +468,16 @@
// Connect new CPU to old CPU's memory only if new CPU isn't
// connected to anything. Also connect old CPU's memory to new
// CPU.
- if (!ic->isConnected()) {
- Port *peer = oldCPU->getPort("icache_port")->getPeer();
- ic->setPeer(peer);
- peer->setPeer(ic);
+ if (!ic.isConnected()) {
+ Port *peer = oldCPU->getInstPort().getPeer();
+ ic.setPeer(peer);
+ peer->setPeer(&ic);
}
- if (!dc->isConnected()) {
- Port *peer = oldCPU->getPort("dcache_port")->getPeer();
- dc->setPeer(peer);
- peer->setPeer(dc);
+ if (!dc.isConnected()) {
+ Port *peer = oldCPU->getDataPort().getPeer();
+ dc.setPeer(peer);
+ peer->setPeer(&dc);
}
}
diff -r 6c15fa5fe377 -r ed91b534ed04 src/cpu/base.hh
--- a/src/cpu/base.hh Fri Feb 24 11:40:29 2012 -0500
+++ b/src/cpu/base.hh Fri Feb 24 11:42:00 2012 -0500
@@ -63,7 +63,6 @@
class CheckerCPU;
class ThreadContext;
class System;
-class Port;
namespace TheISA
{
@@ -147,6 +146,23 @@
};
public:
+
+ /**
+ * Purely virtual method that returns a reference to the data
+ * port. All subclasses must implement this method.
+ *
+ * @return a reference to the data port
+ */
+ virtual CpuPort &getDataPort() = 0;
+
+ /**
+ * Purely virtual method that returns a reference to the instruction
+ * port. All subclasses must implement this method.
+ *
+ * @return a reference to the instruction port
+ */
+ virtual CpuPort &getInstPort() = 0;
+
/** Reads this CPU's ID. */
int cpuId() { return _cpuId; }
@@ -155,6 +171,23 @@
/** Reads this CPU's unique instruction requestor ID */
MasterID instMasterId() { return _instMasterId; }
+ /**
+ * Get a port on this MemObject. This method is virtual to allow
+ * the subclasses of the BaseCPU to override it. All CPUs have a
+ * data and instruction port, but the Atomic CPU (in its current
+ * form) adds a port directly connected to the memory and has to
+ * override getPort.
+ *
+ * This method uses getDataPort and getInstPort to resolve the two
+ * ports.
+ *
+ * @param if_name the port name
+ * @param idx ignored index
+ *
+ * @return a pointer to the port with the given name
+ */
+ virtual Port *getPort(const std::string &if_name, int idx = -1);
+
// Tick currentTick;
inline Tick frequency() const { return SimClock::Frequency / clock; }
inline Tick ticks(int numCycles) const { return clock * numCycles; }
diff -r 6c15fa5fe377 -r ed91b534ed04 src/cpu/base_dyn_inst.hh
--- a/src/cpu/base_dyn_inst.hh Fri Feb 24 11:40:29 2012 -0500
+++ b/src/cpu/base_dyn_inst.hh Fri Feb 24 11:42:00 2012 -0500
@@ -975,7 +975,7 @@
RequestPtr &sreqHigh)
{
// Check to see if the request crosses the next level block boundary.
- unsigned block_size = cpu->getDcachePort()->peerBlockSize();
+ unsigned block_size = cpu->getDataPort().peerBlockSize();
Addr addr = req->getVaddr();
Addr split_addr = roundDown(addr + req->getSize() - 1, block_size);
assert(split_addr <= addr || split_addr - addr < block_size);
diff -r 6c15fa5fe377 -r ed91b534ed04 src/cpu/inorder/InOrderCPU.py
--- a/src/cpu/inorder/InOrderCPU.py Fri Feb 24 11:40:29 2012 -0500
+++ b/src/cpu/inorder/InOrderCPU.py Fri Feb 24 11:42:00 2012 -0500
@@ -42,9 +42,6 @@
cachePorts = Param.Unsigned(2, "Cache Ports")
stageWidth = Param.Unsigned(4, "Stage width")
- fetchMemPort = Param.String("icache_port" , "Name of Memory Port to get
instructions from")
- dataMemPort = Param.String("dcache_port" , "Name of Memory Port to get
data from")
-
fetchBuffSize = Param.Unsigned(4, "Fetch Buffer Size (Number of Cache
Blocks Stored)")
memBlockSize = Param.Unsigned(64, "Memory Block Size")
diff -r 6c15fa5fe377 -r ed91b534ed04 src/cpu/inorder/cpu.cc
--- a/src/cpu/inorder/cpu.cc Fri Feb 24 11:40:29 2012 -0500
+++ b/src/cpu/inorder/cpu.cc Fri Feb 24 11:42:00 2012 -0500
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2012 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2007 MIPS Technologies, Inc.
* All rights reserved.
*
@@ -34,6 +46,7 @@
#include "arch/utility.hh"
#include "base/bigint.hh"
#include "config/the_isa.hh"
+#include "cpu/inorder/resources/cache_unit.hh"
#include "cpu/inorder/resources/resource_list.hh"
#include "cpu/inorder/cpu.hh"
#include "cpu/inorder/first_stage.hh"
@@ -50,10 +63,11 @@
#include "cpu/thread_context.hh"
#include "debug/Activity.hh"
#include "debug/InOrderCPU.hh"
+#include "debug/InOrderCachePort.hh"
#include "debug/Interrupt.hh"
+#include "debug/Quiesce.hh"
#include "debug/RefCount.hh"
#include "debug/SkedCache.hh"
-#include "debug/Quiesce.hh"
#include "params/InOrderCPU.hh"
#include "sim/full_system.hh"
#include "sim/process.hh"
@@ -68,6 +82,34 @@
using namespace TheISA;
using namespace ThePipeline;
+InOrderCPU::CachePort::CachePort(CacheUnit *_cacheUnit) :
+ CpuPort(_cacheUnit->name() + "-cache-port", _cacheUnit->cpu),
+ cacheUnit(_cacheUnit)
+{ }
+
+bool
+InOrderCPU::CachePort::recvTiming(Packet *pkt)
+{
+ if (pkt->isError())
+ DPRINTF(InOrderCachePort, "Got error packet back for address: %x\n",
+ pkt->getAddr());
+ else if (pkt->isResponse())
+ cacheUnit->processCacheCompletion(pkt);
+ else {
+ //@note: depending on consistency model, update here
+ DPRINTF(InOrderCachePort, "Received snoop pkt %x,Ignoring\n",
+ pkt->getAddr());
+ }
+
+ return true;
+}
+
+void
+InOrderCPU::CachePort::recvRetry()
+{
+ cacheUnit->recvRetry();
+}
+
InOrderCPU::TickEvent::TickEvent(InOrderCPU *c)
: Event(CPU_Tick_Pri), cpu(c)
{ }
@@ -191,7 +233,10 @@
_status(Idle),
tickEvent(this),
stageWidth(params->stageWidth),
+ resPool(new ResourcePool(this, params)),
timeBuffer(2 , 2),
+ dataPort(resPool->getDataUnit()),
+ instPort(resPool->getInstUnit()),
removeInstsThisCycle(false),
activityRec(params->name, NumStages, 10, params->activity),
system(params->system),
@@ -207,8 +252,6 @@
{
cpu_params = params;
- resPool = new ResourcePool(this, params);
-
// Resize for Multithreading CPUs
thread.resize(numThreads);
@@ -240,17 +283,6 @@
}
}
- // Bind the fetch & data ports from the resource pool.
- fetchPortIdx = resPool->getPortIdx(params->fetchMemPort);
- if (fetchPortIdx == 0) {
- fatal("Unable to find port to fetch instructions from.\n");
- }
-
- dataPortIdx = resPool->getPortIdx(params->dataMemPort);
- if (dataPortIdx == 0) {
- fatal("Unable to find port for data.\n");
- }
-
for (ThreadID tid = 0; tid < numThreads; ++tid) {
pc[tid].set(0);
lastCommittedPC[tid].set(0);
@@ -775,12 +807,6 @@
resPool->init();
}
-Port*
-InOrderCPU::getPort(const std::string &if_name, int idx)
-{
- return resPool->getPort(if_name, idx);
-}
-
Fault
InOrderCPU::hwrei(ThreadID tid)
{
@@ -1735,8 +1761,7 @@
TheISA::TLB*
InOrderCPU::getITBPtr()
{
- CacheUnit *itb_res =
- dynamic_cast<CacheUnit*>(resPool->getResource(fetchPortIdx));
+ CacheUnit *itb_res = resPool->getInstUnit();
return itb_res->tlb();
}
@@ -1744,38 +1769,26 @@
TheISA::TLB*
InOrderCPU::getDTBPtr()
{
- CacheUnit *dtb_res =
- dynamic_cast<CacheUnit*>(resPool->getResource(dataPortIdx));
- return dtb_res->tlb();
+ return resPool->getDataUnit()->tlb();
}
Decoder *
InOrderCPU::getDecoderPtr()
{
- FetchUnit *fetch_res =
- dynamic_cast<FetchUnit*>(resPool->getResource(fetchPortIdx));
- return &fetch_res->decoder;
+ return &resPool->getInstUnit()->decoder;
}
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev