Skip to content

Commit

Permalink
Created the common Allocators class and hooked it up (#97)
Browse files Browse the repository at this point in the history
Removed some dead code as well.

Added `void onStartingTeardown_() override {}` to the
LSU in this PR as an example. This method is called every time just
before the unit is destroyed -- either during an exception or a clean teardown.
  • Loading branch information
Knute Lingaard authored Oct 9, 2023
1 parent aed04b1 commit 0c98a64
Show file tree
Hide file tree
Showing 16 changed files with 281 additions and 152 deletions.
14 changes: 1 addition & 13 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,25 +55,13 @@ set (SIM_BASE ${PROJECT_SOURCE_DIR})
set (OLYMPIA_VERSION "v0.1.0")
add_definitions(-DOLYMPIA_VERSION=\"${OLYMPIA_VERSION}\")

if (CMAKE_BUILD_TYPE MATCHES "^[Rr]elease")
set(SPARTA_BUILD_TYPE "release")
elseif (CMAKE_BUILD_TYPE MATCHES "^[Ff]ast[Dd]ebug")
set(SPARTA_BUILD_TYPE "release")
elseif (CMAKE_BUILD_TYPE MATCHES "^[Dd]ebug")
set(SPARTA_BUILD_TYPE "debug")
elseif (CMAKE_BUILD_TYPE MATCHES "^[Pp]rofile")
set(SPARTA_BUILD_TYPE "release")
else()
message (FATAL_ERROR "Please provide a CMAKE_BUILD_TYPE: -DCMAKE_BUILD_TYPE=Release|FastDebug|Debug|Profile")
endif()

# Profile build flags
set(CMAKE_CXX_FLAGS_PROFILE "-O3 -pg -g -ftime-trace")
set(CMAKE_CXX_FLAGS_FASTDEBUG "-O3 -g")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")

# Include directories
include_directories (core mss)
include_directories (core mss sim)
include_directories (SYSTEM mavis)
include_directories (SYSTEM stf_lib)

Expand Down
5 changes: 5 additions & 0 deletions core/CPUFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,8 @@ auto olympia::CPUFactory::getResourceNames() const -> const std::vector<std::str
{
return resource_names_;
}

// Destroy internal components
void olympia::CPUFactory::deleteSubtree(sparta::ResourceTreeNode*) {
to_delete_.clear();
}
3 changes: 3 additions & 0 deletions core/CPUFactory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ class CPUFactory : public sparta::ResourceFactory<CPU, CPU::CPUParameterSet>{
auto getResourceNames() const -> const std::vector<std::string>&;
private:

//! Destroy internal components
void deleteSubtree(sparta::ResourceTreeNode*) override;

/**
* @brief Implementation : Build the device tree by instantiating resource nodes
*/
Expand Down
5 changes: 5 additions & 0 deletions core/Execute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,9 @@ namespace olympia
}
}
}

void ExecuteFactory::deleteSubtree(sparta::ResourceTreeNode*) {
exe_pipe_tns_.clear();
}

}
1 change: 1 addition & 0 deletions core/Execute.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ namespace olympia
{
public:
void onConfiguring(sparta::ResourceTreeNode* node) override;
void deleteSubtree(sparta::ResourceTreeNode*) override;

~ExecuteFactory() = default;
private:
Expand Down
29 changes: 26 additions & 3 deletions core/Inst.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,30 @@

namespace olympia
{
// This pipeline supports around 250 outstanding instructions.
InstAllocator inst_allocator (3000, 2500);
InstArchInfoAllocator inst_arch_info_allocator(3000, 2500);

/*!
* \brief Construct an Instruction
* \param opcode_info Mavis Opcode information
* \param inst_arch_info Pointer to the static data of instruction
* \param clk Core clock
*
* Called by Mavis when an opcode is decoded to a particular
* instruction.
*/
Inst::Inst(const mavis::OpcodeInfo::PtrType& opcode_info,
const InstArchInfo::PtrType & inst_arch_info,
const sparta::Clock * clk) :
opcode_info_ (opcode_info),
inst_arch_info_ (inst_arch_info),
is_store_(opcode_info->isInstType(mavis::OpcodeInfo::InstructionTypes::STORE)),
is_transfer_(miscutils::isOneOf(inst_arch_info_->getTargetPipe(),
InstArchInfo::TargetPipe::I2F,
InstArchInfo::TargetPipe::F2I)),

status_state_(Status::FETCHED)
{
sparta_assert(inst_arch_info_ != nullptr,
"Mavis decoded the instruction, but Olympia has no uarch data for it: "
<< getDisasm() << " " << std::hex << " opc: 0x" << getOpCode());
}
}
19 changes: 1 addition & 18 deletions core/Inst.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,20 +97,7 @@ namespace olympia
*/
Inst(const mavis::OpcodeInfo::PtrType& opcode_info,
const InstArchInfo::PtrType & inst_arch_info,
const sparta::Clock * clk) :
opcode_info_ (opcode_info),
inst_arch_info_ (inst_arch_info),
is_store_(opcode_info->isInstType(mavis::OpcodeInfo::InstructionTypes::STORE)),
is_transfer_(miscutils::isOneOf(inst_arch_info_->getTargetPipe(),
InstArchInfo::TargetPipe::I2F,
InstArchInfo::TargetPipe::F2I)),

status_state_(Status::FETCHED)
{
sparta_assert(inst_arch_info_ != nullptr,
"Mavis decoded the instruction, but Olympia has no uarch data for it: "
<< getDisasm() << " " << std::hex << " opc: 0x" << getOpCode());
}
const sparta::Clock * clk);

// This is needed by Mavis as an optimization. Try NOT to
// implement it and let the compiler do it for us for speed.
Expand Down Expand Up @@ -311,8 +298,4 @@ namespace olympia
// Instruction allocators
using InstAllocator = sparta::SpartaSharedPointerAllocator<Inst>;
using InstArchInfoAllocator = sparta::SpartaSharedPointerAllocator<InstArchInfo>;

extern InstAllocator inst_allocator;
extern InstArchInfoAllocator inst_arch_info_allocator;

}
30 changes: 23 additions & 7 deletions core/LSU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include "CoreUtils.hpp"
#include "LSU.hpp"

#include "OlympiaAllocators.hpp"

namespace olympia
{
const char LSU::name[] = "lsu";
Expand All @@ -12,10 +14,12 @@ namespace olympia

LSU::LSU(sparta::TreeNode *node, const LSUParameterSet *p) :
sparta::Unit(node),
memory_access_allocator(50, 30), // 50 and 30 are arbitrary numbers here. It can be tuned to an exact value.
load_store_info_allocator(50, 30),
ldst_inst_queue_("lsu_inst_queue", p->ldst_inst_queue_size, getClock()),
ldst_inst_queue_size_(p->ldst_inst_queue_size)
ldst_inst_queue_size_(p->ldst_inst_queue_size),
load_store_info_allocator_(sparta::notNull(OlympiaAllocators::getOlympiaAllocators(node))->
load_store_info_allocator),
memory_access_allocator_(sparta::notNull(OlympiaAllocators::getOlympiaAllocators(node))->
memory_access_allocator)
{
// Pipeline collection config
ldst_pipeline_.enableCollection(node);
Expand Down Expand Up @@ -79,6 +83,16 @@ namespace olympia

}

LSU::~LSU() {
DLOG(getContainer()->getLocation()
<< ": "
<< load_store_info_allocator_.getNumAllocated()
<< " LoadStoreInstInfo objects allocated/created");
DLOG(getContainer()->getLocation()
<< ": "
<< memory_access_allocator_.getNumAllocated()
<< " MemoryAccessInfo objects allocated/created");
}

////////////////////////////////////////////////////////////////////////////////
// Callbacks
Expand Down Expand Up @@ -141,12 +155,14 @@ namespace olympia

if (all_ready) {
// Create load/store memory access info
MemoryAccessInfoPtr mem_info_ptr = sparta::allocate_sparta_shared_pointer<MemoryAccessInfo>(memory_access_allocator,
inst_ptr);
MemoryAccessInfoPtr mem_info_ptr =
sparta::allocate_sparta_shared_pointer<MemoryAccessInfo>(memory_access_allocator_,
inst_ptr);

// Create load/store instruction issue info
LoadStoreInstInfoPtr inst_info_ptr = sparta::allocate_sparta_shared_pointer<LoadStoreInstInfo>(load_store_info_allocator,
mem_info_ptr);
LoadStoreInstInfoPtr inst_info_ptr =
sparta::allocate_sparta_shared_pointer<LoadStoreInstInfo>(load_store_info_allocator_,
mem_info_ptr);
lsu_insts_dispatched_++;

// Append to instruction issue queue
Expand Down
29 changes: 14 additions & 15 deletions core/LSU.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,8 @@ namespace olympia
*/
LSU(sparta::TreeNode* node, const LSUParameterSet* p);

~LSU() {
DLOG(getContainer()->getLocation()
<< ": "
<< load_store_info_allocator.getNumAllocated()
<< " LoadStoreInstInfo objects allocated/created");
DLOG(getContainer()->getLocation()
<< ": "
<< memory_access_allocator.getNumAllocated()
<< " MemoryAccessInfo objects allocated/created");
}
//! Destroy the LSU
~LSU();

//! name of this resource.
static const char name[];
Expand All @@ -91,9 +83,6 @@ namespace olympia
NUM_STAGES
};

// allocator for this object type
sparta::SpartaSharedPointerAllocator<MemoryAccessInfo> memory_access_allocator;

// Forward declaration of the Pair Definition class is must as we are friending it.
class LoadStoreInstInfoPairDef;
// Keep record of instruction issue information
Expand Down Expand Up @@ -186,7 +175,7 @@ namespace olympia

}; // class LoadStoreInstInfo

sparta::SpartaSharedPointerAllocator<LoadStoreInstInfo> load_store_info_allocator;
using LoadStoreInstInfoAllocator = sparta::SpartaSharedPointerAllocator<LoadStoreInstInfo>;

/*!
* \class LoadStoreInstInfoPairDef
Expand Down Expand Up @@ -277,11 +266,16 @@ namespace olympia
sparta::collection::Collectable<bool> cache_busy_collectable_{
getContainer(), "dcache_busy", &cache_busy_};

// LSInstInfo allocator
LoadStoreInstInfoAllocator & load_store_info_allocator_;

// allocator for this object type
MemoryAccessInfoAllocator & memory_access_allocator_;

// NOTE:
// Depending on which kind of cache (e.g. blocking vs. non-blocking) is being used
// This single slot could potentially be extended to a cache pending miss queue


// Load/Store Pipeline
using LoadStorePipeline = sparta::Pipeline<MemoryAccessInfoPtr>;
LoadStorePipeline ldst_pipeline_
Expand Down Expand Up @@ -396,6 +390,11 @@ namespace olympia
"Number of BIU reqs", sparta::Counter::COUNT_NORMAL
};


// When simulation is ending (error or not), this function
// will be called
void onStartingTeardown_() override {}

friend class LSUTester;

};
Expand Down
8 changes: 6 additions & 2 deletions core/MavisUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include "mavis/Mavis.h"
#include "MavisUnit.hpp"

#include "OlympiaAllocators.hpp"

namespace olympia
{

Expand Down Expand Up @@ -67,8 +69,10 @@ namespace olympia
mavis_facade_ (new MavisType(getISAFiles(n, p->isa_file_path, pseudo_file_path_),
getUArchFiles(n, p, p->uarch_file_path, pseudo_file_path_),
mavis_uid_list_, getUArchAnnotationOverrides(p),
InstPtrAllocator<InstAllocator> (inst_allocator),
InstPtrAllocator<InstArchInfoAllocator>(inst_arch_info_allocator)))
InstPtrAllocator<InstAllocator>
(sparta::notNull(OlympiaAllocators::getOlympiaAllocators(n))->inst_allocator),
InstPtrAllocator<InstArchInfoAllocator>
(sparta::notNull(OlympiaAllocators::getOlympiaAllocators(n))->inst_arch_info_allocator)))
{}

/**
Expand Down
19 changes: 14 additions & 5 deletions core/MemoryAccessInfo.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
// <MemoryAccessInfo.hpp> -*- C++ -*-

#pragma once

namespace olympia {
#include "sparta/resources/Scoreboard.hpp"
#include "sparta/pairs/SpartaKeyPairs.hpp"
#include "sparta/utils/SpartaSharedPointer.hpp"
#include "sparta/utils/SpartaSharedPointerAllocator.hpp"

#include "Inst.hpp"

namespace olympia {

class MemoryAccessInfoPairDef;

Expand Down Expand Up @@ -99,9 +107,9 @@ namespace olympia {
};

/*!
* \class MemoryAccessInfoPairDef
* \brief Pair Definition class of the Memory Access Information that flows through the example/CoreModel
*/
* \class MemoryAccessInfoPairDef
* \brief Pair Definition class of the Memory Access Information that flows through the example/CoreModel
*/

// This is the definition of the PairDefinition class of MemoryAccessInfo.
// This PairDefinition class could be named anything but it needs to inherit
Expand All @@ -121,5 +129,6 @@ namespace olympia {
SPARTA_FLATTEN(&MemoryAccessInfo::getInstPtr))
};

using MemoryAccessInfoPtr = sparta::SpartaSharedPointer<MemoryAccessInfo>;
using MemoryAccessInfoPtr = sparta::SpartaSharedPointer<MemoryAccessInfo>;
using MemoryAccessInfoAllocator = sparta::SpartaSharedPointerAllocator<MemoryAccessInfo>;
};
61 changes: 61 additions & 0 deletions sim/OlympiaAllocators.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// <OlympiaAllocators.hpp> -*- C++ -*-

#pragma once

/*!
* \file OlympiaAllocators.hpp
* \brief Defines a general TreeNode that contains all allocators used
* in simulation
*/

#include "sparta/simulation/TreeNode.hpp"

#include "Inst.hpp"
#include "MemoryAccessInfo.hpp"
#include "LSU.hpp" // A little heavyweight to include for now...

namespace olympia
{
/*!
* \class OlympiaAllocators
* \brief A TreeNode that is actually a functional resource
* containing memory allocators
*/
class OlympiaAllocators : public sparta::TreeNode
{
public:
static constexpr char name[] = "olympia_allocators";

OlympiaAllocators(sparta::TreeNode *node) :
sparta::TreeNode(node, name, "Allocators used in simulation")
{}

static OlympiaAllocators * getOlympiaAllocators(sparta::TreeNode *node)
{
OlympiaAllocators * allocators = nullptr;
if(node)
{
if(node->hasChild(OlympiaAllocators::name)) {
// If this class is converted to a resource, use this line
//allocators = node->getChild(OlympiaAllocators::name)->getResourceAs<OlympiaAllocators>();
allocators = node->getChildAs<OlympiaAllocators>(OlympiaAllocators::name);
}
else {
return getOlympiaAllocators(node->getParent());
}
}
return allocators;
}

// Allocators used in simulation. These values can be
// parameterized in the future by converting this class into a
// full-blown sparta::Resource and adding a sparta::ParameterSet
InstAllocator inst_allocator {3000, 2500};
InstArchInfoAllocator inst_arch_info_allocator{3000, 2500};

// For LSU/MSS
LSU::LoadStoreInstInfoAllocator load_store_info_allocator{100, 80};
MemoryAccessInfoAllocator memory_access_allocator {100, 80};

};
}
Loading

0 comments on commit 0c98a64

Please sign in to comment.