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";
|
Check_Pending, desc="Check Pending";
|
||||||
}
|
}
|
||||||
|
|
||||||
// SpecifiedGeneratorTypes
|
// InvalidateGeneratorStatus
|
||||||
enumeration(SpecifiedGeneratorType, desc="...") {
|
enumeration(InvalidateGeneratorStatus, desc="...") {
|
||||||
DetermGETXGenerator, desc="deterministic GETX Tester";
|
Load_Waiting, desc="Load waiting to be issued";
|
||||||
DetermInvGenerator, desc="deterministic all shared then invalidate Tester";
|
Load_Pending, desc="Load issued";
|
||||||
DetermSeriesGETSGenerator, desc="deterministic Series of GETSs Tester for prefetcher tuning";
|
Inv_Waiting, desc="Store (invalidate) waiting to be issued";
|
||||||
|
Inv_Pending, desc="Store (invalidate) issued";
|
||||||
}
|
}
|
||||||
|
|
||||||
// RequestGeneratorStatus
|
// SeriesRequestGeneratorStatus
|
||||||
enumeration(RequestGeneratorStatus, desc="...") {
|
enumeration(SeriesRequestGeneratorStatus, 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="...") {
|
|
||||||
Thinking, desc="Doing work before next action";
|
Thinking, desc="Doing work before next action";
|
||||||
Store_Pending, desc="Store pending";
|
Request_Pending, desc="Request 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";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// LockStatus
|
// 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']:
|
if not env['RUBY']:
|
||||||
Return()
|
Return()
|
||||||
|
|
||||||
#Source('DetermGETXGenerator.cc')
|
|
||||||
#Source('DetermInvGenerator.cc')
|
|
||||||
#Source('DetermSeriesGETSGenerator.cc')
|
|
||||||
#Source('DeterministicDriver.cc')
|
|
||||||
#Source('SpecifiedGenerator.cc')
|
#Source('SpecifiedGenerator.cc')
|
||||||
#Source('getopt.cc')
|
#Source('getopt.cc')
|
||||||
#Source('main.cc')
|
#Source('main.cc')
|
||||||
|
|
Loading…
Reference in a new issue