Skip to content

Commit e098c1c

Browse files
committed
Fix Instruction cost > 1 (does not work for Instruction cost > 1 and numHarts > 1 yet)
1 parent c3dee3c commit e098c1c

File tree

8 files changed

+75
-56
lines changed

8 files changed

+75
-56
lines changed

include/RevCPU.h

+1
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ class RevCPU : public SST::Component {
116116
{"trcStartCycle", "Starting tracer cycle (disables trcOp)", "0"},
117117
{"splash", "Display the splash logo", "0"},
118118
{"independentCoprocClock", "Enables each coprocessor to register its own clock handler", "0"},
119+
{ "randomizeCosts", "Randomizes the cost of each instructionz", "0" },
119120
)
120121

121122
// -------------------------------------------------------

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

include/RevExt.h

+13-2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
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 {
@@ -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,6 +67,14 @@ 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
6879
RevFeature* const feature; ///< RevExt: feature object
6980
RevMem* const mem; ///< RevExt: memory object

include/RevFeature.h

+15-12
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ enum RevFeatureType : uint32_t {
4949
class RevFeature {
5050
public:
5151
/// RevFeature: standard constructor
52-
RevFeature( std::string Machine, SST::Output* Output, unsigned Min, unsigned Max, unsigned Id );
52+
RevFeature( std::string Machine, SST::Output* Output, unsigned Min, unsigned Max, unsigned Id, bool randomizeCosts );
5353

5454
/// RevFeature: standard destructor
5555
~RevFeature() = default;
@@ -99,18 +99,21 @@ class RevFeature {
9999
/// SetHartToExecID: Set the current executing Hart
100100
void SetHartToExecID( unsigned hart ) { HartToExecID = hart; }
101101

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

116119
} // namespace SST::RevCPU

src/RevCPU.cc

+7-2
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,11 @@ RevCPU::RevCPU( SST::ComponentId_t id, const SST::Params& params ) : SST::Compon
101101
msgPerCycle = params.find<unsigned>( "msgPerCycle", 1 );
102102
}
103103

104+
// Whether to randomize the costs of instructions
105+
bool randomizeCosts = params.find<bool>( "randomizeCosts", 0 );
106+
104107
// Look for the fault injection logic
105-
EnableFaults = params.find<bool>( "enable_faults", 0 );
108+
EnableFaults = params.find<bool>( "enable_faults", 0 );
106109
if( EnableFaults ) {
107110
std::vector<std::string> faults;
108111
params.find_array<std::string>( "faults", faults );
@@ -144,7 +147,9 @@ RevCPU::RevCPU( SST::ComponentId_t id, const SST::Params& params ) : SST::Compon
144147
// Create the processor objects
145148
Procs.reserve( Procs.size() + numCores );
146149
for( unsigned i = 0; i < numCores; i++ ) {
147-
Procs.push_back( std::make_unique<RevCore>( i, Opts.get(), numHarts, Mem.get(), Loader.get(), this->GetNewTID(), &output ) );
150+
Procs.push_back(
151+
std::make_unique<RevCore>( i, Opts.get(), numHarts, Mem.get(), Loader.get(), this->GetNewTID(), &output, randomizeCosts )
152+
);
148153
}
149154

150155
EnableCoProc = params.find<bool>( "enableCoProc", 0 );

src/RevCore.cc

+9-12
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ RevCore::RevCore(
2323
RevMem* mem,
2424
RevLoader* loader,
2525
std::function<uint32_t()> GetNewTID,
26-
SST::Output* output
26+
SST::Output* output,
27+
bool randomizeCosts
2728
)
2829
: id( id ), numHarts( numHarts ), opts( opts ), mem( mem ), loader( loader ), GetNewThreadID( std::move( GetNewTID ) ),
2930
output( output ) {
@@ -47,7 +48,7 @@ RevCore::RevCore(
4748
ValidHarts.set( i, true );
4849
}
4950

50-
featureUP = std::make_unique<RevFeature>( Machine, output, MinCost, MaxCost, id );
51+
featureUP = std::make_unique<RevFeature>( Machine, output, MinCost, MaxCost, id, randomizeCosts );
5152
feature = featureUP.get();
5253
if( !feature )
5354
output->fatal( CALL_INFO, -1, "Error: failed to create the RevFeature object for core=%" PRIu32 "\n", id );
@@ -1683,7 +1684,7 @@ bool RevCore::ClockTick( SST::Cycle_t currentCycle ) {
16831684
ExecPC = RegFile->GetPC();
16841685
}
16851686

1686-
if( ( ( HartToExecID != _REV_INVALID_HART_ID_ ) && !RegFile->GetTrigger() ) && !Halted && HartsClearToExecute[HartToExecID] ) {
1687+
if( HartToExecID != _REV_INVALID_HART_ID_ && !RegFile->GetTrigger() && !Halted && HartsClearToExecute[HartToExecID] ) {
16871688
// trigger the next instruction
16881689
// HartToExecID = HartToDecodeID;
16891690
RegFile->SetTrigger( true );
@@ -1784,9 +1785,8 @@ bool RevCore::ClockTick( SST::Cycle_t currentCycle ) {
17841785
}
17851786

17861787
// Check for pipeline hazards
1787-
if( !Pipeline.empty() && ( Pipeline.front().second.cost > 0 ) ) {
1788-
Pipeline.front().second.cost--;
1789-
if( Pipeline.front().second.cost == 0 ) { // &&
1788+
if( !Pipeline.empty() && Pipeline.front().second.cost > 0 ) {
1789+
if( --Pipeline.front().second.cost == 0 ) { // &&
17901790
// Ready to retire this instruction
17911791
uint16_t HartID = Pipeline.front().first;
17921792
#ifdef NO_REV_TRACER
@@ -1805,14 +1805,11 @@ bool RevCore::ClockTick( SST::Cycle_t currentCycle ) {
18051805
++RegFile->InstRet;
18061806

18071807
// Only clear the dependency if there is no outstanding load
1808-
if( ( RegFile->GetLSQueue()->count( LSQHash( Pipeline.front().second.rd, InstTable[Pipeline.front().second.entry].rdClass, HartID ) ) ) == 0 ) {
1809-
DependencyClear( HartID, &( Pipeline.front().second ) );
1808+
if( RegFile->GetLSQueue()->count( LSQHash( Pipeline.front().second.rd, InstTable[Pipeline.front().second.entry].rdClass, HartID ) ) == 0 ) {
1809+
DependencyClear( HartID, &Pipeline.front().second );
18101810
}
18111811
Pipeline.pop_front();
18121812
RegFile->SetCost( 0 );
1813-
} else {
1814-
// could not retire the instruction, bump the cost
1815-
Pipeline.front().second.cost++;
18161813
}
18171814
}
18181815
// Check for completion states and new tasks
@@ -1830,7 +1827,7 @@ bool RevCore::ClockTick( SST::Cycle_t currentCycle ) {
18301827
}
18311828

18321829
if( HartToExecID != _REV_INVALID_HART_ID_ && !IdleHarts[HartToExecID] && HartHasNoDependencies( HartToExecID ) ) {
1833-
std::unique_ptr<RevThread> ActiveThread = PopThreadFromHart( HartToDecodeID );
1830+
std::unique_ptr<RevThread> ActiveThread = PopThreadFromHart( HartToExecID );
18341831
ActiveThread->SetState( ThreadState::DONE );
18351832
HartsClearToExecute[HartToExecID] = false;
18361833
HartsClearToDecode[HartToExecID] = false;

src/RevFeature.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616

1717
namespace SST::RevCPU {
1818

19-
RevFeature::RevFeature( std::string Machine, SST::Output* Output, unsigned Min, unsigned Max, unsigned Id )
20-
: machine( std::move( Machine ) ), output( Output ), MinCost( Min ), MaxCost( Max ), ProcID( Id ), HartToExecID( 0 ),
21-
features( RV_UNKNOWN ), xlen( 0 ) {
19+
RevFeature::RevFeature( std::string Machine, SST::Output* Output, unsigned Min, unsigned Max, unsigned Id, bool randomizeCosts )
20+
: machine( std::move( Machine ) ), output( Output ), MinCost( Min ), MaxCost( Max ), ProcID( Id ),
21+
randomizeCosts( randomizeCosts ) {
2222
output->verbose( CALL_INFO, 6, 0, "Core %u ; Initializing feature set from machine string=%s\n", ProcID, machine.c_str() );
2323
if( !ParseMachineModel() )
2424
output->fatal( CALL_INFO, -1, "Error: failed to parse the machine model: %s\n", machine.c_str() );

src/RevOpts.cc

+13-13
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,16 @@ void RevOpts::SetArgs( const SST::Params& params ) {
4343
std::string args = params.find<std::string>( "args" );
4444
auto nonspace = args.find_first_not_of( delim );
4545
if( nonspace == args.npos || args[nonspace] != '[' ) {
46-
RevOpts::splitStr( args, delim, Argv );
46+
splitStr( args, delim, Argv );
4747
} else {
4848
params.find_array( "args", Argv );
4949
}
5050
}
5151

5252
bool RevOpts::InitPrefetchDepth( const std::vector<std::string>& Depths ) {
5353
std::vector<std::string> vstr;
54-
for( unsigned i = 0; i < Depths.size(); i++ ) {
55-
std::string s = Depths[i];
54+
for( size_t i = 0; i < Depths.size(); i++ ) {
55+
const std::string& s = Depths[i];
5656
splitStr( s, ":", vstr );
5757
if( vstr.size() != 2 )
5858
return false;
@@ -75,7 +75,7 @@ bool RevOpts::InitStartAddrs( const std::vector<std::string>& StartAddrs ) {
7575

7676
// check to see if we expand into multiple cores
7777
if( StartAddrs.size() == 1 ) {
78-
std::string s = StartAddrs[0];
78+
const std::string& s = StartAddrs[0];
7979
splitStr( s, ":", vstr );
8080
if( vstr.size() != 2 )
8181
return false;
@@ -91,7 +91,7 @@ bool RevOpts::InitStartAddrs( const std::vector<std::string>& StartAddrs ) {
9191
}
9292
}
9393

94-
for( unsigned i = 0; i < StartAddrs.size(); i++ ) {
94+
for( size_t i = 0; i < StartAddrs.size(); i++ ) {
9595
std::string s = StartAddrs[i];
9696
splitStr( s, ":", vstr );
9797
if( vstr.size() != 2 )
@@ -112,8 +112,8 @@ bool RevOpts::InitStartAddrs( const std::vector<std::string>& StartAddrs ) {
112112

113113
bool RevOpts::InitStartSymbols( const std::vector<std::string>& StartSymbols ) {
114114
std::vector<std::string> vstr;
115-
for( unsigned i = 0; i < StartSymbols.size(); i++ ) {
116-
std::string s = StartSymbols[i];
115+
for( size_t i = 0; i < StartSymbols.size(); i++ ) {
116+
const std::string& s = StartSymbols[i];
117117
splitStr( s, ":", vstr );
118118
if( vstr.size() != 2 )
119119
return false;
@@ -133,7 +133,7 @@ bool RevOpts::InitMachineModels( const std::vector<std::string>& Machines ) {
133133

134134
// check to see if we expand into multiple cores
135135
if( Machines.size() == 1 ) {
136-
std::string s = Machines[0];
136+
const std::string& s = Machines[0];
137137
splitStr( s, ":", vstr );
138138
if( vstr.size() != 2 )
139139
return false;
@@ -148,7 +148,7 @@ bool RevOpts::InitMachineModels( const std::vector<std::string>& Machines ) {
148148
}
149149

150150
// parse individual core configs
151-
for( unsigned i = 0; i < Machines.size(); i++ ) {
151+
for( size_t i = 0; i < Machines.size(); i++ ) {
152152
std::string s = Machines[i];
153153
splitStr( s, ":", vstr );
154154
if( vstr.size() != 2 )
@@ -166,8 +166,8 @@ bool RevOpts::InitMachineModels( const std::vector<std::string>& Machines ) {
166166

167167
bool RevOpts::InitInstTables( const std::vector<std::string>& InstTables ) {
168168
std::vector<std::string> vstr;
169-
for( unsigned i = 0; i < InstTables.size(); i++ ) {
170-
std::string s = InstTables[i];
169+
for( size_t i = 0; i < InstTables.size(); i++ ) {
170+
const std::string& s = InstTables[i];
171171
splitStr( s, ":", vstr );
172172
if( vstr.size() != 2 )
173173
return false;
@@ -185,8 +185,8 @@ bool RevOpts::InitInstTables( const std::vector<std::string>& InstTables ) {
185185
bool RevOpts::InitMemCosts( const std::vector<std::string>& MemCosts ) {
186186
std::vector<std::string> vstr;
187187

188-
for( unsigned i = 0; i < MemCosts.size(); i++ ) {
189-
std::string s = MemCosts[i];
188+
for( size_t i = 0; i < MemCosts.size(); i++ ) {
189+
const std::string& s = MemCosts[i];
190190
splitStr( s, ":", vstr );
191191
if( vstr.size() != 3 )
192192
return false;

0 commit comments

Comments
 (0)