blob: 758ece50f1bb1b0d8a64debd6f4f9504aeb14dbf [file] [log] [blame]
/*
* Copyright (c) 2017-2021 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:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. Neither the name of the copyright holder 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 HOLDER 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_TESTERS_PROTOCOL_TESTER_PROTOCOL_TESTER_HH_
#define CPU_TESTERS_PROTOCOL_TESTER_PROTOCOL_TESTER_HH_
/*
* The tester includes the main ProtocolTester that manages all ports to the
* memory system.
* TesterThreads are mapped to certain data port(s)
*
* TesterThreads inject memory requests through their data ports.
* The tester receives and validates responses from the memory.
*
* Main components
* - AddressManager: generate DRF request streams &
* validate data response against an internal log_table
* - Episode: a sequence of requests
* - Thread: either GPU wavefront or CPU thread
*/
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include "base/types.hh"
#include "cpu/testers/gpu_ruby_test/address_manager.hh"
#include "mem/packet.hh"
#include "mem/ruby/system/RubyPort.hh"
#include "mem/token_port.hh"
#include "params/ProtocolTester.hh"
namespace gem5
{
class TesterThread;
class CpuThread;
class GpuWavefront;
class ProtocolTester : public ClockedObject
{
public:
class SeqPort : public RequestPort
{
public:
SeqPort(const std::string &_name, ProtocolTester *_tester, PortID _id,
PortID _index)
: RequestPort(_name, _tester, _id)
{}
protected:
virtual bool recvTimingResp(PacketPtr pkt);
virtual void recvReqRetry()
{ panic("%s does not expect a retry\n", name()); }
};
class GMTokenPort : public TokenRequestPort
{
public:
GMTokenPort(const std::string& name, ProtocolTester *_tester,
PortID id = InvalidPortID)
: TokenRequestPort(name, _tester, id)
{}
~GMTokenPort() {}
protected:
bool recvTimingResp(PacketPtr) { return false; }
void recvReqRetry() {}
};
struct SenderState : public Packet::SenderState
{
TesterThread* th;
SenderState(TesterThread* _th)
{
assert(_th);
th = _th;
}
~SenderState()
{}
};
public:
typedef ProtocolTesterParams Params;
ProtocolTester(const Params &p);
~ProtocolTester();
typedef AddressManager::Location Location;
typedef AddressManager::Value Value;
void init() override;
RequestorID requestorId() { return _requestorId; };
Port& getPort(const std::string &if_name,
PortID idx=InvalidPortID) override;
int getEpisodeLength() const { return episodeLength; }
// return pointer to the address manager
AddressManager* getAddressManager() const { return addrManager; }
// return true if the tester should stop issuing new episodes
bool checkExit();
// verify if a location to be picked for LD/ST will satisfy
// data race free requirement
bool checkDRF(Location atomic_loc, Location loc, bool isStore) const;
// return the next episode id and increment it
int getNextEpisodeID() { return nextEpisodeId++; }
// get action sequence number
int getActionSeqNum() { return actionCount++; }
// dump error log into a file and exit the simulation
void dumpErrorLog(std::stringstream& ss);
private:
RequestorID _requestorId;
// list of parameters taken from python scripts
int numCpuPorts;
int numDmaPorts;
int numVectorPorts;
int numSqcPorts;
int numScalarPorts;
int numTokenPorts;
int numCusPerSqc;
int numCusPerScalar;
int numWfsPerCu;
int numWisPerWf;
int numCuTokens;
// parameters controlling the address range that the tester can access
int numAtomicLocs;
int numNormalLocsPerAtomic;
// the number of actions in an episode (episodeLength +- random number)
int episodeLength;
// the maximum number of episodes to be completed by this tester
int maxNumEpisodes;
// are we debuggin the tester
bool debugTester;
// all available requestor ports connected to Ruby
std::vector<RequestPort*> cpuPorts; // cpu data ports
std::vector<RequestPort*> dmaPorts; // DMA data ports
std::vector<RequestPort*> cuVectorPorts; // ports to GPU vector cache
std::vector<RequestPort*> cuSqcPorts; // ports to GPU inst cache
std::vector<RequestPort*> cuScalarPorts; // ports to GPU scalar cache
std::vector<TokenManager*> cuTokenManagers;
std::vector<GMTokenPort*> cuTokenPorts;
// all CPU, DMA, and GPU threads
std::vector<CpuThread*> cpuThreads;
std::vector<DmaThread*> dmaThreads;
std::vector<GpuWavefront*> wfs;
// address manager that (1) generates DRF sequences of requests,
// (2) manages an internal log table and
// (3) validate response data
AddressManager* addrManager;
// number of CPUs and CUs
int numCpus;
int numDmas;
int numCus;
// unique id of the next episode
int nextEpisodeId;
// global action count. Overflow is fine. It's used to uniquely identify
// per-wave & per-instruction memory requests in the coalescer
int actionCount;
// if an exit signal was already sent
bool sentExitSignal;
OutputStream* logFile;
};
} // namespace gem5
#endif /* CPU_TESTERS_PROTOCOL_TESTER_PROTOCOL_TESTER_HH_ */