Skip to content

Commit

Permalink
- Now commit is issuing any RC updates if Rd is overwritten
Browse files Browse the repository at this point in the history
Change-Id: Ie5ee07858d357b023d9c8b9ddc8636a710adbba3
  • Loading branch information
hakase56557 committed Aug 7, 2023
1 parent 5dece40 commit 5202fed
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 17 deletions.
10 changes: 7 additions & 3 deletions src/arch/riscvcapstone/isa/decoder.isa
Original file line number Diff line number Diff line change
Expand Up @@ -951,7 +951,7 @@ decode QUADRANT default Unknown::unknown() {
"Illegal write - out of capability bounds!", machInst);

Mem_rv = Rs1_trv.getRegVal();

//if EA is not aligned, exception/fault
Fault fault = dyn_inst->initiateGetTag(EA);
if(fault != NoFault)
return fault;
Expand Down Expand Up @@ -1300,25 +1300,29 @@ decode QUADRANT default Unknown::unknown() {
Rd_trv = Rd_trv; // just to make the dumb parser happy
}});
0x6: captype ({{
assert(Rd_trv.getTag());
using CapType = gem5::RiscvcapstoneISA::o3::CapType;
CapType temp = static_cast<CapType>(Rs1);
assert(temp >= CapType::LIN && temp <= CapType::SEALEDRET);
Rd_trv.getRegVal().val.cap.setType(temp);
Rd_trv = Rd_trv; // just to make the dumb parser happy
}});
0x7: capnode ({{
assert(Rd_trv.getTag());
using namespace gem5::RiscvcapstoneISA::o3;
Rd_trv.getRegVal().val.cap.setNodeId(static_cast<NodeID>(Rs1));
Rd_trv = Rd_trv; // just to make the dumb parser happy
}});
0x8: capperm ({{
assert(Rd_trv.getTag());
using CapPerm = gem5::RiscvcapstoneISA::o3::CapPerm;
CapPerm temp = static_cast<CapPerm>(Rs1);
assert(temp >= CapPerm::NA && temp <= CapPerm::RWX);
Rd_trv.getRegVal().val.cap.setPerm(temp);
Rd_trv = Rd_trv; // just to make the dumb parser happy
}});
0x9: capbound ({{
assert(Rd_trv.getTag());
//DPRINTFN("Set capability bound to (%llx, %llx)\n", Rs1, Rs2);
Rd_trv.getRegVal().val.cap.setAddresses(Rs1, Rs2, Rs1);
Rd_trv = Rd_trv; // just to make the dumb parser happy
Expand All @@ -1332,13 +1336,13 @@ decode QUADRANT default Unknown::unknown() {
static_cast<unsigned int>(reg_val.val.cap.perm()),
static_cast<unsigned int>(reg_val.val.cap.type()),
reg_val.val.cap.nodeId());
}}, IsSerializing, IsNonSpeculative);
}}, IsSerializing, IsNonSpeculative, IsSerializeAfter);
0xd: printregs ({{
using namespace gem5::RiscvcapstoneISA::o3;
DynInst *dyn_inst = dynamic_cast<DynInst *>(xc);
assert(dyn_inst);
dyn_inst->printRegs();
}}, IsSerializing, IsNonSpeculative);
}}, IsSerializing, IsNonSpeculative, IsSerializeAfter);
0xe: getrand ({{
srand(time(NULL));
Rd = (rand() % (Rs2 - Rs1) + Rs1) & 0xFFFFFFFFFFFFFFF0;
Expand Down
21 changes: 18 additions & 3 deletions src/arch/riscvcapstone/o3/commit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1225,10 +1225,25 @@ Commit::commitHead(const DynInstPtr &head_inst, unsigned inst_num)
// }
// }
//very, very hacked together
if(head_inst->staticInst->opClass() != No_OpClass && head_inst->staticInst->getName() != "captype"
&& head_inst->staticInst->getName() != "capperm" && head_inst->staticInst->getName() != "capnode") {
if(head_inst->staticInst->opClass() != No_OpClass && head_inst->staticInst->getName() != "capperm" &&
head_inst->staticInst->getName() != "captype" && head_inst->staticInst->getName() != "capnode" &&
head_inst->staticInst->getName() != "capbound" && head_inst->staticInst->getName() != "stc" &&
head_inst->staticInst->getName() != "std" && head_inst->staticInst->getName() != "stb" &&
head_inst->staticInst->getName() != "sth" && head_inst->staticInst->getName() != "stw" &&
head_inst->staticInst->getName() != "capcreate" && head_inst->staticInst->getName() != "capprint" &&
head_inst->numDestRegs() > 0) {
if(iewStage->ncQueue.isFull(tid)) {
DPRINTF(Commit, "[tid:%i] NCQ has become full.\n", tid);
//block(tid);
//send signals to previous stages to block
// toIEW->iewBlock[tid] = true;
return false;
// } else if(toIEW->iewBlock[tid]) {
// toIEW->iewBlock[tid] = false;
// toIEW->iewUnblock[tid] = true;
}
CPU* cpu = dynamic_cast<o3::CPU *>(head_inst->getCpuPtr());
PhysRegIdPtr prev_reg = head_inst->prevDestIdx(0);
PhysRegIdPtr prev_reg = head_inst->prevDestIdx(0); //FIXME: this may be 0, may not be 0
if(!(prev_reg->classValue() == InvalidRegClass || prev_reg->classValue() == MiscRegClass)) {
TaggedRegVal tagged_reg = cpu->getWritableTaggedReg(prev_reg);
if(tagged_reg.getTag()) {
Expand Down
54 changes: 44 additions & 10 deletions src/arch/riscvcapstone/o3/ncq_unit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ NCQUnit::tick() {

void
NCQUnit::dumpNcQueue() {
DPRINTF(NCQ, "Dumping the NCQ\n");
for(size_t i = ncQueue.head(); i <= ncQueue.tail(); i++) {
if(ncQueue[i].inst)
DPRINTF(NCQ, "Instruction = %u\n", ncQueue[i].inst->seqNum);
Expand All @@ -65,6 +66,8 @@ NCQUnit::pushCommand(const DynInstPtr& inst, NodeCommandPtr cmd) {

ncq_entry.commands.push_back(cmd);

dumpNcQueue();

return NoFault;
}

Expand All @@ -80,8 +83,7 @@ NCQUnit::pushCommand(NodeCommandPtr cmd) {

ncq_entry.commands.push_back(cmd);
ncq_entry.seqNum = cmd->seqNum;

cmd->dump();
cmd->ncq_ptr = &ncq_entry;

dumpNcQueue();

Expand All @@ -90,6 +92,7 @@ NCQUnit::pushCommand(NodeCommandPtr cmd) {

bool
NCQUnit::isFull() {
dumpNcQueue();
return ncQueue.full();
}

Expand All @@ -111,11 +114,20 @@ NCQUnit::commitBefore(InstSeqNum seq_num) {

void
NCQUnit::cleanupCommands(){
DPRINTF(NCQ, "Cleaning up commands\n");
while(!ncQueue.empty()) {
auto& front = ncQueue.front();
if(front.inst)
DPRINTF(NCQ, "cleanupCommands: inst %u, canWB %u, completed() %u, commands size() %u", front.inst->seqNum, front.canWB, front.completed(), front.commands.size());
else
DPRINTF(NCQ, "cleanupCommands: inst %u, canWB %u, completed() %u, commands size() %u from commit", front.seqNum, front.canWB, front.completed(), front.commands.size());
if(front.canWB && front.completed()) {
if(front.inst)
if(front.inst) {
DPRINTF(NCQ, "Removing NCQEntry for instruction %u\n", front.inst->seqNum);
front.inst->ncqIdx = -1;
}
else
DPRINTF(NCQ, "Removing NCQEntry for instruction %u from commit\n", front.seqNum);
front.clear();
ncQueue.pop_front();
} else{
Expand All @@ -139,7 +151,7 @@ NCQUnit::writebackCommands(){
DPRINTF(NCQ, "Instruction %u with %u commands (completed = %u)\n", it->inst->seqNum, commands.size(),
it->completedCommands);
else
DPRINTF(NCQ, "Inst is null. Command from commit.\n");
DPRINTF(NCQ, "Instruction = %u. Command from commit.\n", it->seqNum);
for(NodeCommandIterator nc_it = commands.begin();
nc_it != commands.end() && ncq->canSend();
++ nc_it) {
Expand Down Expand Up @@ -168,6 +180,13 @@ NCQUnit::writebackCommands(){

DPRINTF(NCQ, "Checking command dependencies\n");

InstSeqNum sn, sn_o;

if(it->inst)
sn = it->inst->seqNum;
else
sn = it->seqNum;

// check for dependencies
// the naive way. Bruteforce
bool dep_ready = true;
Expand All @@ -180,14 +199,22 @@ NCQUnit::writebackCommands(){
++ nc_it_o) {
NodeCommandPtr nc_ptr_o = *nc_it_o;
assert(nc_ptr_o);
if(nc_ptr_o->status != NodeCommand::COMPLETED &&
if(it_o->inst)
sn_o = it_o->inst->seqNum;
else
sn_o = it_o->seqNum;
/** compare seqNum because commands from commit may be issued
* after commands from execute.
* there might be a better way to do it though
*/
if(nc_ptr_o->status != NodeCommand::COMPLETED && sn_o < sn &&
!ncOrder.reorderAllowed(nc_ptr_o, nc_ptr)){
dep_ready = false;
break;
}
}
if(it_o == it)
break;
// if(it_o == it)
// break;
}

if(!dep_ready)
Expand All @@ -196,6 +223,9 @@ NCQUnit::writebackCommands(){
if(it->inst)
DPRINTF(NCQ, "Command ready to execute (instruction %u)\n",
it->inst->seqNum);
else
DPRINTF(NCQ, "Command ready to execute (instruction %u)\n",
it->seqNum);

// the command can be executed
// one state transition in the state machine
Expand All @@ -218,7 +248,6 @@ NCQUnit::writebackCommands(){
}
}


void
NCQUnit::completeCommand(NodeCommandPtr node_command){
DynInstPtr& inst = node_command->inst;
Expand All @@ -236,6 +265,8 @@ NCQUnit::completeCommand(NodeCommandPtr node_command){
inst->setNodeExecuted();
iew->instToCommitIfExeced(inst);
}
} else {
++node_command->ncq_ptr->completedCommands;
}
}

Expand Down Expand Up @@ -291,6 +322,8 @@ NCQUnit::passedQuery(const DynInstPtr& inst) const {
void
NCQUnit::squash(const InstSeqNum &squashed_num) {
if(!ncQueue.empty()) {
DPRINTF(NCQ, "Squashing till seqNum = %u. NcQueue so far:\n", squashed_num);
dumpNcQueue();
NCQIterator temp = ncQueue.end() - 1;
// while(!ncQueue.empty()) {
// if(ncQueue.back().inst && ncQueue.back().inst->seqNum > squashed_num) {
Expand All @@ -302,12 +335,13 @@ NCQUnit::squash(const InstSeqNum &squashed_num) {
// }
// }
for( ;!ncQueue.empty() && temp != ncQueue.begin(); temp--) {
NCQEntry ncq = *temp;
NCQEntry &ncq = *temp;
if(ncq.inst && ncq.inst->seqNum > squashed_num) {
DPRINTF(NCQ, "Squashing NCQ entry for seqNum = %u\n", ncq.inst->seqNum);
ncq.inst->setSquashed();
ncq.inst->ncqIdx = -1;
ncq.clear();
ncQueue.pop_back();
ncQueue.pop_i(temp.idx());
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/arch/riscvcapstone/o3/node_commands.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "arch/riscvcapstone/o3/node.hh"
#include "arch/riscvcapstone/insts/amo.hh"
#include "debug/NodeCmd.hh"
#include "arch/riscvcapstone/o3/ncq_unit.hh"

namespace gem5 {
namespace RiscvcapstoneISA {
Expand Down Expand Up @@ -139,7 +140,7 @@ NodeAllocate::handleResp(PacketPtr pkt) {
savedNode.depth = parentDepth + (asChild ? 1 : 0);
savedNode.next = nextNodeId;
savedNode.state = Node::VALID;
savedNode.counter = 0; // TODO: perhaps 1
savedNode.counter = 1; // TODO: perhaps 1

state = NCAllocate_STORE;
status = TO_RESUME;
Expand Down
2 changes: 2 additions & 0 deletions src/arch/riscvcapstone/o3/node_commands.hh
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace o3 {

class NodeCommandCondition;
class NCQ;
struct NCQEntry;

/**
* base class for all commands to node controller
Expand All @@ -40,6 +41,7 @@ struct NodeCommand {
DynInstPtr inst;
InstSeqNum seqNum;
CPU *cpu;
NCQEntry *ncq_ptr;
bool canWB;
std::unique_ptr<NodeCommandCondition> condition;
// the returned data and size
Expand Down
23 changes: 23 additions & 0 deletions src/base/circular_queue.hh
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,29 @@ class CircularQueue
--_size;
}

/**
* @brief Pop ith element. Guess it's not a queue anymore
*
* @param idx index of the element to be popped
*/
void
pop_i(size_t idx)
{
assert(!empty() && idx <= tail());

if(idx == tail()) {
--_size;
return;
}

for(size_t i = idx; i <= tail() - 1; i++)
{
data[i] = data[i+1];
}

--_size;
}

/**
* Pushes an element at the end of the queue.
*
Expand Down

0 comments on commit 5202fed

Please sign in to comment.