Skip to content

Commit 76f98ae

Browse files
committed
fix cost > 1
1 parent c3dee3c commit 76f98ae

28 files changed

+261
-246
lines changed

Diff for: include/RevCPU.h

+100-99
Large diffs are not rendered by default.

Diff for: include/RevCore.h

+14-12
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ class RevCore {
6868
RevMem* mem,
6969
RevLoader* loader,
7070
std::function<uint32_t()> GetNewThreadID,
71-
SST::Output* output
71+
SST::Output* output,
72+
bool randomizeCosts
7273
);
7374

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

274275
private:
275-
bool Halted = false; ///< RevCore: determines if the core is halted
276-
bool Stalled = false; ///< RevCore: determines if the core is stalled on instruction fetch
277-
bool SingleStep = false; ///< RevCore: determines if we are in a single step
278-
bool CrackFault = false; ///< RevCore: determines if we need to handle a crack fault
279-
bool ALUFault = false; ///< RevCore: determines if we need to handle an ALU fault
280-
unsigned fault_width = 0; ///< RevCore: the width of the target fault
281-
unsigned const id; ///< RevCore: processor id
282-
uint64_t ExecPC = 0; ///< RevCore: executing PC
283-
unsigned HartToDecodeID = 0; ///< RevCore: Current executing ThreadID
284-
unsigned HartToExecID = 0; ///< RevCore: Thread to dispatch instruction
285-
uint64_t currentSimCycle = 0; ///< RevCore: Current simulation cycle
276+
bool Halted = false; ///< RevCore: determines if the core is halted
277+
bool Stalled = false; ///< RevCore: determines if the core is stalled on instruction fetch
278+
bool SingleStep = false; ///< RevCore: determines if we are in a single step
279+
bool CrackFault = false; ///< RevCore: determines if we need to handle a crack fault
280+
bool ALUFault = false; ///< RevCore: determines if we need to handle an ALU fault
281+
bool RandomizeCosts = false; ///< RevCore: whether to randomize costs of instructions
282+
unsigned fault_width = 0; ///< RevCore: the width of the target fault
283+
unsigned const id; ///< RevCore: processor id
284+
uint64_t ExecPC = 0; ///< RevCore: executing PC
285+
unsigned HartToDecodeID = 0; ///< RevCore: Current executing ThreadID
286+
unsigned HartToExecID = 0; ///< RevCore: Thread to dispatch instruction
287+
uint64_t currentSimCycle = 0; ///< RevCore: Current simulation cycle
286288

287289
std::vector<std::shared_ptr<RevHart>> Harts{}; ///< RevCore: vector of Harts without a thread assigned to them
288290
std::bitset<_MAX_HARTS_> IdleHarts{}; ///< RevCore: bitset of Harts with no thread assigned

Diff for: include/RevExt.h

+15-4
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,14 @@
2727
#include "RevInstTable.h"
2828
#include "RevMem.h"
2929

30+
// Maximum cost when randomizing costs of instructions
31+
#define MAX_COST 2
32+
3033
namespace SST::RevCPU {
3134

3235
struct RevExt {
3336
/// RevExt: standard constructor
34-
RevExt( std::string_view name, RevFeature* feature, RevMem* mem, SST::Output* output )
37+
RevExt( std::string_view name, const RevFeature* feature, RevMem* mem, SST::Output* output )
3538
: name( name ), feature( feature ), mem( mem ), output( output ) {}
3639

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

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

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

6669
private:
70+
// RevExt: Randomize instruction costs if randomizeCosts == true
71+
void RandomizeCosts( std::vector<RevInstEntry>& table ) {
72+
if( feature->GetRandomizeCosts() ) {
73+
for( auto& entry : table )
74+
entry.cost = RevRand( 1, MAX_COST );
75+
}
76+
}
77+
6778
std::string_view const name; ///< RevExt: extension name
68-
RevFeature* const feature; ///< RevExt: feature object
79+
const RevFeature* const feature; ///< RevExt: feature object
6980
RevMem* const mem; ///< RevExt: memory object
7081
SST::Output* const output; ///< RevExt: output handler
7182
std::vector<RevInstEntry> table{}; ///< RevExt: instruction table

Diff for: include/RevFeature.h

+16-14
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,9 @@ enum RevFeatureType : uint32_t {
4646
RV_ZTSO = 1 << 20, ///< RevFeatureType: Ztso-extension
4747
};
4848

49-
class RevFeature {
50-
public:
49+
struct RevFeature {
5150
/// RevFeature: standard constructor
52-
RevFeature( std::string Machine, SST::Output* Output, unsigned Min, unsigned Max, unsigned Id );
51+
RevFeature( std::string Machine, SST::Output* Output, unsigned Min, unsigned Max, unsigned Id, bool randomizeCosts );
5352

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

101+
/// GetRandomizeCosts: Return whether to randomize costs
102+
bool GetRandomizeCosts() const { return randomizeCosts; }
103+
102104
private:
103-
std::string machine{}; ///< RevFeature: feature string
104-
SST::Output* output{}; ///< RevFeature: output handler
105-
unsigned MinCost{}; ///< RevFeature: min memory cost
106-
unsigned MaxCost{}; ///< RevFeature: max memory cost
107-
unsigned ProcID{}; ///< RevFeature: RISC-V Proc ID
108-
unsigned HartToExecID{}; ///< RevFeature: The current executing Hart on RevCore
109-
RevFeatureType features{}; ///< RevFeature: feature elements
110-
unsigned xlen{}; ///< RevFeature: RISC-V Xlen
111-
112-
/// ParseMachineModel: parse the machine model string
113-
bool ParseMachineModel();
105+
const std::string machine; ///< RevFeature: feature string
106+
SST::Output* const output; ///< RevFeature: output handler
107+
const unsigned MinCost; ///< RevFeature: min memory cost
108+
const unsigned MaxCost; ///< RevFeature: max memory cost
109+
const unsigned ProcID; ///< RevFeature: RISC-V Proc ID
110+
unsigned HartToExecID{}; ///< RevFeature: The current executing Hart on RevCore
111+
RevFeatureType features{ RV_UNKNOWN }; ///< RevFeature: feature elements
112+
unsigned xlen{}; ///< RevFeature: RISC-V Xlen
113+
const bool randomizeCosts; ///< RevFeature: Whether to randomize costs
114+
bool ParseMachineModel(); ///< RevFeature: Parse the machine model string
115+
114116
}; // class RevFeature
115117

116118
} // namespace SST::RevCPU

Diff for: include/RevInstHelpers.h

+24-24
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ inline constexpr double fpmin<double, uint64_t> = 0x0p+0;
6666
/// FP values outside the range of the target integer type are clipped
6767
/// at the integer type's numerical limits, whether signed or unsigned.
6868
template<typename INT, typename FP>
69-
bool fcvtif( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
69+
bool fcvtif( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
7070
// Read the FP register. Round to integer according to current rounding mode.
7171
FP fp = std::rint( R->GetFP<FP>( Inst.rs1 ) );
7272

@@ -132,7 +132,7 @@ uint32_t fclass( T val ) {
132132

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

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

184184
/// Floating-point load template
185185
template<typename T>
186-
bool fload( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
186+
bool fload( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
187187
if( std::is_same_v<T, double> || F->HasD() ) {
188188
static constexpr RevFlag flags = sizeof( T ) < sizeof( double ) ? RevFlag::F_BOXNAN : RevFlag::F_NONE;
189189
uint64_t rs1 = R->GetX<uint64_t>( Inst.rs1 );
@@ -220,7 +220,7 @@ bool fload( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
220220

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

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

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

323323
// Computes the UPPER half of multiplication, based on signedness
324324
template<bool rs1_is_signed, bool rs2_is_signed>
325-
bool uppermul( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
325+
bool uppermul( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
326326
if( R->IsRV64 ) {
327327
uint64_t rs1 = R->GetX<uint64_t>( Inst.rs1 );
328328
uint64_t rs2 = R->GetX<uint64_t>( Inst.rs2 );
@@ -353,7 +353,7 @@ enum class DivRem { Div, Rem };
353353
// The second parameter is std::make_signed_t or std::make_unsigned_t
354354
// The optional third parameter indicates W mode (32-bit on XLEN == 64)
355355
template<DivRem DIVREM, template<class> class SIGN, bool W_MODE = false>
356-
bool divrem( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
356+
bool divrem( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
357357
if( !W_MODE && !R->IsRV64 ) {
358358
using T = SIGN<int32_t>;
359359
T rs1 = R->GetX<T>( Inst.rs1 );
@@ -386,7 +386,7 @@ bool divrem( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
386386
// The first template parameter is the comparison functor
387387
// The second template parameter is std::make_signed_t or std::make_unsigned_t
388388
template<template<class> class OP, template<class> class SIGN = std::make_unsigned_t>
389-
bool bcond( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
389+
bool bcond( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
390390
bool cond;
391391
if( R->IsRV64 ) {
392392
cond = OP()( R->GetX<SIGN<int64_t>>( Inst.rs1 ), R->GetX<SIGN<int64_t>>( Inst.rs2 ) );
@@ -419,63 +419,63 @@ inline auto revFMA( T x, T y, T z ) {
419419

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

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

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

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

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

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

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

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

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

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

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

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

525525
// Convert floating point to floating point
526526
template<typename FP2, typename FP1>
527-
static bool fcvtff( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
527+
static bool fcvtff( const RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
528528
R->SetFP( Inst.rd, static_cast<FP2>( R->GetFP<FP1>( Inst.rs1 ) ) );
529529
R->AdvancePC( Inst );
530530
return true;

Diff for: include/RevInstTable.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ struct RevInstEntry {
149149
bool raisefpe = false; ///<RevInstEntry: Whether FP exceptions are raised
150150

151151
/// Instruction implementation function
152-
bool ( *func )( RevFeature*, RevRegFile*, RevMem*, const RevInst& ){};
152+
bool ( *func )( const RevFeature*, RevRegFile*, RevMem*, const RevInst& ){};
153153

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

0 commit comments

Comments
 (0)