Adapt BM to avoid ACT without RD/WR.
This commit is contained in:
@@ -61,22 +61,27 @@ void BankMachine::updateState(Command command)
|
||||
case Command::ACT:
|
||||
state = State::Activated;
|
||||
openRow = DramExtension::getRow(currentPayload);
|
||||
keepTrans = true;
|
||||
refreshManagementCounter++;
|
||||
break;
|
||||
case Command::PREPB: case Command::PRESB: case Command::PREAB:
|
||||
state = State::Precharged;
|
||||
keepTrans = false;
|
||||
break;
|
||||
case Command::RD: case Command::WR:
|
||||
currentPayload = nullptr;
|
||||
keepTrans = false;
|
||||
break;
|
||||
case Command::RDA: case Command::WRA:
|
||||
state = State::Precharged;
|
||||
currentPayload = nullptr;
|
||||
keepTrans = false;
|
||||
break;
|
||||
case Command::PDEA: case Command::PDEP: case Command::SREFEN:
|
||||
assert(!keepTrans);
|
||||
sleeping = true;
|
||||
break;
|
||||
case Command::REFPB: case Command::REFP2B: case Command::REFSB: case Command::REFAB:
|
||||
case Command::REFPB: case Command::REFP2B: case Command::REFSB: case Command::REFAB:
|
||||
sleeping = false;
|
||||
blocked = false;
|
||||
|
||||
@@ -88,7 +93,8 @@ void BankMachine::updateState(Command command)
|
||||
refreshManagementCounter = 0;
|
||||
}
|
||||
break;
|
||||
case Command::RFMPB: case Command::RFMP2B: case Command::RFMSB: case Command::RFMAB:
|
||||
case Command::RFMPB: case Command::RFMP2B: case Command::RFMSB: case Command::RFMAB:
|
||||
assert(!keepTrans);
|
||||
sleeping = false;
|
||||
blocked = false;
|
||||
|
||||
@@ -101,6 +107,7 @@ void BankMachine::updateState(Command command)
|
||||
}
|
||||
break;
|
||||
case Command::PDXA: case Command::PDXP:
|
||||
assert(!keepTrans);
|
||||
sleeping = false;
|
||||
break;
|
||||
default:
|
||||
@@ -165,29 +172,45 @@ sc_time BankMachineOpen::start()
|
||||
|
||||
if (!(sleeping || blocked))
|
||||
{
|
||||
currentPayload = scheduler.getNextRequest(*this);
|
||||
if (currentPayload != nullptr)
|
||||
tlm_generic_payload* newPayload = scheduler.getNextRequest(*this);
|
||||
if (newPayload == nullptr)
|
||||
{
|
||||
return timeToSchedule;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(!keepTrans || currentPayload != nullptr);
|
||||
if (keepTrans)
|
||||
{
|
||||
if (DramExtension::getRow(newPayload) == openRow)
|
||||
currentPayload = newPayload;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentPayload = newPayload;
|
||||
}
|
||||
|
||||
if (state == State::Precharged) // bank precharged
|
||||
nextCommand = Command::ACT;
|
||||
else if (state == State::Activated)
|
||||
{
|
||||
if (DramExtension::getRow(currentPayload) == openRow) // row hit
|
||||
{
|
||||
assert(currentPayload->is_read() || currentPayload->is_write());
|
||||
if (currentPayload->is_read())
|
||||
nextCommand = Command::RD;
|
||||
else if (currentPayload->is_write())
|
||||
nextCommand = Command::WR;
|
||||
else
|
||||
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
|
||||
nextCommand = Command::WR;
|
||||
}
|
||||
else // row miss
|
||||
nextCommand = Command::PREPB;
|
||||
}
|
||||
timeToSchedule = checker.timeToSatisfyConstraints(nextCommand, *currentPayload);
|
||||
return timeToSchedule;
|
||||
}
|
||||
}
|
||||
return timeToSchedule;
|
||||
else
|
||||
return timeToSchedule;
|
||||
}
|
||||
|
||||
BankMachineClosed::BankMachineClosed(const SchedulerIF& scheduler, const CheckerIF& checker, Bank bank)
|
||||
@@ -200,24 +223,40 @@ sc_time BankMachineClosed::start()
|
||||
|
||||
if (!(sleeping || blocked))
|
||||
{
|
||||
currentPayload = scheduler.getNextRequest(*this);
|
||||
if (currentPayload != nullptr)
|
||||
tlm_generic_payload* newPayload = scheduler.getNextRequest(*this);
|
||||
if (newPayload == nullptr)
|
||||
{
|
||||
return timeToSchedule;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(!keepTrans || currentPayload != nullptr);
|
||||
if (keepTrans)
|
||||
{
|
||||
if (DramExtension::getRow(newPayload) == openRow)
|
||||
currentPayload = newPayload;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentPayload = newPayload;
|
||||
}
|
||||
|
||||
if (state == State::Precharged) // bank precharged
|
||||
nextCommand = Command::ACT;
|
||||
else if (state == State::Activated)
|
||||
{
|
||||
assert(currentPayload->is_read() || currentPayload->is_write());
|
||||
if (currentPayload->is_read())
|
||||
nextCommand = Command::RDA;
|
||||
else if (currentPayload->is_write())
|
||||
nextCommand = Command::WRA;
|
||||
else
|
||||
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
|
||||
nextCommand = Command::WRA;
|
||||
}
|
||||
timeToSchedule = checker.timeToSatisfyConstraints(nextCommand, *currentPayload);
|
||||
return timeToSchedule;
|
||||
}
|
||||
}
|
||||
return timeToSchedule;
|
||||
else
|
||||
return timeToSchedule;
|
||||
}
|
||||
|
||||
BankMachineOpenAdaptive::BankMachineOpenAdaptive(const SchedulerIF& scheduler, const CheckerIF& checker, Bank bank)
|
||||
@@ -230,9 +269,24 @@ sc_time BankMachineOpenAdaptive::start()
|
||||
|
||||
if (!(sleeping || blocked))
|
||||
{
|
||||
currentPayload = scheduler.getNextRequest(*this);
|
||||
if (currentPayload != nullptr)
|
||||
tlm_generic_payload* newPayload = scheduler.getNextRequest(*this);
|
||||
if (newPayload == nullptr)
|
||||
{
|
||||
return timeToSchedule;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(!keepTrans || currentPayload != nullptr);
|
||||
if (keepTrans)
|
||||
{
|
||||
if (DramExtension::getRow(newPayload) == openRow)
|
||||
currentPayload = newPayload;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentPayload = newPayload;
|
||||
}
|
||||
|
||||
if (state == State::Precharged) // bank precharged
|
||||
nextCommand = Command::ACT;
|
||||
else if (state == State::Activated)
|
||||
@@ -240,32 +294,32 @@ sc_time BankMachineOpenAdaptive::start()
|
||||
if (DramExtension::getRow(currentPayload) == openRow) // row hit
|
||||
{
|
||||
if (scheduler.hasFurtherRequest(bank, currentPayload->get_command())
|
||||
&&!scheduler.hasFurtherRowHit(bank, openRow, currentPayload->get_command()))
|
||||
&& !scheduler.hasFurtherRowHit(bank, openRow, currentPayload->get_command()))
|
||||
{
|
||||
assert(currentPayload->is_read() || currentPayload->is_write());
|
||||
if (currentPayload->is_read())
|
||||
nextCommand = Command::RDA;
|
||||
else if (currentPayload->is_write())
|
||||
nextCommand = Command::WRA;
|
||||
else
|
||||
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
|
||||
nextCommand = Command::WRA;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(currentPayload->is_read() || currentPayload->is_write());
|
||||
if (currentPayload->is_read())
|
||||
nextCommand = Command::RD;
|
||||
else if (currentPayload->is_write())
|
||||
nextCommand = Command::WR;
|
||||
else
|
||||
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
|
||||
nextCommand = Command::WR;
|
||||
}
|
||||
}
|
||||
else // row miss
|
||||
nextCommand = Command::PREPB;
|
||||
}
|
||||
timeToSchedule = checker.timeToSatisfyConstraints(nextCommand, *currentPayload);
|
||||
return timeToSchedule;
|
||||
}
|
||||
}
|
||||
return timeToSchedule;
|
||||
else
|
||||
return timeToSchedule;
|
||||
}
|
||||
|
||||
BankMachineClosedAdaptive::BankMachineClosedAdaptive(const SchedulerIF& scheduler, const CheckerIF& checker, Bank bank)
|
||||
@@ -278,10 +332,25 @@ sc_time BankMachineClosedAdaptive::start()
|
||||
|
||||
if (!(sleeping || blocked))
|
||||
{
|
||||
currentPayload = scheduler.getNextRequest(*this);
|
||||
if (currentPayload != nullptr)
|
||||
tlm_generic_payload* newPayload = scheduler.getNextRequest(*this);
|
||||
if (newPayload == nullptr)
|
||||
{
|
||||
if (state == State::Precharged && !blocked) // bank precharged
|
||||
return timeToSchedule;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(!keepTrans || currentPayload != nullptr);
|
||||
if (keepTrans)
|
||||
{
|
||||
if (DramExtension::getRow(newPayload) == openRow)
|
||||
currentPayload = newPayload;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentPayload = newPayload;
|
||||
}
|
||||
|
||||
if (state == State::Precharged) // bank precharged
|
||||
nextCommand = Command::ACT;
|
||||
else if (state == State::Activated)
|
||||
{
|
||||
@@ -289,28 +358,28 @@ sc_time BankMachineClosedAdaptive::start()
|
||||
{
|
||||
if (scheduler.hasFurtherRowHit(bank, openRow, currentPayload->get_command()))
|
||||
{
|
||||
assert(currentPayload->is_read() || currentPayload->is_write());
|
||||
if (currentPayload->is_read())
|
||||
nextCommand = Command::RD;
|
||||
else if (currentPayload->is_write())
|
||||
nextCommand = Command::WR;
|
||||
else
|
||||
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
|
||||
nextCommand = Command::WR;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(currentPayload->is_read() || currentPayload->is_write());
|
||||
if (currentPayload->is_read())
|
||||
nextCommand = Command::RDA;
|
||||
else if (currentPayload->is_write())
|
||||
nextCommand = Command::WRA;
|
||||
else
|
||||
SC_REPORT_FATAL("BankMachine", "Wrong TLM command");
|
||||
nextCommand = Command::WRA;
|
||||
}
|
||||
}
|
||||
else // row miss, should never happen
|
||||
SC_REPORT_FATAL("BankMachine", "Should never be reached for this policy");
|
||||
else // row miss, can happen when RD/WR mode is switched
|
||||
nextCommand = Command::PREPB;
|
||||
}
|
||||
timeToSchedule = checker.timeToSatisfyConstraints(nextCommand, *currentPayload);
|
||||
return timeToSchedule;
|
||||
}
|
||||
}
|
||||
return timeToSchedule;
|
||||
else
|
||||
return timeToSchedule;
|
||||
}
|
||||
|
||||
@@ -78,6 +78,7 @@ protected:
|
||||
bool sleeping = false;
|
||||
unsigned refreshManagementCounter = 0;
|
||||
bool refreshManagement = false;
|
||||
bool keepTrans = false;
|
||||
};
|
||||
|
||||
class BankMachineOpen final : public BankMachine
|
||||
|
||||
Reference in New Issue
Block a user