Changes Requested
This commit is contained in:
@@ -82,6 +82,26 @@ Bank DramExtension::getBank(const tlm_generic_payload &payload)
|
||||
return DramExtension::getBank(&payload);
|
||||
}
|
||||
|
||||
Channel DramExtension::getChannel(const tlm_generic_payload *payload)
|
||||
{
|
||||
return DramExtension::getExtension(payload).getChannel();
|
||||
}
|
||||
|
||||
Channel DramExtension::getChannel(const tlm_generic_payload &payload)
|
||||
{
|
||||
return DramExtension::getChannel(&payload);
|
||||
}
|
||||
|
||||
Thread DramExtension::getThread(const tlm_generic_payload *payload)
|
||||
{
|
||||
return DramExtension::getExtension(payload).getThread();
|
||||
}
|
||||
|
||||
Thread DramExtension::getThread(const tlm_generic_payload &payload)
|
||||
{
|
||||
return DramExtension::getThread(&payload);
|
||||
}
|
||||
|
||||
Row DramExtension::getRow(const tlm_generic_payload *payload)
|
||||
{
|
||||
return DramExtension::getExtension(payload).getRow();
|
||||
|
||||
@@ -177,6 +177,10 @@ public:
|
||||
// Used for convience, caller could also use getExtension(..) to access these field
|
||||
static Bank getBank(const tlm::tlm_generic_payload *payload);
|
||||
static Bank getBank(const tlm::tlm_generic_payload &payload);
|
||||
static Channel getChannel(const tlm::tlm_generic_payload *payload);
|
||||
static Channel getChannel(const tlm::tlm_generic_payload &payload);
|
||||
static Thread getThread(const tlm::tlm_generic_payload *payload);
|
||||
static Thread getThread(const tlm::tlm_generic_payload &payload);
|
||||
static Row getRow(const tlm::tlm_generic_payload *payload);
|
||||
static Row getRow(const tlm::tlm_generic_payload &payload);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, University of Kaiserslautern
|
||||
* Copyright (c) 2018, University of Kaiserslautern
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -30,8 +30,8 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors:
|
||||
* Matthias Jung
|
||||
* Felipe S. Prado
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef IARBITER_H_
|
||||
@@ -51,20 +51,20 @@ using namespace tlm;
|
||||
|
||||
struct IArbiter: public sc_module {
|
||||
public:
|
||||
tlm_utils::multi_passthrough_initiator_socket<IArbiter> iSocket;
|
||||
tlm_utils::multi_passthrough_target_socket<IArbiter> tSocket;
|
||||
tlm_utils::multi_passthrough_initiator_socket<IArbiter> iSocket;
|
||||
|
||||
SC_CTOR(IArbiter) {
|
||||
// The arbiter communicates with one or more memory unity through one or more sockets (one or more memory channels).
|
||||
// Each of the arbiter's initiator sockets is bound to a memory controller's target socket.
|
||||
// Anytime an transaction comes from a memory unity to the arbiter the "bw" callback is called.
|
||||
iSocket.register_nb_transport_bw(this, &IArbiter::nb_transport_bw);
|
||||
|
||||
// One or more devices can accesss all the memory units through the arbiter.
|
||||
// Devices' initiator sockets are bound to arbiter's target sockets.
|
||||
// As soon the arbiter receives a request in any of its target sockets it should treat and forward it to the proper memory channel.
|
||||
tSocket.register_nb_transport_fw(this, &IArbiter::nb_transport_fw);
|
||||
|
||||
// The arbiter communicates with one or more memory unity through one or more sockets (one or more memory channels).
|
||||
// Each of the arbiter's initiator sockets is bound to a memory controller's target socket.
|
||||
// Anytime an transaction comes from a memory unity to the arbiter the "bw" callback is called.
|
||||
iSocket.register_nb_transport_bw(this, &IArbiter::nb_transport_bw);
|
||||
|
||||
tSocket.register_transport_dbg(this, &IArbiter::transport_dbg);
|
||||
}
|
||||
|
||||
@@ -73,15 +73,57 @@ public:
|
||||
virtual void incrementNumberOfOutputBufferTransactions(unsigned int initiatorSocket) = 0;
|
||||
|
||||
protected:
|
||||
// Initiated by dram side
|
||||
// This function is called when an arbiter's initiator socket receives a transaction from a memory controller
|
||||
virtual tlm_sync_enum nb_transport_bw(int channelId, tlm_generic_payload &payload, tlm_phase &phase, sc_time &bwDelay) = 0;
|
||||
|
||||
// Initiated by initiator side
|
||||
// This function is called when an arbiter's target socket receives a transaction from a device
|
||||
virtual tlm_sync_enum nb_transport_fw(int id, tlm_generic_payload& payload, tlm_phase& phase, sc_time& fwDelay) = 0;
|
||||
|
||||
virtual unsigned int transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans) = 0;
|
||||
// Initiated by dram side
|
||||
// This function is called when an arbiter's initiator socket receives a transaction from a memory controller
|
||||
virtual tlm_sync_enum nb_transport_bw(int channelId, tlm_generic_payload &payload, tlm_phase &phase, sc_time &bwDelay) = 0;
|
||||
|
||||
virtual unsigned int transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans) = 0;
|
||||
|
||||
void printDebugMessage(std::string message)
|
||||
{
|
||||
DebugManager::getInstance().printDebugMessage(this->name(), message);
|
||||
}
|
||||
|
||||
void appendDramExtension(int socketId, tlm_generic_payload& payload)
|
||||
{
|
||||
// Append Generation Extension
|
||||
GenerationExtension* genExtension = new GenerationExtension(clkAlign(sc_time_stamp(),Configuration::getInstance().ControllerClk));
|
||||
payload.set_auto_extension(genExtension);
|
||||
|
||||
unsigned int burstlength = payload.get_streaming_width();
|
||||
DecodedAddress decodedAddress = xmlAddressDecoder::getInstance().decodeAddress(payload.get_address());
|
||||
// Check the valid range of decodedAddress
|
||||
if (addressIsValid(decodedAddress)) {
|
||||
DramExtension* extension = new DramExtension(Thread(socketId+1), Channel(decodedAddress.channel), Bank(decodedAddress.bank), BankGroup(decodedAddress.bankgroup), Row(decodedAddress.row), Column(decodedAddress.column),burstlength);
|
||||
payload.set_auto_extension(extension);
|
||||
} else {
|
||||
SC_REPORT_FATAL("Arbiter", "Decoded Address are not inside the valid range");
|
||||
}
|
||||
}
|
||||
|
||||
bool addressIsValid(DecodedAddress& decodedAddress)
|
||||
{
|
||||
if (decodedAddress.channel >= xmlAddressDecoder::getInstance().amount["channel"]) {
|
||||
return false;
|
||||
}
|
||||
if (decodedAddress.bank >= xmlAddressDecoder::getInstance().amount["bank"]) {
|
||||
return false;
|
||||
}
|
||||
if (decodedAddress.bankgroup > xmlAddressDecoder::getInstance().amount["bankgroup"]) {
|
||||
return false;
|
||||
}
|
||||
if (decodedAddress.column >= xmlAddressDecoder::getInstance().amount["column"]) {
|
||||
return false;
|
||||
}
|
||||
if (decodedAddress.row >= xmlAddressDecoder::getInstance().amount["row"]) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* IARBITER_H_ */
|
||||
|
||||
@@ -1,3 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2018, University of 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:
|
||||
* Felipe S. Prado
|
||||
* Matthias Jung
|
||||
*/
|
||||
|
||||
#ifndef SIMPLEARBITER_H
|
||||
#define SIMPLEARBITER_H
|
||||
|
||||
@@ -9,6 +45,8 @@
|
||||
using namespace std;
|
||||
using namespace tlm;
|
||||
|
||||
// Annotated References [X,Y] --> Please refer to TLM AT Cheat Sheet on README
|
||||
|
||||
struct SimpleArbiter: public IArbiter{
|
||||
public:
|
||||
SimpleArbiter(sc_module_name name) : IArbiter(name) {
|
||||
@@ -30,26 +68,6 @@ public:
|
||||
|
||||
protected:
|
||||
TlmRecorder* tlmRecorder;
|
||||
|
||||
// Initiated by dram side
|
||||
// This function is called when an arbiter's initiator socket receives a transaction from a memory controller
|
||||
virtual tlm_sync_enum nb_transport_bw(int /*channelId*/, tlm_generic_payload &payload, tlm_phase &phase, sc_time &bwDelay)
|
||||
{
|
||||
tlmRecorder->recordPhase(payload, phase, bwDelay + sc_time_stamp());
|
||||
|
||||
sendToInitiator(getPayloadThread(payload)-1, payload, phase, bwDelay);
|
||||
|
||||
if(phase == BEGIN_RESP)
|
||||
{
|
||||
// Early Completion [3.1]
|
||||
tlmRecorder->recordPhase(payload, END_RESP, bwDelay + sc_time_stamp());
|
||||
tlmRecorder->recordArbiterPhase(payload, BEGIN_RESP, sc_time_stamp()+bwDelay);
|
||||
return TLM_COMPLETED;
|
||||
}
|
||||
// 4-Phase Handshake [1.3]
|
||||
return TLM_ACCEPTED;
|
||||
}
|
||||
|
||||
// Initiated by initiator side
|
||||
// This function is called when an arbiter's target socket receives a transaction from a device
|
||||
virtual tlm_sync_enum nb_transport_fw(int id, tlm_generic_payload& payload, tlm_phase& phase, sc_time& fwDelay)
|
||||
@@ -69,7 +87,7 @@ protected:
|
||||
tlmRecorder->recordPhase(payload, phase, sc_time_stamp()+fwDelay);
|
||||
|
||||
// Forward Path [1.0]
|
||||
sendToChannel(getPayloadChannel(payload), payload, phase, fwDelay);
|
||||
iSocket[getISocketIndex(payload)]->nb_transport_fw(payload, phase, fwDelay);
|
||||
}
|
||||
else if(phase == END_RESP)
|
||||
{
|
||||
@@ -86,86 +104,37 @@ protected:
|
||||
return TLM_ACCEPTED;
|
||||
}
|
||||
|
||||
// Initiated by dram side
|
||||
// This function is called when an arbiter's initiator socket receives a transaction from a memory controller
|
||||
virtual tlm_sync_enum nb_transport_bw(int /*channelId*/, tlm_generic_payload &payload, tlm_phase &phase, sc_time &bwDelay)
|
||||
{
|
||||
tlmRecorder->recordPhase(payload, phase, bwDelay + sc_time_stamp());
|
||||
|
||||
tSocket[DramExtension::getThread(payload).ID()-1]->nb_transport_bw(payload, TPhase, bwDelay);
|
||||
|
||||
if(phase == BEGIN_RESP)
|
||||
{
|
||||
// Early Completion [3.1]
|
||||
tlmRecorder->recordPhase(payload, END_RESP, bwDelay + sc_time_stamp());
|
||||
tlmRecorder->recordArbiterPhase(payload, BEGIN_RESP, sc_time_stamp()+bwDelay);
|
||||
return TLM_COMPLETED;
|
||||
}
|
||||
// 4-Phase Handshake [1.3]
|
||||
return TLM_ACCEPTED;
|
||||
}
|
||||
|
||||
virtual unsigned int transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans)
|
||||
{
|
||||
// adjust address offset:
|
||||
trans.set_address(trans.get_address() - Configuration::getInstance().AddressOffset);
|
||||
|
||||
DecodedAddress decodedAddress = xmlAddressDecoder::getInstance().decodeAddress(trans.get_address());
|
||||
size_t index = decodedAddress.channel*Configuration::getInstance().memSpec.NumberOfBanks + DramExtension::getBank(trans).ID();
|
||||
return iSocket[index]->transport_dbg(trans);
|
||||
}
|
||||
|
||||
virtual tlm_sync_enum sendToChannel(unsigned int /*channelId*/, tlm_generic_payload& payload, const tlm_phase& phase, const sc_time& delay)
|
||||
{
|
||||
tlm_phase TPhase = phase;
|
||||
sc_time TDelay = delay;
|
||||
return iSocket[getISocketIndex(payload)]->nb_transport_fw(payload, TPhase, TDelay);
|
||||
return iSocket[getISocketIndex(trans)]->transport_dbg(trans);
|
||||
}
|
||||
|
||||
virtual unsigned int getISocketIndex(tlm_generic_payload& payload)
|
||||
{
|
||||
return DramExtension::getBank(payload).ID();
|
||||
}
|
||||
|
||||
virtual tlm_sync_enum sendToInitiator(unsigned int id, tlm_generic_payload& payload, const tlm_phase& phase, const sc_time& delay)
|
||||
{
|
||||
tlm_phase TPhase = phase;
|
||||
sc_time TDelay = delay;
|
||||
return tSocket[id]->nb_transport_bw(payload, TPhase, TDelay);
|
||||
}
|
||||
|
||||
void printDebugMessage(std::string message)
|
||||
{
|
||||
DebugManager::getInstance().printDebugMessage(this->name(), message);
|
||||
}
|
||||
|
||||
void appendDramExtension(int socketId, tlm_generic_payload& payload)
|
||||
{
|
||||
// Append Generation Extension
|
||||
GenerationExtension* genExtension = new GenerationExtension(clkAlign(sc_time_stamp(),Configuration::getInstance().ControllerClk));
|
||||
payload.set_auto_extension(genExtension);
|
||||
|
||||
unsigned int burstlength = payload.get_streaming_width();
|
||||
DecodedAddress decodedAddress = xmlAddressDecoder::getInstance().decodeAddress(payload.get_address());
|
||||
// Check the valid range of decodedAddress
|
||||
if (addressIsValid(decodedAddress)) {
|
||||
DramExtension* extension = new DramExtension(Thread(socketId+1), Channel(decodedAddress.channel), Bank(decodedAddress.bank), BankGroup(decodedAddress.bankgroup), Row(decodedAddress.row), Column(decodedAddress.column),burstlength);
|
||||
payload.set_auto_extension(extension);
|
||||
} else {
|
||||
SC_REPORT_FATAL("Arbiter", "Decoded Address are not inside the valid range");
|
||||
}
|
||||
}
|
||||
|
||||
bool addressIsValid(DecodedAddress& decodedAddress)
|
||||
{
|
||||
if (decodedAddress.channel >= xmlAddressDecoder::getInstance().amount["channel"]) {
|
||||
return false;
|
||||
}
|
||||
if (decodedAddress.bank >= xmlAddressDecoder::getInstance().amount["bank"]) {
|
||||
return false;
|
||||
}
|
||||
if (decodedAddress.bankgroup > xmlAddressDecoder::getInstance().amount["bankgroup"]) {
|
||||
return false;
|
||||
}
|
||||
if (decodedAddress.column >= xmlAddressDecoder::getInstance().amount["column"]) {
|
||||
return false;
|
||||
}
|
||||
if (decodedAddress.row >= xmlAddressDecoder::getInstance().amount["row"]) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int getPayloadChannel(tlm_generic_payload& payload)
|
||||
{
|
||||
return DramExtension::getExtension(payload).getChannel().ID();
|
||||
}
|
||||
|
||||
unsigned int getPayloadThread(tlm_generic_payload& payload)
|
||||
{
|
||||
return DramExtension::getExtension(payload).getThread().ID();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // SIMPLEARBITER_H
|
||||
|
||||
@@ -724,6 +724,15 @@ For more information check the documentation in [DRAMSylva folder](DRAMSys/libra
|
||||
|
||||
#### DRAMsys Diagrams
|
||||
|
||||
- **TLM Approximately Timed (AT)**
|
||||
|
||||
The figure below shows a cheat sheet with the possibilities that the TLM AT protocol
|
||||
offers. The annotated references [X,Y] are placed into the source code for a better
|
||||
orientation.
|
||||
|
||||

|
||||
|
||||
|
||||
- **Payload Extension information**
|
||||
|
||||
GenerationExtension is added in TracePlayer and DramExtension is added in Arbiter.
|
||||
|
||||
Reference in New Issue
Block a user