Use think delay as miminum END_REQ delay
When the controller accepts requests in the same clock cycle as it handles them, undeterministic simulations can occur as the outcome depends on if the new request is accepted before the controllerMethod is called or not. Therefore, a minimum delay of one clock cylce should be used to always handle request only in the next clock cycle, removing the disambiguity.
This commit is contained in:
@@ -313,3 +313,21 @@ An example follows.
|
|||||||
- maximum number of active transactions per initiator (only applies to "Fifo" and "Reorder" arbiter policy)
|
- maximum number of active transactions per initiator (only applies to "Fifo" and "Reorder" arbiter policy)
|
||||||
- *RefreshManagement* (boolean)
|
- *RefreshManagement* (boolean)
|
||||||
- enable the sending of refresh management commands when the number of activates to one bank exceeds a certain management threshold (only supported in DDR5 and LPDDR5)
|
- enable the sending of refresh management commands when the number of activates to one bank exceeds a certain management threshold (only supported in DDR5 and LPDDR5)
|
||||||
|
- *ArbitrationDelayFw* (unsigned int)
|
||||||
|
- number of clock cycles spent in forward arbitration to channel controllers
|
||||||
|
- *ArbitrationDelayBw* (unsigned int)
|
||||||
|
- number of clock cycles spent in backward arbitration to initiator
|
||||||
|
- *ThinkDelayFw* (unsigned int)
|
||||||
|
- minimum number of clock cycles between acceptance of a request to command issuance
|
||||||
|
- *ThinkDelayBw* (unsigned int)
|
||||||
|
- minimum number of clock cycles until response is forwarded to the arbiter
|
||||||
|
- *PhyDelayFw* (unsigned int)
|
||||||
|
- number of clock cycles between command issuance and occupation on the command/data bus
|
||||||
|
- *PhyDelayBw* (unsigned int)
|
||||||
|
- number of clock cycles between read data on the data bus and arrival in the channel controller
|
||||||
|
- *BlockingReadDelay* (unsigned int)
|
||||||
|
- constant number of clock cycles spent reading data in blocking mode
|
||||||
|
- **warning**: usage of blocking transport produces in inaccurate simulation results
|
||||||
|
- *BlockingWriteDelay* (unsigned int)
|
||||||
|
- constant number of clock cycles spent writing data in blocking mode
|
||||||
|
- **warning**: usage of blocking transport produces in inaccurate simulation results
|
||||||
|
|||||||
@@ -422,7 +422,7 @@ void Controller::controllerMethod()
|
|||||||
scheduler->removeRequest(*trans);
|
scheduler->removeRequest(*trans);
|
||||||
manageRequests(config.thinkDelayFw);
|
manageRequests(config.thinkDelayFw);
|
||||||
respQueue->insertPayload(trans,
|
respQueue->insertPayload(trans,
|
||||||
sc_time_stamp() + config.thinkDelayFw + config.phyDelayFw +
|
sc_time_stamp() + config.phyDelayFw +
|
||||||
memSpec.getIntervalOnDataStrobe(command, *trans).end +
|
memSpec.getIntervalOnDataStrobe(command, *trans).end +
|
||||||
config.phyDelayBw + config.thinkDelayBw);
|
config.phyDelayBw + config.thinkDelayBw);
|
||||||
|
|
||||||
@@ -435,7 +435,7 @@ void Controller::controllerMethod()
|
|||||||
if (ranksNumberOfPayloads[rank] == 0)
|
if (ranksNumberOfPayloads[rank] == 0)
|
||||||
powerDownManagers[rank]->triggerEntry();
|
powerDownManagers[rank]->triggerEntry();
|
||||||
|
|
||||||
sc_time fwDelay = config.thinkDelayFw + config.phyDelayFw;
|
sc_time fwDelay = config.phyDelayFw;
|
||||||
tlm_phase phase = command.toPhase();
|
tlm_phase phase = command.toPhase();
|
||||||
iSocket->nb_transport_fw(*trans, phase, fwDelay);
|
iSocket->nb_transport_fw(*trans, phase, fwDelay);
|
||||||
}
|
}
|
||||||
@@ -501,8 +501,8 @@ Controller::nb_transport_fw(tlm_generic_payload& trans, tlm_phase& phase, sc_tim
|
|||||||
if (phase == BEGIN_REQ)
|
if (phase == BEGIN_REQ)
|
||||||
{
|
{
|
||||||
transToAcquire.payload = &trans;
|
transToAcquire.payload = &trans;
|
||||||
transToAcquire.arrival = sc_time_stamp() + delay;
|
transToAcquire.arrival = sc_time_stamp() + delay + config.thinkDelayFw;
|
||||||
beginReqEvent.notify(delay);
|
beginReqEvent.notify(delay + config.thinkDelayFw);
|
||||||
}
|
}
|
||||||
else if (phase == END_RESP)
|
else if (phase == END_RESP)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -57,23 +57,14 @@ McConfig::McConfig(const Config::McConfig& config, const MemSpec& memSpec) :
|
|||||||
powerDownPolicy(config.PowerDownPolicy.value_or(DEFAULT_POWER_DOWN_POLICY)),
|
powerDownPolicy(config.PowerDownPolicy.value_or(DEFAULT_POWER_DOWN_POLICY)),
|
||||||
maxActiveTransactions(config.MaxActiveTransactions.value_or(DEFAULT_MAX_ACTIVE_TRANSACTIONS)),
|
maxActiveTransactions(config.MaxActiveTransactions.value_or(DEFAULT_MAX_ACTIVE_TRANSACTIONS)),
|
||||||
refreshManagement(config.RefreshManagement.value_or(DEFAULT_REFRESH_MANAGEMENT)),
|
refreshManagement(config.RefreshManagement.value_or(DEFAULT_REFRESH_MANAGEMENT)),
|
||||||
arbitrationDelayFw(sc_core::sc_time(
|
arbitrationDelayFw(config.ArbitrationDelayFw.value_or(DEFAULT_ARBITRATION_DELAY_FW) * memSpec.tCK),
|
||||||
config.ArbitrationDelayFw.value_or(DEFAULT_ARBITRATION_DELAY_FW_NS), sc_core::SC_NS)),
|
arbitrationDelayBw(config.ArbitrationDelayBw.value_or(DEFAULT_ARBITRATION_DELAY_BW) * memSpec.tCK),
|
||||||
arbitrationDelayBw(sc_core::sc_time(
|
thinkDelayFw(config.ThinkDelayFw.value_or(DEFAULT_THINK_DELAY_FW) * memSpec.tCK),
|
||||||
config.ArbitrationDelayBw.value_or(DEFAULT_ARBITRATION_DELAY_BW_NS), sc_core::SC_NS)),
|
thinkDelayBw(config.ThinkDelayBw.value_or(DEFAULT_THINK_DELAY_BW) * memSpec.tCK),
|
||||||
thinkDelayFw(
|
phyDelayFw(config.PhyDelayFw.value_or(DEFAULT_PHY_DELAY_FW) * memSpec.tCK),
|
||||||
sc_core::sc_time(config.ThinkDelayFw.value_or(DEFAULT_THINK_DELAY_FW_NS), sc_core::SC_NS)),
|
phyDelayBw(config.PhyDelayBw.value_or(DEFAULT_PHY_DELAY_BW) * memSpec.tCK),
|
||||||
thinkDelayBw(
|
blockingReadDelay(config.BlockingReadDelay.value_or(DEFAULT_BLOCKING_READ_DELAY) * memSpec.tCK),
|
||||||
sc_core::sc_time(config.ThinkDelayBw.value_or(DEFAULT_THINK_DELAY_BW_NS), sc_core::SC_NS)),
|
blockingWriteDelay(config.BlockingWriteDelay.value_or(DEFAULT_BLOCKING_WRITE_DELAY) * memSpec.tCK)
|
||||||
phyDelayFw(
|
|
||||||
sc_core::sc_time(config.PhyDelayFw.value_or(DEFAULT_PHY_DELAY_FW_NS), sc_core::SC_NS)),
|
|
||||||
phyDelayBw(
|
|
||||||
sc_core::sc_time(config.PhyDelayBw.value_or(DEFAULT_PHY_DELAY_BW_NS), sc_core::SC_NS)),
|
|
||||||
blockingReadDelay(sc_core::sc_time(
|
|
||||||
config.BlockingReadDelay.value_or(DEFAULT_BLOCKING_READ_DELAY_NS), sc_core::SC_NS)),
|
|
||||||
blockingWriteDelay(sc_core::sc_time(
|
|
||||||
config.BlockingWriteDelay.value_or(DEFAULT_BLOCKING_WRITE_DELAY_NS), sc_core::SC_NS))
|
|
||||||
|
|
||||||
{
|
{
|
||||||
if (schedulerBuffer == Config::SchedulerBufferType::ReadWrite &&
|
if (schedulerBuffer == Config::SchedulerBufferType::ReadWrite &&
|
||||||
config.RequestBufferSize.has_value())
|
config.RequestBufferSize.has_value())
|
||||||
@@ -115,18 +106,6 @@ McConfig::McConfig(const Config::McConfig& config, const MemSpec& memSpec) :
|
|||||||
|
|
||||||
if (requestBufferSizeWrite < 1)
|
if (requestBufferSizeWrite < 1)
|
||||||
SC_REPORT_FATAL("Configuration", "Minimum request buffer size is 1!");
|
SC_REPORT_FATAL("Configuration", "Minimum request buffer size is 1!");
|
||||||
|
|
||||||
arbitrationDelayFw = std::round(arbitrationDelayFw / memSpec.tCK) * memSpec.tCK;
|
|
||||||
arbitrationDelayBw = std::round(arbitrationDelayBw / memSpec.tCK) * memSpec.tCK;
|
|
||||||
|
|
||||||
thinkDelayFw = std::round(thinkDelayFw / memSpec.tCK) * memSpec.tCK;
|
|
||||||
thinkDelayBw = std::round(thinkDelayBw / memSpec.tCK) * memSpec.tCK;
|
|
||||||
|
|
||||||
phyDelayFw = std::round(phyDelayFw / memSpec.tCK) * memSpec.tCK;
|
|
||||||
phyDelayBw = std::round(phyDelayBw / memSpec.tCK) * memSpec.tCK;
|
|
||||||
|
|
||||||
blockingReadDelay = std::round(blockingReadDelay / memSpec.tCK) * memSpec.tCK;
|
|
||||||
blockingWriteDelay = std::round(blockingWriteDelay / memSpec.tCK) * memSpec.tCK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace DRAMSys
|
} // namespace DRAMSys
|
||||||
|
|||||||
@@ -100,14 +100,14 @@ struct McConfig
|
|||||||
Config::PowerDownPolicyType::NoPowerDown;
|
Config::PowerDownPolicyType::NoPowerDown;
|
||||||
static constexpr unsigned int DEFAULT_MAX_ACTIVE_TRANSACTIONS = 64;
|
static constexpr unsigned int DEFAULT_MAX_ACTIVE_TRANSACTIONS = 64;
|
||||||
static constexpr bool DEFAULT_REFRESH_MANAGEMENT = false;
|
static constexpr bool DEFAULT_REFRESH_MANAGEMENT = false;
|
||||||
static constexpr unsigned DEFAULT_ARBITRATION_DELAY_FW_NS = 0;
|
static constexpr unsigned DEFAULT_ARBITRATION_DELAY_FW = 0;
|
||||||
static constexpr unsigned DEFAULT_ARBITRATION_DELAY_BW_NS = 0;
|
static constexpr unsigned DEFAULT_ARBITRATION_DELAY_BW = 0;
|
||||||
static constexpr unsigned DEFAULT_THINK_DELAY_FW_NS = 0;
|
static constexpr unsigned DEFAULT_THINK_DELAY_FW = 1;
|
||||||
static constexpr unsigned DEFAULT_THINK_DELAY_BW_NS = 0;
|
static constexpr unsigned DEFAULT_THINK_DELAY_BW = 1;
|
||||||
static constexpr unsigned DEFAULT_PHY_DELAY_FW_NS = 0;
|
static constexpr unsigned DEFAULT_PHY_DELAY_FW = 0;
|
||||||
static constexpr unsigned DEFAULT_PHY_DELAY_BW_NS = 0;
|
static constexpr unsigned DEFAULT_PHY_DELAY_BW = 0;
|
||||||
static constexpr unsigned DEFAULT_BLOCKING_READ_DELAY_NS = 60;
|
static constexpr unsigned DEFAULT_BLOCKING_READ_DELAY = 60;
|
||||||
static constexpr unsigned DEFAULT_BLOCKING_WRITE_DELAY_NS = 60;
|
static constexpr unsigned DEFAULT_BLOCKING_WRITE_DELAY = 60;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace DRAMSys
|
} // namespace DRAMSys
|
||||||
|
|||||||
@@ -92,11 +92,6 @@ void RequestIssuer::sendNextRequest()
|
|||||||
sendingTime -= sendingTime % clkPeriod;
|
sendingTime -= sendingTime % clkPeriod;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sendingTime == lastEndRequest)
|
|
||||||
{
|
|
||||||
sendingTime += clkPeriod;
|
|
||||||
}
|
|
||||||
|
|
||||||
delay = sendingTime - sc_core::sc_time_stamp();
|
delay = sendingTime - sc_core::sc_time_stamp();
|
||||||
iSocket->nb_transport_fw(payload, phase, delay);
|
iSocket->nb_transport_fw(payload, phase, delay);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user