gem5 O3CPU Backend Documentation Update


The documentation about gem5 O3CPU is a little bit abstract and not closely related to the code. Therefore, this post extracts key function chains to show how an instruction is handled by the backend, with some basic description to ease the learning curve of the O3CPU backend (IEW and Commit stage).

Hopefully this could help more people. Reader should already be familiar with gem5. This post has also been added to the documentation.

Compute Instructions

Compute instructions are simpler as they do not access memory and do not interact with the LSQ. Included below is a high-level calling chain (only important functions) with a description about the functionality of each.

Rename::tick()->Rename::RenameInsts()
IEW::tick()->IEW::dispatchInsts()
IEW::tick()->InstructionQueue::scheduleReadyInsts()
IEW::tick()->IEW::executeInsts()
IEW::tick()->IEW::writebackInsts()
Commit::tick()->Commit::commitInsts()->Commit::commitHead()

Load Instruction

Load instructions share the same path as compute instructions until execution.

IEW::tick()->IEW::executeInsts()
  ->LSQUnit::executeLoad()
    ->StaticInst::initiateAcc()
      ->LSQ::pushRequest()
        ->LSQUnit::read()
          ->LSQRequest::buildPackets()
          ->LSQRequest::sendPacketToCache()
    ->LSQUnit::checkViolation()
DcachePort::recvTimingResp()->LSQRequest::recvTimingResp()
  ->LSQUnit::completeDataAccess()
    ->LSQUnit::writeback()
      ->StaticInst::completeAcc()
      ->IEW::instToCommit()
IEW::tick()->IEW::writebackInsts()

Store Instruction

Store instructions are similar to load instructions, but only writeback to cache after committed.

IEW::tick()->IEW::executeInsts()
  ->LSQUnit::executeStore()
    ->StaticInst::initiateAcc()
      ->LSQ::pushRequest()
        ->LSQUnit::write()
    ->LSQUnit::checkViolation()
Commit::tick()->Commit::commitInsts()->Commit::commitHead()
IEW::tick()->LSQUnit::commitStores()
IEW::tick()->LSQUnit::writebackStores()
  ->LSQRequest::buildPackets()
  ->LSQRequest::sendPacketToCache()
  ->LSQUnit::storePostSend()
DcachePort::recvTimingResp()->LSQRequest::recvTimingResp()
  ->LSQUnit::completeDataAccess()
    ->LSQUnit::completeStore()

Branch Misspeculation

Branch misspeculation is handled in IEW::executeInsts(). It will notify the commit stage to start squashing all instructions in the ROB on the misspeculated branch.

IEW::tick()->IEW::executeInsts()->IEW::squashDueToBranch()

Memory Order Misspeculation

The InstructionQueue has a MemDepUnit to track memory order dependence. The IQ will not schedule an instruction if MemDepUnit states there is dependency.

In LSQUnit::read(), the LSQ will search for possible aliasing store and forward if possible. Otherwise, the load is blocked and rescheduled for when the blocking store completes by notifying the MemDepUnit.

Both LSQUnit::executeLoad/Store() will call LSQUnit::checkViolation() to search the LQ for possible misspeculation. If found, it will set LSQUnit::memDepViolator and IEW::executeInsts() will start later to squash the misspeculated instructions.

IEW::tick()->IEW::executeInsts()
  ->LSQUnit::executeLoad()
    ->StaticInst::initiateAcc()
    ->LSQUnit::checkViolation()
  ->IEW::squashDueToMemOrder()