sim: Make clock private and access using clockPeriod()

This patch makes the clock member private to the ClockedObject and
forces all children to access it using clockPeriod(). This makes it
impossible to inadvertently change the clock, and also makes it easier
to transition to a situation where the clock is derived from e.g. a
clock domain, or through a multiplier.
This commit is contained in:
Andreas Hansson 2013-02-19 05:56:06 -05:00
parent 5c7ebee434
commit 7cd49b24d2
12 changed files with 49 additions and 57 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2011 ARM Limited
* Copyright (c) 2010-2013 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@ -58,7 +58,6 @@ CpuLocalTimer::CpuLocalTimer(Params *p)
localTimer[i].parent = this;
localTimer[i].intNumTimer = p->int_num_timer;
localTimer[i].intNumWatchdog = p->int_num_watchdog;
localTimer[i].clock = clock;
localTimer[i].cpuNum = i;
}
pioSize = 0x38;
@ -104,9 +103,11 @@ CpuLocalTimer::Timer::read(PacketPtr pkt, Addr daddr)
break;
case TimerCounterReg:
DPRINTF(Timer, "Event schedule for timer %d, clock=%d, prescale=%d\n",
timerZeroEvent.when(), clock, timerControl.prescalar);
timerZeroEvent.when(), parent->clockPeriod(),
timerControl.prescalar);
time = timerZeroEvent.when() - curTick();
time = time / clock / power(16, timerControl.prescalar);
time = time / parent->clockPeriod() /
power(16, timerControl.prescalar);
DPRINTF(Timer, "-- returning counter at %d\n", time);
pkt->set<uint32_t>(time);
break;
@ -120,10 +121,13 @@ CpuLocalTimer::Timer::read(PacketPtr pkt, Addr daddr)
pkt->set<uint32_t>(watchdogLoadValue);
break;
case WatchdogCounterReg:
DPRINTF(Timer, "Event schedule for watchdog %d, clock=%d, prescale=%d\n",
watchdogZeroEvent.when(), clock, watchdogControl.prescalar);
DPRINTF(Timer,
"Event schedule for watchdog %d, clock=%d, prescale=%d\n",
watchdogZeroEvent.when(), parent->clockPeriod(),
watchdogControl.prescalar);
time = watchdogZeroEvent.when() - curTick();
time = time / clock / power(16, watchdogControl.prescalar);
time = time / parent->clockPeriod() /
power(16, watchdogControl.prescalar);
DPRINTF(Timer, "-- returning counter at %d\n", time);
pkt->set<uint32_t>(time);
break;
@ -249,7 +253,7 @@ CpuLocalTimer::Timer::restartTimerCounter(uint32_t val)
if (!timerControl.enable)
return;
Tick time = clock * power(16, timerControl.prescalar);
Tick time = parent->clockPeriod() * power(16, timerControl.prescalar);
time *= val;
if (timerZeroEvent.scheduled()) {
@ -267,7 +271,7 @@ CpuLocalTimer::Timer::restartWatchdogCounter(uint32_t val)
if (!watchdogControl.enable)
return;
Tick time = clock * power(16, watchdogControl.prescalar);
Tick time = parent->clockPeriod() * power(16, watchdogControl.prescalar);
time *= val;
if (watchdogZeroEvent.scheduled()) {

View file

@ -103,9 +103,6 @@ class CpuLocalTimer : public BasicPioDevice
/** Cpu this timer is attached to */
uint32_t cpuNum;
/** Number of ticks in a clock input */
Tick clock;
/** Control register as specified above */
TimerCtrl timerControl;
WatchdogCtrl watchdogControl;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011-2012 ARM Limited
* Copyright (c) 2011-2013 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@ -132,37 +132,33 @@ BaseBus::getSlavePort(const std::string &if_name, PortID idx)
Tick
BaseBus::calcPacketTiming(PacketPtr pkt)
{
// determine the current time rounded to the closest following
// determine the header time rounded to the closest following
// clock edge
Tick now = nextCycle();
Tick headerTime = now + headerCycles * clock;
Tick headerTime = clockEdge(headerCycles);
// The packet will be sent. Figure out how long it occupies the bus, and
// how much of that time is for the first "word", aka bus width.
int numCycles = 0;
Cycles numCycles(0);
if (pkt->hasData()) {
// If a packet has data, it needs ceil(size/width) cycles to send it
int dataSize = pkt->getSize();
numCycles += dataSize/width;
if (dataSize % width)
numCycles++;
unsigned dataSize = pkt->getSize();
numCycles = Cycles(divCeil(dataSize, width));
}
// The first word will be delivered after the current tick, the delivery
// of the address if any, and one bus cycle to deliver the data
pkt->firstWordTime = headerTime + clock;
// The first word will be delivered on the cycle after the header.
pkt->firstWordTime = headerTime + clockPeriod();
pkt->finishTime = headerTime + numCycles * clock;
// Note that currently finishTime can be smaller than
// firstWordTime if the packet has no data
pkt->finishTime = headerTime + numCycles * clockPeriod();
return headerTime;
}
template <typename PortClass>
BaseBus::Layer<PortClass>::Layer(BaseBus& _bus, const std::string& _name,
Tick _clock) :
BaseBus::Layer<PortClass>::Layer(BaseBus& _bus, const std::string& _name) :
Drainable(),
bus(_bus), _name(_name), state(IDLE), clock(_clock), drainManager(NULL),
bus(_bus), _name(_name), state(IDLE), drainManager(NULL),
releaseEvent(this)
{
}
@ -306,11 +302,8 @@ BaseBus::Layer<PortClass>::retryWaiting()
// snoop responses
state = BUSY;
// determine the current time rounded to the closest following
// clock edge
Tick now = bus.nextCycle();
occupyLayer(now + clock);
// occupy the bus layer until the next cycle ends
occupyLayer(bus.clockEdge(Cycles(1)));
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011-2012 ARM Limited
* Copyright (c) 2011-2013 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@ -105,9 +105,8 @@ class BaseBus : public MemObject
*
* @param _bus the bus this layer belongs to
* @param _name the layer's name
* @param _clock clock period in ticks
*/
Layer(BaseBus& _bus, const std::string& _name, Tick _clock);
Layer(BaseBus& _bus, const std::string& _name);
/**
* Drain according to the normal semantics, so that the bus
@ -203,9 +202,6 @@ class BaseBus : public MemObject
/** track the state of the bus layer */
State state;
/** the clock speed for the bus layer */
Tick clock;
/** manager to signal when drained */
DrainManager *drainManager;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2012 ARM Limited
* Copyright (c) 2010-2013 ARM Limited
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
@ -898,7 +898,7 @@ Cache<TagStore>::handleResponse(PacketPtr pkt)
// responseLatency is the latency of the return path
// from lower level caches/memory to an upper level cache or
// the core.
completion_time = responseLatency * clock +
completion_time = responseLatency * clockPeriod() +
(transfer_offset ? pkt->finishTime : pkt->firstWordTime);
assert(!target->pkt->req->isUncacheable());
@ -914,13 +914,15 @@ Cache<TagStore>::handleResponse(PacketPtr pkt)
// responseLatency is the latency of the return path
// from lower level caches/memory to an upper level cache or
// the core.
completion_time = responseLatency * clock + pkt->finishTime;
completion_time = responseLatency * clockPeriod() +
pkt->finishTime;
target->pkt->req->setExtraData(0);
} else {
// not a cache fill, just forwarding response
// responseLatency is the latency of the return path
// from lower level cahces/memory to the core.
completion_time = responseLatency * clock + pkt->finishTime;
completion_time = responseLatency * clockPeriod() +
pkt->finishTime;
if (pkt->isRead() && !is_error) {
target->pkt->setData(pkt->getPtr<uint8_t>());
}

View file

@ -241,7 +241,7 @@ BasePrefetcher::notify(PacketPtr &pkt, Tick time)
prefetch->req->setThreadContext(pkt->req->contextId(),
pkt->req->threadId());
prefetch->time = time + clock * *delayIter;
prefetch->time = time + clockPeriod() * *delayIter;
// We just remove the head if we are full
if (pf.size() == size) {

View file

@ -55,9 +55,9 @@
#include "sim/system.hh"
CoherentBus::CoherentBus(const CoherentBusParams *p)
: BaseBus(p), reqLayer(*this, ".reqLayer", p->clock),
respLayer(*this, ".respLayer", p->clock),
snoopRespLayer(*this, ".snoopRespLayer", p->clock),
: BaseBus(p), reqLayer(*this, ".reqLayer"),
respLayer(*this, ".respLayer"),
snoopRespLayer(*this, ".snoopRespLayer"),
system(p->system)
{
// create the ports based on the size of the master and slave

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011-2012 ARM Limited
* Copyright (c) 2011-2013 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011-2012 ARM Limited
* Copyright (c) 2011-2013 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@ -55,8 +55,8 @@
#include "mem/noncoherent_bus.hh"
NoncoherentBus::NoncoherentBus(const NoncoherentBusParams *p)
: BaseBus(p), reqLayer(*this, ".reqLayer", p->clock),
respLayer(*this, ".respLayer", p->clock)
: BaseBus(p), reqLayer(*this, ".reqLayer"),
respLayer(*this, ".respLayer")
{
// create the ports based on the size of the master and slave
// vector ports, and the presence of the default port, the ports

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011-2012 ARM Limited
* Copyright (c) 2011-2013 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall

View file

@ -557,7 +557,7 @@ RubyMemoryControl::issueRequest(int bank)
bank, m_event.scheduled() ? 'Y':'N');
if (req.m_msgptr) { // don't enqueue L3 writebacks
enqueueToDirectory(req, m_mem_ctl_latency + m_mem_fixed_delay);
enqueueToDirectory(req, Cycles(m_mem_ctl_latency + m_mem_fixed_delay));
}
m_oldRequest[bank] = 0;
markTfaw(rank);
@ -702,7 +702,7 @@ RubyMemoryControl::wakeup()
m_idleCount--;
if (m_idleCount > 0) {
assert(!m_event.scheduled());
schedule(m_event, curTick() + clock);
schedule(m_event, clockEdge(Cycles(1)));
}
}

View file

@ -103,11 +103,11 @@ class ClockedObject : public SimObject
tick += elapsedCycles * clock;
}
protected:
// Clock period in ticks
Tick clock;
protected:
/**
* Create a clocked object and set the clock based on the
* parameters.