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:
parent
984adf198a
commit
6a4f99899b
19 changed files with 971 additions and 898 deletions
126
configs/example/determ_test.py
Normal file
126
configs/example/determ_test.py
Normal 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()
|
44
src/cpu/directedtest/DirectedGenerator.cc
Normal file
44
src/cpu/directedtest/DirectedGenerator.cc
Normal 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;
|
||||
}
|
56
src/cpu/directedtest/DirectedGenerator.hh
Normal file
56
src/cpu/directedtest/DirectedGenerator.hh
Normal 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__
|
||||
|
142
src/cpu/directedtest/InvalidateGenerator.cc
Normal file
142
src/cpu/directedtest/InvalidateGenerator.cc
Normal 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);
|
||||
}
|
63
src/cpu/directedtest/InvalidateGenerator.hh
Normal file
63
src/cpu/directedtest/InvalidateGenerator.hh
Normal 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__
|
||||
|
136
src/cpu/directedtest/RubyDirectedTester.cc
Normal file
136
src/cpu/directedtest/RubyDirectedTester.cc
Normal 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);
|
||||
}
|
118
src/cpu/directedtest/RubyDirectedTester.hh
Normal file
118
src/cpu/directedtest/RubyDirectedTester.hh
Normal 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__
|
52
src/cpu/directedtest/RubyDirectedTester.py
Normal file
52
src/cpu/directedtest/RubyDirectedTester.py
Normal 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")
|
48
src/cpu/directedtest/SConscript
Normal file
48
src/cpu/directedtest/SConscript
Normal 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')
|
114
src/cpu/directedtest/SeriesRequestGenerator.cc
Normal file
114
src/cpu/directedtest/SeriesRequestGenerator.cc
Normal 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);
|
||||
}
|
63
src/cpu/directedtest/SeriesRequestGenerator.hh
Normal file
63
src/cpu/directedtest/SeriesRequestGenerator.hh
Normal 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__
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
{
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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')
|
||||
|
|
Loading…
Reference in a new issue