Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 35 additions & 17 deletions common/include/RevCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,42 +85,60 @@ enum class MemOp : uint8_t {

std::ostream& operator<<(std::ostream& os, MemOp op);

inline uint64_t make_lsq_hash(uint16_t destReg, RevRegClass regType, unsigned HartID){
return static_cast<uint64_t>(regType) << (16 + 8) | static_cast<uint64_t>(destReg) << 16 | HartID;
};
template<typename T>
constexpr uint64_t LSQHash(T DestReg, RevRegClass RegType, unsigned Hart){
return static_cast<uint64_t>(RegType) << (16 + 8) | static_cast<uint64_t>(DestReg) << 16 | Hart;
}

struct MemReq{
MemReq() = default;
MemReq(const MemReq&) = default;
MemReq(MemReq&&) = default;
MemReq& operator=(const MemReq&) = default;
MemReq& operator=(MemReq&&) = default;
~MemReq() = default;

MemReq(uint64_t addr, uint16_t dest, RevRegClass regclass,
unsigned hart, MemOp req, bool outstanding, std::function<void(MemReq)> func) :
Addr(addr), DestReg(dest), RegType(regclass), Hart(hart),
ReqType(req), isOutstanding(outstanding), MarkLoadComplete(std::move(func))
{
template<typename T>
MemReq(uint64_t Addr,
T DestReg,
RevRegClass RegType,
unsigned Hart,
MemOp ReqType,
bool isOutstanding,
std::function<void(const MemReq&)> MarkLoadCompleteFunc) :
Addr(Addr),
DestReg(uint16_t(DestReg)),
RegType(RegType),
Hart(Hart),
ReqType(ReqType),
isOutstanding(isOutstanding),
MarkLoadCompleteFunc(std::move(MarkLoadCompleteFunc)){}

void MarkLoadComplete() const {
MarkLoadCompleteFunc(*this);
}

auto LSQHash() const {
return SST::RevCPU::LSQHash(DestReg, RegType, Hart);
}

void Set(uint64_t addr, uint16_t dest, RevRegClass regclass, unsigned hart,
MemOp req, bool outstanding, std::function<void(MemReq)> func)
{
Addr = addr; DestReg = dest; RegType = regclass; Hart = hart;
ReqType = req; isOutstanding = outstanding; MarkLoadComplete = std::move(func);
auto LSQHashPair() const {
return std::make_pair( LSQHash(), *this );
}

private:
uint64_t Addr = _INVALID_ADDR_;
uint16_t DestReg = 0;
RevRegClass RegType = RevRegClass::RegUNKNOWN;
unsigned Hart = _REV_INVALID_HART_ID_;
MemOp ReqType = MemOp::MemOpCUSTOM;
bool isOutstanding = false;

std::function<void(MemReq)> MarkLoadComplete = nullptr;
std::function<void(const MemReq&)> MarkLoadCompleteFunc = nullptr;

//std::shared_ptr<std::unordered_map<uint64_t, MemReq>> LSQueue;
// std::function<void((MemOp req)>) SetComplete;
// add lambda that clears the dependency bit directly so we don't need to search the hash
friend class RevTracer;
friend class RevMem;
friend class RevProc;
};//struct MemReq

// Enum for tracking the state of a RevThread.
Expand Down
70 changes: 34 additions & 36 deletions include/RevInstHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,40 +66,39 @@ unsigned fclass(T val, bool quietNaN = true) {
/// Load template
template<typename T>
bool load(RevFeature *F, RevRegFile *R, RevMem *M, RevInst Inst) {
MemReq req{};
if( sizeof(T) < sizeof(int64_t) && R->IsRV32 ){
static constexpr RevFlag flags = sizeof(T) < sizeof(int32_t) ?
std::is_signed_v<T> ? RevFlag::F_SEXT32 : RevFlag::F_ZEXT32 : RevFlag::F_NONE;
uint64_t rs1 = R->GetX<uint64_t>(Inst.rs1); // read once for tracer
req.Set(rs1 + Inst.ImmSignExt(12),
Inst.rd, RevRegClass::RegGPR,
F->GetHartToExecID(),
MemOp::MemOpREAD,
true,
R->GetMarkLoadComplete());
R->LSQueue->insert({make_lsq_hash(Inst.rd, RevRegClass::RegGPR, F->GetHartToExecID()), req});
MemReq req(rs1 + Inst.ImmSignExt(12),
Inst.rd, RevRegClass::RegGPR,
F->GetHartToExecID(),
MemOp::MemOpREAD,
true,
R->GetMarkLoadComplete());
R->LSQueue->insert(req.LSQHashPair());
M->ReadVal(F->GetHartToExecID(),
rs1 + Inst.ImmSignExt(12),
reinterpret_cast<std::make_unsigned_t<T>*>(&R->RV32[Inst.rd]),
req,
std::move(req),
flags);
R->SetX(Inst.rd, static_cast<T>(R->RV32[Inst.rd]));

}else{
static constexpr RevFlag flags = sizeof(T) < sizeof(int64_t) ?
std::is_signed_v<T> ? RevFlag::F_SEXT64 : RevFlag::F_ZEXT64 : RevFlag::F_NONE;
uint64_t rs1 = R->GetX<uint64_t>(Inst.rs1);
req.Set(rs1 + Inst.ImmSignExt(12),
Inst.rd, RevRegClass::RegGPR,
F->GetHartToExecID(),
MemOp::MemOpREAD,
true,
R->GetMarkLoadComplete());
R->LSQueue->insert({make_lsq_hash(Inst.rd, RevRegClass::RegGPR, F->GetHartToExecID()), req});
MemReq req(rs1 + Inst.ImmSignExt(12),
Inst.rd, RevRegClass::RegGPR,
F->GetHartToExecID(),
MemOp::MemOpREAD,
true,
R->GetMarkLoadComplete());
R->LSQueue->insert(req.LSQHashPair());
M->ReadVal(F->GetHartToExecID(),
rs1 + Inst.ImmSignExt(12),
reinterpret_cast<std::make_unsigned_t<T>*>(&R->RV64[Inst.rd]),
req,
std::move(req),
flags);
R->SetX(Inst.rd, static_cast<T>(R->RV64[Inst.rd]));
}
Expand All @@ -123,24 +122,23 @@ bool store(RevFeature *F, RevRegFile *R, RevMem *M, RevInst Inst) {
/// Floating-point load template
template<typename T>
bool fload(RevFeature *F, RevRegFile *R, RevMem *M, RevInst Inst) {
MemReq req{};
if(std::is_same_v<T, double> || F->HasD()){
static constexpr RevFlag flags = sizeof(T) < sizeof(double) ?
RevFlag::F_BOXNAN : RevFlag::F_NONE;

uint64_t rs1 = R->GetX<uint64_t>(Inst.rs1);
req.Set(rs1 + Inst.ImmSignExt(12),
Inst.rd,
RevRegClass::RegFLOAT,
F->GetHartToExecID(),
MemOp::MemOpREAD,
true,
R->GetMarkLoadComplete());
R->LSQueue->insert({make_lsq_hash(Inst.rd, RevRegClass::RegFLOAT, F->GetHartToExecID()), req});
MemReq req(rs1 + Inst.ImmSignExt(12),
Inst.rd,
RevRegClass::RegFLOAT,
F->GetHartToExecID(),
MemOp::MemOpREAD,
true,
R->GetMarkLoadComplete());
R->LSQueue->insert(req.LSQHashPair());
M->ReadVal(F->GetHartToExecID(),
rs1 + Inst.ImmSignExt(12),
reinterpret_cast<T*>(&R->DPF[Inst.rd]),
req,
std::move(req),
flags);

// Box float value into 64-bit FP register
Expand All @@ -151,18 +149,18 @@ bool fload(RevFeature *F, RevRegFile *R, RevMem *M, RevInst Inst) {
}
}else{
uint64_t rs1 = R->GetX<uint64_t>(Inst.rs1);
req.Set(rs1 + Inst.ImmSignExt(12),
Inst.rd,
RevRegClass::RegFLOAT,
F->GetHartToExecID(),
MemOp::MemOpREAD,
true,
R->GetMarkLoadComplete());
R->LSQueue->insert({make_lsq_hash(Inst.rd, RevRegClass::RegFLOAT, F->GetHartToExecID()), req});
MemReq req(rs1 + Inst.ImmSignExt(12),
Inst.rd,
RevRegClass::RegFLOAT,
F->GetHartToExecID(),
MemOp::MemOpREAD,
true,
R->GetMarkLoadComplete());
R->LSQueue->insert(req.LSQHashPair());
M->ReadVal(F->GetHartToExecID(),
rs1 + Inst.ImmSignExt(12),
&R->SPF[Inst.rd],
req,
std::move(req),
RevFlag::F_NONE);
}
// update the cost
Expand Down
1 change: 1 addition & 0 deletions include/RevPrefetcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include "RevMem.h"
#include "RevFeature.h"
#include "RevRegFile.h"

namespace SST::RevCPU{

Expand Down
16 changes: 9 additions & 7 deletions include/RevProc.h
Original file line number Diff line number Diff line change
Expand Up @@ -746,7 +746,7 @@ class RevProc{
bool LSQCheck(unsigned HartID, const RevRegFile* regFile,
uint16_t reg, RevRegClass regClass) const {
return (reg != 0 || regClass != RevRegClass::RegGPR) &&
regFile->GetLSQueue()->count(make_lsq_hash(reg, regClass, HartID)) > 0;
regFile->GetLSQueue()->count(LSQHash(reg, regClass, HartID)) > 0;
}

/// RevProc: Check scoreboard for a source register dependency
Expand Down Expand Up @@ -780,20 +780,22 @@ class RevProc{
}

/// RevProc: Set or clear scoreboard based on register number and floating point.
void DependencySet(unsigned HartID, uint16_t RegNum,
template<typename T>
void DependencySet(unsigned HartID, T RegNum,
bool isFloat, bool value = true){
if( RegNum < _REV_NUM_REGS_ ){
if( size_t(RegNum) < _REV_NUM_REGS_ ){
RevRegFile* regFile = GetRegFile(HartID);
if(isFloat){
regFile->FP_Scoreboard[RegNum] = value;
}else if( RegNum != 0 ){
regFile->RV_Scoreboard[RegNum] = value;
regFile->FP_Scoreboard[size_t(RegNum)] = value;
}else if( size_t(RegNum) != 0 ){
regFile->RV_Scoreboard[size_t(RegNum)] = value;
}
}
}

/// RevProc: Clear scoreboard on instruction retirement
void DependencyClear(unsigned HartID, uint16_t RegNum, bool isFloat){
template<typename T>
void DependencyClear(unsigned HartID, T RegNum, bool isFloat){
DependencySet(HartID, RegNum, isFloat, false);
}

Expand Down
2 changes: 1 addition & 1 deletion include/RevRegFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ inline void BoxNaN(double* dest, const void* value){
}

/// RISC-V Register Mneumonics
enum class RevReg {
enum class RevReg : uint16_t {
zero = 0, ra = 1, sp = 2, gp = 3, tp = 4, t0 = 5, t1 = 6, t2 = 7,
s0 = 8, s1 = 9, a0 = 10, a1 = 11, a2 = 12, a3 = 13, a4 = 14, a5 = 15,
a6 = 16, a7 = 17, s2 = 18, s3 = 19, s4 = 20, s5 = 21, s6 = 22, s7 = 23,
Expand Down
46 changes: 20 additions & 26 deletions include/insns/RV32A.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,16 @@ namespace SST::RevCPU{
class RV32A : public RevExt {

static bool lrw(RevFeature *F, RevRegFile *R, RevMem *M, RevInst Inst) {
MemReq req;
if( R->IsRV32 ){
req.Set(uint64_t(R->RV32[Inst.rs1]), Inst.rd, RevRegClass::RegGPR, F->GetHartToExecID(), MemOp::MemOpAMO, true, R->GetMarkLoadComplete());
R->LSQueue->insert({make_lsq_hash(req.DestReg, req.RegType, req.Hart), req});
MemReq req(uint64_t(R->RV32[Inst.rs1]), Inst.rd, RevRegClass::RegGPR, F->GetHartToExecID(), MemOp::MemOpAMO, true, R->GetMarkLoadComplete());
R->LSQueue->insert( req.LSQHashPair() );
M->LR(F->GetHartToExecID(), uint64_t(R->RV32[Inst.rs1]),
&R->RV32[Inst.rd],
Inst.aq, Inst.rl, req,
RevFlag::F_SEXT32);
}else{
req.Set(R->RV64[Inst.rs1], Inst.rd, RevRegClass::RegGPR, F->GetHartToExecID(), MemOp::MemOpAMO, true, R->GetMarkLoadComplete());
R->LSQueue->insert({make_lsq_hash(req.DestReg, req.RegType, req.Hart), req});
MemReq req(R->RV64[Inst.rs1], Inst.rd, RevRegClass::RegGPR, F->GetHartToExecID(), MemOp::MemOpAMO, true, R->GetMarkLoadComplete());
R->LSQueue->insert( req.LSQHashPair() );
M->LR(F->GetHartToExecID(), R->RV64[Inst.rs1],
reinterpret_cast<uint32_t*>(&R->RV64[Inst.rd]),
Inst.aq, Inst.rl, req,
Expand Down Expand Up @@ -72,18 +71,15 @@ class RV32A : public RevExt {
flags |= uint32_t(RevFlag::F_RL);
}

MemReq req;
if( R->IsRV32 ){
req.Set(R->RV32[Inst.rs1],
Inst.rd,
RevRegClass::RegGPR,
F->GetHartToExecID(),
MemOp::MemOpAMO,
true,
R->GetMarkLoadComplete());
R->LSQueue->insert({make_lsq_hash(Inst.rd,
RevRegClass::RegGPR,
F->GetHartToExecID()), req});
MemReq req(R->RV32[Inst.rs1],
Inst.rd,
RevRegClass::RegGPR,
F->GetHartToExecID(),
MemOp::MemOpAMO,
true,
R->GetMarkLoadComplete());
R->LSQueue->insert( req.LSQHashPair() );
M->AMOVal(F->GetHartToExecID(),
R->RV32[Inst.rs1],
&R->RV32[Inst.rs2],
Expand All @@ -92,16 +88,14 @@ class RV32A : public RevExt {
RevFlag{flags});
}else{
flags |= uint32_t(RevFlag::F_SEXT64);
req.Set(R->RV64[Inst.rs1],
Inst.rd,
RevRegClass::RegGPR,
F->GetHartToExecID(),
MemOp::MemOpAMO,
true,
R->GetMarkLoadComplete());
R->LSQueue->insert({make_lsq_hash(Inst.rd,
RevRegClass::RegGPR,
F->GetHartToExecID()), req});
MemReq req(R->RV64[Inst.rs1],
Inst.rd,
RevRegClass::RegGPR,
F->GetHartToExecID(),
MemOp::MemOpAMO,
true,
R->GetMarkLoadComplete());
R->LSQueue->insert( req.LSQHashPair() );
M->AMOVal(F->GetHartToExecID(),
R->RV64[Inst.rs1],
reinterpret_cast<int32_t*>(&R->RV64[Inst.rs2]),
Expand Down
6 changes: 2 additions & 4 deletions include/insns/RV64A.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class RV64A : public RevExt {

static bool lrd(RevFeature *F, RevRegFile *R, RevMem *M, RevInst Inst) {
MemReq req(R->RV64[Inst.rs1], Inst.rd, RevRegClass::RegGPR, F->GetHartToExecID(), MemOp::MemOpAMO, true, R->GetMarkLoadComplete() );
R->LSQueue->insert({make_lsq_hash(req.DestReg, req.RegType, req.Hart), req});
R->LSQueue->insert( req.LSQHashPair() );
M->LR(F->GetHartToExecID(),
R->RV64[Inst.rs1],
&R->RV64[Inst.rd],
Expand Down Expand Up @@ -63,9 +63,7 @@ class RV64A : public RevExt {
MemOp::MemOpAMO,
true,
R->GetMarkLoadComplete());
R->LSQueue->insert({make_lsq_hash(Inst.rd,
RevRegClass::RegGPR,
F->GetHartToExecID()), req});
R->LSQueue->insert( req.LSQHashPair() );
M->AMOVal(F->GetHartToExecID(),
R->RV64[Inst.rs1],
&R->RV64[Inst.rs2],
Expand Down
4 changes: 3 additions & 1 deletion src/RevCPU.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
#include <cmath>
#include <memory>

using namespace SST::RevCPU;
namespace SST::RevCPU{

using MemSegment = RevMem::MemSegment;

const char splash_msg[] = "\
Expand Down Expand Up @@ -851,4 +852,5 @@ void RevCPU::InitMainThread(uint32_t MainThreadID, const uint64_t StartAddr){
ReadyThreads.emplace_back(std::move(MainThread));
}

} // namespace SST::RevCPU
// EOF
3 changes: 2 additions & 1 deletion src/RevExt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
//

#include "RevExt.h"
using namespace SST::RevCPU;
namespace SST::RevCPU{

/// Change the FP environment
auto RevExt::SetFPEnv(unsigned Inst, const RevInst& payload, uint16_t HartID, RevRegFile* regFile){
Expand Down Expand Up @@ -82,4 +82,5 @@ bool RevExt::Execute(unsigned Inst, const RevInst& payload, uint16_t HartID, Rev
return ret;
}

} // namespace SST::RevCPU
// EOF
3 changes: 2 additions & 1 deletion src/RevFeature.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#include <cstring>
#include <string_view>

using namespace SST::RevCPU;
namespace SST::RevCPU{

RevFeature::RevFeature( std::string Machine,
SST::Output *Output,
Expand Down Expand Up @@ -101,4 +101,5 @@ bool RevFeature::ParseMachineModel(){
return false;
}

} // namespace SST::RevCPU
// EOF
Loading