Skip to content

Commit

Permalink
fix cost > 1
Browse files Browse the repository at this point in the history
  • Loading branch information
leekillough committed Sep 4, 2024
1 parent c3dee3c commit 76f98ae
Show file tree
Hide file tree
Showing 28 changed files with 261 additions and 246 deletions.
199 changes: 100 additions & 99 deletions include/RevCPU.h

Large diffs are not rendered by default.

26 changes: 14 additions & 12 deletions include/RevCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ class RevCore {
RevMem* mem,
RevLoader* loader,
std::function<uint32_t()> GetNewThreadID,
SST::Output* output
SST::Output* output,
bool randomizeCosts
);

/// RevCore: standard destructor
Expand Down Expand Up @@ -272,17 +273,18 @@ class RevCore {
uint64_t GetCycles() const { return cycles; }

private:
bool Halted = false; ///< RevCore: determines if the core is halted
bool Stalled = false; ///< RevCore: determines if the core is stalled on instruction fetch
bool SingleStep = false; ///< RevCore: determines if we are in a single step
bool CrackFault = false; ///< RevCore: determines if we need to handle a crack fault
bool ALUFault = false; ///< RevCore: determines if we need to handle an ALU fault
unsigned fault_width = 0; ///< RevCore: the width of the target fault
unsigned const id; ///< RevCore: processor id
uint64_t ExecPC = 0; ///< RevCore: executing PC
unsigned HartToDecodeID = 0; ///< RevCore: Current executing ThreadID
unsigned HartToExecID = 0; ///< RevCore: Thread to dispatch instruction
uint64_t currentSimCycle = 0; ///< RevCore: Current simulation cycle
bool Halted = false; ///< RevCore: determines if the core is halted
bool Stalled = false; ///< RevCore: determines if the core is stalled on instruction fetch
bool SingleStep = false; ///< RevCore: determines if we are in a single step
bool CrackFault = false; ///< RevCore: determines if we need to handle a crack fault
bool ALUFault = false; ///< RevCore: determines if we need to handle an ALU fault
bool RandomizeCosts = false; ///< RevCore: whether to randomize costs of instructions
unsigned fault_width = 0; ///< RevCore: the width of the target fault
unsigned const id; ///< RevCore: processor id
uint64_t ExecPC = 0; ///< RevCore: executing PC
unsigned HartToDecodeID = 0; ///< RevCore: Current executing ThreadID
unsigned HartToExecID = 0; ///< RevCore: Thread to dispatch instruction
uint64_t currentSimCycle = 0; ///< RevCore: Current simulation cycle

std::vector<std::shared_ptr<RevHart>> Harts{}; ///< RevCore: vector of Harts without a thread assigned to them
std::bitset<_MAX_HARTS_> IdleHarts{}; ///< RevCore: bitset of Harts with no thread assigned
Expand Down
19 changes: 15 additions & 4 deletions include/RevExt.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,14 @@
#include "RevInstTable.h"
#include "RevMem.h"

// Maximum cost when randomizing costs of instructions
#define MAX_COST 2

namespace SST::RevCPU {

struct RevExt {
/// RevExt: standard constructor
RevExt( std::string_view name, RevFeature* feature, RevMem* mem, SST::Output* output )
RevExt( std::string_view name, const RevFeature* feature, RevMem* mem, SST::Output* output )
: name( name ), feature( feature ), mem( mem ), output( output ) {}

/// RevExt: standard destructor. virtual so that Extensions[i] can be deleted
Expand All @@ -46,10 +49,10 @@ struct RevExt {
/// RevExt: sets the internal instruction table
// Note: && means the argument should be an rvalue or std::move(lvalue)
// This avoids deep std::vector copies and uses only one std::vector move.
void SetTable( std::vector<RevInstEntry>&& InstVect ) { table = std::move( InstVect ); }
void SetTable( std::vector<RevInstEntry>&& InstVect ) { RandomizeCosts( table = std::move( InstVect ) ); }

/// RevExt: sets the internal compressed instruction table
void SetCTable( std::vector<RevInstEntry>&& InstVect ) { ctable = std::move( InstVect ); }
void SetCTable( std::vector<RevInstEntry>&& InstVect ) { RandomizeCosts( ctable = std::move( InstVect ) ); }

/// RevExt: retrieve the extension name
std::string_view GetName() const { return name; }
Expand All @@ -64,8 +67,16 @@ struct RevExt {
const std::vector<RevInstEntry>& GetCTable() { return ctable; }

private:
// RevExt: Randomize instruction costs if randomizeCosts == true
void RandomizeCosts( std::vector<RevInstEntry>& table ) {
if( feature->GetRandomizeCosts() ) {
for( auto& entry : table )
entry.cost = RevRand( 1, MAX_COST );
}
}

std::string_view const name; ///< RevExt: extension name
RevFeature* const feature; ///< RevExt: feature object
const RevFeature* const feature; ///< RevExt: feature object
RevMem* const mem; ///< RevExt: memory object
SST::Output* const output; ///< RevExt: output handler
std::vector<RevInstEntry> table{}; ///< RevExt: instruction table
Expand Down
30 changes: 16 additions & 14 deletions include/RevFeature.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,9 @@ enum RevFeatureType : uint32_t {
RV_ZTSO = 1 << 20, ///< RevFeatureType: Ztso-extension
};

class RevFeature {
public:
struct RevFeature {
/// RevFeature: standard constructor
RevFeature( std::string Machine, SST::Output* Output, unsigned Min, unsigned Max, unsigned Id );
RevFeature( std::string Machine, SST::Output* Output, unsigned Min, unsigned Max, unsigned Id, bool randomizeCosts );

/// RevFeature: standard destructor
~RevFeature() = default;
Expand Down Expand Up @@ -99,18 +98,21 @@ class RevFeature {
/// SetHartToExecID: Set the current executing Hart
void SetHartToExecID( unsigned hart ) { HartToExecID = hart; }

/// GetRandomizeCosts: Return whether to randomize costs
bool GetRandomizeCosts() const { return randomizeCosts; }

private:
std::string machine{}; ///< RevFeature: feature string
SST::Output* output{}; ///< RevFeature: output handler
unsigned MinCost{}; ///< RevFeature: min memory cost
unsigned MaxCost{}; ///< RevFeature: max memory cost
unsigned ProcID{}; ///< RevFeature: RISC-V Proc ID
unsigned HartToExecID{}; ///< RevFeature: The current executing Hart on RevCore
RevFeatureType features{}; ///< RevFeature: feature elements
unsigned xlen{}; ///< RevFeature: RISC-V Xlen

/// ParseMachineModel: parse the machine model string
bool ParseMachineModel();
const std::string machine; ///< RevFeature: feature string
SST::Output* const output; ///< RevFeature: output handler
const unsigned MinCost; ///< RevFeature: min memory cost
const unsigned MaxCost; ///< RevFeature: max memory cost
const unsigned ProcID; ///< RevFeature: RISC-V Proc ID
unsigned HartToExecID{}; ///< RevFeature: The current executing Hart on RevCore
RevFeatureType features{ RV_UNKNOWN }; ///< RevFeature: feature elements
unsigned xlen{}; ///< RevFeature: RISC-V Xlen
const bool randomizeCosts; ///< RevFeature: Whether to randomize costs
bool ParseMachineModel(); ///< RevFeature: Parse the machine model string

}; // class RevFeature

} // namespace SST::RevCPU
Expand Down
48 changes: 24 additions & 24 deletions include/RevInstHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ inline constexpr double fpmin<double, uint64_t> = 0x0p+0;
/// FP values outside the range of the target integer type are clipped
/// at the integer type's numerical limits, whether signed or unsigned.
template<typename INT, typename FP>
bool fcvtif( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
bool fcvtif( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
// Read the FP register. Round to integer according to current rounding mode.
FP fp = std::rint( R->GetFP<FP>( Inst.rs1 ) );

Expand Down Expand Up @@ -132,7 +132,7 @@ uint32_t fclass( T val ) {

/// Load template
template<typename T>
bool load( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
bool load( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
if( sizeof( T ) < sizeof( int64_t ) && !R->IsRV64 ) {
static constexpr RevFlag flags =
sizeof( T ) < sizeof( int32_t ) ? std::is_signed_v<T> ? RevFlag::F_SEXT32 : RevFlag::F_ZEXT32 : RevFlag::F_NONE;
Expand Down Expand Up @@ -175,15 +175,15 @@ bool load( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {

/// Store template
template<typename T>
bool store( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
bool store( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
M->Write( F->GetHartToExecID(), R->GetX<uint64_t>( Inst.rs1 ) + Inst.ImmSignExt( 12 ), R->GetX<T>( Inst.rs2 ) );
R->AdvancePC( Inst );
return true;
}

/// Floating-point load template
template<typename T>
bool fload( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
bool fload( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
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 );
Expand Down Expand Up @@ -220,7 +220,7 @@ bool fload( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {

/// Floating-point store template
template<typename T>
bool fstore( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
bool fstore( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
T val = R->GetFP<T, true>( Inst.rs2 );
M->Write( F->GetHartToExecID(), R->GetX<uint64_t>( Inst.rs1 ) + Inst.ImmSignExt( 12 ), val );
R->AdvancePC( Inst );
Expand All @@ -229,7 +229,7 @@ bool fstore( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {

/// Floating-point operation template
template<typename T, template<class> class OP>
bool foper( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
bool foper( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
R->SetFP( Inst.rd, OP()( R->GetFP<T>( Inst.rs1 ), R->GetFP<T>( Inst.rs2 ) ) );
R->AdvancePC( Inst );
return true;
Expand Down Expand Up @@ -267,7 +267,7 @@ struct FMax {

/// Floating-point conditional operation template
template<typename T, template<class> class OP>
bool fcondop( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
bool fcondop( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
bool res = OP()( R->GetFP<T>( Inst.rs1 ), R->GetFP<T>( Inst.rs2 ) );
R->SetX( Inst.rd, res );
R->AdvancePC( Inst );
Expand All @@ -283,7 +283,7 @@ enum class OpKind { Imm, Reg };
// The third parameter is std::make_unsigned_t or std::make_signed_t (default)
// The optional fourth parameter indicates W mode (32-bit on XLEN == 64)
template<template<class> class OP, OpKind KIND, template<class> class SIGN = std::make_signed_t, bool W_MODE = false>
bool oper( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
bool oper( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
if( !W_MODE && !R->IsRV64 ) {
using T = SIGN<int32_t>;
T rs1 = R->GetX<T>( Inst.rs1 );
Expand Down Expand Up @@ -322,7 +322,7 @@ struct ShiftRight {

// Computes the UPPER half of multiplication, based on signedness
template<bool rs1_is_signed, bool rs2_is_signed>
bool uppermul( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
bool uppermul( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
if( R->IsRV64 ) {
uint64_t rs1 = R->GetX<uint64_t>( Inst.rs1 );
uint64_t rs2 = R->GetX<uint64_t>( Inst.rs2 );
Expand Down Expand Up @@ -353,7 +353,7 @@ enum class DivRem { Div, Rem };
// The second parameter is std::make_signed_t or std::make_unsigned_t
// The optional third parameter indicates W mode (32-bit on XLEN == 64)
template<DivRem DIVREM, template<class> class SIGN, bool W_MODE = false>
bool divrem( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
bool divrem( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
if( !W_MODE && !R->IsRV64 ) {
using T = SIGN<int32_t>;
T rs1 = R->GetX<T>( Inst.rs1 );
Expand Down Expand Up @@ -386,7 +386,7 @@ bool divrem( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
// The first template parameter is the comparison functor
// The second template parameter is std::make_signed_t or std::make_unsigned_t
template<template<class> class OP, template<class> class SIGN = std::make_unsigned_t>
bool bcond( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
bool bcond( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
bool cond;
if( R->IsRV64 ) {
cond = OP()( R->GetX<SIGN<int64_t>>( Inst.rs1 ), R->GetX<SIGN<int64_t>>( Inst.rs2 ) );
Expand Down Expand Up @@ -419,63 +419,63 @@ inline auto revFMA( T x, T y, T z ) {

/// Fused Multiply+Add
template<typename T>
bool fmadd( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
bool fmadd( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
R->SetFP( Inst.rd, revFMA( R->GetFP<T>( Inst.rs1 ), R->GetFP<T>( Inst.rs2 ), R->GetFP<T>( Inst.rs3 ) ) );
R->AdvancePC( Inst );
return true;
}

/// Fused Multiply-Subtract
template<typename T>
bool fmsub( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
bool fmsub( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
R->SetFP( Inst.rd, revFMA( R->GetFP<T>( Inst.rs1 ), R->GetFP<T>( Inst.rs2 ), negate( R->GetFP<T>( Inst.rs3 ) ) ) );
R->AdvancePC( Inst );
return true;
}

/// Fused Negated (Multiply-Subtract)
template<typename T>
bool fnmsub( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
bool fnmsub( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
R->SetFP( Inst.rd, revFMA( negate( R->GetFP<T>( Inst.rs1 ) ), R->GetFP<T>( Inst.rs2 ), R->GetFP<T>( Inst.rs3 ) ) );
R->AdvancePC( Inst );
return true;
}

/// Fused Negated (Multiply+Add)
template<typename T>
bool fnmadd( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
bool fnmadd( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
R->SetFP( Inst.rd, negate( revFMA( R->GetFP<T>( Inst.rs1 ), R->GetFP<T>( Inst.rs2 ), R->GetFP<T>( Inst.rs3 ) ) ) );
R->AdvancePC( Inst );
return true;
}

// Square root
template<typename T>
static bool fsqrt( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
static bool fsqrt( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
R->SetFP( Inst.rd, std::sqrt( R->GetFP<T>( Inst.rs1 ) ) );
R->AdvancePC( Inst );
return true;
}

// Transfer sign bit
template<typename T>
static bool fsgnj( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
static bool fsgnj( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
R->SetFP( Inst.rd, std::copysign( R->GetFP<T>( Inst.rs1 ), R->GetFP<T>( Inst.rs2 ) ) );
R->AdvancePC( Inst );
return true;
}

// Negated transfer sign bit
template<typename T>
static bool fsgnjn( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
static bool fsgnjn( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
R->SetFP( Inst.rd, std::copysign( R->GetFP<T>( Inst.rs1 ), negate( R->GetFP<T>( Inst.rs2 ) ) ) );
R->AdvancePC( Inst );
return true;
}

// Xor transfer sign bit
template<typename T>
static bool fsgnjx( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
static bool fsgnjx( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
T rs1 = R->GetFP<T>( Inst.rs1 ), rs2 = R->GetFP<T>( Inst.rs2 );
R->SetFP( Inst.rd, std::copysign( rs1, std::signbit( rs1 ) ? negate( rs2 ) : rs2 ) );
R->AdvancePC( Inst );
Expand All @@ -484,7 +484,7 @@ static bool fsgnjx( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst

// Move floating-point register to integer register
template<typename T>
static bool fmvif( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
static bool fmvif( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
std::make_signed_t<uint_type_t<T>> i;
T fp = R->GetFP<T, true>( Inst.rs1 ); // The FP value
static_assert( sizeof( i ) == sizeof( fp ) );
Expand All @@ -496,7 +496,7 @@ static bool fmvif( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst

// Move integer register to floating-point register
template<typename T>
static bool fmvfi( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
static bool fmvfi( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
T fp;
auto i = R->GetX<uint_type_t<T>>( Inst.rs1 ); // The X register
static_assert( sizeof( i ) == sizeof( fp ) );
Expand All @@ -508,23 +508,23 @@ static bool fmvfi( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst

// Floating-point classify
template<typename T>
static bool fclassify( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
static bool fclassify( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
R->SetX( Inst.rd, fclass( R->GetFP<T>( Inst.rs1 ) ) );
R->AdvancePC( Inst );
return true;
}

// Convert integer to floating point
template<typename FP, typename INT>
static bool fcvtfi( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
static bool fcvtfi( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
R->SetFP( Inst.rd, static_cast<FP>( R->GetX<INT>( Inst.rs1 ) ) );
R->AdvancePC( Inst );
return true;
}

// Convert floating point to floating point
template<typename FP2, typename FP1>
static bool fcvtff( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
static bool fcvtff( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
R->SetFP( Inst.rd, static_cast<FP2>( R->GetFP<FP1>( Inst.rs1 ) ) );
R->AdvancePC( Inst );
return true;
Expand Down
4 changes: 2 additions & 2 deletions include/RevInstTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ struct RevInstEntry {
bool raisefpe = false; ///<RevInstEntry: Whether FP exceptions are raised

/// Instruction implementation function
bool ( *func )( RevFeature*, RevRegFile*, RevMem*, const RevInst& ){};
bool ( *func )( const RevFeature*, RevRegFile*, RevMem*, const RevInst& ){};

/// Predicate for enabling table entries for only certain encodings
bool ( *predicate )( uint32_t Inst ) = []( uint32_t ) { return true; };
Expand All @@ -176,7 +176,7 @@ struct RevInstEntry {
auto& SetCompressed(bool c) { this->compressed = c; return *this; }
auto& Setrs2fcvtOp(uint8_t op) { this->rs2fcvtOp = op; return *this; }
auto& SetRaiseFPE(bool c) { this->raisefpe = c; return *this; }
auto& SetImplFunc( bool func( RevFeature *, RevRegFile *, RevMem *, const RevInst& ) )
auto& SetImplFunc( bool func( const RevFeature *, RevRegFile *, RevMem *, const RevInst& ) )
{ this->func = func; return *this; }
auto& SetPredicate( bool pred( uint32_t ) )
{ this->predicate = pred; return *this; }
Expand Down
Loading

0 comments on commit 76f98ae

Please sign in to comment.