ruby: Resurrected Ruby's deterministic tests

Added the request series and invalidate deterministic tests as new cpu models
and removed the no longer needed ruby tests

--HG--
rename : configs/example/rubytest.py => configs/example/determ_test.py
rename : src/mem/ruby/tester/DetermGETXGenerator.cc => src/cpu/directedtest/DirectedGenerator.cc
rename : src/mem/ruby/tester/DetermGETXGenerator.hh => src/cpu/directedtest/DirectedGenerator.hh
rename : src/mem/ruby/tester/DetermGETXGenerator.cc => src/cpu/directedtest/InvalidateGenerator.cc
rename : src/mem/ruby/tester/DetermGETXGenerator.hh => src/cpu/directedtest/InvalidateGenerator.hh
rename : src/cpu/rubytest/RubyTester.cc => src/cpu/directedtest/RubyDirectedTester.cc
rename : src/cpu/rubytest/RubyTester.hh => src/cpu/directedtest/RubyDirectedTester.hh
rename : src/mem/ruby/tester/DetermGETXGenerator.cc => src/cpu/directedtest/SeriesRequestGenerator.cc
rename : src/mem/ruby/tester/DetermGETXGenerator.hh => src/cpu/directedtest/SeriesRequestGenerator.hh
This commit is contained in:
Brad Beckmann 2010-08-20 11:46:13 -07:00
parent 984adf198a
commit 6a4f99899b
19 changed files with 971 additions and 898 deletions

View file

@ -0,0 +1,126 @@
# Copyright (c) 2006-2007 The Regents of The University of Michigan
# Copyright (c) 2009 Advanced Micro Devices, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Ron Dreslinski
# Brad Beckmann
import m5
from m5.objects import *
from m5.defines import buildEnv
from m5.util import addToPath
import os, optparse, sys
addToPath('../common')
addToPath('../ruby')
import Ruby
if buildEnv['FULL_SYSTEM']:
panic("This script requires system-emulation mode (*_SE).")
# Get paths we might need. It's expected this file is in m5/configs/example.
config_path = os.path.dirname(os.path.abspath(__file__))
config_root = os.path.dirname(config_path)
m5_root = os.path.dirname(config_root)
parser = optparse.OptionParser()
parser.add_option("-l", "--requests", metavar="N", default=100,
help="Stop after N requests")
parser.add_option("-f", "--wakeup_freq", metavar="N", default=10,
help="Wakeup every N cycles")
parser.add_option("--test-type", type="string", default="SeriesGetx",
help="SeriesGetx|SeriesGets|Invalidate")
#
# Add the ruby specific and protocol specific options
#
Ruby.define_options(parser)
execfile(os.path.join(config_root, "common", "Options.py"))
(options, args) = parser.parse_args()
if args:
print "Error: script doesn't take any positional arguments"
sys.exit(1)
#
# Select the directed generator
#
if options.test_type == "SeriesGetx":
generator = SeriesRequestGenerator(num_cpus = options.num_cpus,
issue_writes = True)
elif options.test_type == "SeriesGets":
generator = SeriesRequestGenerator(num_cpus = options.num_cpus,
issue_writes = False)
elif options.test_type == "Invalidate":
generator = InvalidateGenerator(num_cpus = options.num_cpus)
else:
print "Error: unknown directed generator"
sys.exit(1)
#
# Create the M5 system. Note that the PhysicalMemory Object isn't
# actually used by the rubytester, but is included to support the
# M5 memory size == Ruby memory size checks
#
system = System(physmem = PhysicalMemory())
#
# Create the ruby random tester
#
system.tester = RubyDirectedTester(requests_to_complete = \
options.requests,
generator = generator)
system.ruby = Ruby.create_system(options, system)
assert(options.num_cpus == len(system.ruby.cpu_ruby_ports))
for ruby_port in system.ruby.cpu_ruby_ports:
#
# Tie the ruby tester ports to the ruby cpu ports
#
system.tester.cpuPort = ruby_port.port
# -----------------------
# run simulation
# -----------------------
root = Root( system = system )
root.system.mem_mode = 'timing'
# Not much point in this being higher than the L1 latency
m5.ticks.setGlobalFrequency('1ns')
# instantiate configuration
m5.instantiate()
# simulate until program terminates
exit_event = m5.simulate(options.maxtick)
print 'Exiting @ tick', m5.curTick(), 'because', exit_event.getCause()

View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* Copyright (c) 2009-2010 Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "cpu/directedtest/DirectedGenerator.hh"
DirectedGenerator::DirectedGenerator(const Params *p)
: SimObject(p)
{
m_num_cpus = p->num_cpus;
m_directed_tester = NULL;
}
void
DirectedGenerator::setDirectedTester(RubyDirectedTester* directed_tester)
{
assert(m_directed_tester == NULL);
m_directed_tester = directed_tester;
}

View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __CPU_DIRECTEDTEST_DIRECTEDGENERATOR_HH__
#define __CPU_DIRECTEDTEST_DIRECTEDGENERATOR_HH__
#include "cpu/directedtest/DirectedGenerator.hh"
#include "cpu/directedtest/RubyDirectedTester.hh"
#include "params/DirectedGenerator.hh"
#include "sim/sim_object.hh"
class DirectedGenerator : public SimObject
{
public:
typedef DirectedGeneratorParams Params;
DirectedGenerator(const Params *p);
virtual ~DirectedGenerator() {}
virtual bool initiate() = 0;
virtual void performCallback(uint proc, Addr address) = 0;
void setDirectedTester(RubyDirectedTester* directed_tester);
protected:
int m_num_cpus;
RubyDirectedTester* m_directed_tester;
};
#endif //__CPU_DIRECTEDTEST_DIRECTEDGENERATOR_HH__

View file

@ -0,0 +1,142 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* Copyright (c) 2009-2010 Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "cpu/directedtest/RubyDirectedTester.hh"
#include "cpu/directedtest/DirectedGenerator.hh"
#include "cpu/directedtest/InvalidateGenerator.hh"
InvalidateGenerator::InvalidateGenerator(const Params *p)
: DirectedGenerator(p)
{
//
// First, issue loads to bring the block into S state
//
m_status = InvalidateGeneratorStatus_Load_Waiting;
m_active_read_node = 0;
m_active_inv_node = 0;
m_address = 0x0;
m_addr_increment_size = p->addr_increment_size;
}
InvalidateGenerator::~InvalidateGenerator()
{
}
bool
InvalidateGenerator::initiate()
{
RubyDirectedTester::CpuPort* port;
Request::Flags flags;
PacketPtr pkt;
Packet::Command cmd;
// For simplicity, requests are assumed to be 1 byte-sized
Request *req = new Request(m_address, 1, flags);
//
// Based on the current state, issue a load or a store
//
if (m_status == InvalidateGeneratorStatus_Load_Waiting) {
DPRINTF(DirectedTest, "initiating read\n");
cmd = MemCmd::ReadReq;
port = safe_cast<RubyDirectedTester::CpuPort*>(m_directed_tester->
getCpuPort(m_active_read_node));
pkt = new Packet(req, cmd, m_active_read_node);
} else if (m_status == InvalidateGeneratorStatus_Inv_Waiting) {
DPRINTF(DirectedTest, "initiating invalidating write\n");
cmd = MemCmd::WriteReq;
port = safe_cast<RubyDirectedTester::CpuPort*>(m_directed_tester->
getCpuPort(m_active_inv_node));
pkt = new Packet(req, cmd, m_active_inv_node);
} else {
panic("initiate was unexpectedly called\n");
}
uint8_t* dummyData = new uint8_t;
*dummyData = 0;
pkt->dataDynamic(dummyData);
if (port->sendTiming(pkt)) {
DPRINTF(DirectedTest, "initiating request - successful\n");
if (m_status == InvalidateGeneratorStatus_Load_Waiting) {
m_status = InvalidateGeneratorStatus_Load_Pending;
} else {
m_status = InvalidateGeneratorStatus_Inv_Pending;
}
return true;
} else {
// If the packet did not issue, must delete
// Note: No need to delete the data, the packet destructor
// will delete it
delete pkt->req;
delete pkt;
DPRINTF(DirectedTest, "failed to issue request - sequencer not ready\n");
return false;
}
}
void
InvalidateGenerator::performCallback(uint proc, Addr address)
{
assert(m_address == address);
if (m_status == InvalidateGeneratorStatus_Load_Pending) {
assert(m_active_read_node == proc);
m_active_read_node++;
//
// Once all cpus have the block in S state, issue the invalidate
//
if (m_active_read_node == m_num_cpus) {
m_status = InvalidateGeneratorStatus_Inv_Waiting;
m_active_read_node = 0;
} else {
m_status = InvalidateGeneratorStatus_Load_Waiting;
}
} else if (m_status == InvalidateGeneratorStatus_Inv_Pending) {
assert(m_active_inv_node == proc);
m_active_inv_node++;
if (m_active_inv_node == m_num_cpus) {
m_address += m_addr_increment_size;
m_active_inv_node = 0;
}
//
// Invalidate completed, send that info to the tester and restart
// the cycle
//
m_directed_tester->incrementCycleCompletions();
m_status = InvalidateGeneratorStatus_Load_Waiting;
}
}
InvalidateGenerator *
InvalidateGeneratorParams::create()
{
return new InvalidateGenerator(this);
}

View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//
// This Directed Generator generates GETX requests for all nodes in the
// system. The GETX requests are generated one at a time in round-robin fashion
// 0...1...2...etc.
//
#ifndef __CPU_DIRECTEDTEST_INVALIDATEGENERATOR_HH__
#define __CPU_DIRECTEDTEST_INVALIDATEGENERATOR_HH__
#include "cpu/directedtest/RubyDirectedTester.hh"
#include "cpu/directedtest/DirectedGenerator.hh"
#include "mem/protocol/InvalidateGeneratorStatus.hh"
#include "params/InvalidateGenerator.hh"
class InvalidateGenerator : public DirectedGenerator
{
public:
typedef InvalidateGeneratorParams Params;
InvalidateGenerator(const Params *p);
~InvalidateGenerator();
bool initiate();
void performCallback(uint proc, Addr address);
private:
InvalidateGeneratorStatus m_status;
Addr m_address;
uint m_active_read_node;
uint m_active_inv_node;
uint m_addr_increment_size;
};
#endif //__CPU_DIRECTEDTEST_INVALIDATEGENERATOR_HH__

View file

@ -0,0 +1,136 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* Copyright (c) 2009-2010 Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "cpu/directedtest/RubyDirectedTester.hh"
#include "cpu/directedtest/DirectedGenerator.hh"
#include "mem/ruby/eventqueue/RubyEventQueue.hh"
#include "sim/sim_exit.hh"
RubyDirectedTester::RubyDirectedTester(const Params *p)
: MemObject(p), directedStartEvent(this),
m_requests_to_complete(p->requests_to_complete),
generator(p->generator)
{
m_requests_completed = 0;
// add the check start event to the event queue
schedule(directedStartEvent, 1);
}
RubyDirectedTester::~RubyDirectedTester()
{
for (int i = 0; i < ports.size(); i++)
delete ports[i];
}
void
RubyDirectedTester::init()
{
assert(ports.size() > 0);
generator->setDirectedTester(this);
}
Port *
RubyDirectedTester::getPort(const std::string &if_name, int idx)
{
if (if_name != "cpuPort") {
panic("RubyDirectedTester::getPort: unknown port %s requested", if_name);
}
if (idx >= (int)ports.size()) {
ports.resize(idx + 1);
}
if (ports[idx] != NULL) {
panic("RubyDirectedTester::getPort: port %d already assigned", idx);
}
CpuPort *port = new CpuPort(csprintf("%s-port%d", name(), idx), this, idx);
ports[idx] = port;
return port;
}
Tick
RubyDirectedTester::CpuPort::recvAtomic(PacketPtr pkt)
{
panic("RubyDirectedTester::CpuPort::recvAtomic() not implemented!\n");
return 0;
}
bool
RubyDirectedTester::CpuPort::recvTiming(PacketPtr pkt)
{
tester->hitCallback(idx, pkt->getAddr());
//
// Now that the tester has completed, delete the packet, then return
//
delete pkt->req;
delete pkt;
return true;
}
Port*
RubyDirectedTester::getCpuPort(int idx)
{
assert(idx >= 0 && idx < ports.size());
return ports[idx];
}
void
RubyDirectedTester::hitCallback(NodeID proc, Addr addr)
{
DPRINTF(DirectedTest,
"completed request for proc: %d addr: 0x%x\n",
proc,
addr);
generator->performCallback(proc, addr);
schedule(directedStartEvent, curTick);
}
void
RubyDirectedTester::wakeup()
{
if (m_requests_completed < m_requests_to_complete) {
if (!generator->initiate()) {
schedule(directedStartEvent, curTick + 1);
}
} else {
exitSimLoop("Ruby DirectedTester completed");
}
}
RubyDirectedTester *
RubyDirectedTesterParams::create()
{
return new RubyDirectedTester(this);
}

View file

@ -0,0 +1,118 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* Copyright (c) 2009-2010 Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __CPU_DIRECTEDTEST_RUBYDIRECTEDTESTER_HH__
#define __CPU_DIRECTEDTEST_RUBYDIRECTEDTESTER_HH__
#include <iostream>
#include <vector>
#include <string>
#include "mem/mem_object.hh"
#include "mem/packet.hh"
#include "mem/ruby/common/DataBlock.hh"
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/common/SubBlock.hh"
#include "mem/ruby/system/RubyPort.hh"
#include "params/RubyDirectedTester.hh"
class DirectedGenerator;
class RubyDirectedTester : public MemObject
{
public:
class CpuPort : public SimpleTimingPort
{
private:
RubyDirectedTester *tester;
public:
CpuPort(const std::string &_name, RubyDirectedTester *_tester, uint _idx)
: SimpleTimingPort(_name, _tester), tester(_tester), idx(_idx)
{}
uint idx;
protected:
virtual bool recvTiming(PacketPtr pkt);
virtual Tick recvAtomic(PacketPtr pkt);
};
typedef RubyDirectedTesterParams Params;
RubyDirectedTester(const Params *p);
~RubyDirectedTester();
virtual Port *getPort(const std::string &if_name, int idx = -1);
Port* getCpuPort(int idx);
virtual void init();
void wakeup();
void incrementCycleCompletions() { m_requests_completed++; }
void printStats(std::ostream& out) const {}
void clearStats() {}
void printConfig(std::ostream& out) const {}
void print(std::ostream& out) const;
protected:
class DirectedStartEvent : public Event
{
private:
RubyDirectedTester *tester;
public:
DirectedStartEvent(RubyDirectedTester *_tester)
: Event(CPU_Tick_Pri), tester(_tester)
{}
void process() { tester->wakeup(); }
virtual const char *description() const { return "Directed tick"; }
};
DirectedStartEvent directedStartEvent;
private:
void hitCallback(NodeID proc, Addr addr);
void checkForDeadlock();
// Private copy constructor and assignment operator
RubyDirectedTester(const RubyDirectedTester& obj);
RubyDirectedTester& operator=(const RubyDirectedTester& obj);
uint64 m_requests_completed;
std::vector<CpuPort*> ports;
uint64 m_requests_to_complete;
DirectedGenerator* generator;
};
#endif // __CPU_DIRECTEDTEST_RUBYDIRECTEDTESTER_HH__

View file

@ -0,0 +1,52 @@
# Copyright (c) 2010 Advanced Micro Devices, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Brad Beckmann
from m5.SimObject import SimObject
from MemObject import MemObject
from m5.params import *
from m5.proxy import *
class DirectedGenerator(SimObject):
type = 'DirectedGenerator'
abstract = True
num_cpus = Param.Int("num of cpus")
class SeriesRequestGenerator(DirectedGenerator):
type = 'SeriesRequestGenerator'
addr_increment_size = Param.Int(64, "address increment size")
issue_writes = Param.Bool(True, "issue writes if true, otherwise reads")
class InvalidateGenerator(DirectedGenerator):
type = 'InvalidateGenerator'
addr_increment_size = Param.Int(64, "address increment size")
class RubyDirectedTester(MemObject):
type = 'RubyDirectedTester'
cpuPort = VectorPort("the cpu ports")
requests_to_complete = Param.Int("checks to complete")
generator = Param.DirectedGenerator("the request generator")

View file

@ -0,0 +1,48 @@
# -*- mode:python -*-
# Copyright (c) 2006 The Regents of The University of Michigan
# Copyright (c) 2009-2010 Advanced Micro Devices, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
Import('*')
#
# Currently the ruby testser relies on Ruby specific objects (SubBlock, etc.)
# When this dependency is removed, the ruby tester should be compiled
# independently from Ruby
#
if not env['RUBY']:
Return()
SimObject('RubyDirectedTester.py')
Source('RubyDirectedTester.cc')
Source('DirectedGenerator.cc')
Source('SeriesRequestGenerator.cc')
Source('InvalidateGenerator.cc')
TraceFlag('DirectedTest')

View file

@ -0,0 +1,114 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* Copyright (c) 2009-2010 Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "cpu/directedtest/RubyDirectedTester.hh"
#include "cpu/directedtest/DirectedGenerator.hh"
#include "cpu/directedtest/SeriesRequestGenerator.hh"
SeriesRequestGenerator::SeriesRequestGenerator(const Params *p)
: DirectedGenerator(p)
{
m_status = SeriesRequestGeneratorStatus_Thinking;
m_active_node = 0;
m_address = 0x0;
m_addr_increment_size = p->addr_increment_size;
m_issue_writes = p->issue_writes;
}
SeriesRequestGenerator::~SeriesRequestGenerator()
{
}
bool
SeriesRequestGenerator::initiate()
{
DPRINTF(DirectedTest, "initiating request\n");
assert(m_status == SeriesRequestGeneratorStatus_Thinking);
RubyDirectedTester::CpuPort* port =
safe_cast<RubyDirectedTester::CpuPort*>(m_directed_tester->
getCpuPort(m_active_node));
Request::Flags flags;
// For simplicity, requests are assumed to be 1 byte-sized
Request *req = new Request(m_address, 1, flags);
Packet::Command cmd;
if (m_issue_writes) {
cmd = MemCmd::WriteReq;
} else {
cmd = MemCmd::ReadReq;
}
PacketPtr pkt = new Packet(req, cmd, m_active_node);
uint8_t* dummyData = new uint8_t;
*dummyData = 0;
pkt->dataDynamic(dummyData);
if (port->sendTiming(pkt)) {
DPRINTF(DirectedTest, "initiating request - successful\n");
m_status = SeriesRequestGeneratorStatus_Request_Pending;
return true;
} else {
// If the packet did not issue, must delete
// Note: No need to delete the data, the packet destructor
// will delete it
delete pkt->req;
delete pkt;
DPRINTF(DirectedTest, "failed to initiate request - sequencer not ready\n");
return false;
}
}
void
SeriesRequestGenerator::performCallback(uint proc, Addr address)
{
assert(m_active_node == proc);
assert(m_address == address);
assert(m_status == SeriesRequestGeneratorStatus_Request_Pending);
m_status = SeriesRequestGeneratorStatus_Thinking;
m_active_node++;
if (m_active_node == m_num_cpus) {
//
// Cycle of requests completed, increment cycle completions and restart
// at cpu zero
//
m_directed_tester->incrementCycleCompletions();
m_address += m_addr_increment_size;
m_active_node = 0;
}
}
SeriesRequestGenerator *
SeriesRequestGeneratorParams::create()
{
return new SeriesRequestGenerator(this);
}

View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//
// This Deterministic Generator generates GETX requests for all nodes in the
// system. The GETX requests are generated one at a time in round-robin fashion
// 0...1...2...etc.
//
#ifndef __CPU_DIRECTEDTEST_SERIESREQUESTGENERATOR_HH__
#define __CPU_DIRECTEDTEST_SERIESREQUESTGENERATOR_HH__
#include "cpu/directedtest/RubyDirectedTester.hh"
#include "cpu/directedtest/DirectedGenerator.hh"
#include "mem/protocol/SeriesRequestGeneratorStatus.hh"
#include "params/SeriesRequestGenerator.hh"
class SeriesRequestGenerator : public DirectedGenerator
{
public:
typedef SeriesRequestGeneratorParams Params;
SeriesRequestGenerator(const Params *p);
~SeriesRequestGenerator();
bool initiate();
void performCallback(uint proc, Addr address);
private:
SeriesRequestGeneratorStatus m_status;
Addr m_address;
uint m_active_node;
uint m_addr_increment_size;
bool m_issue_writes;
};
#endif //__CPU_DIRECTEDTEST_SERIESREQUESTGENERATOR_HH__

View file

@ -65,45 +65,18 @@ enumeration(TesterStatus, desc="...") {
Check_Pending, desc="Check Pending";
}
// SpecifiedGeneratorTypes
enumeration(SpecifiedGeneratorType, desc="...") {
DetermGETXGenerator, desc="deterministic GETX Tester";
DetermInvGenerator, desc="deterministic all shared then invalidate Tester";
DetermSeriesGETSGenerator, desc="deterministic Series of GETSs Tester for prefetcher tuning";
// InvalidateGeneratorStatus
enumeration(InvalidateGeneratorStatus, desc="...") {
Load_Waiting, desc="Load waiting to be issued";
Load_Pending, desc="Load issued";
Inv_Waiting, desc="Store (invalidate) waiting to be issued";
Inv_Pending, desc="Store (invalidate) issued";
}
// RequestGeneratorStatus
enumeration(RequestGeneratorStatus, desc="...") {
Thinking, desc="Doing work between release and next acquire";
Test_Pending, desc="Test pending";
Before_Swap, desc="We're about to perform the swap";
Swap_Pending, desc="The swap used for test-and-send is pending";
Holding, desc="We are holding the lock performing the critical section";
Release_Pending, desc="The write for the release is pending";
Done, desc="Done, waiting for end of run";
}
// DetermGETXGeneratorStatus
enumeration(DetermGETXGeneratorStatus, desc="...") {
// SeriesRequestGeneratorStatus
enumeration(SeriesRequestGeneratorStatus, desc="...") {
Thinking, desc="Doing work before next action";
Store_Pending, desc="Store pending";
Done, desc="Done, waiting for end of run";
}
// DetermGETXGeneratorStatus
enumeration(DetermInvGeneratorStatus, desc="...") {
Thinking, desc="Doing work before next action";
Store_Pending, desc="Store pending";
Load_Complete, desc="Load complete";
Load_Pending, desc="Load pending";
Done, desc="Done, waiting for end of run";
}
// DetermSeriesGETSGeneratorStatus
enumeration(DetermSeriesGETSGeneratorStatus, desc="...") {
Thinking, desc="Doing work before next action";
Load_Pending, desc="Load pending";
Done, desc="Done, waiting for end of run";
Request_Pending, desc="Request pending";
}
// LockStatus

View file

@ -1,176 +0,0 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* $Id$
*
*/
// This Deterministic Generator generates GETX requests for all nodes in the system
// The GETX requests are generated one at a time in round-robin fashion 0...1...2...etc.
#include "mem/ruby/tester/DetermGETXGenerator.hh"
#include "mem/protocol/DetermGETXGeneratorStatus.hh"
#include "mem/ruby/tester/DeterministicDriver.hh"
#include "mem/ruby/tester/Tester_Globals.hh"
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/tester/SpecifiedGenerator.hh"
//#include "DMAController.hh"
#include "mem/ruby/libruby.hh"
DetermGETXGenerator::DetermGETXGenerator(NodeID node, DeterministicDriver * driver)
{
m_status = DetermGETXGeneratorStatus_Thinking;
m_last_transition = 0;
counter = 0;
m_node = node;
m_address = Address(1); // initialize to null value
m_counter = 0;
issued_load = false;
parent_driver = driver;
// don't know exactly when this node needs to request so just guess randomly
parent_driver->eventQueue->scheduleEvent(this, 1+(random() % 200));
}
DetermGETXGenerator::~DetermGETXGenerator()
{
}
void DetermGETXGenerator::wakeup()
{
DEBUG_EXPR(TESTER_COMP, MedPrio, m_node);
DEBUG_EXPR(TESTER_COMP, MedPrio, m_status);
// determine if this node is next for the GETX round robin request
if (m_status == DetermGETXGeneratorStatus_Thinking) {
if (parent_driver->isStoreReady(m_node)) {
if (!issued_load) {
pickAddress();
}
m_status = DetermGETXGeneratorStatus_Store_Pending; // Store Pending
m_last_transition = parent_driver->eventQueue->getTime();
initiateStore(); // GETX
} else { // I'll check again later
parent_driver->eventQueue->scheduleEvent(this, thinkTime());
}
} else {
WARN_EXPR(m_status);
ERROR_MSG("Invalid status");
}
}
void DetermGETXGenerator::performCallback(NodeID proc, Address address)
{
assert(proc == m_node);
assert(address == m_address);
DEBUG_EXPR(TESTER_COMP, LowPrio, proc);
DEBUG_EXPR(TESTER_COMP, LowPrio, m_status);
DEBUG_EXPR(TESTER_COMP, LowPrio, address);
if (m_status == DetermGETXGeneratorStatus_Store_Pending) {
parent_driver->recordStoreLatency(parent_driver->eventQueue->getTime() - m_last_transition);
parent_driver->storeCompleted(m_node, address); // advance the store queue
m_counter++;
if (m_counter < parent_driver->m_tester_length) {
m_status = DetermGETXGeneratorStatus_Thinking;
m_last_transition = parent_driver->eventQueue->getTime();
parent_driver->eventQueue->scheduleEvent(this, waitTime());
} else {
parent_driver->reportDone();
m_status = DetermGETXGeneratorStatus_Done;
m_last_transition = parent_driver->eventQueue->getTime();
}
} else {
WARN_EXPR(m_status);
ERROR_MSG("Invalid status");
}
}
int DetermGETXGenerator::thinkTime() const
{
return parent_driver->m_think_time;
}
int DetermGETXGenerator::waitTime() const
{
return parent_driver->m_wait_time;
}
void DetermGETXGenerator::pickAddress()
{
assert(m_status == DetermGETXGeneratorStatus_Thinking);
m_address = parent_driver->getNextStoreAddr(m_node);
}
void DetermGETXGenerator::initiateStore()
{
DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Store");
uint8_t *write_data = new uint8_t[64];
for(int i=0; i < 64; i++) {
write_data[i] = m_node;
}
char name [] = "Sequencer_";
char port_name [13];
sprintf(port_name, "%s%d", name, m_node);
int64_t request_id;
if (counter%10 == 0) {
if (!issued_load) {
cerr << m_node << " RMW_Read to address: " << m_address.getAddress() << endl << flush;
request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(m_address.getAddress(), write_data, 64, 0, RubyRequestType_RMW_Read, RubyAccessMode_Supervisor));
issued_load = true;
}
else {
cerr << m_node << " RMW_Write to address: " << m_address.getAddress() << endl << flush;
request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(m_address.getAddress(), write_data, 64, 0, RubyRequestType_RMW_Write, RubyAccessMode_Supervisor));
issued_load = false;
counter++;
}
}
else {
cerr << m_node << " ST to address: " << m_address.getAddress() << endl << flush;
request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(m_address.getAddress(), write_data, 64, 0, RubyRequestType_ST, RubyAccessMode_Supervisor));
counter++;
}
// delete [] write_data;
ASSERT(parent_driver->requests.find(request_id) == parent_driver->requests.end());
parent_driver->requests.insert(make_pair(request_id, make_pair(m_node, m_address)));
}
void DetermGETXGenerator::print(ostream& out) const
{
}

View file

@ -1,105 +0,0 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* $Id$
*
* Description:
*
*/
// This Deterministic Generator generates GETX requests for all nodes in the system
// The GETX requests are generated one at a time in round-robin fashion 0...1...2...etc.
#ifndef DETERMGETXGENERATOR_H
#define DETERMGETXGENERATOR_H
#include "mem/ruby/tester/Tester_Globals.hh"
#include "mem/ruby/common/Consumer.hh"
#include "mem/protocol/DetermGETXGeneratorStatus.hh"
#include "mem/ruby/tester/SpecifiedGenerator.hh"
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/common/Address.hh"
class DeterministicDriver;
class DMAController;
class DetermGETXGenerator : public SpecifiedGenerator {
public:
// Constructors
DetermGETXGenerator(NodeID node, DeterministicDriver * driver);
// Destructor
~DetermGETXGenerator();
// Public Methods
void wakeup();
void performCallback(NodeID proc, Address address);
void print(ostream& out) const;
private:
// Private Methods
int thinkTime() const;
int waitTime() const;
void initiateStore();
void initiateDMA();
void pickAddress();
DMAController* dma() const;
// copy constructor and assignment operator
DetermGETXGenerator(const DetermGETXGenerator& obj);
DetermGETXGenerator& operator=(const DetermGETXGenerator& obj);
DeterministicDriver * parent_driver;
// Data Members (m_ prefix)
DetermGETXGeneratorStatus m_status;
int m_counter;
bool issued_load;
Address m_address;
NodeID m_node;
long int counter;
Time m_last_transition;
};
// Output operator declaration
ostream& operator<<(ostream& out, const DetermGETXGenerator& obj);
// ******************* Definitions *******************
// Output operator definition
extern inline
ostream& operator<<(ostream& out, const DetermGETXGenerator& obj)
{
obj.print(out);
out << flush;
return out;
}
#endif //DETERMGETXGENERATOR_H

View file

@ -1,220 +0,0 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* $Id$
*
*/
// This Deterministic Generator generates GETS request for all nodes in the system
// then Invalidates them with a GETX. The GETS and GETX request are generated one
// at a time in round-robin fashion 0...1...2...etc.
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/tester/DetermInvGenerator.hh"
#include "mem/protocol/DetermInvGeneratorStatus.hh"
#include "mem/ruby/tester/DeterministicDriver.hh"
#include "mem/ruby/tester/Tester_Globals.hh"
//#include "DMAController.hh"
#include "mem/ruby/libruby.hh"
DetermInvGenerator::DetermInvGenerator(NodeID node, DeterministicDriver& driver) :
m_driver(driver)
{
m_status = DetermInvGeneratorStatus_Thinking;
m_last_transition = 0;
m_node = node;
m_address = Address(9999); // initiate to a NULL value
m_counter = 0;
// don't know exactly when this node needs to request so just guess randomly
m_driver.eventQueue->scheduleEvent(this, 1+(random() % 200));
}
DetermInvGenerator::~DetermInvGenerator()
{
}
void DetermInvGenerator::wakeup()
{
DEBUG_EXPR(TESTER_COMP, MedPrio, m_node);
DEBUG_EXPR(TESTER_COMP, MedPrio, m_status);
// determine if this node is next for the load round robin request
if (m_status == DetermInvGeneratorStatus_Thinking) {
// is a load ready and waiting and are my transactions insync with global transactions
if (m_driver.isLoadReady(m_node) && m_counter == m_driver.getStoresCompleted()) {
pickLoadAddress();
m_status = DetermInvGeneratorStatus_Load_Pending; // Load Pending
m_last_transition = m_driver.eventQueue->getTime();
initiateLoad(); // GETS
} else { // I'll check again later
m_driver.eventQueue->scheduleEvent(this, thinkTime());
}
} else if (m_status == DetermInvGeneratorStatus_Load_Complete) {
if (m_driver.isStoreReady(m_node, m_address)) { // do a store in this transaction or start the next one
if (m_driver.isLoadReady((0), m_address)) { // everyone is in S for this address i.e. back to node 0
m_status = DetermInvGeneratorStatus_Store_Pending;
m_last_transition = m_driver.eventQueue->getTime();
initiateStore(); // GETX
} else { // I'm next, I just have to wait for all loads to complete
m_driver.eventQueue->scheduleEvent(this, thinkTime());
}
} else { // I'm not next to store, go back to thinking
m_status = DetermInvGeneratorStatus_Thinking;
m_driver.eventQueue->scheduleEvent(this, thinkTime());
}
} else {
WARN_EXPR(m_status);
ERROR_MSG("Invalid status");
}
}
void DetermInvGenerator::performCallback(NodeID proc, Address address)
{
assert(proc == m_node);
assert(address == m_address);
DEBUG_EXPR(TESTER_COMP, LowPrio, proc);
DEBUG_EXPR(TESTER_COMP, LowPrio, m_status);
DEBUG_EXPR(TESTER_COMP, LowPrio, address);
if (m_status == DetermInvGeneratorStatus_Load_Pending) {
m_driver.recordLoadLatency(m_driver.eventQueue->getTime() - m_last_transition);
//NodeID firstByte = data.readByte(); // dummy read
m_driver.loadCompleted(m_node, address);
if (!m_driver.isStoreReady(m_node, m_address)) { // if we don't have to store, we are done for this transaction
m_counter++;
}
if (m_counter < m_driver.m_tester_length) {
m_status = DetermInvGeneratorStatus_Load_Complete;
m_last_transition = m_driver.eventQueue->getTime();
m_driver.eventQueue->scheduleEvent(this, waitTime());
} else {
m_driver.reportDone();
m_status = DetermInvGeneratorStatus_Done;
m_last_transition = m_driver.eventQueue->getTime();
}
} else if (m_status == DetermInvGeneratorStatus_Store_Pending) {
m_driver.recordStoreLatency(m_driver.eventQueue->getTime() - m_last_transition);
//data.writeByte(m_node);
m_driver.storeCompleted(m_node, address); // advance the store queue
m_counter++;
if (m_counter < m_driver.m_tester_length) {
m_status = DetermInvGeneratorStatus_Thinking;
m_last_transition = m_driver.eventQueue->getTime();
m_driver.eventQueue->scheduleEvent(this, waitTime());
} else {
m_driver.reportDone();
m_status = DetermInvGeneratorStatus_Done;
m_last_transition = m_driver.eventQueue->getTime();
}
} else {
WARN_EXPR(m_status);
ERROR_MSG("Invalid status");
}
DEBUG_EXPR(TESTER_COMP, LowPrio, proc);
DEBUG_EXPR(TESTER_COMP, LowPrio, m_status);
DEBUG_EXPR(TESTER_COMP, LowPrio, address);
}
int DetermInvGenerator::thinkTime() const
{
return m_driver.m_think_time;
}
int DetermInvGenerator::waitTime() const
{
return m_driver.m_wait_time;
}
int DetermInvGenerator::holdTime() const
{
assert(0);
}
void DetermInvGenerator::pickLoadAddress()
{
assert(m_status == DetermInvGeneratorStatus_Thinking);
m_address = m_driver.getNextLoadAddr(m_node);
}
void DetermInvGenerator::initiateLoad()
{
DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Load");
// sequencer()->makeRequest(CacheMsg(m_address, m_address, CacheRequestType_LD, Address(1), AccessModeType_UserMode, 1, PrefetchBit_No, Address(0), 0 /* only 1 SMT thread */));
uint8_t * read_data = new uint8_t[64];
char name [] = "Sequencer_";
char port_name [13];
sprintf(port_name, "%s%d", name, m_node);
int64_t request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(m_address.getAddress(), read_data, 64, 0, RubyRequestType_LD, RubyAccessMode_Supervisor));
//delete [] read_data;
ASSERT(m_driver.requests.find(request_id) == m_driver.requests.end());
m_driver.requests.insert(make_pair(request_id, make_pair(m_node, m_address)));
}
void DetermInvGenerator::initiateStore()
{
DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Store");
// sequencer()->makeRequest(CacheMsg(m_address, m_address, CacheRequestType_ST, Address(3), AccessModeType_UserMode, 1, PrefetchBit_No, Address(0), 0 /* only 1 SMT thread */));
uint8_t *write_data = new uint8_t[64];
for(int i=0; i < 64; i++) {
write_data[i] = m_node;
}
char name [] = "Sequencer_";
char port_name [13];
sprintf(port_name, "%s%d", name, m_node);
int64_t request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(m_address.getAddress(), write_data, 64, 0, RubyRequestType_ST, RubyAccessMode_Supervisor));
//delete [] write_data;
ASSERT(m_driver.requests.find(request_id) == m_driver.requests.end());
m_driver.requests.insert(make_pair(request_id, make_pair(m_node, m_address)));
}
void DetermInvGenerator::print(ostream& out) const
{
out << "[DetermInvGenerator]" << endl;
}

View file

@ -1,105 +0,0 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* $Id$
*
* Description:
*
*/
// This Deterministic Generator generates GETS request for all nodes in the system
// then Invalidates them with a GETX. The GETS and GETX request are generated one
// at a time in round-robin fashion 0...1...2...etc.
#ifndef DETERMINVGENERATOR_H
#define DETERMINVGENERATOR_H
#include "mem/ruby/tester/Tester_Globals.hh"
#include "mem/ruby/common/Consumer.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/common/Global.hh"
#include "mem/protocol/DetermInvGeneratorStatus.hh"
#include "mem/ruby/tester/SpecifiedGenerator.hh"
class DeterministicDriver;
class DetermInvGenerator : public SpecifiedGenerator {
public:
// Constructors
DetermInvGenerator(NodeID node, DeterministicDriver& driver);
// Destructor
~DetermInvGenerator();
// Public Methods
void wakeup();
void performCallback(NodeID proc, Address address);
void print(ostream& out) const;
private:
// Private Methods
int thinkTime() const;
int waitTime() const;
int holdTime() const;
void initiateLoad();
void initiateStore();
void pickLoadAddress();
void pickStoreAddress();
// copy constructor and assignment operator
DetermInvGenerator(const DetermInvGenerator& obj);
DetermInvGenerator& operator=(const DetermInvGenerator& obj);
// Data Members (m_ prefix)
DetermInvGeneratorStatus m_status;
int m_counter;
Address m_address;
NodeID m_node;
DeterministicDriver& m_driver;
Time m_last_transition;
};
// Output operator declaration
ostream& operator<<(ostream& out, const DetermInvGenerator& obj);
// ******************* Definitions *******************
// Output operator definition
extern inline
ostream& operator<<(ostream& out, const DetermInvGenerator& obj)
{
obj.print(out);
out << flush;
return out;
}
#endif //DETERMINVGENERATOR_H

View file

@ -1,150 +0,0 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* $Id$
*
*/
#include "mem/ruby/tester/DetermSeriesGETSGenerator.hh"
#include "mem/protocol/DetermSeriesGETSGeneratorStatus.hh"
#include "mem/ruby/tester/DeterministicDriver.hh"
DetermSeriesGETSGenerator::DetermSeriesGETSGenerator(NodeID node, DeterministicDriver& driver) :
m_driver(driver)
{
m_status = DetermSeriesGETSGeneratorStatus_Thinking;
m_last_transition = 0;
m_node = node;
m_address = Address(9999); // initialize to null value
m_counter = 0;
// don't know exactly when this node needs to request so just guess randomly
m_driver.eventQueue->scheduleEvent(this, 1+(random() % 200));
}
DetermSeriesGETSGenerator::~DetermSeriesGETSGenerator()
{
}
void DetermSeriesGETSGenerator::wakeup()
{
DEBUG_EXPR(TESTER_COMP, MedPrio, m_node);
DEBUG_EXPR(TESTER_COMP, MedPrio, m_status);
// determine if this node is next for the SeriesGETS round robin request
if (m_status == DetermSeriesGETSGeneratorStatus_Thinking) {
if (m_driver.isLoadReady(m_node)) {
pickAddress();
m_status = DetermSeriesGETSGeneratorStatus_Load_Pending; // Load Pending
m_last_transition = m_driver.eventQueue->getTime();
initiateLoad(); // SeriesGETS
} else { // I'll check again later
m_driver.eventQueue->scheduleEvent(this, thinkTime());
}
} else {
WARN_EXPR(m_status);
ERROR_MSG("Invalid status");
}
}
void DetermSeriesGETSGenerator::performCallback(NodeID proc, Address address)
{
assert(proc == m_node);
assert(address == m_address);
DEBUG_EXPR(TESTER_COMP, LowPrio, proc);
DEBUG_EXPR(TESTER_COMP, LowPrio, m_status);
DEBUG_EXPR(TESTER_COMP, LowPrio, address);
if (m_status == DetermSeriesGETSGeneratorStatus_Load_Pending) {
m_driver.recordLoadLatency(m_driver.eventQueue->getTime() - m_last_transition);
//data.writeByte(m_node);
m_driver.loadCompleted(m_node, address); // advance the load queue
m_counter++;
// do we still have more requests to complete before the next proc starts?
if (m_counter < m_driver.m_tester_length*m_driver.m_numCompletionsPerNode) {
m_status = DetermSeriesGETSGeneratorStatus_Thinking;
m_last_transition = m_driver.eventQueue->getTime();
m_driver.eventQueue->scheduleEvent(this, waitTime());
} else {
m_driver.reportDone();
m_status = DetermSeriesGETSGeneratorStatus_Done;
m_last_transition = m_driver.eventQueue->getTime();
}
} else {
WARN_EXPR(m_status);
ERROR_MSG("Invalid status");
}
}
int DetermSeriesGETSGenerator::thinkTime() const
{
return m_driver.m_think_time;
}
int DetermSeriesGETSGenerator::waitTime() const
{
return m_driver.m_wait_time;
}
void DetermSeriesGETSGenerator::pickAddress()
{
assert(m_status == DetermSeriesGETSGeneratorStatus_Thinking);
m_address = m_driver.getNextLoadAddr(m_node);
}
void DetermSeriesGETSGenerator::initiateLoad()
{
DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Load");
//sequencer()->makeRequest(CacheMsg(m_address, m_address, CacheRequestType_IFETCH, Address(3), AccessModeType_UserMode, 1, PrefetchBit_No, Address(0), 0 /* only 1 SMT thread */));
uint8_t *read_data = new uint8_t[64];
char name [] = "Sequencer_";
char port_name [13];
sprintf(port_name, "%s%d", name, m_node);
int64_t request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(m_address.getAddress(), read_data, 64, 0, RubyRequestType_LD, RubyAccessMode_Supervisor));
//delete [] read_data;
ASSERT(m_driver.requests.find(request_id) == m_driver.requests.end());
m_driver.requests.insert(make_pair(request_id, make_pair(m_node, m_address)));
}
void DetermSeriesGETSGenerator::print(ostream& out) const
{
}

View file

@ -1,102 +0,0 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* $Id$
*
* Description:
*
*/
// This Deterministic Generator generates a series of GETS requests for a given node.
// Sequentially goes through all nodes in the system
// This generator is used to tune the HW prefetcher
// The GETS requests are generated one at a time in round-robin fashion 0...1...2...etc.
#ifndef DETERMSERIESGETSGENERATOR_H
#define DETERMSERIESGETSGENERATOR_H
#include "mem/ruby/tester/Tester_Globals.hh"
#include "mem/ruby/common/Consumer.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/common/Global.hh"
#include "mem/protocol/DetermSeriesGETSGeneratorStatus.hh"
#include "mem/ruby/tester/SpecifiedGenerator.hh"
class DeterministicDriver;
class DetermSeriesGETSGenerator : public SpecifiedGenerator {
public:
// Constructors
DetermSeriesGETSGenerator(NodeID node, DeterministicDriver& driver);
// Destructor
~DetermSeriesGETSGenerator();
// Public Methods
void wakeup();
void performCallback(NodeID proc, Address address);
void print(ostream& out) const;
private:
// Private Methods
int thinkTime() const;
int waitTime() const;
void initiateLoad();
void pickAddress();
// copy constructor and assignment operator
DetermSeriesGETSGenerator(const DetermSeriesGETSGenerator& obj);
DetermSeriesGETSGenerator& operator=(const DetermSeriesGETSGenerator& obj);
// Data Members (m_ prefix)
DetermSeriesGETSGeneratorStatus m_status;
int m_counter;
Address m_address;
NodeID m_node;
DeterministicDriver& m_driver;
Time m_last_transition;
};
// Output operator declaration
ostream& operator<<(ostream& out, const DetermSeriesGETSGenerator& obj);
// ******************* Definitions *******************
// Output operator definition
extern inline
ostream& operator<<(ostream& out, const DetermSeriesGETSGenerator& obj)
{
obj.print(out);
out << flush;
return out;
}
#endif //DETERMSeriesGETSGENERATOR_H

View file

@ -33,10 +33,6 @@ Import('*')
if not env['RUBY']:
Return()
#Source('DetermGETXGenerator.cc')
#Source('DetermInvGenerator.cc')
#Source('DetermSeriesGETSGenerator.cc')
#Source('DeterministicDriver.cc')
#Source('SpecifiedGenerator.cc')
#Source('getopt.cc')
#Source('main.cc')