cpu: Stream/SubstreamID support in TrafficGen

This patch is adding support for generating memory requests which set
the StreamID/SubstreamID field, so that is possible to emulate devices
attached to an external IOMMU/SMMU with a Traffic generator.

Change-Id: Iea068de581ae7125a9d49314124a08c045c75b49
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/12188
This commit is contained in:
Giacomo Travaglini
2018-07-20 11:23:49 +01:00
parent 2b3168021c
commit f741bb7cdb
6 changed files with 243 additions and 2 deletions

View File

@@ -41,6 +41,13 @@ from m5.params import *
from m5.proxy import *
from MemObject import MemObject
# Types of Stream Generators.
# Those are orthogonal to the other generators in the TrafficGen
# and are meant to initialize the stream and substream IDs for
# every memory request, regardless of how the packet has been
# generated (Random, Linear, Trace etc)
class StreamGenType(Enum): vals = [ 'none', 'fixed', 'random' ]
# The traffic generator is a master module that generates stimuli for
# the memory system, based on a collection of simple behaviours that
# are either probabilistic or based on traces. It can be used stand
@@ -70,3 +77,11 @@ class BaseTrafficGen(MemObject):
# somewhat arbitrary and may well have to be tuned.
progress_check = Param.Latency('1ms', "Time before exiting " \
"due to lack of progress")
# Generator type used for applying Stream and/or Substream IDs to requests
stream_gen = Param.StreamGenType('none',
"Generator for adding Stream and/or Substream ID's to requests")
# Sources for Stream/Substream IDs to apply to requests
sids = VectorParam.Unsigned([], "StreamIDs to use")
ssids = VectorParam.Unsigned([], "SubstreamIDs to use")

View File

@@ -48,6 +48,7 @@ Source('exit_gen.cc')
Source('idle_gen.cc')
Source('linear_gen.cc')
Source('random_gen.cc')
Source('stream_gen.cc')
DebugFlag('TrafficGen')
SimObject('BaseTrafficGen.py')

View File

@@ -52,6 +52,7 @@
#include "cpu/testers/traffic_gen/idle_gen.hh"
#include "cpu/testers/traffic_gen/linear_gen.hh"
#include "cpu/testers/traffic_gen/random_gen.hh"
#include "cpu/testers/traffic_gen/stream_gen.hh"
#include "debug/Checkpoint.hh"
#include "debug/TrafficGen.hh"
#include "params/BaseTrafficGen.hh"
@@ -78,7 +79,12 @@ BaseTrafficGen::BaseTrafficGen(const BaseTrafficGenParams* p)
retryPkt(NULL),
retryPktTick(0),
updateEvent([this]{ update(); }, name()),
masterID(system->getMasterId(this))
masterID(system->getMasterId(this)),
streamGenerator(StreamGen::create(p))
{
}
BaseTrafficGen::~BaseTrafficGen()
{
}
@@ -172,6 +178,19 @@ BaseTrafficGen::update()
// get the next packet and try to send it
PacketPtr pkt = activeGenerator->getNextPacket();
// If generating stream/substream IDs are enabled,
// try to pick and assign them to the new packet
if (streamGenerator) {
auto sid = streamGenerator->pickStreamID();
auto ssid = streamGenerator->pickSubStreamID();
pkt->req->setStreamId(sid);
if (streamGenerator->ssidValid()) {
pkt->req->setSubStreamId(ssid);
}
}
// suppress packets that are not destined for a memory, such as
// device accesses that could be part of a trace
if (pkt && system->isMemAddr(pkt->getAddr())) {

View File

@@ -50,6 +50,7 @@
#include "mem/qport.hh"
class BaseGen;
class StreamGen;
class System;
struct BaseTrafficGenParams;
@@ -179,7 +180,7 @@ class BaseTrafficGen : public MemObject
public:
BaseTrafficGen(const BaseTrafficGenParams* p);
~BaseTrafficGen() {}
~BaseTrafficGen();
BaseMasterPort& getMasterPort(const std::string &if_name,
PortID idx = InvalidPortID) override;
@@ -247,6 +248,9 @@ class BaseTrafficGen : public MemObject
/** Currently active generator */
std::shared_ptr<BaseGen> activeGenerator;
/** Stream/SubStreamID Generator */
std::unique_ptr<StreamGen> streamGenerator;
};
#endif //__CPU_TRAFFIC_GEN_BASE_HH__

View File

@@ -0,0 +1,63 @@
/*
* Copyright (c) 2018 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed here under. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* 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: Giacomo Travaglini
*/
#include "stream_gen.hh"
#include "base/random.hh"
StreamGen*
StreamGen::create(const BaseTrafficGenParams *p)
{
switch (p->stream_gen) {
case Enums::fixed:
return new FixedStreamGen(p);
case Enums::random:
return new RandomStreamGen(p);
case Enums::none:
default:
return nullptr;
}
}
uint32_t
RandomStreamGen::randomPick(const std::vector<uint32_t> &svec)
{
// Pick a random entry in the vector of IDs
return svec[random_mt.random<size_t>(0, svec.size()-1)];
}

View File

@@ -0,0 +1,139 @@
/*
* Copyright (c) 2018 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed here under. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* 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: Giacomo Travaglini
*/
/**
* @file
* Declaration of the Stream generator for issuing memory requests
* with variable/fixed stream and substream IDs.
*/
#ifndef __CPU_TRAFFIC_GEN_STREAM_GEN_HH__
#define __CPU_TRAFFIC_GEN_STREAM_GEN_HH__
#include "params/BaseTrafficGen.hh"
class StreamGen
{
protected:
StreamGen(const BaseTrafficGenParams *p)
: streamIds(p->sids), substreamIds(p->ssids)
{
// A non empty vector of StreamIDs must be provided.
// SubstreamIDs are not mandatory hence having an empty
// vector means that they are not used and no configuration
// error must be thrown
fatal_if(streamIds.empty(),
"Must provide a vector of StreamIDs");
}
public:
virtual uint32_t pickStreamID() = 0;
virtual uint32_t pickSubStreamID() = 0;
/**
* Factory method for constructing a Stream generator.
* The Stream generator type is selected by the
* StreamGenType enum parameter.
*
* @params p pointer to BaseTrafficGenParams struct where
* the stream generator type is stored.
* @return a pointer to the newly alocated StremGen
*/
static StreamGen* create(const BaseTrafficGenParams *p);
/**
* Returns true if the substreamID generation is valid
* and hence should be taken into account.
* It is valid if the set of substreamIDs passed as a
* parameter to the TrafficGenerator is a non empty list.
*
* @return true if ssid is valid, false otherwise
*/
bool ssidValid() const { return !substreamIds.empty(); }
protected:
/**
* Store preset Stream and Substream IDs to use for requests
* This is the set of available streamIDs the generator can
* pick. The actual ID being picked for a specific memory
* request is selected by the pickStreamID and pickSubStreamID
* methods.
*/
std::vector<uint32_t> streamIds;
std::vector<uint32_t> substreamIds;
};
class FixedStreamGen : public StreamGen
{
public:
FixedStreamGen(const BaseTrafficGenParams *p)
: StreamGen(p)
{
// For a fixed stream generator only one sid must be provided. The
// ssid can have either 0 (not used) or 1 value.
fatal_if(streamIds.size() != 1 || substreamIds.size() > 1,
"Invalid sids/ssids configuration");
}
uint32_t pickStreamID() override
{ return streamIds[0]; }
uint32_t pickSubStreamID() override
{ return substreamIds[0]; }
};
class RandomStreamGen : public StreamGen
{
public:
RandomStreamGen(const BaseTrafficGenParams *p)
: StreamGen(p)
{}
uint32_t pickStreamID() override
{ return randomPick(streamIds); }
uint32_t pickSubStreamID() override
{ return randomPick(substreamIds); }
protected:
/** Function to pick one of the preset Stream or Substream ID */
uint32_t randomPick(const std::vector<uint32_t> &svec);
};
#endif // __CPU_TRAFFIC_GEN_STREAM_GEN_HH__