Files
DRAMSys/DRAMSys/simulator/TrafficGenerator.cpp
2022-02-15 09:39:06 +01:00

174 lines
6.9 KiB
C++

/*
* Copyright (c) 2015, Technische Universität Kaiserslautern
* 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.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Derek Christ
*/
#include "TrafficGenerator.h"
using namespace sc_core;
using namespace tlm;
TrafficGenerator::TrafficGenerator(const sc_module_name &name,
const sc_time &generatorClk,
uint64_t numRequests,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
float rwRatio,
unsigned int seed,
TraceSetup *setup) :
TrafficInitiator(name, setup, maxPendingReadRequests, maxPendingWriteRequests),
generatorClk(generatorClk), numRequests(numRequests), rwRatio(rwRatio)
{
defaultDataLength = Configuration::getInstance().memSpec->bytesPerBurst;
randomGenerator = std::default_random_engine(seed);
}
void TrafficGenerator::sendNextPayload()
{
if (transactionsSent >= numRequests)
{
finished = true;
return;
}
tlm_generic_payload *payload = setup->allocatePayload();
payload->acquire();
// TODO: column / burst breite
uint64_t address = getNextAddress();
tlm_command command;
if (randomRwDistribution(randomGenerator) < rwRatio)
{
command = tlm::TLM_READ_COMMAND;
pendingReadRequests++;
}
else
{
command = tlm::TLM_WRITE_COMMAND;
pendingWriteRequests++;
}
payload->set_address(address);
payload->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
payload->set_dmi_allowed(false);
payload->set_byte_enable_length(0);
payload->set_data_length(defaultDataLength);
payload->set_command(command);
sc_time sendingOffset;
if (transactionsSent == 0)
sendingOffset = SC_ZERO_TIME;
else
sendingOffset = generatorClk - (sc_time_stamp() % generatorClk);
// TODO: do not send two requests in the same cycle
sendToTarget(*payload, tlm::BEGIN_REQ, sendingOffset);
transactionsSent++;
PRINTDEBUGMESSAGE(name(), "Performing request #" + std::to_string(transactionsSent));
}
TrafficGeneratorRandom::TrafficGeneratorRandom(const sc_core::sc_module_name &name,
const sc_core::sc_time &generatorClk,
uint64_t numRequests,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
uint64_t minAddress,
uint64_t maxAddress,
float rwRatio,
unsigned int seed,
TraceSetup *setup) :
TrafficGenerator(name, generatorClk, numRequests, maxPendingReadRequests, maxPendingWriteRequests,
rwRatio, seed, setup)
{
randomAddressDistribution = std::uniform_int_distribution<uint64_t> (minAddress, maxAddress);
}
uint64_t TrafficGeneratorRandom::getNextAddress()
{
return randomAddressDistribution(randomGenerator);
}
TrafficGeneratorSequential::TrafficGeneratorSequential(const sc_core::sc_module_name &name,
const sc_core::sc_time &generatorClk,
uint64_t numRequests,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
uint64_t minAddress,
uint64_t maxAddress,
float rwRatio,
uint64_t addressIncrement,
unsigned int seed,
TraceSetup *setup) :
TrafficGenerator(name, generatorClk, numRequests, maxPendingReadRequests, maxPendingWriteRequests,
rwRatio, seed, setup),
minAddress(minAddress), maxAddress(maxAddress), addressIncrement(addressIncrement),
currentAddress(minAddress)
{
}
uint64_t TrafficGeneratorSequential::getNextAddress()
{
uint64_t address = currentAddress;
currentAddress += addressIncrement;
if (currentAddress > maxAddress)
currentAddress = minAddress;
return address;
}
TrafficGeneratorHammer::TrafficGeneratorHammer(const sc_core::sc_module_name &name,
const sc_core::sc_time &generatorClk,
uint64_t numRequests,
uint64_t rowIncrement,
TraceSetup *setup) :
TrafficGenerator(name, generatorClk, numRequests, 1, 1, 1.0f, 1, setup), rowIncrement(rowIncrement)
{
}
uint64_t TrafficGeneratorHammer::getNextAddress()
{
if (currentAddress == 0x0)
currentAddress = rowIncrement;
else
currentAddress = 0x0;
return currentAddress;
}