Adapt BM to avoid ACT without RD/WR.

This commit is contained in:
Lukas Steiner
2022-04-04 16:46:01 +02:00
parent 9c9b31416d
commit 576691cd65
2 changed files with 106 additions and 36 deletions

View File

@@ -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;
}

View File

@@ -78,6 +78,7 @@ protected:
bool sleeping = false;
unsigned refreshManagementCounter = 0;
bool refreshManagement = false;
bool keepTrans = false;
};
class BankMachineOpen final : public BankMachine